aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/ChangeLog3417
-rw-r--r--gcc/rust/Make-lang.in22
-rw-r--r--gcc/rust/ast/rust-ast-builder-type.cc1
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc370
-rw-r--r--gcc/rust/ast/rust-ast-builder.h187
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc147
-rw-r--r--gcc/rust/ast/rust-ast-collector.h4
-rw-r--r--gcc/rust/ast/rust-ast-full-decls.h1
-rw-r--r--gcc/rust/ast/rust-ast-visitor.cc92
-rw-r--r--gcc/rust/ast/rust-ast-visitor.h19
-rw-r--r--gcc/rust/ast/rust-ast.cc51
-rw-r--r--gcc/rust/ast/rust-ast.h161
-rw-r--r--gcc/rust/ast/rust-builtin-ast-nodes.h2
-rw-r--r--gcc/rust/ast/rust-collect-lang-items.cc113
-rw-r--r--gcc/rust/ast/rust-collect-lang-items.h61
-rw-r--r--gcc/rust/ast/rust-desugar-for-loops.cc204
-rw-r--r--gcc/rust/ast/rust-desugar-for-loops.h108
-rw-r--r--gcc/rust/ast/rust-desugar-question-mark.cc167
-rw-r--r--gcc/rust/ast/rust-desugar-question-mark.h79
-rw-r--r--gcc/rust/ast/rust-expr.h304
-rw-r--r--gcc/rust/ast/rust-item.h439
-rw-r--r--gcc/rust/ast/rust-macro.h39
-rw-r--r--gcc/rust/ast/rust-path.cc34
-rw-r--r--gcc/rust/ast/rust-path.h436
-rw-r--r--gcc/rust/ast/rust-pattern.cc1
-rw-r--r--gcc/rust/ast/rust-stmt.h31
-rw-r--r--gcc/rust/ast/rust-type.h10
-rw-r--r--gcc/rust/backend/rust-compile-asm.cc63
-rw-r--r--gcc/rust/backend/rust-compile-asm.h16
-rw-r--r--gcc/rust/backend/rust-compile-base.cc97
-rw-r--r--gcc/rust/backend/rust-compile-base.h20
-rw-r--r--gcc/rust/backend/rust-compile-block.cc27
-rw-r--r--gcc/rust/backend/rust-compile-block.h10
-rw-r--r--gcc/rust/backend/rust-compile-context.cc15
-rw-r--r--gcc/rust/backend/rust-compile-context.h5
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc426
-rw-r--r--gcc/rust/backend/rust-compile-expr.h15
-rw-r--r--gcc/rust/backend/rust-compile-extern.h6
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.cc39
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.h8
-rw-r--r--gcc/rust/backend/rust-compile-implitem.cc55
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h6
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc325
-rw-r--r--gcc/rust/backend/rust-compile-item.cc73
-rw-r--r--gcc/rust/backend/rust-compile-item.h6
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc245
-rw-r--r--gcc/rust/backend/rust-compile-pattern.h10
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc191
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.h60
-rw-r--r--gcc/rust/backend/rust-compile-stmt.cc12
-rw-r--r--gcc/rust/backend/rust-compile-struct-field-expr.cc16
-rw-r--r--gcc/rust/backend/rust-compile-struct-field-expr.h2
-rw-r--r--gcc/rust/backend/rust-compile-type.cc121
-rw-r--r--gcc/rust/backend/rust-compile-type.h6
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h4
-rw-r--r--gcc/rust/backend/rust-compile.cc12
-rw-r--r--gcc/rust/backend/rust-constexpr.cc14
-rw-r--r--gcc/rust/backend/rust-mangle-legacy.cc1
-rw-r--r--gcc/rust/backend/rust-mangle-v0.cc5
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/.cargo/config.toml5
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock10
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml10
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml2
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs138
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc135
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h3
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h17
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc20
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h1
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h11
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder.h16
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h1
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-place.h13
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir.h40
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc2
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-function-collector.h8
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc187
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-reporter.h5
-rw-r--r--gcc/rust/checks/errors/privacy/rust-reachability.cc2
-rw-r--r--gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc21
-rw-r--r--gcc/rust/checks/errors/rust-ast-validation.cc20
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.cc151
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.h4
-rw-r--r--gcc/rust/checks/errors/rust-feature-gate.cc7
-rw-r--r--gcc/rust/checks/errors/rust-feature.cc4
-rw-r--r--gcc/rust/checks/errors/rust-feature.h7
-rw-r--r--gcc/rust/checks/errors/rust-hir-pattern-analysis.cc232
-rw-r--r--gcc/rust/checks/errors/rust-hir-pattern-analysis.h4
-rw-r--r--gcc/rust/checks/errors/rust-readonly-check.cc54
-rw-r--r--gcc/rust/checks/errors/rust-unsafe-checker.cc200
-rw-r--r--gcc/rust/checks/errors/rust-unsafe-checker.h6
-rw-r--r--gcc/rust/checks/lints/rust-lint-marklive.cc34
-rw-r--r--gcc/rust/checks/lints/rust-lint-marklive.h76
-rw-r--r--gcc/rust/checks/lints/rust-lint-scan-deadcode.h3
-rw-r--r--gcc/rust/expand/rust-cfg-strip.cc10
-rw-r--r--gcc/rust/expand/rust-derive-clone.cc320
-rw-r--r--gcc/rust/expand/rust-derive-clone.h17
-rw-r--r--gcc/rust/expand/rust-derive-copy.cc93
-rw-r--r--gcc/rust/expand/rust-derive-debug.cc121
-rw-r--r--gcc/rust/expand/rust-derive-debug.h55
-rw-r--r--gcc/rust/expand/rust-derive-default.cc172
-rw-r--r--gcc/rust/expand/rust-derive-default.h58
-rw-r--r--gcc/rust/expand/rust-derive-eq.cc216
-rw-r--r--gcc/rust/expand/rust-derive-eq.h82
-rw-r--r--gcc/rust/expand/rust-derive-hash.cc293
-rw-r--r--gcc/rust/expand/rust-derive-hash.h61
-rw-r--r--gcc/rust/expand/rust-derive-partial-eq.cc313
-rw-r--r--gcc/rust/expand/rust-derive-partial-eq.h85
-rw-r--r--gcc/rust/expand/rust-derive.cc102
-rw-r--r--gcc/rust/expand/rust-derive.h34
-rw-r--r--gcc/rust/expand/rust-expand-format-args.cc2
-rw-r--r--gcc/rust/expand/rust-expand-visitor.cc38
-rw-r--r--gcc/rust/expand/rust-expand-visitor.h1
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.cc268
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.h32
-rw-r--r--gcc/rust/expand/rust-macro-builtins-format-args.cc7
-rw-r--r--gcc/rust/expand/rust-macro-builtins-helpers.cc2
-rw-r--r--gcc/rust/expand/rust-macro-builtins-helpers.h1
-rw-r--r--gcc/rust/expand/rust-macro-builtins-include.cc1
-rw-r--r--gcc/rust/expand/rust-macro-builtins-log-debug.cc2
-rw-r--r--gcc/rust/expand/rust-macro-builtins-utility.cc83
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc17
-rw-r--r--gcc/rust/expand/rust-macro-builtins.h8
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc32
-rw-r--r--gcc/rust/expand/rust-macro-expand.h3
-rw-r--r--gcc/rust/expand/rust-macro-substitute-ctx.cc51
-rw-r--r--gcc/rust/expand/rust-macro-substitute-ctx.h25
-rw-r--r--gcc/rust/expand/rust-token-tree-desugar.cc72
-rw-r--r--gcc/rust/expand/rust-token-tree-desugar.h55
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc55
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.h359
-rw-r--r--gcc/rust/hir/rust-ast-lower-block.h15
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.cc102
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.cc29
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.cc22
-rw-r--r--gcc/rust/hir/rust-ast-lower-stmt.cc36
-rw-r--r--gcc/rust/hir/rust-ast-lower-stmt.h1
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.cc118
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.h6
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc196
-rw-r--r--gcc/rust/hir/rust-ast-lower.h5
-rw-r--r--gcc/rust/hir/rust-hir-dump.cc165
-rw-r--r--gcc/rust/hir/rust-hir-dump.h5
-rw-r--r--gcc/rust/hir/tree/rust-hir-attrs.h56
-rw-r--r--gcc/rust/hir/tree/rust-hir-bound-abstract.h65
-rw-r--r--gcc/rust/hir/tree/rust-hir-bound.h82
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr-abstract.h175
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.cc1490
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h1759
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-decls.h4
-rw-r--r--gcc/rust/hir/tree/rust-hir-generic-param.cc95
-rw-r--r--gcc/rust/hir/tree/rust-hir-generic-param.h187
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.cc1024
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h1142
-rw-r--r--gcc/rust/hir/tree/rust-hir-literal.h78
-rw-r--r--gcc/rust/hir/tree/rust-hir-node.h63
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.cc420
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.h496
-rw-r--r--gcc/rust/hir/tree/rust-hir-pattern-abstract.h82
-rw-r--r--gcc/rust/hir/tree/rust-hir-pattern.h23
-rw-r--r--gcc/rust/hir/tree/rust-hir-simple-path.h64
-rw-r--r--gcc/rust/hir/tree/rust-hir-stmt.cc114
-rw-r--r--gcc/rust/hir/tree/rust-hir-stmt.h163
-rw-r--r--gcc/rust/hir/tree/rust-hir-trait-bound.h87
-rw-r--r--gcc/rust/hir/tree/rust-hir-type-abstract.cc (renamed from gcc/rust/util/rust-make-unique.h)19
-rw-r--r--gcc/rust/hir/tree/rust-hir-type-abstract.h80
-rw-r--r--gcc/rust/hir/tree/rust-hir-type-no-bounds.h58
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.cc290
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.h361
-rw-r--r--gcc/rust/hir/tree/rust-hir-visibility.h80
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitable.h41
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h13
-rw-r--r--gcc/rust/hir/tree/rust-hir.cc264
-rw-r--r--gcc/rust/hir/tree/rust-hir.h817
-rw-r--r--gcc/rust/lang.opt17
-rw-r--r--gcc/rust/lex/rust-lex.cc6
-rw-r--r--gcc/rust/lex/rust-token.h7
-rw-r--r--gcc/rust/metadata/rust-export-metadata.cc2
-rw-r--r--gcc/rust/metadata/rust-import-archive.cc5
-rw-r--r--gcc/rust/metadata/rust-imports.cc5
-rw-r--r--gcc/rust/parse/rust-parse-impl.h359
-rw-r--r--gcc/rust/parse/rust-parse.h51
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.cc12
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h8
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.cc91
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h1
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h19
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc110
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.cc225
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.cc21
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h56
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h53
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc285
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h148
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc2
-rw-r--r--gcc/rust/resolve/rust-default-resolver.cc43
-rw-r--r--gcc/rust/resolve/rust-default-resolver.h5
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc157
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.h28
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.cc46
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.h7
-rw-r--r--gcc/rust/resolve/rust-finalize-imports-2.0.cc95
-rw-r--r--gcc/rust/resolve/rust-finalize-imports-2.0.h57
-rw-r--r--gcc/rust/resolve/rust-forever-stack.cc318
-rw-r--r--gcc/rust/resolve/rust-forever-stack.h235
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx389
-rw-r--r--gcc/rust/resolve/rust-ice-finalizer.cc36
-rw-r--r--gcc/rust/resolve/rust-ice-finalizer.h65
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc447
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.h22
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.cc84
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h184
-rw-r--r--gcc/rust/resolve/rust-name-resolver.cc23
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h35
-rw-r--r--gcc/rust/resolve/rust-rib.cc19
-rw-r--r--gcc/rust/resolve/rust-rib.h48
-rw-r--r--gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc190
-rw-r--r--gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h26
-rw-r--r--gcc/rust/rust-backend.h6
-rw-r--r--gcc/rust/rust-gcc.cc291
-rw-r--r--gcc/rust/rust-lang.cc2
-rw-r--r--gcc/rust/rust-session-manager.cc73
-rw-r--r--gcc/rust/rust-session-manager.h16
-rw-r--r--gcc/rust/typecheck/rust-autoderef.cc4
-rw-r--r--gcc/rust/typecheck/rust-casts.cc43
-rw-r--r--gcc/rust/typecheck/rust-hir-dot-operator.cc188
-rw-r--r--gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.cc23
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-reference.cc24
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-reference.h18
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc100
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-bounds.h1
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc186
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h19
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-enumitem.cc73
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-enumitem.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc780
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h9
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.cc311
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h14
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.cc187
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc152
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.cc112
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.h11
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.cc43
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-struct-field.h7
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-struct.cc102
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc553
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h51
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc100
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h44
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.cc40
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h6
-rw-r--r--gcc/rust/typecheck/rust-type-util.cc55
-rw-r--r--gcc/rust/typecheck/rust-typecheck-context.cc89
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc223
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.h25
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.cc44
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h5
-rw-r--r--gcc/rust/typecheck/rust-tyty-cmp.h39
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.cc40
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.h12
-rw-r--r--gcc/rust/typecheck/rust-tyty-variance-analysis-private.h2
-rw-r--r--gcc/rust/typecheck/rust-tyty-variance-analysis.cc2
-rw-r--r--gcc/rust/typecheck/rust-tyty-visitor.h2
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc490
-rw-r--r--gcc/rust/typecheck/rust-tyty.h242
-rw-r--r--gcc/rust/typecheck/rust-unify.cc105
-rw-r--r--gcc/rust/typecheck/rust-unify.h2
-rw-r--r--gcc/rust/util/expected.h4
-rw-r--r--gcc/rust/util/rust-attribute-values.h28
-rw-r--r--gcc/rust/util/rust-attributes.cc32
-rw-r--r--gcc/rust/util/rust-attributes.h13
-rw-r--r--gcc/rust/util/rust-common.h1
-rw-r--r--gcc/rust/util/rust-edition.cc40
-rw-r--r--gcc/rust/util/rust-edition.h41
-rw-r--r--gcc/rust/util/rust-hir-map.cc118
-rw-r--r--gcc/rust/util/rust-hir-map.h42
-rw-r--r--gcc/rust/util/rust-lang-item.cc84
-rw-r--r--gcc/rust/util/rust-lang-item.h45
-rw-r--r--gcc/rust/util/rust-operators.h8
-rw-r--r--gcc/rust/util/rust-stacked-contexts.h14
-rw-r--r--gcc/rust/util/rust-token-converter.cc3
-rw-r--r--gcc/rust/util/rust-token-converter.h2
-rw-r--r--gcc/rust/util/rust-unwrap-segment.cc61
-rw-r--r--gcc/rust/util/rust-unwrap-segment.h121
290 files changed, 23221 insertions, 9854 deletions
diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog
index b871717..2a5219d 100644
--- a/gcc/rust/ChangeLog
+++ b/gcc/rust/ChangeLog
@@ -1,3 +1,3420 @@
+2025-06-26 Martin Jambor <mjambor@suse.cz>
+
+ * checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
+ (BorrowCheckerDiagnostics::get_loan): Type cast loan to uint32_t.
+
+2025-04-28 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/borrowck/rust-bir-place.h
+ (IndexVec::size_type): Add.
+ (IndexVec::MAX_INDEX): Add.
+ (IndexVec::size): Change the return type to the type of the
+ internal value used by the index type.
+ (PlaceDB::lookup_or_add_variable): Use the return value from the
+ PlaceDB::add_place call.
+ * checks/errors/borrowck/rust-bir.h
+ (struct BasicBlockId): Move this definition before the
+ definition of the struct Function.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Visit visibility.
+
+2025-04-28 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-visitor.cc
+ (DefaultASTVisitor::visit): Visit the loop labels of
+ WhileLetLoopExpr instances before visiting their scrutinee
+ expressions.
+ * resolve/rust-early-name-resolver-2.0.cc
+ (Early::resolve_glob_import): Pass the glob import's path
+ directly to NameResolutionContext::resolve_path.
+ * resolve/rust-toplevel-name-resolver-2.0.cc
+ (TopLevel::visit): Remove unnecessary call to
+ Identifier::as_string.
+ (flatten_glob): Improve handling of cases where a glob use tree
+ has no path.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * expand/rust-derive-clone.cc (DeriveClone::clone_enum_struct): Clone
+ path to avoid using the same nodeid.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit_function_params):
+ Add specialized function to visit function parameters.
+ (DefaultASTVisitor::visit): Remove parameter visit and call specialized
+ function instead.
+ * ast/rust-ast-visitor.h: Add function prototye.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Remove
+ function.
+ (Late::visit_function_params): Override specialized visit function.
+ * resolve/rust-late-name-resolver-2.0.h: Add overriden function
+ prototype.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-name-resolution-context.h: Use BindingLayer instead.
+ * resolve/rust-name-resolution-context.cc (BindingLayer::BindingLayer):
+ Add new constructor for binding layer.
+ (BindingLayer::bind_test): Add a function to test a binding constraint.
+ (BindingLayer::push): Push a new binding group.
+ (BindingLayer::and_binded): Add function to test and-binding
+ constraint.
+ (BindingLayer::or_binded): Add function to test or-binding constraints.
+ (BindingLayer::insert_ident): Insert a new identifier in the current
+ binding group.
+ (BindingLayer::merge): Merge current binding group with it's parent.
+ (BindingLayer::get_source): Get the source of the current binding
+ group.
+ * resolve/rust-late-name-resolver-2.0.cc: Use stacked context for
+ binding group.
+ * util/rust-stacked-contexts.h: Add mutable peek function.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add binding
+ creation in visitor.
+ * resolve/rust-late-name-resolver-2.0.h: Add function prototypes.
+ * resolve/rust-name-resolution-context.h: Add binding context.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-name-resolution-context.h (struct Binding): Add Binding
+ struct to differentiate Or and Product bindings in patterns.
+ (enum class): Add Binding kind.
+ (class BindingContext): Add binding context with Binding stack.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast.h: Add hash function.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast.h: Add equality operator.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-default-resolver.cc (DefaultResolver::visit): Add visit
+ function for TypeParam.
+ * resolve/rust-default-resolver.h: Add function prototype.
+ * resolve/rust-forever-stack.h: Add function to check for forward
+ declaration ban.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Check forward
+ declarations.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Remove error kind
+ and change function call.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Change call name.
+ * ast/rust-path.cc (ConstGenericParam::as_string): Likewise.
+ * ast/rust-path.h: Remove error kind.
+ * hir/rust-ast-lower-type.cc (ASTLowerGenericParam::visit): Change call
+ name.
+ * parse/rust-parse-impl.h (Parser::parse_generic_param): Use optional
+ on parsing failure.
+ (Parser::parse_generic_arg): Likewise.
+ (Parser::parse_path_generic_args): Likewise.
+ * parse/rust-parse.h: Likewise.
+ * resolve/rust-ast-resolve-type.h: Change call name.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Change error
+ message.
+
+2025-04-28 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc
+ (Early::build_import_mapping): Avoid outputting an "unresolved
+ import" error if other errors are outputted during resolution.
+ * resolve/rust-early-name-resolver-2.0.h
+ (Early::resolve_path_in_all_ns): Collect path resolution errors
+ while avoiding duplicate errors for resolutions in each
+ namespace.
+ * resolve/rust-forever-stack.h
+ (ForeverStack::resolve_path): Add parameter for collecting
+ errors.
+ (ForeverStack::find_starting_point): Likewise.
+ (ForeverStack::resolve_segments): Likewise.
+ * resolve/rust-forever-stack.hxx
+ (check_leading_kw_at_start): Likewise.
+ (ForeverStack::find_starting_point): Likewise.
+ (ForeverStack::resolve_segments): Likewise.
+ (ForeverStack::resolve_path): Likewise.
+ * resolve/rust-name-resolution-context.h
+ (NameResolutionContext::resolve_path): Add optional parameter
+ for collecting errors.
+
+2025-04-28 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::array_copied_expr): prealloc the vector
+
+2025-04-28 Philip Herron <herron.philip@googlemail.com>
+
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): add guard
+ * expand/rust-expand-visitor.cc (ExpandVisitor::visit): add guard
+
+2025-04-28 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-ast-resolve-path.cc
+ (ResolvePath::resolve_path): Adjust error messages.
+ * resolve/rust-ast-resolve-type.cc
+ (ResolveRelativeTypePath::go): Likewise.
+ * resolve/rust-forever-stack.hxx
+ (check_leading_kw_at_start): Likewise.
+
+2025-04-28 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): fix bad assertion
+
+2025-04-28 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::resolve_path): Pass instance of Node to lambda by
+ reference instead of by value.
+
+2025-04-28 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-struct-field.h: keep reference to parent expression
+ * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::TypeCheckStructExpr):
+ update ctor
+ (TypeCheckStructExpr::resolve): remove bad rust_fatal_errors
+ (TypeCheckStructExpr::visit): cleanup errors
+
+2025-04-28 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Handle StructPatternFieldIdent.
+ * resolve/rust-late-name-resolver-2.0.h
+ (Late::visit): Likewise.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Dump llvm inline
+ asm tokens.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Remove unreachable
+ code.
+ * ast/rust-expr.h (struct LlvmOperand): Add LlvmOperand struct to
+ represent input and outputs.
+ (class LlvmInlineAsm): Add input, output and clobber operands.
+ (struct TupleTemplateStr): Add locus getter.
+ * backend/rust-compile-block.h: Add visit for LlvmInlineAsm.
+ * backend/rust-compile-expr.cc (CompileExpr::visit): Add llvm inline
+ asm stmt compilation.
+ * backend/rust-compile-expr.h: Add function prototype.
+ * backend/rust-compile-asm.h (class CompileLlvmAsm): Add llvm asm hir
+ not to gimple.
+ * backend/rust-compile-asm.cc (CompileLlvmAsm::CompileLlvmAsm): Add
+ constructor.
+ (CompileLlvmAsm::construct_operands): Add function to construct operand
+ tree.
+ (CompileLlvmAsm::construct_clobbers): Add function to construct clobber
+ tree.
+ (CompileLlvmAsm::tree_codegen_asm): Generate the whole tree for a given
+ llvm inline assembly node.
+ * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc (ExprStmtBuilder::visit):
+ Add visit function.
+ * checks/errors/borrowck/rust-bir-builder-expr-stmt.h: Add function
+ prototype.
+ * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Add visit
+ function.
+ * checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
+ * checks/errors/borrowck/rust-function-collector.h: Likewise.
+ * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::visit):
+ Likewise.
+ * checks/errors/privacy/rust-privacy-reporter.h: Add visit function
+ prototype.
+ * checks/errors/rust-const-checker.cc (ConstChecker::visit): Add visit
+ function.
+ * checks/errors/rust-const-checker.h: Add visit function prototype.
+ * checks/errors/rust-hir-pattern-analysis.cc (PatternChecker::visit):
+ Add visit function.
+ * checks/errors/rust-hir-pattern-analysis.h: Add visit function
+ prototype.
+ * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Add
+ visit function.
+ * checks/errors/rust-unsafe-checker.h: Add function prototype.
+ * expand/rust-macro-builtins-asm.cc (parse_llvm_templates): Parse
+ templates.
+ (parse_llvm_arguments): Add function to parse non template tokens.
+ (parse_llvm_operands): Add function to parse operands, either input or
+ output.
+ (parse_llvm_outputs): Add function to parse and collect llvm asm
+ outputs.
+ (parse_llvm_inputs): Likewise with inputs.
+ (parse_llvm_clobbers): Add function to parse llvm asm clobbers.
+ (parse_llvm_options): Add function to parse llvm asm options.
+ (parse_llvm_asm): Add function to parse llvm asm.
+ * expand/rust-macro-builtins-asm.h (class LlvmAsmContext): Add context
+ for llvm asm parser.
+ (parse_llvm_outputs): Add function prototype.
+ (parse_llvm_inputs): Likewise.
+ (parse_llvm_clobbers): Likewise.
+ (parse_llvm_options): Likewise.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Lower AST llvm
+ asm node to HIR.
+ * hir/rust-ast-lower-expr.h: Add function prototype.
+ * hir/rust-hir-dump.cc (Dump::visit): Add visit function.
+ * hir/rust-hir-dump.h: Add function prototype.
+ * hir/tree/rust-hir-expr-abstract.h: Add HIR llvm asm node kind.
+ * hir/tree/rust-hir-expr.h (struct LlvmOperand): Add LlvmOperand type
+ to represent input and outputs.
+ (class LlvmInlineAsm): Add LlvmInlineAsm hir node.
+ * hir/tree/rust-hir-full-decls.h (class LlvmInlineAsm): Add
+ LlvmInlineAsm hir node forward declaration.
+ * hir/tree/rust-hir-visitor.h: Add visit functions for LlvmInlineAsm
+ hir node.
+ * hir/tree/rust-hir.cc (LlvmInlineAsm::accept_vis): Add hir node
+ visitor related functions.
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
+ Type check input and output operands.
+ * typecheck/rust-hir-type-check-expr.h: Add function prototype.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Visit input and
+ output operand expressions.
+ * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Resolve input
+ and output expressions.
+ * resolve/rust-ast-resolve-expr.h: Add function prototypes.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Make visitor
+ unreachable.
+ * ast/rust-ast-collector.h: Add visit for LlvmInlineAsmNode.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Add visit
+ function for the default ast visitor.
+ * ast/rust-ast-visitor.h: Add function prototype.
+ * ast/rust-ast.cc (LlvmInlineAsm::accept_vis): Add accept_vis to
+ LlvmInlineAsm node.
+ * ast/rust-ast.h: Add LlvmInlineAsm node kind.
+ * ast/rust-expr.h (class LlvmInlineAsm): Add LlvmInlineAsm node.
+ * expand/rust-derive.h: Add visit function for LlvmInlineAsm node.
+ * expand/rust-macro-builtins-asm.cc (MacroBuiltin::llvm_asm_handler):
+ Add handler for llvm inline assembly nodes.
+ (parse_llvm_asm): Add function to parse llvm assembly nodes.
+ * expand/rust-macro-builtins-asm.h (parse_llvm_asm): Add function
+ prototypes.
+ * expand/rust-macro-builtins.cc (inline_llvm_asm_maker): Add macro
+ transcriber.
+ * expand/rust-macro-builtins.h: Add transcriber function prototype.
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Add visit
+ function for LlvmInlineAsm node.
+ * hir/rust-ast-lower-base.h: Add visit function prototype.
+ * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Add visit
+ function for LlvmInlineAsm node.
+ * resolve/rust-ast-resolve-base.h: Add visit function prototype.
+
+2025-04-28 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * expand/rust-macro-builtins-asm.cc (parse_asm_arg): Emit error
+ message.
+
+2025-04-28 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): add diagnostic
+ * typecheck/rust-tyty.cc (BaseType::contains_infer): new helper to grab first infer var
+ * typecheck/rust-tyty.h: prototype
+
+2025-04-28 Philip Herron <herron.philip@googlemail.com>
+
+ * rust-gcc.cc (arithmetic_or_logical_expression): Ensure this is an integer
+
+2025-04-28 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-hir-dump.cc (Dump::visit): add guard for optional label
+
+2025-04-28 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * typecheck/rust-tyty.h: Remove extra redundant comment.
+ * typecheck/rust-hir-type-check-base.cc: Update comment on repr
+ handling.
+
+2025-04-28 Zhi Heng <yapzhhg@gmail.com>
+
+ * typecheck/rust-hir-type-check-base.cc: Set enum representing
+ type properly if repr is an integer type.
+ * typecheck/rust-hir-type-check-item.cc: Update comments.
+
+2025-04-28 Zhi Heng <yapzhhg@gmail.com>
+
+ * typecheck/rust-tyty.h: Add new `ReprKind` enum to
+ `ReprOptions`.
+ * typecheck/rust-hir-type-check-base.cc: Handle setting of
+ `repr_kind`.
+ * typecheck/rust-hir-type-check-item.cc: New check for
+ zero-variant enums.
+
+2025-04-28 Philip Herron <herron.philip@googlemail.com>
+
+ * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): add null check
+ * hir/tree/rust-hir-item.h: add has_type helper
+ * typecheck/rust-hir-trait-resolve.cc (TraitItemReference::resolve_item):
+ add missing type checking
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.h: Add new manually_drop lang item.
+ * util/rust-lang-item.cc: Likewise.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-attribute-values.h: Add RUSTFMT value.
+ * util/rust-attributes.cc: Define the attribute.
+ * util/rust-attributes.h (enum CompilerPass): Add EXTERNAL variant.
+ * expand/rust-macro-builtins.cc: Fix formatting.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc (Early::visit_attributes): Remove assertion.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-attribute-values.h: Add missing attributes.
+ * util/rust-attributes.cc: Likewise.
+ * util/rust-attributes.h (enum CompilerPass): Mention adding something for const
+ functions.
+
+2025-04-14 beamandala <mandalapubhavesh@gmail.com>
+
+ * expand/rust-macro-builtins.cc (MacroBuiltin::builtin_transcribers):
+ Add entry for track_caller.
+ * util/rust-attribute-values.h: add `TRACK_CALLER` attribute.
+ * util/rust-attributes.cc: add `track_caller` attribute definition.
+
+2025-04-14 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/rust-const-checker.cc
+ (ConstChecker::visit): Visit the enum items of enums.
+ * resolve/rust-ast-resolve-item.cc
+ (ResolveItem::visit): Resolve enum discriminants during nr1.0.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-macro-builtins-format-args.cc (format_args_parse_arguments): Improve safety,
+ allow extra commas after end of argument list.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-macro-expand.cc (MacroExpander::expand_decl_macro): Call into
+ TokenTreeDesugar.
+ * expand/rust-token-tree-desugar.cc: New file.
+ * expand/rust-token-tree-desugar.h: New file.
+ * Make-lang.in: Compile them.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-macro-expand.cc (MacroExpander::match_n_matches): Do not
+ insert fragments and substack fragments if the matcher failed.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * rust-session-manager.cc (Session::compile_crate): Call the visitor later in the pipeline.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast.h (DelimTokenTree::get_locus): New function.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-expr.h (class RangeExpr): Add empty outer attributes and allow getting them
+ and setting them.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Return if module
+ is unloaded.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * typecheck/rust-hir-type-check-expr.cc (is_default_fn): New.
+ (emit_ambiguous_resolution_error): New.
+ (handle_multiple_candidates): Properly handle multiple candidates in
+ the case of specialization.
+ (TypeCheckExpr::visit): Call `handle_multiple_candidates`.
+
+2025-04-14 Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR rust/119342
+ * rust-gcc.cc (block): Add comment on why chaining
+ the variables of the scope toether.
+
+2025-04-14 Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR rust/119341
+ * rust-gcc.cc (function_type): Use range fors.
+ (function_type_variadic): Likewise.
+ (fill_in_fields): Likewise.
+ (statement_list): Likewise.
+ (block): Likewise.
+ (block_add_statements): Likewise.
+ (function_set_parameters): Likewise.
+ (write_global_definitions): Likewise.
+
+2025-04-14 Andrew Pinski <quic_apinski@quicinc.com>
+
+ * rust-gcc.cc (Bvariable::get_tree): Use error_operand_p.
+ (pointer_type): Likewise.
+ (reference_type): Likewise.
+ (immutable_type): Likewise.
+ (function_type): Likewise.
+ (function_type_variadic): Likewise.
+ Cleanup the check for receiver.type first.
+ (function_ptr_type): Use error_operand_p.
+ (fill_in_fields): Likewise.
+ (fill_in_array): Likewise.
+ (named_type): Likewise.
+ (type_size): Likewise.
+ (type_alignment): Likewise.
+ (type_field_alignment): Likewise.
+ (type_field_offset): Likewise.
+ (zero_expression): Likewise.
+ (float_constant_expression): Likewise.
+ (convert_expression): Likewise.
+ (struct_field_expression): Likewise.
+ (compound_expression): Likewise.
+ (conditional_expression): Likewise.
+ (negation_expression): Likewise.
+ (arithmetic_or_logical_expression): Likewise.
+ (arithmetic_or_logical_expression_checked): Likewise.
+ (comparison_expression): Likewise.
+ (lazy_boolean_expression): Likewise.
+ (constructor_expression): Likewise.
+ (array_constructor_expression): Likewise.
+ (array_index_expression): Likewise.
+ (call_expression): Likewise.
+ (init_statement): Likewise.
+ (assignment_statement): Likewise.
+ (return_statement): Likewise.
+ (exception_handler_statement): Likewise.
+ (if_statement): Likewise.
+ (compound_statement): Likewise.
+ Tighten up the code, removing t variable.
+ (statement_list): Use error_operand_p.
+ (block): Likewise.
+ (block_add_statements): Likewise.
+ (convert_tree): Likewise.
+ (global_variable): Likewise.
+ (global_variable_set_init): Likewise.
+ (local_variable): Likewise.
+ (parameter_variable): Likewise.
+ (static_chain_variable): Likewise.
+ (temporary_variable): Likewise.
+ (function): Likewise. Tighten up the code.
+ (function_defer_statement): Use error_operand_p.
+ (function_set_parameters): Use error_operand_p.
+ (write_global_definitions): Use error_operand_p.
+ Tighten up the code around the loop.
+
+2025-04-14 Andrew Pinski <quic_apinski@quicinc.com>
+
+ * rust-gcc.cc (is_floating_point): Use FLOAT_TYPE_P
+ instead of manually checking the type.
+
+2025-04-08 Matty Kuhn <matty.kuhn.1@gmail.com>
+
+ * ast/rust-ast.h: (AST::Attribute): add empty_input function
+ * checks/errors/rust-feature-gate.cc: (FeatureGate::visit): check for empty feature gate
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Update label
+ getter call.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
+ * ast/rust-ast.cc (BreakExpr::as_string): Likewise.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
+ * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Likewise.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise.
+ * ast/rust-expr.h: Add optional getter and rename label getter to
+ get_label_unchecked.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit):
+ Call unchecked getter.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit):
+ Likewise.
+ * ast/rust-ast.cc (ContinueExpr::as_string): Likewise.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
+ * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Likewise.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise.
+ * ast/rust-expr.h: Add new getter for the optional and rename getter
+ to get_label_unchecked.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_loop_label): Change function
+ return type to expected.
+ (Parser::parse_labelled_loop_expr): Adapt call location to new return
+ type.
+ * parse/rust-parse.h (enum class): Update function prototype.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add call
+ to label resolution if there is one label.
+ (Late::resolve_label): Look for labels and emit an error message on
+ failure.
+ * resolve/rust-late-name-resolver-2.0.h: Add function prototypes.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit):
+ Change error message to match rustc.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::self_ref_param): Remove error state
+ and use optional.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Check label
+ before visiting.
+ * ast/rust-ast.cc (ContinueExpr::as_string): Retrieve label value.
+ (Lifetime::as_string): Retrieve lifetime value.
+ (ReferenceType::as_string): Likewise.
+ (SelfParam::as_string): Likewise.
+ * ast/rust-ast.h: Remove lifetime and LifetimeParam error state.
+ * ast/rust-desugar-for-loops.cc (DesugarForLoops::DesugarCtx::make_break_arm):
+ Use optional instead of error state.
+ * ast/rust-expr.h (class ContinueExpr): Make label optional.
+ * ast/rust-item.h (class SelfParam): Make lifetime optional.
+ * ast/rust-type.h (class ReferenceType): Likewise.
+ * backend/rust-compile-base.cc: Use optional for self param instead
+ of error state.
+ * backend/rust-compile-base.h: Update function prototype.
+ * expand/rust-derive-clone.cc (DeriveClone::clone_fn): Use optional.
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_self): Lower
+ lifetime only if it exists.
+ * hir/rust-ast-lower-block.h: Lower loop label only if it exists.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
+ * hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): Remove
+ references to error state.
+ (ASTLowerTraitItem::visit): Lower self param only if it exists.
+ * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Use nullopt
+ for default value instead of SelfParam error state.
+ * hir/rust-ast-lower.cc (ASTLoweringExprWithBlock::visit): Lower label
+ only if it exists.
+ * hir/rust-hir-dump.cc (Dump::do_traitfunctiondecl): Print self only if
+ it exists.
+ (Dump::visit): Liewise.
+ * hir/tree/rust-hir-bound.h: Remove error state.
+ * hir/tree/rust-hir-expr.cc (ContinueExpr::ContinueExpr): Use optional
+ in constructor for loop label.
+ (BreakExpr::BreakExpr): Likewise.
+ * hir/tree/rust-hir-expr.h (class ContinueExpr): Remove error state
+ implementation.
+ (class BreakExpr): Likewise.
+ * hir/tree/rust-hir-generic-param.h: Likewise.
+ * hir/tree/rust-hir-item.cc (SelfParam::SelfParam): Make lifetime
+ optional.
+ (Function::Function): Make self param optional.
+ * hir/tree/rust-hir-item.h (class Function): Likewise.
+ * hir/tree/rust-hir-type.cc (ReferenceType::ReferenceType): Make
+ lifetime optional.
+ * hir/tree/rust-hir-type.h (class ReferenceType): Likewise.
+ * hir/tree/rust-hir.cc (ContinueExpr::as_string): Use new getter.
+ (BreakExpr::as_string): Likewise.
+ (Lifetime::as_string): Likewise.
+ (ReferenceType::as_string): Likewise.
+ (TraitFunctionDecl::as_string): Likewise.
+ (SelfParam::as_string): Remove error state checking.
+ * parse/rust-parse-impl.h (Parser::parse_generic_param): Adapt to
+ optional.
+ (Parser::parse_lifetime_params): Likewise.
+ (Parser::parse_lifetime_params_objs): Likewise.
+ (Parser::parse_lifetime_param): Likewise.
+ (Parser::parse_lifetime_where_clause_item): Likewise.
+ (Parser::parse_type_param_bound): Likewise.
+ (Parser::parse_lifetime_bounds): Likewise.
+ (Parser::parse_path_generic_args): Likewise.
+ (Parser::parse_self_param): Likewise.
+ (Parser::parse_break_expr): Likewise.
+ (Parser::parse_continue_expr): Likewise.
+ (Parser::parse_reference_type_inner): Likewise.
+ * parse/rust-parse.h (class ParseLifetimeParamError): Add new class for
+ lifetime param parsing errors.
+ (class ParseLifetimeError): Add new class for lifetime parsing errors.
+ (enum ParseSelfError): Add new class for self param parsing errors.
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItem::visit):
+ Use unchecked getter in checked context. And make anonymous region.
+ * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn):
+ Likewise.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Add
+ check for loop label before visiting it.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-expr.h: Remove error getter and constructor.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::block): Call with a nullopt instead
+ of an error loop label.
+ (WhileLetLoopExpr::as_string): Use getter function and adapt to
+ newtype.
+ * ast/rust-ast.cc (WhileLoopExpr::as_string): Likewise.
+ (LoopExpr::as_string): Likewise.
+ (BreakExpr::as_string): Likewise.
+ (ForLoopExpr::as_string): Likewise.
+ * ast/rust-expr.h (class BlockExpr): Make loop label optional.
+ (class BreakExpr): Likewise.
+ * expand/rust-derive-clone.cc (DeriveClone::clone_fn): Use nullopt.
+ * expand/rust-derive-debug.cc (DeriveDebug::stub_debug_fn): Likewise.
+ * expand/rust-derive-default.cc (DeriveDefault::default_fn): Likewise.
+ * expand/rust-derive-eq.cc: Likewise.
+ * parse/rust-parse-impl.h (Parser::parse_block_expr): Use optional
+ for arguments.
+ (Parser::parse_loop_expr): Likewise.
+ (Parser::parse_while_loop_expr): Likewise.
+ (Parser::parse_while_let_loop_expr): Likewise.
+ (Parser::parse_for_loop_expr): Likewise.
+ (Parser::parse_labelled_loop_expr): Likewise.
+ (Parser::parse_loop_label): Return an optional.
+ * parse/rust-parse.h: Update function prototype and use nullopt for
+ default values.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Change default
+ visit order.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Visit loop label
+ only if it exists.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * hir/rust-ast-lower.cc (ASTLoweringBlock::visit): Lower label only if
+ it exists.
+ * hir/tree/rust-hir-expr.cc (BlockExpr::BlockExpr): Make loop label
+ optional.
+ (BaseLoopExpr::BaseLoopExpr): Likewise.
+ (LoopExpr::LoopExpr): Likewise.
+ (WhileLoopExpr::WhileLoopExpr): Likewise.
+ * hir/tree/rust-hir-expr.h: Use optional for lifetime and labels.
+ * hir/tree/rust-hir.cc (WhileLoopExpr::as_string): Use getter.
+ (WhileLetLoopExpr::as_string): Likewise.
+ (LoopExpr::as_string): Likewise.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Resolve labels.
+ * resolve/rust-late-name-resolver-2.0.h: Add visit function prototype
+ for loop labels.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * util/expected.h: Use gcc_unreachable within gcc context.
+
+2025-04-08 Sri Ganesh Thota <sriganeshthota12345@gmail.com>
+
+ * resolve/rust-ast-resolve-base.h (redefined_error): created a function for
+ rust_error_at for redefined at multiple times.
+ * resolve/rust-ast-resolve-implitem.h: changed rust_error_at to redefined_error.
+ * resolve/rust-ast-resolve-stmt.cc (ResolveStmt::visit): changed rust_error_at to
+ redefined_error.
+ * resolve/rust-ast-resolve-stmt.h: changed rust_error_at to redefined_error.
+ * resolve/rust-ast-resolve-toplevel.h: changed rust_error_at to redefined_error.
+
+2025-04-08 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-visitor.cc
+ (DefaultASTVisitor::visit): Remove explicit visitation of a
+ function's self parameter, as if it exists it'll be visited as
+ one of the function parameters.
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-typecheck-context.cc (TypeCheckContext::lookup_lifetime): emit error
+
+2025-04-08 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast.cc (Function::Function): Rename is_default -> has_default.
+ (Function::operator=): Likewise.
+ * ast/rust-item.h (class Function): Add `is_default` method.
+ * hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): Lower default qualifier.
+ * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Likewise.
+ * hir/tree/rust-hir-item.cc (Function::Function): Add `is_default` member.
+ (Function::operator=): Likewise.
+ * hir/tree/rust-hir-item.h (enum class Defaultness): New enum.
+ (class Function): Use it.
+
+2025-04-08 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * checks/errors/rust-feature.cc (Feature::create): Handle `#![feature(min_specialization)]`.
+ * checks/errors/rust-feature.h: Likewise.
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): fix error msg
+ * typecheck/rust-substitution-mapper.cc (SubstMapper::Resolve): add validation
+ (SubstMapper::valid_type): new check
+ (SubstMapper::visit): check if can resolve
+ * typecheck/rust-substitution-mapper.h: new prototype
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-base.cc (HIRCompileBase::address_expression): allow optional type
+ * backend/rust-compile-base.h: update prototype
+ * backend/rust-compile-expr.cc (CompileExpr::visit): update borrow expr
+ * backend/rust-compile-extern.h: remove unused debug
+ * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): update usage
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): lower raw ref
+ * hir/tree/rust-hir-expr.cc (BorrowExpr::BorrowExpr): add flag for raw ref
+ * hir/tree/rust-hir-expr.h (class BorrowExpr): add new raw ref field
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): add handle for raw ref
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): emit error
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): new argument
+ * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::TypeCheckBase): new helper
+ * typecheck/rust-hir-type-check-base.h: new helper prototype
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit):
+ remove comment out code
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_root_path): check for null
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path): likewise
+ (TypeResolveGenericParam::Resolve): new args
+ (TypeResolveGenericParam::ApplyAnyTraitBounds): new helper
+ (TypeResolveGenericParam::apply_trait_bounds): new field
+ (TypeResolveGenericParam::visit): update
+ * typecheck/rust-hir-type-check-type.h: new args
+ * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn): reuse helper
+ * typecheck/rust-type-util.cc (query_type): check for recursive query
+ * typecheck/rust-tyty-subst.cc (SubstitutionParamMapping::SubstitutionParamMapping):
+ remove const
+ (SubstitutionParamMapping::get_generic_param): likewise
+ * typecheck/rust-tyty-subst.h: likewise
+ * typecheck/rust-tyty-variance-analysis.cc (GenericTyVisitorCtx::process_type): likewise
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-base.cc: new flag is_root_item
+ * backend/rust-compile-base.h: update prototype
+ * backend/rust-compile-implitem.cc (CompileTraitItem::visit): update call
+ * backend/rust-compile-implitem.h: remove old debug internal error
+ * backend/rust-compile-item.cc (CompileItem::visit): update call
+ * backend/rust-compile-item.h: remove old debug
+ * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): update calls
+ * backend/rust-compile.cc: likewise
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_path_to_trait):
+ remove assertion and error
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-base.cc: remove assertion
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * rust-gcc.cc (arithmetic_or_logical_expression): unwrap const decls
+
+2025-04-08 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.h
+ (ForeverStack::ForeverStack): Initialize extern_prelude.
+ (ForeverStack::resolve_path): Add parameter
+ has_opening_scope_resolution.
+ (ForeverStack::extern_prelude): Add field.
+ * resolve/rust-forever-stack.hxx: Include rust-edition.h.
+ (ForeverStacl::resolve_path): Handle global paths (paths with an
+ opening scope resolution operator).
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Handle global paths.
+ * resolve/rust-name-resolution-context.h
+ (NameResolutionContext::resolve_path): Handle global paths.
+
+2025-04-08 Ryutaro Okada <1015ryu88@gmail.com>
+
+ * backend/rust-compile-resolve-path.cc: Evaluate the enum's discriminant in a const context
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path):
+ catch nullptr root_tyty
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::parse_repr_options):
+ check for null and empty and add missing delete call
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-tyty-subst.h: check for min range
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::parse_repr_options): check for input
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-hir-dump.cc (Dump::visit): check has type
+ * hir/tree/rust-hir-type.cc (BareFunctionType::BareFunctionType): likewise
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-constexpr.cc (eval_store_expression): turn this back on
+
+2025-03-31 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * expand/rust-macro-builtins-log-debug.cc:
+ Add newline to end of file.
+
+2025-03-31 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.h
+ (ForeverStack::get_prelude): Rename to...
+ (ForeverStack::get_lang_prelude): ...here.
+ (ForeverStack::prelude): Rename to...
+ (ForeverStack::lang_prelude): ...here.
+ (ForeverStack::ForeverStack): Handle renames.
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::push_inner): Likewise.
+ (ForeverStack::resolve_segments): Likewise.
+ (ForeverStack::resolve_path): Likewise.
+ (ForeverStack::get_prelude): Rename to...
+ (ForeverStack::get_lang_prelude): ...here and handle renames.
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Handle renames.
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-context.h: only push named types
+ * backend/rust-compile-type.cc (TyTyResolveCompile::visit): run the type hasher
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): check for Expr trait
+ * hir/rust-hir-dump.cc (Dump::visit): expr is optional
+
+2025-03-31 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-forever-stack.hxx: Add a new specialized function
+ to retrieve the last "real" segment depending on the namespace.
+ * resolve/rust-forever-stack.h: Add new function prototype.
+ * resolve/rust-early-name-resolver-2.0.cc (Early::finalize_rebind_import):
+ Set declared name according to the selected segment, if there is a self
+ suffix in the use declaration then select the previous segment.
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-base.cc (HIRCompileBase::unit_expression): pass ctx
+ * backend/rust-compile-base.h: cant be static
+ * backend/rust-compile-intrinsic.cc (try_handler_inner): pass ctx
+ * backend/rust-compile-type.cc
+ (TyTyResolveCompile::get_unit_type): update to grab the first locus
+ (TyTyResolveCompile::visit): pass ctx
+ * backend/rust-compile-type.h: likewise
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-dot-operator.cc:
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * resolve/rust-ast-resolve-path.cc (ResolvePath::resolve_path): check for super mid path
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-base.cc (HIRCompileBase::address_expression): new helper constexpr
+ * backend/rust-compile-base.h: prototype
+ * backend/rust-compile-type.cc (TyTyResolveCompile::visit): call constexpr helper
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::resolve_impl_block_substitutions):
+ Track the polarity
+ * typecheck/rust-tyty-bounds.cc (TypeBoundPredicate::validate_type_implements_this):
+ new validator
+ * typecheck/rust-tyty.h: new prototypes
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::array_value_expr): add value chk for array expr
+
+2025-03-31 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-trait-reference.h: add default infer arg
+ * typecheck/rust-hir-trait-resolve.cc: dont add new infer vars
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): dont infer
+
+2025-03-31 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/rust-ast-validation.cc
+ (ASTValidation::visit): Allow constant items lacking expressions
+ if and only if they're associated with a trait definition, not a
+ trait implementation.
+
+2025-03-31 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * hir/rust-ast-lower-base.cc
+ (ASTLoweringBase::lower_literal): Lower raw string literals into
+ normal string literals.
+
+2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * checks/errors/borrowck/ffi-polonius/Cargo.lock: Regenerate.
+ * checks/errors/borrowck/ffi-polonius/Cargo.toml: Update to use source patching instead of
+ vendoring, lower edition to 2018.
+ * checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml: Change edition to 2018.
+ * checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs: Remove uses of unstable
+ feature.
+ * checks/errors/borrowck/ffi-polonius/.cargo/config.toml: Removed.
+
+2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/tree/rust-hir-stmt.h (class LetStmt): Add optional diverging else expression.
+ * hir/tree/rust-hir-stmt.cc: Likewise.
+ * hir/rust-ast-lower-stmt.cc (ASTLoweringStmt::visit): Add handling for lowering
+ diverging else.
+
+2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-ast-resolve-stmt.h: Add handling for diverging else.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise.
+
+2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Add handling for diverging else
+ expression.
+
+2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_let_stmt): Add new parsing in case of `else` token.
+
+2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-stmt.h (class LetStmt): Add optional expression for diverging else.
+ * ast/rust-ast-builder.cc (Builder::let): Use new API.
+
+2025-03-26 Iain Sandoe <iain@sandoe.co.uk>
+
+ * metadata/rust-export-metadata.cc
+ (PublicInterface::write_to_path): Use 'lbasename()' instead of
+ 'basename()'.
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-path-probe.cc: update call
+ * typecheck/rust-hir-trait-reference.cc (TraitReference::lookup_trait_item): track predicate
+ (TraitReference::is_equal): likewise
+ (TraitReference::is_object_safe): likewise
+ (TraitReference::satisfies_bound): likewise
+ * typecheck/rust-hir-trait-reference.h: likewise
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): likewise
+ * typecheck/rust-tyty-bounds.cc (TypeBoundPredicate::TypeBoundPredicate): track super traits
+ (TypeBoundPredicate::operator=): likewise
+ (TypeBoundPredicate::apply_generic_arguments): ensure we apply to super predicates
+ (TypeBoundPredicateItem::operator=): take copy of parent predicate
+ (TypeBoundPredicateItem::error): pass error instead of nullptr
+ (TypeBoundPredicateItem::is_error): update to no longer check for nullptr
+ (TypeBoundPredicateItem::get_parent): updated
+ (TypeBoundPredicateItem::get_tyty_for_receiver): likewise
+ (TypeBoundPredicate::get_associated_type_items): likewise
+ * typecheck/rust-tyty-bounds.h (class TypeBoundPredicateItem): move
+ * typecheck/rust-tyty-subst.cc: flag to handle placeholder Self on traits
+ * typecheck/rust-tyty-subst.h (class TypeBoundPredicateItem): likewise
+ * typecheck/rust-tyty.h (class TypeBoundPredicateItem): refactored
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Add visitor for StructExprFieldIdentifier.
+ * resolve/rust-late-name-resolver-2.0.h
+ (Late::visit): Likewise.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Make sure to return early after a resolution
+ error, improve the resolution error message, fix a typo, handle
+ ambiguous resolutions, and remove an old comment.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-ast-resolve-expr.cc
+ (ResolveExpr::visit): Modify error message.
+ * resolve/rust-ast-resolve-implitem.h
+ (ResolveToplevelImplItem::visit): Likewise.
+ (ResolveTopLevelTraitItems::visit): Likewise.
+ (ResolveToplevelExternItem::visit): Likewise.
+ * resolve/rust-ast-resolve-stmt.cc
+ (ResolveStmt::visit): Likewise.
+ * resolve/rust-ast-resolve-stmt.h
+ (ResolveStmt::visit): Likewise.
+ * resolve/rust-ast-resolve-toplevel.h
+ (ResolveTopLevel::visit): Likewise.
+ * resolve/rust-ast-resolve-type.h
+ (ResolveGenericParams::visit): Likewise.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-visitor.cc
+ (DefaultASTVisitor::visit): Make sure to always visit the struct
+ name.
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Avoid visiting the struct name twice.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * expand/rust-derive-clone.cc
+ (DeriveClone::clone_impl): Avoid using the same node id multiple
+ times.
+ (DeriveClone::clone_enum_identifier): Likewise.
+ (DeriveClone::clone_enum_tuple): Likewise.
+ * expand/rust-derive-copy.cc
+ (DeriveCopy::copy_impl): Likewise.
+ * resolve/rust-ast-resolve-item.cc
+ (flatten_list): Likewise.
+ * resolve/rust-ast-resolve-path.cc
+ (ResolvePath::resolve_path): Prevent reinsertion of resolutions.
+ * resolve/rust-ast-resolve-type.cc
+ (ResolveRelativeTypePath::go): Likewise.
+ * typecheck/rust-hir-type-check-expr.cc
+ (TypeCheckExpr::resolve_fn_trait_call): Likewise.
+ * resolve/rust-name-resolver.cc
+ (Resolver::insert_resolved_name): Catch multiple resolution
+ insertions.
+ (Resolver::insert_resolved_type): Likewise.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-ast-resolve-path.cc
+ (ResolvePath::resolve_path): Adjust the error message for a lower
+ self segment in the middle of a path.
+ * resolve/rust-ast-resolve-type.cc
+ (ResolveRelativeTypePath::go): Likewise.
+
+2025-03-24 Ryutaro Okada <1015ryu88@gmail.com>
+
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit):
+ emit an error for type or const parameters on foreign items
+
+2025-03-24 Liam Naddell <liamnprg@gmail.com>
+
+ * resolve/rust-forever-stack.h (ForeverStack): Add a dedicated prelude node for
+ the Language prelude
+ * resolve/rust-forever-stack.hxx (ForeverStack): Add support code for the
+ prelude node
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Move
+ language prelude builtins to the prelude context
+ * resolve/rust-name-resolution-context.cc
+ (NameResolutionContext::scoped): Add code for handling
+ the prelude corner case
+ * resolve/rust-rib.h (Rib::Kind): Add a special Prelude rib type
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-forever-stack.hxx: Fix the id comparison.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-forever-stack.hxx: Insert a new segment with the crate's
+ name as canonical's path prefix.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * util/rust-hir-map.cc (Mappings::lookup_crate_num): Add function to
+ retrieve crate number from it's node id.
+ (Mappings::node_is_crate): change function with call to
+ lookup_crate_num to avoid looping through all crates.
+ (Mappings::insert_ast_crate): Populate node id to crate number map.
+ * util/rust-hir-map.h: Change function prototype.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-finalize-imports-2.0.cc (FinalizeImports::FinalizeImports):
+ Remove constructor.
+ (FinalizeImports::go): Remove function.
+ (FinalizeImports::visit): Likewise.
+ * resolve/rust-finalize-imports-2.0.h (class FinalizeImports): Remove
+ FinalizeImports class.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc (Early::Early): Move the
+ top level visitor from the function scope to attributes.
+ (Early::go): Remove top level visitor creation and adapt calling code.
+ Remove call to mapping resolution and import finalization.
+ (Early::finalize_simple_import): Move the finalization from it's
+ visitor.
+ (Early::finalize_glob_import): Likewise.
+ (Early::finalize_rebind_import): Likewise.
+ (Early::visit): Add mapping resolution and finalization in
+ UseDeclaration visitor function.
+ * resolve/rust-finalize-imports-2.0.cc (finalize_simple_import): Move
+ function.
+ (finalize_glob_import): Likewise.
+ (finalize_rebind_import): Likewise.
+ (FinalizeImports::visit): Remove call to finalizers.
+ * resolve/rust-early-name-resolver-2.0.h (class Early): Add top level
+ attribute.
+ * resolve/rust-finalize-imports-2.0.h: Add function prototypes.
+ * resolve/rust-toplevel-name-resolver-2.0.h: Change getter return type
+ to reference.
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::ResolveHirItem): new helper
+ * typecheck/rust-hir-trait-resolve.h: add helper prototype
+ * typecheck/rust-type-util.cc (query_type): add debug
+ * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): check for recursion
+ * typecheck/rust-tyty.cc (VariantDef::is_equal): fix is equal check
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): track DefId of origin
+ * typecheck/rust-tyty.cc (BaseType::monomorphized_clone): likewise
+ (ADTType::ADTType): likewise
+ (ADTType::get_id): likewise
+ (ADTType::clone): likewise
+ * typecheck/rust-tyty.h: likewise
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-resolve-path.cc (ResolvePathRef::Compile): remove visitor
+ (ResolvePathRef::ResolvePathRef): likewise
+ (ResolvePathRef::visit): likewise
+ * backend/rust-compile-resolve-path.h (class ResolvePathRef): likewise
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * backend/rust-compile-intrinsic.cc
+ (assume_handler): Fix copy/paste error.
+ * typecheck/rust-hir-type-check-pattern.cc
+ (TypeCheckPattern::visit): Fix spelling mistake.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-rib.cc (Rib::Definition::to_string): Add enum variant
+ status.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-forever-stack.h: Add new function to insert enum
+ variants and add argument to resolver's get function to explicitely
+ skip enum variants.
+ * resolve/rust-forever-stack.hxx: Update function
+ definitions.
+ * resolve/rust-name-resolution-context.cc (NameResolutionContext::insert_variant):
+ Add function to insert enum variants.
+ * resolve/rust-name-resolution-context.h: Add function's prototype.
+ * resolve/rust-rib.cc (Rib::Definition::Definition): Add new boolean to
+ hint at enum variant provenance.
+ (Rib::Definition::is_variant): New getter for variant status.
+ (Rib::Definition::Shadowable): Update constructor to opt out of enum
+ variants.
+ (Rib::Definition::Globbed): Likewise.
+ (Rib::Definition::NonShadowable): Change constructor to forward enum
+ variant provenance status.
+ * resolve/rust-rib.h: Update function prototypes.
+ * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::insert_enum_variant_or_error_out):
+ Add function to insert enum variants in the name resolver.
+ (TopLevel::visit): Update several enum variant's visitor function
+ with the new enum variant name resolving code.
+ * resolve/rust-toplevel-name-resolver-2.0.h: Update function
+ prototypes.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-forever-stack.hxx: Output rib kind.
+ * resolve/rust-rib.h: Add function to get string representation from
+ a rib kind.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.h
+ (ForeverStack::ForeverStack): Set the node id of the root node
+ to that of the current crate.
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::find_starting_point): Use the node id of the root
+ node during resolution of crate segments.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-macro-expand.cc: Use new SubstituteCtx API.
+ * expand/rust-macro-expand.h: Likewise.
+ * expand/rust-macro-substitute-ctx.cc: Implement proper expansion of $crate.
+ * expand/rust-macro-substitute-ctx.h: Adapt APIs to take macro definition when
+ substituting.
+ * util/rust-hir-map.cc (Mappings::insert_macro_def): Store crate information when
+ inserting macro definition in mappings.
+ (Mappings::lookup_macro_def_crate): New.
+ * util/rust-hir-map.h: Adapt mappings to store crate in which macros were defined.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Call DefaultResolver::visit earlier, in order to
+ ensure it is called even if Late::visit returns early.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * util/rust-edition.cc: New file.
+ * util/rust-edition.h: New file.
+ * Make-lang.in: Add rust-edition.o to the object list.
+ * ast/rust-pattern.cc: Remove inclusion of
+ rust-session-manager.h.
+ * expand/rust-macro-expand.cc: Likewise.
+ * expand/rust-macro-builtins-helpers.h: Likewise.
+ * expand/rust-macro-builtins-include.cc: Include
+ rust-session-manager.h.
+ * expand/rust-macro-builtins-utility.cc: Likewise.
+ * lex/rust-lex.cc: Include rust-edition.h instead of
+ rust-session-manager.h.
+ (Lexer::classify_keyword): Use get_rust_edition instead of
+ Session and CompileOptions.
+ * parse/rust-parse-impl.h: Include rust-edition.h instead of
+ rust-session-manager.h.
+ (Parser::parse_async_item): Use get_rust_edition instead of
+ Session and CompileOptions.
+ * checks/errors/rust-feature.h: Include rust-edition.h instead
+ of rust-session-manager.h.
+ (class Feature): Use Rust::Edition instead of
+ Rust::CompileOptions::Edition.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * rust-session-manager.cc (Session::compile_crate): Call DesugarQuestionMark::go().
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/rust-ast-lower-base.cc: Adapt functions for ErrorPropagationExpr and MacroInvocation.
+ * hir/rust-ast-lower-base.h: Mark them as final.
+ * hir/rust-ast-lower-expr.cc: Remove previous definition for those overrides.
+ * hir/rust-ast-lower-expr.h: Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * Make-lang.in: Compile it.
+ * ast/rust-desugar-question-mark.cc: New file.
+ * ast/rust-desugar-question-mark.h: New file.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc
+ (Early::visit): Adjust error produced when macro resolution
+ fails.
+ * resolve/rust-early-name-resolver.cc
+ (EarlyNameResolver::visit): Likewise.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::find_starting_point): Stop when hitting a lang
+ item segment.
+ (ForeverStack::resolve_segments): Resolve lang item segments.
+ (ForeverStacl::resolve_path): Handle single segment lang item
+ paths and add comment.
+ * util/rust-unwrap-segment.cc
+ (unwrap_segment_get_lang_item): Add.
+ * util/rust-unwrap-segment.h
+ (unwrap_segment_get_lang_item): Add.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-expand-visitor.cc (ExpandVisitor::visit): Correctly visit the generic args
+ of a generic type path segment.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-early-name-resolver.cc: Remove definitions.
+ * resolve/rust-early-name-resolver.h: Remove declarations.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Add base implementation
+ for visitor.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc:
+ Include rust-attribute-values.h.
+ (Early::visit): If a module has a macro_use attribute, avoid
+ pushing a new textual macro scope.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-ast-resolve-type.cc
+ (ResolveRelativeTypePath::go): Adjust error message to match
+ the 2.0 name resolver.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/rust-hir-dump.cc: Check unique_ptr members are present before
+ visiting them.
+ * hir/tree/rust-hir-path.h: Add `has_{type, trait}` methods to
+ QualifiedPathInType.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * Make-lang.in: Compile it.
+ * expand/rust-derive.cc (DeriveVisitor::derive): Call it.
+ * expand/rust-derive-hash.cc: New file.
+ * expand/rust-derive-hash.h: New file.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-debug.cc (ptrify): Remove function.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::statementify): New.
+ (Builder::function): Add generic params optional argument.
+ (Builder::path_in_expression): Add opening_scope_resolution optional argument.
+ (Builder::block): Add function for creating empty blocks.
+ (Builder::generic_type_param): New.
+ * ast/rust-ast-builder.h (ptrify): New.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast.h
+ (SingleASTNode::take_trait_item): Remove.
+ (SingleASTNode::take_impl_item): Remove.
+ (SingleASTNode::take_trait_impl_item): Remove.
+ * expand/rust-expand-visitor.cc
+ (ExpandVisitor::visit): Replace calls to aforementioned
+ functions with calls to SingleASTNode::take_assoc_item.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * expand/rust-expand-visitor.cc
+ (ExpandVisitor::visit): Override DefaultASTVisitor in order to
+ expand a module's items, rather than directly visit them.
+ * expand/rust-expand-visitor.h
+ (ExpandVisitor::visit): Add override.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-path.h
+ (PathInExpression::get_pattern_node_id): Remove.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-eq.cc: Copy `Eq` typepath.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-eq.cc: Adapt functions to return two generated impls.
+ * expand/rust-derive-eq.h: Likewise.
+ * expand/rust-derive.cc (DeriveVisitor::derive): Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-partial-eq.cc: Adapt signatures to generate two impls.
+ * expand/rust-derive-partial-eq.h: Likewise.
+ * expand/rust-derive.cc (DeriveVisitor::derive): Adapt to multiple item generation.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive.cc (DeriveVisitor::derive): Return a vector of items.
+ * expand/rust-derive.h: Change return type.
+ * expand/rust-expand-visitor.cc: Insert all generated items into the AST.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-partial-eq.cc: New file.
+ * expand/rust-derive-partial-eq.h: New file.
+ * expand/rust-derive.cc (DeriveVisitor::derive): Call them.
+ * Make-lang.in: Compile them.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc: Cleanup implementation, avoid repetitions.
+ * expand/rust-derive-clone.h: Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::literal_bool): New method.
+ (Builder::comparison_expr): Likewise.
+ (Builder::boolean_operation): Likewise.
+ * ast/rust-ast-builder.h: Declare them.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::block): Change return type.
+ (Builder::loop): Use new APIs.
+ * ast/rust-ast-builder.h: Change return type of block functions.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive.cc (DeriveVisitor::derive): Call into DeriveEq.
+ * expand/rust-derive-eq.cc: New file.
+ * expand/rust-derive-eq.h: New file.
+ * Make-lang.in: Compile them.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): When visiting a PathInExpression instance, call
+ into DefaultResolver::visit, ensuring generic arguments are
+ visited.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-toplevel-name-resolver-2.0.cc
+ (TopLevel::visit): When visiting an external crate declaration,
+ handle failed crate name lookups. This can happen when
+ Session::load_extern_crate fails to load a crate during the
+ CfgStrip phase.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::resolve_segments): Add comments explaining
+ the behaviour of a while loop.
+
+2025-03-24 Benjamin Thos <benjamin.thos@epita.fr>
+
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
+ Add check on if-expr.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::find_starting_point): Be more careful about
+ applying ForeverStack::find_closest_module.
+ (ForeverStack::resolve_segments): Allow traversal into parent
+ nodes when not in a module node or root node, which
+ ForeverStack::find_starting_point previously made moot through
+ use of ForeverStack::find_closest_module. Also, when a child
+ node lookup fails when resolving in the type namespace, attempt
+ a rib lookup as a fallback.
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Avoid throwing a resolution error for type paths
+ when the typechecker may be able to finish the resolution. Also,
+ throw an error when a resolution is ambiguous.
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-type.cc (TyTyResolveCompile::visit): new tyty::OpaqueType
+ * backend/rust-compile-type.h: likewise
+ * checks/errors/borrowck/rust-bir-fact-collector.h: likewise
+ * checks/errors/borrowck/rust-bir-place.h: likewise
+ * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::check_base_type_privacy):
+ likewise
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise
+ * typecheck/rust-hir-type-check-type.h: likewise
+ * typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit): likewise
+ * typecheck/rust-substitution-mapper.h: likewise
+ * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::assemble_sized_builtin): likewise
+ * typecheck/rust-tyty-call.h: likewise
+ * typecheck/rust-tyty-cmp.h (class OpaqueCmp): likewise
+ * typecheck/rust-tyty-variance-analysis-private.h: likewise
+ * typecheck/rust-tyty-visitor.h: likewise
+ * typecheck/rust-tyty.cc (TypeKindFormat::to_string): likewise
+ (BaseType::is_unit): likewise
+ (BaseType::destructure): likewise
+ (BaseType::has_substitutions_defined): likewise
+ (BaseType::needs_generic_substitutions): likewise
+ (OpaqueType::OpaqueType): likewise
+ (OpaqueType::can_resolve): likewise
+ (OpaqueType::accept_vis): likewise
+ (OpaqueType::as_string): likewise
+ (OpaqueType::get_name): likewise
+ (OpaqueType::can_eq): likewise
+ (OpaqueType::clone): likewise
+ (OpaqueType::resolve): likewise
+ (OpaqueType::is_equal): likewise
+ (OpaqueType::handle_substitions): likewise
+ * typecheck/rust-tyty.h (enum TypeKind): likewise
+ (class OpaqueType): likewise
+ * typecheck/rust-unify.cc (UnifyRules::go): likewise
+ (UnifyRules::expect_inference_variable): likewise
+ (UnifyRules::expect_adt): likewise
+ (UnifyRules::expect_str): likewise
+ (UnifyRules::expect_reference): likewise
+ (UnifyRules::expect_pointer): likewise
+ (UnifyRules::expect_param): likewise
+ (UnifyRules::expect_array): likewise
+ (UnifyRules::expect_slice): likewise
+ (UnifyRules::expect_fndef): likewise
+ (UnifyRules::expect_fnptr): likewise
+ (UnifyRules::expect_tuple): likewise
+ (UnifyRules::expect_bool): likewise
+ (UnifyRules::expect_char): likewise
+ (UnifyRules::expect_int): likewise
+ (UnifyRules::expect_uint): likewise
+ (UnifyRules::expect_float): likewise
+ (UnifyRules::expect_isize): likewise
+ (UnifyRules::expect_usize): likewise
+ (UnifyRules::expect_placeholder): likewise
+ (UnifyRules::expect_projection): likewise
+ (UnifyRules::expect_dyn): likewise
+ (UnifyRules::expect_opaque): likewise
+ * typecheck/rust-unify.h: likewise
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * checks/errors/borrowck/rust-bir-builder-struct.h: remove HIR::ImplTraitTypeOneBound
+ * checks/errors/borrowck/rust-function-collector.h: likewise
+ * checks/errors/rust-const-checker.cc (ConstChecker::visit): likewise
+ * checks/errors/rust-const-checker.h: likewise
+ * checks/errors/rust-hir-pattern-analysis.cc (PatternChecker::visit): likewise
+ * checks/errors/rust-hir-pattern-analysis.h: likewise
+ * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): likewise
+ * checks/errors/rust-unsafe-checker.h: likewise
+ * hir/rust-ast-lower-type.cc (ASTLoweringType::translate): likewise
+ (ASTLoweringType::visit): likewise
+ * hir/rust-ast-lower-type.h: cleanup
+ * hir/rust-hir-dump.cc (Dump::visit): remove ImplTraitTypeOneBound
+ * hir/rust-hir-dump.h: likewise
+ * hir/tree/rust-hir-full-decls.h (class ImplTraitTypeOneBound): likewise
+ * hir/tree/rust-hir-type.h (class ImplTraitTypeOneBound): likewise
+ * hir/tree/rust-hir-visitor.h: likewise
+ * hir/tree/rust-hir.cc (ImplTraitTypeOneBound::as_string): likewise
+ (ImplTraitTypeOneBound::accept_vis): likewise
+ * resolve/rust-ast-resolve-type.cc (ResolveType::go): likewise
+ (ResolveType::visit): likewise
+ * resolve/rust-ast-resolve-type.h: add name resolution
+ * typecheck/rust-hir-type-check-type.h: likewise
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): improve error diag
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_self): add location mappings
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_root_path): check for self
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit): use new api
+ (ResolveItem::visit): likewise
+ (ResolveExternItem::visit): likewise
+ * resolve/rust-ast-resolve-stmt.h: likewise
+ * resolve/rust-ast-resolve-type.h (class ResolveGenericParam): remove
+ (class ResolveGenericParams): added new api
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-base.cc (walk_types_to_constrain): recursive walker
+ * typecheck/rust-tyty.cc (BaseType::get_subst_argument_mappings): new helper
+ * typecheck/rust-tyty.h: prototype
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-base.h: add flag
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise
+ * typecheck/rust-tyty-bounds.cc: new diagnostic
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): remove name resolution info
+ (TypeCheckType::resolve_root_path): likewise
+ * typecheck/rust-hir-type-check-type.h: likewise
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-type.cc (TyTyResolveCompile::get_implicit_enumeral_node_type):
+ use repr
+ (TyTyResolveCompile::visit): update prototype
+ * backend/rust-compile-type.h: likewise
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-intrinsic.cc (variant_count_handler): new intrinsic
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-intrinsic.cc (discriminant_value_handler): new handler
+ * typecheck/rust-hir-trait-resolve.cc (TraitItemReference::resolve_item): track the defid
+ * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::parse_repr_options): default isize
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): special case CallExpr
+ * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): parse repr options enum
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): remove bad diagnostic
+ * typecheck/rust-tyty.cc (PlaceholderType::PlaceholderType): track defid
+ (PlaceholderType::clone): likewise
+ (PlaceholderType::get_def_id): likeiwse
+ * typecheck/rust-tyty.h: placeholder track defid
+ * util/rust-lang-item.cc: add new lang items
+ * util/rust-lang-item.h: likewise
+
+2025-03-24 GS-GOAT <86884129+GS-GOAT@users.noreply.github.com>
+
+ * typecheck/rust-autoderef.cc
+ (insert_implicit_type): Update single-parameter call to
+ pass explicit HirId.
+ * typecheck/rust-hir-type-check-expr.cc: Same.
+ * typecheck/rust-hir-type-check-pattern.cc: Same.
+ * typecheck/rust-hir-type-check.h: Removed call
+ to the duplicate interface.
+ * typecheck/rust-typecheck-context.cc
+ (TypeCheckContext::insert_implicit_type): Removed the
+ interface with no HirId field.
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-tyty-subst.cc (SubstitutionRef::monomorphize): remove diagnostic
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * rust-session-manager.cc (Session::compile_crate): Call the visitor.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-desugar-for-loops.cc: New file.
+ * ast/rust-desugar-for-loops.h: New file.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Make lowering of for-loops an
+ unreachable.
+ * Make-lang.in: Compile it.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.h: Mark all arguments as &&.
+ * ast/rust-ast-builder.cc (Builder::let): Likewise.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * util/rust-unwrap-segment.cc: New file.
+ * util/rust-unwrap-segment.h: New file.
+ * Make-lang.in: Add rust-unwrap-segment.o to the object list.
+ * resolve/rust-forever-stack.hxx: Include rust-unwrap-segment.h.
+ (ForeverStack::find_starting_point): Use unwrap_type_segment.
+ (ForeverStack::resolve_segments): Likewise.
+ (ForeverStack::resolve_path): Likewise.
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Resolve type paths using
+ NameResolutionContext::resolve_path.
+ * resolve/rust-name-resolution-context.h
+ (NameResolutionContext::resolve_path): Use
+ unwrap_segment_node_id.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-macro-builtins-asm.cc (strip_double_quotes): Special case empty
+ strings ("\"\"").
+ (parse_reg_operand): Remove use of the `struct` keyword.
+ (parse_reg_operand_in): Likewise.
+ (parse_reg_operand_out): Likewise.
+ * expand/rust-macro-builtins.cc: Add llvm_asm! built-in macro as an alias to asm!.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Add
+ warning about current code.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive.cc (DeriveVisitor::derive): Call DeriveDefault.
+ * expand/rust-derive-default.cc: New file.
+ * expand/rust-derive-default.h: New file.
+ * Make-lang.in: Compile them.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::qualified_path_in_expression): New.
+ (Builder::function): Change the return type.
+ * ast/rust-ast-builder.h: Declare qualified_path_in_expression functions.
+ * expand/rust-derive-debug.cc (DeriveDebug::stub_debug_fn): Adapt to new APIs.
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::visit): remove receiver interface
+ * backend/rust-compile-item.cc (CompileItem::visit): monomorphize trait to impl item
+ * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): use trait item Self
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): remove receiver interface
+ (TypeCheckExpr::resolve_fn_trait_call): likewise
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): likewise
+ (TypeCheckExpr::resolve_segments): likewise
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise
+ * typecheck/rust-hir-type-check.h: likewise
+ * typecheck/rust-typecheck-context.cc (TypeCheckContext::insert_receiver): remove
+ (TypeCheckContext::lookup_receiver): remove
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit):
+ continue on for trait item mode.
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::check_base_type_privacy):
+ Add guard for placeholder
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-type-util.cc (coercion_site): allow inference vars
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-path-probe.cc (PathProbeType::visit): remove assertion
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-tyty.cc (ClosureType::setup_fn_once_output): add checks for lang items
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc
+ (Early::resolve_glob_import): Use
+ NameResolutionContext::resolve_path instead of
+ ForeverStack::resolve_path.
+ (Early::visit): Likewise.
+ (Early::visit_attributes): Likewise.
+ * resolve/rust-early-name-resolver-2.0.h
+ (Early::resolve_path_in_all_ns): Likewise.
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Likewise, insert segment resolutions not
+ handled by NameResolutionContext::resolve_path, and avoid throwing
+ an error when path resolution could be finished by the typechecker.
+ * resolve/rust-name-resolution-context.h
+ (NameResolutionContext::resolve_path): Add.
+ * typecheck/rust-hir-type-check-path.cc
+ (TypeCheckExpr::resolve_root_path): Use segment node ids instead
+ of the path node id to look up segment resolutions when using
+ the 2.0 resolver, as is done with the 1.0 resolver.
+ * typecheck/rust-hir-type-check-type.cc
+ (TypeCheckType::resolve_root_path): Likewise.
+ * resolve/rust-forever-stack.h
+ (ForeverStack::resolve_path): Add callback parameter for
+ inserting segment resolutions.
+ (ForeverStack::find_starting_point): Likewise.
+ (ForeverStack::resolve_segments): Likewise.
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::find_starting_point): Likewise.
+ (ForeverStack::resolve_segments): Likewise.
+ (ForeverStack::resolve_path): Likewise and avoid resolving
+ inside TraitOrImpl ribs.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * backend/rust-compile-expr.cc
+ (CompileExpr::generate_closure_function): Take
+ NameResolutionContext by reference instead of by value.
+ * backend/rust-compile-item.cc
+ (CompileItem::visit): Likewise.
+ * backend/rust-compile-resolve-path.cc
+ (ResolvePathRef::resolve): Likewise.
+ * checks/lints/rust-lint-marklive.cc
+ (MarkLive::find_ref_node_id): Likewise.
+ * typecheck/rust-hir-type-check-enumitem.cc
+ (TypeCheckEnumItem::visit): Likewise.
+ * typecheck/rust-hir-type-check-implitem.cc
+ (TypeCheckImplItem::visit): Likewise.
+ * typecheck/rust-hir-type-check-item.cc
+ (TypeCheckItem::visit): Likewise.
+ * typecheck/rust-hir-type-check-path.cc
+ (TypeCheckExpr::resolve_root_path): Likewise.
+ * typecheck/rust-hir-type-check-type.cc
+ (TypeCheckType::resolve_root_path): Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.h: Declare it.
+ * ast/rust-ast-builder.cc (Builder::return_expr): Define it.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-debug.cc: New file.
+ * expand/rust-derive-debug.h: New file.
+ * Make-lang.in: Compile them.
+ * expand/rust-derive.cc (DeriveVisitor::derive): Call into DeriveDebug.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc: Cleanup using DeriveVisitor::setup_impl_generics.
+ * expand/rust-derive-copy.cc: Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive.cc (DeriveVisitor::setup_impl_generics): New method.
+ * expand/rust-derive.h: Declare it, define DeriveVisitor::ImplGenerics struct.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc: New methods.
+ * ast/rust-ast-builder.h: Declare them.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::type_path): New functions.
+ * ast/rust-ast-builder.h: Declare them.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * checks/lints/rust-lint-scan-deadcode.h: Check if the field name starts with an
+ underscore before warning.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.cc: New items.
+ * util/rust-lang-item.h: Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Special case lang item paths.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::dfs_rib): Fix const implementation.
+
+2025-03-24 Liam Naddell <liamnprg@gmail.com>
+
+ * expand/rust-macro-builtins-utility.cc: Add macro expansion for
+ option_env with eager expansion
+ * expand/rust-macro-builtins.cc: Add option_env to builtin list
+ * expand/rust-macro-builtins.h: Add option_env handler to header
+ file
+ * resolve/rust-late-name-resolver-2.0.cc: Prevent NR2.0 from
+ recursing into lang-item segments
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast.h: Add new Expr::Kinds.
+ * ast/rust-expr.h: Implement missing get_expr_kind(), Add get_function_expr_ptr()
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-pattern.cc (CompilePatternBindings::visit): make recursive
+ * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): handle ref flag
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.h: Declare it.
+ * util/rust-lang-item.cc: Use it.
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::visit): disable overflow checks
+ * lang.opt: new flag
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * backend/rust-compile-resolve-path.cc (ResolvePathRef::resolve): Do
+ not use query system for unit struct but compile it's constructor
+ instead.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_path_to_trait):
+ Query all namespaces.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-forever-stack.h: Make debug functions const.
+ * resolve/rust-forever-stack.hxx: Likewise.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-hir-type-check-enumitem.cc (TypeCheckEnumItem::visit):
+ Clone expr instead of taking it.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * backend/rust-compile-item.h: Remove query mode.
+ * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile):
+ Likewise.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-ast-resolve-toplevel.h: Add struct to name namespace.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-name-resolver.h: Add new degug dump for old name
+ resolver.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Change label
+ push function from type rib to label rib.
+ * resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit):
+ Likewise.
+ (ResolveItem::visit): Likewise.
+ (ResolveExternItem::visit): Likewise.
+ * resolve/rust-ast-resolve-stmt.h: Likewise.
+ * resolve/rust-ast-resolve.cc (NameResolution::go): Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * backend/rust-compile-resolve-path.cc (ResolvePathRef::visit): Call into
+ resolve_path_like instead.
+ (ResolvePathRef::resolve_path_like): New.
+ (ResolvePathRef::resolve): Call into resolve_with_node_id.
+ * backend/rust-compile-resolve-path.h: Declare new functions and document them.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-path.h: New function.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * checks/lints/rust-lint-marklive.cc (MarkLive::visit): Adapt to lang items.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * backend/rust-compile-resolve-path.cc (ResolvePathRef::visit): Adapt visitor to lang item
+ HIR::PathInExpressions.
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/tree/rust-hir-path.h: Adapt PathPattern to accept lang-item paths.
+ * hir/tree/rust-hir-path.cc: Assert we are dealing with a segmented path, create lang-item
+ constructors.
+ * hir/tree/rust-hir.cc (PathPattern::convert_to_simple_path): Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Adapt visitor to lang item
+ PathInExpressions.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
+ * expand/rust-cfg-strip.cc (CfgStrip::visit): Likewise.
+ * expand/rust-expand-visitor.cc (ExpandVisitor::visit): Likewise.
+ * hir/rust-ast-lower.cc (ASTLoweringExprWithBlock::visit): Likewise.
+ (ASTLowerPathInExpression::visit): Likewise.
+ * resolve/rust-ast-resolve-path.cc (ResolvePath::resolve_path): Likewise.
+ * resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit): Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.cc (LangItem::IsEnumVariant): New function.
+ * util/rust-lang-item.h: Declare it.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-hir-map.cc (Mappings::get_lang_item_node): Better formatting when a lang
+ item does not exist when it should.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-collect-lang-items.h: Declare visitor.
+ * ast/rust-collect-lang-items.cc (CollectLangItems::visit): New.
+
+2025-03-24 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): add guard
+
+2025-03-24 Dylan Gardner <dylan@gardnermedia.com>
+
+ * rust-session-manager.cc (Session::handle_crate_name): Remove
+ crate name inference
+ (Session::compile_crate): Add crate name inference and error if
+ inferred name is empty. Remove CompileOptions::get_instance ()
+ that returned a local copy of the options. Rename
+ crate_name_changed to crate_name_found to match semantics.
+ (rust_crate_name_validation_test): Test inferring ".rs" name
+ * rust-session-manager.h: Modify handle_crate_name definition to
+ include filename.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add
+ ClosureExprInnerTyped visit implementation.
+ (add_captures): Add a function to avoid code duplication.
+ * resolve/rust-late-name-resolver-2.0.h: Add function prototype.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add environment
+ collection.
+ * resolve/rust-late-name-resolver-2.0.h: Add function prototype.
+ * resolve/rust-name-resolver.cc (Resolver::get_captures): Add assertion
+ to prevent NR2 usage with nr1 capture functions.
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Use
+ nr2 captures.
+ * util/rust-hir-map.cc (Mappings::add_capture): Add function to
+ register capture for a given closure.
+ (Mappings::lookup_captures): Add a function to lookup all captures
+ available for a given closure.
+ * util/rust-hir-map.h: Add function prototypes.
+
+2025-03-24 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Error out if a type path has multiple segments,
+ as we currently ignore every segment except the last.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * backend/rust-compile-expr.cc (check_match_scrutinee): Allow anything to be used as a
+ match scrutinee, not just ADTs.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.h: Add handling for Result::Ok, Result::Err, Try, Try::into_result,
+ Try::from_ok, Try::from_err.
+ * util/rust-lang-item.cc: Likewise.
+
+2025-03-24 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add "rust"
+ identifier detection akin to nr1.
+ (funny_ice_finalizer): Copy ICE finalizer from nr1.
+ * resolve/rust-late-name-resolver-2.0.h: Add funny_error member
+ context state.
+ * Make-lang.in: Add new translation unit for new ice finalizer.
+ * resolve/rust-ast-resolve-expr.cc: Move ice
+ finalizer to it's own file.
+ * resolve/rust-ice-finalizer.cc: New file.
+ * resolve/rust-ice-finalizer.h: New file.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-copy.cc: Always add an extra Copy bound on generic Copy impls.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc (DeriveClone::visit_union): Use lang items for Copy and
+ Sized bounds.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc: Add extra bound when deriving generic Clone
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::new_type_param): Add optional extra trait bounds.
+ * ast/rust-ast-builder.h: Likewise.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/rust-hir-dump.cc (Dump::do_typepathsegment): Add handling for lang items.
+
+2025-03-24 lishin <lishin1008@gmail.com>
+
+ * util/rust-lang-item.cc: Add receiver to map.
+ * util/rust-lang-item.h: Define LangItem::Kind::RECEIVER.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Register auto traits in mappings.
+ * util/rust-hir-map.cc (Mappings::insert_auto_trait): New.
+ (Mappings::get_auto_traits): New.
+ * util/rust-hir-map.h: Declare them.
+ * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): Add auto trait bounds when
+ scanning.
+
+2025-03-24 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::add_trait_bound): New function.
+ * typecheck/rust-hir-type-bounds.h: Declare it.
+ (TypeBoundsProbe::assemble_builtin_candidate): Call into add_trait_bound.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Improve formatting.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc (DeriveClone::clone_enum_struct): New function for deriving
+ enum struct variants.
+ (DeriveClone::visit_enum): Call into the new function.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc (DeriveClone::variant_match_path): New function.
+ (DeriveClone::clone_enum_identifier): Rename.
+ (DeriveClone::clone_enum_tuple): New function.
+ (DeriveClone::visit_enum): Visit tuple variants properly.
+ * expand/rust-derive-clone.h: Declare new functions.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc: Add new methods for constructing struct exprs.
+ * ast/rust-ast-builder.h: Mention how to build tuple expressions.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc: Clone enum identifier variants properly
+ * expand/rust-derive-clone.h: Declare new functions used.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc (DeriveClone::clone_call): Mention using `clone_fn`
+ lang item in the future.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc (DeriveClone::visit_union): Create a lang item path
+ instead of a regular path.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc: New functions.
+ * ast/rust-ast-builder.h: Declare them.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-copy.cc: Use lang item path.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-clone.cc (DeriveClone::visit_union): Manually generate
+ the struct used for asserting a union implements Copy.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::struct_struct): New function.
+ * ast/rust-ast-builder.h (vec): New function.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Visit tuple pattern items as
+ separated by commas.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Fix collector to better
+ handle lang item type path segments.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-hir-map.cc (Mappings::get_lang_item_node): New.
+ * util/rust-hir-map.h: New function.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.cc (LangItem::PrettyString): New.
+ * util/rust-lang-item.h: New.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-collect-lang-items.cc (CollectLangItems::visit): New.
+ * ast/rust-collect-lang-items.h: New.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/rust-ast-lower-type.cc (ASTLowerTypePath::visit): Adapt code to lang item
+ type path segments.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path): Adapt
+ code to handle lang item type paths.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-path.h: Rework how lang item paths are represented.
+ * ast/rust-path.cc: Likewise.
+ * ast/rust-item.h: Likewise.
+ * ast/rust-ast.cc: Likewise.
+ * ast/rust-ast-collector.cc: Adapt to new lang item path system.
+ * ast/rust-ast-collector.h: Likewise.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
+ * ast/rust-ast-visitor.h: Likewise.
+ * expand/rust-derive-copy.cc: Likewise.
+ * expand/rust-derive.h: Likewise.
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
+ * hir/rust-ast-lower-base.h: Likewise.
+ * hir/rust-ast-lower-type.cc (ASTLowerTypePath::translate): Likewise.
+ (ASTLowerTypePath::visit): Likewise.
+ * hir/rust-ast-lower-type.h: Likewise.
+ * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
+ * resolve/rust-ast-resolve-base.h: Likewise.
+ * resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Likewise.
+ * resolve/rust-ast-resolve-type.h: Likewise.
+ * resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): Likewise.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise.
+ * resolve/rust-late-name-resolver-2.0.h: Likewise.
+ * hir/tree/rust-hir-path.cc (TypePathSegment::TypePathSegment): Likewise.
+ (TypePathSegmentGeneric::TypePathSegmentGeneric): Likewise.
+ * hir/tree/rust-hir-path.h: Likewise.
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path): Likewise.
+ * ast/rust-ast-builder.cc: Likewise.
+ * ast/rust-ast-builder.h: Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-collect-lang-items.cc (get_lang_item_attr): Show unknown attribute upon error.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-attribute-values.h: Declare new attribute value.
+ * util/rust-attributes.cc: Use it.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast.cc (BlockExpr::normalize_tail_expr): Remove overzealous
+ std::move
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-collector.cc
+ (TokenCollector::visit): Remove visitor for NamedFunctionParam.
+ * ast/rust-ast-collector.h
+ (TokenCollector::visit): Likewise.
+ * ast/rust-ast-full-decls.h
+ (class NamedFunctionParam): Remove forward declaration.
+ * ast/rust-ast-visitor.cc
+ (DefaultASTVisitor::visit): Remove visitor for
+ NamedFunctionParam.
+ * ast/rust-ast-visitor.h
+ (DefaultASTVisitor::visit): Likewise.
+ * ast/rust-ast.cc
+ (NamedFunctionParam::as_string): Remove.
+ * ast/rust-item.h
+ (class NamedFunctionParam): Remove.
+ (class ExternalFunctionItem): Remove.
+ * parse/rust-parse-impl.h
+ (Parser::parse_named_function_param): Remove.
+ (Parser::parse_named_function_params): Remove.
+ * parse/rust-parse.h
+ (Parser::parse_named_function_param): Remove.
+ (Parser::parse_named_function_params): Remove.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc
+ (Early::visit): Resolve the pending eager invocations inside
+ builtin macro invocations.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-ast-lower-stmt.cc (ASTLoweringStmt::visit): hir lowering
+ * hir/rust-ast-lower-stmt.h: likewise
+ * resolve/rust-ast-resolve-stmt.cc (ResolveStmt::visit): name resolution
+ * resolve/rust-ast-resolve-stmt.h: likewise
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * Make-lang.in: Handle rust-forever-stack.cc.
+ * resolve/rust-forever-stack.h
+ (class ForeverStackStore): Add.
+ * resolve/rust-forever-stack.cc: New file, based on
+ rust-forever-stack.hxx.
+
+2025-03-21 Om Swaroop Nayak <96killerat96@gmail.com>
+
+ * ast/rust-collect-lang-items.cc (get_lang_item_attr): "removed checker fn"
+ * util/rust-attributes.cc (Attributes::is_lang_item): "added fn"
+ * util/rust-attributes.h: "added fn"
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * checks/errors/rust-readonly-check.cc (check_decl): improve mut check
+ (emit_error): helper
+ (check_modify_expr): likewise
+ (readonly_walk_fn): reuse helper
+ (ReadonlyCheck::Lint): cleanup context each run
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-visitor.cc
+ (DefaultASTVisitor::visit): When visiting a TraitImpl, visit its
+ trait path.
+
+2025-03-21 liushuyu <liushuyu011@gmail.com>
+
+ * backend/rust-compile-intrinsic.cc: add the new `catch_unwind` variant
+ of the `try` intrinsic: this variant can be seen on Rust 1.78+
+ and returns `()` instead of `i32`.
+
+2025-03-21 liushuyu <liushuyu011@gmail.com>
+
+ * backend/rust-compile-intrinsic.cc: add `try` intrinsic handler.
+ * lang.opt: add `-frust-panic` option.
+ * rust-lang.cc: enable exception handler code generation.
+ * rust-session-manager.cc: add getter and setter for panic
+ strategy option.
+ * rust-session-manager.h: Likewise.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::visit): implement coercion
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): this is an LUB
+ * typecheck/rust-unify.cc (UnifyRules::go): remove unify ! coercion
+
+2025-03-21 Nobel <nobel2073@gmail.com>
+
+ * typecheck/rust-casts.cc (TypeCastRules::cast_rules): Add rule.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::visit): new layout
+ * backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit): likewise
+ (CompilePatternBindings::visit): likewise
+ * backend/rust-compile-resolve-path.cc: likewise
+ * backend/rust-compile-type.cc (TyTyResolveCompile::visit): implement new layout
+ * rust-gcc.cc (constructor_expression): get rid of useless assert
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-toplevel-name-resolver-2.0.cc
+ (TopLevel::visit): Insert a definition for Self when visiting
+ InherentImpl and TraitImpl instances.
+ * resolve/rust-toplevel-name-resolver-2.0.h
+ (TopLevel::visit): Add visitors for InherentImpl and TraitImpl.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-hir-dump.cc (Dump::visit): add null guard
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::visit): handle partial_eq possible call
+ * backend/rust-compile-expr.h: handle case where lang item calls differ from name
+ * hir/tree/rust-hir-expr.cc (OperatorExprMeta::OperatorExprMeta): new helper
+ * hir/tree/rust-hir-expr.h: likewise
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): handle partial_eq
+ (TypeCheckExpr::resolve_operator_overload): likewise
+ * typecheck/rust-hir-type-check-expr.h: likewise
+ * util/rust-lang-item.cc (LangItem::ComparisonToLangItem): map comparison to lang item
+ (LangItem::ComparisonToSegment): likewise
+ * util/rust-lang-item.h: new lang items PartialOrd and Eq
+ * util/rust-operators.h (enum class): likewise
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): check for error
+ * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): likewise and remove debug error
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-default-resolver.cc
+ (DefaultResolver::visit): Make sure to scope visitation of the
+ children of type definition items.
+ * resolve/rust-default-resolver.h
+ (DefaultResolver::visit): Add overrides for TupleStruct, Union,
+ and TypeAlias.
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Remove override for Enum.
+ * resolve/rust-late-name-resolver-2.0.h
+ (Late::visit): Likewise.
+ * resolve/rust-toplevel-name-resolver-2.0.cc
+ (TopLevel::visit): Rely more on DefaultResolver::visit.
+ * resolve/rust-toplevel-name-resolver-2.0.h
+ (TopLevel::visit): Remove override for BlockExpr.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-hir-dump.cc (Dump::do_qualifiedpathtype): add guard
+ (Dump::do_traitfunctiondecl): likewise
+ (Dump::visit): likewise
+
+2025-03-21 Prajwal S N <prajwalnadig21@gmail.com>
+
+ * typecheck/rust-hir-type-check.h (class TypeCheckContext): add
+ header file and use StackedContexts for blocks
+ * typecheck/rust-typecheck-context.cc: update methods
+ * typecheck/rust-hir-trait-resolve.cc: refactor function calls
+ * typecheck/rust-hir-type-check-implitem.cc: refactor function calls
+ * typecheck/rust-hir-type-check-type.cc: refactor function calls
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast.h: Add new Kind enums, remove Node class.
+ * ast/rust-builtin-ast-nodes.h: Use new Kind enums.
+ * ast/rust-expr.h (class LoopLabel): Likewise.
+ * ast/rust-item.h: Likewise.
+ * ast/rust-macro.h: Likewise.
+ * ast/rust-path.h: Likewise.
+ * expand/rust-macro-builtins-helpers.cc: Likewise.
+ * expand/rust-macro-builtins-utility.cc (MacroBuiltin::concat_handler): Likewise.
+ (MacroBuiltin::stringify_handler): Likewise.
+ * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Likewise.
+ * resolve/rust-early-name-resolver.cc: Likewise.
+ * hir/rust-ast-lower.cc (ASTLoweringBlock::visit): Likewise.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-toplevel-name-resolver-2.0.cc
+ (TopLevel::visit): Add visitor for TraitItemType.
+ * resolve/rust-toplevel-name-resolver-2.0.h
+ (TopLevel::visit): Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-ast-resolve-type.cc (ResolveType::visit): New visitor to handle
+ ParenthesizedType.
+ * resolve/rust-ast-resolve-type.h: Likewise.
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): Likewise.
+ * typecheck/rust-hir-type-check-type.h: Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/rust-ast-lower-type.cc (ASTLoweringType::visit): Add implementation for
+ ParenthesizedType.
+ * hir/rust-ast-lower-type.h: Declare that new visitor.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-builder-type.cc: Remove inclusion of
+ rust-make-unique.h.
+ * ast/rust-ast-builder.cc: Likewise.
+ (Builder::array): Use std::make_unique instead of
+ Rust::make_unique.
+ * ast/rust-ast.cc (Attribute::get_traits_to_derive): Likewise.
+ * ast/rust-macro.h: Remove inclusion of rust-make-unique.h.
+ (MacroRulesDefinition::mbe): Use std::make_unique instead of
+ Rust::make_unique.
+ (MacroRulesDefinition::decl_macro): Likewise.
+ * ast/rust-path.h
+ (PathInExpression::PathInExpression): Likewise.
+ (QualifiedPathInExpression::QualifiedPathInExpression):
+ Likewise.
+ * backend/rust-compile-pattern.cc
+ (CompilePatternCheckExpr::visit): Likewise.
+ * expand/rust-derive-copy.cc
+ (DeriveCopy::copy_impl): Likewise.
+ * expand/rust-expand-format-args.cc
+ (expand_format_args): Likewise.
+ * expand/rust-macro-builtins-asm.cc: Remove inclusion of
+ rust-make-unique.h.
+ (parse_asm): Use std::make_unique instead of Rust::make_unique.
+ * hir/rust-ast-lower-expr.cc
+ (ASTLoweringExpr::visit): Likewise.
+ * hir/tree/rust-hir-expr.cc
+ (StructExprStructFields::StructExprStructFields): Likewise.
+ (StructExprStructFields::operator=): Likewise.
+ * hir/tree/rust-hir.cc
+ (TypePath::to_trait_bound): Likewise.
+ * lex/rust-token.h: Remove inclusion of rust-make-unique.h.
+ (Token::Token): Use std::make_unique instead of
+ Rust::make_unique.
+ * metadata/rust-import-archive.cc: Remove inclusion of
+ rust-make-unique.h.
+ (Import::find_archive_export_data): Use std::make_unique instead
+ of Rust::make_unique.
+ * metadata/rust-imports.cc: Remove inclusion of
+ rust-make-unique.h.
+ (Import::find_export_data): Use std::make_unique instead of
+ Rust::make_unique.
+ (Import::find_object_export_data): Likewise.
+ * parse/rust-parse-impl.h: Remove inclusion of
+ rust-make-unique.h.
+ (Parser::parse_function_param): Use std::make_unique instead of
+ Rust::make_unique.
+ (Parser::parse_self_param): Likewise.
+ (Parser::parse_array_expr): Likewise.
+ * typecheck/rust-hir-type-check-enumitem.cc
+ (TypeCheckEnumItem::visit): Likewise.
+ * typecheck/rust-hir-type-check-implitem.cc
+ (TypeCheckTopLevelExternItem::visit): Likewise.
+ (TypeCheckImplItem::visit): Likewise.
+ * typecheck/rust-hir-type-check-type.cc
+ (TypeResolveGenericParam::visit): Likewise.
+ * typecheck/rust-hir-type-check.cc: Remove inclusion of
+ rust-make-unique.h.
+ (TraitItemReference::get_type_from_fn): Use std::make_unique
+ instead of Rust::make_unique.
+ * typecheck/rust-tyty-bounds.cc
+ (TypeCheckBase::get_predicate_from_bound): Likewise.
+ * util/rust-make-unique.h: Removed.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-item.h: Add EnumItem::Kind for differentiating all variants that may be
+ used inside an enum declaration.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-visitor.cc
+ (DefaultASTVisitor::visit): Visit implicit Self parameters of
+ traits.
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Resolve implicit Self parameters of traits.
+ * resolve/rust-late-name-resolver-2.0.h:
+ (Late::visit): Add trait visitor.
+ * resolve/rust-toplevel-name-resolver-2.0.cc
+ (TopLevel::visit): Insert resolutions for Self type parameters
+ as well.
+
+2025-03-21 Liam Naddell <liamnprg@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc:
+ Change the late name resolver to enter proper lexical scope during typechecking
+ * resolve/rust-late-name-resolver-2.0.h:
+ Add needed prototype to header
+ * resolve/rust-toplevel-name-resolver-2.0.cc:
+ Add generic parameters to enum's scoped RIB to allow for proper name resolution on types.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-builder.cc: Add new functions.
+ * ast/rust-ast-builder.h: Declare them.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-path.h: Add two new constructors.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-collect-lang-items.cc (CollectLangItems::visit): Add visitor for collecting
+ functions that might be lang items.
+ * ast/rust-collect-lang-items.h: Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.h: Add new lang items.
+ * util/rust-lang-item.cc: Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.h: Add Sync marker trait.
+ * util/rust-lang-item.cc: Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * typecheck/rust-hir-type-check-type.cc: Add TODO note.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-ast-resolve-type.cc (ResolveTypeToCanonicalPath::visit): Resolve additional
+ trait bounds.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Error out properly on unresolved
+ type-path instead of crashing.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * typecheck/rust-hir-path-probe.cc: Fix typos.
+ * typecheck/rust-hir-path-probe.h: Likewise.
+ * typecheck/rust-hir-type-check-path.cc: Likewise.
+
+2025-03-21 Nobel <nobel2073@gmail.com>
+
+ * typecheck/rust-casts.cc (TypeCastRules::cast_rules): Add rule.
+
+2025-03-21 Sri Ganesh Thota <sriganeshthota12345@gmail.com>
+
+ * ast/rust-item.h: I have changed helper constructor for typepath
+ to be a delegating constructor.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-fnparam.cc (CompileFnParam::visit): compile tuple patterns
+ (CompileSelfParam::compile): update return type
+ (CompileFnParam::create_tmp_param_var): return Bvariable not tree to stop ICE
+ * backend/rust-compile-fnparam.h: update prototype
+ * backend/rust-compile-pattern.cc (CompilePatternBindings::visit): implement TuplePattern
+ * backend/rust-compile-pattern.h: update prototype
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * rust-gcc.cc (operator_to_tree_code): ! expressions are BIT_NOT_EXPR
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-path.h: Adapt children of Path to fix some NodeId issues.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): New.
+ * resolve/rust-late-name-resolver-2.0.h: New.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/rust-ast-lower-type.cc (ASTLowerTypePath::translate): Adapt to
+ handle lang item paths.
+ (ASTLowerTypePath::visit): Likewise.
+ (ASTLowerTypePath::translate_type_path): New.
+ (ASTLowerTypePath::translate_lang_item_type_path): New.
+ * hir/rust-ast-lower-type.h: Adapt to handle lang item paths.
+ * resolve/rust-ast-resolve-type.h: Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Adapt resolver
+ to lang item paths.
+ * resolve/rust-ast-resolve-type.h: Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-item.h: Add new method to specifically get a type-path.
+ * ast/rust-path.cc (LangItemPath::as_string): Implement properly.
+ * hir/rust-ast-lower-type.cc (ASTLowerTypePath::translate): Adapt
+ visitor to use the new LangItemPath.
+ * hir/rust-ast-lower-type.h: Likewise.
+ * resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Likewise.
+ * resolve/rust-ast-resolve-type.h: Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-derive-copy.cc: Use new LangItemPath for derive(Copy).
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-path.h (class LangItemPath): New.
+ (class TypePath): Adapt to accomodate LangItemPath.
+ * ast/rust-ast.cc (TraitImpl::as_string): Use new checks for lang items.
+ (QualifiedPathType::as_string): Likewise.
+ (FormatArgs::set_outer_attrs): Likewise.
+ * ast/rust-item.h (class TraitImpl): Likewise.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.h
+ (ForeverStack::find_starting_point): Use type
+ 'std::reference_wrapper<Node> &' instead of 'Node &' for
+ parameter starting_point.
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::find_starting_point): Likewise.
+ (ForeverStack::resolve_path): Handle change to
+ ForeverStack::find_starting_point.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path):
+ Remove unused capture in lambda.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-attributes.h (class Attributes): New.
+ * util/rust-attributes.cc: Implement Attributes::is_known().
+ * ast/rust-collect-lang-items.cc (is_known_attribute): Remove.
+ (get_lang_item_attr): Call Attributes::is_known() instead.
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::handle_outer_attributes): Likewise.
+ (ASTLoweringBase::is_known_attribute): Remove.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * Make-lang.in: Add new object file.
+ * rust-session-manager.cc (Session::compile_crate): Call CollectLangItems.
+ * ast/rust-collect-lang-items.cc: New file.
+ * ast/rust-collect-lang-items.h: New file.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-hir-map.h: Keep a NodeId mappings for lang items.
+ * util/rust-hir-map.cc (Mappings::insert_lang_item_node): New function.
+ (Mappings::lookup_lang_item_node): Likewise.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-hir-dump.cc (Dump::visit): add missing check for no return value
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-constexpr.cc (eval_store_expression): check for null
+ (eval_call_expression): remove bad warning
+ * rust-gcc.cc (arithmetic_or_logical_expression): add warnings
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-base.cc: apply coercion site to result
+ * backend/rust-compile-base.h: update prototype
+ * backend/rust-compile-implitem.cc (CompileTraitItem::visit): send in coercion info
+ * backend/rust-compile-item.cc (CompileItem::visit): likewise
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * resolve/rust-ast-resolve-item.cc (ResolveItem::visit): remove assertions
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-visitor.h: Replace context with StackedContexts.
+ * ast/rust-ast-visitor.cc (ContextualASTVisitor::visit): Use new APIs.
+ * checks/errors/rust-ast-validation.cc (ASTValidation::visit): Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-stacked-contexts.h: Add new method to see what context we are currently in.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/tree/rust-hir-item.h: Remove TraitItemFunc::has_block_defined()
+ * backend/rust-compile-implitem.cc (CompileTraitItem::visit):
+ Call TraitItemFunc::has_definition() instead.
+ * checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise.
+ * checks/errors/rust-hir-pattern-analysis.cc (PatternChecker::visit): Likewise.
+ * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise.
+ * typecheck/rust-hir-trait-resolve.cc (ResolveTraitItemToRef::visit): Likewise.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-hir-map.h: Move definitions from header...
+ * util/rust-hir-map.cc: ...to source file.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.h: Fix comment location to align with other comments.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-type.cc (TyTyResolveCompile::visit): call lauout type directly
+ * rust-backend.h (struct_type): add optional layout parameter
+ (union_type): likewise
+ (fill_in_fields): likewise
+ * rust-gcc.cc (struct_type): likewise
+ (union_type): likewise
+ (fill_in_fields): only layout if we required
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-casts.cc (TypeCastRules::cast_rules): allow casts to float
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): track trait
+ * typecheck/rust-hir-type-check-implitem.cc: trait block
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): dont when dyn
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): look at Self contenxt
+ (TypeCheckType::resolve_root_path): track if Self
+ (TypeCheckType::resolve_associated_type): look at current context for associated types
+ * typecheck/rust-hir-type-check-type.h: change prototype
+ * typecheck/rust-hir-type-check.h (class TypeCheckBlockContextItem):
+ new context system to track current state
+ * typecheck/rust-typecheck-context.cc (TypeCheckContext::have_block_context): likewise
+ (TypeCheckContext::peek_block_context): likewise
+ (TypeCheckContext::push_block_context): likewise
+ (TypeCheckContext::pop_block_context): likewise
+ (TypeCheckBlockContextItem::Item::Item): likewise
+ (TypeCheckBlockContextItem::TypeCheckBlockContextItem): likewise
+ (TypeCheckBlockContextItem::is_impl_block): likewise
+ (TypeCheckBlockContextItem::is_trait_block): likewise
+ (TypeCheckBlockContextItem::get_impl_block): likewise
+ (TypeCheckBlockContextItem::get_trait): likewise
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-hir-dump.cc (Dump::visit): add missing null checks
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * backend/rust-compile-base.cc: Prepend crate name to function's ir
+ name.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-name-resolver.cc: Include options.txt.
+ (Resolver::insert_resolved_name): Assert that name resolution
+ 2.0 is disabled.
+ (Resolver::lookup_resolved_name): Likewise.
+ (Resolver::insert_resolved_type): Likewise.
+ (Resolver::lookup_resolved_type): Likewise.
+ (Resolver::insert_resolved_label): Likewise.
+ (Resolver::lookup_resolved_label): Likewise.
+ (Resolver::insert_resolved_macro): Likewise.
+ (Resolver::lookup_resolved_macro): Likewise.
+ (Resolver::insert_resolved_misc): Likewise.
+ (Resolver::lookup_resolved_misc): Likewise.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (check_match_scrutinee): check for empty match
+ (CompileExpr::visit): fix assertion
+ * checks/errors/rust-hir-pattern-analysis.cc (check_match_usefulness): check for empty
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): resolve to !
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-hir-dump.cc (Dump::visit): add guards
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-stmt.h: Remove stdlib include and use rust-system instead.
+ * backend/rust-compile-expr.cc: Likewise.
+ * backend/rust-mangle-legacy.cc: Likewise.
+ * backend/rust-mangle-v0.cc: Likewise.
+ * hir/rust-hir-dump.cc: Likewise.
+ * typecheck/rust-hir-type-check-type.cc: Likewise.
+ * typecheck/rust-tyty.cc: Likewise.
+ * typecheck/rust-tyty.h: Likewise.
+ * util/rust-common.h: Likewise.
+ * util/rust-token-converter.cc: Likewise.
+ * util/rust-token-converter.h: Likewise.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * typecheck/rust-hir-type-check-expr.cc: Add includes.
+ (TypeCheckExpr::visit): Use name resolver 2.0.
+ (TypeCheckExpr::resolve_operator_overload): Likewise.
+ (TypeCheckExpr::resolve_fn_trait_call): Likewise.
+ * typecheck/rust-hir-type-check-path.cc
+ (TypeCheckExpr::visit): Likewise.
+ (TypeCheckExpr::resolve_segments): Likewise.
+ * typecheck/rust-hir-type-check-type.cc
+ (TypeCheckType::resolve_segments): Likewise.
+ (ResolveWhereClauseItem::visit): Likewise.
+ (TypeCheckType::visit): Avoid usage of
+ Resolver::get_unit_type_node_id when handling TupleType, use
+ name resolver 2.0 when handling QualifiedPathInType.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Call DefaultResolver::visit when visiting
+ TypePath.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/privacy/rust-privacy-reporter.cc
+ (PrivacyReporter::check_for_privacy_violation): Use name
+ resolver 2.0.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::visit): Change call.
+ (CompileExpr::resolve_operator_overload): Update function arguments.
+ * backend/rust-compile-expr.h: Change the function's prototype to use
+ a reference wrapper instead of a reference within the optional.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-tyty.h: Change initializer list to default constructor
+ call.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Add template
+ to tl::optional.
+ * hir/rust-ast-lower-type.cc (ASTLowerGenericParam::visit): Likewise.
+ * typecheck/rust-hir-type-check-type.cc (TypeResolveGenericParam::visit):
+ Likewise.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Do not
+ get a reference if the pattern does not exist.
+ (TypeCheckMethodCallExpr::check): Likewise.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * hir/rust-ast-lower-stmt.cc (ASTLoweringStmt::visit): Change the
+ ternary expression with a more readable if.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-tyty.h: Reverse monomorphization during cloning and
+ make a new function to explicitly monomorphize.
+ * typecheck/rust-tyty.cc: Use monomorphization when required.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * hir/rust-ast-lower-type.cc (ASTLowerGenericParam::visit): Forward
+ an optional to the constructor.
+ * hir/tree/rust-hir-item.cc (TypeParam::TypeParam): Use an optional
+ in the constructor.
+ (TypeParam::operator=): Ensure the TypeParam has a type properly.
+ (TypeParam::get_type_mappings): Likewise.
+ * hir/tree/rust-hir-item.h: Wrap the type smart pointer into an
+ optional.
+ * hir/tree/rust-hir.cc (TypeParam::as_string): Unwrap optional type
+ correctly.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::visit): Call getter
+ instead of size function.
+ * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::visit):
+ Only check privacy if the type is present.
+ * hir/rust-ast-lower-stmt.cc (ASTLoweringStmt::visit): Use an optional.
+ * hir/tree/rust-hir-generic-param.h: Assert type before getting it.
+ * hir/tree/rust-hir-item.h: Assert pointers before dereference, fix
+ has_type condition.
+ * hir/tree/rust-hir-path.h: Add more assertions.
+ * hir/tree/rust-hir-stmt.cc: Change constructor with optionals.
+ * hir/tree/rust-hir-stmt.h: Use optionals over smart pointers to
+ emphasize these fields might be missing.
+ * hir/tree/rust-hir.cc (LetStmt::as_string): Use getters.
+ * typecheck/rust-hir-type-check-expr.cc: Clone structures to prevent
+ parent's fields from being nulled by the move operation.
+ * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): Use
+ optionals.
+ * typecheck/rust-tyty.cc: Likewise.
+ * typecheck/rust-tyty.h: Likewise.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * Make-lang.in: Add new files.
+ * hir/tree/rust-hir-item.h: Move Item definition and remove
+ implementations to their corresponding cc file.
+ * hir/tree/rust-hir-expr.h: Move implementation to the corresponding
+ cc file.
+ * hir/tree/rust-hir-path.h: Likewise.
+ * hir/tree/rust-hir-pattern.h: Likewise.
+ * hir/tree/rust-hir-stmt.h: Likewise.
+ * hir/tree/rust-hir-type.h: Likewise.
+ * hir/tree/rust-hir-visitor.h: Likewise.
+ * hir/tree/rust-hir.h: Likewise.
+ * hir/tree/rust-hir.cc (Crate::Crate): Add implementations from Crate
+ and remove ConstGenericParam implementations to move them to their
+ own file.
+ * hir/tree/rust-hir-attrs.h: New file.
+ * hir/tree/rust-hir-bound-abstract.h: New file.
+ * hir/tree/rust-hir-bound.h: New file.
+ * hir/tree/rust-hir-expr-abstract.h: New file.
+ * hir/tree/rust-hir-expr.cc: New file.
+ * hir/tree/rust-hir-generic-param.cc: New file.
+ * hir/tree/rust-hir-generic-param.h: New file.
+ * hir/tree/rust-hir-item.cc: New file.
+ * hir/tree/rust-hir-literal.h: New file.
+ * hir/tree/rust-hir-node.h: New file.
+ * hir/tree/rust-hir-path.cc: New file.
+ * hir/tree/rust-hir-pattern-abstract.h: New file.
+ * hir/tree/rust-hir-simple-path.h: New file.
+ * hir/tree/rust-hir-stmt.cc: New file.
+ * hir/tree/rust-hir-trait-bound.h: New file.
+ * hir/tree/rust-hir-type-abstract.cc: New file.
+ * hir/tree/rust-hir-type-abstract.h: New file.
+ * hir/tree/rust-hir-type-no-bounds.h: New file.
+ * hir/tree/rust-hir-type.cc: New file.
+ * hir/tree/rust-hir-visibility.h: New file.
+ * hir/tree/rust-hir-visitable.h: New file.
+ * checks/lints/rust-lint-marklive.h: Use References.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Reformat
+ vectors.
+ * hir/rust-hir-dump.cc (Dump::visit): Use reference.
+ * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::resolve):
+ Use references.
+ * typecheck/rust-tyty-bounds.cc: Likewise.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * backend/rust-compile-base.cc: Use FnParam getter.
+ * backend/rust-compile-expr.cc (CompileExpr::visit): Likewise.
+ * backend/rust-compile-intrinsic.cc: Likewise.
+ * backend/rust-compile-type.cc: Likewise.
+ * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::visit):
+ Only visit childrens if not missing.
+ * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Use
+ a reference instead of a raw pointer.
+ * hir/tree/rust-hir-expr.h: Add presence function for return
+ expression.
+ * hir/tree/rust-hir-item.h: Remove take_param_name.
+ * hir/tree/rust-hir.h: Make mapping getter const.
+ * typecheck/rust-hir-dot-operator.cc (MethodResolver::Select): Use
+ getter.
+ * typecheck/rust-hir-type-check-expr.cc: Likewise.
+ * typecheck/rust-hir-type-check-implitem.cc: Use FnParam vector instead
+ of std::pair of Pattern and BaseType.
+ * typecheck/rust-hir-type-check-item.cc: Likewise.
+ * typecheck/rust-hir-type-check.cc: Likewise.
+ * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Use getters.
+ (TypeCheckMethodCallExpr::check): Likewise.
+ * typecheck/rust-tyty-cmp.h: Likewise.
+ * typecheck/rust-tyty.cc: Use FnParam.
+ * typecheck/rust-tyty.h (class FnParam): Add FnParam to handle function
+ parameters instead of handling std::pairs.
+ * typecheck/rust-unify.cc (UnifyRules::expect_fndef): Use getters.
+ (UnifyRules::expect_fnptr): Likewise.
+
+2025-03-21 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * backend/rust-compile-base.cc (HIRCompileBase::compile_function_body):
+ Remove usage of get function to retrieve a raw pointer.
+ * backend/rust-compile-base.h:
+ Change API usage from raw pointer to a reference.
+ * backend/rust-compile-block.cc (CompileBlock::compile): Likewise.
+ (CompileBlock::visit): Likewise.
+ (CompileConditionalBlocks::visit): Likewise.
+ * backend/rust-compile-block.h: Likewise.
+ * backend/rust-compile-expr.cc (CompileExpr::Compile): Likewise.
+ (CompileExpr::visit): Likewise.
+ (check_match_scrutinee): Likewise.
+ (CompileExpr::array_value_expr): Likewise.
+ (CompileExpr::array_copied_expr): Likewise.
+ (CompileExpr::generate_closure_function): Likewise.
+ (CompileExpr::generate_possible_fn_trait_call): Likewise.
+ * backend/rust-compile-expr.h: Likewise.
+ * backend/rust-compile-fnparam.cc (CompileFnParam::compile): Likewise.
+ (CompileFnParam::visit): Likewise.
+ * backend/rust-compile-fnparam.h: Likewise.
+ * backend/rust-compile-implitem.cc (CompileTraitItem::visit): Likewise.
+ * backend/rust-compile-intrinsic.cc (compile_fn_params): Likewise.
+ * backend/rust-compile-item.cc (CompileItem::visit): Likewise.
+ * backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit):
+ Likewise.
+ (compile_range_pattern_bound): Likewise.
+ (CompilePatternBindings::visit): Likewise.
+ (CompilePatternLet::visit): Likewise.
+ * backend/rust-compile-pattern.h: Likewise.
+ * backend/rust-compile-resolve-path.cc (ResolvePathRef::resolve):
+ Likewise.
+ (HIRCompileBase::query_compile): Likewise.
+ * backend/rust-compile-stmt.cc (CompileStmt::visit): Likewise.
+ * backend/rust-compile-struct-field-expr.cc (CompileStructExprField::Compile):
+ Likewise.
+ (CompileStructExprField::visit): Likewise.
+ * backend/rust-compile-struct-field-expr.h: Likewise.
+ * backend/rust-compile-type.cc (TyTyResolveCompile::visit): Likewise.
+ * backend/rust-compile-var-decl.h: Likewise.
+ * backend/rust-compile.cc: Likewise.
+ * backend/rust-mangle-v0.cc (v0_inherent_or_trait_impl_path): Likewise.
+ * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc (ExprStmtBuilder::visit):
+ Likewise.
+ * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Likewise.
+ * checks/errors/borrowck/rust-bir-builder-pattern.h: Likewise.
+ * checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
+ * checks/errors/borrowck/rust-bir-builder.h: Likewise.
+ * checks/errors/borrowck/rust-function-collector.h: Likewise.
+ * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::check_type_privacy):
+ Likewise.
+ (PrivacyReporter::visit): Likewise.
+ * checks/errors/privacy/rust-privacy-reporter.h: Likewise.
+ * checks/errors/privacy/rust-reachability.cc (ReachabilityVisitor::visit):
+ Likewise.
+ * checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise.
+ * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit):
+ Likewise.
+ * checks/lints/rust-lint-marklive.cc (MarkLive::visit): Likewise.
+ * checks/lints/rust-lint-marklive.h: Likewise.
+ * hir/rust-hir-dump.cc (Dump::visit): Likewise.
+ * hir/tree/rust-hir-expr.h: Likewise.
+ * hir/tree/rust-hir-item.h: Likewise.
+ * hir/tree/rust-hir-path.h: Likewise.
+ * hir/tree/rust-hir-pattern.h: Likewise.
+ * hir/tree/rust-hir-stmt.h: Likewise.
+ * hir/tree/rust-hir-type.h: Likewise.
+ * hir/tree/rust-hir.h: Likewise.
+ * typecheck/rust-autoderef.cc: Likewise.
+ * typecheck/rust-hir-dot-operator.cc (MethodResolver::select):
+ Likewise.
+ * typecheck/rust-hir-inherent-impl-overlap.h: Likewise.
+ * typecheck/rust-hir-path-probe.cc (PathProbeType::process_impl_item_candidate):
+ Likewise.
+ (PathProbeImplTrait::process_trait_impl_items_for_candidates): Likewise.
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait):
+ Likewise.
+ (TraitItemReference::resolve_item): Likewise.
+ * typecheck/rust-hir-type-check-base.cc: Likewise.
+ * typecheck/rust-hir-type-check-base.h: Likewise.
+ * typecheck/rust-hir-type-check-enumitem.cc (TypeCheckEnumItem::Resolve):
+ Likewise.
+ (TypeCheckEnumItem::visit): Likewise.
+ * typecheck/rust-hir-type-check-enumitem.h: Likewise.
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::Resolve):
+ Likewise.
+ (TypeCheckExpr::visit): Likewise.
+ (TypeCheckExpr::resolve_fn_trait_call): Likewise.
+ * typecheck/rust-hir-type-check-expr.h: Likewise.
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::Resolve):
+ Likewise.
+ (TypeCheckTopLevelExternItem::visit): Likewise.
+ (TypeCheckImplItem::visit): Likewise.
+ (TypeCheckImplItemWithTrait::visit): Likewise.
+ * typecheck/rust-hir-type-check-implitem.h: Likewise.
+ * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): Likewise.
+ (TypeCheckItem::resolve_impl_item): Likewise.
+ (TypeCheckItem::resolve_impl_block_substitutions): Likewise.
+ (TypeCheckItem::resolve_impl_block_self): Likewise.
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): Likewise.
+ (TypeCheckExpr::resolve_segments): Likewise.
+ * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::Resolve):
+ Likewise.
+ (TypeCheckPattern::visit): Likewise.
+ (ClosureParamInfer::Resolve): Likewise.
+ (ClosureParamInfer::visit): Likewise.
+ * typecheck/rust-hir-type-check-pattern.h: Likewise.
+ * typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::Resolve):
+ Likewise.
+ (TypeCheckStmt::visit): Likewise.
+ * typecheck/rust-hir-type-check-stmt.h: Likewise.
+ * typecheck/rust-hir-type-check-struct-field.h: Likewise.
+ * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::TypeCheckStructExpr):
+ Likewise.
+ (TypeCheckStructExpr::Resolve): Likewise.
+ (TypeCheckStructExpr::resolve): Likewise.
+ (TypeCheckStructExpr::visit): Likewise.
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckResolveGenericArguments::resolve):
+ Likewise.
+ (TypeCheckType::Resolve): Likewise.
+ (TypeCheckType::visit): Likewise.
+ (TypeCheckType::resolve_root_path): Likewise.
+ (TypeResolveGenericParam::Resolve): Likewise.
+ (TypeResolveGenericParam::visit): Likewise.
+ (ResolveWhereClauseItem::visit): Likewise.
+ * typecheck/rust-hir-type-check-type.h: Likewise.
+ * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn):
+ Likewise.
+ * typecheck/rust-hir-type-check.h: Likewise.
+ * typecheck/rust-type-util.cc (query_type): Likewise.
+ * typecheck/rust-typecheck-context.cc (TypeCheckContextItem::TypeCheckContextItem):
+ Likewise.
+ * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): Likewise.
+ (TypeCheckBase::get_predicate_from_bound): Likewise.
+ * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Likewise.
+ (TypeCheckMethodCallExpr::go): Likewise.
+ (TypeCheckMethodCallExpr::check): Likewise.
+ * typecheck/rust-tyty-subst.cc: Likewise.
+ * typecheck/rust-tyty.cc (BaseType::monomorphized_clone): Likewise.
+ (VariantDef::VariantDef): Remove copy constructor.
+ (VariantDef::operator=): Change to move operator.
+ (VariantDef::get_discriminant): Replace return type to a reference
+ instead of a reference to a unique pointer.
+ (VariantDef::clone): Change to references.
+ (VariantDef::monomorphized_clone): Likewise.
+ (FnType::as_string): Likewise.
+ (FnType::clone): Likewise.
+ * typecheck/rust-tyty.h: Likewise.
+ * util/rust-hir-map.cc (Mappings::insert_hir_impl_block): Likewise.
+ * backend/rust-compile-asm.cc: Use a reference instead of the raw
+ pointer value.
+ * checks/errors/borrowck/rust-bir-builder-pattern.cc: Use references.
+ * checks/errors/rust-hir-pattern-analysis.cc: Likewise.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-toplevel-name-resolver-2.0.cc
+ (TopLevel::visit): Use DefaultResolver::visit and avoid a call
+ to Identifier::as_string while handling instances of StaticItem.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.h
+ (ForeverStack::push): Accept argument of type Rib::Kind rather
+ than Rib.
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::push): Likewise.
+ * resolve/rust-name-resolution-context.cc
+ (NameResolutionContext::scoped): Likewise.
+ * resolve/rust-name-resolution-context.h
+ (NameResolutionContext::scoped): Likewise.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::resolve_impl_block_substitutions):
+ dont check for unconstrained when the self is not resolved
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path):
+ remove bad debug error diagnostic
+ * typecheck/rust-tyty-subst.cc: likewise
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-expr.h: Remove invalid usage of `struct`.
+ * backend/rust-compile-asm.h: Remove unused `translated` member.
+ * backend/rust-compile-asm.cc (CompileAsm::CompileAsm): Remove usage
+ of `translated` member.
+ * checks/errors/rust-unsafe-checker.h: Mark visitor as `override`.
+ * hir/tree/rust-hir-expr.h (struct AnonConst): Remove unused `locus`
+ member.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * typecheck/rust-tyty-call.h: Remove unused context member.
+
+2025-03-21 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * hir/tree/rust-hir.h: Add override qualifier to overriden method.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-item.h
+ (Trait::self_param): Add.
+ (Trait::Trait): Initialize self_param.
+ (Trait::operator=): Copy self_param.
+ (Trait::insert_implicit_self): Remove.
+ (Trait::get_implicit_self): Add.
+ * hir/rust-ast-lower-item.cc
+ (ASTLoweringItem::visit): Make sure implicit self is still
+ lowered to HIR.
+ * resolve/rust-ast-resolve-item.cc
+ (ResolveItem::visit): Adjust handling of implicit self.
+ * resolve/rust-early-name-resolver.cc
+ (EarlyNameResolver::visit): Add commit to Trait visitor
+ mentioning that implicit self is not visited.
+ * resolve/rust-toplevel-name-resolver-2.0.cc
+ (TopLevel::visit): Remove call to Trait::insert_implicit_self.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): fix the ty_id
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-tyty.cc (PlaceholderType::can_resolve): check for empty mappings
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/privacy/rust-privacy-reporter.cc:
+ Include rust-immutable-name-resolution-context.h.
+ (is_child_module): Use ForeverStack::is_module_descendant if name
+ resolution 2.0 is enabled.
+ * resolve/rust-forever-stack.h
+ (ForeverStack::is_module_descendant): Add.
+ (ForeverStack::dfs_node): Add.
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::dfs_rib): Use ForeverStack::dfs_node.
+ (ForeverStack::dfs_node): Add.
+ (ForeverStack::is_module_descendant): Add.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/privacy/rust-visibility-resolver.cc:
+ Add includes.
+ (VisibilityResolver::resolve_module_path): Use name resolver 2.0
+ (when enabled) to lookup path resolutions.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_root_path): dont infer here
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Handle StructExprStruct and use
+ ForeverStack::resolve_path instead of ForeverStack::get to
+ resolve struct expression paths.
+ * resolve/rust-late-name-resolver-2.0.h
+ (Late::visit): Handle StructExprStruct.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * backend/rust-compile-context.cc
+ (Context::setup_builtins): Use TypeCheckContext::get_builtins
+ instead of Resolver::get_builtin_types,
+ TypeCheckContext::lookup_type_by_node_id, and
+ TypeCheckContext::lookup_type.
+ * typecheck/rust-hir-type-check.h
+ (TypeCheckContext::get_builtins): Add.
+ * typecheck/rust-typecheck-context.cc
+ (TypeCheckContext::get_builtins): Add.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): remove hack
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * typecheck/rust-tyty.cc
+ (TupleType::get_unit_type): Remove parameter, cache return
+ value.
+ * typecheck/rust-tyty.h
+ (TupleType::get_unit_type): Remove parameter.
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::setup_builtin_types): Adjust calls to get_unit_type.
+ * resolve/rust-name-resolver.cc
+ (Resolver::generate_builtins): Likewise.
+ * typecheck/rust-hir-type-check-expr.cc
+ (TypeCheckExpr::visit): Likewise.
+ * typecheck/rust-hir-type-check-implitem.cc
+ (TypeCheckTopLevelExternItem::visit): Likewise.
+ (TypeCheckImplItem::visit): Likewise.
+ * typecheck/rust-hir-type-check-item.cc
+ (TypeCheckItem::visit): Likewise.
+ * typecheck/rust-hir-type-check-stmt.cc
+ (TypeCheckStmt::visit): Likewise.
+ * typecheck/rust-hir-type-check-type.cc
+ (TypeCheckType::visit): Likewise.
+ * typecheck/rust-hir-type-check.cc
+ (TraitItemReference::get_type_from_fn): Likewise.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Handle SelfParam.
+ * resolve/rust-late-name-resolver-2.0.h
+ (Late::visit): Likewise.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * typecheck/rust-hir-trait-resolve.cc: Add includes.
+ (TraitResolver::resolve_path_to_trait):
+ Use name resolution 2.0 resolver when enabled.
+
+2025-03-21 Marc Poulhiès <dkm@kataplop.net>
+
+ * backend/rust-compile-block.h: Adjust after removal of
+ HIR::IfLetExpr and HIR::IfLetExprConseqElse.
+ * backend/rust-compile-expr.h: Likewise.
+ * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+ (ExprStmtBuilder::visit): Likewise.
+ * checks/errors/borrowck/rust-bir-builder-expr-stmt.h: Likewise.
+ * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h:
+ Likewise.
+ * checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
+ * checks/errors/borrowck/rust-function-collector.h: Likewise.
+ * checks/errors/privacy/rust-privacy-reporter.cc
+ (PrivacyReporter::visit): Likewise.
+ * checks/errors/privacy/rust-privacy-reporter.h: Likewise.
+ * checks/errors/rust-const-checker.cc (ConstChecker::visit):
+ Likewise.
+ * checks/errors/rust-const-checker.h: Likewise.
+ * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit):
+ Likewise.
+ * checks/errors/rust-unsafe-checker.h: Likewise.
+ * hir/rust-ast-lower-block.h (ASTLoweringIfLetBlock::translate):
+ Change return type.
+ * hir/rust-ast-lower.cc (ASTLoweringIfLetBlock::desugar_iflet):
+ New.
+ (ASTLoweringIfLetBlock::visit(AST::IfLetExpr &)): Adjust and use
+ desugar_iflet.
+ * hir/rust-ast-lower.h: Add comment.
+ * hir/rust-hir-dump.cc (Dump::do_ifletexpr): Remove.
+ (Dump::visit(IfLetExpr&)): Remove.
+ (Dump::visit(IfLetExprConseqElse&)): Remove.
+ * hir/rust-hir-dump.h (Dump::do_ifletexpr): Remove.
+ (Dump::visit(IfLetExpr&)): Remove.
+ (Dump::visit(IfLetExprConseqElse&)): Remove.
+ * hir/tree/rust-hir-expr.h (class IfLetExpr): Remove.
+ (class IfLetExprConseqElse): Remove.
+ * hir/tree/rust-hir-full-decls.h (class IfLetExpr): Remove.
+ (class IfLetExprConseqElse): Remove.
+ * hir/tree/rust-hir-visitor.h: Adjust after removal of
+ HIR::IfLetExpr and HIR::IfLetExprConseqElse.
+ * hir/tree/rust-hir.cc (IfLetExpr::as_string): Remove.
+ (IfLetExprConseqElse::as_string): Remove.
+ (IfLetExpr::accept_vis): Remove.
+ (IfLetExprConseqElse::accept_vis): Remove.
+ * hir/tree/rust-hir.h: Adjust after removal of HIR::IfLetExpr and
+ HIR::IfLetExprConseqElse.
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
+ Likewise.
+ * typecheck/rust-hir-type-check-expr.h: Likewise.
+ * checks/errors/rust-hir-pattern-analysis.cc
+ (PatternChecker::visit (IfLetExpr &)): Remove.
+ (PatternChecker::visit (IfLetExprConseqElse &)): Remove.
+ * checks/errors/rust-hir-pattern-analysis.h (visit(IfLetExpr &)): Remove.
+ (visit(IfLetExprConseqElse &)): Remove.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/rust-unsafe-checker.cc: Add includes.
+ (UnsafeChecker::visit): Use 2.0 version of resolver when name
+ resolution 2.0 is enabled.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * backend/rust-compile-implitem.cc
+ (CompileTraitItem::visit): Use name resolver 2.0 (when enabled)
+ to obtain canonical paths for instances of TraitItemConst and
+ TraitItemFunc.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * typecheck/rust-hir-type-check.cc: Add includes.
+ (TraitItemReference::get_type_from_fn): Use
+ ForeverStack::to_canonical_path when name resolution 2.0 is
+ enabled.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-path.h
+ (PathIdentSegment::is_super_segment): Rename to...
+ (PathIdentSegment::is_super_path_seg): ...here.
+ (PathIdentSegment::is_crate_segment): Rename to...
+ (PathIdentSegment::is_crate_path_seg): ...here.
+ (PathIdentSegment::is_lower_self): Rename to...
+ (PathIdentSegment::is_lower_self_seg): ...here.
+ (PathIdentSegment::is_big_self): Rename to...
+ (PathIdentSegment::is_big_self_seg): ...here.
+ (PathExprSegment::is_super_path_seg): Handle renames.
+ (PathExprSegment::is_crate_path_seg): Likewise.
+ (PathExprSegment::is_lower_self_seg): Likewise.
+ (TypePathSegment::is_crate_path_seg): Likewise.
+ (TypePathSegment::is_super_path_seg): Likewise.
+ (TypePathSegment::is_big_self_seg): Likewise.
+ (TypePathSegment::is_lower_self_seg): Likewise.
+ * ast/rust-ast-collector.cc
+ (TokenCollector::visit): Likewise.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Visit the initialization expressions of let
+ statements before visiting their patterns.
+
+2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-toplevel-name-resolver-2.0.cc
+ (TopLevel::visit): Insert trait names into the type namespace.
+
+2025-03-21 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-trait-reference.h: new get locus helper
+ * typecheck/rust-hir-trait-resolve.cc (AssociatedImplTrait::get_locus): implemention
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::resolve_operator_overload):
+ fix overload
+
2025-03-19 Owen Avery <powerboat9.gamer@gmail.com>
* resolve/rust-toplevel-name-resolver-2.0.cc
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index b1777e3..835e113 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -96,6 +96,11 @@ GRS_OBJS = \
rust/rust-derive.o \
rust/rust-derive-clone.o \
rust/rust-derive-copy.o \
+ rust/rust-derive-debug.o \
+ rust/rust-derive-default.o \
+ rust/rust-derive-partial-eq.o \
+ rust/rust-derive-eq.o \
+ rust/rust-derive-hash.o \
rust/rust-proc-macro.o \
rust/rust-macro-invoc-lexer.o \
rust/rust-proc-macro-invoc-lexer.o \
@@ -110,6 +115,7 @@ GRS_OBJS = \
rust/rust-macro-builtins-format-args.o \
rust/rust-macro-builtins-location.o \
rust/rust-macro-builtins-include.o \
+ rust/rust-token-tree-desugar.o \
rust/rust-fmt.o \
rust/rust-hir.o \
rust/rust-hir-map.o \
@@ -133,6 +139,7 @@ GRS_OBJS = \
rust/rust-toplevel-name-resolver-2.0.o \
rust/rust-early-name-resolver-2.0.o \
rust/rust-finalize-imports-2.0.o \
+ rust/rust-ice-finalizer.o \
rust/rust-late-name-resolver-2.0.o \
rust/rust-immutable-name-resolution-context.o \
rust/rust-early-name-resolver.o \
@@ -146,6 +153,7 @@ GRS_OBJS = \
rust/rust-ast-resolve-path.o \
rust/rust-ast-resolve-stmt.o \
rust/rust-ast-resolve-struct-expr-field.o \
+ rust/rust-forever-stack.o \
rust/rust-hir-type-check.o \
rust/rust-privacy-check.o \
rust/rust-privacy-ctx.o \
@@ -178,6 +186,13 @@ GRS_OBJS = \
rust/rust-polonius.o\
rust/rust-hir-dot-operator.o \
rust/rust-hir-path-probe.o \
+ rust/rust-hir-path.o \
+ rust/rust-hir-type.o \
+ rust/rust-hir-expr.o \
+ rust/rust-hir-type-abstract.o \
+ rust/rust-hir-item.o \
+ rust/rust-hir-stmt.o \
+ rust/rust-hir-generic-param.o \
rust/rust-type-util.o \
rust/rust-coercion.o \
rust/rust-casts.o \
@@ -220,8 +235,13 @@ GRS_OBJS = \
rust/rust-dir-owner.o \
rust/rust-unicode.o \
rust/rust-punycode.o \
- rust/rust-lang-item.o \
+ rust/rust-unwrap-segment.o \
+ rust/rust-edition.o \
rust/rust-expand-format-args.o \
+ rust/rust-lang-item.o \
+ rust/rust-collect-lang-items.o \
+ rust/rust-desugar-for-loops.o \
+ rust/rust-desugar-question-mark.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 e76d0de..13126b4 100644
--- a/gcc/rust/ast/rust-ast-builder-type.cc
+++ b/gcc/rust/ast/rust-ast-builder-type.cc
@@ -20,7 +20,6 @@
#include "rust-ast-builder.h"
#include "rust-ast-full.h"
#include "rust-common.h"
-#include "rust-make-unique.h"
namespace Rust {
namespace AST {
diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 529c686..08c52b1 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -17,15 +17,31 @@
// <http://www.gnu.org/licenses/>.
#include "rust-ast-builder.h"
+#include "optional.h"
#include "rust-ast-builder-type.h"
+#include "rust-ast.h"
#include "rust-common.h"
#include "rust-expr.h"
+#include "rust-keyword-values.h"
+#include "rust-path.h"
+#include "rust-item.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-system.h"
#include "rust-token.h"
-#include "rust-make-unique.h"
+#include <memory>
namespace Rust {
namespace AST {
+std::unique_ptr<Stmt>
+Builder::statementify (std::unique_ptr<Expr> &&value,
+ bool semicolon_followed) const
+{
+ return std::make_unique<ExprStmt> (std::move (value), loc,
+ semicolon_followed);
+}
+
std::unique_ptr<Expr>
Builder::literal_string (std::string &&content) const
{
@@ -35,6 +51,17 @@ Builder::literal_string (std::string &&content) const
}
std::unique_ptr<Expr>
+Builder::literal_bool (bool b) const
+{
+ auto str
+ = b ? Values::Keywords::TRUE_LITERAL : Values::Keywords::FALSE_LITERAL;
+
+ return std::unique_ptr<Expr> (
+ new AST::LiteralExpr (std::move (str), Literal::LitType::BOOL,
+ PrimitiveCoreType::CORETYPE_BOOL, {}, loc));
+}
+
+std::unique_ptr<Expr>
Builder::call (std::unique_ptr<Expr> &&path,
std::vector<std::unique_ptr<Expr>> &&args) const
{
@@ -43,19 +70,56 @@ Builder::call (std::unique_ptr<Expr> &&path,
}
std::unique_ptr<Expr>
+Builder::call (std::unique_ptr<Expr> &&path, std::unique_ptr<Expr> &&arg) const
+{
+ auto args = std::vector<std::unique_ptr<Expr>> ();
+ args.emplace_back (std::move (arg));
+
+ return call (std::move (path), std::move (args));
+}
+
+std::unique_ptr<Expr>
Builder::array (std::vector<std::unique_ptr<Expr>> &&members) const
{
- auto elts = Rust::make_unique<ArrayElemsValues> (std::move (members), loc);
+ auto elts = std::make_unique<ArrayElemsValues> (std::move (members), loc);
return std::unique_ptr<Expr> (new ArrayExpr (std::move (elts), {}, {}, loc));
}
std::unique_ptr<Expr>
+Builder::qualified_path_in_expression (std::unique_ptr<Type> &&type,
+ TypePath trait,
+ PathExprSegment segment) const
+{
+ auto segments = {segment};
+
+ return qualified_path_in_expression (std::move (type), trait, segments);
+}
+
+std::unique_ptr<Expr>
+Builder::qualified_path_in_expression (
+ std::unique_ptr<Type> &&type, TypePath trait,
+ std::vector<PathExprSegment> &&segments) const
+{
+ auto qual_type = QualifiedPathType (std::move (type), loc, trait);
+
+ return std::unique_ptr<QualifiedPathInExpression> (
+ new QualifiedPathInExpression (qual_type, std::move (segments), {}, loc));
+}
+
+std::unique_ptr<Expr>
Builder::identifier (std::string name) const
{
return std::unique_ptr<Expr> (new IdentifierExpr (name, {}, loc));
}
+std::unique_ptr<Pattern>
+Builder::identifier_pattern (std::string name, bool mut) const
+{
+ return std::unique_ptr<Pattern> (
+ new IdentifierPattern (name, loc, false, mut));
+}
+
std::unique_ptr<Expr>
Builder::tuple_idx (std::string receiver, int idx) const
{
@@ -63,12 +127,48 @@ Builder::tuple_idx (std::string receiver, int idx) const
new TupleIndexExpr (identifier (receiver), idx, {}, loc));
}
+std::unique_ptr<Expr>
+Builder::tuple (std::vector<std::unique_ptr<Expr>> &&values) const
+{
+ return std::unique_ptr<TupleExpr> (
+ new TupleExpr (std::move (values), {}, {}, loc));
+}
+
+std::unique_ptr<Param>
+Builder::self_ref_param (bool mutability) const
+{
+ return std::make_unique<SelfParam> (tl::nullopt, mutability, loc);
+}
+
+std::unique_ptr<Param>
+Builder::function_param (std::unique_ptr<Pattern> &&pattern,
+ std::unique_ptr<Type> &&type) const
+{
+ return std::unique_ptr<FunctionParam> (
+ new FunctionParam (std::move (pattern), std::move (type), {}, loc));
+}
+
FunctionQualifiers
Builder::fn_qualifiers () const
{
return FunctionQualifiers (loc, Async::No, Const::No, Unsafety::Normal);
}
+std::unique_ptr<Function>
+Builder::function (std::string function_name,
+ std::vector<std::unique_ptr<Param>> params,
+ std::unique_ptr<Type> return_type,
+ std::unique_ptr<BlockExpr> block,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ FunctionQualifiers qualifiers, WhereClause where_clause,
+ Visibility visibility) const
+{
+ return std::unique_ptr<Function> (
+ new Function (function_name, qualifiers, std::move (generic_params),
+ std::move (params), std::move (return_type), where_clause,
+ std::move (block), visibility, {}, loc));
+}
+
PathExprSegment
Builder::path_segment (std::string seg) const
{
@@ -83,12 +183,27 @@ Builder::type_path_segment (std::string seg) const
}
std::unique_ptr<TypePathSegment>
-Builder::generic_type_path_segment (std::string seg, GenericArgs args) const
+Builder::type_path_segment (LangItem::Kind lang_item) const
+{
+ return std::unique_ptr<TypePathSegment> (
+ new TypePathSegment (lang_item, loc));
+}
+
+std::unique_ptr<TypePathSegment>
+Builder::type_path_segment_generic (std::string seg, GenericArgs args) const
{
return std::unique_ptr<TypePathSegment> (
new TypePathSegmentGeneric (PathIdentSegment (seg, loc), false, args, loc));
}
+std::unique_ptr<TypePathSegment>
+Builder::type_path_segment_generic (LangItem::Kind lang_item,
+ GenericArgs args) const
+{
+ return std::unique_ptr<TypePathSegment> (
+ new TypePathSegmentGeneric (lang_item, args, loc));
+}
+
std::unique_ptr<Type>
Builder::single_type_path (std::string type) const
{
@@ -99,40 +214,146 @@ Builder::single_type_path (std::string type) const
}
std::unique_ptr<Type>
+Builder::single_type_path (LangItem::Kind lang_item) const
+{
+ return std::unique_ptr<Type> (new TypePath (lang_item, {}, loc));
+}
+
+std::unique_ptr<Type>
Builder::single_generic_type_path (std::string type, GenericArgs args) const
{
auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
- segments.emplace_back (generic_type_path_segment (type, args));
+ segments.emplace_back (type_path_segment_generic (type, args));
return std::unique_ptr<Type> (new TypePath (std::move (segments), loc));
}
+std::unique_ptr<Type>
+Builder::single_generic_type_path (LangItem::Kind lang_item,
+ GenericArgs args) const
+{
+ auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
+ segments.emplace_back (type_path_segment_generic (lang_item, args));
+
+ return std::unique_ptr<Type> (new TypePath (std::move (segments), loc));
+}
+
+TypePath
+Builder::type_path (std::vector<std::unique_ptr<TypePathSegment>> &&segments,
+ bool opening_scope) const
+{
+ return TypePath (std::move (segments), loc, opening_scope);
+}
+
+TypePath
+Builder::type_path (std::vector<std::string> &&segments,
+ bool opening_scope) const
+{
+ auto type_segments = std::vector<std::unique_ptr<TypePathSegment>> ();
+
+ for (auto &&segment : segments)
+ type_segments.emplace_back (type_path_segment (segment));
+
+ return TypePath (std::move (type_segments), loc, opening_scope);
+}
+
+TypePath
+Builder::type_path (std::unique_ptr<TypePathSegment> &&segment) const
+{
+ auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
+ segments.emplace_back (std::move (segment));
+
+ return type_path (std::move (segments));
+}
+
+TypePath
+Builder::type_path (std::string type) const
+{
+ return type_path (type_path_segment (type));
+}
+
+TypePath
+Builder::type_path (LangItem::Kind lang_item) const
+{
+ return type_path (type_path_segment (lang_item));
+}
+
+std::unique_ptr<Type>
+Builder::reference_type (std::unique_ptr<TypeNoBounds> &&inner_type,
+ bool mutability) const
+{
+ return std::make_unique<ReferenceType> (mutability, std::move (inner_type),
+ loc);
+}
+
PathInExpression
-Builder::path_in_expression (std::vector<std::string> &&segments) const
+Builder::path_in_expression (std::vector<std::string> &&segments,
+ bool opening_scope) const
{
auto path_segments = std::vector<PathExprSegment> ();
for (auto &seg : segments)
path_segments.emplace_back (path_segment (seg));
- return PathInExpression (std::move (path_segments), {}, loc);
+ return PathInExpression (std::move (path_segments), {}, loc, opening_scope);
}
-std::unique_ptr<Expr>
+PathInExpression
+Builder::path_in_expression (LangItem::Kind lang_item) const
+{
+ return PathInExpression (lang_item, {}, loc);
+}
+
+PathInExpression
+Builder::variant_path (const std::string &enum_path,
+ const std::string &variant) const
+{
+ return PathInExpression ({path_segment (enum_path), path_segment (variant)},
+ {}, loc, false);
+}
+
+std::unique_ptr<BlockExpr>
+Builder::block (tl::optional<std::unique_ptr<Stmt>> &&stmt,
+ std::unique_ptr<Expr> &&tail_expr) const
+{
+ auto stmts = std::vector<std::unique_ptr<Stmt>> ();
+
+ if (stmt)
+ stmts.emplace_back (std::move (*stmt));
+
+ return block (std::move (stmts), std::move (tail_expr));
+}
+
+std::unique_ptr<BlockExpr>
+Builder::block () const
+{
+ auto stmts = std::vector<std::unique_ptr<Stmt>> ();
+
+ return block (std::move (stmts));
+}
+
+std::unique_ptr<BlockExpr>
Builder::block (std::vector<std::unique_ptr<Stmt>> &&stmts,
std::unique_ptr<Expr> &&tail_expr) const
{
- return std::unique_ptr<Expr> (new BlockExpr (std::move (stmts),
- std::move (tail_expr), {}, {},
- LoopLabel::error (), loc, loc));
+ return std::unique_ptr<BlockExpr> (new BlockExpr (std::move (stmts),
+ std::move (tail_expr), {},
+ {}, tl::nullopt, loc, loc));
+}
+
+std::unique_ptr<Expr>
+Builder::return_expr (std::unique_ptr<Expr> &&to_return)
+{
+ return std::unique_ptr<Expr> (
+ new ReturnExpr (std::move (to_return), {}, loc));
}
std::unique_ptr<Stmt>
-Builder::let (std::unique_ptr<Pattern> pattern, std::unique_ptr<Type> type,
- std::unique_ptr<Expr> init) const
+Builder::let (std::unique_ptr<Pattern> &&pattern, std::unique_ptr<Type> &&type,
+ std::unique_ptr<Expr> &&init) const
{
return std::unique_ptr<Stmt> (new LetStmt (std::move (pattern),
std::move (init), std::move (type),
- {}, loc));
+ tl::nullopt, {}, loc));
}
std::unique_ptr<Expr>
@@ -151,6 +372,37 @@ Builder::deref (std::unique_ptr<Expr> &&of) const
}
std::unique_ptr<Expr>
+Builder::comparison_expr (std::unique_ptr<Expr> &&lhs,
+ std::unique_ptr<Expr> &&rhs,
+ ComparisonOperator op) const
+{
+ return std::make_unique<ComparisonExpr> (std::move (lhs), std::move (rhs), op,
+ loc);
+}
+
+std::unique_ptr<Expr>
+Builder::boolean_operation (std::unique_ptr<Expr> &&lhs,
+ std::unique_ptr<Expr> &&rhs,
+ LazyBooleanOperator op) const
+{
+ return std::make_unique<LazyBooleanExpr> (std::move (lhs), std::move (rhs),
+ op, loc);
+}
+
+std::unique_ptr<Stmt>
+Builder::struct_struct (std::string struct_name,
+ std::vector<std::unique_ptr<GenericParam>> &&generics,
+ std::vector<StructField> &&fields)
+{
+ auto is_unit = fields.empty ();
+
+ return std::unique_ptr<Stmt> (
+ new StructStruct (std::move (fields), struct_name, std::move (generics),
+ WhereClause::create_empty (), is_unit,
+ Visibility::create_private (), {}, loc));
+}
+
+std::unique_ptr<Expr>
Builder::struct_expr_struct (std::string struct_name) const
{
return std::unique_ptr<Expr> (
@@ -162,9 +414,16 @@ Builder::struct_expr (
std::string struct_name,
std::vector<std::unique_ptr<StructExprField>> &&fields) const
{
+ return struct_expr (path_in_expression ({struct_name}), std::move (fields));
+}
+
+std::unique_ptr<Expr>
+Builder::struct_expr (
+ PathInExpression struct_name,
+ std::vector<std::unique_ptr<StructExprField>> &&fields) const
+{
return std::unique_ptr<Expr> (
- new StructExprStructFields (path_in_expression ({struct_name}),
- std::move (fields), loc));
+ new StructExprStructFields (struct_name, std::move (fields), loc));
}
std::unique_ptr<StructExprField>
@@ -189,6 +448,81 @@ Builder::wildcard () const
return std::unique_ptr<Pattern> (new WildcardPattern (loc));
}
+std::unique_ptr<Pattern>
+Builder::ref_pattern (std::unique_ptr<Pattern> &&inner) const
+{
+ return std::make_unique<ReferencePattern> (std::move (inner), false, false,
+ loc);
+}
+
+std::unique_ptr<Path>
+Builder::lang_item_path (LangItem::Kind kind) const
+{
+ return std::unique_ptr<Path> (new PathInExpression (kind, {}, loc));
+}
+
+std::unique_ptr<Expr>
+Builder::match (std::unique_ptr<Expr> &&scrutinee,
+ std::vector<MatchCase> &&cases)
+{
+ return std::unique_ptr<Expr> (
+ new MatchExpr (std::move (scrutinee), std::move (cases), {}, {}, loc));
+}
+
+MatchArm
+Builder::match_arm (std::unique_ptr<Pattern> &&pattern)
+{
+ auto patterns = std::vector<std::unique_ptr<Pattern>> ();
+ patterns.emplace_back (std::move (pattern));
+
+ return MatchArm (std::move (patterns), loc);
+}
+
+MatchCase
+Builder::match_case (std::unique_ptr<Pattern> &&pattern,
+ std::unique_ptr<Expr> &&expr)
+{
+ return MatchCase (match_arm (std::move (pattern)), std::move (expr));
+}
+
+std::unique_ptr<Expr>
+Builder::loop (std::vector<std::unique_ptr<Stmt>> &&stmts)
+{
+ auto block_expr = block (std::move (stmts), nullptr);
+
+ return std::unique_ptr<Expr> (new LoopExpr (std::move (block_expr), loc));
+}
+
+std::unique_ptr<TypeParamBound>
+Builder::trait_bound (TypePath bound)
+{
+ return std::make_unique<TraitBound> (bound, loc);
+}
+
+std::unique_ptr<Item>
+Builder::trait_impl (TypePath trait_path, std::unique_ptr<Type> target,
+ std::vector<std::unique_ptr<AssociatedItem>> trait_items,
+ std::vector<std::unique_ptr<GenericParam>> generics,
+ WhereClause where_clause, Visibility visibility) const
+{
+ return std::unique_ptr<Item> (
+ new TraitImpl (trait_path, /* unsafe */ false,
+ /* exclam */ false, std::move (trait_items),
+ std::move (generics), std::move (target), where_clause,
+ visibility, {}, {}, loc));
+}
+
+std::unique_ptr<GenericParam>
+Builder::generic_type_param (
+ std::string type_representation,
+ std::vector<std::unique_ptr<TypeParamBound>> &&bounds,
+ std::unique_ptr<Type> &&type)
+{
+ return std::make_unique<TypeParam> (type_representation, loc,
+ std::move (bounds), std::move (type),
+ std::vector<Attribute> ());
+}
+
std::unique_ptr<Type>
Builder::new_type (Type &type)
{
@@ -213,7 +547,8 @@ Builder::new_lifetime_param (LifetimeParam &param)
}
std::unique_ptr<GenericParam>
-Builder::new_type_param (TypeParam &param)
+Builder::new_type_param (
+ TypeParam &param, std::vector<std::unique_ptr<TypeParamBound>> extra_bounds)
{
location_t locus = param.get_locus ();
AST::AttrVec outer_attrs = param.get_outer_attrs ();
@@ -224,6 +559,9 @@ Builder::new_type_param (TypeParam &param)
if (param.has_type ())
type = new_type (param.get_type ());
+ for (auto &&extra_bound : extra_bounds)
+ type_param_bounds.emplace_back (std::move (extra_bound));
+
for (const auto &b : param.get_type_param_bounds ())
{
switch (b->get_bound_type ())
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index bad79d0..41ce118 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -20,10 +20,45 @@
#define AST_BUILDER_H
#include "rust-ast-full.h"
+#include "rust-expr.h"
+#include "rust-ast.h"
+#include "rust-item.h"
+#include "rust-operators.h"
namespace Rust {
namespace AST {
+template <typename T>
+std::vector<std::unique_ptr<T>>
+vec (std::unique_ptr<T> &&t)
+{
+ auto v = std::vector<std::unique_ptr<T>> ();
+
+ v.emplace_back (std::move (t));
+
+ return v;
+}
+
+template <typename T>
+std::vector<std::unique_ptr<T>>
+vec (std::unique_ptr<T> &&t1, std::unique_ptr<T> &&t2)
+{
+ auto v = std::vector<std::unique_ptr<T>> ();
+
+ v.emplace_back (std::move (t1));
+ v.emplace_back (std::move (t2));
+
+ return v;
+}
+
+/* Pointer-ify something */
+template <typename T>
+static std::unique_ptr<T>
+ptrify (T value)
+{
+ return std::unique_ptr<T> (new T (value));
+}
+
// TODO: Use this builder when expanding regular macros
/* Builder class with helper methods to create AST nodes. This builder is
* tailored towards generating multiple AST nodes from a single location, and
@@ -33,15 +68,28 @@ class Builder
public:
Builder (location_t loc) : loc (loc) {}
+ /* Create an expression statement from an expression */
+ std::unique_ptr<Stmt> statementify (std::unique_ptr<Expr> &&value,
+ bool semicolon_followed = true) const;
+
/* Create a string literal expression ("content") */
std::unique_ptr<Expr> literal_string (std::string &&content) const;
+ /* Create a boolean literal expression (true) */
+ std::unique_ptr<Expr> literal_bool (bool b) const;
+
/* Create an identifier expression (`variable`) */
std::unique_ptr<Expr> identifier (std::string name) const;
+ std::unique_ptr<Pattern> identifier_pattern (std::string name,
+ bool mut = false) const;
/* Create a tuple index expression (`receiver.0`) */
std::unique_ptr<Expr> tuple_idx (std::string receiver, int idx) const;
+ /* Create a tuple expression (`(a1, a2, a3)`) */
+ std::unique_ptr<Expr> tuple (std::vector<std::unique_ptr<Expr>> &&values
+ = {}) const;
+
/* Create a reference to an expression (`&of`) */
std::unique_ptr<Expr> ref (std::unique_ptr<Expr> &&of,
bool mut = false) const;
@@ -49,23 +97,45 @@ public:
/* Create a dereference of an expression (`*of`) */
std::unique_ptr<Expr> deref (std::unique_ptr<Expr> &&of) const;
+ /* Build a comparison expression (`lhs == rhs`) */
+ std::unique_ptr<Expr> comparison_expr (std::unique_ptr<Expr> &&lhs,
+ std::unique_ptr<Expr> &&rhs,
+ ComparisonOperator op) const;
+
+ /* Build a lazy boolean operator expression (`lhs && rhs`) */
+ std::unique_ptr<Expr> boolean_operation (std::unique_ptr<Expr> &&lhs,
+ std::unique_ptr<Expr> &&rhs,
+ LazyBooleanOperator op) const;
+
/* Create a block with an optional tail expression */
- std::unique_ptr<Expr> block (std::vector<std::unique_ptr<Stmt>> &&stmts,
- std::unique_ptr<Expr> &&tail_expr
- = nullptr) const;
+ std::unique_ptr<BlockExpr> block (std::vector<std::unique_ptr<Stmt>> &&stmts,
+ std::unique_ptr<Expr> &&tail_expr
+ = nullptr) const;
+ std::unique_ptr<BlockExpr> block (tl::optional<std::unique_ptr<Stmt>> &&stmt,
+ std::unique_ptr<Expr> &&tail_expr
+ = nullptr) const;
+ /* Create an empty block */
+ std::unique_ptr<BlockExpr> block () const;
+
+ /* Create an early return expression with an optional expression */
+ std::unique_ptr<Expr> return_expr (std::unique_ptr<Expr> &&to_return
+ = nullptr);
/* Create a let binding with an optional type and initializer (`let <name> :
* <type> = <init>`) */
- std::unique_ptr<Stmt> let (std::unique_ptr<Pattern> pattern,
- std::unique_ptr<Type> type = nullptr,
- std::unique_ptr<Expr> init = nullptr) const;
+ std::unique_ptr<Stmt> let (std::unique_ptr<Pattern> &&pattern,
+ std::unique_ptr<Type> &&type = nullptr,
+ std::unique_ptr<Expr> &&init = nullptr) const;
/**
* Create a call expression to a function, struct or enum variant, given its
* arguments (`path(arg0, arg1, arg2)`)
*/
std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path,
- std::vector<std::unique_ptr<Expr>> &&args) const;
+ std::vector<std::unique_ptr<Expr>> &&args
+ = {}) const;
+ std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path,
+ std::unique_ptr<Expr> &&arg) const;
/**
* Create an array expression (`[member0, member1, member2]`)
@@ -73,42 +143,107 @@ public:
std::unique_ptr<Expr>
array (std::vector<std::unique_ptr<Expr>> &&members) const;
+ /* Create a qualified path in expression (`<type as Trait>::seg::expr`) */
+ std::unique_ptr<Expr>
+ qualified_path_in_expression (std::unique_ptr<Type> &&type, TypePath trait,
+ PathExprSegment segment) const;
+ std::unique_ptr<Expr>
+ qualified_path_in_expression (std::unique_ptr<Type> &&type, TypePath trait,
+ std::vector<PathExprSegment> &&segments
+ = {}) const;
+
+ /* Self parameter for a function definition (`&self`) */
+ std::unique_ptr<Param> self_ref_param (bool mutability = false) const;
+ /* A regular named function parameter for a definition (`a: type`) */
+ std::unique_ptr<Param> function_param (std::unique_ptr<Pattern> &&pattern,
+ std::unique_ptr<Type> &&type) const;
+
/* Empty function qualifiers, with no specific qualifiers */
FunctionQualifiers fn_qualifiers () const;
+ std::unique_ptr<Function>
+ function (std::string function_name,
+ std::vector<std::unique_ptr<Param>> params,
+ std::unique_ptr<Type> return_type, std::unique_ptr<BlockExpr> block,
+ std::vector<std::unique_ptr<GenericParam>> generic_params = {},
+ FunctionQualifiers qualifiers
+ = FunctionQualifiers (UNKNOWN_LOCATION, Async::No, Const::No,
+ Unsafety::Normal),
+ WhereClause where_clause = WhereClause::create_empty (),
+ Visibility visibility = Visibility::create_private ()) const;
+
/* Create a single path segment from one string */
PathExprSegment path_segment (std::string seg) const;
/* And similarly for type path segments */
std::unique_ptr<TypePathSegment> type_path_segment (std::string seg) const;
+ std::unique_ptr<TypePathSegment>
+ type_path_segment (LangItem::Kind lang_item) const;
std::unique_ptr<TypePathSegment>
- generic_type_path_segment (std::string seg, GenericArgs args) const;
+ type_path_segment_generic (std::string seg, GenericArgs args) const;
+ std::unique_ptr<TypePathSegment>
+ type_path_segment_generic (LangItem::Kind lang_item, GenericArgs args) const;
/* Create a Type from a single string - the most basic kind of type in our AST
*/
std::unique_ptr<Type> single_type_path (std::string type) const;
+ std::unique_ptr<Type> single_type_path (LangItem::Kind lang_item) const;
std::unique_ptr<Type> single_generic_type_path (std::string type,
GenericArgs args) const;
+ std::unique_ptr<Type> single_generic_type_path (LangItem::Kind lang_item,
+ GenericArgs args) const;
+
+ TypePath type_path (std::vector<std::unique_ptr<TypePathSegment>> &&segment,
+ bool opening_scope = false) const;
+ TypePath type_path (std::vector<std::string> &&segments,
+ bool opening_scope = false) const;
+ TypePath type_path (std::unique_ptr<TypePathSegment> &&segment) const;
+ TypePath type_path (std::string type) const;
+ TypePath type_path (LangItem::Kind lang_item) const;
+
+ std::unique_ptr<Type>
+ reference_type (std::unique_ptr<TypeNoBounds> &&inner_type,
+ bool mutability = false) const;
/**
* Create a path in expression from multiple segments (`Clone::clone`). You
* do not need to separate the segments using `::`, you can simply provide a
* vector of strings to the functions which will get turned into path segments
*/
- PathInExpression
- path_in_expression (std::vector<std::string> &&segments) const;
+ PathInExpression path_in_expression (std::vector<std::string> &&segments,
+ bool opening_scope = false) const;
+
+ /**
+ * Create a path in expression from a lang item.
+ */
+ PathInExpression path_in_expression (LangItem::Kind lang_item) const;
+
+ /* Create the path to an enum's variant (`Result::Ok`) */
+ PathInExpression variant_path (const std::string &enum_path,
+ const std::string &variant) const;
+
+ /* Create a new struct */
+ std::unique_ptr<Stmt>
+ struct_struct (std::string struct_name,
+ std::vector<std::unique_ptr<GenericParam>> &&generics,
+ std::vector<StructField> &&fields);
/* Create a struct expression for unit structs (`S`) */
std::unique_ptr<Expr> struct_expr_struct (std::string struct_name) const;
/**
* Create an expression for struct instantiation with fields (`S { a, b: c }`)
+ * Named tuple expressions (`S(a, b, c)`) are call expressions and can thus be
+ * constructed with `call`
*/
std::unique_ptr<Expr>
struct_expr (std::string struct_name,
std::vector<std::unique_ptr<StructExprField>> &&fields) const;
+ std::unique_ptr<Expr>
+ struct_expr (PathInExpression struct_name,
+ std::vector<std::unique_ptr<StructExprField>> &&fields) const;
/* Create a field expression for struct instantiation (`field_name: value`) */
std::unique_ptr<StructExprField>
@@ -121,13 +256,43 @@ public:
/* Create a wildcard pattern (`_`) */
std::unique_ptr<Pattern> wildcard () const;
+ /* Create a reference pattern (`&pattern`) */
+ std::unique_ptr<Pattern> ref_pattern (std::unique_ptr<Pattern> &&inner) const;
+
+ /* Create a lang item path usable as a general path */
+ std::unique_ptr<Path> lang_item_path (LangItem::Kind) const;
+
+ /* Create match expressions and their components */
+ std::unique_ptr<Expr> match (std::unique_ptr<Expr> &&scrutinee,
+ std::vector<MatchCase> &&cases);
+ MatchArm match_arm (std::unique_ptr<Pattern> &&pattern);
+ MatchCase match_case (std::unique_ptr<Pattern> &&pattern,
+ std::unique_ptr<Expr> &&expr);
+
+ /* Create a loop expression */
+ std::unique_ptr<Expr> loop (std::vector<std::unique_ptr<Stmt>> &&stmts);
+
+ std::unique_ptr<TypeParamBound> trait_bound (TypePath bound);
+ std::unique_ptr<Item>
+ trait_impl (TypePath trait_path, std::unique_ptr<Type> target,
+ std::vector<std::unique_ptr<AssociatedItem>> trait_items = {},
+ std::vector<std::unique_ptr<GenericParam>> generics = {},
+ WhereClause where_clause = WhereClause::create_empty (),
+ Visibility visibility = Visibility::create_private ()) const;
+
+ std::unique_ptr<GenericParam>
+ generic_type_param (std::string type_representation,
+ std::vector<std::unique_ptr<TypeParamBound>> &&bounds,
+ std::unique_ptr<Type> &&type = nullptr);
static std::unique_ptr<Type> new_type (Type &type);
static std::unique_ptr<GenericParam>
new_lifetime_param (LifetimeParam &param);
- static std::unique_ptr<GenericParam> new_type_param (TypeParam &param);
+ static std::unique_ptr<GenericParam> new_type_param (
+ TypeParam &param,
+ std::vector<std::unique_ptr<TypeParamBound>> extra_trait_bounds = {});
static Lifetime new_lifetime (const Lifetime &lifetime);
diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index 2022668..c850e96 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -15,12 +15,15 @@
// 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-ast-collector.h"
#include "rust-ast.h"
#include "rust-diagnostics.h"
#include "rust-expr.h"
#include "rust-item.h"
#include "rust-keyword-values.h"
+#include "rust-location.h"
+#include "rust-path.h"
#include "rust-system.h"
#include "rust-token.h"
@@ -251,29 +254,6 @@ TokenCollector::visit (Visibility &vis)
}
void
-TokenCollector::visit (NamedFunctionParam &param)
-{
- auto name = param.get_name ();
- if (!param.is_variadic ())
- {
- push (
- Rust::Token::make_identifier (param.get_locus (), std::move (name)));
- push (Rust::Token::make (COLON, UNDEF_LOCATION));
- visit (param.get_type ());
- }
- else
- {
- if (name != "")
- {
- push (Rust::Token::make_identifier (param.get_locus (),
- std::move (name)));
- push (Rust::Token::make (COLON, UNDEF_LOCATION));
- }
- push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
- }
-}
-
-void
TokenCollector::visit (std::vector<std::unique_ptr<GenericParam>> &params)
{
push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
@@ -511,7 +491,7 @@ TokenCollector::visit (ConstGenericParam &param)
if (param.has_default_value ())
{
push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
- visit (param.get_default_value ());
+ visit (param.get_default_value_unchecked ());
}
}
@@ -553,25 +533,24 @@ TokenCollector::visit (PathExprSegment &segment)
void
TokenCollector::visit (PathInExpression &path)
{
- if (path.opening_scope_resolution ())
+ if (path.is_lang_item ())
{
- push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
- }
+ push (Rust::Token::make (TokenId::HASH, path.get_locus ()));
+ push (Rust::Token::make (TokenId::LEFT_SQUARE, path.get_locus ()));
+ push (Rust::Token::make_identifier (path.get_locus (), "lang"));
+ push (Rust::Token::make (TokenId::EQUAL, path.get_locus ()));
+ push (
+ Rust::Token::make_string (path.get_locus (),
+ LangItem::ToString (path.get_lang_item ())));
+ push (Rust::Token::make (TokenId::RIGHT_SQUARE, path.get_locus ()));
- visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
-}
+ return;
+ }
-void
-TokenCollector::visit (RegularPath &path)
-{
- // FIXME: We probably want to have a proper implementation here, and call this
- // function from things like the PathInExpression visitor
-}
+ if (path.opening_scope_resolution ())
+ push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
-void
-TokenCollector::visit (LangItemPath &path)
-{
- // TODO: Implement proper token collection for lang item paths
+ visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
}
void
@@ -579,10 +558,14 @@ TokenCollector::visit (TypePathSegment &segment)
{
// Syntax:
// PathIdentSegment
- auto ident_segment = segment.get_ident_segment ();
- auto id = ident_segment.as_string ();
- push (
- Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id)));
+
+ auto locus = segment.is_lang_item ()
+ ? segment.get_locus ()
+ : segment.get_ident_segment ().get_locus ();
+ auto segment_string = segment.is_lang_item ()
+ ? LangItem::PrettyString (segment.get_lang_item ())
+ : segment.get_ident_segment ().as_string ();
+ push (Rust::Token::make_identifier (locus, std::move (segment_string)));
}
void
@@ -594,10 +577,13 @@ TokenCollector::visit (TypePathSegmentGeneric &segment)
// `<` `>`
// | `<` ( GenericArg `,` )* GenericArg `,`? `>`
- auto ident_segment = segment.get_ident_segment ();
- auto id = ident_segment.as_string ();
- push (
- Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id)));
+ auto locus = segment.is_lang_item ()
+ ? segment.get_locus ()
+ : segment.get_ident_segment ().get_locus ();
+ auto segment_string = segment.is_lang_item ()
+ ? LangItem::PrettyString (segment.get_lang_item ())
+ : segment.get_ident_segment ().as_string ();
+ push (Rust::Token::make_identifier (locus, std::move (segment_string)));
if (segment.get_separating_scope_resolution ())
push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
@@ -653,8 +639,6 @@ TokenCollector::visit (GenericArg &arg)
push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (path)));
}
break;
- case GenericArg::Kind::Error:
- rust_unreachable ();
}
}
@@ -711,19 +695,19 @@ TokenCollector::visit (TypePath &path)
void
TokenCollector::visit (PathIdentSegment &segment)
{
- if (segment.is_super_segment ())
+ if (segment.is_super_path_seg ())
{
push (Rust::Token::make (SUPER, segment.get_locus ()));
}
- else if (segment.is_crate_segment ())
+ else if (segment.is_crate_path_seg ())
{
push (Rust::Token::make (CRATE, segment.get_locus ()));
}
- else if (segment.is_lower_self ())
+ else if (segment.is_lower_self_seg ())
{
push (Rust::Token::make (SELF, segment.get_locus ()));
}
- else if (segment.is_big_self ())
+ else if (segment.is_big_self_seg ())
{
push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
}
@@ -1293,7 +1277,7 @@ TokenCollector::visit (ContinueExpr &expr)
{
push (Rust::Token::make (CONTINUE, expr.get_locus ()));
if (expr.has_label ())
- visit (expr.get_label ());
+ visit (expr.get_label_unchecked ());
}
void
@@ -1301,7 +1285,7 @@ TokenCollector::visit (BreakExpr &expr)
{
push (Rust::Token::make (BREAK, expr.get_locus ()));
if (expr.has_label ())
- visit (expr.get_label ());
+ visit (expr.get_label_unchecked ());
if (expr.has_break_expr ())
visit (expr.get_break_expr ());
}
@@ -1536,6 +1520,47 @@ void
TokenCollector::visit (InlineAsm &expr)
{}
+void
+TokenCollector::visit (LlvmInlineAsm &expr)
+{
+ push (Rust::Token::make_identifier (expr.get_locus (), "llvm_asm"));
+ push (Rust::Token::make (EXCLAM, expr.get_locus ()));
+ push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
+ for (auto &template_str : expr.get_templates ())
+ push (Rust::Token::make_string (template_str.get_locus (),
+ std::move (template_str.symbol)));
+
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+ for (auto output : expr.get_outputs ())
+ {
+ push (Rust::Token::make_string (expr.get_locus (),
+ std::move (output.constraint)));
+ visit (output.expr);
+ push (Rust::Token::make (COMMA, expr.get_locus ()));
+ }
+
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+ for (auto input : expr.get_inputs ())
+ {
+ push (Rust::Token::make_string (expr.get_locus (),
+ std::move (input.constraint)));
+ visit (input.expr);
+ push (Rust::Token::make (COMMA, expr.get_locus ()));
+ }
+
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+ for (auto &clobber : expr.get_clobbers ())
+ {
+ 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 ()));
+ // Dump options
+
+ push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
+}
+
// rust-item.h
void
@@ -2499,10 +2524,7 @@ TokenCollector::visit (StructPattern &pattern)
void
TokenCollector::visit (TupleStructItemsNoRange &pattern)
{
- for (auto &pat : pattern.get_patterns ())
- {
- visit (pat);
- }
+ visit_items_joined_by_separator (pattern.get_patterns ());
}
void
@@ -2605,6 +2627,13 @@ TokenCollector::visit (LetStmt &stmt)
push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
visit (stmt.get_init_expr ());
}
+
+ if (stmt.has_else_expr ())
+ {
+ push (Rust::Token::make (ELSE, UNDEF_LOCATION));
+ visit (stmt.get_else_expr ());
+ }
+
push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
}
diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h
index 32a5bd3..f45e3cc 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -210,7 +210,6 @@ public:
void visit (TupleField &field);
void visit (StructField &field);
void visit (SimplePathSegment &segment);
- void visit (NamedFunctionParam &param);
void visit (MacroRule &rule);
void visit (WhereClause &rule);
void visit (std::vector<LifetimeParam> &for_lifetimes);
@@ -234,8 +233,6 @@ public:
void visit (PathExprSegment &segment);
void visit (PathIdentSegment &segment);
void visit (PathInExpression &path);
- void visit (RegularPath &path);
- void visit (LangItemPath &path);
void visit (TypePathSegment &segment);
void visit (TypePathSegmentGeneric &segment);
void visit (TypePathSegmentFunction &segment);
@@ -306,6 +303,7 @@ public:
void visit (AwaitExpr &expr);
void visit (AsyncBlockExpr &expr);
void visit (InlineAsm &expr);
+ void visit (LlvmInlineAsm &expr);
// rust-item.h
void visit (TypeParam &param);
void visit (LifetimeWhereClauseItem &item);
diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h
index 80d217e..9359248 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -202,7 +202,6 @@ class TraitImpl;
class ExternalItem;
class ExternalTypeItem;
class ExternalStaticItem;
-class NamedFunctionParam;
class ExternBlock;
// rust-macro.h
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 8f53e52..b6833f6 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -82,26 +82,17 @@ DefaultASTVisitor::visit (AST::ConstGenericParam &const_param)
if (const_param.has_type ())
visit (const_param.get_type ());
if (const_param.has_default_value ())
- visit (const_param.get_default_value ());
+ visit (const_param.get_default_value_unchecked ());
}
void
-DefaultASTVisitor::visit (AST::RegularPath &path)
-{
- for (auto &segment : path.get_segments ())
- visit (segment);
-}
-
-void
-DefaultASTVisitor::visit (AST::LangItemPath &path)
-{}
-
-void
DefaultASTVisitor::visit (AST::PathInExpression &path)
{
visit_outer_attrs (path);
- for (auto &segment : path.get_segments ())
- visit (segment);
+
+ if (!path.is_lang_item ())
+ for (auto &segment : path.get_segments ())
+ visit (segment);
}
void
@@ -117,7 +108,8 @@ DefaultASTVisitor::visit (GenericArgsBinding &binding)
void
DefaultASTVisitor::visit (AST::TypePathSegmentGeneric &segment)
{
- visit (segment.get_generic_args ());
+ if (segment.has_generic_args ())
+ visit (segment.get_generic_args ());
}
void
@@ -401,6 +393,7 @@ DefaultASTVisitor::visit (AST::StructExprStructFields &expr)
{
visit_outer_attrs (expr);
visit_inner_attrs (expr);
+ visit (expr.get_struct_name ());
if (expr.has_struct_base ())
visit (expr.get_struct_base ());
for (auto &field : expr.get_fields ())
@@ -412,6 +405,7 @@ DefaultASTVisitor::visit (AST::StructExprStructBase &expr)
{
visit_outer_attrs (expr);
visit_inner_attrs (expr);
+ visit (expr.get_struct_name ());
visit (expr.get_struct_base ());
}
@@ -484,7 +478,8 @@ void
DefaultASTVisitor::visit (AST::ContinueExpr &expr)
{
visit_outer_attrs (expr);
- visit (expr.get_label ());
+ if (expr.has_label ())
+ visit (expr.get_label_unchecked ());
}
void
@@ -492,7 +487,7 @@ DefaultASTVisitor::visit (AST::BreakExpr &expr)
{
visit_outer_attrs (expr);
if (expr.has_label ())
- visit (expr.get_label ());
+ visit (expr.get_label_unchecked ());
if (expr.has_break_expr ())
visit (expr.get_break_expr ());
@@ -566,7 +561,8 @@ void
DefaultASTVisitor::visit (AST::LoopExpr &expr)
{
visit_outer_attrs (expr);
- visit (expr.get_loop_label ());
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
visit (expr.get_loop_block ());
}
@@ -574,8 +570,9 @@ void
DefaultASTVisitor::visit (AST::WhileLoopExpr &expr)
{
visit_outer_attrs (expr);
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
visit (expr.get_predicate_expr ());
- visit (expr.get_loop_label ());
visit (expr.get_loop_block ());
}
@@ -585,8 +582,8 @@ DefaultASTVisitor::visit (AST::WhileLetLoopExpr &expr)
visit_outer_attrs (expr);
for (auto &pattern : expr.get_patterns ())
visit (pattern);
- visit (expr.get_scrutinee_expr ());
visit (expr.get_loop_label ());
+ visit (expr.get_scrutinee_expr ());
visit (expr.get_loop_block ());
}
@@ -596,7 +593,8 @@ DefaultASTVisitor::visit (AST::ForLoopExpr &expr)
visit_outer_attrs (expr);
visit (expr.get_pattern ());
visit (expr.get_iterator_expr ());
- visit (expr.get_loop_label ());
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
visit (expr.get_loop_block ());
}
@@ -717,6 +715,16 @@ DefaultASTVisitor::visit (AST::InlineAsm &expr)
}
void
+DefaultASTVisitor::visit (AST::LlvmInlineAsm &expr)
+{
+ for (auto &output : expr.get_outputs ())
+ visit (output.expr);
+
+ for (auto &input : expr.get_inputs ())
+ visit (input.expr);
+}
+
+void
DefaultASTVisitor::visit (AST::TypeParam &param)
{
visit_outer_attrs (param);
@@ -820,10 +828,18 @@ DefaultASTVisitor::visit (AST::UseTreeRebind &use_tree)
void
DefaultASTVisitor::visit (AST::UseDeclaration &use_decl)
{
+ visit (use_decl.get_visibility ());
visit (use_decl.get_tree ());
}
void
+DefaultASTVisitor::visit_function_params (AST::Function &function)
+{
+ for (auto &param : function.get_function_params ())
+ visit (param);
+}
+
+void
DefaultASTVisitor::visit (AST::Function &function)
{
visit_outer_attrs (function);
@@ -831,10 +847,9 @@ DefaultASTVisitor::visit (AST::Function &function)
visit (function.get_qualifiers ());
for (auto &generic : function.get_generic_params ())
visit (generic);
- if (function.has_self_param ())
- visit (function.get_self_param ());
- for (auto &param : function.get_function_params ())
- visit (param);
+
+ visit_function_params (function);
+
if (function.has_return_type ())
visit (function.get_return_type ());
if (function.has_where_clause ())
@@ -997,6 +1012,8 @@ DefaultASTVisitor::visit (AST::Trait &trait)
visit_inner_attrs (trait);
+ visit (trait.get_implicit_self ());
+
for (auto &generic : trait.get_generic_params ())
visit (generic);
@@ -1037,6 +1054,7 @@ DefaultASTVisitor::visit (AST::TraitImpl &impl)
if (impl.has_where_clause ())
visit (impl.get_where_clause ());
visit (impl.get_type ());
+ visit (impl.get_trait_path ());
visit_inner_attrs (impl);
for (auto &item : impl.get_impl_items ())
visit (item);
@@ -1058,14 +1076,6 @@ DefaultASTVisitor::visit (AST::ExternalStaticItem &item)
}
void
-DefaultASTVisitor::visit (AST::NamedFunctionParam &param)
-{
- visit_outer_attrs (param);
- if (!param.is_variadic ())
- visit (param.get_type ());
-}
-
-void
DefaultASTVisitor::visit (AST::ExternBlock &block)
{
visit_outer_attrs (block);
@@ -1453,33 +1463,33 @@ DefaultASTVisitor::visit (AST::VariadicParam &param)
void
ContextualASTVisitor::visit (AST::Crate &crate)
{
- push_context (Context::CRATE);
+ ctx.enter (Kind::CRATE);
DefaultASTVisitor::visit (crate);
- pop_context ();
+ ctx.exit ();
}
void
ContextualASTVisitor::visit (AST::InherentImpl &impl)
{
- push_context (Context::INHERENT_IMPL);
+ ctx.enter (Kind::INHERENT_IMPL);
DefaultASTVisitor::visit (impl);
- pop_context ();
+ ctx.exit ();
}
void
ContextualASTVisitor::visit (AST::TraitImpl &impl)
{
- push_context (Context::TRAIT_IMPL);
+ ctx.enter (Kind::TRAIT_IMPL);
DefaultASTVisitor::visit (impl);
- pop_context ();
+ ctx.exit ();
}
void
ContextualASTVisitor::visit (AST::Trait &trait)
{
- push_context (Context::TRAIT);
+ ctx.enter (Kind::TRAIT);
DefaultASTVisitor::visit (trait);
- pop_context ();
+ ctx.exit ();
}
} // namespace AST
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 50b9301..b1fc504 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -26,6 +26,7 @@
#include "rust-item.h"
#include "rust-path.h"
#include "rust-system.h"
+#include "rust-stacked-contexts.h"
namespace Rust {
namespace AST {
@@ -59,8 +60,6 @@ public:
// virtual void visit(TraitImplItem& trait_impl_item) = 0;
// rust-path.h
- virtual void visit (RegularPath &path) = 0;
- virtual void visit (LangItemPath &path) = 0;
virtual void visit (PathInExpression &path) = 0;
virtual void visit (TypePathSegment &segment) = 0;
virtual void visit (TypePathSegmentGeneric &segment) = 0;
@@ -132,6 +131,7 @@ public:
virtual void visit (AwaitExpr &expr) = 0;
virtual void visit (AsyncBlockExpr &expr) = 0;
virtual void visit (InlineAsm &expr) = 0;
+ virtual void visit (LlvmInlineAsm &expr) = 0;
// rust-item.h
virtual void visit (TypeParam &param) = 0;
@@ -242,6 +242,8 @@ public:
class DefaultASTVisitor : public ASTVisitor
{
public:
+ virtual void visit_function_params (AST::Function &function);
+
virtual void visit (AST::Crate &crate);
virtual void visit (AST::Token &tok) override;
@@ -251,8 +253,6 @@ public:
virtual void visit (AST::Lifetime &lifetime) override;
virtual void visit (AST::LifetimeParam &lifetime_param) override;
virtual void visit (AST::ConstGenericParam &const_param) override;
- virtual void visit (AST::RegularPath &path) override;
- virtual void visit (AST::LangItemPath &path) override;
virtual void visit (AST::PathInExpression &path) override;
virtual void visit (AST::TypePathSegment &segment) override;
virtual void visit (AST::TypePathSegmentGeneric &segment) override;
@@ -317,6 +317,7 @@ public:
virtual void visit (AST::AwaitExpr &expr) override;
virtual void visit (AST::AsyncBlockExpr &expr) override;
virtual void visit (InlineAsm &expr) override;
+ virtual void visit (LlvmInlineAsm &expr) override;
virtual void visit (AST::TypeParam &param) override;
virtual void visit (AST::LifetimeWhereClauseItem &item) override;
@@ -427,7 +428,6 @@ public:
virtual void visit (AST::WhereClause &where);
virtual void visit (AST::StructField &field);
virtual void visit (AST::TupleField &field);
- virtual void visit (AST::NamedFunctionParam &param);
virtual void visit (AST::MacroRule &rule);
virtual void visit (AST::MacroInvocData &data);
virtual void visit (AST::MacroTranscriber &transcriber);
@@ -452,7 +452,7 @@ public:
class ContextualASTVisitor : public DefaultASTVisitor
{
protected:
- enum class Context
+ enum class Kind
{
FUNCTION,
INHERENT_IMPL,
@@ -461,6 +461,7 @@ protected:
MODULE,
CRATE,
};
+
using DefaultASTVisitor::visit;
virtual void visit (AST::Crate &crate) override;
@@ -476,11 +477,7 @@ protected:
DefaultASTVisitor::visit (item);
}
- std::vector<Context> context;
-
- void push_context (Context ctx) { context.push_back (ctx); }
-
- void pop_context () { context.pop_back (); }
+ StackedContexts<Kind> ctx;
};
} // namespace AST
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 1d52352..4e82be4 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -272,8 +272,8 @@ Attribute::get_traits_to_derive ()
case AST::MetaItem::ItemKind::Word: {
auto word = static_cast<AST::MetaWord *> (meta_item);
// Convert current word to path
- current
- = make_unique<AST::MetaItemPath> (AST::MetaItemPath (
+ current = std::make_unique<AST::MetaItemPath> (
+ AST::MetaItemPath (
AST::SimplePath (word->get_ident ())));
auto path
= static_cast<AST::MetaItemPath *> (current.get ());
@@ -1068,7 +1068,7 @@ Function::Function (Function const &other)
: VisItem (other), ExternalItem (other.get_node_id ()),
qualifiers (other.qualifiers), function_name (other.function_name),
where_clause (other.where_clause), locus (other.locus),
- is_default (other.is_default),
+ has_default (other.has_default),
is_external_function (other.is_external_function)
{
// guard to prevent null dereference (always required)
@@ -1100,7 +1100,7 @@ Function::operator= (Function const &other)
// visibility = other.visibility->clone_visibility();
// outer_attrs = other.outer_attrs;
locus = other.locus;
- is_default = other.is_default;
+ has_default = other.has_default;
is_external_function = other.is_external_function;
// guard to prevent null dereference (always required)
@@ -1631,7 +1631,7 @@ ContinueExpr::as_string () const
std::string str ("continue ");
if (has_label ())
- str += label.as_string ();
+ str += get_label_unchecked ().as_string ();
return str;
}
@@ -2095,7 +2095,7 @@ WhileLoopExpr::as_string () const
if (!has_loop_label ())
str += "none";
else
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
str += "\n Conditional expr: " + condition->as_string ();
@@ -2115,7 +2115,7 @@ WhileLetLoopExpr::as_string () const
if (!has_loop_label ())
str += "none";
else
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
str += "\n Match arm patterns: ";
if (match_arm_patterns.empty ())
@@ -2146,7 +2146,7 @@ LoopExpr::as_string () const
if (!has_loop_label ())
str += "none";
else
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
str += "\n Loop block: " + loop_block->as_string ();
@@ -2183,7 +2183,7 @@ BreakExpr::as_string () const
std::string str ("break ");
if (has_label ())
- str += label.as_string () + " ";
+ str += get_label_unchecked ().as_string () + " ";
if (has_break_expr ())
str += break_expr->as_string ();
@@ -2485,9 +2485,6 @@ MacroMatchRepetition::as_string () const
std::string
Lifetime::as_string () const
{
- if (is_error ())
- return "error lifetime";
-
switch (lifetime_type)
{
case NAMED:
@@ -2545,7 +2542,7 @@ ForLoopExpr::as_string () const
if (!has_loop_label ())
str += "none";
else
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
str += "\n Pattern: " + pattern->as_string ();
@@ -2612,7 +2609,7 @@ ReferenceType::as_string () const
std::string str ("&");
if (has_lifetime ())
- str += lifetime.as_string () + " ";
+ str += get_lifetime ().as_string () + " ";
if (has_mut)
str += "mut ";
@@ -2998,22 +2995,6 @@ ExternalStaticItem::as_string () const
}
std::string
-NamedFunctionParam::as_string () const
-{
- std::string str = append_attributes (outer_attrs, OUTER);
-
- if (has_name ())
- str += "\n" + name;
-
- if (is_variadic ())
- str += "...";
- else
- str += "\n Type: " + param_type->as_string ();
-
- return str;
-}
-
-std::string
TraitItemConst::as_string () const
{
// TODO: rewrite to work with non-linearisable exprs
@@ -3086,7 +3067,7 @@ SelfParam::as_string () const
else if (has_lifetime ())
{
// ref and lifetime
- std::string str = "&" + lifetime.as_string () + " ";
+ std::string str = "&" + get_lifetime ().as_string () + " ";
if (is_mut)
str += "mut ";
@@ -4286,7 +4267,7 @@ BlockExpr::normalize_tail_expr ()
if (!stmt.is_semicolon_followed ())
{
- expr = std::move (stmt.take_expr ());
+ expr = stmt.take_expr ();
statements.pop_back ();
}
}
@@ -4670,6 +4651,12 @@ InlineAsm::accept_vis (ASTVisitor &vis)
}
void
+LlvmInlineAsm::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
TypeParam::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 42ad011..aa6ad50 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -57,6 +57,11 @@ public:
bool empty () const { return ident.empty (); }
+ bool operator== (const Identifier &other) const
+ {
+ return ident == other.ident;
+ }
+
private:
std::string ident;
location_t loc;
@@ -70,16 +75,6 @@ namespace AST {
class ASTVisitor;
using AttrVec = std::vector<Attribute>;
-// The available kinds of AST Nodes
-enum class Kind
-{
- UNKNOWN,
- MODULE,
- MACRO_RULES_DEFINITION,
- MACRO_INVOCATION,
- IDENTIFIER,
-};
-
class Visitable
{
public:
@@ -87,20 +82,6 @@ public:
virtual void accept_vis (ASTVisitor &vis) = 0;
};
-// Abstract base class for all AST elements
-class Node : public Visitable
-{
-public:
- /**
- * Get the kind of Node this is. This is used to differentiate various AST
- * elements with very little overhead when extracting the derived type
- * through static casting is not necessary.
- */
- // FIXME: Mark this as `= 0` in the future to make sure every node
- // implements it
- virtual Kind get_ast_kind () const { return Kind::UNKNOWN; }
-};
-
// Delimiter types - used in macros and whatever.
enum DelimType
{
@@ -681,6 +662,9 @@ public:
// Returns whether the attribute is considered an "empty" attribute.
bool is_empty () const { return attr_input == nullptr && path.is_empty (); }
+ // Returns whether the attribute has no input
+ bool empty_input () const { return !attr_input; }
+
location_t get_locus () const { return locus; }
AttrInput &get_attr_input () const { return *attr_input; }
@@ -1039,6 +1023,7 @@ public:
}
DelimType get_delim_type () const { return delim_type; }
+ location_t get_locus () const { return locus; }
};
/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
@@ -1092,7 +1077,7 @@ class MetaListNameValueStr;
/* Base statement abstract class. Note that most "statements" are not allowed
* in top-level module scope - only a subclass of statements called "items"
* are. */
-class Stmt : public Node
+class Stmt : public Visitable
{
public:
enum class Kind
@@ -1141,6 +1126,28 @@ protected:
class Item : public Stmt
{
public:
+ enum class Kind
+ {
+ MacroRulesDefinition,
+ MacroInvocation,
+ Module,
+ ExternCrate,
+ UseDeclaration,
+ Function,
+ TypeAlias,
+ Struct,
+ EnumItem,
+ Enum,
+ Union,
+ ConstantItem,
+ StaticItem,
+ Trait,
+ Impl,
+ ExternBlock,
+ };
+
+ virtual Kind get_item_kind () const = 0;
+
// Unique pointer custom clone function
std::unique_ptr<Item> clone_item () const
{
@@ -1221,14 +1228,65 @@ public:
{
return outer_attrs;
}
+
+ virtual Item::Kind get_item_kind () const override = 0;
};
+
// forward decl of ExprWithoutBlock
class ExprWithoutBlock;
// Base expression AST node - abstract
-class Expr : public Node
+class Expr : public Visitable
{
public:
+ enum class Kind
+ {
+ PathInExpression,
+ QualifiedPathInExpression,
+ Literal,
+ Operator,
+ Grouped,
+ Array,
+ ArrayIndex,
+ Tuple,
+ TupleIndex,
+ Struct,
+ Call,
+ MethodCall,
+ FieldAccess,
+ Closure,
+ Block,
+ Continue,
+ Break,
+ Range,
+ Box,
+ Return,
+ UnsafeBlock,
+ Loop,
+ If,
+ IfLet,
+ Match,
+ Await,
+ AsyncBlock,
+ InlineAsm,
+ LlvmInlineAsm,
+ Identifier,
+ FormatArgs,
+ MacroInvocation,
+ Borrow,
+ Dereference,
+ ErrorPropagation,
+ Negation,
+ ArithmeticOrLogical,
+ Comparison,
+ LazyBoolean,
+ TypeCast,
+ Assignment,
+ CompoundAssignment,
+ };
+
+ virtual Kind get_expr_kind () const = 0;
+
// Unique pointer custom clone function
std::unique_ptr<Expr> clone_expr () const
{
@@ -1343,7 +1401,7 @@ public:
outer_attrs = std::move (new_attrs);
}
- Kind get_ast_kind () const override { return Kind::IDENTIFIER; }
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Identifier; }
protected:
// Clone method implementation
@@ -1410,7 +1468,7 @@ protected:
class TraitBound;
// Base class for types as represented in AST - abstract
-class Type : public Node
+class Type : public Visitable
{
public:
// Unique pointer custom clone function
@@ -1539,17 +1597,9 @@ public:
lifetime_name (std::move (name)), locus (locus)
{}
- // Creates an "error" lifetime.
- static Lifetime error () { return Lifetime (NAMED, ""); }
-
static Lifetime elided () { return Lifetime (WILDCARD, ""); }
// Returns true if the lifetime is in an error state.
- bool is_error () const
- {
- return lifetime_type == NAMED && lifetime_name.empty ();
- }
-
std::string as_string () const override;
void accept_vis (ASTVisitor &vis) override;
@@ -1640,15 +1690,6 @@ public:
// Returns whether the lifetime param has an outer attribute.
bool has_outer_attribute () const { return !outer_attrs.empty (); }
- // Creates an error state lifetime param.
- static LifetimeParam create_error ()
- {
- return LifetimeParam (Lifetime::error (), {}, {}, UNDEF_LOCATION);
- }
-
- // Returns whether the lifetime param is in an error state.
- bool is_error () const { return lifetime.is_error (); }
-
// Constructor
LifetimeParam (Lifetime lifetime, std::vector<Lifetime> lifetime_bounds,
AST::AttrVec outer_attrs, location_t locus)
@@ -1948,13 +1989,6 @@ public:
return std::move (item);
}
- std::unique_ptr<AssociatedItem> take_trait_item ()
- {
- rust_assert (!is_error ());
- return std::unique_ptr<AssociatedItem> (
- static_cast<AssociatedItem *> (assoc_item.release ()));
- }
-
std::unique_ptr<ExternalItem> take_external_item ()
{
rust_assert (!is_error ());
@@ -1967,16 +2001,6 @@ public:
return std::move (assoc_item);
}
- std::unique_ptr<AssociatedItem> take_impl_item ()
- {
- return take_assoc_item ();
- }
-
- std::unique_ptr<AssociatedItem> take_trait_impl_item ()
- {
- return take_assoc_item ();
- }
-
std::unique_ptr<Type> take_type ()
{
rust_assert (!is_error ());
@@ -2078,6 +2102,19 @@ template <> struct less<Rust::Identifier>
return lhs.as_string () < rhs.as_string ();
}
};
+
+template <> struct hash<Rust::Identifier>
+{
+ std::size_t operator() (const Rust::Identifier &k) const
+ {
+ using std::hash;
+ using std::size_t;
+ using std::string;
+
+ return hash<string> () (k.as_string ()) ^ (hash<int> () (k.get_locus ()));
+ }
+};
+
} // namespace std
#endif
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h b/gcc/rust/ast/rust-builtin-ast-nodes.h
index 7ebd656..3684092 100644
--- a/gcc/rust/ast/rust-builtin-ast-nodes.h
+++ b/gcc/rust/ast/rust-builtin-ast-nodes.h
@@ -202,6 +202,8 @@ public:
const FormatArguments &get_arguments () const { return arguments; }
virtual location_t get_locus () const override;
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::FormatArgs; }
+
private:
location_t loc;
// FIXME: This probably needs to be a separate type - it is one in rustc's
diff --git a/gcc/rust/ast/rust-collect-lang-items.cc b/gcc/rust/ast/rust-collect-lang-items.cc
new file mode 100644
index 0000000..cd6be7f
--- /dev/null
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -0,0 +1,113 @@
+// Copyright (C) 2024 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-collect-lang-items.h"
+#include "optional.h"
+#include "rust-ast-collector.h"
+#include "rust-ast-visitor.h"
+#include "rust-ast.h"
+#include "rust-attribute-values.h"
+#include "rust-attributes.h"
+#include "rust-hir-map.h"
+#include "rust-item.h"
+
+namespace Rust {
+namespace AST {
+
+template <typename T>
+tl::optional<LangItem::Kind>
+get_lang_item_attr (const T &maybe_lang_item)
+{
+ for (const auto &attr : maybe_lang_item.get_outer_attrs ())
+ {
+ const auto &str_path = attr.get_path ().as_string ();
+ if (!Analysis::Attributes::is_known (str_path))
+ {
+ rust_error_at (attr.get_locus (), "unknown attribute %qs",
+ str_path.c_str ());
+ continue;
+ }
+
+ bool is_lang_item = str_path == Values::Attributes::LANG
+ && attr.has_attr_input ()
+ && attr.get_attr_input ().get_attr_input_type ()
+ == AST::AttrInput::AttrInputType::LITERAL;
+
+ if (is_lang_item)
+ {
+ auto &literal
+ = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
+ const auto &lang_item_type_str = literal.get_literal ().as_string ();
+
+ return LangItem::Parse (lang_item_type_str);
+ }
+ }
+
+ return tl::nullopt;
+}
+
+template <typename T>
+void
+CollectLangItems::maybe_add_lang_item (const T &item)
+{
+ if (auto lang_item = get_lang_item_attr (item))
+ mappings.insert_lang_item_node (lang_item.value (), item.get_node_id ());
+}
+
+void
+CollectLangItems::visit (AST::Trait &item)
+{
+ maybe_add_lang_item (item);
+
+ DefaultASTVisitor::visit (item);
+}
+
+void
+CollectLangItems::visit (AST::TraitItemType &item)
+{
+ maybe_add_lang_item (item);
+
+ DefaultASTVisitor::visit (item);
+}
+
+void
+CollectLangItems::visit (AST::Function &item)
+{
+ maybe_add_lang_item (item);
+
+ DefaultASTVisitor::visit (item);
+}
+
+void
+CollectLangItems::visit (AST::StructStruct &item)
+{
+ maybe_add_lang_item (item);
+
+ DefaultASTVisitor::visit (item);
+}
+
+void
+CollectLangItems::visit (AST::EnumItem &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
new file mode 100644
index 0000000..ddb34a9
--- /dev/null
+++ b/gcc/rust/ast/rust-collect-lang-items.h
@@ -0,0 +1,61 @@
+// Copyright (C) 2024 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_COLLECT_LANG_ITEMS_H
+#define RUST_COLLECT_LANG_ITEMS_H
+
+#include "rust-ast-visitor.h"
+#include "rust-ast.h"
+#include "rust-hir-map.h"
+#include "rust-item.h"
+
+namespace Rust {
+namespace AST {
+
+// This class collects lang items ahead of lowering, as they are now needed for
+// some parts of name resolution
+class CollectLangItems : public DefaultASTVisitor
+{
+public:
+ CollectLangItems () : mappings (Analysis::Mappings::get ()){};
+
+ void go (AST::Crate &crate) { DefaultASTVisitor::visit (crate); }
+
+ Analysis::Mappings &mappings;
+
+ // We must implement visitors for all constructs that could be lang items.
+ // Lang items can be traits, but also enums, and even enum variants.
+ //
+ // https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir/src/lang_items.rs
+
+ using DefaultASTVisitor::visit;
+
+ void visit (AST::Trait &item) override;
+ void visit (AST::TraitItemType &item) override;
+ void visit (AST::Function &item) override;
+ void visit (AST::StructStruct &item) override;
+ void visit (AST::EnumItem &item) override;
+
+private:
+ template <typename T> void maybe_add_lang_item (const T &item);
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_COLLECT_LANG_ITEMS_H
diff --git a/gcc/rust/ast/rust-desugar-for-loops.cc b/gcc/rust/ast/rust-desugar-for-loops.cc
new file mode 100644
index 0000000..ffc3470
--- /dev/null
+++ b/gcc/rust/ast/rust-desugar-for-loops.cc
@@ -0,0 +1,204 @@
+// 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-for-loops.h"
+#include "rust-ast-visitor.h"
+#include "rust-ast.h"
+#include "rust-hir-map.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-stmt.h"
+#include "rust-expr.h"
+#include "rust-ast-builder.h"
+
+namespace Rust {
+namespace AST {
+
+DesugarForLoops::DesugarForLoops () {}
+
+void
+DesugarForLoops::go (AST::Crate &crate)
+{
+ DefaultASTVisitor::visit (crate);
+}
+
+static void
+replace_for_loop (std::unique_ptr<Expr> &for_loop,
+ std::unique_ptr<Expr> &&expanded)
+{
+ for_loop = std::move (expanded);
+}
+
+MatchArm
+DesugarForLoops::DesugarCtx::make_match_arm (std::unique_ptr<Pattern> &&path)
+{
+ auto patterns = std::vector<std::unique_ptr<Pattern>> ();
+ patterns.emplace_back (std::move (path));
+
+ return MatchArm (std::move (patterns), loc);
+}
+
+MatchCase
+DesugarForLoops::DesugarCtx::make_break_arm ()
+{
+ auto arm = make_match_arm (std::unique_ptr<Pattern> (new PathInExpression (
+ builder.path_in_expression (LangItem::Kind::OPTION_NONE))));
+
+ auto break_expr
+ = std::unique_ptr<Expr> (new BreakExpr (tl::nullopt, nullptr, {}, loc));
+
+ return MatchCase (std::move (arm), std::move (break_expr));
+}
+
+MatchCase
+DesugarForLoops::DesugarCtx::make_continue_arm ()
+{
+ auto val = builder.identifier_pattern (DesugarCtx::continue_pattern_id);
+
+ auto patterns = std::vector<std::unique_ptr<Pattern>> ();
+ patterns.emplace_back (std::move (val));
+
+ auto pattern_item = std::unique_ptr<TupleStructItems> (
+ new TupleStructItemsNoRange (std::move (patterns)));
+ auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
+ builder.path_in_expression (LangItem::Kind::OPTION_SOME),
+ std::move (pattern_item)));
+
+ auto val_arm = make_match_arm (std::move (pattern));
+
+ auto next = builder.identifier (DesugarCtx::next_value_id);
+
+ auto assignment = std::unique_ptr<Expr> (
+ new AssignmentExpr (std::move (next),
+ builder.identifier (DesugarCtx::continue_pattern_id),
+ {}, loc));
+
+ return MatchCase (std::move (val_arm), std::move (assignment));
+}
+
+std::unique_ptr<Stmt>
+DesugarForLoops::DesugarCtx::statementify (std::unique_ptr<Expr> &&expr)
+{
+ return std::unique_ptr<Stmt> (new ExprStmt (std::move (expr), loc, true));
+}
+
+std::unique_ptr<Expr>
+DesugarForLoops::desugar (AST::ForLoopExpr &expr)
+{
+ auto ctx = DesugarCtx (expr.get_locus ());
+
+ auto into_iter = std::make_unique<PathInExpression> (
+ ctx.builder.path_in_expression (LangItem::Kind::INTOITER_INTOITER));
+ auto next = std::make_unique<PathInExpression> (
+ ctx.builder.path_in_expression (LangItem::Kind::ITERATOR_NEXT));
+
+ // IntoIterator::into_iter(<head>)
+ auto into_iter_call
+ = ctx.builder.call (std::move (into_iter),
+ expr.get_iterator_expr ().clone_expr ());
+
+ // Iterator::next(iter)
+ auto next_call = ctx.builder.call (
+ std::move (next),
+ ctx.builder.ref (ctx.builder.identifier (DesugarCtx::iter_id), true));
+
+ // None => break,
+ auto break_arm = ctx.make_break_arm ();
+ // Some(val) => __next = val; },
+ auto continue_arm = ctx.make_continue_arm ();
+
+ // match <next_call> {
+ // <continue_arm>
+ // <break_arm>
+ // }
+ auto match_next
+ = ctx.builder.match (std::move (next_call),
+ {std::move (continue_arm), std::move (break_arm)});
+
+ // let mut __next;
+ auto let_next = ctx.builder.let (
+ ctx.builder.identifier_pattern (DesugarCtx::next_value_id, true));
+ // let <pattern> = __next;
+ auto let_pat
+ = ctx.builder.let (expr.get_pattern ().clone_pattern (), nullptr,
+ ctx.builder.identifier (DesugarCtx::next_value_id));
+
+ auto loop_stmts = std::vector<std::unique_ptr<Stmt>> ();
+ loop_stmts.emplace_back (std::move (let_next));
+ loop_stmts.emplace_back (ctx.statementify (std::move (match_next)));
+ loop_stmts.emplace_back (std::move (let_pat));
+ loop_stmts.emplace_back (
+ ctx.statementify (expr.get_loop_block ().clone_expr ()));
+
+ // loop {
+ // <let_next>;
+ // <match_next>;
+ // <let_pat>;
+ //
+ // <body>;
+ // }
+ auto loop = ctx.builder.loop (std::move (loop_stmts));
+
+ auto mut_iter_pattern
+ = ctx.builder.identifier_pattern (DesugarCtx::iter_id, true);
+ auto match_iter
+ = ctx.builder.match (std::move (into_iter_call),
+ {ctx.builder.match_case (std::move (mut_iter_pattern),
+ std::move (loop))});
+
+ auto let_result
+ = ctx.builder.let (ctx.builder.identifier_pattern (DesugarCtx::result_id),
+ nullptr, std::move (match_iter));
+ auto result_return = ctx.builder.identifier (DesugarCtx::result_id);
+
+ return ctx.builder.block (std::move (let_result), std::move (result_return));
+}
+
+void
+DesugarForLoops::maybe_desugar_expr (std::unique_ptr<Expr> &expr)
+{
+ if (expr->get_expr_kind () == AST::Expr::Kind::Loop)
+ {
+ auto &loop = static_cast<AST::BaseLoopExpr &> (*expr);
+
+ if (loop.get_loop_kind () == AST::BaseLoopExpr::Kind::For)
+ {
+ auto &for_loop = static_cast<AST::ForLoopExpr &> (loop);
+
+ auto desugared = desugar (for_loop);
+
+ replace_for_loop (expr, std::move (desugared));
+ }
+ }
+}
+
+void
+DesugarForLoops::visit (AST::BlockExpr &block)
+{
+ for (auto &stmt : block.get_statements ())
+ if (stmt->get_stmt_kind () == AST::Stmt::Kind::Expr)
+ maybe_desugar_expr (static_cast<AST::ExprStmt &> (*stmt).get_expr_ptr ());
+
+ if (block.has_tail_expr ())
+ maybe_desugar_expr (block.get_tail_expr_ptr ());
+
+ DefaultASTVisitor::visit (block);
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-desugar-for-loops.h b/gcc/rust/ast/rust-desugar-for-loops.h
new file mode 100644
index 0000000..7beb692
--- /dev/null
+++ b/gcc/rust/ast/rust-desugar-for-loops.h
@@ -0,0 +1,108 @@
+// 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_DESUGAR_FOR_LOOPS_H
+#define RUST_DESUGAR_FOR_LOOPS_H
+
+#include "rust-ast-builder.h"
+#include "rust-ast-visitor.h"
+#include "rust-expr.h"
+
+namespace Rust {
+namespace AST {
+
+// Desugar for-loops into a set of other AST nodes. The desugar is of the
+// following form:
+//
+// ```
+// for <pat> in <head> <body>
+// ```
+//
+// becomes:
+//
+// ```
+// {
+// let result = match ::std::iter::IntoIterator::into_iter(<head>) {
+// mut iter => {
+// loop {
+// let mut __next;
+// match ::std::iter::Iterator::next(&mut iter) {
+// ::std::option::Option::Some(val) => __next = val,
+// ::std::option::Option::None => break
+// };
+// let <pat> = __next;
+//
+// <body>;
+// }
+// }
+// };
+// result
+// }
+// ```
+//
+// NOTE: In a perfect world, this would be an immutable visitor which would take
+// ownership of the AST node and return a new one, instead of mutating this one
+// in place. Nevertheless, this isn't Rust, and doing immutable visitors in C++
+// sucks, and the world isn't perfect, so we are impure and sad.
+//
+// NOTE: This class could eventually be removed in favor of
+// an HIR desugar. This would avoid mutating the AST and would be cleaner.
+// However, it requires multiple changes in the way we do typechecking and name
+// resolution, as this desugar creates new bindings. Because of this, these new
+// bindings need to be inserted into the name-resolution context outside of the
+// name resolution pass, which is difficult. Those bindings are needed because
+// of the way the typechecker is currently structured, where it will fetch name
+// resolution information in order to typecheck paths - which technically isn't
+// necessary.
+class DesugarForLoops : public DefaultASTVisitor
+{
+ using DefaultASTVisitor::visit;
+
+public:
+ DesugarForLoops ();
+ void go (AST::Crate &);
+
+private:
+ struct DesugarCtx
+ {
+ DesugarCtx (location_t loc) : builder (Builder (loc)), loc (loc) {}
+
+ Builder builder;
+ location_t loc;
+
+ MatchArm make_match_arm (std::unique_ptr<Pattern> &&pattern);
+ MatchCase make_break_arm ();
+ MatchCase make_continue_arm ();
+ std::unique_ptr<Stmt> statementify (std::unique_ptr<Expr> &&expr);
+
+ constexpr static const char *continue_pattern_id = "#val";
+ constexpr static const char *next_value_id = "#__next";
+ constexpr static const char *iter_id = "#iter";
+ constexpr static const char *result_id = "#result";
+ };
+
+ std::unique_ptr<Expr> desugar (AST::ForLoopExpr &expr);
+ void maybe_desugar_expr (std::unique_ptr<Expr> &expr);
+
+ void visit (AST::BlockExpr &) override;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_DESUGAR_FOR_LOOPS_H
diff --git a/gcc/rust/ast/rust-desugar-question-mark.cc b/gcc/rust/ast/rust-desugar-question-mark.cc
new file mode 100644
index 0000000..4d2933b
--- /dev/null
+++ b/gcc/rust/ast/rust-desugar-question-mark.cc
@@ -0,0 +1,167 @@
+// 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-question-mark.h"
+#include "rust-ast-builder.h"
+#include "rust-ast-visitor.h"
+
+namespace Rust {
+namespace AST {
+
+DesugarQuestionMark::DesugarQuestionMark () {}
+
+void
+DesugarQuestionMark::go (AST::Crate &crate)
+{
+ DesugarQuestionMark::visit (crate);
+}
+
+void
+DesugarQuestionMark::visit (ExprStmt &stmt)
+{
+ if (stmt.get_expr ().get_expr_kind () == Expr::Kind::ErrorPropagation)
+ desugar_and_replace (stmt.get_expr_ptr ());
+
+ DefaultASTVisitor::visit (stmt);
+}
+
+void
+DesugarQuestionMark::visit (CallExpr &call)
+{
+ if (call.get_function_expr ().get_expr_kind ()
+ == Expr::Kind::ErrorPropagation)
+ desugar_and_replace (call.get_function_expr_ptr ());
+
+ for (auto &arg : call.get_params ())
+ if (arg->get_expr_kind () == Expr::Kind::ErrorPropagation)
+ desugar_and_replace (arg);
+
+ DefaultASTVisitor::visit (call);
+}
+
+void
+DesugarQuestionMark::visit (LetStmt &stmt)
+{
+ if (stmt.has_init_expr ()
+ && stmt.get_init_expr ().get_expr_kind () == Expr::Kind::ErrorPropagation)
+ desugar_and_replace (stmt.get_init_expr_ptr ());
+
+ DefaultASTVisitor::visit (stmt);
+}
+
+MatchArm
+make_match_arm (std::unique_ptr<Pattern> &&pattern)
+{
+ auto loc = pattern->get_locus ();
+
+ auto patterns = std::vector<std::unique_ptr<Pattern>> ();
+ patterns.emplace_back (std::move (pattern));
+
+ return MatchArm (std::move (patterns), loc);
+}
+
+MatchCase
+ok_case (Builder &builder)
+{
+ auto val = builder.identifier_pattern ("val");
+
+ auto patterns = std::vector<std::unique_ptr<Pattern>> ();
+ patterns.emplace_back (std::move (val));
+
+ auto pattern_item = std::unique_ptr<TupleStructItems> (
+ new TupleStructItemsNoRange (std::move (patterns)));
+ auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
+ builder.path_in_expression (LangItem::Kind::RESULT_OK),
+ std::move (pattern_item)));
+
+ auto arm = make_match_arm (std::move (pattern));
+
+ auto ret_val = builder.identifier ("val");
+
+ return MatchCase (std::move (arm), std::move (ret_val));
+}
+
+MatchCase
+err_case (Builder &builder)
+{
+ auto val = builder.identifier_pattern ("err");
+
+ auto patterns = std::vector<std::unique_ptr<Pattern>> ();
+ patterns.emplace_back (std::move (val));
+
+ auto pattern_item = std::unique_ptr<TupleStructItems> (
+ new TupleStructItemsNoRange (std::move (patterns)));
+ auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
+ builder.path_in_expression (LangItem::Kind::RESULT_ERR),
+ std::move (pattern_item)));
+
+ auto arm = make_match_arm (std::move (pattern));
+
+ auto try_from_err = std::make_unique<PathInExpression> (
+ builder.path_in_expression (LangItem::Kind::TRY_FROM_ERROR));
+ auto from_from = std::make_unique<PathInExpression> (
+ builder.path_in_expression (LangItem::Kind::FROM_FROM));
+
+ auto early_return = builder.return_expr (
+ builder.call (std::move (try_from_err),
+ builder.call (std::move (from_from),
+ builder.identifier ("err"))));
+
+ return MatchCase (std::move (arm), std::move (early_return));
+}
+
+std::unique_ptr<Expr>
+DesugarQuestionMark::desugar (ErrorPropagationExpr &expr)
+{
+ auto builder = Builder (expr.get_locus ());
+
+ // Try::into_result(<expr>)
+ auto try_into = std::make_unique<PathInExpression> (
+ builder.path_in_expression (LangItem::Kind::TRY_INTO_RESULT));
+ auto call = builder.call (std::move (try_into),
+ expr.get_propagating_expr ().clone_expr ());
+
+ // Ok(val) => val,
+ auto ok_match_case = ok_case (builder);
+ // Err(err) => return Try::from_error(From::from(err)),
+ auto err_match_case = err_case (builder);
+
+ auto cases = std::vector<MatchCase> ();
+ cases.emplace_back (ok_match_case);
+ cases.emplace_back (err_match_case);
+
+ // match <call> {
+ // <ok_arm>
+ // <err_arm>
+ // }
+ return std::unique_ptr<MatchExpr> (new MatchExpr (std::move (call),
+ std::move (cases), {}, {},
+ expr.get_locus ()));
+}
+
+void
+DesugarQuestionMark::desugar_and_replace (std::unique_ptr<Expr> &ptr)
+{
+ auto original = static_cast<ErrorPropagationExpr &> (*ptr);
+ auto desugared = desugar (original);
+
+ ptr = std::move (desugared);
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-desugar-question-mark.h b/gcc/rust/ast/rust-desugar-question-mark.h
new file mode 100644
index 0000000..e4c513f
--- /dev/null
+++ b/gcc/rust/ast/rust-desugar-question-mark.h
@@ -0,0 +1,79 @@
+// 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_DESUGAR_QUESTION_MARK
+#define RUST_DESUGAR_QUESTION_MARK
+
+#include "rust-ast-visitor.h"
+#include "rust-expr.h"
+#include "rust-stmt.h"
+
+namespace Rust {
+namespace AST {
+
+// NOTE: One more complexity compare to desugaring for-loops is that we need to
+// desugar every possible expression... should we do that during lowering
+// instead? but would it get resolved and expanded etc? Not sure...
+
+// The goal of this desugar is to go from this:
+//
+// ```
+// <expr>?
+// ```
+//
+// to this:
+//
+// ```
+// match Try::into_result(<expr>) {
+// Ok(val) => val,
+// Err(err) => return Try::from_err(From::from(err))
+// }
+// ```
+//
+// We use lang items for almost everything, so the actual desugared code looks
+// more like this:
+//
+// ```
+// match #[lang = "into_result"](<expr>) {
+// #[lang = "Ok"](val) => val,
+// #[lang = "Err"](err) => {
+// return #[lang = "from_error"](#[lang ="from"](err))
+// }
+// }
+// ```
+class DesugarQuestionMark : public DefaultASTVisitor
+{
+ using DefaultASTVisitor::visit;
+
+public:
+ DesugarQuestionMark ();
+ void go (AST::Crate &);
+
+private:
+ void desugar_and_replace (std::unique_ptr<Expr> &ptr);
+ std::unique_ptr<Expr> desugar (ErrorPropagationExpr &);
+
+ void visit (AST::ExprStmt &) override;
+ void visit (AST::CallExpr &) override;
+ void visit (AST::LetStmt &) override;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_DESUGAR_QUESTION_MARK
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 438d3d3..fdb6360 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -15,7 +15,7 @@ namespace AST {
// Loop label expression AST node used with break and continue expressions
// TODO: inline?
-class LoopLabel /*: public Node*/
+class LoopLabel /*: public Visitable*/
{
Lifetime label; // or type LIFETIME_OR_LABEL
location_t locus;
@@ -31,11 +31,6 @@ public:
{}
// Returns whether the LoopLabel is in an error state.
- bool is_error () const { return label.is_error (); }
-
- // Creates an error state LoopLabel.
- static LoopLabel error () { return LoopLabel (Lifetime::error ()); }
-
location_t get_locus () const { return locus; }
Lifetime &get_lifetime () { return label; }
@@ -117,6 +112,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Literal; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -365,6 +362,8 @@ public:
{
outer_attrs = std::move (new_attrs);
}
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Operator; }
};
/* Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be
@@ -403,6 +402,8 @@ public:
bool get_is_double_borrow () const { return double_borrow; }
bool is_raw_borrow () const { return raw_borrow; }
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Borrow; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -433,6 +434,8 @@ public:
return *main_or_left_expr;
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Dereference; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -464,6 +467,11 @@ public:
return *main_or_left_expr;
}
+ Expr::Kind get_expr_kind () const override
+ {
+ return Expr::Kind::ErrorPropagation;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -507,6 +515,8 @@ public:
return *main_or_left_expr;
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Negation; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -595,6 +605,11 @@ public:
void visit_lhs (ASTVisitor &vis) { main_or_left_expr->accept_vis (vis); }
void visit_rhs (ASTVisitor &vis) { right_expr->accept_vis (vis); }
+ Expr::Kind get_expr_kind () const override
+ {
+ return Expr::Kind::ArithmeticOrLogical;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -682,6 +697,8 @@ public:
ExprType get_kind () { return expr_type; }
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Comparison; }
+
/* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2)
* maybe? */
protected:
@@ -770,6 +787,8 @@ public:
ExprType get_kind () { return expr_type; }
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::LazyBoolean; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -832,6 +851,8 @@ public:
return *type_to_convert_to;
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::TypeCast; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -910,6 +931,8 @@ public:
return *right_expr;
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Assignment; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -996,6 +1019,11 @@ public:
return right_expr;
}
+ Expr::Kind get_expr_kind () const override
+ {
+ return Expr::Kind::CompoundAssignment;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1090,6 +1118,8 @@ public:
return expr_in_parens;
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Grouped; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1319,6 +1349,8 @@ public:
return internal_elements;
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Array; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1424,6 +1456,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::ArrayIndex; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1520,6 +1554,8 @@ public:
bool is_unit () const { return tuple_elems.size () == 0; }
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Tuple; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1607,6 +1643,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::TupleIndex; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1650,6 +1688,8 @@ public:
{
outer_attrs = std::move (new_attrs);
}
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Struct; }
};
// Actual AST node of the struct creator (with no fields). Not abstract!
@@ -2123,6 +2163,8 @@ public:
return *function;
}
+ std::unique_ptr<Expr> &get_function_expr_ptr () { return function; }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -2131,6 +2173,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Call; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2234,6 +2278,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::MethodCall; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2319,6 +2365,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::FieldAccess; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2454,6 +2502,8 @@ public:
}
bool get_has_move () const { return has_move; }
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Closure; }
};
// Represents a non-type-specified closure expression AST node
@@ -2535,7 +2585,7 @@ class BlockExpr : public ExprWithBlock
std::vector<Attribute> inner_attrs;
std::vector<std::unique_ptr<Stmt> > statements;
std::unique_ptr<Expr> expr;
- LoopLabel label;
+ tl::optional<LoopLabel> label;
location_t start_locus;
location_t end_locus;
bool marked_for_strip = false;
@@ -2552,8 +2602,9 @@ public:
BlockExpr (std::vector<std::unique_ptr<Stmt> > block_statements,
std::unique_ptr<Expr> block_expr,
std::vector<Attribute> inner_attribs,
- std::vector<Attribute> outer_attribs, LoopLabel label,
- location_t start_locus, location_t end_locus)
+ std::vector<Attribute> outer_attribs,
+ tl::optional<LoopLabel> label, location_t start_locus,
+ location_t end_locus)
: outer_attrs (std::move (outer_attribs)),
inner_attrs (std::move (inner_attribs)),
statements (std::move (block_statements)), expr (std::move (block_expr)),
@@ -2672,8 +2723,10 @@ public:
outer_attrs = std::move (new_attrs);
}
- bool has_label () { return !label.is_error (); }
- LoopLabel &get_label () { return label; }
+ bool has_label () { return label.has_value (); }
+ LoopLabel &get_label () { return label.value (); }
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Block; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -2791,7 +2844,7 @@ protected:
class ContinueExpr : public ExprWithoutBlock
{
std::vector<Attribute> outer_attrs;
- Lifetime label;
+ tl::optional<Lifetime> label;
location_t locus;
// TODO: find another way to store this to save memory?
@@ -2801,11 +2854,11 @@ public:
std::string as_string () const override;
// Returns true if the continue expr has a label.
- bool has_label () const { return !label.is_error (); }
+ bool has_label () const { return label.has_value (); }
// Constructor for a ContinueExpr with a label.
- ContinueExpr (Lifetime label, std::vector<Attribute> outer_attribs,
- location_t locus)
+ ContinueExpr (tl::optional<Lifetime> label,
+ std::vector<Attribute> outer_attribs, location_t locus)
: outer_attrs (std::move (outer_attribs)), label (std::move (label)),
locus (locus)
{}
@@ -2826,7 +2879,13 @@ public:
outer_attrs = std::move (new_attrs);
}
- Lifetime &get_label () { return label; }
+ Lifetime &get_label_unchecked () { return label.value (); }
+ const Lifetime &get_label_unchecked () const { return label.value (); }
+
+ tl::optional<Lifetime> &get_label () { return label; }
+ const tl::optional<Lifetime> &get_label () const { return label; }
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Continue; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -2842,7 +2901,7 @@ protected:
class BreakExpr : public ExprWithoutBlock
{
std::vector<Attribute> outer_attrs;
- LoopLabel label;
+ tl::optional<LoopLabel> label;
std::unique_ptr<Expr> break_expr;
location_t locus;
@@ -2853,14 +2912,15 @@ public:
std::string as_string () const override;
// Returns whether the break expression has a label or not.
- bool has_label () const { return !label.is_error (); }
+ bool has_label () const { return label.has_value (); }
/* Returns whether the break expression has an expression used in the break or
* not. */
bool has_break_expr () const { return break_expr != nullptr; }
// Constructor for a break expression
- BreakExpr (LoopLabel break_label, std::unique_ptr<Expr> expr_in_break,
+ BreakExpr (tl::optional<LoopLabel> break_label,
+ std::unique_ptr<Expr> expr_in_break,
std::vector<Attribute> outer_attribs, location_t locus)
: outer_attrs (std::move (outer_attribs)), label (std::move (break_label)),
break_expr (std::move (expr_in_break)), locus (locus)
@@ -2922,7 +2982,13 @@ public:
outer_attrs = std::move (new_attrs);
}
- LoopLabel &get_label () { return label; }
+ LoopLabel &get_label_unchecked () { return label.value (); }
+ const LoopLabel &get_label_unchecked () const { return label.value (); }
+
+ tl::optional<LoopLabel> &get_label () { return label; }
+ const tl::optional<LoopLabel> &get_label () const { return label; }
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Break; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -2938,6 +3004,10 @@ class RangeExpr : public ExprWithoutBlock
{
location_t locus;
+ // Some visitors still check for attributes on RangeExprs, and they will need
+ // to be supported in the future - so keep that for now
+ std::vector<Attribute> empty_attributes = {};
+
protected:
// outer attributes not allowed before range expressions
RangeExpr (location_t locus) : locus (locus) {}
@@ -2947,15 +3017,13 @@ public:
std::vector<Attribute> &get_outer_attrs () override final
{
- // RangeExpr cannot have any outer attributes
- rust_assert (false);
+ return empty_attributes;
}
// should never be called - error if called
- void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override
- {
- rust_assert (false);
- }
+ void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override {}
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Range; }
};
// Range from (inclusive) and to (exclusive) expression AST node object
@@ -3404,6 +3472,8 @@ public:
return *expr;
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Box; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3491,6 +3561,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Return; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3573,6 +3645,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::UnsafeBlock; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3588,7 +3662,7 @@ class BaseLoopExpr : public ExprWithBlock
protected:
// protected to allow subclasses better use of them
std::vector<Attribute> outer_attrs;
- LoopLabel loop_label;
+ tl::optional<LoopLabel> loop_label;
std::unique_ptr<BlockExpr> loop_block;
private:
@@ -3597,7 +3671,7 @@ private:
protected:
// Constructor for BaseLoopExpr
BaseLoopExpr (std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs
= std::vector<Attribute> ())
: outer_attrs (std::move (outer_attribs)),
@@ -3637,9 +3711,10 @@ protected:
BaseLoopExpr &operator= (BaseLoopExpr &&other) = default;
public:
- bool has_loop_label () const { return !loop_label.is_error (); }
+ bool has_loop_label () const { return loop_label.has_value (); }
- LoopLabel &get_loop_label () { return loop_label; }
+ LoopLabel &get_loop_label () { return loop_label.value (); }
+ const LoopLabel &get_loop_label () const { return loop_label.value (); }
location_t get_locus () const override final { return locus; }
@@ -3661,6 +3736,18 @@ public:
{
outer_attrs = std::move (new_attrs);
}
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Loop; }
+
+ enum class Kind
+ {
+ Loop,
+ While,
+ WhileLet,
+ For
+ };
+
+ virtual Kind get_loop_kind () const = 0;
};
// 'Loop' expression (i.e. the infinite loop) AST node
@@ -3671,7 +3758,7 @@ public:
// Constructor for LoopExpr
LoopExpr (std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs = std::vector<Attribute> ())
: BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label),
std::move (outer_attribs))
@@ -3679,6 +3766,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ BaseLoopExpr::Kind get_loop_kind () const override
+ {
+ return BaseLoopExpr::Kind::Loop;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3699,7 +3791,7 @@ public:
// Constructor for while loop with loop label
WhileLoopExpr (std::unique_ptr<Expr> loop_condition,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs
= std::vector<Attribute> ())
: BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label),
@@ -3737,6 +3829,11 @@ public:
return *condition;
}
+ BaseLoopExpr::Kind get_loop_kind () const override
+ {
+ return BaseLoopExpr::Kind::While;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3760,7 +3857,7 @@ public:
WhileLetLoopExpr (std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
std::unique_ptr<Expr> scrutinee,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs
= std::vector<Attribute> ())
: BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label),
@@ -3820,6 +3917,11 @@ public:
return match_arm_patterns;
}
+ BaseLoopExpr::Kind get_loop_kind () const override
+ {
+ return BaseLoopExpr::Kind::WhileLet;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3842,7 +3944,7 @@ public:
ForLoopExpr (std::unique_ptr<Pattern> loop_pattern,
std::unique_ptr<Expr> iterator_expr,
std::unique_ptr<BlockExpr> loop_body, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs = std::vector<Attribute> ())
: BaseLoopExpr (std::move (loop_body), locus, std::move (loop_label),
std::move (outer_attribs)),
@@ -3889,6 +3991,11 @@ public:
return *pattern;
}
+ BaseLoopExpr::Kind get_loop_kind () const override
+ {
+ return BaseLoopExpr::Kind::For;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -4012,6 +4119,8 @@ public:
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::If; }
+
protected:
// Base clone function but still concrete as concrete base class
virtual IfExpr *clone_if_expr_impl () const { return new IfExpr (*this); }
@@ -4206,6 +4315,8 @@ public:
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::IfLet; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base (or rather this or any derived object) */
@@ -4535,6 +4646,8 @@ public:
const std::vector<MatchCase> &get_match_cases () const { return match_arms; }
std::vector<MatchCase> &get_match_cases () { return match_arms; }
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Match; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -4614,6 +4727,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Await; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -4696,6 +4811,8 @@ public:
outer_attrs = std::move (new_attrs);
}
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::AsyncBlock; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -4768,6 +4885,27 @@ struct InlineAsmRegOrRegClass
location_t locus;
};
+struct LlvmOperand
+{
+ std::string constraint;
+ std::unique_ptr<Expr> expr;
+
+ LlvmOperand (std::string constraint, std::unique_ptr<Expr> &&expr)
+ : constraint (constraint), expr (std::move (expr))
+ {}
+
+ LlvmOperand (const LlvmOperand &other)
+ : constraint (other.constraint), expr (other.expr->clone_expr ())
+ {}
+ LlvmOperand &operator= (const LlvmOperand &other)
+ {
+ constraint = other.constraint;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+ }
+};
+
class InlineAsmOperand
{
public:
@@ -4810,14 +4948,14 @@ public:
rust_assert (this->expr != nullptr);
}
- In (const struct In &other)
+ In (const In &other)
{
reg = other.reg;
expr = other.expr->clone_expr ();
}
- In operator= (const struct In &other)
+ In operator= (const In &other)
{
reg = other.reg;
expr = other.expr->clone_expr ();
@@ -4843,14 +4981,14 @@ public:
rust_assert (this->expr != nullptr);
}
- Out (const struct Out &other)
+ Out (const Out &other)
{
reg = other.reg;
late = other.late;
expr = other.expr->clone_expr ();
}
- Out operator= (const struct Out &other)
+ Out operator= (const Out &other)
{
reg = other.reg;
late = other.late;
@@ -4876,14 +5014,14 @@ public:
rust_assert (this->expr != nullptr);
}
- InOut (const struct InOut &other)
+ InOut (const InOut &other)
{
reg = other.reg;
late = other.late;
expr = other.expr->clone_expr ();
}
- InOut operator= (const struct InOut &other)
+ InOut operator= (const InOut &other)
{
reg = other.reg;
late = other.late;
@@ -4913,7 +5051,7 @@ public:
rust_assert (this->out_expr != nullptr);
}
- SplitInOut (const struct SplitInOut &other)
+ SplitInOut (const SplitInOut &other)
{
reg = other.reg;
late = other.late;
@@ -4921,7 +5059,7 @@ public:
out_expr = other.out_expr->clone_expr ();
}
- SplitInOut operator= (const struct SplitInOut &other)
+ SplitInOut operator= (const SplitInOut &other)
{
reg = other.reg;
late = other.late;
@@ -4953,12 +5091,12 @@ public:
{
rust_assert (this->expr != nullptr);
}
- Sym (const struct Sym &other)
+ Sym (const Sym &other)
{
expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
}
- Sym operator= (const struct Sym &other)
+ Sym operator= (const Sym &other)
{
expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
return *this;
@@ -4981,12 +5119,12 @@ public:
if (label_name.has_value ())
this->label_name = label_name.value ();
}
- Label (const struct Label &other)
+ Label (const Label &other)
{
expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
}
- Label operator= (const struct Label &other)
+ Label operator= (const Label &other)
{
expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
return *this;
@@ -5141,6 +5279,7 @@ struct TupleTemplateStr
location_t loc;
std::string symbol;
+ location_t get_locus () { return loc; }
TupleTemplateStr (location_t loc, const std::string &symbol)
: loc (loc), symbol (symbol)
{}
@@ -5209,6 +5348,79 @@ public:
{
return new InlineAsm (*this);
}
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::InlineAsm; }
+};
+
+class LlvmInlineAsm : public ExprWithoutBlock
+{
+ // llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
+ // Asm, Outputs, Inputs, Clobbers, Options,
+
+public:
+ enum class Dialect
+ {
+ Att,
+ Intel,
+ };
+
+private:
+ location_t locus;
+ std::vector<Attribute> outer_attrs;
+ std::vector<LlvmOperand> inputs;
+ std::vector<LlvmOperand> outputs;
+ std::vector<TupleTemplateStr> templates;
+ std::vector<TupleClobber> clobbers;
+ bool volatility;
+ bool align_stack;
+ Dialect dialect;
+
+public:
+ LlvmInlineAsm (location_t locus) : locus (locus) {}
+
+ Dialect get_dialect () { return dialect; }
+
+ location_t get_locus () const override { return locus; }
+
+ void mark_for_strip () override {}
+
+ bool is_marked_for_strip () const override { return false; }
+
+ std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
+
+ void accept_vis (ASTVisitor &vis) override;
+
+ std::string as_string () const override { return "InlineAsm AST Node"; }
+
+ void set_outer_attrs (std::vector<Attribute> v) override { outer_attrs = v; }
+
+ LlvmInlineAsm *clone_expr_without_block_impl () const override
+ {
+ return new LlvmInlineAsm (*this);
+ }
+
+ std::vector<TupleTemplateStr> &get_templates () { return templates; }
+
+ Expr::Kind get_expr_kind () const override
+ {
+ return Expr::Kind::LlvmInlineAsm;
+ }
+
+ void set_align_stack (bool align_stack) { this->align_stack = align_stack; }
+ bool is_stack_aligned () { return align_stack; }
+
+ void set_volatile (bool volatility) { this->volatility = volatility; }
+ bool is_volatile () { return volatility; }
+
+ void set_dialect (Dialect dialect) { this->dialect = dialect; }
+
+ void set_inputs (std::vector<LlvmOperand> operands) { inputs = operands; }
+ void set_outputs (std::vector<LlvmOperand> operands) { outputs = operands; }
+
+ std::vector<LlvmOperand> &get_inputs () { return inputs; }
+ std::vector<LlvmOperand> &get_outputs () { return outputs; }
+
+ std::vector<TupleClobber> &get_clobbers () { return clobbers; }
};
} // namespace AST
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 2ae7c44..062f85d 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -434,13 +434,14 @@ class SelfParam : public Param
bool has_ref;
bool is_mut;
// bool has_lifetime; // only possible if also ref
- Lifetime lifetime;
+ tl::optional<Lifetime> lifetime;
// bool has_type; // only possible if not ref
std::unique_ptr<Type> type;
// Unrestricted constructor used for error state
- SelfParam (Lifetime lifetime, bool has_ref, bool is_mut, Type *type)
+ SelfParam (tl::optional<Lifetime> lifetime, bool has_ref, bool is_mut,
+ Type *type)
: Param ({}, UNDEF_LOCATION), has_ref (has_ref), is_mut (is_mut),
lifetime (std::move (lifetime)), type (type)
{}
@@ -453,7 +454,7 @@ public:
bool has_type () const { return type != nullptr; }
// Returns whether the self-param has a valid lifetime.
- bool has_lifetime () const { return !lifetime.is_error (); }
+ bool has_lifetime () const { return lifetime.has_value (); }
// Returns whether the self-param is in an error state.
bool is_error () const
@@ -472,11 +473,11 @@ public:
// Type-based self parameter (not ref, no lifetime)
SelfParam (std::unique_ptr<Type> type, bool is_mut, location_t locus)
: Param ({}, locus), has_ref (false), is_mut (is_mut),
- lifetime (Lifetime::error ()), type (std::move (type))
+ lifetime (tl::nullopt), type (std::move (type))
{}
// Lifetime-based self parameter (is ref, no type)
- SelfParam (Lifetime lifetime, bool is_mut, location_t locus)
+ SelfParam (tl::optional<Lifetime> lifetime, bool is_mut, location_t locus)
: Param ({}, locus), has_ref (true), is_mut (is_mut),
lifetime (std::move (lifetime))
{}
@@ -522,8 +523,8 @@ public:
bool get_has_ref () const { return has_ref; };
bool get_is_mut () const { return is_mut; }
- Lifetime get_lifetime () const { return lifetime; }
- Lifetime &get_lifetime () { return lifetime; }
+ Lifetime get_lifetime () const { return lifetime.value (); }
+ Lifetime &get_lifetime () { return lifetime.value (); }
NodeId get_node_id () const { return node_id; }
@@ -758,8 +759,6 @@ public:
Identifier get_name () const { return module_name; }
- AST::Kind get_ast_kind () const override { return AST::Kind::MODULE; }
-
private:
Identifier module_name;
location_t locus;
@@ -899,6 +898,8 @@ public:
void mark_for_strip () override { module_name = {""}; }
bool is_marked_for_strip () const override { return module_name.empty (); }
+ Item::Kind get_item_kind () const override { return Item::Kind::Module; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -960,6 +961,8 @@ public:
return referenced_crate.empty ();
}
+ Item::Kind get_item_kind () const override { return Item::Kind::ExternCrate; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1301,6 +1304,11 @@ public:
void mark_for_strip () override { use_tree = nullptr; }
bool is_marked_for_strip () const override { return use_tree == nullptr; }
+ Item::Kind get_item_kind () const override
+ {
+ return Item::Kind::UseDeclaration;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1323,7 +1331,7 @@ class Function : public VisItem, public AssociatedItem, public ExternalItem
WhereClause where_clause;
tl::optional<std::unique_ptr<BlockExpr>> function_body;
location_t locus;
- bool is_default;
+ bool has_default;
bool is_external_function;
public:
@@ -1348,6 +1356,8 @@ public:
bool has_body () const { return function_body.has_value (); }
+ bool is_default () const { return has_default; }
+
// Mega-constructor with all possible fields
Function (Identifier function_name, FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam>> generic_params,
@@ -1355,7 +1365,7 @@ public:
std::unique_ptr<Type> return_type, WhereClause where_clause,
tl::optional<std::unique_ptr<BlockExpr>> function_body,
Visibility vis, std::vector<Attribute> outer_attrs,
- location_t locus, bool is_default = false,
+ location_t locus, bool has_default = false,
bool is_external_function = false)
: VisItem (std::move (vis), std::move (outer_attrs)),
ExternalItem (Stmt::node_id), qualifiers (std::move (qualifiers)),
@@ -1365,7 +1375,7 @@ public:
return_type (std::move (return_type)),
where_clause (std::move (where_clause)),
function_body (std::move (function_body)), locus (locus),
- is_default (is_default), is_external_function (is_external_function)
+ has_default (has_default), is_external_function (is_external_function)
{}
// TODO: add constructor with less fields
@@ -1459,6 +1469,8 @@ public:
// ExternalItem::node_id is same as Stmt::node_id
NodeId get_node_id () const override { return Stmt::node_id; }
+ Item::Kind get_item_kind () const override { return Item::Kind::Function; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1590,6 +1602,8 @@ public:
Identifier get_new_type_name () const { return new_type_name; }
+ Item::Kind get_item_kind () const override { return Item::Kind::TypeAlias; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1649,6 +1663,8 @@ public:
Identifier get_identifier () const { return struct_name; }
+ Item::Kind get_item_kind () const override { return Item::Kind::Struct; }
+
protected:
Struct (Identifier struct_name,
std::vector<std::unique_ptr<GenericParam>> generic_params,
@@ -1994,6 +2010,41 @@ class EnumItem : public VisItem
location_t locus;
public:
+ enum class Kind
+ {
+ Identifier,
+ Tuple,
+ Struct,
+
+ // FIXME: In the future, we'll need to remove this possibility as well as
+ // remove the EnumItemDiscriminant class. The feature for arbitrary
+ // discriminants on all kinds of variants has been stabilized, and a
+ // "discriminant" is no longer an enum item variant - it's simply an
+ // optional part of all variants.
+ //
+ // Per the reference:
+ //
+ // EnumItem :
+ // OuterAttribute* Visibility?
+ // IDENTIFIER ( EnumItemTuple | EnumItemStruct )? EnumItemDiscriminant?
+ //
+ // EnumItemTuple :
+ // ( TupleFields? )
+ //
+ // EnumItemStruct :
+ // { StructFields? }
+ //
+ // EnumItemDiscriminant :
+ // = Expression
+ //
+ // So we instead need to remove the class, and add an optional expression to
+ // the base EnumItem class
+ //
+ // gccrs#3340
+
+ Discriminant,
+ };
+
virtual ~EnumItem () {}
EnumItem (Identifier variant_name, Visibility vis,
@@ -2002,6 +2053,8 @@ public:
variant_name (std::move (variant_name)), locus (locus)
{}
+ virtual Kind get_enum_item_kind () const { return Kind::Identifier; }
+
// Unique pointer custom clone function
std::unique_ptr<EnumItem> clone_enum_item () const
{
@@ -2021,6 +2074,8 @@ public:
void mark_for_strip () override { variant_name = {""}; }
bool is_marked_for_strip () const override { return variant_name.empty (); }
+ Item::Kind get_item_kind () const override { return Item::Kind::EnumItem; }
+
protected:
EnumItem *clone_item_impl () const override { return new EnumItem (*this); }
};
@@ -2043,6 +2098,11 @@ public:
tuple_fields (std::move (tuple_fields))
{}
+ EnumItem::Kind get_enum_item_kind () const override
+ {
+ return EnumItem::Kind::Tuple;
+ }
+
std::string as_string () const override;
void accept_vis (ASTVisitor &vis) override;
@@ -2080,6 +2140,11 @@ public:
struct_fields (std::move (struct_fields))
{}
+ EnumItem::Kind get_enum_item_kind () const override
+ {
+ return EnumItem::Kind::Struct;
+ }
+
std::string as_string () const override;
void accept_vis (ASTVisitor &vis) override;
@@ -2133,6 +2198,11 @@ public:
EnumItemDiscriminant (EnumItemDiscriminant &&other) = default;
EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default;
+ EnumItem::Kind get_enum_item_kind () const override
+ {
+ return EnumItem::Kind::Discriminant;
+ }
+
std::string as_string () const override;
void accept_vis (ASTVisitor &vis) override;
@@ -2269,6 +2339,8 @@ public:
// TODO: is this better? Or is a "vis_block" better?
WhereClause &get_where_clause () { return where_clause; }
+ Item::Kind get_item_kind () const override { return Item::Kind::Enum; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -2368,6 +2440,8 @@ public:
Identifier get_identifier () const { return union_name; }
+ Item::Kind get_item_kind () const override { return Item::Kind::Union; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -2489,6 +2563,11 @@ public:
std::string get_identifier () const { return identifier; }
+ Item::Kind get_item_kind () const override
+ {
+ return Item::Kind::ConstantItem;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -2610,6 +2689,8 @@ public:
Identifier get_identifier () const { return name; }
+ Item::Kind get_item_kind () const override { return Item::Kind::StaticItem; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -2831,6 +2912,7 @@ class Trait : public VisItem
bool has_auto;
Identifier name;
std::vector<std::unique_ptr<GenericParam>> generic_params;
+ TypeParam self_param;
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
WhereClause where_clause;
std::vector<Attribute> inner_attrs;
@@ -2870,7 +2952,7 @@ public:
std::vector<Attribute> inner_attrs, location_t locus)
: VisItem (std::move (vis), std::move (outer_attrs)),
has_unsafe (is_unsafe), has_auto (is_auto), name (std::move (name)),
- generic_params (std::move (generic_params)),
+ generic_params (std::move (generic_params)), self_param ({"Self"}, locus),
type_param_bounds (std::move (type_param_bounds)),
where_clause (std::move (where_clause)),
inner_attrs (std::move (inner_attrs)),
@@ -2880,8 +2962,9 @@ public:
// Copy constructor with vector clone
Trait (Trait const &other)
: VisItem (other), has_unsafe (other.has_unsafe), has_auto (other.has_auto),
- name (other.name), where_clause (other.where_clause),
- inner_attrs (other.inner_attrs), locus (other.locus)
+ name (other.name), self_param (other.self_param),
+ where_clause (other.where_clause), inner_attrs (other.inner_attrs),
+ locus (other.locus)
{
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
@@ -2901,6 +2984,7 @@ public:
{
VisItem::operator= (other);
name = other.name;
+ self_param = other.self_param;
has_unsafe = other.has_unsafe;
has_auto = other.has_auto;
where_clause = other.where_clause;
@@ -2968,19 +3052,9 @@ public:
WhereClause &get_where_clause () { return where_clause; }
- void insert_implict_self (std::unique_ptr<AST::GenericParam> &&param)
- {
- std::vector<std::unique_ptr<GenericParam>> new_list;
- new_list.reserve (generic_params.size () + 1);
-
- new_list.push_back (std::move (param));
- for (auto &p : generic_params)
- {
- new_list.push_back (std::move (p));
- }
+ AST::TypeParam &get_implicit_self () { return self_param; }
- generic_params = std::move (new_list);
- }
+ Item::Kind get_item_kind () const override { return Item::Kind::Trait; }
protected:
/* Use covariance to implement clone function as returning this object
@@ -3054,6 +3128,8 @@ public:
return trait_type;
}
+ Item::Kind get_item_kind () const override { return Item::Kind::Impl; }
+
protected:
// Mega-constructor
Impl (std::vector<std::unique_ptr<GenericParam>> generic_params,
@@ -3202,8 +3278,8 @@ public:
: Impl (std::move (generic_params), std::move (trait_type),
std::move (where_clause), std::move (vis), std::move (inner_attrs),
std::move (outer_attrs), locus),
- has_unsafe (is_unsafe), has_exclam (has_exclam),
- trait_path (std::move (trait_path)), impl_items (std::move (impl_items))
+ has_unsafe (is_unsafe), has_exclam (has_exclam), trait_path (trait_path),
+ impl_items (std::move (impl_items))
{}
// Copy constructor with vector clone
@@ -3251,11 +3327,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- TypePath &get_trait_path ()
- {
- // TODO: assert that trait path is not empty?
- return trait_path;
- }
+ TypePath &get_trait_path () { return trait_path; }
protected:
/* Use covariance to implement clone function as returning this object
@@ -3528,303 +3600,6 @@ protected:
}
};
-// A named function parameter used in external functions
-class NamedFunctionParam
-{
- // bool has_name; // otherwise is _
- std::string name;
-
- std::unique_ptr<Type> param_type;
-
- // seemingly new since writing this node
- std::vector<Attribute> outer_attrs;
-
- NodeId node_id;
- location_t locus;
- bool variadic;
-
-public:
- /* Returns whether the named function parameter has a name (i.e. name is not
- * '_'). */
- bool has_name () const { return name != "_" && name != ""; }
-
- bool has_outer_attrs () const { return !outer_attrs.empty (); }
-
- // Returns whether the named function parameter is in an error state.
- bool is_error () const
- {
- // also if identifier is "" but that is probably more costly to compute
- return param_type == nullptr && !variadic;
- }
-
- bool is_variadic () const { return variadic; }
-
- std::string get_name () const { return name; }
-
- location_t get_locus () { return locus; }
-
- // Creates an error state named function parameter.
- static NamedFunctionParam create_error ()
- {
- return NamedFunctionParam ("", nullptr, {}, UNDEF_LOCATION);
- }
-
- NamedFunctionParam (std::string name, std::unique_ptr<Type> param_type,
- std::vector<Attribute> outer_attrs, location_t locus)
- : name (std::move (name)), param_type (std::move (param_type)),
- outer_attrs (std::move (outer_attrs)),
- node_id (Analysis::Mappings::get ().get_next_node_id ()), locus (locus),
- variadic (false)
- {}
-
- NamedFunctionParam (std::string name, std::vector<Attribute> outer_attrs,
- location_t locus)
- : name (std::move (name)), param_type (nullptr),
- outer_attrs (std::move (outer_attrs)),
- node_id (Analysis::Mappings::get ().get_next_node_id ()), locus (locus),
- variadic (true)
- {}
-
- NamedFunctionParam (std::vector<Attribute> outer_attrs, location_t locus)
- : name (""), param_type (nullptr), outer_attrs (std::move (outer_attrs)),
- node_id (Analysis::Mappings::get ().get_next_node_id ()), locus (locus),
- variadic (true)
- {}
-
- // Copy constructor
- NamedFunctionParam (NamedFunctionParam const &other)
- : name (other.name), outer_attrs (other.outer_attrs),
- variadic (other.variadic)
- {
- node_id = other.node_id;
- // guard to prevent null dereference (only required if error state)
- if (other.param_type != nullptr)
- param_type = other.param_type->clone_type ();
- else
- param_type = nullptr;
- }
-
- ~NamedFunctionParam () = default;
-
- // Overloaded assignment operator to clone
- NamedFunctionParam &operator= (NamedFunctionParam const &other)
- {
- node_id = other.node_id;
- name = other.name;
- // has_name = other.has_name;
- outer_attrs = other.outer_attrs;
-
- // guard to prevent null dereference (only required if error state)
- if (other.param_type != nullptr)
- param_type = other.param_type->clone_type ();
- else
- param_type = nullptr;
-
- return *this;
- }
-
- // move constructors
- NamedFunctionParam (NamedFunctionParam &&other) = default;
- NamedFunctionParam &operator= (NamedFunctionParam &&other) = default;
-
- std::string as_string () const;
-
- // Based on idea that nane should never be empty.
- void mark_for_strip () { param_type = nullptr; };
- bool is_marked_for_strip () const { return is_error (); };
-
- // TODO: this mutable getter seems really dodgy. Think up better way.
- std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
- const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
-
- // TODO: is this better? Or is a "vis_block" better?
- Type &get_type ()
- {
- rust_assert (param_type != nullptr);
- return *param_type;
- }
-
- std::unique_ptr<Type> &get_type_ptr ()
- {
- rust_assert (param_type != nullptr);
- return param_type;
- }
-
- NodeId get_node_id () const { return node_id; }
-};
-
-// A function item used in an extern block
-class ExternalFunctionItem : public ExternalItem
-{
- // bool has_outer_attrs;
- std::vector<Attribute> outer_attrs;
-
- // bool has_visibility;
- Visibility visibility;
-
- Identifier item_name;
- location_t locus;
-
- // bool has_generics;
- // Generics generic_params;
- std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
-
- // bool has_return_type;
- // FunctionReturnType return_type;
- std::unique_ptr<Type> return_type; // inlined
-
- // bool has_where_clause;
- WhereClause where_clause;
-
- std::vector<NamedFunctionParam> function_params;
-
-public:
- // Returns whether item has generic parameters.
- bool has_generics () const { return !generic_params.empty (); }
-
- // Returns whether item has a return type (otherwise void).
- bool has_return_type () const { return return_type != nullptr; }
-
- // Returns whether item has a where clause.
- bool has_where_clause () const { return !where_clause.is_empty (); }
-
- // Returns whether item has outer attributes.
- bool has_outer_attrs () const { return !outer_attrs.empty (); }
-
- // Returns whether item has non-default visibility.
- bool has_visibility () const { return !visibility.is_error (); }
-
- // Returns whether item has variadic parameters.
- bool is_variadic () const
- {
- return function_params.size () != 0
- && function_params.back ().is_variadic ();
- }
-
- location_t get_locus () const { return locus; }
-
- Visibility &get_visibility () { return visibility; }
- const Visibility &get_visibility () const { return visibility; }
-
- ExternalFunctionItem (
- Identifier item_name,
- std::vector<std::unique_ptr<GenericParam>> generic_params,
- std::unique_ptr<Type> return_type, WhereClause where_clause,
- std::vector<NamedFunctionParam> function_params, Visibility vis,
- std::vector<Attribute> outer_attrs, location_t locus)
- : ExternalItem (), outer_attrs (std::move (outer_attrs)),
- visibility (std::move (vis)), item_name (std::move (item_name)),
- locus (locus), generic_params (std::move (generic_params)),
- return_type (std::move (return_type)),
- where_clause (std::move (where_clause)),
- function_params (std::move (function_params))
- {
- // TODO: assert that if has variadic outer attrs, then has_variadics is
- // true?
- }
-
- // Copy constructor with clone
- ExternalFunctionItem (ExternalFunctionItem const &other)
- : ExternalItem (other.get_node_id ()), outer_attrs (other.outer_attrs),
- visibility (other.visibility), item_name (other.item_name),
- locus (other.locus), where_clause (other.where_clause),
- function_params (other.function_params)
- {
- node_id = other.node_id;
- // guard to prevent null pointer dereference
- if (other.return_type != nullptr)
- return_type = other.return_type->clone_type ();
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
- }
-
- // Overloaded assignment operator with clone
- ExternalFunctionItem &operator= (ExternalFunctionItem const &other)
- {
- outer_attrs = other.outer_attrs;
- visibility = other.visibility;
- item_name = other.item_name;
- locus = other.locus;
- where_clause = other.where_clause;
- function_params = other.function_params;
- node_id = other.node_id;
-
- // guard to prevent null pointer dereference
- if (other.return_type != nullptr)
- return_type = other.return_type->clone_type ();
- else
- return_type = nullptr;
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- return *this;
- }
-
- // move constructors
- ExternalFunctionItem (ExternalFunctionItem &&other) = default;
- ExternalFunctionItem &operator= (ExternalFunctionItem &&other) = default;
-
- std::string as_string () const override;
-
- void accept_vis (ASTVisitor &vis) override;
-
- // Based on idea that nane should never be empty.
- void mark_for_strip () override { item_name = {""}; };
- bool is_marked_for_strip () const override { return item_name.empty (); };
-
- // TODO: this mutable getter seems really dodgy. Think up better way.
- std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
- const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
-
- std::vector<NamedFunctionParam> &get_function_params ()
- {
- return function_params;
- }
- const std::vector<NamedFunctionParam> &get_function_params () const
- {
- return function_params;
- }
-
- std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
- {
- return generic_params;
- }
- const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
- {
- return generic_params;
- }
-
- // TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause () { return where_clause; }
-
- // TODO: is this better? Or is a "vis_block" better?
- Type &get_return_type ()
- {
- rust_assert (has_return_type ());
- return *return_type;
- }
-
- std::unique_ptr<Type> &get_return_type_ptr ()
- {
- rust_assert (has_return_type ());
- return return_type;
- }
-
- Identifier get_identifier () const { return item_name; };
-
-protected:
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- ExternalFunctionItem *clone_external_item_impl () const override
- {
- return new ExternalFunctionItem (*this);
- }
-};
-
// An extern block AST node
class ExternBlock : public VisItem
{
@@ -3917,6 +3692,8 @@ public:
const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; }
std::vector<Attribute> &get_inner_attrs () { return inner_attrs; }
+ Item::Kind get_item_kind () const override { return Item::Kind::ExternBlock; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 76b3b2a..fc01e57 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -24,11 +24,11 @@
#include "rust-ast-fragment.h"
#include "rust-location.h"
#include "rust-item.h"
-#include "rust-make-unique.h"
#include "rust-macro-builtins.h"
namespace Rust {
namespace AST {
+
class MacroFragSpec
{
public:
@@ -521,7 +521,7 @@ public:
mbe (Identifier rule_name, DelimType delim_type, std::vector<MacroRule> rules,
std::vector<Attribute> outer_attrs, location_t locus)
{
- return Rust::make_unique<MacroRulesDefinition> (
+ return std::make_unique<MacroRulesDefinition> (
MacroRulesDefinition (rule_name, delim_type, rules, outer_attrs, locus,
AST::MacroRulesDefinition::MacroKind::MBE,
AST::Visibility::create_error ()));
@@ -532,7 +532,7 @@ public:
std::vector<Attribute> outer_attrs, location_t locus,
Visibility vis)
{
- return Rust::make_unique<MacroRulesDefinition> (MacroRulesDefinition (
+ return std::make_unique<MacroRulesDefinition> (MacroRulesDefinition (
rule_name, AST::DelimType::CURLY, rules, outer_attrs, locus,
AST::MacroRulesDefinition::MacroKind::DeclMacro, vis));
}
@@ -572,13 +572,13 @@ public:
is_builtin_rule = true;
}
- AST::Kind get_ast_kind () const override
+ MacroKind get_kind () const { return kind; }
+
+ Item::Kind get_item_kind () const override
{
- return AST::Kind::MACRO_RULES_DEFINITION;
+ return Item::Kind::MacroRulesDefinition;
}
- MacroKind get_kind () const { return kind; }
-
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -610,11 +610,6 @@ public:
std::string as_string () const override;
- Pattern::Kind get_pattern_kind () override
- {
- return Pattern::Kind::MacroInvocation;
- }
-
/**
* The default constructor you should use. Whenever we parse a macro call, we
* cannot possibly know whether or not this call refers to a builtin macro or
@@ -677,11 +672,6 @@ public:
return ExprWithoutBlock::get_node_id ();
}
- AST::Kind get_ast_kind () const override
- {
- return AST::Kind::MACRO_INVOCATION;
- }
-
NodeId get_macro_node_id () const { return node_id; }
MacroInvocData &get_invoc_data () { return invoc_data; }
@@ -800,6 +790,21 @@ public:
void add_semicolon () override { is_semi_coloned = true; }
+ Pattern::Kind get_pattern_kind () override
+ {
+ return Pattern::Kind::MacroInvocation;
+ }
+
+ Expr::Kind get_expr_kind () const override
+ {
+ return Expr::Kind::MacroInvocation;
+ }
+
+ Item::Kind get_item_kind () const override
+ {
+ return Item::Kind::MacroInvocation;
+ }
+
protected:
Item *clone_item_impl () const override
{
diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
index 06c98cd..8e43ddf 100644
--- a/gcc/rust/ast/rust-path.cc
+++ b/gcc/rust/ast/rust-path.cc
@@ -119,7 +119,7 @@ ConstGenericParam::as_string () const
str += "const " + name.as_string () + ": " + type->as_string ();
if (has_default_value ())
- str += " = " + get_default_value ().as_string ();
+ str += " = " + get_default_value_unchecked ().as_string ();
return str;
}
@@ -136,8 +136,11 @@ PathExprSegment::as_string () const
}
std::string
-RegularPath::as_string () const
+Path::as_string () const
{
+ // FIXME: Impl for lang items
+ rust_assert (kind == Kind::Regular);
+
std::string str;
for (const auto &segment : segments)
@@ -149,16 +152,11 @@ RegularPath::as_string () const
return str;
}
-std::string
-LangItemPath::as_string () const
-{
- // FIXME: Handle #[lang] paths
- rust_unreachable ();
-}
-
SimplePath
-RegularPath::convert_to_simple_path (bool with_opening_scope_resolution) const
+Path::convert_to_simple_path (bool with_opening_scope_resolution) const
{
+ rust_assert (kind == Kind::Regular);
+
if (!has_segments ())
return SimplePath::create_empty ();
@@ -192,18 +190,6 @@ RegularPath::convert_to_simple_path (bool with_opening_scope_resolution) const
}
void
-RegularPath::accept_vis (ASTVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
-LangItemPath::accept_vis (ASTVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
PathInExpression::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
@@ -217,7 +203,7 @@ PathInExpression::as_string () const
if (has_opening_scope_resolution)
str = "::";
- return str + path->as_string ();
+ return str + Path::as_string ();
}
std::string
@@ -317,7 +303,7 @@ TypePathFunction::as_string () const
std::string
QualifiedPathInExpression::as_string () const
{
- return path_type.as_string () + "::" + path->as_string ();
+ return path_type.as_string () + "::" + Path::as_string ();
}
std::string
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 98fde5a..a4ba93b 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -21,6 +21,7 @@
/* "Path" (identifier within namespaces, essentially) handling. Required include
* for virtually all AST-related functionality. */
+#include "optional.h"
#include "rust-ast.h"
#include "rust-hir-map.h"
#include "rust-mapping-common.h"
@@ -55,10 +56,16 @@ public:
location_t get_locus () const { return locus; }
- bool is_super_segment () const { return as_string ().compare ("super") == 0; }
- bool is_crate_segment () const { return as_string ().compare ("crate") == 0; }
- bool is_lower_self () const { return as_string ().compare ("self") == 0; }
- bool is_big_self () const { return as_string ().compare ("Self") == 0; }
+ bool is_super_path_seg () const
+ {
+ return as_string ().compare ("super") == 0;
+ }
+ bool is_crate_path_seg () const
+ {
+ return as_string ().compare ("crate") == 0;
+ }
+ bool is_lower_self_seg () const { return as_string ().compare ("self") == 0; }
+ bool is_big_self_seg () const { return as_string ().compare ("Self") == 0; }
};
// A binding of an identifier to a type used in generic arguments in paths
@@ -160,17 +167,11 @@ public:
*/
enum class Kind
{
- Error,
Const, // A const value
Type, // A type argument (not discernable during parsing)
Either, // Either a type or a const value, cleared up during resolving
};
- static GenericArg create_error ()
- {
- return GenericArg (nullptr, nullptr, {""}, Kind::Error, UNDEF_LOCATION);
- }
-
static GenericArg create_const (std::unique_ptr<Expr> expression)
{
auto locus = expression->get_locus ();
@@ -215,8 +216,6 @@ public:
GenericArg (GenericArg &&other) = default;
GenericArg &operator= (GenericArg &&other) = default;
- bool is_error () const { return kind == Kind::Error; }
-
Kind get_kind () const { return kind; }
location_t get_locus () const { return locus; }
@@ -232,8 +231,6 @@ public:
break;
case Kind::Either:
break;
- case Kind::Error:
- rust_unreachable ();
}
}
@@ -276,8 +273,6 @@ public:
{
switch (get_kind ())
{
- case Kind::Error:
- rust_unreachable ();
case Kind::Either:
return "Ambiguous: " + path.as_string ();
case Kind::Const:
@@ -348,15 +343,15 @@ class ConstGenericParam : public GenericParam
/**
* Default value for the const generic parameter
*/
- GenericArg default_value;
+ tl::optional<GenericArg> default_value;
AST::AttrVec outer_attrs;
location_t locus;
public:
ConstGenericParam (Identifier name, std::unique_ptr<AST::Type> type,
- GenericArg default_value, AST::AttrVec outer_attrs,
- location_t locus)
+ tl::optional<GenericArg> default_value,
+ AST::AttrVec outer_attrs, location_t locus)
: name (name), type (std::move (type)),
default_value (std::move (default_value)), outer_attrs (outer_attrs),
locus (locus)
@@ -369,7 +364,7 @@ public:
{}
bool has_type () const { return type != nullptr; }
- bool has_default_value () const { return !default_value.is_error (); }
+ bool has_default_value () const { return default_value.has_value (); }
const Identifier &get_name () const { return name; }
@@ -382,18 +377,18 @@ public:
return *type;
}
- GenericArg &get_default_value ()
+ GenericArg &get_default_value_unchecked ()
{
rust_assert (has_default_value ());
- return default_value;
+ return default_value.value ();
}
- const GenericArg &get_default_value () const
+ const GenericArg &get_default_value_unchecked () const
{
rust_assert (has_default_value ());
- return default_value;
+ return default_value.value ();
}
std::string as_string () const override;
@@ -560,17 +555,17 @@ public:
bool is_super_path_seg () const
{
- return !has_generic_args () && get_ident_segment ().is_super_segment ();
+ return !has_generic_args () && get_ident_segment ().is_super_path_seg ();
}
bool is_crate_path_seg () const
{
- return !has_generic_args () && get_ident_segment ().is_crate_segment ();
+ return !has_generic_args () && get_ident_segment ().is_crate_path_seg ();
}
bool is_lower_self_seg () const
{
- return !has_generic_args () && get_ident_segment ().is_lower_self ();
+ return !has_generic_args () && get_ident_segment ().is_lower_self_seg ();
}
};
@@ -585,104 +580,75 @@ public:
Regular,
};
- virtual Kind get_path_kind () const = 0;
-
- Pattern::Kind get_pattern_kind () override final
- {
- return Pattern::Kind::Path;
- }
-
- location_t get_locus () const override final { return locus; }
- NodeId get_node_id () const override final { return node_id; }
-
- std::unique_ptr<Path> clone_path ()
- {
- return std::unique_ptr<Path> (clone_path_impl ());
- }
-
- Pattern *clone_pattern_impl () const override final
- {
- return clone_path_impl ();
- }
-
-protected:
- location_t locus;
- NodeId node_id;
-
- Path (location_t locus, NodeId node_id) : locus (locus), node_id (node_id) {}
-
- virtual Path *clone_path_impl () const = 0;
-};
-
-class RegularPath : public Path
-{
- std::vector<PathExprSegment> segments;
-
-public:
- explicit RegularPath (std::vector<PathExprSegment> &&segments,
- location_t locus, NodeId node_id)
- : Path (locus, node_id), segments (std::move (segments))
+ Path (std::vector<PathExprSegment> segments)
+ : segments (std::move (segments)), lang_item (tl::nullopt),
+ kind (Kind::Regular)
{}
- std::string as_string () const override;
+ Path (LangItem::Kind lang_item)
+ : segments ({}), lang_item (lang_item), kind (Kind::LangItem)
+ {}
// Returns whether path has segments.
- bool has_segments () const { return !segments.empty (); }
-
- std::vector<PathExprSegment> &get_segments () { return segments; }
-
- const std::vector<PathExprSegment> &get_segments () const { return segments; }
-
- /* Returns whether the path is a single segment (excluding qualified path
- * initial as segment). */
- bool is_single_segment () const { return segments.size () == 1; }
+ bool has_segments () const
+ {
+ rust_assert (kind == Kind::Regular);
+ return !segments.empty ();
+ }
/* Converts path segments to their equivalent SimplePath segments if
* possible, and creates a SimplePath from them. */
SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const;
- Path::Kind get_path_kind () const override { return Path::Kind::Regular; }
-
- void accept_vis (ASTVisitor &vis) override;
-
- Path *clone_path_impl () const override
+ /* Returns whether the path is a single segment (excluding qualified path
+ * initial as segment). */
+ bool is_single_segment () const
{
- return new RegularPath (std::vector<PathExprSegment> (segments), locus,
- node_id);
+ rust_assert (kind == Kind::Regular);
+ return segments.size () == 1;
}
-};
-
-class LangItemPath : public Path
-{
- NodeId lang_item;
- // TODO: Add LangItemKind or w/ever here as well
- // TODO: This constructor is wrong
- explicit LangItemPath (NodeId lang_item, location_t locus)
- : Path (locus, lang_item), lang_item (lang_item)
- {}
+ std::string as_string () const override;
- Path::Kind get_path_kind () const override { return Path::Kind::LangItem; }
+ bool is_lang_item () const { return kind == Kind::LangItem; }
- void accept_vis (ASTVisitor &vis) override;
+ // TODO: this seems kinda dodgy
+ std::vector<PathExprSegment> &get_segments ()
+ {
+ rust_assert (kind == Kind::Regular);
+ return segments;
+ }
+ const std::vector<PathExprSegment> &get_segments () const
+ {
+ rust_assert (kind == Kind::Regular);
+ return segments;
+ }
- Path *clone_path_impl () const override
+ LangItem::Kind get_lang_item () const
{
- return new LangItemPath (lang_item, locus);
+ rust_assert (kind == Kind::LangItem);
+ return *lang_item;
}
- std::string as_string () const override;
+ Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
+ Path::Kind get_path_kind () { return kind; }
+
+protected:
+ std::vector<PathExprSegment> segments;
+ tl::optional<LangItem::Kind> lang_item;
+
+ Path::Kind kind;
};
/* AST node representing a path-in-expression pattern (path that allows
* generic arguments) */
-class PathInExpression : public Pattern, public ExprWithoutBlock
+class PathInExpression : public Path, public ExprWithoutBlock
{
std::vector<Attribute> outer_attrs;
bool has_opening_scope_resolution;
location_t locus;
NodeId _node_id;
- std::unique_ptr<Path> path;
+
bool marked_for_strip;
public:
@@ -692,61 +658,41 @@ public:
PathInExpression (std::vector<PathExprSegment> path_segments,
std::vector<Attribute> outer_attrs, location_t locus,
bool has_opening_scope_resolution = false)
- : outer_attrs (std::move (outer_attrs)),
+ : Path (std::move (path_segments)), outer_attrs (std::move (outer_attrs)),
has_opening_scope_resolution (has_opening_scope_resolution),
locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()),
- path (Rust::make_unique<RegularPath> (std::move (path_segments), locus,
- _node_id)),
marked_for_strip (false)
{}
- PathInExpression (const PathInExpression &other)
- : outer_attrs (other.outer_attrs),
- has_opening_scope_resolution (other.has_opening_scope_resolution),
- locus (other.locus), _node_id (other._node_id),
- path (other.path->clone_path ()),
- marked_for_strip (other.marked_for_strip)
+ PathInExpression (LangItem::Kind lang_item,
+ std::vector<Attribute> outer_attrs, location_t locus)
+ : Path (lang_item), outer_attrs (std::move (outer_attrs)),
+ has_opening_scope_resolution (false), locus (locus),
+ _node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ marked_for_strip (false)
{}
- PathInExpression &operator= (const PathInExpression &other)
- {
- outer_attrs = other.outer_attrs;
- has_opening_scope_resolution = other.has_opening_scope_resolution;
- locus = other.locus;
- _node_id = other._node_id;
- path = other.path->clone_path ();
- marked_for_strip = other.marked_for_strip;
-
- return *this;
- }
-
// Creates an error state path in expression.
static PathInExpression create_error ()
{
- return PathInExpression ({}, {}, UNDEF_LOCATION);
+ return PathInExpression (std::vector<PathExprSegment> (), {},
+ UNDEF_LOCATION);
}
// Returns whether path in expression is in an error state.
- bool is_error () const
- {
- // FIXME: Cleanup
- if (path->get_path_kind () == Path::Kind::Regular)
- return !static_cast<RegularPath &> (*path).has_segments ();
-
- return false;
- }
+ bool is_error () const { return !has_segments (); }
/* Converts PathInExpression to SimplePath if possible (i.e. no generic
* arguments). Otherwise returns an empty SimplePath. */
SimplePath as_simple_path () const
{
- // FIXME: Cleanup
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).convert_to_simple_path (
- has_opening_scope_resolution);
- else
- // FIXME: lang item to simple path?
- rust_unreachable ();
+ /* delegate to parent class as can't access segments. however,
+ * QualifiedPathInExpression conversion to simple path wouldn't make
+ * sense, so the method in the parent class should be protected, not
+ * public. Have to pass in opening scope resolution as parent class has no
+ * access to it.
+ */
+ return convert_to_simple_path (has_opening_scope_resolution);
}
location_t get_locus () const override final { return locus; }
@@ -771,63 +717,18 @@ public:
outer_attrs = std::move (new_attrs);
}
- NodeId get_pattern_node_id () const { return get_node_id (); }
-
- PathExprSegment &get_final_segment ()
- {
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ().back ();
-
- // lang item segment?
- rust_unreachable ();
- }
-
+ PathExprSegment &get_final_segment () { return get_segments ().back (); }
const PathExprSegment &get_final_segment () const
{
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ().back ();
-
- // lang item segment?
- rust_unreachable ();
+ return get_segments ().back ();
}
- const std::vector<PathExprSegment> &get_segments () const
+ Expr::Kind get_expr_kind () const override
{
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ();
-
- rust_unreachable ();
+ return Expr::Kind::PathInExpression;
}
- std::vector<PathExprSegment> &get_segments ()
- {
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ();
-
- rust_unreachable ();
- }
-
- bool is_single_segment () const
- {
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ().size () == 1;
-
- return false;
- }
-
- Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
-
protected:
- PathInExpression (std::vector<Attribute> &&outer_attrs,
- bool has_opening_scope_resolution, location_t locus,
- NodeId node_id, std::unique_ptr<Path> &&path,
- bool marked_for_strip)
- : outer_attrs (std::move (outer_attrs)),
- has_opening_scope_resolution (has_opening_scope_resolution),
- locus (locus), _node_id (node_id), path (std::move (path)),
- marked_for_strip (marked_for_strip)
- {}
-
/* Use covariance to implement clone function as returning this object
* rather than base */
PathInExpression *clone_pattern_impl () const final override
@@ -861,7 +762,8 @@ public:
};
private:
- PathIdentSegment ident_segment;
+ tl::optional<LangItem::Kind> lang_item;
+ tl::optional<PathIdentSegment> ident_segment;
location_t locus;
protected:
@@ -891,21 +793,30 @@ public:
TypePathSegment (PathIdentSegment ident_segment,
bool has_separating_scope_resolution, location_t locus)
- : ident_segment (std::move (ident_segment)), locus (locus),
+ : lang_item (tl::nullopt), ident_segment (std::move (ident_segment)),
+ locus (locus),
has_separating_scope_resolution (has_separating_scope_resolution),
node_id (Analysis::Mappings::get ().get_next_node_id ())
{}
+ TypePathSegment (LangItem::Kind lang_item, location_t locus)
+ : lang_item (lang_item), ident_segment (tl::nullopt), locus (locus),
+ has_separating_scope_resolution (false),
+ node_id (Analysis::Mappings::get ().get_next_node_id ())
+ {}
+
TypePathSegment (std::string segment_name,
bool has_separating_scope_resolution, location_t locus)
- : ident_segment (PathIdentSegment (std::move (segment_name), locus)),
+ : lang_item (tl::nullopt),
+ ident_segment (PathIdentSegment (std::move (segment_name), locus)),
locus (locus),
has_separating_scope_resolution (has_separating_scope_resolution),
node_id (Analysis::Mappings::get ().get_next_node_id ())
{}
TypePathSegment (TypePathSegment const &other)
- : ident_segment (other.ident_segment), locus (other.locus),
+ : lang_item (other.lang_item), ident_segment (other.ident_segment),
+ locus (other.locus),
has_separating_scope_resolution (other.has_separating_scope_resolution),
node_id (other.node_id)
{}
@@ -913,6 +824,7 @@ public:
TypePathSegment &operator= (TypePathSegment const &other)
{
ident_segment = other.ident_segment;
+ lang_item = other.lang_item;
locus = other.locus;
has_separating_scope_resolution = other.has_separating_scope_resolution;
node_id = other.node_id;
@@ -923,16 +835,28 @@ public:
TypePathSegment (TypePathSegment &&other) = default;
TypePathSegment &operator= (TypePathSegment &&other) = default;
- virtual std::string as_string () const { return ident_segment.as_string (); }
+ virtual std::string as_string () const
+ {
+ if (lang_item.has_value ())
+ return LangItem::PrettyString (*lang_item);
+
+ return ident_segment->as_string ();
+ }
/* Returns whether the type path segment is in an error state. May be
* virtual in future. */
- bool is_error () const { return ident_segment.is_error (); }
+ bool is_error () const
+ {
+ rust_assert (ident_segment);
+ return ident_segment->is_error ();
+ }
/* Returns whether segment is identifier only (as opposed to generic args or
* function). Overridden in derived classes with other segments. */
virtual bool is_ident_only () const { return true; }
+ bool is_lang_item () const { return lang_item.has_value (); }
+
location_t get_locus () const { return locus; }
// not pure virtual as class not abstract
@@ -943,23 +867,41 @@ public:
return has_separating_scope_resolution;
}
- PathIdentSegment &get_ident_segment () { return ident_segment; };
- const PathIdentSegment &get_ident_segment () const { return ident_segment; };
+ PathIdentSegment &get_ident_segment ()
+ {
+ rust_assert (!is_lang_item ());
+ return *ident_segment;
+ };
+
+ const PathIdentSegment &get_ident_segment () const
+ {
+ rust_assert (!is_lang_item ());
+ return *ident_segment;
+ };
+
+ LangItem::Kind get_lang_item () const
+ {
+ rust_assert (is_lang_item ());
+ return *lang_item;
+ }
NodeId get_node_id () const { return node_id; }
bool is_crate_path_seg () const
{
- return get_ident_segment ().is_crate_segment ();
+ return get_ident_segment ().is_crate_path_seg ();
}
bool is_super_path_seg () const
{
- return get_ident_segment ().is_super_segment ();
+ return get_ident_segment ().is_super_path_seg ();
+ }
+ bool is_big_self_seg () const
+ {
+ return get_ident_segment ().is_big_self_seg ();
}
- bool is_big_self_seg () const { return get_ident_segment ().is_big_self (); }
bool is_lower_self_seg () const
{
- return get_ident_segment ().is_lower_self ();
+ return get_ident_segment ().is_lower_self_seg ();
}
};
@@ -984,6 +926,12 @@ public:
generic_args (std::move (generic_args))
{}
+ TypePathSegmentGeneric (LangItem::Kind lang_item, GenericArgs generic_args,
+ location_t locus)
+ : TypePathSegment (lang_item, locus),
+ generic_args (std::move (generic_args))
+ {}
+
// Constructor from segment name and all args
TypePathSegmentGeneric (std::string segment_name,
bool has_separating_scope_resolution,
@@ -1041,7 +989,7 @@ private:
/*bool has_inputs;
TypePathFnInputs inputs;*/
// inlined from TypePathFnInputs
- std::vector<std::unique_ptr<Type> > inputs;
+ std::vector<std::unique_ptr<Type>> inputs;
// bool has_type;
std::unique_ptr<Type> return_type;
@@ -1074,8 +1022,8 @@ public:
}
// Constructor
- TypePathFunction (std::vector<std::unique_ptr<Type> > inputs,
- location_t locus, std::unique_ptr<Type> type = nullptr)
+ TypePathFunction (std::vector<std::unique_ptr<Type>> inputs, location_t locus,
+ std::unique_ptr<Type> type = nullptr)
: inputs (std::move (inputs)), return_type (std::move (type)),
is_invalid (false), locus (locus)
{}
@@ -1120,11 +1068,11 @@ public:
std::string as_string () const;
// TODO: this mutable getter seems really dodgy. Think up better way.
- const std::vector<std::unique_ptr<Type> > &get_params () const
+ const std::vector<std::unique_ptr<Type>> &get_params () const
{
return inputs;
}
- std::vector<std::unique_ptr<Type> > &get_params () { return inputs; }
+ std::vector<std::unique_ptr<Type>> &get_params () { return inputs; }
// TODO: is this better? Or is a "vis_pattern" better?
Type &get_return_type ()
@@ -1188,11 +1136,10 @@ public:
}
};
-// Path used inside types
class TypePath : public TypeNoBounds
{
bool has_opening_scope_resolution;
- std::vector<std::unique_ptr<TypePathSegment> > segments;
+ std::vector<std::unique_ptr<TypePathSegment>> segments;
location_t locus;
protected:
@@ -1217,12 +1164,20 @@ public:
// Creates an error state TypePath.
static TypePath create_error ()
{
- return TypePath (std::vector<std::unique_ptr<TypePathSegment> > (),
+ return TypePath (std::vector<std::unique_ptr<TypePathSegment>> (),
UNDEF_LOCATION);
}
// Constructor
- TypePath (std::vector<std::unique_ptr<TypePathSegment> > segments,
+ TypePath (std::vector<std::unique_ptr<TypePathSegment>> segments,
+ location_t locus, bool has_opening_scope_resolution = false)
+ : TypeNoBounds (),
+ has_opening_scope_resolution (has_opening_scope_resolution),
+ segments (std::move (segments)), locus (locus)
+ {}
+
+ TypePath (LangItem::Kind lang_item,
+ std::vector<std::unique_ptr<TypePathSegment>> segments,
location_t locus, bool has_opening_scope_resolution = false)
: TypeNoBounds (),
has_opening_scope_resolution (has_opening_scope_resolution),
@@ -1268,15 +1223,19 @@ public:
TraitBound *to_trait_bound (bool in_parens) const override;
location_t get_locus () const override final { return locus; }
+ NodeId get_node_id () const { return node_id; }
+
+ void mark_for_strip () override {}
+ bool is_marked_for_strip () const override { return false; }
void accept_vis (ASTVisitor &vis) override;
// TODO: this seems kinda dodgy
- std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
+ std::vector<std::unique_ptr<TypePathSegment>> &get_segments ()
{
return segments;
}
- const std::vector<std::unique_ptr<TypePathSegment> > &get_segments () const
+ const std::vector<std::unique_ptr<TypePathSegment>> &get_segments () const
{
return segments;
}
@@ -1297,9 +1256,8 @@ public:
QualifiedPathType (std::unique_ptr<Type> invoke_on_type,
location_t locus = UNDEF_LOCATION,
TypePath trait_path = TypePath::create_error ())
- : type_to_invoke_on (std::move (invoke_on_type)),
- trait_path (std::move (trait_path)), locus (locus),
- node_id (Analysis::Mappings::get ().get_next_node_id ())
+ : type_to_invoke_on (std::move (invoke_on_type)), trait_path (trait_path),
+ locus (locus), node_id (Analysis::Mappings::get ().get_next_node_id ())
{}
// Copy constructor uses custom deep copy for Type to preserve polymorphism
@@ -1376,12 +1334,12 @@ public:
/* AST node representing a qualified path-in-expression pattern (path that
* allows specifying trait functions) */
-class QualifiedPathInExpression : public Pattern, public ExprWithoutBlock
+class QualifiedPathInExpression : public Path, public ExprWithoutBlock
{
std::vector<Attribute> outer_attrs;
QualifiedPathType path_type;
-
- std::unique_ptr<Path> path;
+ location_t locus;
+ NodeId _node_id;
public:
std::string as_string () const override;
@@ -1390,16 +1348,9 @@ public:
std::vector<PathExprSegment> path_segments,
std::vector<Attribute> outer_attrs,
location_t locus)
- : outer_attrs (std::move (outer_attrs)),
- path_type (std::move (qual_path_type)),
- path (Rust::make_unique<RegularPath> (
- std::move (path_segments), locus,
- Analysis::Mappings::get ().get_next_node_id ()))
- {}
-
- QualifiedPathInExpression (const QualifiedPathInExpression &other)
- : outer_attrs (other.outer_attrs), path_type (other.path_type),
- path (other.path->clone_path ())
+ : Path (std::move (path_segments)), outer_attrs (std::move (outer_attrs)),
+ path_type (std::move (qual_path_type)), locus (locus),
+ _node_id (Analysis::Mappings::get ().get_next_node_id ())
{}
/* TODO: maybe make a shortcut constructor that has QualifiedPathType
@@ -1415,9 +1366,7 @@ public:
{}, UNDEF_LOCATION);
}
- Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
-
- location_t get_locus () const override final { return path->get_locus (); }
+ location_t get_locus () const override final { return locus; }
void accept_vis (ASTVisitor &vis) override;
@@ -1443,30 +1392,11 @@ public:
outer_attrs = std::move (new_attrs);
}
- NodeId get_node_id () const override { return path->get_node_id (); }
-
- const std::vector<PathExprSegment> &get_segments () const
- {
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ();
-
- rust_unreachable ();
- }
-
- std::vector<PathExprSegment> &get_segments ()
- {
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ();
-
- rust_unreachable ();
- }
+ NodeId get_node_id () const override { return _node_id; }
- bool is_single_segment () const
+ Expr::Kind get_expr_kind () const override
{
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ().size () == 1;
-
- return false;
+ return Expr::Kind::QualifiedPathInExpression;
}
protected:
@@ -1498,7 +1428,7 @@ class QualifiedPathInType : public TypeNoBounds
{
QualifiedPathType path_type;
std::unique_ptr<TypePathSegment> associated_segment;
- std::vector<std::unique_ptr<TypePathSegment> > segments;
+ std::vector<std::unique_ptr<TypePathSegment>> segments;
location_t locus;
protected:
@@ -1513,7 +1443,7 @@ public:
QualifiedPathInType (
QualifiedPathType qual_path_type,
std::unique_ptr<TypePathSegment> associated_segment,
- std::vector<std::unique_ptr<TypePathSegment> > path_segments,
+ std::vector<std::unique_ptr<TypePathSegment>> path_segments,
location_t locus)
: path_type (std::move (qual_path_type)),
associated_segment (std::move (associated_segment)),
@@ -1560,7 +1490,7 @@ public:
{
return QualifiedPathInType (
QualifiedPathType::create_error (), nullptr,
- std::vector<std::unique_ptr<TypePathSegment> > (), UNDEF_LOCATION);
+ std::vector<std::unique_ptr<TypePathSegment>> (), UNDEF_LOCATION);
}
std::string as_string () const override;
@@ -1580,11 +1510,11 @@ public:
}
// TODO: this seems kinda dodgy
- std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
+ std::vector<std::unique_ptr<TypePathSegment>> &get_segments ()
{
return segments;
}
- const std::vector<std::unique_ptr<TypePathSegment> > &get_segments () const
+ const std::vector<std::unique_ptr<TypePathSegment>> &get_segments () const
{
return segments;
}
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index 98fd8e5..fc7b610 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -22,7 +22,6 @@ along with GCC; see the file COPYING3. If not see
#include "rust-diagnostics.h"
#include "rust-ast-visitor.h"
#include "rust-macro.h"
-#include "rust-session-manager.h"
#include "rust-lex.h"
#include "rust-parse.h"
#include "rust-operators.h"
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index e8aec34..f843a79 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -19,10 +19,11 @@
#ifndef RUST_AST_STATEMENT_H
#define RUST_AST_STATEMENT_H
+#include "optional.h"
#include "rust-ast.h"
#include "rust-path.h"
#include "rust-expr.h"
-#include <memory>
+#include "rust-system.h"
namespace Rust {
namespace AST {
@@ -72,6 +73,8 @@ class LetStmt : public Stmt
// bool has_init_expr;
std::unique_ptr<Expr> init_expr;
+ tl::optional<std::unique_ptr<Expr>> else_expr;
+
location_t locus;
public:
@@ -85,15 +88,18 @@ public:
// Returns whether let statement has an initialisation expression.
bool has_init_expr () const { return init_expr != nullptr; }
+ bool has_else_expr () const { return else_expr.has_value (); }
std::string as_string () const override;
LetStmt (std::unique_ptr<Pattern> variables_pattern,
std::unique_ptr<Expr> init_expr, std::unique_ptr<Type> type,
+ tl::optional<std::unique_ptr<Expr>> else_expr,
std::vector<Attribute> outer_attrs, location_t locus)
: outer_attrs (std::move (outer_attrs)),
variables_pattern (std::move (variables_pattern)),
- type (std::move (type)), init_expr (std::move (init_expr)), locus (locus)
+ type (std::move (type)), init_expr (std::move (init_expr)),
+ else_expr (std::move (else_expr)), locus (locus)
{}
// Copy constructor with clone
@@ -107,6 +113,9 @@ public:
// guard to prevent null dereference (always required)
if (other.init_expr != nullptr)
init_expr = other.init_expr->clone_expr ();
+ if (other.else_expr.has_value ())
+ else_expr = other.else_expr.value ()->clone_expr ();
+
if (other.type != nullptr)
type = other.type->clone_type ();
}
@@ -128,6 +137,12 @@ public:
init_expr = other.init_expr->clone_expr ();
else
init_expr = nullptr;
+
+ if (other.else_expr != nullptr)
+ else_expr = other.else_expr.value ()->clone_expr ();
+ else
+ else_expr = tl::nullopt;
+
if (other.type != nullptr)
type = other.type->clone_type ();
else
@@ -162,12 +177,24 @@ public:
return *init_expr;
}
+ Expr &get_else_expr ()
+ {
+ rust_assert (has_else_expr ());
+ return *else_expr.value ();
+ }
+
std::unique_ptr<Expr> &get_init_expr_ptr ()
{
rust_assert (has_init_expr ());
return init_expr;
}
+ std::unique_ptr<Expr> &get_else_expr_ptr ()
+ {
+ rust_assert (has_else_expr ());
+ return else_expr.value ();
+ }
+
Pattern &get_pattern ()
{
rust_assert (variables_pattern != nullptr);
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 20e0232..1bb521d 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -542,7 +542,7 @@ protected:
class ReferenceType : public TypeNoBounds
{
// bool has_lifetime; // TODO: handle in lifetime or something?
- Lifetime lifetime;
+ tl::optional<Lifetime> lifetime;
bool has_mut;
std::unique_ptr<TypeNoBounds> type;
@@ -553,11 +553,12 @@ public:
bool is_mut () const { return has_mut; }
// Returns whether the reference has a lifetime.
- bool has_lifetime () const { return !lifetime.is_error (); }
+ bool has_lifetime () const { return lifetime.has_value (); }
// Constructor
ReferenceType (bool is_mut, std::unique_ptr<TypeNoBounds> type_no_bounds,
- location_t locus, Lifetime lifetime = Lifetime::elided ())
+ location_t locus,
+ tl::optional<Lifetime> lifetime = Lifetime::elided ())
: lifetime (std::move (lifetime)), has_mut (is_mut),
type (std::move (type_no_bounds)), locus (locus)
{}
@@ -598,7 +599,8 @@ public:
bool get_has_mut () const { return has_mut; }
- Lifetime &get_lifetime () { return lifetime; }
+ Lifetime &get_lifetime () { return lifetime.value (); }
+ const Lifetime &get_lifetime () const { return lifetime.value (); }
TypeNoBounds &get_base_type () { return *type; }
diff --git a/gcc/rust/backend/rust-compile-asm.cc b/gcc/rust/backend/rust-compile-asm.cc
index e85d08d..7351cf0 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -1,11 +1,12 @@
#include "rust-compile-asm.h"
#include "rust-compile-expr.h"
+#include "rust-system.h"
+
namespace Rust {
namespace Compile {
-CompileAsm::CompileAsm (Context *ctx)
- : HIRCompileBase (ctx), translated (error_mark_node)
-{}
+CompileAsm::CompileAsm (Context *ctx) : HIRCompileBase (ctx) {}
+
tree
CompileAsm::tree_codegen_asm (HIR::InlineAsm &expr)
{
@@ -86,7 +87,7 @@ CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
{
auto out = output.get_out ();
- tree out_tree = CompileExpr::Compile (out.expr.get (), this->ctx);
+ tree out_tree = CompileExpr::Compile (*out.expr, this->ctx);
// expects a tree list
// TODO: This assumes that the output is a register
std::string expr_name = "=r";
@@ -113,7 +114,7 @@ CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
{
auto in = input.get_in ();
- tree in_tree = CompileExpr::Compile (in.expr.get (), this->ctx);
+ tree in_tree = CompileExpr::Compile (*in.expr, this->ctx);
// expects a tree list
// TODO: This assumes that the input is a register
std::string expr_name = "r";
@@ -142,5 +143,57 @@ CompileAsm::asm_construct_label_tree (HIR::InlineAsm &expr)
return NULL_TREE;
}
+CompileLlvmAsm::CompileLlvmAsm (Context *ctx) : HIRCompileBase (ctx) {}
+
+tree
+CompileLlvmAsm::construct_operands (std::vector<HIR::LlvmOperand> operands)
+{
+ tree head = NULL_TREE;
+ for (auto &operand : operands)
+ {
+ tree t = CompileExpr::Compile (*operand.expr, this->ctx);
+ auto name = build_string (operand.constraint.size () + 1,
+ operand.constraint.c_str ());
+ head = chainon (head,
+ build_tree_list (build_tree_list (NULL_TREE, name), t));
+ }
+ return head;
+}
+
+tree
+CompileLlvmAsm::construct_clobbers (std::vector<AST::TupleClobber> clobbers)
+{
+ tree head = NULL_TREE;
+ for (auto &clobber : clobbers)
+ {
+ auto name
+ = build_string (clobber.symbol.size () + 1, clobber.symbol.c_str ());
+ head = chainon (head, build_tree_list (NULL_TREE, name));
+ }
+ return head;
+}
+
+tree
+CompileLlvmAsm::tree_codegen_asm (HIR::LlvmInlineAsm &expr)
+{
+ tree ret = make_node (ASM_EXPR);
+ TREE_TYPE (ret) = void_type_node;
+ SET_EXPR_LOCATION (ret, expr.get_locus ());
+ ASM_VOLATILE_P (ret) = expr.options.is_volatile;
+
+ std::stringstream ss;
+ for (const auto &template_str : expr.templates)
+ {
+ ss << template_str.symbol << "\n";
+ }
+
+ ASM_STRING (ret) = Backend::string_constant_expression (ss.str ());
+ ASM_INPUTS (ret) = construct_operands (expr.inputs);
+ ASM_OUTPUTS (ret) = construct_operands (expr.outputs);
+ ASM_CLOBBERS (ret) = construct_clobbers (expr.get_clobbers ());
+
+ return ret;
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-asm.h b/gcc/rust/backend/rust-compile-asm.h
index 402d950..22be94a 100644
--- a/gcc/rust/backend/rust-compile-asm.h
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -28,8 +28,6 @@ namespace Compile {
class CompileAsm : private HIRCompileBase
{
private:
- tree translated;
-
// RELEVANT MEMBER FUNCTIONS
// The limit is 5 because it stands for the 5 things that the C version of
@@ -58,6 +56,20 @@ public:
tree tree_codegen_asm (HIR::InlineAsm &);
};
+
+class CompileLlvmAsm : private HIRCompileBase
+{
+private:
+ tree construct_operands (std::vector<HIR::LlvmOperand> operands);
+
+ tree construct_clobbers (std::vector<AST::TupleClobber>);
+
+public:
+ CompileLlvmAsm (Context *ctx);
+
+ tree tree_codegen_asm (HIR::LlvmInlineAsm &);
+};
+
} // namespace Compile
} // namespace Rust
#endif // RUST_COMPILE_ASM
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 8166c3a..12b9561 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -25,7 +25,8 @@
#include "rust-compile-type.h"
#include "rust-constexpr.h"
#include "rust-diagnostics.h"
-#include "rust-expr.h" // for AST::AttrInputLiteral
+#include "rust-expr.h" // for AST::AttrInputLiteral
+#include "rust-hir-map.h"
#include "rust-macro.h" // for AST::MetaNameValueStr
#include "rust-hir-path-probe.h"
#include "rust-type-util.h"
@@ -39,6 +40,9 @@
#include "tree.h"
#include "print-tree.h"
+// rust-name-resolution-2.0
+#include "options.h"
+
namespace Rust {
namespace Compile {
@@ -545,7 +549,7 @@ HIRCompileBase::mark_addressable (tree exp, location_t locus)
}
tree
-HIRCompileBase::address_expression (tree expr, location_t location)
+HIRCompileBase::address_expression (tree expr, location_t location, tree ptrty)
{
if (expr == error_mark_node)
return error_mark_node;
@@ -553,7 +557,22 @@ HIRCompileBase::address_expression (tree expr, location_t location)
if (!mark_addressable (expr, location))
return error_mark_node;
- return build_fold_addr_expr_loc (location, expr);
+ if (ptrty == NULL || ptrty == error_mark_node)
+ ptrty = build_pointer_type (TREE_TYPE (expr));
+
+ return build_fold_addr_expr_with_type_loc (location, expr, ptrty);
+}
+
+tree
+HIRCompileBase::compile_constant_expr (
+ Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type,
+ TyTy::BaseType *expected_type, const Resolver::CanonicalPath &canonical_path,
+ HIR::Expr &const_value_expr, location_t locus, location_t expr_locus)
+{
+ HIRCompileBase c (ctx);
+ return c.compile_constant_item (coercion_id, resolved_type, expected_type,
+ canonical_path, const_value_expr, locus,
+ expr_locus);
}
tree
@@ -582,8 +601,9 @@ HIRCompileBase::compile_function_body (tree fndecl,
if (function_body.has_expr ())
{
- location_t locus = function_body.get_final_expr ()->get_locus ();
- tree return_value = CompileExpr::Compile (function_body.expr.get (), ctx);
+ location_t locus = function_body.get_final_expr ().get_locus ();
+ tree return_value
+ = CompileExpr::Compile (function_body.get_final_expr (), ctx);
// we can only return this if non unit value return type
if (!fn_return_ty->is_unit ())
@@ -646,7 +666,8 @@ get_abi (const AST::AttrVec &outer_attrs,
tree
HIRCompileBase::compile_function (
- const std::string &fn_name, HIR::SelfParam &self_param,
+ bool is_root_item, const std::string &fn_name,
+ tl::optional<HIR::SelfParam> &self_param,
std::vector<HIR::FunctionParam> &function_params,
const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility,
AST::AttrVec &outer_attrs, location_t locus, HIR::BlockExpr *function_body,
@@ -657,7 +678,7 @@ HIRCompileBase::compile_function (
= canonical_path.get () + fntype->subst_as_string ();
// we don't mangle the main fn since we haven't implemented the main shim
- bool is_main_fn = fn_name.compare ("main") == 0;
+ bool is_main_fn = fn_name.compare ("main") == 0 && is_root_item;
if (is_main_fn)
{
rust_assert (!main_identifier_node);
@@ -666,6 +687,11 @@ 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);
@@ -688,39 +714,39 @@ HIRCompileBase::compile_function (
// setup the params
TyTy::BaseType *tyret = fntype->get_return_type ();
std::vector<Bvariable *> param_vars;
- if (!self_param.is_error ())
+ if (self_param)
{
rust_assert (fntype->is_method ());
TyTy::BaseType *self_tyty_lookup = fntype->get_self_type ();
tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
Bvariable *compiled_self_param
- = CompileSelfParam::compile (ctx, fndecl, self_param, self_type,
- self_param.get_locus ());
+ = CompileSelfParam::compile (ctx, fndecl, self_param.value (),
+ self_type, self_param->get_locus ());
param_vars.push_back (compiled_self_param);
- ctx->insert_var_decl (self_param.get_mappings ().get_hirid (),
+ ctx->insert_var_decl (self_param->get_mappings ().get_hirid (),
compiled_self_param);
}
// offset from + 1 for the TyTy::FnType being used when this is a method to
// skip over Self on the FnType
- bool is_method = !self_param.is_error ();
+ bool is_method = self_param.has_value ();
size_t i = is_method ? 1 : 0;
for (auto &referenced_param : function_params)
{
- auto tyty_param = fntype->param_at (i++);
- auto param_tyty = tyty_param.second;
+ auto &tyty_param = fntype->param_at (i++);
+ auto param_tyty = tyty_param.get_type ();
auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
location_t param_locus = referenced_param.get_locus ();
Bvariable *compiled_param_var
- = CompileFnParam::compile (ctx, fndecl, &referenced_param,
+ = CompileFnParam::compile (ctx, fndecl, referenced_param,
compiled_param_type, param_locus);
param_vars.push_back (compiled_param_var);
- const HIR::Pattern &param_pattern = *referenced_param.get_param_name ();
+ const HIR::Pattern &param_pattern = referenced_param.get_param_name ();
ctx->insert_var_decl (param_pattern.get_mappings ().get_hirid (),
compiled_param_var);
}
@@ -767,15 +793,20 @@ HIRCompileBase::compile_function (
tree
HIRCompileBase::compile_constant_item (
- TyTy::BaseType *resolved_type, const Resolver::CanonicalPath &canonical_path,
- HIR::Expr *const_value_expr, location_t locus)
+ HirId coercion_id, TyTy::BaseType *resolved_type,
+ TyTy::BaseType *expected_type, const Resolver::CanonicalPath &canonical_path,
+ HIR::Expr &const_value_expr, location_t locus, location_t expr_locus)
{
const std::string &ident = canonical_path.get ();
tree type = TyTyResolveCompile::compile (ctx, resolved_type);
tree const_type = build_qualified_type (type, TYPE_QUAL_CONST);
+
+ tree actual_type = TyTyResolveCompile::compile (ctx, expected_type);
+ tree actual_const_type = build_qualified_type (actual_type, TYPE_QUAL_CONST);
+
bool is_block_expr
- = const_value_expr->get_expression_type () == HIR::Expr::ExprType::Block;
+ = const_value_expr.get_expression_type () == HIR::Expr::ExprType::Block;
// in order to compile a block expr we want to reuse as much existing
// machineary that we already have. This means the best approach is to
@@ -789,14 +820,14 @@ HIRCompileBase::compile_constant_item (
TREE_READONLY (fndecl) = 1;
tree enclosing_scope = NULL_TREE;
- location_t start_location = const_value_expr->get_locus ();
- location_t end_location = const_value_expr->get_locus ();
+ location_t start_location = const_value_expr.get_locus ();
+ location_t end_location = const_value_expr.get_locus ();
if (is_block_expr)
{
- HIR::BlockExpr *function_body
- = static_cast<HIR::BlockExpr *> (const_value_expr);
- start_location = function_body->get_locus ();
- end_location = function_body->get_end_locus ();
+ HIR::BlockExpr &function_body
+ = static_cast<HIR::BlockExpr &> (const_value_expr);
+ start_location = function_body.get_locus ();
+ end_location = function_body.get_end_locus ();
}
tree code_block = Backend::block (fndecl, enclosing_scope, {} /*locals*/,
@@ -814,9 +845,9 @@ HIRCompileBase::compile_constant_item (
if (is_block_expr)
{
- HIR::BlockExpr *function_body
- = static_cast<HIR::BlockExpr *> (const_value_expr);
- compile_function_body (fndecl, *function_body, resolved_type);
+ HIR::BlockExpr &function_body
+ = static_cast<HIR::BlockExpr &> (const_value_expr);
+ compile_function_body (fndecl, function_body, resolved_type);
}
else
{
@@ -824,7 +855,7 @@ HIRCompileBase::compile_constant_item (
tree return_expr
= Backend::return_statement (fndecl, value,
- const_value_expr->get_locus ());
+ const_value_expr.get_locus ());
ctx->add_statement (return_expr);
}
@@ -841,7 +872,11 @@ HIRCompileBase::compile_constant_item (
tree call = build_call_array_loc (locus, const_type, fndecl, 0, NULL);
tree folded_expr = fold_expr (call);
- return named_constant_expression (const_type, ident, folded_expr, locus);
+ // coercion site
+ tree coerced = coercion_site (coercion_id, folded_expr, resolved_type,
+ expected_type, locus, expr_locus);
+
+ return named_constant_expression (actual_const_type, ident, coerced, locus);
}
tree
@@ -992,7 +1027,7 @@ HIRCompileBase::resolve_method_address (TyTy::FnType *fntype,
tree
HIRCompileBase::unit_expression (location_t locus)
{
- tree unit_type = TyTyResolveCompile::get_unit_type ();
+ tree unit_type = TyTyResolveCompile::get_unit_type (ctx);
return Backend::constructor_expression (unit_type, false, {}, -1, locus);
}
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index eeb3ff0..6814abc 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -29,7 +29,14 @@ class HIRCompileBase
public:
virtual ~HIRCompileBase () {}
- static tree address_expression (tree expr, location_t locus);
+ static tree address_expression (tree expr, location_t locus,
+ tree ptrty = NULL_TREE);
+
+ static tree compile_constant_expr (
+ Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type,
+ TyTy::BaseType *expected_type,
+ const Resolver::CanonicalPath &canonical_path, HIR::Expr &const_value_expr,
+ location_t locus, location_t expr_locus);
protected:
HIRCompileBase (Context *ctx) : ctx (ctx) {}
@@ -90,11 +97,14 @@ protected:
void compile_function_body (tree fndecl, HIR::BlockExpr &function_body,
TyTy::BaseType *fn_return_ty);
- tree compile_constant_item (TyTy::BaseType *resolved_type,
+ tree compile_constant_item (HirId coercion_id, TyTy::BaseType *resolved_type,
+ TyTy::BaseType *expected_type,
const Resolver::CanonicalPath &canonical_path,
- HIR::Expr *const_value_expr, location_t locus);
+ HIR::Expr &const_value_expr, location_t locus,
+ location_t expr_locus);
- tree compile_function (const std::string &fn_name, HIR::SelfParam &self_param,
+ tree compile_function (bool is_root_item, const std::string &fn_name,
+ tl::optional<HIR::SelfParam> &self_param,
std::vector<HIR::FunctionParam> &function_params,
const HIR::FunctionQualifiers &qualifiers,
HIR::Visibility &visibility, AST::AttrVec &outer_attrs,
@@ -102,7 +112,7 @@ protected:
const Resolver::CanonicalPath &canonical_path,
TyTy::FnType *fntype);
- static tree unit_expression (location_t locus);
+ tree unit_expression (location_t locus);
void setup_fndecl (tree fndecl, bool is_main_entry_point, bool is_generic_fn,
HIR::Visibility &visibility,
diff --git a/gcc/rust/backend/rust-compile-block.cc b/gcc/rust/backend/rust-compile-block.cc
index eb8af2a..f844a27 100644
--- a/gcc/rust/backend/rust-compile-block.cc
+++ b/gcc/rust/backend/rust-compile-block.cc
@@ -28,10 +28,10 @@ CompileBlock::CompileBlock (Context *ctx, Bvariable *result)
{}
tree
-CompileBlock::compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result)
+CompileBlock::compile (HIR::BlockExpr &expr, Context *ctx, Bvariable *result)
{
CompileBlock compiler (ctx, result);
- compiler.visit (*expr);
+ compiler.visit (expr);
return compiler.translated;
}
@@ -60,10 +60,10 @@ CompileBlock::visit (HIR::BlockExpr &expr)
if (expr.has_expr ())
{
- tree compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
+ tree compiled_expr = CompileExpr::Compile (expr.get_final_expr (), ctx);
if (result != nullptr)
{
- location_t locus = expr.get_final_expr ()->get_locus ();
+ location_t locus = expr.get_final_expr ().get_locus ();
tree result_reference = Backend::var_expression (result, locus);
tree assignment
@@ -93,10 +93,8 @@ CompileConditionalBlocks::visit (HIR::IfExpr &expr)
{
fncontext fnctx = ctx->peek_fn ();
tree fndecl = fnctx.fndecl;
- tree condition_expr
- = CompileExpr::Compile (expr.get_if_condition ().get (), ctx);
- tree then_block
- = CompileBlock::compile (expr.get_if_block ().get (), ctx, result);
+ tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+ tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
translated = Backend::if_statement (fndecl, condition_expr, then_block, NULL,
expr.get_locus ());
@@ -107,23 +105,20 @@ CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr)
{
fncontext fnctx = ctx->peek_fn ();
tree fndecl = fnctx.fndecl;
- tree condition_expr
- = CompileExpr::Compile (expr.get_if_condition ().get (), ctx);
- tree then_block
- = CompileBlock::compile (expr.get_if_block ().get (), ctx, result);
+ tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+ tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
// else block
std::vector<Bvariable *> locals;
- location_t start_location = expr.get_else_block ()->get_locus ();
- location_t end_location = expr.get_else_block ()->get_locus (); // FIXME
+ location_t start_location = expr.get_else_block ().get_locus ();
+ location_t end_location = expr.get_else_block ().get_locus (); // FIXME
tree enclosing_scope = ctx->peek_enclosing_scope ();
tree else_block = Backend::block (fndecl, enclosing_scope, locals,
start_location, end_location);
ctx->push_block (else_block);
tree else_stmt_decl
- = CompileExprWithBlock::compile (expr.get_else_block ().get (), ctx,
- result);
+ = CompileExprWithBlock::compile (&expr.get_else_block (), ctx, result);
ctx->add_statement (else_stmt_decl);
diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h
index d226b4b..3f38d08 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -28,7 +28,7 @@ namespace Compile {
class CompileBlock : private HIRCompileBase
{
public:
- static tree compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result);
+ static tree compile (HIR::BlockExpr &expr, Context *ctx, Bvariable *result);
protected:
void visit (HIR::BlockExpr &expr);
@@ -96,12 +96,11 @@ public:
void visit (HIR::LoopExpr &) override {}
void visit (HIR::WhileLoopExpr &) override {}
void visit (HIR::WhileLetLoopExpr &) override {}
- void visit (HIR::IfLetExpr &) override {}
- void visit (HIR::IfLetExprConseqElse &) override {}
void visit (HIR::MatchExpr &) override {}
void visit (HIR::AwaitExpr &) override {}
void visit (HIR::AsyncBlockExpr &) override {}
void visit (HIR::InlineAsm &) override {}
+ void visit (HIR::LlvmInlineAsm &) override {}
private:
CompileConditionalBlocks (Context *ctx, Bvariable *result)
@@ -136,7 +135,7 @@ public:
void visit (HIR::BlockExpr &expr) override
{
- translated = CompileBlock::compile (&expr, ctx, result);
+ translated = CompileBlock::compile (expr, ctx, result);
}
// Empty visit for unused Expression HIR nodes.
@@ -180,12 +179,11 @@ public:
void visit (HIR::LoopExpr &) override {}
void visit (HIR::WhileLoopExpr &) override {}
void visit (HIR::WhileLetLoopExpr &) override {}
- void visit (HIR::IfLetExpr &) override {}
- void visit (HIR::IfLetExprConseqElse &) override {}
void visit (HIR::MatchExpr &) override {}
void visit (HIR::AwaitExpr &) override {}
void visit (HIR::AsyncBlockExpr &) override {}
void visit (HIR::InlineAsm &) override {}
+ void visit (HIR::LlvmInlineAsm &) 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 c80f956..86f0894 100644
--- a/gcc/rust/backend/rust-compile-context.cc
+++ b/gcc/rust/backend/rust-compile-context.cc
@@ -33,19 +33,8 @@ Context::Context ()
void
Context::setup_builtins ()
{
- auto builtins = resolver->get_builtin_types ();
- for (auto it = builtins.begin (); it != builtins.end (); it++)
- {
- HirId ref;
- bool ok = tyctx->lookup_type_by_node_id ((*it)->get_node_id (), &ref);
- rust_assert (ok);
-
- TyTy::BaseType *lookup;
- ok = tyctx->lookup_type (ref, &lookup);
- rust_assert (ok);
-
- TyTyResolveCompile::compile (this, lookup);
- }
+ for (auto &builtin : tyctx->get_builtins ())
+ TyTyResolveCompile::compile (this, builtin.get ());
}
hashval_t
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index a446388..ce81a1d 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -72,7 +72,10 @@ public:
return it->second;
compiled_type_map.insert ({h, type});
- push_type (type);
+
+ if (TYPE_NAME (type) != NULL)
+ push_type (type);
+
return type;
}
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 7251cc8..dd3420f 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -31,6 +31,7 @@
#include "convert.h"
#include "print-tree.h"
#include "rust-system.h"
+#include "rust-tyty.h"
namespace Rust {
namespace Compile {
@@ -40,24 +41,24 @@ CompileExpr::CompileExpr (Context *ctx)
{}
tree
-CompileExpr::Compile (HIR::Expr *expr, Context *ctx)
+CompileExpr::Compile (HIR::Expr &expr, Context *ctx)
{
CompileExpr compiler (ctx);
- expr->accept_vis (compiler);
+ expr.accept_vis (compiler);
return compiler.translated;
}
void
CompileExpr::visit (HIR::TupleIndexExpr &expr)
{
- HIR::Expr *tuple_expr = expr.get_tuple_expr ().get ();
+ HIR::Expr &tuple_expr = expr.get_tuple_expr ();
TupleIndex index = expr.get_tuple_index ();
tree receiver_ref = CompileExpr::Compile (tuple_expr, ctx);
TyTy::BaseType *tuple_expr_ty = nullptr;
bool ok
- = ctx->get_tyctx ()->lookup_type (tuple_expr->get_mappings ().get_hirid (),
+ = ctx->get_tyctx ()->lookup_type (tuple_expr.get_mappings ().get_hirid (),
&tuple_expr_ty);
rust_assert (ok);
@@ -97,7 +98,7 @@ CompileExpr::visit (HIR::TupleExpr &expr)
std::vector<tree> vals;
for (auto &elem : expr.get_tuple_elems ())
{
- auto e = CompileExpr::Compile (elem.get (), ctx);
+ auto e = CompileExpr::Compile (*elem, ctx);
vals.push_back (e);
}
@@ -111,7 +112,7 @@ CompileExpr::visit (HIR::ReturnExpr &expr)
auto fncontext = ctx->peek_fn ();
tree return_value = expr.has_return_expr ()
- ? CompileExpr::Compile (expr.return_expr.get (), ctx)
+ ? CompileExpr::Compile (expr.get_expr (), ctx)
: unit_expression (expr.get_locus ());
if (expr.has_return_expr ())
@@ -141,8 +142,8 @@ void
CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
{
auto op = expr.get_expr_type ();
- auto lhs = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
- auto rhs = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
// this might be an operator overload situation lets check
TyTy::FnType *fntype;
@@ -152,41 +153,42 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
{
auto lang_item_type
= LangItem::OperatorToLangItem (expr.get_expr_type ());
- translated = resolve_operator_overload (lang_item_type, expr, lhs, rhs,
- expr.get_lhs ().get (),
- expr.get_rhs ().get ());
+ translated = resolve_operator_overload (
+ lang_item_type, expr, lhs, rhs, expr.get_lhs (),
+ tl::optional<std::reference_wrapper<HIR::Expr>> (expr.get_rhs ()));
return;
}
- if (ctx->in_fn () && !ctx->const_context_p ())
- {
- auto receiver_tmp = NULL_TREE;
- auto receiver
- = Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
- TREE_TYPE (lhs), lhs, true,
- expr.get_locus (), &receiver_tmp);
- auto check
- = Backend::arithmetic_or_logical_expression_checked (op, lhs, rhs,
- expr.get_locus (),
- receiver);
-
- ctx->add_statement (check);
- translated = receiver->get_tree (expr.get_locus ());
- }
- else
+ bool can_generate_overflow_checks
+ = (ctx->in_fn () && !ctx->const_context_p ()) && flag_overflow_checks;
+ if (!can_generate_overflow_checks)
{
translated
= Backend::arithmetic_or_logical_expression (op, lhs, rhs,
expr.get_locus ());
+ return;
}
+
+ auto receiver_tmp = NULL_TREE;
+ auto receiver
+ = Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
+ TREE_TYPE (lhs), lhs, true,
+ expr.get_locus (), &receiver_tmp);
+ auto check
+ = Backend::arithmetic_or_logical_expression_checked (op, lhs, rhs,
+ expr.get_locus (),
+ receiver);
+
+ ctx->add_statement (check);
+ translated = receiver->get_tree (expr.get_locus ());
}
void
CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
{
auto op = expr.get_expr_type ();
- auto lhs = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
- auto rhs = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
// this might be an operator overload situation lets check
TyTy::FnType *fntype;
@@ -198,8 +200,7 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
expr.get_expr_type ());
auto compound_assignment
= resolve_operator_overload (lang_item_type, expr, lhs, rhs,
- expr.get_lhs ().get (),
- expr.get_rhs ().get ());
+ expr.get_lhs (), expr.get_rhs ());
ctx->add_statement (compound_assignment);
return;
@@ -236,18 +237,18 @@ CompileExpr::visit (HIR::NegationExpr &expr)
{
auto op = expr.get_expr_type ();
- const auto literal_expr = expr.get_expr ().get ();
+ auto &literal_expr = expr.get_expr ();
// If it's a negated integer/float literal, we can return early
if (op == NegationOperator::NEGATE
- && literal_expr->get_expression_type () == HIR::Expr::ExprType::Lit)
+ && literal_expr.get_expression_type () == HIR::Expr::ExprType::Lit)
{
- auto new_literal_expr = static_cast<HIR::LiteralExpr *> (literal_expr);
- auto lit_type = new_literal_expr->get_lit_type ();
+ auto &new_literal_expr = static_cast<HIR::LiteralExpr &> (literal_expr);
+ auto lit_type = new_literal_expr.get_lit_type ();
if (lit_type == HIR::Literal::LitType::INT
|| lit_type == HIR::Literal::LitType::FLOAT)
{
- new_literal_expr->set_negative ();
+ new_literal_expr.set_negative ();
translated = CompileExpr::Compile (literal_expr, ctx);
return;
}
@@ -265,7 +266,7 @@ CompileExpr::visit (HIR::NegationExpr &expr)
auto lang_item_type = LangItem::NegationOperatorToLangItem (op);
translated
= resolve_operator_overload (lang_item_type, expr, negated_expr,
- nullptr, expr.get_expr ().get (), nullptr);
+ nullptr, expr.get_expr (), tl::nullopt);
return;
}
@@ -276,10 +277,30 @@ void
CompileExpr::visit (HIR::ComparisonExpr &expr)
{
auto op = expr.get_expr_type ();
- auto lhs = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
- auto rhs = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
auto location = expr.get_locus ();
+ // this might be an operator overload situation lets check
+ TyTy::FnType *fntype;
+ bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
+ expr.get_mappings ().get_hirid (), &fntype);
+ if (is_op_overload)
+ {
+ auto seg_name = LangItem::ComparisonToSegment (expr.get_expr_type ());
+ auto segment = HIR::PathIdentSegment (seg_name);
+ auto lang_item_type
+ = LangItem::ComparisonToLangItem (expr.get_expr_type ());
+
+ rhs = address_expression (rhs, EXPR_LOCATION (rhs));
+
+ translated = resolve_operator_overload (
+ lang_item_type, expr, lhs, rhs, expr.get_lhs (),
+ tl::optional<std::reference_wrapper<HIR::Expr>> (expr.get_rhs ()),
+ segment);
+ return;
+ }
+
translated = Backend::comparison_expression (op, lhs, rhs, location);
}
@@ -287,8 +308,8 @@ void
CompileExpr::visit (HIR::LazyBooleanExpr &expr)
{
auto op = expr.get_expr_type ();
- auto lhs = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
- auto rhs = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
auto location = expr.get_locus ();
translated = Backend::lazy_boolean_expression (op, lhs, rhs, location);
@@ -307,14 +328,14 @@ CompileExpr::visit (HIR::TypeCastExpr &expr)
TyTy::BaseType *casted_tyty = nullptr;
if (!ctx->get_tyctx ()->lookup_type (
- expr.get_casted_expr ()->get_mappings ().get_hirid (), &casted_tyty))
+ expr.get_casted_expr ().get_mappings ().get_hirid (), &casted_tyty))
{
translated = error_mark_node;
return;
}
auto type_to_cast_to = TyTyResolveCompile::compile (ctx, type_to_cast_to_ty);
- auto casted_expr = CompileExpr::Compile (expr.get_casted_expr ().get (), ctx);
+ auto casted_expr = CompileExpr::Compile (expr.get_casted_expr (), ctx);
std::vector<Resolver::Adjustment> *adjustments = nullptr;
bool ok = ctx->get_tyctx ()->lookup_cast_autoderef_mappings (
@@ -347,6 +368,13 @@ CompileExpr::visit (HIR::InlineAsm &expr)
}
void
+CompileExpr::visit (HIR::LlvmInlineAsm &expr)
+{
+ CompileLlvmAsm asm_codegen (ctx);
+ ctx->add_statement (asm_codegen.tree_codegen_asm (expr));
+}
+
+void
CompileExpr::visit (HIR::IfExprConseqElse &expr)
{
TyTy::BaseType *if_type = nullptr;
@@ -405,7 +433,7 @@ CompileExpr::visit (HIR::BlockExpr &expr)
&ret_var_stmt);
ctx->add_statement (ret_var_stmt);
- auto block_stmt = CompileBlock::compile (&expr, ctx, tmp);
+ auto block_stmt = CompileBlock::compile (expr, ctx, tmp);
rust_assert (TREE_CODE (block_stmt) == BIND_EXPR);
ctx->add_statement (block_stmt);
@@ -415,7 +443,7 @@ CompileExpr::visit (HIR::BlockExpr &expr)
void
CompileExpr::visit (HIR::UnsafeBlockExpr &expr)
{
- expr.get_block_expr ()->accept_vis (*this);
+ expr.get_block_expr ().accept_vis (*this);
}
void
@@ -487,7 +515,7 @@ CompileExpr::visit (HIR::StructExprStructFields &struct_expr)
auto lvalue_locus
= ctx->get_mappings ().lookup_location (expected->get_ty_ref ());
auto rvalue_locus = argument->get_locus ();
- auto rvalue = CompileStructExprField::Compile (argument.get (), ctx);
+ auto rvalue = CompileStructExprField::Compile (*argument, ctx);
TyTy::BaseType *actual = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
@@ -519,7 +547,7 @@ CompileExpr::visit (HIR::StructExprStructFields &struct_expr)
auto lvalue_locus
= ctx->get_mappings ().lookup_location (expected->get_ty_ref ());
auto rvalue_locus = argument->get_locus ();
- auto rvalue = CompileStructExprField::Compile (argument.get (), ctx);
+ auto rvalue = CompileStructExprField::Compile (*argument, ctx);
TyTy::BaseType *actual = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
@@ -539,45 +567,53 @@ CompileExpr::visit (HIR::StructExprStructFields &struct_expr)
}
}
- // the constructor depends on whether this is actually an enum or not if
- // its an enum we need to setup the discriminator
- std::vector<tree> ctor_arguments;
- if (adt->is_enum ())
+ if (!adt->is_enum ())
{
- HIR::Expr *discrim_expr = variant->get_discriminant ();
- tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
- tree folded_discrim_expr = fold_expr (discrim_expr_node);
- tree qualifier = folded_discrim_expr;
-
- ctor_arguments.push_back (qualifier);
+ translated
+ = Backend::constructor_expression (compiled_adt_type, adt->is_enum (),
+ arguments, union_disriminator,
+ struct_expr.get_locus ());
+ return;
}
- for (auto &arg : arguments)
- ctor_arguments.push_back (arg);
+
+ HIR::Expr &discrim_expr = variant->get_discriminant ();
+ tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
+ tree folded_discrim_expr = fold_expr (discrim_expr_node);
+ tree qualifier = folded_discrim_expr;
+
+ tree enum_root_files = TYPE_FIELDS (compiled_adt_type);
+ tree payload_root = DECL_CHAIN (enum_root_files);
+
+ tree payload = Backend::constructor_expression (TREE_TYPE (payload_root),
+ adt->is_enum (), arguments,
+ union_disriminator,
+ struct_expr.get_locus ());
+
+ std::vector<tree> ctor_arguments = {qualifier, payload};
translated
- = Backend::constructor_expression (compiled_adt_type, adt->is_enum (),
- ctor_arguments, union_disriminator,
+ = Backend::constructor_expression (compiled_adt_type, 0, ctor_arguments, -1,
struct_expr.get_locus ());
}
void
CompileExpr::visit (HIR::GroupedExpr &expr)
{
- translated = CompileExpr::Compile (expr.get_expr_in_parens ().get (), ctx);
+ translated = CompileExpr::Compile (expr.get_expr_in_parens (), ctx);
}
void
CompileExpr::visit (HIR::FieldAccessExpr &expr)
{
- HIR::Expr *receiver_expr = expr.get_receiver_expr ().get ();
+ HIR::Expr &receiver_expr = expr.get_receiver_expr ();
tree receiver_ref = CompileExpr::Compile (receiver_expr, ctx);
// resolve the receiver back to ADT type
TyTy::BaseType *receiver = nullptr;
if (!ctx->get_tyctx ()->lookup_type (
- expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
+ expr.get_receiver_expr ().get_mappings ().get_hirid (), &receiver))
{
- rust_error_at (expr.get_receiver_expr ()->get_locus (),
+ rust_error_at (expr.get_receiver_expr ().get_locus (),
"unresolved type for receiver");
return;
}
@@ -672,7 +708,7 @@ CompileExpr::visit (HIR::LoopExpr &expr)
ctx->push_loop_begin_label (loop_begin_label);
tree code_block
- = CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
+ = CompileBlock::compile (expr.get_loop_block (), ctx, nullptr);
tree loop_expr = Backend::loop_expression (code_block, expr.get_locus ());
ctx->add_statement (loop_expr);
@@ -699,8 +735,8 @@ CompileExpr::visit (HIR::WhileLoopExpr &expr)
}
std::vector<Bvariable *> locals;
- location_t start_location = expr.get_loop_block ()->get_locus ();
- location_t end_location = expr.get_loop_block ()->get_locus (); // FIXME
+ location_t start_location = expr.get_loop_block ().get_locus ();
+ location_t end_location = expr.get_loop_block ().get_locus (); // FIXME
tree enclosing_scope = ctx->peek_enclosing_scope ();
tree loop_block = Backend::block (fnctx.fndecl, enclosing_scope, locals,
@@ -713,15 +749,14 @@ CompileExpr::visit (HIR::WhileLoopExpr &expr)
ctx->add_statement (loop_begin_label_decl);
ctx->push_loop_begin_label (loop_begin_label);
- tree condition
- = CompileExpr::Compile (expr.get_predicate_expr ().get (), ctx);
+ tree condition = CompileExpr::Compile (expr.get_predicate_expr (), ctx);
tree exit_condition = fold_build1_loc (expr.get_locus (), TRUTH_NOT_EXPR,
boolean_type_node, condition);
tree exit_expr = Backend::exit_expression (exit_condition, expr.get_locus ());
ctx->add_statement (exit_expr);
tree code_block_stmt
- = CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
+ = CompileBlock::compile (expr.get_loop_block (), ctx, nullptr);
rust_assert (TREE_CODE (code_block_stmt) == BIND_EXPR);
ctx->add_statement (code_block_stmt);
@@ -737,12 +772,12 @@ CompileExpr::visit (HIR::BreakExpr &expr)
{
if (expr.has_break_expr ())
{
- tree compiled_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+ tree compiled_expr = CompileExpr::Compile (expr.get_expr (), ctx);
Bvariable *loop_result_holder = ctx->peek_loop_context ();
tree result_reference
= Backend::var_expression (loop_result_holder,
- expr.get_expr ()->get_locus ());
+ expr.get_expr ().get_locus ());
tree assignment
= Backend::assignment_statement (result_reference, compiled_expr,
@@ -865,7 +900,7 @@ CompileExpr::visit (HIR::ContinueExpr &expr)
void
CompileExpr::visit (HIR::BorrowExpr &expr)
{
- tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+ tree main_expr = CompileExpr::Compile (expr.get_expr (), ctx);
if (RS_DST_FLAG_P (TREE_TYPE (main_expr)))
{
translated = main_expr;
@@ -877,7 +912,8 @@ CompileExpr::visit (HIR::BorrowExpr &expr)
&tyty))
return;
- translated = address_expression (main_expr, expr.get_locus ());
+ tree expected_type = TyTyResolveCompile::compile (ctx, tyty);
+ translated = address_expression (main_expr, expr.get_locus (), expected_type);
}
void
@@ -892,7 +928,7 @@ CompileExpr::visit (HIR::DereferenceExpr &expr)
return;
}
- tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+ tree main_expr = CompileExpr::Compile (expr.get_expr (), ctx);
// this might be an operator overload situation lets check
TyTy::FnType *fntype;
@@ -903,7 +939,7 @@ CompileExpr::visit (HIR::DereferenceExpr &expr)
auto lang_item_type = LangItem::Kind::DEREF;
tree operator_overload_call
= resolve_operator_overload (lang_item_type, expr, main_expr, nullptr,
- expr.get_expr ().get (), nullptr);
+ expr.get_expr (), tl::nullopt);
// rust deref always returns a reference from this overload then we can
// actually do the indirection
@@ -963,8 +999,8 @@ CompileExpr::visit (HIR::LiteralExpr &expr)
void
CompileExpr::visit (HIR::AssignmentExpr &expr)
{
- auto lvalue = CompileExpr::Compile (expr.get_lhs ().get (), ctx);
- auto rvalue = CompileExpr::Compile (expr.get_rhs ().get (), ctx);
+ auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx);
// assignments are coercion sites so lets convert the rvalue if necessary
TyTy::BaseType *expected = nullptr;
@@ -972,16 +1008,16 @@ CompileExpr::visit (HIR::AssignmentExpr &expr)
bool ok;
ok = ctx->get_tyctx ()->lookup_type (
- expr.get_lhs ()->get_mappings ().get_hirid (), &expected);
+ expr.get_lhs ().get_mappings ().get_hirid (), &expected);
rust_assert (ok);
ok = ctx->get_tyctx ()->lookup_type (
- expr.get_rhs ()->get_mappings ().get_hirid (), &actual);
+ expr.get_rhs ().get_mappings ().get_hirid (), &actual);
rust_assert (ok);
rvalue = coercion_site (expr.get_mappings ().get_hirid (), rvalue, actual,
- expected, expr.get_lhs ()->get_locus (),
- expr.get_rhs ()->get_locus ());
+ expected, expr.get_lhs ().get_locus (),
+ expr.get_rhs ().get_locus ());
// rust_debug_loc (expr.get_locus (), "XXXXXX assignment");
// debug_tree (rvalue);
@@ -1002,30 +1038,15 @@ check_match_scrutinee (HIR::MatchExpr &expr, Context *ctx)
{
TyTy::BaseType *scrutinee_expr_tyty = nullptr;
if (!ctx->get_tyctx ()->lookup_type (
- expr.get_scrutinee_expr ()->get_mappings ().get_hirid (),
+ expr.get_scrutinee_expr ().get_mappings ().get_hirid (),
&scrutinee_expr_tyty))
{
return TyTy::TypeKind::ERROR;
}
TyTy::TypeKind scrutinee_kind = scrutinee_expr_tyty->get_kind ();
- rust_assert ((TyTy::is_primitive_type_kind (scrutinee_kind)
- && scrutinee_kind != TyTy::TypeKind::NEVER)
- || scrutinee_kind == TyTy::TypeKind::ADT
- || scrutinee_kind == TyTy::TypeKind::TUPLE
- || scrutinee_kind == TyTy::TypeKind::REF);
-
- if (scrutinee_kind == TyTy::TypeKind::ADT)
- {
- // this will need to change but for now the first pass implementation,
- // lets assert this is the case
- TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (scrutinee_expr_tyty);
- if (adt->is_enum ())
- rust_assert (adt->number_of_variants () > 0);
- else
- rust_assert (adt->number_of_variants () == 1);
- }
- else if (scrutinee_kind == TyTy::TypeKind::FLOAT)
+
+ if (scrutinee_kind == TyTy::TypeKind::FLOAT)
{
// FIXME: CASE_LABEL_EXPR does not support floating point types.
// Find another way to compile these.
@@ -1066,6 +1087,15 @@ CompileExpr::visit (HIR::MatchExpr &expr)
return;
}
+ // if the result of this expression is meant to be never type then we can
+ // optimise this away but there is the case where match arms resolve to !
+ // because of return statements we need to special case this
+ if (!expr.has_match_arms () && expr_tyty->is<TyTy::NeverType> ())
+ {
+ translated = unit_expression (expr.get_locus ());
+ return;
+ }
+
fncontext fnctx = ctx->peek_fn ();
Bvariable *tmp = NULL;
tree enclosing_scope = ctx->peek_enclosing_scope ();
@@ -1080,7 +1110,7 @@ CompileExpr::visit (HIR::MatchExpr &expr)
// lets compile the scrutinee expression
tree match_scrutinee_rval
- = CompileExpr::Compile (expr.get_scrutinee_expr ().get (), ctx);
+ = CompileExpr::Compile (expr.get_scrutinee_expr (), ctx);
Bvariable *match_scrutinee_tmp_var
= Backend::temporary_variable (fnctx.fndecl, enclosing_scope,
@@ -1090,7 +1120,7 @@ CompileExpr::visit (HIR::MatchExpr &expr)
ctx->add_statement (ret_var_stmt);
tree match_scrutinee_expr = match_scrutinee_tmp_var->get_tree (
- expr.get_scrutinee_expr ()->get_locus ());
+ expr.get_scrutinee_expr ().get_locus ());
tree assignment
= Backend::assignment_statement (match_scrutinee_expr, match_scrutinee_rval,
@@ -1123,17 +1153,27 @@ CompileExpr::visit (HIR::MatchExpr &expr)
ctx->push_block (arm_body_block);
// setup the bindings for the block
- CompilePatternBindings::Compile (kase_pattern.get (),
- match_scrutinee_expr, ctx);
+ CompilePatternBindings::Compile (*kase_pattern, match_scrutinee_expr,
+ ctx);
// compile the expr and setup the assignment if required when tmp !=
// NULL
location_t arm_locus = kase_arm.get_locus ();
- tree kase_expr_tree
- = CompileExpr::Compile (kase.get_expr ().get (), ctx);
+ tree kase_expr_tree = CompileExpr::Compile (kase.get_expr (), ctx);
tree result_reference = Backend::var_expression (tmp, arm_locus);
+
+ TyTy::BaseType *actual = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ kase.get_expr ().get_mappings ().get_hirid (), &actual);
+ rust_assert (ok);
+
+ tree coerced_result
+ = coercion_site (kase.get_expr ().get_mappings ().get_hirid (),
+ kase_expr_tree, actual, expr_tyty,
+ expr.get_locus (), arm_locus);
+
tree assignment
- = Backend::assignment_statement (result_reference, kase_expr_tree,
+ = Backend::assignment_statement (result_reference, coerced_result,
arm_locus);
ctx->add_statement (assignment);
@@ -1145,7 +1185,7 @@ CompileExpr::visit (HIR::MatchExpr &expr)
ctx->pop_block ();
tree check_expr
- = CompilePatternCheckExpr::Compile (kase_pattern.get (),
+ = CompilePatternCheckExpr::Compile (*kase_pattern,
match_scrutinee_expr, ctx);
tree check_stmt
@@ -1167,7 +1207,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
{
TyTy::BaseType *tyty = nullptr;
if (!ctx->get_tyctx ()->lookup_type (
- expr.get_fnexpr ()->get_mappings ().get_hirid (), &tyty))
+ expr.get_fnexpr ().get_mappings ().get_hirid (), &tyty))
{
rust_error_at (expr.get_locus (), "unknown type");
return;
@@ -1193,7 +1233,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
{
HirId variant_id;
bool ok = ctx->get_tyctx ()->lookup_variant_definition (
- expr.get_fnexpr ()->get_mappings ().get_hirid (), &variant_id);
+ expr.get_fnexpr ().get_mappings ().get_hirid (), &variant_id);
rust_assert (ok);
ok = adt->lookup_variant_by_id (variant_id, &variant,
@@ -1204,10 +1244,10 @@ CompileExpr::visit (HIR::CallExpr &expr)
// this assumes all fields are in order from type resolution and if a
// base struct was specified those fields are filed via accessors
std::vector<tree> arguments;
- for (size_t i = 0; i < expr.get_arguments ().size (); i++)
+ for (size_t i = 0; i < expr.num_params (); i++)
{
auto &argument = expr.get_arguments ().at (i);
- auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+ auto rvalue = CompileExpr::Compile (*argument, ctx);
// assignments are coercion sites so lets convert the rvalue if
// necessary
@@ -1231,26 +1271,34 @@ CompileExpr::visit (HIR::CallExpr &expr)
arguments.push_back (rvalue);
}
- // the constructor depends on whether this is actually an enum or not if
- // its an enum we need to setup the discriminator
- std::vector<tree> ctor_arguments;
- if (adt->is_enum ())
+ if (!adt->is_enum ())
{
- HIR::Expr *discrim_expr = variant->get_discriminant ();
- tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
- tree folded_discrim_expr = fold_expr (discrim_expr_node);
- tree qualifier = folded_discrim_expr;
-
- ctor_arguments.push_back (qualifier);
+ translated
+ = Backend::constructor_expression (compiled_adt_type,
+ adt->is_enum (), arguments,
+ union_disriminator,
+ expr.get_locus ());
+ return;
}
- for (auto &arg : arguments)
- ctor_arguments.push_back (arg);
- translated
- = Backend::constructor_expression (compiled_adt_type, adt->is_enum (),
- ctor_arguments, union_disriminator,
+ HIR::Expr &discrim_expr = variant->get_discriminant ();
+ tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
+ tree folded_discrim_expr = fold_expr (discrim_expr_node);
+ tree qualifier = folded_discrim_expr;
+
+ tree enum_root_files = TYPE_FIELDS (compiled_adt_type);
+ tree payload_root = DECL_CHAIN (enum_root_files);
+
+ tree payload
+ = Backend::constructor_expression (TREE_TYPE (payload_root), true,
+ {arguments}, union_disriminator,
expr.get_locus ());
+ std::vector<tree> ctor_arguments = {qualifier, payload};
+ translated = Backend::constructor_expression (compiled_adt_type, false,
+ ctor_arguments, -1,
+ expr.get_locus ());
+
return;
}
@@ -1270,13 +1318,13 @@ CompileExpr::visit (HIR::CallExpr &expr)
}
const TyTy::FnType *fn = static_cast<const TyTy::FnType *> (base);
- auto param = fn->param_at (index);
- *result = param.second;
+ auto &param = fn->param_at (index);
+ *result = param.get_type ();
return true;
};
- auto fn_address = CompileExpr::Compile (expr.get_fnexpr ().get (), ctx);
+ auto fn_address = CompileExpr::Compile (expr.get_fnexpr (), ctx);
// is this a closure call?
bool possible_trait_call
@@ -1303,7 +1351,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
for (size_t i = 0; i < expr.get_arguments ().size (); i++)
{
auto &argument = expr.get_arguments ().at (i);
- auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+ auto rvalue = CompileExpr::Compile (*argument, ctx);
if (is_variadic && i >= required_num_args)
{
@@ -1343,7 +1391,7 @@ void
CompileExpr::visit (HIR::MethodCallExpr &expr)
{
// method receiver
- tree self = CompileExpr::Compile (expr.get_receiver ().get (), ctx);
+ tree self = CompileExpr::Compile (expr.get_receiver (), ctx);
// lookup the expected function type
TyTy::BaseType *lookup_fntype = nullptr;
@@ -1354,8 +1402,8 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup_fntype);
TyTy::BaseType *receiver = nullptr;
- ok = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
- &receiver);
+ ok = ctx->get_tyctx ()->lookup_type (
+ expr.get_receiver ().get_mappings ().get_hirid (), &receiver);
rust_assert (ok);
bool is_dyn_dispatch
@@ -1383,7 +1431,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
// lookup the autoderef mappings
HirId autoderef_mappings_id
- = expr.get_receiver ()->get_mappings ().get_hirid ();
+ = expr.get_receiver ().get_mappings ().get_hirid ();
std::vector<Resolver::Adjustment> *adjustments = nullptr;
ok = ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id,
&adjustments);
@@ -1391,7 +1439,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
// apply adjustments for the fn call
self = resolve_adjustements (*adjustments, self,
- expr.get_receiver ()->get_locus ());
+ expr.get_receiver ().get_locus ());
std::vector<tree> args;
args.push_back (self); // adjusted self
@@ -1400,12 +1448,12 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
for (size_t i = 0; i < expr.get_arguments ().size (); i++)
{
auto &argument = expr.get_arguments ().at (i);
- auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+ auto rvalue = CompileExpr::Compile (*argument, ctx);
// assignments are coercion sites so lets convert the rvalue if
// necessary, offset from the already adjusted implicit self
bool ok;
- TyTy::BaseType *expected = fntype->param_at (i + 1).second;
+ TyTy::BaseType *expected = fntype->param_at (i + 1).get_type ();
TyTy::BaseType *actual = nullptr;
ok = ctx->get_tyctx ()->lookup_type (
@@ -1480,10 +1528,10 @@ CompileExpr::get_receiver_from_dyn (const TyTy::DynamicObjectType *dyn,
}
tree
-CompileExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
- HIR::OperatorExprMeta expr, tree lhs,
- tree rhs, HIR::Expr *lhs_expr,
- HIR::Expr *rhs_expr)
+CompileExpr::resolve_operator_overload (
+ LangItem::Kind lang_item_type, HIR::OperatorExprMeta expr, tree lhs, tree rhs,
+ HIR::Expr &lhs_expr, tl::optional<std::reference_wrapper<HIR::Expr>> rhs_expr,
+ HIR::PathIdentSegment specified_segment)
{
TyTy::FnType *fntype;
bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
@@ -1492,8 +1540,8 @@ CompileExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
TyTy::BaseType *receiver = nullptr;
bool ok
- = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
- &receiver);
+ = ctx->get_tyctx ()->lookup_type (lhs_expr.get_mappings ().get_hirid (),
+ &receiver);
rust_assert (ok);
bool is_generic_receiver = receiver->get_kind () == TyTy::TypeKind::PARAM;
@@ -1504,7 +1552,10 @@ CompileExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
}
// lookup compiled functions since it may have already been compiled
- HIR::PathIdentSegment segment_name (LangItem::ToString (lang_item_type));
+ HIR::PathIdentSegment segment_name
+ = specified_segment.is_error ()
+ ? HIR::PathIdentSegment (LangItem::ToString (lang_item_type))
+ : specified_segment;
tree fn_expr = resolve_method_address (fntype, receiver, expr.get_locus ());
// lookup the autoderef mappings
@@ -1514,7 +1565,7 @@ CompileExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
rust_assert (ok);
// apply adjustments for the fn call
- tree self = resolve_adjustements (*adjustments, lhs, lhs_expr->get_locus ());
+ tree self = resolve_adjustements (*adjustments, lhs, lhs_expr.get_locus ());
std::vector<tree> args;
args.push_back (self); // adjusted self
@@ -1829,7 +1880,7 @@ CompileExpr::visit (HIR::ArrayExpr &expr)
const TyTy::ArrayType &array_tyty
= static_cast<const TyTy::ArrayType &> (*tyty);
- HIR::ArrayElems &elements = *expr.get_internal_elements ();
+ HIR::ArrayElems &elements = expr.get_internal_elements ();
switch (elements.get_array_expr_type ())
{
case HIR::ArrayElems::ArrayExprType::VALUES: {
@@ -1858,7 +1909,15 @@ CompileExpr::array_value_expr (location_t expr_locus,
size_t i = 0;
for (auto &elem : elems.get_values ())
{
- tree translated_expr = CompileExpr::Compile (elem.get (), ctx);
+ tree translated_expr = CompileExpr::Compile (*elem, ctx);
+ if (translated_expr == error_mark_node)
+ {
+ rich_location r (line_table, expr_locus);
+ r.add_fixit_replace (elem->get_locus (), "not a value");
+ rust_error_at (r, ErrorCode::E0423, "expected value");
+ return error_mark_node;
+ }
+
constructor.push_back (translated_expr);
indexes.push_back (i++);
}
@@ -1885,8 +1944,7 @@ CompileExpr::array_copied_expr (location_t expr_locus,
}
ctx->push_const_context ();
- tree capacity_expr
- = CompileExpr::Compile (elems.get_num_copies_expr ().get (), ctx);
+ tree capacity_expr = CompileExpr::Compile (elems.get_num_copies_expr (), ctx);
ctx->pop_const_context ();
if (!TREE_CONSTANT (capacity_expr))
@@ -1896,8 +1954,7 @@ CompileExpr::array_copied_expr (location_t expr_locus,
}
// get the compiled value
- tree translated_expr
- = CompileExpr::Compile (elems.get_elem_to_copy ().get (), ctx);
+ tree translated_expr = CompileExpr::Compile (elems.get_elem_to_copy (), ctx);
tree max_domain = TYPE_MAX_VALUE (domain);
tree min_domain = TYPE_MIN_VALUE (domain);
@@ -1915,8 +1972,12 @@ CompileExpr::array_copied_expr (location_t expr_locus,
if (ctx->const_context_p ())
{
size_t idx = 0;
+
std::vector<unsigned long> indexes;
std::vector<tree> constructor;
+
+ indexes.reserve (len);
+ constructor.reserve (len);
for (unsigned HOST_WIDE_INT i = 0; i < len; i++)
{
constructor.push_back (translated_expr);
@@ -1962,6 +2023,9 @@ HIRCompileBase::resolve_adjustements (
tree e = expression;
for (auto &adjustment : adjustments)
{
+ if (e == error_mark_node)
+ return error_mark_node;
+
switch (adjustment.get_type ())
{
case Resolver::Adjustment::AdjustmentType::ERROR:
@@ -2102,8 +2166,8 @@ HIRCompileBase::resolve_unsized_dyn_adjustment (
void
CompileExpr::visit (HIR::RangeFromToExpr &expr)
{
- tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx);
- tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx);
+ tree from = CompileExpr::Compile (expr.get_from_expr (), ctx);
+ tree to = CompileExpr::Compile (expr.get_to_expr (), ctx);
if (from == error_mark_node || to == error_mark_node)
{
translated = error_mark_node;
@@ -2125,7 +2189,7 @@ CompileExpr::visit (HIR::RangeFromToExpr &expr)
void
CompileExpr::visit (HIR::RangeFromExpr &expr)
{
- tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx);
+ tree from = CompileExpr::Compile (expr.get_from_expr (), ctx);
if (from == error_mark_node)
{
translated = error_mark_node;
@@ -2147,7 +2211,7 @@ CompileExpr::visit (HIR::RangeFromExpr &expr)
void
CompileExpr::visit (HIR::RangeToExpr &expr)
{
- tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx);
+ tree to = CompileExpr::Compile (expr.get_to_expr (), ctx);
if (to == error_mark_node)
{
translated = error_mark_node;
@@ -2182,8 +2246,8 @@ CompileExpr::visit (HIR::RangeFullExpr &expr)
void
CompileExpr::visit (HIR::RangeFromToInclExpr &expr)
{
- tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx);
- tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx);
+ tree from = CompileExpr::Compile (expr.get_from_expr (), ctx);
+ tree to = CompileExpr::Compile (expr.get_to_expr (), ctx);
if (from == error_mark_node || to == error_mark_node)
{
translated = error_mark_node;
@@ -2205,9 +2269,8 @@ CompileExpr::visit (HIR::RangeFromToInclExpr &expr)
void
CompileExpr::visit (HIR::ArrayIndexExpr &expr)
{
- tree array_reference
- = CompileExpr::Compile (expr.get_array_expr ().get (), ctx);
- tree index = CompileExpr::Compile (expr.get_index_expr ().get (), ctx);
+ tree array_reference = CompileExpr::Compile (expr.get_array_expr (), ctx);
+ tree index = CompileExpr::Compile (expr.get_index_expr (), ctx);
// this might be an core::ops::index lang item situation
TyTy::FnType *fntype;
@@ -2218,8 +2281,8 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr)
auto lang_item_type = LangItem::Kind::INDEX;
tree operator_overload_call
= resolve_operator_overload (lang_item_type, expr, array_reference,
- index, expr.get_array_expr ().get (),
- expr.get_index_expr ().get ());
+ index, expr.get_array_expr (),
+ expr.get_index_expr ());
tree actual_type = TREE_TYPE (operator_overload_call);
bool can_indirect = TYPE_PTR_P (actual_type) || TYPE_REF_P (actual_type);
@@ -2241,7 +2304,7 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr)
// indirection if required
TyTy::BaseType *array_expr_ty = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
- expr.get_array_expr ()->get_mappings ().get_hirid (), &array_expr_ty);
+ expr.get_array_expr ().get_mappings ().get_hirid (), &array_expr_ty);
rust_assert (ok);
// do we need to add an indirect reference
@@ -2392,7 +2455,7 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
= Backend::struct_field_expression (args_param_expr, i,
closure_param.get_locus ());
- CompilePatternBindings::Compile (closure_param.get_pattern ().get (),
+ CompilePatternBindings::Compile (closure_param.get_pattern (),
compiled_param_var, ctx);
i++;
}
@@ -2404,16 +2467,16 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
}
// lookup locals
- HIR::Expr *function_body = expr.get_expr ().get ();
+ HIR::Expr &function_body = expr.get_expr ();
bool is_block_expr
- = function_body->get_expression_type () == HIR::Expr::ExprType::Block;
+ = function_body.get_expression_type () == HIR::Expr::ExprType::Block;
if (is_block_expr)
{
- auto body_mappings = function_body->get_mappings ();
+ auto body_mappings = function_body.get_mappings ();
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
auto candidate = nr_ctx.values.to_rib (body_mappings.get_nodeid ());
@@ -2431,13 +2494,13 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
}
tree enclosing_scope = NULL_TREE;
- location_t start_location = function_body->get_locus ();
- location_t end_location = function_body->get_locus ();
+ location_t start_location = function_body.get_locus ();
+ location_t end_location = function_body.get_locus ();
if (is_block_expr)
{
- HIR::BlockExpr *body = static_cast<HIR::BlockExpr *> (function_body);
- start_location = body->get_locus ();
- end_location = body->get_end_locus ();
+ auto &body = static_cast<HIR::BlockExpr &> (function_body);
+ start_location = body.get_locus ();
+ end_location = body.get_end_locus ();
}
tree code_block = Backend::block (fndecl, enclosing_scope, {} /*locals*/,
@@ -2462,15 +2525,14 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
if (is_block_expr)
{
- HIR::BlockExpr *body = static_cast<HIR::BlockExpr *> (function_body);
- compile_function_body (fndecl, *body, tyret);
+ auto &body = static_cast<HIR::BlockExpr &> (function_body);
+ compile_function_body (fndecl, body, tyret);
}
else
{
tree value = CompileExpr::Compile (function_body, ctx);
tree return_expr
- = Backend::return_statement (fndecl, value,
- function_body->get_locus ());
+ = Backend::return_statement (fndecl, value, function_body.get_locus ());
ctx->add_statement (return_expr);
}
@@ -2557,8 +2619,8 @@ CompileExpr::generate_possible_fn_trait_call (HIR::CallExpr &expr,
}
// need to apply any autoderef's to the self argument
- HIR::Expr *fnexpr = expr.get_fnexpr ().get ();
- HirId autoderef_mappings_id = fnexpr->get_mappings ().get_hirid ();
+ HIR::Expr &fnexpr = expr.get_fnexpr ();
+ HirId autoderef_mappings_id = fnexpr.get_mappings ().get_hirid ();
std::vector<Resolver::Adjustment> *adjustments = nullptr;
bool ok = ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id,
&adjustments);
@@ -2571,7 +2633,7 @@ CompileExpr::generate_possible_fn_trait_call (HIR::CallExpr &expr,
std::vector<tree> tuple_arg_vals;
for (auto &argument : expr.get_arguments ())
{
- auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+ auto rvalue = CompileExpr::Compile (*argument, ctx);
tuple_arg_vals.push_back (rvalue);
}
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index ef907d1..65ed4b3 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -28,7 +28,7 @@ namespace Compile {
class CompileExpr : private HIRCompileBase, protected HIR::HIRExpressionVisitor
{
public:
- static tree Compile (HIR::Expr *expr, Context *ctx);
+ static tree Compile (HIR::Expr &expr, Context *ctx);
void visit (HIR::TupleIndexExpr &expr) override;
void visit (HIR::TupleExpr &expr) override;
@@ -69,6 +69,7 @@ public:
void visit (HIR::RangeFromToInclExpr &expr) override;
void visit (HIR::ClosureExpr &expr) override;
void visit (HIR::InlineAsm &expr) override;
+ void visit (HIR::LlvmInlineAsm &expr) override;
// TODO
void visit (HIR::ErrorPropagationExpr &) override {}
@@ -77,8 +78,6 @@ public:
// TODO
// these need to be sugared in the HIR to if statements and a match
void visit (HIR::WhileLetLoopExpr &) override {}
- void visit (HIR::IfLetExpr &) override {}
- void visit (HIR::IfLetExprConseqElse &) override {}
// lets not worry about async yet....
void visit (HIR::AwaitExpr &) override {}
@@ -98,10 +97,12 @@ protected:
TyTy::BaseType *receiver, TyTy::FnType *fntype,
tree receiver_ref, location_t expr_locus);
- tree resolve_operator_overload (LangItem::Kind lang_item_type,
- HIR::OperatorExprMeta expr, tree lhs,
- tree rhs, HIR::Expr *lhs_expr,
- HIR::Expr *rhs_expr);
+ tree resolve_operator_overload (
+ LangItem::Kind lang_item_type, HIR::OperatorExprMeta expr, tree lhs,
+ tree rhs, HIR::Expr &lhs_expr,
+ tl::optional<std::reference_wrapper<HIR::Expr>> rhs_expr,
+ HIR::PathIdentSegment specified_segment
+ = HIR::PathIdentSegment::create_error ());
tree compile_bool_literal (const HIR::LiteralExpr &expr,
const TyTy::BaseType *tyty);
diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index bacd1c0..d6aa589 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -34,16 +34,10 @@ class CompileExternItem : public HIRCompileBase,
public:
static tree compile (HIR::ExternalItem *item, Context *ctx,
TyTy::BaseType *concrete = nullptr,
- bool is_query_mode = false,
location_t ref_locus = UNDEF_LOCATION)
{
CompileExternItem compiler (ctx, concrete, ref_locus);
item->accept_vis (compiler);
-
- if (is_query_mode && compiler.reference == error_mark_node)
- rust_internal_error_at (ref_locus, "failed to compile extern item: %s",
- item->as_string ().c_str ());
-
return compiler.reference;
}
diff --git a/gcc/rust/backend/rust-compile-fnparam.cc b/gcc/rust/backend/rust-compile-fnparam.cc
index af24ca0..b40065e 100644
--- a/gcc/rust/backend/rust-compile-fnparam.cc
+++ b/gcc/rust/backend/rust-compile-fnparam.cc
@@ -31,20 +31,20 @@ CompileFnParam::CompileFnParam (Context *ctx, tree fndecl, tree decl_type,
{}
Bvariable *
-CompileFnParam::compile (Context *ctx, tree fndecl, HIR::FunctionParam *param,
+CompileFnParam::compile (Context *ctx, tree fndecl, HIR::FunctionParam &param,
tree decl_type, location_t locus)
{
CompileFnParam compiler (ctx, fndecl, decl_type, locus);
- param->get_param_name ()->accept_vis (compiler);
+ param.get_param_name ().accept_vis (compiler);
return compiler.compiled_param;
}
Bvariable *
-CompileFnParam::compile (Context *ctx, tree fndecl, HIR::Pattern *param,
+CompileFnParam::compile (Context *ctx, tree fndecl, HIR::Pattern &param,
tree decl_type, location_t locus)
{
CompileFnParam compiler (ctx, fndecl, decl_type, locus);
- param->accept_vis (compiler);
+ param.accept_vis (compiler);
return compiler.compiled_param;
}
@@ -69,24 +69,35 @@ CompileFnParam::visit (HIR::WildcardPattern &pattern)
}
void
+CompileFnParam::visit (HIR::TuplePattern &pattern)
+{
+ compiled_param = create_tmp_param_var (decl_type);
+ CompilePatternBindings::Compile (
+ pattern, Backend::var_expression (compiled_param, locus), ctx);
+}
+
+void
CompileFnParam::visit (HIR::StructPattern &pattern)
{
- tree tmp_param_var = create_tmp_param_var (decl_type);
- CompilePatternBindings::Compile (&pattern, tmp_param_var, ctx);
+ compiled_param = create_tmp_param_var (decl_type);
+ CompilePatternBindings::Compile (
+ pattern, Backend::var_expression (compiled_param, locus), ctx);
}
void
CompileFnParam::visit (HIR::TupleStructPattern &pattern)
{
- tree tmp_param_var = create_tmp_param_var (decl_type);
- CompilePatternBindings::Compile (&pattern, tmp_param_var, ctx);
+ compiled_param = create_tmp_param_var (decl_type);
+ CompilePatternBindings::Compile (
+ pattern, Backend::var_expression (compiled_param, locus), ctx);
}
void
CompileFnParam::visit (HIR::ReferencePattern &pattern)
{
- tree tmp_param_var = create_tmp_param_var (decl_type);
- CompilePatternBindings::Compile (&pattern, tmp_param_var, ctx);
+ compiled_param = create_tmp_param_var (decl_type);
+ CompilePatternBindings::Compile (
+ pattern, Backend::var_expression (compiled_param, locus), ctx);
}
Bvariable *
@@ -102,7 +113,7 @@ CompileSelfParam::compile (Context *ctx, tree fndecl, HIR::SelfParam &self,
return Backend::parameter_variable (fndecl, "self", decl_type, locus);
}
-tree
+Bvariable *
CompileFnParam::create_tmp_param_var (tree decl_type)
{
// generate the anon param
@@ -110,10 +121,8 @@ CompileFnParam::create_tmp_param_var (tree decl_type)
std::string cpp_str_identifier = std::string (IDENTIFIER_POINTER (tmp_ident));
decl_type = Backend::immutable_type (decl_type);
- compiled_param = Backend::parameter_variable (fndecl, cpp_str_identifier,
- decl_type, locus);
-
- return Backend::var_expression (compiled_param, locus);
+ return Backend::parameter_variable (fndecl, cpp_str_identifier, decl_type,
+ locus);
}
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h
index 09a3e69..189216c 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -29,9 +29,9 @@ class CompileFnParam : private HIRCompileBase, protected HIR::HIRPatternVisitor
{
public:
static Bvariable *compile (Context *ctx, tree fndecl,
- HIR::FunctionParam *param, tree decl_type,
+ HIR::FunctionParam &param, tree decl_type,
location_t locus);
- static Bvariable *compile (Context *ctx, tree fndecl, HIR::Pattern *param,
+ static Bvariable *compile (Context *ctx, tree fndecl, HIR::Pattern &param,
tree decl_type, location_t locus);
void visit (HIR::IdentifierPattern &pattern) override;
@@ -47,12 +47,12 @@ public:
void visit (HIR::QualifiedPathInExpression &) override {}
void visit (HIR::RangePattern &) override {}
void visit (HIR::SlicePattern &) override {}
- void visit (HIR::TuplePattern &) override {}
+ void visit (HIR::TuplePattern &) override;
private:
CompileFnParam (Context *ctx, tree fndecl, tree decl_type, location_t locus);
- tree create_tmp_param_var (tree decl_type);
+ Bvariable *create_tmp_param_var (tree decl_type);
tree fndecl;
tree decl_type;
diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc
index 4c7d8e8..1230c85 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -27,13 +27,34 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
rust_assert (concrete != nullptr);
TyTy::BaseType *resolved_type = concrete;
- auto canonical_path = ctx->get_mappings ().lookup_canonical_path (
- constant.get_mappings ().get_nodeid ());
+ tl::optional<Resolver::CanonicalPath> canonical_path;
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ canonical_path = nr_ctx.values.to_canonical_path (
+ constant.get_mappings ().get_nodeid ());
+ }
+ else
+ {
+ canonical_path = ctx->get_mappings ().lookup_canonical_path (
+ constant.get_mappings ().get_nodeid ());
+ }
+
+ rust_assert (canonical_path);
+
+ HIR::Expr &const_value_expr = constant.get_expr ();
+ TyTy::BaseType *expr_type = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ const_value_expr.get_mappings ().get_hirid (), &expr_type);
+ rust_assert (ok);
- HIR::Expr *const_value_expr = constant.get_expr ().get ();
tree const_expr
- = compile_constant_item (resolved_type, *canonical_path, const_value_expr,
- constant.get_locus ());
+ = compile_constant_item (constant.get_mappings ().get_hirid (), expr_type,
+ resolved_type, *canonical_path, const_value_expr,
+ constant.get_locus (),
+ const_value_expr.get_locus ());
ctx->push_const (const_expr);
ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
@@ -43,7 +64,7 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
void
CompileTraitItem::visit (HIR::TraitItemFunc &func)
{
- rust_assert (func.has_block_defined ());
+ rust_assert (func.has_definition ());
rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (concrete);
@@ -75,18 +96,32 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func)
fntype->override_context ();
}
- auto canonical_path = ctx->get_mappings ().lookup_canonical_path (
- func.get_mappings ().get_nodeid ());
+ tl::optional<Resolver::CanonicalPath> canonical_path;
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ canonical_path
+ = nr_ctx.values.to_canonical_path (func.get_mappings ().get_nodeid ());
+ }
+ else
+ {
+ canonical_path = ctx->get_mappings ().lookup_canonical_path (
+ func.get_mappings ().get_nodeid ());
+ }
+
+ rust_assert (canonical_path);
// FIXME: How do we get the proper visibility here?
auto vis = HIR::Visibility (HIR::Visibility::VisType::PUBLIC);
HIR::TraitFunctionDecl &function = func.get_decl ();
tree fndecl
- = compile_function (function.get_function_name ().as_string (),
+ = compile_function (false, function.get_function_name ().as_string (),
function.get_self (), function.get_function_params (),
function.get_qualifiers (), vis,
func.get_outer_attrs (), func.get_locus (),
- func.get_block_expr ().get (), *canonical_path, fntype);
+ &func.get_block_expr (), *canonical_path, fntype);
reference = address_expression (fndecl, ref_locus);
}
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index d2ef989..2d18dbf 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -30,16 +30,10 @@ class CompileInherentImplItem : public CompileItem
public:
static tree Compile (HIR::ImplItem *item, Context *ctx,
TyTy::BaseType *concrete = nullptr,
- bool is_query_mode = false,
location_t ref_locus = UNDEF_LOCATION)
{
CompileInherentImplItem compiler (ctx, concrete, ref_locus);
item->accept_vis (compiler);
-
- if (is_query_mode && compiler.reference == error_mark_node)
- rust_internal_error_at (ref_locus, "failed to compile impl item: %s",
- item->as_string ().c_str ());
-
return compiler.reference;
}
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index de3bb6e..4888e23 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -17,23 +17,19 @@
#include "rust-compile-intrinsic.h"
#include "rust-compile-context.h"
#include "rust-compile-type.h"
-#include "rust-compile-expr.h"
#include "rust-compile-fnparam.h"
#include "rust-builtins.h"
#include "rust-diagnostics.h"
#include "rust-location.h"
#include "rust-constexpr.h"
+#include "rust-session-manager.h"
#include "rust-tree.h"
#include "tree-core.h"
#include "rust-gcc.h"
-#include "print-tree.h"
#include "fold-const.h"
#include "langhooks.h"
-#include "rust-gcc.h"
#include "rust-constexpr.h"
-#include "print-tree.h"
-
// declaration taken from "stringpool.h"
// the get_identifier macro causes compilation issues
extern tree
@@ -92,6 +88,10 @@ 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
{
@@ -194,6 +194,17 @@ expect_handler (bool likely)
};
}
+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)
+{
+ return [is_new_api] (Context *ctx, TyTy::FnType *fntype) {
+ return try_handler_inner (ctx, fntype, is_new_api);
+ };
+}
+
inline tree
sorry_handler (Context *ctx, TyTy::FnType *fntype)
{
@@ -205,43 +216,46 @@ sorry_handler (Context *ctx, TyTy::FnType *fntype)
static const std::map<std::string,
std::function<tree (Context *, TyTy::FnType *)>>
- generic_intrinsics = {
- {"offset", offset_handler},
- {"size_of", sizeof_handler},
- {"transmute", transmute_handler},
- {"rotate_left", rotate_left_handler},
- {"rotate_right", rotate_right_handler},
- {"wrapping_add", wrapping_op_handler (PLUS_EXPR)},
- {"wrapping_sub", wrapping_op_handler (MINUS_EXPR)},
- {"wrapping_mul", wrapping_op_handler (MULT_EXPR)},
- {"add_with_overflow", op_with_overflow (PLUS_EXPR)},
- {"sub_with_overflow", op_with_overflow (MINUS_EXPR)},
- {"mul_with_overflow", op_with_overflow (MULT_EXPR)},
- {"copy", copy_handler (true)},
- {"copy_nonoverlapping", copy_handler (false)},
- {"prefetch_read_data", prefetch_read_data},
- {"prefetch_write_data", prefetch_write_data},
- {"atomic_store_seqcst", atomic_store_handler (__ATOMIC_SEQ_CST)},
- {"atomic_store_release", atomic_store_handler (__ATOMIC_RELEASE)},
- {"atomic_store_relaxed", atomic_store_handler (__ATOMIC_RELAXED)},
- {"atomic_store_unordered", atomic_store_handler (__ATOMIC_RELAXED)},
- {"atomic_load_seqcst", atomic_load_handler (__ATOMIC_SEQ_CST)},
- {"atomic_load_acquire", atomic_load_handler (__ATOMIC_ACQUIRE)},
- {"atomic_load_relaxed", atomic_load_handler (__ATOMIC_RELAXED)},
- {"atomic_load_unordered", atomic_load_handler (__ATOMIC_RELAXED)},
- {"unchecked_add", unchecked_op_handler (PLUS_EXPR)},
- {"unchecked_sub", unchecked_op_handler (MINUS_EXPR)},
- {"unchecked_mul", unchecked_op_handler (MULT_EXPR)},
- {"unchecked_div", unchecked_op_handler (TRUNC_DIV_EXPR)},
- {"unchecked_rem", unchecked_op_handler (TRUNC_MOD_EXPR)},
- {"unchecked_shl", unchecked_op_handler (LSHIFT_EXPR)},
- {"unchecked_shr", unchecked_op_handler (RSHIFT_EXPR)},
- {"uninit", uninit_handler},
- {"move_val_init", move_val_init_handler},
- {"likely", expect_handler (true)},
- {"unlikely", expect_handler (false)},
- {"assume", assume_handler},
-};
+ generic_intrinsics
+ = {{"offset", offset_handler},
+ {"size_of", sizeof_handler},
+ {"transmute", transmute_handler},
+ {"rotate_left", rotate_left_handler},
+ {"rotate_right", rotate_right_handler},
+ {"wrapping_add", wrapping_op_handler (PLUS_EXPR)},
+ {"wrapping_sub", wrapping_op_handler (MINUS_EXPR)},
+ {"wrapping_mul", wrapping_op_handler (MULT_EXPR)},
+ {"add_with_overflow", op_with_overflow (PLUS_EXPR)},
+ {"sub_with_overflow", op_with_overflow (MINUS_EXPR)},
+ {"mul_with_overflow", op_with_overflow (MULT_EXPR)},
+ {"copy", copy_handler (true)},
+ {"copy_nonoverlapping", copy_handler (false)},
+ {"prefetch_read_data", prefetch_read_data},
+ {"prefetch_write_data", prefetch_write_data},
+ {"atomic_store_seqcst", atomic_store_handler (__ATOMIC_SEQ_CST)},
+ {"atomic_store_release", atomic_store_handler (__ATOMIC_RELEASE)},
+ {"atomic_store_relaxed", atomic_store_handler (__ATOMIC_RELAXED)},
+ {"atomic_store_unordered", atomic_store_handler (__ATOMIC_RELAXED)},
+ {"atomic_load_seqcst", atomic_load_handler (__ATOMIC_SEQ_CST)},
+ {"atomic_load_acquire", atomic_load_handler (__ATOMIC_ACQUIRE)},
+ {"atomic_load_relaxed", atomic_load_handler (__ATOMIC_RELAXED)},
+ {"atomic_load_unordered", atomic_load_handler (__ATOMIC_RELAXED)},
+ {"unchecked_add", unchecked_op_handler (PLUS_EXPR)},
+ {"unchecked_sub", unchecked_op_handler (MINUS_EXPR)},
+ {"unchecked_mul", unchecked_op_handler (MULT_EXPR)},
+ {"unchecked_div", unchecked_op_handler (TRUNC_DIV_EXPR)},
+ {"unchecked_rem", unchecked_op_handler (TRUNC_MOD_EXPR)},
+ {"unchecked_shl", unchecked_op_handler (LSHIFT_EXPR)},
+ {"unchecked_shr", unchecked_op_handler (RSHIFT_EXPR)},
+ {"uninit", uninit_handler},
+ {"move_val_init", move_val_init_handler},
+ {"likely", expect_handler (true)},
+ {"unlikely", expect_handler (false)},
+ {"assume", assume_handler},
+ {"try", try_handler (false)},
+ {"catch_unwind", try_handler (true)},
+ {"discriminant_value", discriminant_value_handler},
+ {"variant_count", variant_count_handler}};
Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
@@ -315,11 +329,11 @@ compile_fn_params (Context *ctx, TyTy::FnType *fntype, tree fndecl,
{
for (auto &parm : fntype->get_params ())
{
- auto &referenced_param = parm.first;
- auto &param_tyty = parm.second;
+ auto &referenced_param = parm.get_pattern ();
+ auto param_tyty = parm.get_type ();
auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
- location_t param_locus = referenced_param->get_locus ();
+ location_t param_locus = referenced_param.get_locus ();
Bvariable *compiled_param_var
= CompileFnParam::compile (ctx, fndecl, referenced_param,
compiled_param_type, param_locus);
@@ -496,9 +510,10 @@ transmute_handler (Context *ctx, TyTy::FnType *fntype)
rust_error_at (fntype->get_locus (),
"cannot transmute between types of different sizes, or "
"dependently-sized types");
- rust_inform (fntype->get_ident ().locus, "source type: %qs (%lu bits)",
- fntype->get_params ().at (0).second->as_string ().c_str (),
- (unsigned long) source_size);
+ rust_inform (
+ fntype->get_ident ().locus, "source type: %qs (%lu bits)",
+ fntype->get_params ().at (0).get_type ()->as_string ().c_str (),
+ (unsigned long) source_size);
rust_inform (fntype->get_ident ().locus, "target type: %qs (%lu bits)",
fntype->get_return_type ()->as_string ().c_str (),
(unsigned long) target_size);
@@ -1226,7 +1241,7 @@ assume_handler (Context *ctx, TyTy::FnType *fntype)
// TODO: make sure this is actually helping the compiler optimize
rust_assert (fntype->get_params ().size () == 1);
- rust_assert (fntype->param_at (0).second->get_kind ()
+ rust_assert (fntype->param_at (0).get_type ()->get_kind ()
== TyTy::TypeKind::BOOL);
tree lookup = NULL_TREE;
@@ -1258,7 +1273,217 @@ assume_handler (Context *ctx, TyTy::FnType *fntype)
TREE_SIDE_EFFECTS (assume_expr) = 1;
ctx->add_statement (assume_expr);
- // BUILTIN size_of FN BODY END
+ // BUILTIN assume FN BODY END
+
+ finalize_intrinsic_block (ctx, fndecl);
+
+ return fndecl;
+}
+
+static tree
+try_handler_inner (Context *ctx, TyTy::FnType *fntype, bool is_new_api)
+{
+ rust_assert (fntype->get_params ().size () == 3);
+
+ tree lookup = NULL_TREE;
+ if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+ return lookup;
+ auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+ enter_intrinsic_block (ctx, fndecl);
+
+ // The following tricks are needed to make sure the try-catch blocks are not
+ // optimized away
+ TREE_READONLY (fndecl) = 0;
+ DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;
+ DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("always_inline"),
+ NULL_TREE, DECL_ATTRIBUTES (fndecl));
+
+ // BUILTIN try_handler FN BODY BEGIN
+ // setup the params
+ std::vector<Bvariable *> param_vars;
+ compile_fn_params (ctx, fntype, fndecl, &param_vars);
+ if (!Backend::function_set_parameters (fndecl, param_vars))
+ return error_mark_node;
+ tree enclosing_scope = NULL_TREE;
+
+ bool panic_is_abort = Session::get_instance ().options.get_panic_strategy ()
+ == CompileOptions::PanicStrategy::Abort;
+ tree try_fn = Backend::var_expression (param_vars[0], UNDEF_LOCATION);
+ tree user_data = Backend::var_expression (param_vars[1], UNDEF_LOCATION);
+ tree catch_fn = Backend::var_expression (param_vars[2], UNDEF_LOCATION);
+ tree normal_return_stmt = NULL_TREE;
+ tree error_return_stmt = NULL_TREE;
+ tree try_call = Backend::call_expression (try_fn, {user_data}, nullptr,
+ BUILTINS_LOCATION);
+ tree catch_call = NULL_TREE;
+ tree try_block = Backend::block (fndecl, enclosing_scope, {}, UNDEF_LOCATION,
+ UNDEF_LOCATION);
+
+ if (is_new_api)
+ {
+ auto ret_type = TyTyResolveCompile::get_unit_type (ctx);
+ auto ret_expr = Backend::constructor_expression (ret_type, false, {}, -1,
+ UNDEF_LOCATION);
+ normal_return_stmt
+ = Backend::return_statement (fndecl, ret_expr, BUILTINS_LOCATION);
+ error_return_stmt
+ = Backend::return_statement (fndecl, ret_expr, BUILTINS_LOCATION);
+ }
+ else
+ {
+ normal_return_stmt = Backend::return_statement (fndecl, integer_zero_node,
+ BUILTINS_LOCATION);
+ error_return_stmt = Backend::return_statement (fndecl, integer_one_node,
+ BUILTINS_LOCATION);
+ }
+ Backend::block_add_statements (try_block,
+ std::vector<tree>{try_call,
+ normal_return_stmt});
+ if (panic_is_abort)
+ {
+ // skip building the try-catch construct
+ ctx->add_statement (try_block);
+ finalize_intrinsic_block (ctx, fndecl);
+ return fndecl;
+ }
+
+ tree eh_pointer
+ = build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER), 1,
+ integer_zero_node);
+ catch_call = Backend::call_expression (catch_fn, {user_data, eh_pointer},
+ NULL_TREE, BUILTINS_LOCATION);
+
+ tree catch_block = Backend::block (fndecl, enclosing_scope, {},
+ UNDEF_LOCATION, UNDEF_LOCATION);
+ Backend::block_add_statements (catch_block,
+ std::vector<tree>{catch_call,
+ error_return_stmt});
+ // emulate what cc1plus is doing for C++ try-catch
+ tree inner_eh_construct
+ = Backend::exception_handler_statement (catch_call, NULL_TREE,
+ error_return_stmt,
+ BUILTINS_LOCATION);
+ // TODO(liushuyu): eh_personality needs to be implemented as a runtime thing
+ auto eh_construct
+ = Backend::exception_handler_statement (try_block, inner_eh_construct,
+ NULL_TREE, BUILTINS_LOCATION);
+ ctx->add_statement (eh_construct);
+ // BUILTIN try_handler FN BODY END
+ finalize_intrinsic_block (ctx, fndecl);
+
+ return fndecl;
+}
+
+static tree
+discriminant_value_handler (Context *ctx, TyTy::FnType *fntype)
+{
+ rust_assert (fntype->get_params ().size () == 1);
+ rust_assert (fntype->get_return_type ()->is<TyTy::PlaceholderType> ());
+ rust_assert (fntype->has_substitutions ());
+ rust_assert (fntype->get_num_type_params () == 1);
+ auto &mapping = fntype->get_substs ().at (0);
+ auto param_ty = mapping.get_param_ty ();
+ rust_assert (param_ty->can_resolve ());
+ auto resolved = param_ty->resolve ();
+ auto p = static_cast<TyTy::PlaceholderType *> (fntype->get_return_type ());
+
+ TyTy::BaseType *return_type = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_builtin ("isize", &return_type);
+ rust_assert (ok);
+
+ bool is_adt = resolved->is<TyTy::ADTType> ();
+ bool is_enum = false;
+ if (is_adt)
+ {
+ const auto &adt = *static_cast<TyTy::ADTType *> (resolved);
+ return_type = adt.get_repr_options ().repr;
+ rust_assert (return_type != nullptr);
+ is_enum = adt.is_enum ();
+ }
+
+ p->set_associated_type (return_type->get_ref ());
+
+ tree lookup = NULL_TREE;
+ if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+ return lookup;
+
+ auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+ std::vector<Bvariable *> param_vars;
+ compile_fn_params (ctx, fntype, fndecl, &param_vars);
+
+ if (!Backend::function_set_parameters (fndecl, param_vars))
+ return error_mark_node;
+
+ enter_intrinsic_block (ctx, fndecl);
+
+ // BUILTIN disriminant_value FN BODY BEGIN
+
+ tree result = integer_zero_node;
+ if (is_enum)
+ {
+ tree val = Backend::var_expression (param_vars[0], UNDEF_LOCATION);
+ tree deref = build_fold_indirect_ref_loc (UNKNOWN_LOCATION, val);
+ result = Backend::struct_field_expression (deref, 0, UNKNOWN_LOCATION);
+ }
+
+ auto return_statement
+ = Backend::return_statement (fndecl, result, BUILTINS_LOCATION);
+ ctx->add_statement (return_statement);
+
+ // BUILTIN disriminant_value FN BODY END
+
+ finalize_intrinsic_block (ctx, fndecl);
+
+ return fndecl;
+}
+
+static tree
+variant_count_handler (Context *ctx, TyTy::FnType *fntype)
+{
+ rust_assert (fntype->get_num_type_params () == 1);
+ auto &mapping = fntype->get_substs ().at (0);
+ auto param_ty = mapping.get_param_ty ();
+ rust_assert (param_ty->can_resolve ());
+ auto resolved = param_ty->resolve ();
+
+ size_t variant_count = 0;
+ bool is_adt = resolved->is<TyTy::ADTType> ();
+ if (is_adt)
+ {
+ const auto &adt = *static_cast<TyTy::ADTType *> (resolved);
+ variant_count = adt.number_of_variants ();
+ }
+
+ tree lookup = NULL_TREE;
+ if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+ return lookup;
+
+ auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+ std::vector<Bvariable *> param_vars;
+ compile_fn_params (ctx, fntype, fndecl, &param_vars);
+
+ if (!Backend::function_set_parameters (fndecl, param_vars))
+ return error_mark_node;
+
+ enter_intrinsic_block (ctx, fndecl);
+
+ // BUILTIN disriminant_value FN BODY BEGIN
+ tree result_decl = DECL_RESULT (fndecl);
+ tree type = TREE_TYPE (result_decl);
+
+ mpz_t ival;
+ mpz_init_set_ui (ival, variant_count);
+ tree result = wide_int_to_tree (type, wi::from_mpz (type, ival, true));
+ mpz_clear (ival);
+
+ auto return_statement
+ = Backend::return_statement (fndecl, result, BUILTINS_LOCATION);
+ ctx->add_statement (return_statement);
+
+ // BUILTIN disriminant_value FN BODY END
finalize_intrinsic_block (ctx, fndecl);
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index 0878716..9666990 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -19,6 +19,8 @@
#include "rust-compile-item.h"
#include "rust-compile-implitem.h"
#include "rust-compile-extern.h"
+#include "rust-substitution-mapper.h"
+#include "rust-type-util.h"
#include "rust-immutable-name-resolution-context.h"
namespace Rust {
@@ -35,10 +37,16 @@ CompileItem::visit (HIR::StaticItem &var)
return;
}
+ HIR::Expr &const_value_expr = var.get_expr ();
+
TyTy::BaseType *resolved_type = nullptr;
+ TyTy::BaseType *expr_type = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (),
&resolved_type);
rust_assert (ok);
+ ok = ctx->get_tyctx ()->lookup_type (
+ const_value_expr.get_mappings ().get_hirid (), &expr_type);
+ rust_assert (ok);
tree type = TyTyResolveCompile::compile (ctx, resolved_type);
@@ -46,7 +54,7 @@ CompileItem::visit (HIR::StaticItem &var)
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
@@ -60,10 +68,11 @@ CompileItem::visit (HIR::StaticItem &var)
rust_assert (canonical_path.has_value ());
- HIR::Expr *const_value_expr = var.get_expr ().get ();
ctx->push_const_context ();
- tree value = compile_constant_item (resolved_type, *canonical_path,
- const_value_expr, var.get_locus ());
+ tree value
+ = compile_constant_item (var.get_mappings ().get_hirid (), expr_type,
+ resolved_type, *canonical_path, const_value_expr,
+ var.get_locus (), const_value_expr.get_locus ());
ctx->pop_const_context ();
std::string name = canonical_path->get ();
@@ -89,16 +98,21 @@ CompileItem::visit (HIR::StaticItem &var)
void
CompileItem::visit (HIR::ConstantItem &constant)
{
+ HIR::Expr &const_value_expr = constant.get_expr ();
auto &mappings = constant.get_mappings ();
if (ctx->lookup_const_decl (mappings.get_hirid (), &reference))
return;
// resolve the type
- TyTy::BaseType *resolved_type = nullptr;
+ TyTy::BaseType *constant_type = nullptr;
+ TyTy::BaseType *expr_type = nullptr;
bool ok
- = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &resolved_type);
+ = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &constant_type);
+ rust_assert (ok);
+ ok = ctx->get_tyctx ()->lookup_type (
+ const_value_expr.get_mappings ().get_hirid (), &expr_type);
rust_assert (ok);
// canonical path
@@ -107,7 +121,7 @@ CompileItem::visit (HIR::ConstantItem &constant)
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
@@ -120,11 +134,12 @@ CompileItem::visit (HIR::ConstantItem &constant)
.value ();
}
- HIR::Expr *const_value_expr = constant.get_expr ().get ();
ctx->push_const_context ();
tree const_expr
- = compile_constant_item (resolved_type, canonical_path, const_value_expr,
- constant.get_locus ());
+ = compile_constant_item (mappings.get_hirid (), expr_type, constant_type,
+ canonical_path, const_value_expr,
+ constant.get_locus (),
+ const_value_expr.get_locus ());
ctx->pop_const_context ();
ctx->push_const (const_expr);
@@ -152,12 +167,33 @@ CompileItem::visit (HIR::Function &function)
// is given
if (concrete == nullptr)
return;
- else
+
+ rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
+ bool is_trait_item_concrete
+ = ctx->get_mappings ()
+ .lookup_trait_item_defid (concrete_fnty->get_id ())
+ .has_value ();
+ if (!is_trait_item_concrete)
{
rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
fntype = static_cast<TyTy::FnType *> (concrete);
- fntype->monomorphize ();
}
+ else
+ {
+ TyTy::BaseType *infer
+ = Resolver::SubstMapper::InferSubst (fntype, function.get_locus ());
+ TyTy::BaseType *resolved
+ = Resolver::unify_site (function.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (infer),
+ TyTy::TyWithLocation (concrete),
+ function.get_locus ());
+
+ rust_assert (resolved->is<TyTy::FnType> ());
+ fntype = resolved->as<TyTy::FnType> ();
+ }
+
+ fntype->monomorphize ();
}
else
{
@@ -179,7 +215,7 @@ CompileItem::visit (HIR::Function &function)
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
auto path = nr_ctx.values.to_canonical_path (
@@ -216,14 +252,17 @@ CompileItem::visit (HIR::Function &function)
if (function.get_qualifiers ().is_const ())
ctx->push_const_context ();
+ auto lookup_root_item = ctx->get_mappings ().lookup_hir_item (
+ function.get_mappings ().get_hirid ());
+ bool is_root_item = lookup_root_item.has_value ();
tree fndecl
- = compile_function (function.get_function_name ().as_string (),
+ = compile_function (is_root_item,
+ function.get_function_name ().as_string (),
function.get_self_param (),
function.get_function_params (),
function.get_qualifiers (), function.get_visibility (),
function.get_outer_attrs (), function.get_locus (),
- function.get_definition ().get (), canonical_path,
- fntype);
+ &function.get_definition (), canonical_path, fntype);
reference = address_expression (fndecl, ref_locus);
if (function.get_qualifiers ().is_const ())
@@ -235,7 +274,7 @@ CompileItem::visit (HIR::ImplBlock &impl_block)
{
TyTy::BaseType *self_lookup = nullptr;
if (!ctx->get_tyctx ()->lookup_type (
- impl_block.get_type ()->get_mappings ().get_hirid (), &self_lookup))
+ impl_block.get_type ().get_mappings ().get_hirid (), &self_lookup))
{
rust_error_at (impl_block.get_locus (), "failed to resolve type of impl");
return;
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index efc65fe..d9d946d 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -31,16 +31,10 @@ protected:
public:
static tree compile (HIR::Item *item, Context *ctx,
TyTy::BaseType *concrete = nullptr,
- bool is_query_mode = false,
location_t ref_locus = UNDEF_LOCATION)
{
CompileItem compiler (ctx, concrete, ref_locus);
item->accept_vis (compiler);
-
- if (is_query_mode && compiler.reference == error_mark_node)
- rust_internal_error_at (ref_locus, "failed to compile item: %s",
- item->as_string ().c_str ());
-
return compiler.reference;
}
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index ffa1fa7..e83717b 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -21,6 +21,7 @@
#include "rust-compile-resolve-path.h"
#include "rust-constexpr.h"
#include "rust-compile-type.h"
+#include "print-tree.h"
namespace Rust {
namespace Compile {
@@ -57,17 +58,14 @@ CompilePatternCheckExpr::visit (HIR::PathInExpression &pattern)
rust_assert (ok);
// find discriminant field of scrutinee
- tree scrutinee_record_expr
- = Backend::struct_field_expression (match_scrutinee_expr, 0,
- pattern.get_locus ());
tree scrutinee_expr_qualifier_expr
- = Backend::struct_field_expression (scrutinee_record_expr, 0,
+ = Backend::struct_field_expression (match_scrutinee_expr, 0,
pattern.get_locus ());
// must be enum
match_scrutinee_expr = scrutinee_expr_qualifier_expr;
- HIR::Expr *discrim_expr = variant->get_discriminant ();
+ HIR::Expr &discrim_expr = variant->get_discriminant ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
check_expr
@@ -80,10 +78,9 @@ void
CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
{
// Compile the literal
- HIR::LiteralExpr *litexpr
- = new HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (),
- pattern.get_locus (),
- std::vector<AST::Attribute> ());
+ auto litexpr = std::make_unique<HIR::LiteralExpr> (
+ HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (),
+ pattern.get_locus (), std::vector<AST::Attribute> ()));
// Note: Floating point literals are currently accepted but will likely be
// forbidden in LiteralPatterns in a future version of Rust.
@@ -95,7 +92,7 @@ CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
rust_sorry_at (pattern.get_locus (), "floating-point literal in pattern");
}
- tree lit = CompileExpr::Compile (litexpr, ctx);
+ tree lit = CompileExpr::Compile (*litexpr, ctx);
check_expr = Backend::comparison_expression (ComparisonOperator::EQUAL,
match_scrutinee_expr, lit,
@@ -103,19 +100,17 @@ CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
}
static tree
-compile_range_pattern_bound (HIR::RangePatternBound *bound,
+compile_range_pattern_bound (HIR::RangePatternBound &bound,
Analysis::NodeMapping mappings, location_t locus,
Context *ctx)
{
tree result = NULL_TREE;
- switch (bound->get_bound_type ())
+ switch (bound.get_bound_type ())
{
case HIR::RangePatternBound::RangePatternBoundType::LITERAL: {
- HIR::RangePatternBoundLiteral &ref
- = *static_cast<HIR::RangePatternBoundLiteral *> (bound);
+ auto &ref = static_cast<HIR::RangePatternBoundLiteral &> (bound);
- HIR::LiteralExpr *litexpr
- = new HIR::LiteralExpr (mappings, ref.get_literal (), locus,
+ HIR::LiteralExpr litexpr (mappings, ref.get_literal (), locus,
std::vector<AST::Attribute> ());
result = CompileExpr::Compile (litexpr, ctx);
@@ -123,8 +118,7 @@ compile_range_pattern_bound (HIR::RangePatternBound *bound,
break;
case HIR::RangePatternBound::RangePatternBoundType::PATH: {
- HIR::RangePatternBoundPath &ref
- = *static_cast<HIR::RangePatternBoundPath *> (bound);
+ auto &ref = static_cast<HIR::RangePatternBoundPath &> (bound);
result = ResolvePathRef::Compile (ref.get_path (), ctx);
@@ -134,8 +128,7 @@ compile_range_pattern_bound (HIR::RangePatternBound *bound,
break;
case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: {
- HIR::RangePatternBoundQualPath &ref
- = *static_cast<HIR::RangePatternBoundQualPath *> (bound);
+ auto &ref = static_cast<HIR::RangePatternBoundQualPath &> (bound);
result = ResolvePathRef::Compile (ref.get_qualified_path (), ctx);
@@ -150,10 +143,10 @@ compile_range_pattern_bound (HIR::RangePatternBound *bound,
void
CompilePatternCheckExpr::visit (HIR::RangePattern &pattern)
{
- tree upper = compile_range_pattern_bound (pattern.get_upper_bound ().get (),
+ tree upper = compile_range_pattern_bound (pattern.get_upper_bound (),
pattern.get_mappings (),
pattern.get_locus (), ctx);
- tree lower = compile_range_pattern_bound (pattern.get_lower_bound ().get (),
+ tree lower = compile_range_pattern_bound (pattern.get_lower_bound (),
pattern.get_mappings (),
pattern.get_locus (), ctx);
@@ -175,7 +168,7 @@ CompilePatternCheckExpr::visit (HIR::ReferencePattern &pattern)
{
match_scrutinee_expr
= indirect_expression (match_scrutinee_expr, pattern.get_locus ());
- pattern.get_referenced_pattern ()->accept_vis (*this);
+ pattern.get_referenced_pattern ().accept_vis (*this);
}
void
@@ -183,14 +176,13 @@ CompilePatternCheckExpr::visit (HIR::AltPattern &pattern)
{
auto &alts = pattern.get_alts ();
- check_expr = CompilePatternCheckExpr::Compile (alts.at (0).get (),
+ check_expr = CompilePatternCheckExpr::Compile (*alts.at (0),
match_scrutinee_expr, ctx);
auto end = alts.end ();
for (auto i = alts.begin () + 1; i != end; i++)
{
tree next_expr
- = CompilePatternCheckExpr::Compile (i->get (), match_scrutinee_expr,
- ctx);
+ = CompilePatternCheckExpr::Compile (**i, match_scrutinee_expr, ctx);
check_expr = Backend::arithmetic_or_logical_expression (
ArithmeticOrLogicalOperator::BITWISE_OR, check_expr, next_expr,
(*i)->get_locus ());
@@ -229,15 +221,12 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
// // 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
- HIR::Expr *discrim_expr = variant->get_discriminant ();
+ HIR::Expr &discrim_expr = variant->get_discriminant ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
// find discriminant field of scrutinee
- tree scrutinee_record_expr
- = Backend::struct_field_expression (match_scrutinee_expr, variant_index,
- pattern.get_path ().get_locus ());
tree scrutinee_expr_qualifier_expr
- = Backend::struct_field_expression (scrutinee_record_expr, 0,
+ = Backend::struct_field_expression (match_scrutinee_expr, 0,
pattern.get_path ().get_locus ());
check_expr
@@ -246,7 +235,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
discrim_expr_node,
pattern.get_path ().get_locus ());
- match_scrutinee_expr = scrutinee_record_expr;
+ match_scrutinee_expr = scrutinee_expr_qualifier_expr;
}
else
{
@@ -282,11 +271,11 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
ident.get_locus ());
tree check_expr_sub
- = CompilePatternCheckExpr::Compile (ident.get_pattern ().get (),
+ = CompilePatternCheckExpr::Compile (ident.get_pattern (),
field_expr, ctx);
check_expr = Backend::arithmetic_or_logical_expression (
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
- check_expr_sub, ident.get_pattern ()->get_locus ());
+ check_expr_sub, ident.get_pattern ().get_locus ());
}
break;
@@ -301,8 +290,6 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
void
CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
{
- size_t tuple_field_index;
-
// lookup the type
TyTy::BaseType *lookup = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
@@ -313,6 +300,7 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
rust_assert (lookup->get_kind () == TyTy::TypeKind::ADT);
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (lookup);
+ int variant_index = 0;
rust_assert (adt->number_of_variants () > 0);
TyTy::VariantDef *variant = nullptr;
if (adt->is_enum ())
@@ -323,20 +311,16 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
rust_assert (ok);
- int variant_index = 0;
ok = adt->lookup_variant_by_id (variant_id, &variant, &variant_index);
rust_assert (ok);
// find expected discriminant
- HIR::Expr *discrim_expr = variant->get_discriminant ();
+ HIR::Expr &discrim_expr = variant->get_discriminant ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
// find discriminant field of scrutinee
- tree scrutinee_record_expr
- = Backend::struct_field_expression (match_scrutinee_expr, variant_index,
- pattern.get_path ().get_locus ());
tree scrutinee_expr_qualifier_expr
- = Backend::struct_field_expression (scrutinee_record_expr, 0,
+ = Backend::struct_field_expression (match_scrutinee_expr, 0,
pattern.get_path ().get_locus ());
check_expr
@@ -344,21 +328,15 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
scrutinee_expr_qualifier_expr,
discrim_expr_node,
pattern.get_path ().get_locus ());
-
- match_scrutinee_expr = scrutinee_record_expr;
- // we are offsetting by + 1 here since the first field in the record
- // is always the discriminator
- tuple_field_index = 1;
}
else
{
variant = adt->get_variants ().at (0);
check_expr = boolean_true_node;
- tuple_field_index = 0;
}
- std::unique_ptr<HIR::TupleStructItems> &items = pattern.get_items ();
- switch (items->get_item_type ())
+ HIR::TupleStructItems &items = pattern.get_items ();
+ switch (items.get_item_type ())
{
case HIR::TupleStructItems::RANGED: {
// TODO
@@ -368,21 +346,30 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
case HIR::TupleStructItems::MULTIPLE: {
HIR::TupleStructItemsNoRange &items_no_range
- = static_cast<HIR::TupleStructItemsNoRange &> (*items.get ());
+ = static_cast<HIR::TupleStructItemsNoRange &> (items);
rust_assert (items_no_range.get_patterns ().size ()
== variant->num_fields ());
+ size_t tuple_field_index = 0;
for (auto &pattern : items_no_range.get_patterns ())
{
+ // find payload union field of scrutinee
+ tree payload_ref
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pattern->get_locus ());
+
+ tree variant_ref
+ = Backend::struct_field_expression (payload_ref, variant_index,
+ pattern->get_locus ());
+
tree field_expr
- = Backend::struct_field_expression (match_scrutinee_expr,
+ = Backend::struct_field_expression (variant_ref,
tuple_field_index++,
pattern->get_locus ());
tree check_expr_sub
- = CompilePatternCheckExpr::Compile (pattern.get (), field_expr,
- ctx);
+ = CompilePatternCheckExpr::Compile (*pattern, field_expr, ctx);
check_expr = Backend::arithmetic_or_logical_expression (
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
check_expr_sub, pattern->get_locus ());
@@ -397,7 +384,7 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
{
check_expr = boolean_true_node;
- switch (pattern.get_items ()->get_item_type ())
+ switch (pattern.get_items ().get_item_type ())
{
case HIR::TuplePatternItems::RANGED: {
// TODO
@@ -407,7 +394,7 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
case HIR::TuplePatternItems::MULTIPLE: {
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- *pattern.get_items ());
+ pattern.get_items ());
size_t tuple_field_index = 0;
for (auto &pat : items.get_patterns ())
@@ -418,7 +405,7 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
pat->get_locus ());
tree check_expr_sub
- = CompilePatternCheckExpr::Compile (pat.get (), field_expr, ctx);
+ = CompilePatternCheckExpr::Compile (*pat, field_expr, ctx);
check_expr = Backend::arithmetic_or_logical_expression (
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
check_expr_sub, pat->get_locus ());
@@ -459,8 +446,8 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
rust_assert (variant->get_variant_type ()
== TyTy::VariantDef::VariantType::TUPLE);
- std::unique_ptr<HIR::TupleStructItems> &items = pattern.get_items ();
- switch (items->get_item_type ())
+ HIR::TupleStructItems &items = pattern.get_items ();
+ switch (items.get_item_type ())
{
case HIR::TupleStructItems::RANGED: {
// TODO
@@ -470,20 +457,22 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
case HIR::TupleStructItems::MULTIPLE: {
HIR::TupleStructItemsNoRange &items_no_range
- = static_cast<HIR::TupleStructItemsNoRange &> (*items.get ());
+ = static_cast<HIR::TupleStructItemsNoRange &> (items);
rust_assert (items_no_range.get_patterns ().size ()
== variant->num_fields ());
if (adt->is_enum ())
{
- // we are offsetting by + 1 here since the first field in the record
- // is always the discriminator
- size_t tuple_field_index = 1;
+ size_t tuple_field_index = 0;
for (auto &pattern : items_no_range.get_patterns ())
{
+ tree payload_accessor_union
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pattern->get_locus ());
+
tree variant_accessor
- = Backend::struct_field_expression (match_scrutinee_expr,
+ = Backend::struct_field_expression (payload_accessor_union,
variant_index,
pattern->get_locus ());
@@ -492,8 +481,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
tuple_field_index++,
pattern->get_locus ());
- ctx->insert_pattern_binding (
- pattern->get_mappings ().get_hirid (), binding);
+ CompilePatternBindings::Compile (*pattern, binding, ctx);
}
}
else
@@ -508,8 +496,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
tuple_field_index++,
pattern->get_locus ());
- ctx->insert_pattern_binding (
- pattern->get_mappings ().get_hirid (), binding);
+ CompilePatternBindings::Compile (*pattern, binding, ctx);
}
}
}
@@ -576,16 +563,18 @@ CompilePatternBindings::visit (HIR::StructPattern &pattern)
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 (match_scrutinee_expr,
+ = Backend::struct_field_expression (payload_accessor_union,
variant_index,
ident.get_locus ());
- // we are offsetting by + 1 here since the first field in the
- // record is always the discriminator
- binding = Backend::struct_field_expression (variant_accessor,
- offs + 1,
- ident.get_locus ());
+ binding
+ = Backend::struct_field_expression (variant_accessor, offs,
+ ident.get_locus ());
}
else
{
@@ -609,17 +598,111 @@ CompilePatternBindings::visit (HIR::ReferencePattern &pattern)
tree derefed
= indirect_expression (match_scrutinee_expr, pattern.get_locus ());
- CompilePatternBindings::Compile (pattern.get_referenced_pattern ().get (),
- derefed, ctx);
+ CompilePatternBindings::Compile (pattern.get_referenced_pattern (), derefed,
+ ctx);
}
void
CompilePatternBindings::visit (HIR::IdentifierPattern &pattern)
{
- ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (),
- match_scrutinee_expr);
+ if (!pattern.get_is_ref ())
+ {
+ ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (),
+ match_scrutinee_expr);
+ return;
+ }
+
+ tree ref = address_expression (match_scrutinee_expr,
+ EXPR_LOCATION (match_scrutinee_expr));
+ ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (), ref);
+}
+
+void
+CompilePatternBindings::visit (HIR::TuplePattern &pattern)
+{
+ rust_assert (pattern.has_tuple_pattern_items ());
+
+ // lookup the type
+ TyTy::BaseType *ty = nullptr;
+ bool ok
+ = ctx->get_tyctx ()->lookup_type (pattern.get_mappings ().get_hirid (),
+ &ty);
+ rust_assert (ok);
+
+ switch (pattern.get_items ().get_item_type ())
+ {
+ case HIR::TuplePatternItems::ItemType::RANGED: {
+ size_t tuple_idx = 0;
+ auto &items
+ = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+
+ auto &items_lower = items.get_lower_patterns ();
+ auto &items_upper = items.get_upper_patterns ();
+
+ for (auto &sub : items_lower)
+ {
+ TyTy::BaseType *ty_sub = nullptr;
+ HirId sub_id = sub->get_mappings ().get_hirid ();
+ bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
+ rust_assert (ok);
+
+ tree sub_init
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_idx, sub->get_locus ());
+
+ CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
+ tuple_idx++;
+ }
+
+ rust_assert (ty->get_kind () == TyTy::TypeKind::TUPLE);
+ tuple_idx = static_cast<TyTy::TupleType &> (*ty).num_fields ()
+ - items_upper.size ();
+
+ for (auto &sub : items_upper)
+ {
+ TyTy::BaseType *ty_sub = nullptr;
+ HirId sub_id = sub->get_mappings ().get_hirid ();
+ bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
+ rust_assert (ok);
+
+ tree sub_init
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_idx, sub->get_locus ());
+ CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
+ tuple_idx++;
+ }
+
+ return;
+ }
+ case HIR::TuplePatternItems::ItemType::MULTIPLE: {
+ size_t tuple_idx = 0;
+ auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
+ pattern.get_items ());
+
+ for (auto &sub : items.get_patterns ())
+ {
+ TyTy::BaseType *ty_sub = nullptr;
+ HirId sub_id = sub->get_mappings ().get_hirid ();
+ bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
+ rust_assert (ok);
+
+ tree sub_init
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_idx, sub->get_locus ());
+ CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
+ tuple_idx++;
+ }
+
+ return;
+ }
+ default: {
+ rust_unreachable ();
+ }
+ }
}
+//
+
void
CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
{
@@ -670,12 +753,12 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
tree access_expr = Backend::var_expression (tmp_var, pattern.get_locus ());
ctx->add_statement (init_stmt);
- switch (pattern.get_items ()->get_item_type ())
+ switch (pattern.get_items ().get_item_type ())
{
case HIR::TuplePatternItems::ItemType::RANGED: {
size_t tuple_idx = 0;
auto &items
- = static_cast<HIR::TuplePatternItemsRanged &> (*pattern.get_items ());
+ = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
auto &items_lower = items.get_lower_patterns ();
auto &items_upper = items.get_upper_patterns ();
@@ -719,7 +802,7 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
case HIR::TuplePatternItems::ItemType::MULTIPLE: {
size_t tuple_idx = 0;
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- *pattern.get_items ());
+ pattern.get_items ());
for (auto &sub : items.get_patterns ())
{
diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h
index 521ed0d..c7a62fc 100644
--- a/gcc/rust/backend/rust-compile-pattern.h
+++ b/gcc/rust/backend/rust-compile-pattern.h
@@ -26,11 +26,11 @@ class CompilePatternCheckExpr : public HIRCompileBase,
public HIR::HIRPatternVisitor
{
public:
- static tree Compile (HIR::Pattern *pattern, tree match_scrutinee_expr,
+ static tree Compile (HIR::Pattern &pattern, tree match_scrutinee_expr,
Context *ctx)
{
CompilePatternCheckExpr compiler (ctx, match_scrutinee_expr);
- pattern->accept_vis (compiler);
+ pattern.accept_vis (compiler);
rust_assert (compiler.check_expr);
return compiler.check_expr;
}
@@ -71,17 +71,18 @@ class CompilePatternBindings : public HIRCompileBase,
public HIR::HIRPatternVisitor
{
public:
- static void Compile (HIR::Pattern *pattern, tree match_scrutinee_expr,
+ static void Compile (HIR::Pattern &pattern, tree match_scrutinee_expr,
Context *ctx)
{
CompilePatternBindings compiler (ctx, match_scrutinee_expr);
- pattern->accept_vis (compiler);
+ pattern.accept_vis (compiler);
}
void visit (HIR::StructPattern &pattern) override;
void visit (HIR::TupleStructPattern &pattern) override;
void visit (HIR::ReferencePattern &pattern) override;
void visit (HIR::IdentifierPattern &) override;
+ void visit (HIR::TuplePattern &pattern) override;
// Empty visit for unused Pattern HIR nodes.
void visit (HIR::AltPattern &) override {}
@@ -90,7 +91,6 @@ public:
void visit (HIR::QualifiedPathInExpression &) override {}
void visit (HIR::RangePattern &) override {}
void visit (HIR::SlicePattern &) override {}
- void visit (HIR::TuplePattern &) override {}
void visit (HIR::WildcardPattern &) override {}
protected:
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 7c9b303..81d2dbb 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -32,18 +32,41 @@
namespace Rust {
namespace Compile {
-void
-ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr)
+tree
+ResolvePathRef::Compile (HIR::QualifiedPathInExpression &expr, Context *ctx)
{
- resolved = resolve (expr.get_final_segment ().get_segment (),
- expr.get_mappings (), expr.get_locus (), true);
+ ResolvePathRef resolver (ctx);
+ return resolver.resolve_path_like (expr);
}
-void
-ResolvePathRef::visit (HIR::PathInExpression &expr)
+tree
+ResolvePathRef::Compile (HIR::PathInExpression &expr, Context *ctx)
{
- resolved = resolve (expr.get_final_segment ().get_segment (),
- expr.get_mappings (), expr.get_locus (), false);
+ ResolvePathRef resolver (ctx);
+ return resolver.resolve_path_like (expr);
+}
+
+ResolvePathRef::ResolvePathRef (Context *ctx) : HIRCompileBase (ctx) {}
+
+template <typename T>
+tree
+ResolvePathRef::resolve_path_like (T &expr)
+{
+ if (expr.is_lang_item ())
+ {
+ auto lang_item
+ = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
+
+ // FIXME: Is that correct? :/
+ auto final_segment
+ = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ()));
+
+ return resolve_with_node_id (final_segment, expr.get_mappings (),
+ expr.get_locus (), true, lang_item);
+ }
+
+ return resolve (expr.get_final_segment ().get_segment (),
+ expr.get_mappings (), expr.get_locus (), true);
}
tree
@@ -81,52 +104,30 @@ ResolvePathRef::attempt_constructor_expression_lookup (
tree compiled_adt_type = TyTyResolveCompile::compile (ctx, adt);
// make the ctor for the union
- HIR::Expr *discrim_expr = variant->get_discriminant ();
+ HIR::Expr &discrim_expr = variant->get_discriminant ();
+ ctx->push_const_context ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
+ ctx->pop_const_context ();
tree folded_discrim_expr = fold_expr (discrim_expr_node);
tree qualifier = folded_discrim_expr;
- return Backend::constructor_expression (compiled_adt_type, true, {qualifier},
- union_disriminator, expr_locus);
+ // false for is enum but this is an enum but we have a new layout
+ return Backend::constructor_expression (compiled_adt_type, false, {qualifier},
+ -1, expr_locus);
}
tree
-ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
- const Analysis::NodeMapping &mappings,
- location_t expr_locus, bool is_qualified_path)
+ResolvePathRef::resolve_with_node_id (
+ const HIR::PathIdentSegment &final_segment,
+ const Analysis::NodeMapping &mappings, location_t expr_locus,
+ bool is_qualified_path, NodeId resolved_node_id)
{
TyTy::BaseType *lookup = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &lookup);
rust_assert (ok);
- // need to look up the reference for this identifier
-
- // this can fail because it might be a Constructor for something
- // in that case the caller should attempt ResolvePathType::Compile
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (flag_name_resolution_2_0)
- {
- auto nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
-
- auto resolved = nr_ctx.lookup (mappings.get_nodeid ());
-
- if (!resolved)
- return attempt_constructor_expression_lookup (lookup, ctx, mappings,
- expr_locus);
-
- ref_node_id = *resolved;
- }
- else
- {
- if (!ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (),
- &ref_node_id))
- return attempt_constructor_expression_lookup (lookup, ctx, mappings,
- expr_locus);
- }
-
tl::optional<HirId> hid
- = ctx->get_mappings ().lookup_node_to_hir (ref_node_id);
+ = ctx->get_mappings ().lookup_node_to_hir (resolved_node_id);
if (!hid.has_value ())
{
rust_error_at (expr_locus, "reverse call path lookup failure");
@@ -185,6 +186,11 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
}
}
+ // Handle unit struct
+ if (lookup->get_kind () == TyTy::TypeKind::ADT)
+ return attempt_constructor_expression_lookup (lookup, ctx, mappings,
+ expr_locus);
+
// let the query system figure it out
tree resolved_item = query_compile (ref, lookup, final_segment, mappings,
expr_locus, is_qualified_path);
@@ -192,10 +198,50 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
{
TREE_USED (resolved_item) = 1;
}
+
return resolved_item;
}
tree
+ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
+ const Analysis::NodeMapping &mappings,
+ location_t expr_locus, bool is_qualified_path)
+{
+ TyTy::BaseType *lookup = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &lookup);
+ rust_assert (ok);
+
+ // need to look up the reference for this identifier
+
+ // this can fail because it might be a Constructor for something
+ // in that case the caller should attempt ResolvePathType::Compile
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ auto resolved = nr_ctx.lookup (mappings.get_nodeid ());
+
+ if (!resolved)
+ return attempt_constructor_expression_lookup (lookup, ctx, mappings,
+ expr_locus);
+
+ ref_node_id = *resolved;
+ }
+ else
+ {
+ if (!ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (),
+ &ref_node_id))
+ return attempt_constructor_expression_lookup (lookup, ctx, mappings,
+ expr_locus);
+ }
+
+ return resolve_with_node_id (final_segment, mappings, expr_locus,
+ is_qualified_path, ref_node_id);
+}
+
+tree
HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
const HIR::PathIdentSegment &final_segment,
const Analysis::NodeMapping &mappings,
@@ -205,11 +251,9 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
if (auto resolved_item = ctx->get_mappings ().lookup_hir_item (ref))
{
if (!lookup->has_substitutions_defined ())
- return CompileItem::compile (*resolved_item, ctx, nullptr, true,
- expr_locus);
+ return CompileItem::compile (*resolved_item, ctx, nullptr, expr_locus);
else
- return CompileItem::compile (*resolved_item, ctx, lookup, true,
- expr_locus);
+ return CompileItem::compile (*resolved_item, ctx, lookup, expr_locus);
}
else if (auto hir_extern_item
= ctx->get_mappings ().lookup_hir_extern_item (ref))
@@ -217,10 +261,10 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
HIR::ExternalItem *resolved_extern_item = hir_extern_item->first;
if (!lookup->has_substitutions_defined ())
return CompileExternItem::compile (resolved_extern_item, ctx, nullptr,
- true, expr_locus);
+ expr_locus);
else
return CompileExternItem::compile (resolved_extern_item, ctx, lookup,
- true, expr_locus);
+ expr_locus);
}
else
{
@@ -242,17 +286,14 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
{
if (!lookup->has_substitutions_defined ())
return CompileInherentImplItem::Compile (resolved_item->first, ctx,
- nullptr, true, expr_locus);
+ nullptr, expr_locus);
else
return CompileInherentImplItem::Compile (resolved_item->first, ctx,
- lookup, true, expr_locus);
+ lookup, expr_locus);
}
- else
+ else if (auto trait_item
+ = ctx->get_mappings ().lookup_hir_trait_item (ref))
{
- // it might be resolved to a trait item
- tl::optional<HIR::TraitItem *> trait_item
- = ctx->get_mappings ().lookup_hir_trait_item (ref);
-
HIR::Trait *trait = ctx->get_mappings ().lookup_trait_item_mapping (
trait_item.value ()->get_mappings ().get_hirid ());
@@ -262,16 +303,41 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
trait->get_mappings ().get_defid (), &trait_ref);
rust_assert (ok);
- TyTy::BaseType *receiver = nullptr;
- ok = ctx->get_tyctx ()->lookup_receiver (mappings.get_hirid (),
- &receiver);
- rust_assert (ok);
- receiver = receiver->destructure ();
+ if (trait_item.value ()->get_item_kind ()
+ == HIR::TraitItem::TraitItemKind::CONST)
+ {
+ auto &c
+ = *static_cast<HIR::TraitItemConst *> (trait_item.value ());
+ if (!c.has_expr ())
+ {
+ rich_location r (line_table, expr_locus);
+ r.add_range (trait->get_locus ());
+ r.add_range (c.get_locus ());
+ rust_error_at (r, "no default expression on trait constant");
+ return error_mark_node;
+ }
+
+ return CompileExpr::Compile (c.get_expr (), ctx);
+ }
+
+ if (trait_item.value ()->get_item_kind ()
+ != HIR::TraitItem::TraitItemKind::FUNC)
+ return error_mark_node;
// the type resolver can only resolve type bounds to their trait
// item so its up to us to figure out if this path should resolve
// to an trait-impl-block-item or if it can be defaulted to the
// trait-impl-item's definition
+ //
+ // because we know this is resolved to a trait item we can actually
+ // just grab the Self type parameter here for the receiver to match
+ // the appropriate impl block
+
+ rust_assert (lookup->is<TyTy::FnType> ());
+ auto fn = lookup->as<TyTy::FnType> ();
+ rust_assert (fn->get_num_type_params () > 0);
+ auto &self = fn->get_substs ().at (0);
+ auto receiver = self.get_param_ty ();
auto candidates
= Resolver::PathProbeImplTrait::Probe (receiver, final_segment,
trait_ref);
@@ -301,16 +367,15 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
TyTy::BaseType *self = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
- impl->get_type ()->get_mappings ().get_hirid (), &self);
+ impl->get_type ().get_mappings ().get_hirid (), &self);
rust_assert (ok);
if (!lookup->has_substitutions_defined ())
return CompileInherentImplItem::Compile (impl_item, ctx,
- nullptr, true,
- expr_locus);
+ nullptr, expr_locus);
else
return CompileInherentImplItem::Compile (impl_item, ctx, lookup,
- true, expr_locus);
+ expr_locus);
}
}
}
diff --git a/gcc/rust/backend/rust-compile-resolve-path.h b/gcc/rust/backend/rust-compile-resolve-path.h
index 7654fd9..79bfb86 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.h
+++ b/gcc/rust/backend/rust-compile-resolve-path.h
@@ -20,53 +20,39 @@
#define RUST_COMPILE_RESOLVE_PATH
#include "rust-compile-base.h"
-#include "rust-hir-visitor.h"
namespace Rust {
namespace Compile {
-class ResolvePathRef : public HIRCompileBase, public HIR::HIRPatternVisitor
+class ResolvePathRef : public HIRCompileBase
{
public:
- static tree Compile (HIR::QualifiedPathInExpression &expr, Context *ctx)
- {
- ResolvePathRef resolver (ctx);
- expr.accept_vis (resolver);
- return resolver.resolved;
- }
-
- static tree Compile (HIR::PathInExpression &expr, Context *ctx)
- {
- ResolvePathRef resolver (ctx);
- expr.accept_vis (resolver);
- return resolver.resolved;
- }
-
- void visit (HIR::PathInExpression &expr) override;
- void visit (HIR::QualifiedPathInExpression &expr) override;
-
- // Empty visit for unused Pattern HIR nodes.
- void visit (HIR::IdentifierPattern &) override {}
- void visit (HIR::LiteralPattern &) override {}
- void visit (HIR::RangePattern &) override {}
- void visit (HIR::ReferencePattern &) override {}
- void visit (HIR::SlicePattern &) override {}
- void visit (HIR::AltPattern &) override {}
- void visit (HIR::StructPattern &) override {}
- void visit (HIR::TuplePattern &) override {}
- void visit (HIR::TupleStructPattern &) override {}
- void visit (HIR::WildcardPattern &) override {}
-
- ResolvePathRef (Context *ctx)
- : HIRCompileBase (ctx), resolved (error_mark_node)
- {}
-
+ static tree Compile (HIR::QualifiedPathInExpression &expr, Context *ctx);
+
+ static tree Compile (HIR::PathInExpression &expr, Context *ctx);
+
+ ResolvePathRef (Context *ctx);
+
+ /**
+ * Generic visitor for both PathInExpression and QualifiedPathInExpression
+ */
+ template <typename T> tree resolve_path_like (T &expr);
+
+ /**
+ * Inner implementation of `resolve` - resolution with an already known NodeId
+ */
+ tree resolve_with_node_id (const HIR::PathIdentSegment &final_segment,
+ const Analysis::NodeMapping &mappings,
+ location_t locus, bool is_qualified_path,
+ NodeId resolved_node_id);
+ /**
+ * Resolve a mappings' NodeId and call into `resolve_with_node_id` which
+ * performs the rest of the path resolution
+ */
tree resolve (const HIR::PathIdentSegment &final_segment,
const Analysis::NodeMapping &mappings, location_t locus,
bool is_qualified_path);
- tree resolved;
-
private:
tree
attempt_constructor_expression_lookup (TyTy::BaseType *lookup, Context *ctx,
diff --git a/gcc/rust/backend/rust-compile-stmt.cc b/gcc/rust/backend/rust-compile-stmt.cc
index d8b27ff..a4b5a98 100644
--- a/gcc/rust/backend/rust-compile-stmt.cc
+++ b/gcc/rust/backend/rust-compile-stmt.cc
@@ -40,13 +40,13 @@ CompileStmt::Compile (HIR::Stmt *stmt, Context *ctx)
void
CompileStmt::visit (HIR::ExprStmt &stmt)
{
- translated = CompileExpr::Compile (stmt.get_expr ().get (), ctx);
+ translated = CompileExpr::Compile (stmt.get_expr (), ctx);
}
void
CompileStmt::visit (HIR::LetStmt &stmt)
{
- HIR::Pattern &stmt_pattern = *stmt.get_pattern ();
+ HIR::Pattern &stmt_pattern = stmt.get_pattern ();
HirId stmt_id = stmt_pattern.get_mappings ().get_hirid ();
TyTy::BaseType *ty = nullptr;
@@ -68,7 +68,7 @@ CompileStmt::visit (HIR::LetStmt &stmt)
if (!stmt.has_init_expr ())
return;
- tree init = CompileExpr::Compile (stmt.get_init_expr ().get (), ctx);
+ tree init = CompileExpr::Compile (stmt.get_init_expr (), ctx);
// FIXME use error_mark_node, check that CompileExpr returns error_mark_node
// on failure and make this an assertion
if (init == nullptr)
@@ -76,11 +76,11 @@ CompileStmt::visit (HIR::LetStmt &stmt)
TyTy::BaseType *actual = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
- stmt.get_init_expr ()->get_mappings ().get_hirid (), &actual);
+ stmt.get_init_expr ().get_mappings ().get_hirid (), &actual);
rust_assert (ok);
- location_t lvalue_locus = stmt.get_pattern ()->get_locus ();
- location_t rvalue_locus = stmt.get_init_expr ()->get_locus ();
+ location_t lvalue_locus = stmt.get_pattern ().get_locus ();
+ location_t rvalue_locus = stmt.get_init_expr ().get_locus ();
TyTy::BaseType *expected = ty;
init = coercion_site (stmt.get_mappings ().get_hirid (), init, actual,
expected, lvalue_locus, rvalue_locus);
diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.cc b/gcc/rust/backend/rust-compile-struct-field-expr.cc
index 4a3b26c..0ac25e7 100644
--- a/gcc/rust/backend/rust-compile-struct-field-expr.cc
+++ b/gcc/rust/backend/rust-compile-struct-field-expr.cc
@@ -27,22 +27,22 @@ CompileStructExprField::CompileStructExprField (Context *ctx)
{}
tree
-CompileStructExprField::Compile (HIR::StructExprField *field, Context *ctx)
+CompileStructExprField::Compile (HIR::StructExprField &field, Context *ctx)
{
CompileStructExprField compiler (ctx);
- switch (field->get_kind ())
+ switch (field.get_kind ())
{
case HIR::StructExprField::StructExprFieldKind::IDENTIFIER:
- compiler.visit (static_cast<HIR::StructExprFieldIdentifier &> (*field));
+ compiler.visit (static_cast<HIR::StructExprFieldIdentifier &> (field));
break;
case HIR::StructExprField::StructExprFieldKind::IDENTIFIER_VALUE:
compiler.visit (
- static_cast<HIR::StructExprFieldIdentifierValue &> (*field));
+ static_cast<HIR::StructExprFieldIdentifierValue &> (field));
break;
case HIR::StructExprField::StructExprFieldKind::INDEX_VALUE:
- compiler.visit (static_cast<HIR::StructExprFieldIndexValue &> (*field));
+ compiler.visit (static_cast<HIR::StructExprFieldIndexValue &> (field));
break;
}
return compiler.translated;
@@ -51,13 +51,13 @@ CompileStructExprField::Compile (HIR::StructExprField *field, Context *ctx)
void
CompileStructExprField::visit (HIR::StructExprFieldIdentifierValue &field)
{
- translated = CompileExpr::Compile (field.get_value ().get (), ctx);
+ translated = CompileExpr::Compile (field.get_value (), ctx);
}
void
CompileStructExprField::visit (HIR::StructExprFieldIndexValue &field)
{
- translated = CompileExpr::Compile (field.get_value ().get (), ctx);
+ translated = CompileExpr::Compile (field.get_value (), ctx);
}
void
@@ -74,7 +74,7 @@ CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
HIR::GenericArgs::create_empty ());
HIR::PathInExpression expr (mappings_copy2, {seg}, field.get_locus (), false,
{});
- translated = CompileExpr::Compile (&expr, ctx);
+ translated = CompileExpr::Compile (expr, ctx);
}
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.h b/gcc/rust/backend/rust-compile-struct-field-expr.h
index f1d7055..055019c 100644
--- a/gcc/rust/backend/rust-compile-struct-field-expr.h
+++ b/gcc/rust/backend/rust-compile-struct-field-expr.h
@@ -27,7 +27,7 @@ namespace Compile {
class CompileStructExprField : private HIRCompileBase
{
public:
- static tree Compile (HIR::StructExprField *field, Context *ctx);
+ static tree Compile (HIR::StructExprField &field, Context *ctx);
protected:
void visit (HIR::StructExprFieldIdentifierValue &field);
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index b546a05..83e5756 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -22,6 +22,7 @@
#include "rust-gcc.h"
#include "tree.h"
+#include "stor-layout.h"
namespace Rust {
namespace Compile {
@@ -54,7 +55,7 @@ TyTyResolveCompile::compile (Context *ctx, const TyTy::BaseType *ty,
// see: gcc/c/c-decl.cc:8230-8241
// https://github.com/Rust-GCC/gccrs/blob/0024bc2f028369b871a65ceb11b2fddfb0f9c3aa/gcc/c/c-decl.c#L8229-L8241
tree
-TyTyResolveCompile::get_implicit_enumeral_node_type ()
+TyTyResolveCompile::get_implicit_enumeral_node_type (TyTy::BaseType *repr)
{
// static tree enum_node = NULL_TREE;
// if (enum_node == NULL_TREE)
@@ -76,25 +77,26 @@ TyTyResolveCompile::get_implicit_enumeral_node_type ()
// }
// return enum_node;
- static tree enum_node = NULL_TREE;
- if (enum_node == NULL_TREE)
- {
- // equivalent to isize
- enum_node = Backend::named_type (
- "enumeral", Backend::integer_type (false, Backend::get_pointer_size ()),
- BUILTINS_LOCATION);
- }
- return enum_node;
+ return compile (ctx, repr);
}
tree
-TyTyResolveCompile::get_unit_type ()
+TyTyResolveCompile::get_unit_type (Context *ctx)
{
static tree unit_type;
if (unit_type == nullptr)
{
+ auto cn = ctx->get_mappings ().get_current_crate ();
+ auto &c = ctx->get_mappings ().get_ast_crate (cn);
+ location_t locus = BUILTINS_LOCATION;
+ if (c.items.size () > 0)
+ {
+ auto &item = c.items[0];
+ locus = item->get_locus ();
+ }
+
auto unit_type_node = Backend::struct_type ({});
- unit_type = Backend::named_type ("()", unit_type_node, BUILTINS_LOCATION);
+ unit_type = Backend::named_type ("()", unit_type_node, locus);
}
return unit_type;
}
@@ -208,12 +210,12 @@ TyTyResolveCompile::visit (const TyTy::FnType &type)
for (auto &param_pair : type.get_params ())
{
- auto param_tyty = param_pair.second;
+ auto param_tyty = param_pair.get_type ();
auto compiled_param_type
= TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
auto compiled_param = Backend::typed_identifier (
- param_pair.first->as_string (), compiled_param_type,
+ param_pair.get_pattern ().as_string (), compiled_param_type,
ctx->get_mappings ().lookup_location (param_tyty->get_ref ()));
parameters.push_back (compiled_param);
@@ -268,8 +270,8 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
fields.push_back (std::move (f));
}
- type_record = type.is_union () ? Backend::union_type (fields)
- : Backend::struct_type (fields);
+ type_record = type.is_union () ? Backend::union_type (fields, false)
+ : Backend::struct_type (fields, false);
}
else
{
@@ -297,21 +299,39 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
// Ada, qual_union_types might still work for this but I am not 100% sure.
// I ran into some issues lets reuse our normal union and ask Ada people
// about it.
+ //
+ // I think the above is actually wrong and it should actually be this
+ //
+ // struct {
+ // int RUST$ENUM$DISR; // take into account the repr for this TODO
+ // union {
+ // // Variant A
+ // struct {
+ // // No additional fields
+ // } A;
+
+ // // Variant B
+ // struct {
+ // // No additional fields
+ // } B;
+
+ // // Variant C
+ // struct {
+ // char c;
+ // } C;
+
+ // // Variant D
+ // struct {
+ // int64_t x;
+ // int64_t y;
+ // } D;
+ // } payload; // The union of all variant data
+ // };
std::vector<tree> variant_records;
for (auto &variant : type.get_variants ())
{
std::vector<Backend::typed_identifier> fields;
-
- // add in the qualifier field for the variant
- tree enumeral_type
- = TyTyResolveCompile::get_implicit_enumeral_node_type ();
- Backend::typed_identifier f (RUST_ENUM_DISR_FIELD_NAME, enumeral_type,
- ctx->get_mappings ().lookup_location (
- variant->get_id ()));
- fields.push_back (std::move (f));
-
- // compile the rest of the fields
for (size_t i = 0; i < variant->num_fields (); i++)
{
const TyTy::StructFieldType *field
@@ -335,9 +355,6 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
= Backend::named_type (variant->get_ident ().path.get (),
variant_record, variant->get_ident ().locus);
- // set the qualifier to be a builtin
- DECL_ARTIFICIAL (TYPE_FIELDS (variant_record)) = 1;
-
// add them to the list
variant_records.push_back (named_variant_record);
}
@@ -358,8 +375,27 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
enum_fields.push_back (std::move (f));
}
+ //
+ location_t locus = ctx->get_mappings ().lookup_location (type.get_ref ());
+
// finally make the union or the enum
- type_record = Backend::union_type (enum_fields);
+ tree variants_union = Backend::union_type (enum_fields, false);
+ layout_type (variants_union);
+ tree named_union_record
+ = Backend::named_type ("payload", variants_union, locus);
+
+ // create the overall struct
+ tree enumeral_type = TyTyResolveCompile::get_implicit_enumeral_node_type (
+ type.get_repr_options ().repr);
+ Backend::typed_identifier discrim (RUST_ENUM_DISR_FIELD_NAME,
+ enumeral_type, locus);
+ Backend::typed_identifier variants_union_field ("payload",
+ named_union_record,
+ locus);
+
+ std::vector<Backend::typed_identifier> fields
+ = {discrim, variants_union_field};
+ type_record = Backend::struct_type (fields, false);
}
// Handle repr options
@@ -381,6 +417,7 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
SET_TYPE_ALIGN (type_record, repr.align * 8);
TYPE_USER_ALIGN (type_record) = 1;
}
+ layout_type (type_record);
std::string named_struct_str
= type.get_ident ().path.get () + type.subst_as_string ();
@@ -393,7 +430,7 @@ TyTyResolveCompile::visit (const TyTy::TupleType &type)
{
if (type.num_fields () == 0)
{
- translated = get_unit_type ();
+ translated = get_unit_type (ctx);
return;
}
@@ -428,12 +465,24 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type)
= TyTyResolveCompile::compile (ctx, type.get_element_type ());
ctx->push_const_context ();
- tree capacity_expr = CompileExpr::Compile (&type.get_capacity_expr (), ctx);
+
+ HIR::Expr &hir_capacity_expr = type.get_capacity_expr ();
+ TyTy::BaseType *capacity_expr_ty = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ hir_capacity_expr.get_mappings ().get_hirid (), &capacity_expr_ty);
+ rust_assert (ok);
+ tree capacity_expr = HIRCompileBase::compile_constant_expr (
+ ctx, hir_capacity_expr.get_mappings ().get_hirid (), capacity_expr_ty,
+ capacity_expr_ty, Resolver::CanonicalPath::create_empty (),
+ hir_capacity_expr, type.get_locus (), hir_capacity_expr.get_locus ());
+
ctx->pop_const_context ();
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);
}
void
@@ -686,7 +735,7 @@ TyTyResolveCompile::visit (const TyTy::StrType &type)
void
TyTyResolveCompile::visit (const TyTy::NeverType &)
{
- translated = get_unit_type ();
+ translated = get_unit_type (ctx);
}
void
@@ -703,6 +752,12 @@ TyTyResolveCompile::visit (const TyTy::DynamicObjectType &type)
type.get_ident ().locus);
}
+void
+TyTyResolveCompile::visit (const TyTy::OpaqueType &type)
+{
+ translated = error_mark_node;
+}
+
tree
TyTyResolveCompile::create_dyn_obj_record (const TyTy::DynamicObjectType &type)
{
diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h
index e01ca43..7ebc4a6 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -30,9 +30,7 @@ public:
static tree compile (Context *ctx, const TyTy::BaseType *ty,
bool trait_object_mode = false);
- static tree get_implicit_enumeral_node_type ();
-
- static tree get_unit_type ();
+ static tree get_unit_type (Context *ctx);
void visit (const TyTy::InferType &) override;
void visit (const TyTy::ADTType &) override;
@@ -58,6 +56,7 @@ public:
void visit (const TyTy::ProjectionType &) override;
void visit (const TyTy::DynamicObjectType &) override;
void visit (const TyTy::ClosureType &) override;
+ void visit (const TyTy::OpaqueType &) override;
public:
static hashval_t type_hasher (tree type);
@@ -66,6 +65,7 @@ protected:
tree create_slice_type_record (const TyTy::SliceType &type);
tree create_str_type_record (const TyTy::StrType &type);
tree create_dyn_obj_record (const TyTy::DynamicObjectType &type);
+ tree get_implicit_enumeral_node_type (TyTy::BaseType *repr);
private:
TyTyResolveCompile (Context *ctx, bool trait_object_mode);
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index 6b6af77..4c46a7b 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -68,12 +68,12 @@ public:
void visit (HIR::TuplePattern &pattern) override
{
- switch (pattern.get_items ()->get_item_type ())
+ switch (pattern.get_items ().get_item_type ())
{
case HIR::TuplePatternItems::ItemType::MULTIPLE: {
rust_assert (TREE_CODE (translated_type) == RECORD_TYPE);
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- *pattern.get_items ());
+ pattern.get_items ());
size_t offs = 0;
for (auto &sub : items.get_patterns ())
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 7e0a9b6..dbd8515 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -259,17 +259,17 @@ HIRCompileBase::compute_address_for_trait_item (
HIR::ImplBlock *impl_block = item.second;
rust_assert (impl_block != nullptr);
- // Lookup type for potentially associated impl.
- std::unique_ptr<HIR::Type> &self_type_path = impl_block->get_type ();
-
// Checks for empty impl blocks, triggered by Sized trait.
- if (self_type_path == nullptr)
+ if (!impl_block->has_type ())
continue;
+ // Lookup type for potentially associated impl.
+ HIR::Type &self_type_path = impl_block->get_type ();
+
// Convert HIR::Type to TyTy::BaseType
TyTy::BaseType *self = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
- self_type_path->get_mappings ().get_hirid (), &self);
+ self_type_path.get_mappings ().get_hirid (), &self);
rust_assert (ok);
@@ -338,7 +338,7 @@ HIRCompileBase::compute_address_for_trait_item (
}
return CompileInherentImplItem::Compile (associated_function, ctx,
- lookup_fntype, true, locus);
+ lookup_fntype, locus);
}
// we can only compile trait-items with a body
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index bfd7d95..dc2d6b1 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -2697,10 +2697,8 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
}
if (TREE_CODE (probe) == ARRAY_REF)
{
- // TODO
- rust_unreachable ();
- // elt = eval_and_check_array_index (ctx, probe, false,
- // non_constant_p, overflow_p);
+ elt = eval_and_check_array_index (ctx, probe, false,
+ non_constant_p, overflow_p);
if (*non_constant_p)
return t;
}
@@ -2929,8 +2927,13 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
}
}
+ if (*non_constant_p)
+ return t;
+
/* Don't share a CONSTRUCTOR that might be changed later. */
init = unshare_constructor (init);
+ if (init == NULL_TREE)
+ return t;
if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
&& TREE_CODE (init) == CONSTRUCTOR)
@@ -3585,9 +3588,6 @@ eval_call_expression (const constexpr_ctx *ctx, tree t, bool lval,
result = *ctx->global->values.get (res);
if (result == NULL_TREE && !*non_constant_p)
{
- if (!ctx->quiet)
- error ("%<constexpr%> call flows off the end "
- "of the function");
*non_constant_p = true;
}
}
diff --git a/gcc/rust/backend/rust-mangle-legacy.cc b/gcc/rust/backend/rust-mangle-legacy.cc
index 2c0ddd9..7671982 100644
--- a/gcc/rust/backend/rust-mangle-legacy.cc
+++ b/gcc/rust/backend/rust-mangle-legacy.cc
@@ -21,7 +21,6 @@
#include "rust-unicode.h"
#include "rust-diagnostics.h"
#include "rust-system.h"
-#include <sstream>
namespace Rust {
namespace Compile {
diff --git a/gcc/rust/backend/rust-mangle-v0.cc b/gcc/rust/backend/rust-mangle-v0.cc
index d604dcf..d0df4ab 100644
--- a/gcc/rust/backend/rust-mangle-v0.cc
+++ b/gcc/rust/backend/rust-mangle-v0.cc
@@ -25,7 +25,6 @@
#include "rust-unicode.h"
#include "rust-punycode.h"
#include "rust-compile-type.h"
-#include <sstream>
namespace Rust {
namespace Compile {
@@ -328,7 +327,7 @@ v0_inherent_or_trait_impl_path (Rust::Compile::Context *ctx,
// lookup impl type
TyTy::BaseType *impl_ty = nullptr;
ok = ctx->get_tyctx ()->lookup_type (
- impl_block->get_type ()->get_mappings ().get_hirid (), &impl_ty);
+ impl_block->get_type ().get_mappings ().get_hirid (), &impl_ty);
rust_assert (ok);
// FIXME: dummy value for now
@@ -342,7 +341,7 @@ v0_inherent_or_trait_impl_path (Rust::Compile::Context *ctx,
TyTy::BaseType *trait_ty = nullptr;
ok = ctx->get_tyctx ()->lookup_type (
- impl_block->get_trait_ref ()->get_mappings ().get_hirid (), &trait_ty);
+ impl_block->get_trait_ref ().get_mappings ().get_hirid (), &trait_ty);
rust_assert (ok);
v0path.trait_type = v0_type_prefix (ctx, trait_ty);
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/.cargo/config.toml b/gcc/rust/checks/errors/borrowck/ffi-polonius/.cargo/config.toml
deleted file mode 100644
index 0236928..0000000
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/.cargo/config.toml
+++ /dev/null
@@ -1,5 +0,0 @@
-[source.crates-io]
-replace-with = "vendored-sources"
-
-[source.vendored-sources]
-directory = "vendor"
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock
index f7cbd41..1b223b6 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock
@@ -1,12 +1,8 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-version = 3
-
[[package]]
name = "datafrog"
version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
[[package]]
name = "ffi-polonius"
@@ -18,14 +14,10 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "polonius-engine"
version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4e8e505342045d397d0b6674dcb82d6faf5cf40484d30eeb88fc82ef14e903f"
dependencies = [
"datafrog",
"log",
@@ -35,5 +27,3 @@ dependencies = [
[[package]]
name = "rustc-hash"
version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml
index 71315c3..3bc8e3f 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml
@@ -1,11 +1,17 @@
[package]
name = "ffi-polonius"
version = "0.1.0"
-edition = "2021"
+edition = "2018"
license = "GPL-3"
[lib]
crate-type = ["staticlib"]
[dependencies]
-polonius-engine = "0.13.0" \ No newline at end of file
+polonius-engine = "0.13.0"
+
+[patch.crates-io]
+log = { path = "vendor/log" }
+datafrog = { path = "vendor/datafrog" }
+polonius-engine = { path = "vendor/polonius-engine" }
+rustc-hash = { path = "vendor/rustc-hash" }
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml
index 313a005..a199e31 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml
@@ -10,7 +10,7 @@
# See Cargo.toml.orig for the original contents.
[package]
-edition = "2021"
+edition = "2018"
rust-version = "1.60.0"
name = "log"
version = "0.4.22"
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs
index 6b43a9a..603bbac 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs
@@ -397,20 +397,13 @@ mod serde;
#[cfg(feature = "kv")]
pub mod kv;
-#[cfg(target_has_atomic = "ptr")]
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-#[cfg(not(target_has_atomic = "ptr"))]
use std::cell::Cell;
-#[cfg(not(target_has_atomic = "ptr"))]
use std::sync::atomic::Ordering;
-#[cfg(not(target_has_atomic = "ptr"))]
struct AtomicUsize {
v: Cell<usize>,
}
-#[cfg(not(target_has_atomic = "ptr"))]
impl AtomicUsize {
const fn new(v: usize) -> AtomicUsize {
AtomicUsize { v: Cell::new(v) }
@@ -423,26 +416,10 @@ impl AtomicUsize {
fn store(&self, val: usize, _order: Ordering) {
self.v.set(val)
}
-
- #[cfg(target_has_atomic = "ptr")]
- fn compare_exchange(
- &self,
- current: usize,
- new: usize,
- _success: Ordering,
- _failure: Ordering,
- ) -> Result<usize, usize> {
- let prev = self.v.get();
- if current == prev {
- self.v.set(new);
- }
- Ok(prev)
- }
}
// Any platform without atomics is unlikely to have multiple cores, so
// writing via Cell will not be a race condition.
-#[cfg(not(target_has_atomic = "ptr"))]
unsafe impl Sync for AtomicUsize {}
// The LOGGER static holds a pointer to the global logger. It is protected by
@@ -1258,17 +1235,6 @@ where
}
}
-/// Sets the global maximum log level.
-///
-/// Generally, this should only be called by the active logging implementation.
-///
-/// Note that `Trace` is the maximum level, because it provides the maximum amount of detail in the emitted logs.
-#[inline]
-#[cfg(target_has_atomic = "ptr")]
-pub fn set_max_level(level: LevelFilter) {
- MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::Relaxed);
-}
-
/// A thread-unsafe version of [`set_max_level`].
///
/// This function is available on all platforms, even those that do not have
@@ -1320,110 +1286,6 @@ pub fn max_level() -> LevelFilter {
unsafe { mem::transmute(MAX_LOG_LEVEL_FILTER.load(Ordering::Relaxed)) }
}
-/// Sets the global logger to a `Box<Log>`.
-///
-/// This is a simple convenience wrapper over `set_logger`, which takes a
-/// `Box<Log>` rather than a `&'static Log`. See the documentation for
-/// [`set_logger`] for more details.
-///
-/// Requires the `std` feature.
-///
-/// # Errors
-///
-/// An error is returned if a logger has already been set.
-///
-/// [`set_logger`]: fn.set_logger.html
-#[cfg(all(feature = "std", target_has_atomic = "ptr"))]
-pub fn set_boxed_logger(logger: Box<dyn Log>) -> Result<(), SetLoggerError> {
- set_logger_inner(|| Box::leak(logger))
-}
-
-/// Sets the global logger to a `&'static Log`.
-///
-/// This function may only be called once in the lifetime of a program. Any log
-/// events that occur before the call to `set_logger` completes will be ignored.
-///
-/// This function does not typically need to be called manually. Logger
-/// implementations should provide an initialization method that installs the
-/// logger internally.
-///
-/// # Availability
-///
-/// This method is available even when the `std` feature is disabled. However,
-/// it is currently unavailable on `thumbv6` targets, which lack support for
-/// some atomic operations which are used by this function. Even on those
-/// targets, [`set_logger_racy`] will be available.
-///
-/// # Errors
-///
-/// An error is returned if a logger has already been set.
-///
-/// # Examples
-///
-/// ```
-/// use log::{error, info, warn, Record, Level, Metadata, LevelFilter};
-///
-/// static MY_LOGGER: MyLogger = MyLogger;
-///
-/// struct MyLogger;
-///
-/// impl log::Log for MyLogger {
-/// fn enabled(&self, metadata: &Metadata) -> bool {
-/// metadata.level() <= Level::Info
-/// }
-///
-/// fn log(&self, record: &Record) {
-/// if self.enabled(record.metadata()) {
-/// println!("{} - {}", record.level(), record.args());
-/// }
-/// }
-/// fn flush(&self) {}
-/// }
-///
-/// # fn main(){
-/// log::set_logger(&MY_LOGGER).unwrap();
-/// log::set_max_level(LevelFilter::Info);
-///
-/// info!("hello log");
-/// warn!("warning");
-/// error!("oops");
-/// # }
-/// ```
-///
-/// [`set_logger_racy`]: fn.set_logger_racy.html
-#[cfg(target_has_atomic = "ptr")]
-pub fn set_logger(logger: &'static dyn Log) -> Result<(), SetLoggerError> {
- set_logger_inner(|| logger)
-}
-
-#[cfg(target_has_atomic = "ptr")]
-fn set_logger_inner<F>(make_logger: F) -> Result<(), SetLoggerError>
-where
- F: FnOnce() -> &'static dyn Log,
-{
- match STATE.compare_exchange(
- UNINITIALIZED,
- INITIALIZING,
- Ordering::Acquire,
- Ordering::Relaxed,
- ) {
- Ok(UNINITIALIZED) => {
- unsafe {
- LOGGER = make_logger();
- }
- STATE.store(INITIALIZED, Ordering::Release);
- Ok(())
- }
- Err(INITIALIZING) => {
- while STATE.load(Ordering::Relaxed) == INITIALIZING {
- std::hint::spin_loop();
- }
- Err(SetLoggerError(()))
- }
- _ => Err(SetLoggerError(())),
- }
-}
-
/// A thread-unsafe version of [`set_logger`].
///
/// This function is available on all platforms, even those that do not have
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 1713bf6..6b8b2e9 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
@@ -135,7 +135,7 @@ ExprStmtBuilder::visit (HIR::LiteralExpr &expr)
void
ExprStmtBuilder::visit (HIR::BorrowExpr &expr)
{
- auto operand = visit_expr (*expr.get_expr ());
+ auto operand = visit_expr (expr.get_expr ());
if (ctx.place_db[operand].is_constant ())
{
// Cannot borrow a constant, must create a temporary copy.
@@ -150,7 +150,7 @@ ExprStmtBuilder::visit (HIR::BorrowExpr &expr)
void
ExprStmtBuilder::visit (HIR::DereferenceExpr &expr)
{
- auto operand = visit_expr (*expr.get_expr ());
+ auto operand = visit_expr (expr.get_expr ());
return_place (ctx.place_db.lookup_or_add_path (Place::DEREF,
lookup_type (expr), operand),
expr.get_locus ());
@@ -166,30 +166,31 @@ ExprStmtBuilder::visit (HIR::ErrorPropagationExpr &expr)
void
ExprStmtBuilder::visit (HIR::NegationExpr &expr)
{
- PlaceId operand = visit_expr (*expr.get_expr ());
- return_expr (new Operator<1> ({move_place (operand, expr.get_locus ())}),
+ PlaceId operand = visit_expr (expr.get_expr ());
+ return_expr (new Operator<1> (
+ {move_place (operand, expr.get_expr ().get_locus ())}),
lookup_type (expr), expr.get_locus ());
}
void
ExprStmtBuilder::visit (HIR::ArithmeticOrLogicalExpr &expr)
{
- PlaceId lhs = visit_expr (*expr.get_lhs ());
- PlaceId rhs = visit_expr (*expr.get_rhs ());
+ PlaceId lhs = visit_expr (expr.get_lhs ());
+ PlaceId rhs = visit_expr (expr.get_rhs ());
return_expr (new Operator<2> (
- {move_place (lhs, expr.get_lhs ()->get_locus ()),
- move_place (rhs, expr.get_rhs ()->get_locus ())}),
+ {move_place (lhs, expr.get_lhs ().get_locus ()),
+ move_place (rhs, expr.get_rhs ().get_locus ())}),
lookup_type (expr), expr.get_locus ());
}
void
ExprStmtBuilder::visit (HIR::ComparisonExpr &expr)
{
- PlaceId lhs = visit_expr (*expr.get_lhs ());
- PlaceId rhs = visit_expr (*expr.get_rhs ());
+ PlaceId lhs = visit_expr (expr.get_lhs ());
+ PlaceId rhs = visit_expr (expr.get_rhs ());
return_expr (new Operator<2> (
- {move_place (lhs, expr.get_lhs ()->get_locus ()),
- move_place (rhs, expr.get_rhs ()->get_locus ())}),
+ {move_place (lhs, expr.get_lhs ().get_locus ()),
+ move_place (rhs, expr.get_rhs ().get_locus ())}),
lookup_type (expr), expr.get_locus ());
}
@@ -205,7 +206,7 @@ ExprStmtBuilder::visit (HIR::LazyBooleanExpr &expr)
void
ExprStmtBuilder::visit (HIR::TypeCastExpr &expr)
{
- auto operand = visit_expr (*expr.get_expr ());
+ auto operand = visit_expr (expr.get_expr ());
return_expr (new Operator<1> ({operand}), lookup_type (expr),
expr.get_locus ());
}
@@ -213,8 +214,8 @@ ExprStmtBuilder::visit (HIR::TypeCastExpr &expr)
void
ExprStmtBuilder::visit (HIR::AssignmentExpr &expr)
{
- auto lhs = visit_expr (*expr.get_lhs ());
- auto rhs = visit_expr (*expr.get_rhs ());
+ auto lhs = visit_expr (expr.get_lhs ());
+ auto rhs = visit_expr (expr.get_rhs ());
push_assignment (lhs, rhs, expr.get_locus ());
translated = INVALID_PLACE;
}
@@ -222,25 +223,25 @@ ExprStmtBuilder::visit (HIR::AssignmentExpr &expr)
void
ExprStmtBuilder::visit (HIR::CompoundAssignmentExpr &expr)
{
- auto lhs = visit_expr (*expr.get_lhs ());
- auto rhs = visit_expr (*expr.get_rhs ());
+ auto lhs = visit_expr (expr.get_lhs ());
+ auto rhs = visit_expr (expr.get_rhs ());
push_assignment (lhs, new Operator<2> ({lhs, rhs}), expr.get_locus ());
}
void
ExprStmtBuilder::visit (HIR::GroupedExpr &expr)
{
- return_place (visit_expr (*expr.get_expr_in_parens ()), expr.get_locus ());
+ return_place (visit_expr (expr.get_expr_in_parens ()), expr.get_locus ());
}
void
ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
{
auto &elems = expr.get_internal_elements ();
- switch (elems->get_array_expr_type ())
+ switch (elems.get_array_expr_type ())
{
case HIR::ArrayElems::VALUES: {
- auto &elem_vals = (static_cast<HIR::ArrayElemsValues &> (*elems));
+ auto &elem_vals = (static_cast<HIR::ArrayElemsValues &> (elems));
auto init_values = visit_list (elem_vals.get_values ());
// collect locations
std::vector<location_t> value_locations;
@@ -254,8 +255,8 @@ ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
break;
}
case HIR::ArrayElems::COPIED: {
- auto &elem_copied = (static_cast<HIR::ArrayElemsCopied &> (*elems));
- auto init = visit_expr (*elem_copied.get_elem_to_copy ());
+ 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),
expr.get_locus ());
break;
@@ -266,8 +267,8 @@ ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
void
ExprStmtBuilder::visit (HIR::ArrayIndexExpr &expr)
{
- auto lhs = visit_expr (*expr.get_array_expr ());
- auto rhs = visit_expr (*expr.get_index_expr ());
+ auto lhs = visit_expr (expr.get_array_expr ());
+ auto rhs = visit_expr (expr.get_index_expr ());
// The index is not tracked in BIR.
std::ignore = rhs;
return_place (ctx.place_db.lookup_or_add_path (Place::INDEX,
@@ -286,7 +287,7 @@ ExprStmtBuilder::visit (HIR::TupleExpr &expr)
void
ExprStmtBuilder::visit (HIR::TupleIndexExpr &expr)
{
- auto tuple = visit_expr (*expr.get_tuple_expr ());
+ auto tuple = visit_expr (expr.get_tuple_expr ());
return_place (ctx.place_db.lookup_or_add_path (Place::FIELD,
lookup_type (expr), tuple,
expr.get_tuple_index ()),
@@ -296,7 +297,7 @@ ExprStmtBuilder::visit (HIR::TupleIndexExpr &expr)
void
ExprStmtBuilder::visit (HIR::CallExpr &expr)
{
- PlaceId fn = visit_expr (*expr.get_fnexpr ());
+ PlaceId fn = visit_expr (expr.get_fnexpr ());
std::vector<PlaceId> arguments = visit_list (expr.get_arguments ());
const auto fn_type
@@ -324,13 +325,17 @@ ExprStmtBuilder::visit (HIR::InlineAsm &expr)
{}
void
+ExprStmtBuilder::visit (HIR::LlvmInlineAsm &expr)
+{}
+
+void
ExprStmtBuilder::visit (HIR::MethodCallExpr &expr)
{}
void
ExprStmtBuilder::visit (HIR::FieldAccessExpr &expr)
{
- auto receiver = visit_expr (*expr.get_receiver_expr ());
+ auto receiver = visit_expr (expr.get_receiver_expr ());
auto type = autoderef (receiver);
rust_assert (type->get_kind () == TyTy::ADT);
auto adt = type->as<TyTy::ADTType> ();
@@ -383,7 +388,7 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block)
if (block.has_expr () && !unreachable)
{
push_assignment (block_ctx.label_var,
- visit_expr (*block.get_final_expr ()),
+ visit_expr (block.get_final_expr ()),
block.get_start_locus ());
}
if (!ctx.get_current_bb ().is_terminated ())
@@ -397,9 +402,9 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block)
}
else if (block.has_expr () && !unreachable)
{
- return_place (visit_expr (*block.get_final_expr (),
+ return_place (visit_expr (block.get_final_expr (),
take_or_create_return_place (
- lookup_type (*block.get_final_expr ()))),
+ lookup_type (block.get_final_expr ()))),
block.get_start_locus ());
}
@@ -426,7 +431,7 @@ ExprStmtBuilder::visit (HIR::BreakExpr &brk)
LoopAndLabelCtx info = brk.has_label () ? get_label_ctx (brk.get_label ())
: get_unnamed_loop_ctx ();
if (brk.has_break_expr ())
- push_assignment (info.label_var, visit_expr (*brk.get_expr ()),
+ push_assignment (info.label_var, visit_expr (brk.get_expr ()),
brk.get_locus ());
start_new_consecutive_bb ();
@@ -438,8 +443,8 @@ ExprStmtBuilder::visit (HIR::BreakExpr &brk)
void
ExprStmtBuilder::visit (HIR::RangeFromToExpr &range)
{
- auto from = visit_expr (*range.get_from_expr ());
- auto to = visit_expr (*range.get_to_expr ());
+ auto from = visit_expr (range.get_from_expr ());
+ auto to = visit_expr (range.get_to_expr ());
return_expr (new InitializerExpr ({from, to}), lookup_type (range),
range.get_locus ());
}
@@ -447,7 +452,7 @@ ExprStmtBuilder::visit (HIR::RangeFromToExpr &range)
void
ExprStmtBuilder::visit (HIR::RangeFromExpr &expr)
{
- auto from = visit_expr (*expr.get_from_expr ());
+ auto from = visit_expr (expr.get_from_expr ());
return_expr (new InitializerExpr ({from}), lookup_type (expr),
expr.get_locus ());
}
@@ -455,7 +460,7 @@ ExprStmtBuilder::visit (HIR::RangeFromExpr &expr)
void
ExprStmtBuilder::visit (HIR::RangeToExpr &expr)
{
- auto to = visit_expr (*expr.get_to_expr ());
+ auto to = visit_expr (expr.get_to_expr ());
return_expr (new InitializerExpr ({to}), lookup_type (expr),
expr.get_locus ());
}
@@ -469,8 +474,8 @@ ExprStmtBuilder::visit (HIR::RangeFullExpr &expr)
void
ExprStmtBuilder::visit (HIR::RangeFromToInclExpr &expr)
{
- auto from = visit_expr (*expr.get_from_expr ());
- auto to = visit_expr (*expr.get_to_expr ());
+ auto from = visit_expr (expr.get_from_expr ());
+ auto to = visit_expr (expr.get_to_expr ());
return_expr (new InitializerExpr ({from, to}), lookup_type (expr),
expr.get_locus ());
}
@@ -478,7 +483,7 @@ ExprStmtBuilder::visit (HIR::RangeFromToInclExpr &expr)
void
ExprStmtBuilder::visit (HIR::RangeToInclExpr &expr)
{
- auto to = visit_expr (*expr.get_to_expr ());
+ auto to = visit_expr (expr.get_to_expr ());
return_expr (new InitializerExpr ({to}), lookup_type (expr),
expr.get_locus ());
}
@@ -489,9 +494,9 @@ ExprStmtBuilder::visit (HIR::ReturnExpr &ret)
if (ret.has_return_expr ())
{
push_assignment (RETURN_VALUE_PLACE,
- move_place (visit_expr (*ret.get_expr ()),
- ret.get_expr ()->get_locus ()),
- ret.get_expr ()->get_locus ());
+ move_place (visit_expr (ret.get_expr ()),
+ ret.get_expr ().get_locus ()),
+ ret.get_expr ().get_locus ());
}
unwind_until (ROOT_SCOPE);
push_return (ret.get_locus ());
@@ -509,7 +514,7 @@ ExprStmtBuilder::visit (HIR::LoopExpr &expr)
{
auto loop = setup_loop (expr);
- std::ignore = visit_expr (*expr.get_loop_block ());
+ std::ignore = visit_expr (expr.get_loop_block ());
if (!ctx.get_current_bb ().is_terminated ())
push_goto (loop.continue_bb);
@@ -521,12 +526,12 @@ ExprStmtBuilder::visit (HIR::WhileLoopExpr &expr)
{
auto loop = setup_loop (expr);
- auto cond_val = visit_expr (*expr.get_predicate_expr ());
+ auto cond_val = visit_expr (expr.get_predicate_expr ());
auto body_bb = new_bb ();
push_switch (cond_val, expr.get_locus (), {body_bb, loop.break_bb});
ctx.current_bb = body_bb;
- std::ignore = visit_expr (*expr.get_loop_block ());
+ std::ignore = visit_expr (expr.get_loop_block ());
push_goto (loop.continue_bb);
ctx.current_bb = loop.break_bb;
@@ -544,15 +549,15 @@ ExprStmtBuilder::visit (HIR::IfExpr &expr)
{
// If without else cannot return a non-unit value (see [E0317]).
- if (expr.get_if_block ()->statements.empty ())
+ if (expr.get_if_block ().statements.empty ())
return;
- push_switch (visit_expr (*expr.get_if_condition ()), expr.get_locus ());
+ push_switch (visit_expr (expr.get_if_condition ()), expr.get_locus ());
BasicBlockId if_block = ctx.current_bb;
ctx.current_bb = new_bb ();
BasicBlockId then_start_block = ctx.current_bb;
- std::ignore = visit_expr (*expr.get_if_block ());
+ std::ignore = visit_expr (expr.get_if_block ());
if (!ctx.get_current_bb ().is_terminated ())
push_goto (INVALID_BB); // Resolved later.
BasicBlockId then_end_block = ctx.current_bb;
@@ -573,8 +578,8 @@ ExprStmtBuilder::visit (HIR::IfExpr &expr)
void
ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
{
- push_switch (move_place (visit_expr (*expr.get_if_condition ()),
- expr.get_if_condition ()->get_locus ()),
+ push_switch (move_place (visit_expr (expr.get_if_condition ()),
+ expr.get_if_condition ().get_locus ()),
expr.get_locus ());
BasicBlockId if_end_bb = ctx.current_bb;
@@ -582,14 +587,14 @@ ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
ctx.current_bb = new_bb ();
BasicBlockId then_start_bb = ctx.current_bb;
- std::ignore = visit_expr (*expr.get_if_block (), result);
+ std::ignore = visit_expr (expr.get_if_block (), result);
if (!ctx.get_current_bb ().is_terminated ())
push_goto (INVALID_BB); // Resolved later.
BasicBlockId then_end_bb = ctx.current_bb;
ctx.current_bb = new_bb ();
BasicBlockId else_start_bb = ctx.current_bb;
- std::ignore = visit_expr (*expr.get_else_block (), result);
+ std::ignore = visit_expr (expr.get_else_block (), result);
if (!ctx.get_current_bb ().is_terminated ())
push_goto (INVALID_BB); // Resolved later.
BasicBlockId else_end_bb = ctx.current_bb;
@@ -612,18 +617,6 @@ ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
}
void
-ExprStmtBuilder::visit (HIR::IfLetExpr &expr)
-{
- rust_sorry_at (expr.get_locus (), "if let expressions are not supported");
-}
-
-void
-ExprStmtBuilder::visit (HIR::IfLetExprConseqElse &expr)
-{
- rust_sorry_at (expr.get_locus (), "if let expressions are not supported");
-}
-
-void
ExprStmtBuilder::visit (HIR::MatchExpr &expr)
{
rust_sorry_at (expr.get_locus (), "match expressions are not supported");
@@ -702,35 +695,35 @@ ExprStmtBuilder::visit (HIR::LetStmt &stmt)
tl::optional<TyTy::BaseType *> type_annotation;
if (stmt.has_type ())
- type_annotation = lookup_type (*stmt.get_type ());
+ type_annotation = lookup_type (stmt.get_type ());
- if (stmt.get_pattern ()->get_pattern_type () == HIR::Pattern::IDENTIFIER)
+ if (stmt.get_pattern ().get_pattern_type () == HIR::Pattern::IDENTIFIER)
{
// Only if a pattern is just an identifier, no destructuring is needed.
// Hoverer PatternBindingBuilder cannot change existing temporary
// (init expr is evaluated before pattern binding) into a
// variable, so it would emit extra assignment.
- auto var = declare_variable (stmt.get_pattern ()->get_mappings ());
+ auto var = declare_variable (stmt.get_pattern ().get_mappings ());
if (stmt.has_type ())
- push_user_type_ascription (var, lookup_type (*stmt.get_type ()));
+ push_user_type_ascription (var, lookup_type (stmt.get_type ()));
if (stmt.has_init_expr ())
- std::ignore = visit_expr (*stmt.get_init_expr (), var);
+ std::ignore = visit_expr (stmt.get_init_expr (), var);
}
else
{
if (stmt.has_init_expr ())
- init = visit_expr (*stmt.get_init_expr ());
+ init = visit_expr (stmt.get_init_expr ());
PatternBindingBuilder (ctx, init, type_annotation)
- .go (*stmt.get_pattern ());
+ .go (stmt.get_pattern ());
}
}
void
ExprStmtBuilder::visit (HIR::ExprStmt &stmt)
{
- PlaceId result = visit_expr (*stmt.get_expr ());
+ PlaceId result = visit_expr (stmt.get_expr ());
// We must read the value for current liveness and we must not store it into
// the same place.
if (result != INVALID_PLACE)
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 574f0f3..5cab3c4 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
@@ -100,9 +100,8 @@ protected: // Expr
void visit (HIR::IfExpr &expr) override;
void visit (HIR::IfExprConseqElse &expr) override;
void visit (HIR::InlineAsm &expr) override;
+ void visit (HIR::LlvmInlineAsm &expr) override;
- void visit (HIR::IfLetExpr &expr) override;
- void visit (HIR::IfLetExprConseqElse &expr) override;
void visit (HIR::MatchExpr &expr) override;
void visit (HIR::AwaitExpr &expr) override;
void visit (HIR::AsyncBlockExpr &expr) override;
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 f499532..b7a1555 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
@@ -63,16 +63,16 @@ public:
protected:
void visit (HIR::LazyBooleanExpr &expr) override
{
- auto lhs = visit_expr (*expr.get_lhs ());
- push_switch (move_place (lhs, expr.get_lhs ()->get_locus ()),
+ auto lhs = visit_expr (expr.get_lhs ());
+ push_switch (move_place (lhs, expr.get_lhs ().get_locus ()),
expr.get_locus (), {short_circuit_bb});
start_new_consecutive_bb ();
- return_place (visit_expr (*expr.get_rhs ()), expr.get_locus ());
+ return_place (visit_expr (expr.get_rhs ()), expr.get_locus ());
}
void visit (HIR::GroupedExpr &expr) override
{
- expr.get_expr_in_parens ()->accept_vis (*this);
+ expr.get_expr_in_parens ().accept_vis (*this);
}
protected:
@@ -193,14 +193,6 @@ public:
{
return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
}
- void visit (HIR::IfLetExpr &expr) override
- {
- return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
- }
- void visit (HIR::IfLetExprConseqElse &expr) override
- {
- return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
- }
void visit (HIR::MatchExpr &expr) override
{
return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
@@ -215,6 +207,7 @@ public:
}
void visit (HIR::InlineAsm &expr) override {}
+ void visit (HIR::LlvmInlineAsm &expr) override {}
protected: // Illegal at this position.
void visit (HIR::StructExprFieldIdentifier &field) override
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 723ff73..ee37bb0 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
@@ -50,7 +50,7 @@ PatternBindingBuilder::visit (HIR::ReferencePattern &pattern)
return ty->as<TyTy::ReferenceType> ()->get_base ();
});
- pattern.get_referenced_pattern ()->accept_vis (*this);
+ pattern.get_referenced_pattern ().accept_vis (*this);
}
void
@@ -107,7 +107,7 @@ PatternBindingBuilder::visit (HIR::StructPattern &pattern)
init = init.map ([&] (PlaceId id) {
return ctx.place_db.lookup_or_add_path (
- Place::FIELD, lookup_type (*tuple->get_tuple_pattern ()), id,
+ Place::FIELD, lookup_type (tuple->get_tuple_pattern ()), id,
tuple->get_index ());
});
@@ -120,7 +120,7 @@ PatternBindingBuilder::visit (HIR::StructPattern &pattern)
->get_field_type ();
});
- tuple->get_tuple_pattern ()->accept_vis (*this);
+ tuple->get_tuple_pattern ().accept_vis (*this);
break;
}
case HIR::StructPatternField::IDENT_PAT: {
@@ -136,7 +136,7 @@ PatternBindingBuilder::visit (HIR::StructPattern &pattern)
field_ty->get_field_type (),
saved.init.value (),
field_index);
- ident_field->get_pattern ()->accept_vis (*this);
+ ident_field->get_pattern ().accept_vis (*this);
break;
}
case HIR::StructPatternField::IDENT: {
@@ -197,17 +197,17 @@ PatternBindingBuilder::visit (HIR::TuplePattern &pattern)
SavedState saved (this);
size_t index = 0;
- switch (pattern.get_items ()->get_item_type ())
+ switch (pattern.get_items ().get_item_type ())
{
case HIR::TuplePatternItems::MULTIPLE: {
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- *pattern.get_items ());
+ pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
break;
}
case HIR::TuplePatternItems::RANGED: {
auto &items
- = static_cast<HIR::TuplePatternItemsRanged &> (*pattern.get_items ());
+ = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
auto tyty = ctx.place_db[init.value ()].tyty;
rust_assert (tyty->get_kind () == TyTy::TUPLE);
@@ -242,11 +242,11 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
});
size_t index = 0;
- switch (pattern.get_items ()->get_item_type ())
+ switch (pattern.get_items ().get_item_type ())
{
case HIR::TupleStructItems::RANGED: {
auto &items
- = static_cast<HIR::TupleStructItemsRange &> (*pattern.get_items ());
+ = static_cast<HIR::TupleStructItemsRange &> (pattern.get_items ());
rust_assert (type->get_kind () == TyTy::ADT);
auto adt_ty = static_cast<TyTy::ADTType *> (type);
@@ -263,7 +263,7 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
}
case HIR::TupleStructItems::MULTIPLE: {
auto &items
- = static_cast<HIR::TupleStructItemsNoRange &> (*pattern.get_items ());
+ = static_cast<HIR::TupleStructItemsNoRange &> (pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
break;
}
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h
index 5d4b85a..33ecd23 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h
@@ -91,6 +91,7 @@ public:
void visit (HIR::QualifiedPathInExpression &expression) override {}
void visit (HIR::RangePattern &pattern) override {}
};
+
} // namespace BIR
} // namespace Rust
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 53346bf..84311cc 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -52,12 +52,12 @@ public:
}
void visit (HIR::StructExprFieldIdentifierValue &field) override
{
- auto value = ExprStmtBuilder (ctx).build (*field.get_value ());
+ auto value = ExprStmtBuilder (ctx).build (field.get_value ());
handle_named_field (field, value);
}
void visit (HIR::StructExprFieldIndexValue &field) override
{
- auto value = ExprStmtBuilder (ctx).build (*field.get_value ());
+ auto value = ExprStmtBuilder (ctx).build (field.get_value ());
coercion_site (value,
struct_ty->get_field_at_index (field.get_tuple_index ())
->get_field_type ());
@@ -149,12 +149,11 @@ protected:
void visit (HIR::WhileLetLoopExpr &expr) override { rust_unreachable (); }
void visit (HIR::IfExpr &expr) override { rust_unreachable (); }
void visit (HIR::IfExprConseqElse &expr) override { rust_unreachable (); }
- void visit (HIR::IfLetExpr &expr) override { rust_unreachable (); }
- void visit (HIR::IfLetExprConseqElse &expr) override { rust_unreachable (); }
void visit (HIR::MatchExpr &expr) override { rust_unreachable (); }
void visit (HIR::AwaitExpr &expr) override { rust_unreachable (); }
void visit (HIR::AsyncBlockExpr &expr) override { rust_unreachable (); }
void visit (HIR::InlineAsm &expr) override { rust_unreachable (); }
+ void visit (HIR::LlvmInlineAsm &expr) override { rust_unreachable (); }
void visit (HIR::TypeParam &param) override { rust_unreachable (); }
void visit (HIR::ConstGenericParam &param) override { rust_unreachable (); }
void visit (HIR::LifetimeWhereClauseItem &item) override
@@ -252,10 +251,6 @@ protected:
void visit (HIR::ImplTraitType &type) override { rust_unreachable (); }
void visit (HIR::TraitObjectType &type) override { rust_unreachable (); }
void visit (HIR::ParenthesisedType &type) override { rust_unreachable (); }
- void visit (HIR::ImplTraitTypeOneBound &type) override
- {
- rust_unreachable ();
- }
void visit (HIR::TupleType &type) override { rust_unreachable (); }
void visit (HIR::NeverType &type) override { rust_unreachable (); }
void visit (HIR::RawPointerType &type) override { rust_unreachable (); }
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
index 63d3262..e5bdb46 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
@@ -49,7 +49,7 @@ public:
for (auto &param : function.get_function_params ())
handle_param (param);
- handle_body (*function.get_definition ());
+ handle_body (function.get_definition ());
auto region_hir_map
= map_region_to_hir (function.get_generic_params (), ctx.fn_free_regions);
@@ -118,14 +118,14 @@ private:
void handle_param (HIR::FunctionParam &param)
{
- auto param_type = lookup_type (*param.get_param_name ());
+ auto param_type = lookup_type (param.get_param_name ());
auto &pattern = param.get_param_name ();
- if (pattern->get_pattern_type () == HIR::Pattern::IDENTIFIER
- && !static_cast<HIR::IdentifierPattern &> (*pattern).get_is_ref ())
+ if (pattern.get_pattern_type () == HIR::Pattern::IDENTIFIER
+ && !static_cast<HIR::IdentifierPattern &> (pattern).get_is_ref ())
{
// Avoid useless temporary variable for parameter to look like MIR.
- translated = declare_variable (pattern->get_mappings ());
+ translated = declare_variable (pattern.get_mappings ());
ctx.arguments.push_back (translated);
}
else
@@ -133,11 +133,9 @@ private:
translated = ctx.place_db.add_temporary (param_type);
ctx.arguments.push_back (translated);
PatternBindingBuilder (ctx, translated, tl::nullopt)
- .go (*param.get_param_name ());
+ .go (param.get_param_name ());
}
- rust_assert (param.get_type () != nullptr);
-
// Set parameter place to use functions regions, not the fresh ones.
ctx.place_db[translated].regions
= bind_regions (Resolver::TypeCheckContext::get ()
@@ -159,7 +157,7 @@ private:
body.get_end_locus ());
}
auto return_location = body.has_expr ()
- ? body.get_final_expr ()->get_locus ()
+ ? body.get_final_expr ().get_locus ()
: body.get_end_locus ();
push_return (return_location);
}
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 1332ecf..32a4cd7 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
@@ -815,6 +815,7 @@ protected: // Subset helpers.
case TyTy::PLACEHOLDER:
case TyTy::INFER:
case TyTy::PARAM:
+ case TyTy::OPAQUE:
rust_unreachable ();
}
rust_unreachable ();
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-place.h b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
index a1621b7..dd9e672 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-place.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
@@ -204,6 +204,9 @@ template <typename I, typename T> class IndexVec
{
std::vector<T> internal_vector;
+ typedef decltype (std::declval<I> ().value) size_type;
+ static constexpr auto MAX_INDEX = std::numeric_limits<size_type>::max ();
+
public:
IndexVec () = default;
IndexVec (size_t size) { internal_vector.reserve (size); }
@@ -219,7 +222,11 @@ public:
internal_vector.emplace_back (std::forward<Args> (args)...);
}
- size_t size () const { return internal_vector.size (); }
+ size_type size () const
+ {
+ rust_assert (internal_vector.size () < MAX_INDEX);
+ return static_cast<size_type> (internal_vector.size ());
+ }
std::vector<T> &get_vector () { return internal_vector; }
};
@@ -418,8 +425,7 @@ public:
if (lookup != INVALID_PLACE)
return lookup;
- add_place ({Place::VARIABLE, id, {}, is_type_copy (tyty), tyty});
- return {places.size () - 1};
+ return add_place ({Place::VARIABLE, id, {}, is_type_copy (tyty), tyty});
};
template <typename FN> void for_each_path_from_root (PlaceId var, FN fn) const
@@ -485,6 +491,7 @@ private:
case TyTy::PROJECTION: // TODO: DUNNO
case TyTy::CLOSURE: // TODO: DUNNO
case TyTy::DYNAMIC: // TODO: dunno
+ case TyTy::OPAQUE:
return false;
}
rust_unreachable ();
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir.h b/gcc/rust/checks/errors/borrowck/rust-bir.h
index e90e508..8a5f7be 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir.h
@@ -35,6 +35,26 @@ using BasicBlocks = IndexVec<BasicBlockId, BasicBlock>;
class Statement;
class AbstractExpr;
+/** Unique identifier for a basic block in the BIR. */
+struct BasicBlockId
+{
+ uint32_t value;
+ // some overloads for comparision
+ bool operator== (const BasicBlockId &rhs) const { return value == rhs.value; }
+ bool operator!= (const BasicBlockId &rhs) const
+ {
+ return !(operator== (rhs));
+ }
+ bool operator< (const BasicBlockId &rhs) const { return value < rhs.value; }
+ bool operator> (const BasicBlockId &rhs) const { return value > rhs.value; }
+ bool operator<= (const BasicBlockId &rhs) const { return !(operator> (rhs)); }
+ bool operator>= (const BasicBlockId &rhs) const { return !(operator< (rhs)); }
+};
+
+static constexpr BasicBlockId INVALID_BB
+ = {std::numeric_limits<uint32_t>::max ()};
+static constexpr BasicBlockId ENTRY_BASIC_BLOCK = {0};
+
/**
* Top-level entity of the Borrow-checker IR (BIR).
* It represents a single function (method, closure, etc.), which is the
@@ -132,26 +152,6 @@ public:
WARN_UNUSED_RESULT location_t get_location () const { return location; }
};
-/** Unique identifier for a basic block in the BIR. */
-struct BasicBlockId
-{
- uint32_t value;
- // some overloads for comparision
- bool operator== (const BasicBlockId &rhs) const { return value == rhs.value; }
- bool operator!= (const BasicBlockId &rhs) const
- {
- return !(operator== (rhs));
- }
- bool operator< (const BasicBlockId &rhs) const { return value < rhs.value; }
- bool operator> (const BasicBlockId &rhs) const { return value > rhs.value; }
- bool operator<= (const BasicBlockId &rhs) const { return !(operator> (rhs)); }
- bool operator>= (const BasicBlockId &rhs) const { return !(operator< (rhs)); }
-};
-
-static constexpr BasicBlockId INVALID_BB
- = {std::numeric_limits<uint32_t>::max ()};
-static constexpr BasicBlockId ENTRY_BASIC_BLOCK = {0};
-
struct BasicBlock
{
// BIR "instructions".
diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
index 6c67706..adf1448 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
@@ -142,7 +142,7 @@ BorrowCheckerDiagnostics::get_statement (Polonius::Point point)
const BIR::Loan &
BorrowCheckerDiagnostics::get_loan (Polonius::Loan loan)
{
- return bir_function.place_db.get_loans ()[{loan}];
+ return bir_function.place_db.get_loans ()[{(uint32_t) loan}];
}
const HIR::LifetimeParam *
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index 51109d7..7cf0952 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -56,13 +56,13 @@ protected:
void visit (HIR::Function &function) override
{
functions.push_back (&function);
- function.get_definition ()->accept_vis (*this);
+ function.get_definition ().accept_vis (*this);
}
void visit (HIR::ClosureExpr &closure) override
{
closures.push_back (&closure);
- closure.get_expr ()->accept_vis (*this);
+ closure.get_expr ().accept_vis (*this);
}
// TODO: recurse for nested closures and functions.
@@ -119,12 +119,11 @@ public:
void visit (HIR::WhileLetLoopExpr &expr) override {}
void visit (HIR::IfExpr &expr) override {}
void visit (HIR::IfExprConseqElse &expr) override {}
- void visit (HIR::IfLetExpr &expr) override {}
- void visit (HIR::IfLetExprConseqElse &expr) override {}
void visit (HIR::MatchExpr &expr) override {}
void visit (HIR::AwaitExpr &expr) override {}
void visit (HIR::AsyncBlockExpr &expr) override {}
void visit (HIR::InlineAsm &expr) override {}
+ void visit (HIR::LlvmInlineAsm &expr) override {}
void visit (HIR::TypeParam &param) override {}
void visit (HIR::ConstGenericParam &param) override {}
void visit (HIR::LifetimeWhereClauseItem &item) override {}
@@ -182,7 +181,6 @@ public:
void visit (HIR::ImplTraitType &type) override {}
void visit (HIR::TraitObjectType &type) override {}
void visit (HIR::ParenthesisedType &type) override {}
- void visit (HIR::ImplTraitTypeOneBound &type) override {}
void visit (HIR::TupleType &type) override {}
void visit (HIR::NeverType &type) override {}
void visit (HIR::RawPointerType &type) override {}
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index 01d8ea5..2a10053 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -22,6 +22,7 @@
#include "rust-hir-stmt.h"
#include "rust-hir-item.h"
#include "rust-attribute-values.h"
+#include "rust-immutable-name-resolution-context.h"
namespace Rust {
namespace Privacy {
@@ -93,6 +94,14 @@ static bool
is_child_module (Analysis::Mappings &mappings, NodeId parent,
NodeId possible_child)
{
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ return nr_ctx.values.is_module_descendant (parent, possible_child);
+ }
+
auto children = mappings.lookup_module_children (parent);
if (!children)
@@ -118,8 +127,16 @@ PrivacyReporter::check_for_privacy_violation (const NodeId &use_id,
{
NodeId ref_node_id = UNKNOWN_NODEID;
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ if (auto id = nr_ctx.lookup (use_id))
+ ref_node_id = *id;
+ }
// FIXME: Don't assert here - we might be dealing with a type
- if (!resolver.lookup_resolved_name (use_id, &ref_node_id))
+ else if (!resolver.lookup_resolved_name (use_id, &ref_node_id))
resolver.lookup_resolved_type (use_id, &ref_node_id);
// FIXME: Assert here. For now, we return since this causes issues when
@@ -226,10 +243,12 @@ 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:
- return recursive_check (
- // FIXME: Can we use `resolve` here? Is that what we should do?
- static_cast<const TyTy::PlaceholderType *> (ty)->resolve ());
+ case TyTy::PLACEHOLDER: {
+ const auto p = static_cast<const TyTy::PlaceholderType *> (ty);
+ if (!p->can_resolve ())
+ return;
+ return recursive_check (p->resolve ());
+ }
case TyTy::PROJECTION:
return recursive_check (
static_cast<const TyTy::ProjectionType *> (ty)->get ());
@@ -252,22 +271,21 @@ PrivacyReporter::check_base_type_privacy (Analysis::NodeMapping &node_mappings,
// We shouldn't have inference types here, ever
case TyTy::INFER:
return;
+ case TyTy::OPAQUE:
+ return;
case TyTy::ERROR:
return;
}
}
void
-PrivacyReporter::check_type_privacy (const HIR::Type *type)
+PrivacyReporter::check_type_privacy (const HIR::Type &type)
{
- rust_assert (type);
-
TyTy::BaseType *lookup = nullptr;
- rust_assert (
- ty_ctx.lookup_type (type->get_mappings ().get_hirid (), &lookup));
+ rust_assert (ty_ctx.lookup_type (type.get_mappings ().get_hirid (), &lookup));
- auto node_mappings = type->get_mappings ();
- return check_base_type_privacy (node_mappings, lookup, type->get_locus ());
+ auto node_mappings = type.get_mappings ();
+ return check_base_type_privacy (node_mappings, lookup, type.get_locus ());
}
void
@@ -288,6 +306,10 @@ PrivacyReporter::visit (HIR::InlineAsm &)
{}
void
+PrivacyReporter::visit (HIR::LlvmInlineAsm &)
+{}
+
+void
PrivacyReporter::visit (HIR::TypePath &path)
{
check_for_privacy_violation (path.get_mappings ().get_nodeid (),
@@ -317,100 +339,98 @@ PrivacyReporter::visit (HIR::LiteralExpr &)
void
PrivacyReporter::visit (HIR::BorrowExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::DereferenceExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::ErrorPropagationExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::NegationExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::ArithmeticOrLogicalExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::ComparisonExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::LazyBooleanExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::TypeCastExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::AssignmentExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::CompoundAssignmentExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::GroupedExpr &expr)
{
- expr.get_expr_in_parens ()->accept_vis (*this);
+ expr.get_expr_in_parens ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::ArrayExpr &expr)
{
- HIR::ArrayElems &elements = *expr.get_internal_elements ();
+ HIR::ArrayElems &elements = expr.get_internal_elements ();
switch (elements.get_array_expr_type ())
{
case HIR::ArrayElems::ArrayExprType::VALUES: {
- HIR::ArrayElemsValues &elems
- = static_cast<HIR::ArrayElemsValues &> (elements);
+ auto &elems = static_cast<HIR::ArrayElemsValues &> (elements);
for (auto &value : elems.get_values ())
value->accept_vis (*this);
}
return;
case HIR::ArrayElems::ArrayExprType::COPIED:
- HIR::ArrayElemsCopied &elems
- = static_cast<HIR::ArrayElemsCopied &> (elements);
- elems.get_elem_to_copy ()->accept_vis (*this);
+ auto &elems = static_cast<HIR::ArrayElemsCopied &> (elements);
+ elems.get_elem_to_copy ().accept_vis (*this);
}
}
void
PrivacyReporter::visit (HIR::ArrayIndexExpr &expr)
{
- expr.get_array_expr ()->accept_vis (*this);
- expr.get_index_expr ()->accept_vis (*this);
+ expr.get_array_expr ().accept_vis (*this);
+ expr.get_index_expr ().accept_vis (*this);
}
void
@@ -423,7 +443,7 @@ PrivacyReporter::visit (HIR::TupleExpr &expr)
void
PrivacyReporter::visit (HIR::TupleIndexExpr &expr)
{
- expr.get_tuple_expr ()->accept_vis (*this);
+ expr.get_tuple_expr ().accept_vis (*this);
}
void
@@ -439,13 +459,13 @@ PrivacyReporter::visit (HIR::StructExprFieldIdentifier &)
void
PrivacyReporter::visit (HIR::StructExprFieldIdentifierValue &field)
{
- field.get_value ()->accept_vis (*this);
+ field.get_value ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::StructExprFieldIndexValue &field)
{
- field.get_value ()->accept_vis (*this);
+ field.get_value ().accept_vis (*this);
}
void
@@ -458,7 +478,7 @@ PrivacyReporter::visit (HIR::StructExprStructFields &expr)
void
PrivacyReporter::visit (HIR::CallExpr &expr)
{
- expr.get_fnexpr ()->accept_vis (*this);
+ expr.get_fnexpr ().accept_vis (*this);
for (auto &param : expr.get_arguments ())
param->accept_vis (*this);
@@ -467,7 +487,7 @@ PrivacyReporter::visit (HIR::CallExpr &expr)
void
PrivacyReporter::visit (HIR::MethodCallExpr &expr)
{
- expr.get_receiver ()->accept_vis (*this);
+ expr.get_receiver ().accept_vis (*this);
for (auto &param : expr.get_arguments ())
param->accept_vis (*this);
@@ -476,7 +496,7 @@ PrivacyReporter::visit (HIR::MethodCallExpr &expr)
void
PrivacyReporter::visit (HIR::FieldAccessExpr &expr)
{
- expr.get_receiver_expr ()->accept_vis (*this);
+ expr.get_receiver_expr ().accept_vis (*this);
// FIXME: We should also check if the field is public?
}
@@ -493,9 +513,8 @@ PrivacyReporter::visit (HIR::BlockExpr &expr)
for (auto &stmt : expr.get_statements ())
stmt->accept_vis (*this);
- auto &last_expr = expr.get_final_expr ();
- if (last_expr)
- last_expr->accept_vis (*this);
+ if (expr.has_final_expr ())
+ expr.get_final_expr ().accept_vis (*this);
}
void
@@ -505,28 +524,27 @@ PrivacyReporter::visit (HIR::ContinueExpr &)
void
PrivacyReporter::visit (HIR::BreakExpr &expr)
{
- auto &break_expr = expr.get_expr ();
- if (break_expr)
- break_expr->accept_vis (*this);
+ if (expr.has_break_expr ())
+ expr.get_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::RangeFromToExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::RangeFromExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::RangeToExpr &expr)
{
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
@@ -536,8 +554,8 @@ PrivacyReporter::visit (HIR::RangeFullExpr &)
void
PrivacyReporter::visit (HIR::RangeFromToInclExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
@@ -549,70 +567,55 @@ PrivacyReporter::visit (HIR::RangeToInclExpr &)
void
PrivacyReporter::visit (HIR::ReturnExpr &expr)
{
- if (expr.get_expr ())
- expr.get_expr ()->accept_vis (*this);
+ if (expr.has_expr ())
+ expr.get_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::UnsafeBlockExpr &expr)
{
- expr.get_block_expr ()->accept_vis (*this);
+ expr.get_block_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::LoopExpr &expr)
{
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::WhileLoopExpr &expr)
{
- expr.get_predicate_expr ()->accept_vis (*this);
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_predicate_expr ().accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::WhileLetLoopExpr &expr)
{
- expr.get_cond ()->accept_vis (*this);
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_cond ().accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::IfExpr &expr)
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::IfExprConseqElse &expr)
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
- expr.get_else_block ()->accept_vis (*this);
-}
-
-void
-PrivacyReporter::visit (HIR::IfLetExpr &)
-{
- // TODO: We need to visit the if_let_expr
- // TODO: We need to visit the block as well
-}
-
-void
-PrivacyReporter::visit (HIR::IfLetExprConseqElse &)
-{
- // TODO: We need to visit the if_let_expr
- // TODO: We need to visit the if_block as well
- // TODO: We need to visit the else_block as well
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
+ expr.get_else_block ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::MatchExpr &expr)
{
- expr.get_scrutinee_expr ()->accept_vis (*this);
+ expr.get_scrutinee_expr ().accept_vis (*this);
}
void
@@ -655,9 +658,9 @@ void
PrivacyReporter::visit (HIR::Function &function)
{
for (auto &param : function.get_function_params ())
- check_type_privacy (param.get_type ().get ());
+ check_type_privacy (param.get_type ());
- function.get_definition ()->accept_vis (*this);
+ function.get_definition ().accept_vis (*this);
}
void
@@ -714,14 +717,14 @@ void
PrivacyReporter::visit (HIR::ConstantItem &const_item)
{
// TODO: We need to visit the type
- const_item.get_expr ()->accept_vis (*this);
+ const_item.get_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::StaticItem &static_item)
{
// TODO: We need to visit the type
- static_item.get_expr ()->accept_vis (*this);
+ static_item.get_expr ().accept_vis (*this);
}
void
@@ -754,17 +757,17 @@ PrivacyReporter::visit (HIR::EmptyStmt &)
void
PrivacyReporter::visit (HIR::LetStmt &stmt)
{
- if (stmt.get_type ())
- check_type_privacy (stmt.get_type ().get ());
+ if (stmt.has_type ())
+ check_type_privacy (stmt.get_type ());
- if (stmt.get_init_expr ())
- stmt.get_init_expr ()->accept_vis (*this);
+ if (stmt.has_init_expr ())
+ stmt.get_init_expr ().accept_vis (*this);
}
void
PrivacyReporter::visit (HIR::ExprStmt &stmt)
{
- stmt.get_expr ()->accept_vis (*this);
+ stmt.get_expr ().accept_vis (*this);
}
} // namespace Privacy
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
index c4f94ab..7df2cf4 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
@@ -75,7 +75,7 @@ types
* @param type Reference to an explicit type used in a statement, expression
* or parameter
*/
- void check_type_privacy (const HIR::Type *type);
+ void check_type_privacy (const HIR::Type &type);
virtual void visit (HIR::StructExprFieldIdentifier &field);
virtual void visit (HIR::StructExprFieldIdentifierValue &field);
@@ -121,12 +121,11 @@ types
virtual void visit (HIR::WhileLetLoopExpr &expr);
virtual void visit (HIR::IfExpr &expr);
virtual void visit (HIR::IfExprConseqElse &expr);
- virtual void visit (HIR::IfLetExpr &expr);
- virtual void visit (HIR::IfLetExprConseqElse &expr);
virtual void visit (HIR::MatchExpr &expr);
virtual void visit (HIR::AwaitExpr &expr);
virtual void visit (HIR::AsyncBlockExpr &expr);
virtual void visit (HIR::InlineAsm &expr);
+ virtual void visit (HIR::LlvmInlineAsm &expr);
virtual void visit (HIR::EnumItemTuple &);
virtual void visit (HIR::EnumItemStruct &);
diff --git a/gcc/rust/checks/errors/privacy/rust-reachability.cc b/gcc/rust/checks/errors/privacy/rust-reachability.cc
index 9e0cb82..1e57674 100644
--- a/gcc/rust/checks/errors/privacy/rust-reachability.cc
+++ b/gcc/rust/checks/errors/privacy/rust-reachability.cc
@@ -132,7 +132,7 @@ ReachabilityVisitor::visit (HIR::StructStruct &struct_item)
{
for (auto &field : struct_item.get_fields ())
if (field.get_visibility ().is_public ())
- ctx.update_reachability (field.get_field_type ()->get_mappings (),
+ ctx.update_reachability (field.get_field_type ().get_mappings (),
struct_reach);
}
diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
index 464ce86..f0da745 100644
--- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
+++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
@@ -20,6 +20,10 @@
#include "rust-ast.h"
#include "rust-hir.h"
#include "rust-hir-item.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
namespace Rust {
namespace Privacy {
@@ -61,7 +65,22 @@ VisibilityResolver::resolve_module_path (const HIR::SimplePath &restriction,
"cannot use non-module path as privacy restrictor");
NodeId ref_node_id = UNKNOWN_NODEID;
- if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ if (auto id = nr_ctx.lookup (ast_node_id))
+ {
+ ref_node_id = *id;
+ }
+ else
+ {
+ invalid_path.emit ();
+ return false;
+ }
+ }
+ else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
{
invalid_path.emit ();
return false;
diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc b/gcc/rust/checks/errors/rust-ast-validation.cc
index 7938286..0f4bdeb 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -56,7 +56,7 @@ ASTValidation::visit (AST::LoopLabel &label)
void
ASTValidation::visit (AST::ConstantItem &const_item)
{
- if (!const_item.has_expr () && context.back () != Context::TRAIT_IMPL)
+ if (!const_item.has_expr () && ctx.peek () != Kind::TRAIT)
{
rust_error_at (const_item.get_locus (),
"associated constant in %<impl%> without body");
@@ -82,23 +82,19 @@ ASTValidation::visit (AST::Function &function)
"functions cannot be both %<const%> and %<async%>");
if (qualifiers.is_const ()
- && (context.back () == Context::TRAIT_IMPL
- || context.back () == Context::TRAIT))
+ && (ctx.peek () == Kind::TRAIT_IMPL || ctx.peek () == Kind::TRAIT))
rust_error_at (function.get_locus (), ErrorCode::E0379,
"functions in traits cannot be declared %<const%>");
// may change soon
if (qualifiers.is_async ()
- && (context.back () == Context::TRAIT_IMPL
- || context.back () == Context::TRAIT))
+ && (ctx.peek () == Kind::TRAIT_IMPL || ctx.peek () == Kind::TRAIT))
rust_error_at (function.get_locus (), ErrorCode::E0706,
"functions in traits cannot be declared %<async%>");
// if not an associated function but has a self parameter
- if (context.back () != Context::TRAIT
- && context.back () != Context::TRAIT_IMPL
- && context.back () != Context::INHERENT_IMPL
- && function.has_self_param ())
+ if (ctx.peek () != Kind::TRAIT && ctx.peek () != Kind::TRAIT_IMPL
+ && ctx.peek () != Kind::INHERENT_IMPL && function.has_self_param ())
rust_error_at (
function.get_self_param ().get_locus (),
"%<self%> parameter is only allowed in associated functions");
@@ -140,11 +136,11 @@ ASTValidation::visit (AST::Function &function)
{
if (!function.has_body ())
{
- if (context.back () == Context::INHERENT_IMPL
- || context.back () == Context::TRAIT_IMPL)
+ if (ctx.peek () == Kind::INHERENT_IMPL
+ || ctx.peek () == Kind::TRAIT_IMPL)
rust_error_at (function.get_locus (),
"associated function in %<impl%> without body");
- else if (context.back () != Context::TRAIT)
+ else if (ctx.peek () != Kind::TRAIT)
rust_error_at (function.get_locus (),
"free function without a body");
}
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index 84c09dd..3716ea5 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -161,72 +161,72 @@ ConstChecker::visit (LiteralExpr &)
void
ConstChecker::visit (BorrowExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
ConstChecker::visit (DereferenceExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
ConstChecker::visit (ErrorPropagationExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
ConstChecker::visit (NegationExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
ConstChecker::visit (ArithmeticOrLogicalExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
ConstChecker::visit (ComparisonExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
ConstChecker::visit (LazyBooleanExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
ConstChecker::visit (TypeCastExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
ConstChecker::visit (AssignmentExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
ConstChecker::visit (CompoundAssignmentExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
ConstChecker::visit (GroupedExpr &expr)
{
- expr.get_expr_in_parens ()->accept_vis (*this);
+ expr.get_expr_in_parens ().accept_vis (*this);
}
void
@@ -239,11 +239,11 @@ ConstChecker::visit (ArrayElemsValues &elems)
void
ConstChecker::visit (ArrayElemsCopied &elems)
{
- elems.get_elem_to_copy ()->accept_vis (*this);
+ elems.get_elem_to_copy ().accept_vis (*this);
const_context.enter (elems.get_mappings ().get_hirid ());
- elems.get_num_copies_expr ()->accept_vis (*this);
+ elems.get_num_copies_expr ().accept_vis (*this);
const_context.exit ();
}
@@ -251,14 +251,14 @@ ConstChecker::visit (ArrayElemsCopied &elems)
void
ConstChecker::visit (ArrayExpr &expr)
{
- expr.get_internal_elements ()->accept_vis (*this);
+ expr.get_internal_elements ().accept_vis (*this);
}
void
ConstChecker::visit (ArrayIndexExpr &expr)
{
- expr.get_array_expr ()->accept_vis (*this);
- expr.get_index_expr ()->accept_vis (*this);
+ expr.get_array_expr ().accept_vis (*this);
+ expr.get_index_expr ().accept_vis (*this);
}
void
@@ -271,7 +271,7 @@ ConstChecker::visit (TupleExpr &expr)
void
ConstChecker::visit (TupleIndexExpr &expr)
{
- expr.get_tuple_expr ()->accept_vis (*this);
+ expr.get_tuple_expr ().accept_vis (*this);
}
void
@@ -285,13 +285,13 @@ ConstChecker::visit (StructExprFieldIdentifier &)
void
ConstChecker::visit (StructExprFieldIdentifierValue &field)
{
- field.get_value ()->accept_vis (*this);
+ field.get_value ().accept_vis (*this);
}
void
ConstChecker::visit (StructExprFieldIndexValue &field)
{
- field.get_value ()->accept_vis (*this);
+ field.get_value ().accept_vis (*this);
}
void
@@ -352,10 +352,10 @@ ConstChecker::check_function_call (HirId fn_id, location_t locus)
void
ConstChecker::visit (CallExpr &expr)
{
- if (!expr.get_fnexpr ())
+ if (!expr.has_fnexpr ())
return;
- NodeId ast_node_id = expr.get_fnexpr ()->get_mappings ().get_nodeid ();
+ NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid ();
NodeId ref_node_id;
if (flag_name_resolution_2_0)
@@ -388,7 +388,7 @@ ConstChecker::visit (CallExpr &expr)
void
ConstChecker::visit (MethodCallExpr &expr)
{
- expr.get_receiver ()->accept_vis (*this);
+ expr.get_receiver ().accept_vis (*this);
for (auto &arg : expr.get_arguments ())
arg->accept_vis (*this);
@@ -397,13 +397,13 @@ ConstChecker::visit (MethodCallExpr &expr)
void
ConstChecker::visit (FieldAccessExpr &expr)
{
- expr.get_receiver_expr ()->accept_vis (*this);
+ expr.get_receiver_expr ().accept_vis (*this);
}
void
ConstChecker::visit (ClosureExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
@@ -413,7 +413,7 @@ ConstChecker::visit (BlockExpr &expr)
stmt->accept_vis (*this);
if (expr.has_expr ())
- expr.get_final_expr ()->accept_vis (*this);
+ expr.get_final_expr ().accept_vis (*this);
}
void
@@ -424,26 +424,26 @@ void
ConstChecker::visit (BreakExpr &expr)
{
if (expr.has_break_expr ())
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
ConstChecker::visit (RangeFromToExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
ConstChecker::visit (RangeFromExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
}
void
ConstChecker::visit (RangeToExpr &expr)
{
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
@@ -453,8 +453,8 @@ ConstChecker::visit (RangeFullExpr &)
void
ConstChecker::visit (RangeFromToInclExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
@@ -467,73 +467,57 @@ void
ConstChecker::visit (ReturnExpr &expr)
{
if (expr.has_return_expr ())
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
ConstChecker::visit (UnsafeBlockExpr &expr)
{
- expr.get_block_expr ()->accept_vis (*this);
+ expr.get_block_expr ().accept_vis (*this);
}
void
ConstChecker::visit (LoopExpr &expr)
{
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
ConstChecker::visit (WhileLoopExpr &expr)
{
- expr.get_predicate_expr ()->accept_vis (*this);
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_predicate_expr ().accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
ConstChecker::visit (WhileLetLoopExpr &expr)
{
- expr.get_cond ()->accept_vis (*this);
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_cond ().accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
ConstChecker::visit (IfExpr &expr)
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
}
void
ConstChecker::visit (IfExprConseqElse &expr)
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
- expr.get_else_block ()->accept_vis (*this);
-}
-
-void
-ConstChecker::visit (IfLetExpr &expr)
-{
- expr.get_scrutinee_expr ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
-}
-
-void
-ConstChecker::visit (IfLetExprConseqElse &expr)
-{
- expr.get_scrutinee_expr ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
-
- // TODO: Visit else expression
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
+ expr.get_else_block ().accept_vis (*this);
}
void
ConstChecker::visit (MatchExpr &expr)
{
- expr.get_scrutinee_expr ()->accept_vis (*this);
+ expr.get_scrutinee_expr ().accept_vis (*this);
for (auto &match_arm : expr.get_match_cases ())
- match_arm.get_expr ()->accept_vis (*this);
+ match_arm.get_expr ().accept_vis (*this);
}
void
@@ -553,6 +537,10 @@ ConstChecker::visit (InlineAsm &)
{}
void
+ConstChecker::visit (LlvmInlineAsm &)
+{}
+
+void
ConstChecker::visit (TypeParam &)
{}
@@ -606,9 +594,9 @@ ConstChecker::visit (Function &function)
ConstGenericCtx::Function);
for (auto &param : function.get_function_params ())
- param.get_type ()->accept_vis (*this);
+ param.get_type ().accept_vis (*this);
- function.get_definition ()->accept_vis (*this);
+ function.get_definition ().accept_vis (*this);
if (const_fn)
const_context.exit ();
@@ -652,7 +640,7 @@ ConstChecker::visit (EnumItemDiscriminant &item)
{
const_context.enter (item.get_mappings ().get_hirid ());
- item.get_discriminant_expression ()->accept_vis (*this);
+ item.get_discriminant_expression ().accept_vis (*this);
const_context.exit ();
}
@@ -662,6 +650,9 @@ ConstChecker::visit (Enum &enum_item)
{
check_default_const_generics (enum_item.get_generic_params (),
ConstGenericCtx::Enum);
+
+ for (auto &item : enum_item.get_variants ())
+ item->accept_vis (*this);
}
void
@@ -676,7 +667,7 @@ ConstChecker::visit (ConstantItem &const_item)
{
const_context.enter (const_item.get_mappings ().get_hirid ());
- const_item.get_expr ()->accept_vis (*this);
+ const_item.get_expr ().accept_vis (*this);
const_context.exit ();
}
@@ -686,7 +677,7 @@ ConstChecker::visit (StaticItem &static_item)
{
const_context.enter (static_item.get_mappings ().get_hirid ());
- static_item.get_expr ()->accept_vis (*this);
+ static_item.get_expr ().accept_vis (*this);
const_context.exit ();
}
@@ -694,15 +685,15 @@ ConstChecker::visit (StaticItem &static_item)
void
ConstChecker::visit (TraitItemFunc &item)
{
- if (item.has_block_defined ())
- item.get_block_expr ()->accept_vis (*this);
+ if (item.has_definition ())
+ item.get_block_expr ().accept_vis (*this);
}
void
ConstChecker::visit (TraitItemConst &item)
{
if (item.has_expr ())
- item.get_expr ()->accept_vis (*this);
+ item.get_expr ().accept_vis (*this);
}
void
@@ -837,13 +828,13 @@ void
ConstChecker::visit (LetStmt &stmt)
{
if (stmt.has_init_expr ())
- stmt.get_init_expr ()->accept_vis (*this);
+ stmt.get_init_expr ().accept_vis (*this);
}
void
ConstChecker::visit (ExprStmt &stmt)
{
- stmt.get_expr ()->accept_vis (*this);
+ stmt.get_expr ().accept_vis (*this);
}
void
@@ -863,10 +854,6 @@ ConstChecker::visit (ParenthesisedType &)
{}
void
-ConstChecker::visit (ImplTraitTypeOneBound &)
-{}
-
-void
ConstChecker::visit (TupleType &)
{}
@@ -891,7 +878,7 @@ ConstChecker::visit (ArrayType &type)
{
const_context.enter (type.get_mappings ().get_hirid ());
- type.get_size_expr ()->accept_vis (*this);
+ type.get_size_expr ().accept_vis (*this);
const_context.exit ();
}
diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h
index 8890761..b954330 100644
--- a/gcc/rust/checks/errors/rust-const-checker.h
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -128,12 +128,11 @@ private:
virtual void visit (WhileLetLoopExpr &expr) override;
virtual void visit (IfExpr &expr) override;
virtual void visit (IfExprConseqElse &expr) override;
- virtual void visit (IfLetExpr &expr) override;
- virtual void visit (IfLetExprConseqElse &expr) override;
virtual void visit (MatchExpr &expr) override;
virtual void visit (AwaitExpr &expr) override;
virtual void visit (AsyncBlockExpr &expr) override;
virtual void visit (InlineAsm &expr) override;
+ virtual void visit (LlvmInlineAsm &expr) override;
virtual void visit (TypeParam &param) override;
virtual void visit (ConstGenericParam &param) override;
@@ -193,7 +192,6 @@ private:
virtual void visit (ImplTraitType &type) override;
virtual void visit (TraitObjectType &type) override;
virtual void visit (ParenthesisedType &type) override;
- virtual void visit (ImplTraitTypeOneBound &type) override;
virtual void visit (TupleType &type) override;
virtual void visit (NeverType &type) override;
virtual void visit (RawPointerType &type) override;
diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc b/gcc/rust/checks/errors/rust-feature-gate.cc
index f3daa61..44007f9 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/rust-feature-gate.cc
@@ -40,6 +40,13 @@ FeatureGate::visit (AST::Crate &crate)
{
if (attr.get_path ().as_string () == "feature")
{
+ // check for empty feature, such as `#![feature], this is an error
+ if (attr.empty_input ())
+ {
+ rust_error_at (attr.get_locus (), ErrorCode::E0556,
+ "malformed %<feature%> attribute input");
+ continue;
+ }
const auto &attr_input = attr.get_attr_input ();
auto type = attr_input.get_attr_input_type ();
if (type == AST::AttrInput::AttrInputType::TOKEN_TREE)
diff --git a/gcc/rust/checks/errors/rust-feature.cc b/gcc/rust/checks/errors/rust-feature.cc
index 25af46c..441a1b2 100644
--- a/gcc/rust/checks/errors/rust-feature.cc
+++ b/gcc/rust/checks/errors/rust-feature.cc
@@ -55,6 +55,9 @@ Feature::create (Feature::Name f)
"1.11.0", 37854);
case Feature::Name::PRELUDE_IMPORT:
return Feature (f, Feature::State::ACTIVE, "prelude_import", "1.0.0");
+ case Feature::Name::MIN_SPECIALIZATION:
+ return Feature (f, Feature::State::ACTIVE, "min_specialization",
+ "1.0.0" /* FIXME: What version here? */, 31844);
case Feature::Name::AUTO_TRAITS:
return Feature (f, Feature::State::ACTIVE, "optin_builtin_traits",
"1.0.0", 13231);
@@ -80,6 +83,7 @@ const std::map<std::string, Feature::Name> Feature::name_hash_map = {
{"raw_ref_op", Feature::Name::RAW_REF_OP},
{"exclusive_range_pattern", Feature::Name::EXCLUSIVE_RANGE_PATTERN},
{"prelude_import", Feature::Name::PRELUDE_IMPORT},
+ {"min_specialization", Feature::Name::MIN_SPECIALIZATION},
}; // namespace Rust
tl::optional<Feature::Name>
diff --git a/gcc/rust/checks/errors/rust-feature.h b/gcc/rust/checks/errors/rust-feature.h
index e2082c5..e7cb0af 100644
--- a/gcc/rust/checks/errors/rust-feature.h
+++ b/gcc/rust/checks/errors/rust-feature.h
@@ -19,7 +19,7 @@
#ifndef RUST_FEATURE_H
#define RUST_FEATURE_H
-#include "rust-session-manager.h"
+#include "rust-edition.h"
#include "optional.h"
namespace Rust {
@@ -51,6 +51,7 @@ public:
RAW_REF_OP,
EXCLUSIVE_RANGE_PATTERN,
PRELUDE_IMPORT,
+ MIN_SPECIALIZATION,
};
const std::string &as_string () { return m_name_str; }
@@ -66,7 +67,7 @@ private:
Feature (Name name, State state, const char *name_str,
const char *rustc_since,
tl::optional<unsigned> issue_number = tl::nullopt,
- const tl::optional<CompileOptions::Edition> &edition = tl::nullopt,
+ const tl::optional<Edition> &edition = tl::nullopt,
const char *description = "")
: m_state (state), m_name (name), m_name_str (name_str),
m_rustc_since (rustc_since), m_issue (issue_number), edition (edition),
@@ -78,7 +79,7 @@ private:
std::string m_name_str;
std::string m_rustc_since;
tl::optional<unsigned> m_issue;
- tl::optional<CompileOptions::Edition> edition;
+ tl::optional<Edition> edition;
std::string m_description; // TODO: Switch to optional?
static const std::map<std::string, Name> name_hash_map;
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index f46f429..648bc07 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -92,72 +92,72 @@ PatternChecker::visit (LiteralExpr &)
void
PatternChecker::visit (BorrowExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PatternChecker::visit (DereferenceExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PatternChecker::visit (ErrorPropagationExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PatternChecker::visit (NegationExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PatternChecker::visit (ArithmeticOrLogicalExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PatternChecker::visit (ComparisonExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PatternChecker::visit (LazyBooleanExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PatternChecker::visit (TypeCastExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PatternChecker::visit (AssignmentExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PatternChecker::visit (CompoundAssignmentExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
PatternChecker::visit (GroupedExpr &expr)
{
- expr.get_expr_in_parens ()->accept_vis (*this);
+ expr.get_expr_in_parens ().accept_vis (*this);
}
void
@@ -170,20 +170,20 @@ PatternChecker::visit (ArrayElemsValues &elems)
void
PatternChecker::visit (ArrayElemsCopied &elems)
{
- elems.get_elem_to_copy ()->accept_vis (*this);
+ elems.get_elem_to_copy ().accept_vis (*this);
}
void
PatternChecker::visit (ArrayExpr &expr)
{
- expr.get_internal_elements ()->accept_vis (*this);
+ expr.get_internal_elements ().accept_vis (*this);
}
void
PatternChecker::visit (ArrayIndexExpr &expr)
{
- expr.get_array_expr ()->accept_vis (*this);
- expr.get_index_expr ()->accept_vis (*this);
+ expr.get_array_expr ().accept_vis (*this);
+ expr.get_index_expr ().accept_vis (*this);
}
void
@@ -196,7 +196,7 @@ PatternChecker::visit (TupleExpr &expr)
void
PatternChecker::visit (TupleIndexExpr &expr)
{
- expr.get_tuple_expr ()->accept_vis (*this);
+ expr.get_tuple_expr ().accept_vis (*this);
}
void
@@ -210,13 +210,13 @@ PatternChecker::visit (StructExprFieldIdentifier &)
void
PatternChecker::visit (StructExprFieldIdentifierValue &field)
{
- field.get_value ()->accept_vis (*this);
+ field.get_value ().accept_vis (*this);
}
void
PatternChecker::visit (StructExprFieldIndexValue &field)
{
- field.get_value ()->accept_vis (*this);
+ field.get_value ().accept_vis (*this);
}
void
@@ -233,10 +233,10 @@ PatternChecker::visit (StructExprStructBase &)
void
PatternChecker::visit (CallExpr &expr)
{
- if (!expr.get_fnexpr ())
+ if (!expr.has_fnexpr ())
return;
- NodeId ast_node_id = expr.get_fnexpr ()->get_mappings ().get_nodeid ();
+ NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid ();
NodeId ref_node_id;
if (flag_name_resolution_2_0)
{
@@ -266,7 +266,7 @@ PatternChecker::visit (CallExpr &expr)
void
PatternChecker::visit (MethodCallExpr &expr)
{
- expr.get_receiver ()->accept_vis (*this);
+ expr.get_receiver ().accept_vis (*this);
for (auto &arg : expr.get_arguments ())
arg->accept_vis (*this);
@@ -275,13 +275,13 @@ PatternChecker::visit (MethodCallExpr &expr)
void
PatternChecker::visit (FieldAccessExpr &expr)
{
- expr.get_receiver_expr ()->accept_vis (*this);
+ expr.get_receiver_expr ().accept_vis (*this);
}
void
PatternChecker::visit (ClosureExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
@@ -291,7 +291,7 @@ PatternChecker::visit (BlockExpr &expr)
stmt->accept_vis (*this);
if (expr.has_expr ())
- expr.get_final_expr ()->accept_vis (*this);
+ expr.get_final_expr ().accept_vis (*this);
}
void
@@ -302,26 +302,26 @@ void
PatternChecker::visit (BreakExpr &expr)
{
if (expr.has_break_expr ())
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PatternChecker::visit (RangeFromToExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
PatternChecker::visit (RangeFromExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
}
void
PatternChecker::visit (RangeToExpr &expr)
{
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
@@ -331,92 +331,76 @@ PatternChecker::visit (RangeFullExpr &)
void
PatternChecker::visit (RangeFromToInclExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
PatternChecker::visit (RangeToInclExpr &expr)
{
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
PatternChecker::visit (ReturnExpr &expr)
{
if (expr.has_return_expr ())
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
PatternChecker::visit (UnsafeBlockExpr &expr)
{
- expr.get_block_expr ()->accept_vis (*this);
+ expr.get_block_expr ().accept_vis (*this);
}
void
PatternChecker::visit (LoopExpr &expr)
{
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
PatternChecker::visit (WhileLoopExpr &expr)
{
- expr.get_predicate_expr ()->accept_vis (*this);
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_predicate_expr ().accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
PatternChecker::visit (WhileLetLoopExpr &expr)
{
- expr.get_cond ()->accept_vis (*this);
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_cond ().accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
PatternChecker::visit (IfExpr &expr)
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
}
void
PatternChecker::visit (IfExprConseqElse &expr)
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
- expr.get_else_block ()->accept_vis (*this);
-}
-
-void
-PatternChecker::visit (IfLetExpr &expr)
-{
- expr.get_scrutinee_expr ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
-}
-
-void
-PatternChecker::visit (IfLetExprConseqElse &expr)
-{
- expr.get_scrutinee_expr ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
-
- expr.get_else_block ()->accept_vis (*this);
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
+ expr.get_else_block ().accept_vis (*this);
}
void
PatternChecker::visit (MatchExpr &expr)
{
- expr.get_scrutinee_expr ()->accept_vis (*this);
+ expr.get_scrutinee_expr ().accept_vis (*this);
for (auto &match_arm : expr.get_match_cases ())
- match_arm.get_expr ()->accept_vis (*this);
+ match_arm.get_expr ().accept_vis (*this);
// match expressions are only an entrypoint
TyTy::BaseType *scrutinee_ty;
bool ok = tyctx.lookup_type (
- expr.get_scrutinee_expr ()->get_mappings ().get_hirid (), &scrutinee_ty);
+ expr.get_scrutinee_expr ().get_mappings ().get_hirid (), &scrutinee_ty);
rust_assert (ok);
check_match_usefulness (&tyctx, scrutinee_ty, expr);
@@ -439,6 +423,10 @@ PatternChecker::visit (InlineAsm &expr)
{}
void
+PatternChecker::visit (LlvmInlineAsm &expr)
+{}
+
+void
PatternChecker::visit (TypeParam &)
{}
@@ -484,7 +472,7 @@ PatternChecker::visit (UseDeclaration &)
void
PatternChecker::visit (Function &function)
{
- function.get_definition ()->accept_vis (*this);
+ function.get_definition ().accept_vis (*this);
}
void
@@ -526,27 +514,27 @@ PatternChecker::visit (Union &)
void
PatternChecker::visit (ConstantItem &const_item)
{
- const_item.get_expr ()->accept_vis (*this);
+ const_item.get_expr ().accept_vis (*this);
}
void
PatternChecker::visit (StaticItem &static_item)
{
- static_item.get_expr ()->accept_vis (*this);
+ static_item.get_expr ().accept_vis (*this);
}
void
PatternChecker::visit (TraitItemFunc &item)
{
- if (item.has_block_defined ())
- item.get_block_expr ()->accept_vis (*this);
+ if (item.has_definition ())
+ item.get_block_expr ().accept_vis (*this);
}
void
PatternChecker::visit (TraitItemConst &item)
{
if (item.has_expr ())
- item.get_expr ()->accept_vis (*this);
+ item.get_expr ().accept_vis (*this);
}
void
@@ -675,13 +663,13 @@ void
PatternChecker::visit (LetStmt &stmt)
{
if (stmt.has_init_expr ())
- stmt.get_init_expr ()->accept_vis (*this);
+ stmt.get_init_expr ().accept_vis (*this);
}
void
PatternChecker::visit (ExprStmt &stmt)
{
- stmt.get_expr ()->accept_vis (*this);
+ stmt.get_expr ().accept_vis (*this);
}
void
@@ -701,10 +689,6 @@ PatternChecker::visit (ParenthesisedType &)
{}
void
-PatternChecker::visit (ImplTraitTypeOneBound &)
-{}
-
-void
PatternChecker::visit (TupleType &)
{}
@@ -1177,33 +1161,34 @@ WitnessMatrix::extend (const WitnessMatrix &other)
// forward declarations
static DeconstructedPat
-lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
+lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern &pattern,
TyTy::BaseType *scrutinee_ty);
static DeconstructedPat
lower_tuple_pattern (Resolver::TypeCheckContext *ctx,
- HIR::TupleStructPattern *pattern,
+ HIR::TupleStructPattern &pattern,
TyTy::VariantDef *variant, Constructor &ctor)
{
int arity = variant->get_fields ().size ();
- HIR::TupleStructItems *elems = pattern->get_items ().get ();
+ HIR::TupleStructItems &elems = pattern.get_items ();
std::vector<DeconstructedPat> fields;
- switch (elems->get_item_type ())
+ switch (elems.get_item_type ())
{
case HIR::TupleStructItems::ItemType::MULTIPLE: {
- HIR::TupleStructItemsNoRange *multiple
- = static_cast<HIR::TupleStructItemsNoRange *> (elems);
+ HIR::TupleStructItemsNoRange &multiple
+ = static_cast<HIR::TupleStructItemsNoRange &> (elems);
rust_assert (variant->get_fields ().size ()
- == multiple->get_patterns ().size ());
- for (size_t i = 0; i < multiple->get_patterns ().size (); i++)
+ == multiple.get_patterns ().size ());
+
+ for (size_t i = 0; i < multiple.get_patterns ().size (); i++)
{
fields.push_back (
- lower_pattern (ctx, multiple->get_patterns ().at (i).get (),
+ lower_pattern (ctx, *multiple.get_patterns ().at (i),
variant->get_fields ().at (i)->get_field_type ()));
}
- return DeconstructedPat (ctor, arity, fields, pattern->get_locus ());
+ return DeconstructedPat (ctor, arity, fields, pattern.get_locus ());
}
break;
case HIR::TupleStructItems::ItemType::RANGED: {
@@ -1219,7 +1204,7 @@ lower_tuple_pattern (Resolver::TypeCheckContext *ctx,
static DeconstructedPat
lower_struct_pattern (Resolver::TypeCheckContext *ctx,
- HIR::StructPattern *pattern, TyTy::VariantDef *variant,
+ HIR::StructPattern &pattern, TyTy::VariantDef *variant,
Constructor ctor)
{
int arity = variant->get_fields ().size ();
@@ -1227,7 +1212,7 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
// Initialize all field patterns to wildcard.
std::vector<DeconstructedPat> fields
= std::vector<DeconstructedPat> (arity, DeconstructedPat::make_wildcard (
- pattern->get_locus ()));
+ pattern.get_locus ()));
std::map<std::string, int> field_map;
for (int i = 0; i < arity; i++)
@@ -1237,7 +1222,7 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
}
// Fill in the fields with the present patterns.
- HIR::StructPatternElements elems = pattern->get_struct_pattern_elems ();
+ HIR::StructPatternElements elems = pattern.get_struct_pattern_elems ();
for (auto &elem : elems.get_struct_pattern_fields ())
{
switch (elem->get_item_type ())
@@ -1248,7 +1233,7 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
int field_idx
= field_map.at (ident->get_identifier ().as_string ());
fields.at (field_idx)
- = DeconstructedPat::make_wildcard (pattern->get_locus ());
+ = DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::StructPatternField::ItemType::IDENT_PAT: {
@@ -1257,7 +1242,7 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
int field_idx
= field_map.at (ident_pat->get_identifier ().as_string ());
fields.at (field_idx) = lower_pattern (
- ctx, ident_pat->get_pattern ().get (),
+ ctx, ident_pat->get_pattern (),
variant->get_fields ().at (field_idx)->get_field_type ());
}
break;
@@ -1272,19 +1257,19 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
}
}
- return DeconstructedPat{ctor, arity, fields, pattern->get_locus ()};
+ return DeconstructedPat{ctor, arity, fields, pattern.get_locus ()};
};
static DeconstructedPat
-lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
+lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern &pattern,
TyTy::BaseType *scrutinee_ty)
{
- HIR::Pattern::PatternType pat_type = pattern->get_pattern_type ();
+ HIR::Pattern::PatternType pat_type = pattern.get_pattern_type ();
switch (pat_type)
{
case HIR::Pattern::PatternType::WILDCARD:
case HIR::Pattern::PatternType::IDENTIFIER: {
- return DeconstructedPat::make_wildcard (pattern->get_locus ());
+ return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::Pattern::PatternType::PATH: {
@@ -1292,12 +1277,12 @@ lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
// structs
// https://doc.rust-lang.org/reference/patterns.html#path-patterns
// unimplemented. Treat this pattern as wildcard for now.
- return DeconstructedPat::make_wildcard (pattern->get_locus ());
+ return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::Pattern::PatternType::REFERENCE: {
// TODO: unimplemented. Treat this pattern as wildcard for now.
- return DeconstructedPat::make_wildcard (pattern->get_locus ());
+ return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::Pattern::PatternType::STRUCT:
@@ -1305,15 +1290,15 @@ lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
HirId path_id = UNKNOWN_HIRID;
if (pat_type == HIR::Pattern::PatternType::STRUCT)
{
- HIR::StructPattern *struct_pattern
- = static_cast<HIR::StructPattern *> (pattern);
- path_id = struct_pattern->get_path ().get_mappings ().get_hirid ();
+ HIR::StructPattern &struct_pattern
+ = static_cast<HIR::StructPattern &> (pattern);
+ path_id = struct_pattern.get_path ().get_mappings ().get_hirid ();
}
else
{
- HIR::TupleStructPattern *tuple_pattern
- = static_cast<HIR::TupleStructPattern *> (pattern);
- path_id = tuple_pattern->get_path ().get_mappings ().get_hirid ();
+ HIR::TupleStructPattern &tuple_pattern
+ = static_cast<HIR::TupleStructPattern &> (pattern);
+ path_id = tuple_pattern.get_path ().get_mappings ().get_hirid ();
}
rust_assert (scrutinee_ty->get_kind () == TyTy::TypeKind::ADT);
@@ -1346,46 +1331,46 @@ lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
if (pat_type == HIR::Pattern::PatternType::STRUCT)
{
- HIR::StructPattern *struct_pattern
- = static_cast<HIR::StructPattern *> (pattern);
+ HIR::StructPattern &struct_pattern
+ = static_cast<HIR::StructPattern &> (pattern);
return lower_struct_pattern (ctx, struct_pattern, variant, ctor);
}
else
{
- HIR::TupleStructPattern *tuple_pattern
- = static_cast<HIR::TupleStructPattern *> (pattern);
+ HIR::TupleStructPattern &tuple_pattern
+ = static_cast<HIR::TupleStructPattern &> (pattern);
return lower_tuple_pattern (ctx, tuple_pattern, variant, ctor);
}
}
break;
case HIR::Pattern::PatternType::TUPLE: {
// TODO: unimplemented. Treat this pattern as wildcard for now.
- return DeconstructedPat::make_wildcard (pattern->get_locus ());
+ return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::Pattern::PatternType::SLICE: {
// TODO: unimplemented. Treat this pattern as wildcard for now.
- return DeconstructedPat::make_wildcard (pattern->get_locus ());
+ return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::Pattern::PatternType::ALT: {
// TODO: unimplemented. Treat this pattern as wildcard for now.
- return DeconstructedPat::make_wildcard (pattern->get_locus ());
+ return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::Pattern::PatternType::LITERAL: {
// TODO: unimplemented. Treat this pattern as wildcard for now.
- return DeconstructedPat::make_wildcard (pattern->get_locus ());
+ return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::Pattern::PatternType::RANGE: {
// TODO: unimplemented. Treat this pattern as wildcard for now.
- return DeconstructedPat::make_wildcard (pattern->get_locus ());
+ return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::Pattern::PatternType::GROUPED: {
// TODO: unimplemented. Treat this pattern as wildcard for now.
- return DeconstructedPat::make_wildcard (pattern->get_locus ());
+ return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
default: {
@@ -1401,8 +1386,7 @@ lower_arm (Resolver::TypeCheckContext *ctx, HIR::MatchCase &arm,
rust_assert (arm.get_arm ().get_patterns ().size () > 0);
DeconstructedPat pat
- = lower_pattern (ctx, arm.get_arm ().get_patterns ().at (0).get (),
- scrutinee_ty);
+ = lower_pattern (ctx, *arm.get_arm ().get_patterns ().at (0), scrutinee_ty);
return MatchArm (pat, arm.get_arm ().has_match_arm_guard ());
}
@@ -1511,8 +1495,9 @@ emit_exhaustiveness_error (Resolver::TypeCheckContext *ctx,
HIR::MatchExpr &expr, WitnessMatrix &witness)
{
TyTy::BaseType *scrutinee_ty;
- bool ok = ctx->lookup_type (
- expr.get_scrutinee_expr ()->get_mappings ().get_hirid (), &scrutinee_ty);
+ bool ok
+ = ctx->lookup_type (expr.get_scrutinee_expr ().get_mappings ().get_hirid (),
+ &scrutinee_ty);
rust_assert (ok);
if (!witness.empty ())
@@ -1530,7 +1515,7 @@ emit_exhaustiveness_error (Resolver::TypeCheckContext *ctx,
if (i != witness.get_stacks ().size () - 1)
buf << " and ";
}
- rust_error_at (expr.get_scrutinee_expr ()->get_locus (),
+ rust_error_at (expr.get_scrutinee_expr ().get_locus (),
"non-exhaustive patterns: %s not covered",
buf.str ().c_str ());
}
@@ -1545,6 +1530,9 @@ void
check_match_usefulness (Resolver::TypeCheckContext *ctx,
TyTy::BaseType *scrutinee_ty, HIR::MatchExpr &expr)
{
+ if (!expr.has_match_arms ())
+ return;
+
// Lower the arms to a more convenient representation.
std::vector<MatrixRow> rows;
for (auto &arm : expr.get_match_cases ())
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
index 1af02ba..6d60ced 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
@@ -102,12 +102,11 @@ private:
virtual void visit (WhileLetLoopExpr &expr) override;
virtual void visit (IfExpr &expr) override;
virtual void visit (IfExprConseqElse &expr) override;
- virtual void visit (IfLetExpr &expr) override;
- virtual void visit (IfLetExprConseqElse &expr) override;
virtual void visit (HIR::MatchExpr &expr) override;
virtual void visit (AwaitExpr &expr) override;
virtual void visit (AsyncBlockExpr &expr) override;
virtual void visit (InlineAsm &expr) override;
+ virtual void visit (LlvmInlineAsm &expr) override;
virtual void visit (TypeParam &param) override;
virtual void visit (ConstGenericParam &param) override;
virtual void visit (LifetimeWhereClauseItem &item) override;
@@ -166,7 +165,6 @@ private:
virtual void visit (ImplTraitType &type) override;
virtual void visit (TraitObjectType &type) override;
virtual void visit (ParenthesisedType &type) override;
- virtual void visit (ImplTraitTypeOneBound &type) override;
virtual void visit (TupleType &type) override;
virtual void visit (NeverType &type) override;
virtual void visit (RawPointerType &type) override;
diff --git a/gcc/rust/checks/errors/rust-readonly-check.cc b/gcc/rust/checks/errors/rust-readonly-check.cc
index b899898..c128933 100644
--- a/gcc/rust/checks/errors/rust-readonly-check.cc
+++ b/gcc/rust/checks/errors/rust-readonly-check.cc
@@ -19,10 +19,13 @@
#include "rust-readonly-check.h"
#include "rust-tree.h"
#include "rust-gcc.h"
+#include "print-tree.h"
namespace Rust {
namespace Analysis {
+static std::map<tree, int> assignment_map = {};
+
// ported over from c-family/c-warn.cc
void
readonly_error (location_t loc, tree arg, enum lvalue_use use)
@@ -106,37 +109,68 @@ readonly_error (location_t loc, tree arg, enum lvalue_use use)
}
static void
-check_decl (tree *t)
+emit_error (tree *t, tree lhs, enum lvalue_use use)
{
- if (TREE_CODE (*t) == MODIFY_EXPR)
+ readonly_error (EXPR_LOCATION (*t), lhs, use);
+ TREE_OPERAND (*t, 0) = error_mark_node;
+}
+
+static void
+check_modify_expr (tree *t)
+{
+ tree lhs = TREE_OPERAND (*t, 0);
+ if (TREE_CODE (lhs) == ARRAY_REF || TREE_CODE (lhs) == COMPONENT_REF)
+ lhs = TREE_OPERAND (lhs, 0);
+
+ tree lhs_type = TREE_TYPE (lhs);
+ if (TYPE_READONLY (lhs_type) || TREE_READONLY (lhs) || TREE_CONSTANT (lhs))
{
- tree lhs = TREE_OPERAND (*t, 0);
- if (TREE_READONLY (lhs) || TREE_CONSTANT (lhs))
+ if (TREE_CODE (lhs) != VAR_DECL)
+ emit_error (t, lhs, lv_assign);
+ else if (!DECL_ARTIFICIAL (lhs))
{
- readonly_error (EXPR_LOCATION (*t), lhs, lv_assign);
- TREE_OPERAND (*t, 0) = error_mark_node;
+ if (DECL_INITIAL (lhs) != NULL)
+ emit_error (t, lhs, lv_assign);
+ else
+ {
+ if (assignment_map.find (lhs) == assignment_map.end ())
+ {
+ assignment_map.insert ({lhs, 0});
+ }
+ assignment_map[lhs]++;
+
+ if (assignment_map[lhs] > 1)
+ emit_error (t, lhs, lv_assign);
+ }
}
}
}
-static tree
-readonly_walk_fn (tree *t, int *, void *)
+static void
+check_decl (tree *t)
{
switch (TREE_CODE (*t))
{
case MODIFY_EXPR:
- check_decl (t);
+ check_modify_expr (t);
break;
default:
break;
}
+}
+
+static tree
+readonly_walk_fn (tree *t, int *, void *)
+{
+ check_decl (t);
return NULL_TREE;
}
void
ReadonlyCheck::Lint (Compile::Context &ctx)
{
+ assignment_map.clear ();
for (auto &fndecl : ctx.get_func_decls ())
{
for (tree p = DECL_ARGUMENTS (fndecl); p != NULL_TREE; p = DECL_CHAIN (p))
@@ -148,12 +182,14 @@ ReadonlyCheck::Lint (Compile::Context &ctx)
&readonly_walk_fn, &ctx);
}
+ assignment_map.clear ();
for (auto &var : ctx.get_var_decls ())
{
tree decl = var->get_decl ();
check_decl (&decl);
}
+ assignment_map.clear ();
for (auto &const_decl : ctx.get_const_decls ())
{
check_decl (&const_decl);
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 4c8db3a..46eef11 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -23,6 +23,10 @@
#include "rust-hir-item.h"
#include "rust-attribute-values.h"
#include "rust-system.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
namespace Rust {
namespace HIR {
@@ -216,8 +220,23 @@ UnsafeChecker::visit (PathInExpression &path)
NodeId ast_node_id = path.get_mappings ().get_nodeid ();
NodeId ref_node_id;
- if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
- return;
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ auto resolved = nr_ctx.lookup (ast_node_id);
+
+ if (!resolved.has_value ())
+ return;
+
+ ref_node_id = resolved.value ();
+ }
+ else
+ {
+ if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ return;
+ }
if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id))
{
@@ -260,14 +279,14 @@ UnsafeChecker::visit (LiteralExpr &)
void
UnsafeChecker::visit (BorrowExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (DereferenceExpr &expr)
{
TyTy::BaseType *to_deref_type;
- auto to_deref = expr.get_expr ()->get_mappings ().get_hirid ();
+ auto to_deref = expr.get_expr ().get_mappings ().get_hirid ();
rust_assert (context.lookup_type (to_deref, &to_deref_type));
@@ -280,60 +299,60 @@ UnsafeChecker::visit (DereferenceExpr &expr)
void
UnsafeChecker::visit (ErrorPropagationExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (NegationExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (ArithmeticOrLogicalExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
UnsafeChecker::visit (ComparisonExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
UnsafeChecker::visit (LazyBooleanExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
UnsafeChecker::visit (TypeCastExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (AssignmentExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
UnsafeChecker::visit (CompoundAssignmentExpr &expr)
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void
UnsafeChecker::visit (GroupedExpr &expr)
{
- expr.get_expr_in_parens ()->accept_vis (*this);
+ expr.get_expr_in_parens ().accept_vis (*this);
}
void
@@ -346,20 +365,20 @@ UnsafeChecker::visit (ArrayElemsValues &elems)
void
UnsafeChecker::visit (ArrayElemsCopied &elems)
{
- elems.get_elem_to_copy ()->accept_vis (*this);
+ elems.get_elem_to_copy ().accept_vis (*this);
}
void
UnsafeChecker::visit (ArrayExpr &expr)
{
- expr.get_internal_elements ()->accept_vis (*this);
+ expr.get_internal_elements ().accept_vis (*this);
}
void
UnsafeChecker::visit (ArrayIndexExpr &expr)
{
- expr.get_array_expr ()->accept_vis (*this);
- expr.get_index_expr ()->accept_vis (*this);
+ expr.get_array_expr ().accept_vis (*this);
+ expr.get_index_expr ().accept_vis (*this);
}
void
@@ -372,7 +391,7 @@ UnsafeChecker::visit (TupleExpr &expr)
void
UnsafeChecker::visit (TupleIndexExpr &expr)
{
- expr.get_tuple_expr ()->accept_vis (*this);
+ expr.get_tuple_expr ().accept_vis (*this);
}
void
@@ -386,13 +405,13 @@ UnsafeChecker::visit (StructExprFieldIdentifier &)
void
UnsafeChecker::visit (StructExprFieldIdentifierValue &field)
{
- field.get_value ()->accept_vis (*this);
+ field.get_value ().accept_vis (*this);
}
void
UnsafeChecker::visit (StructExprFieldIndexValue &field)
{
- field.get_value ()->accept_vis (*this);
+ field.get_value ().accept_vis (*this);
}
void
@@ -409,17 +428,32 @@ UnsafeChecker::visit (StructExprStructBase &)
void
UnsafeChecker::visit (CallExpr &expr)
{
- if (!expr.get_fnexpr ())
+ if (!expr.has_fnexpr ())
return;
- NodeId ast_node_id = expr.get_fnexpr ()->get_mappings ().get_nodeid ();
+ NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid ();
NodeId ref_node_id;
// There are no unsafe types, and functions are defined in the name resolver.
// If we can't find the name, then we're dealing with a type and should return
// early.
- if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
- return;
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ auto resolved = nr_ctx.lookup (ast_node_id);
+
+ if (!resolved.has_value ())
+ return;
+
+ ref_node_id = resolved.value ();
+ }
+ else
+ {
+ if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ return;
+ }
if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id))
{
@@ -447,15 +481,20 @@ UnsafeChecker::visit (MethodCallExpr &expr)
TyTy::BaseType *method_type;
context.lookup_type (expr.get_method_name ().get_mappings ().get_hirid (),
&method_type);
+ if (!method_type || !method_type->is<TyTy::FnType> ())
+ return;
- auto fn = *static_cast<TyTy::FnType *> (method_type);
+ auto &fn = static_cast<TyTy::FnType &> (*method_type);
+ // FIXME
+ // should probably use the defid lookup instead
+ // tl::optional<HIR::Item *> lookup_defid (DefId id);
auto method = mappings.lookup_hir_implitem (fn.get_ref ());
if (!unsafe_context.is_in_context () && method)
check_unsafe_call (static_cast<Function *> (method->first),
expr.get_locus (), "method");
- expr.get_receiver ()->accept_vis (*this);
+ expr.get_receiver ().accept_vis (*this);
for (auto &arg : expr.get_arguments ())
arg->accept_vis (*this);
@@ -464,14 +503,14 @@ UnsafeChecker::visit (MethodCallExpr &expr)
void
UnsafeChecker::visit (FieldAccessExpr &expr)
{
- expr.get_receiver_expr ()->accept_vis (*this);
+ expr.get_receiver_expr ().accept_vis (*this);
if (unsafe_context.is_in_context ())
return;
TyTy::BaseType *receiver_ty;
auto ok = context.lookup_type (
- expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver_ty);
+ expr.get_receiver_expr ().get_mappings ().get_hirid (), &receiver_ty);
rust_assert (ok);
if (receiver_ty->get_kind () == TyTy::TypeKind::ADT)
@@ -487,7 +526,7 @@ UnsafeChecker::visit (FieldAccessExpr &expr)
void
UnsafeChecker::visit (ClosureExpr &expr)
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
@@ -497,7 +536,7 @@ UnsafeChecker::visit (BlockExpr &expr)
stmt->accept_vis (*this);
if (expr.has_expr ())
- expr.get_final_expr ()->accept_vis (*this);
+ expr.get_final_expr ().accept_vis (*this);
}
void
@@ -508,26 +547,26 @@ void
UnsafeChecker::visit (BreakExpr &expr)
{
if (expr.has_break_expr ())
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (RangeFromToExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (RangeFromExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (RangeToExpr &expr)
{
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
@@ -537,21 +576,21 @@ UnsafeChecker::visit (RangeFullExpr &)
void
UnsafeChecker::visit (RangeFromToInclExpr &expr)
{
- expr.get_from_expr ()->accept_vis (*this);
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_from_expr ().accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (RangeToInclExpr &expr)
{
- expr.get_to_expr ()->accept_vis (*this);
+ expr.get_to_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (ReturnExpr &expr)
{
if (expr.has_return_expr ())
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void
@@ -559,7 +598,7 @@ UnsafeChecker::visit (UnsafeBlockExpr &expr)
{
unsafe_context.enter (expr.get_mappings ().get_hirid ());
- expr.get_block_expr ()->accept_vis (*this);
+ expr.get_block_expr ().accept_vis (*this);
unsafe_context.exit ();
}
@@ -567,61 +606,45 @@ UnsafeChecker::visit (UnsafeBlockExpr &expr)
void
UnsafeChecker::visit (LoopExpr &expr)
{
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
UnsafeChecker::visit (WhileLoopExpr &expr)
{
- expr.get_predicate_expr ()->accept_vis (*this);
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_predicate_expr ().accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
UnsafeChecker::visit (WhileLetLoopExpr &expr)
{
- expr.get_cond ()->accept_vis (*this);
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_cond ().accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void
UnsafeChecker::visit (IfExpr &expr)
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
}
void
UnsafeChecker::visit (IfExprConseqElse &expr)
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
- expr.get_else_block ()->accept_vis (*this);
-}
-
-void
-UnsafeChecker::visit (IfLetExpr &expr)
-{
- expr.get_scrutinee_expr ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
-}
-
-void
-UnsafeChecker::visit (IfLetExprConseqElse &expr)
-{
- expr.get_scrutinee_expr ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
-
- // TODO: Visit else expression
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
+ expr.get_else_block ().accept_vis (*this);
}
void
UnsafeChecker::visit (MatchExpr &expr)
{
- expr.get_scrutinee_expr ()->accept_vis (*this);
+ expr.get_scrutinee_expr ().accept_vis (*this);
for (auto &match_arm : expr.get_match_cases ())
- match_arm.get_expr ()->accept_vis (*this);
+ match_arm.get_expr ().accept_vis (*this);
}
void
@@ -648,6 +671,17 @@ UnsafeChecker::visit (InlineAsm &expr)
}
void
+UnsafeChecker::visit (LlvmInlineAsm &expr)
+{
+ if (unsafe_context.is_in_context ())
+ return;
+
+ rust_error_at (
+ expr.get_locus (), ErrorCode::E0133,
+ "use of inline assembly is unsafe and requires unsafe function or block");
+}
+
+void
UnsafeChecker::visit (TypeParam &)
{}
@@ -698,7 +732,7 @@ UnsafeChecker::visit (Function &function)
if (is_unsafe_fn)
unsafe_context.enter (function.get_mappings ().get_hirid ());
- function.get_definition ()->accept_vis (*this);
+ function.get_definition ().accept_vis (*this);
if (is_unsafe_fn)
unsafe_context.exit ();
@@ -746,27 +780,27 @@ UnsafeChecker::visit (Union &)
void
UnsafeChecker::visit (ConstantItem &const_item)
{
- const_item.get_expr ()->accept_vis (*this);
+ const_item.get_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (StaticItem &static_item)
{
- static_item.get_expr ()->accept_vis (*this);
+ static_item.get_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (TraitItemFunc &item)
{
- if (item.has_block_defined ())
- item.get_block_expr ()->accept_vis (*this);
+ if (item.has_definition ())
+ item.get_block_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (TraitItemConst &item)
{
if (item.has_expr ())
- item.get_expr ()->accept_vis (*this);
+ item.get_expr ().accept_vis (*this);
}
void
@@ -913,13 +947,13 @@ void
UnsafeChecker::visit (LetStmt &stmt)
{
if (stmt.has_init_expr ())
- stmt.get_init_expr ()->accept_vis (*this);
+ stmt.get_init_expr ().accept_vis (*this);
}
void
UnsafeChecker::visit (ExprStmt &stmt)
{
- stmt.get_expr ()->accept_vis (*this);
+ stmt.get_expr ().accept_vis (*this);
}
void
@@ -939,10 +973,6 @@ UnsafeChecker::visit (ParenthesisedType &)
{}
void
-UnsafeChecker::visit (ImplTraitTypeOneBound &)
-{}
-
-void
UnsafeChecker::visit (TupleType &)
{}
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h
index 1fa1fe0..9a8fb7c 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -110,12 +110,11 @@ private:
virtual void visit (WhileLetLoopExpr &expr) override;
virtual void visit (IfExpr &expr) override;
virtual void visit (IfExprConseqElse &expr) override;
- virtual void visit (IfLetExpr &expr) override;
- virtual void visit (IfLetExprConseqElse &expr) override;
virtual void visit (MatchExpr &expr) override;
virtual void visit (AwaitExpr &expr) override;
virtual void visit (AsyncBlockExpr &expr) override;
- virtual void visit (InlineAsm &expr);
+ virtual void visit (InlineAsm &expr) override;
+ virtual void visit (LlvmInlineAsm &expr) override;
virtual void visit (TypeParam &param) override;
virtual void visit (ConstGenericParam &param) override;
virtual void visit (LifetimeWhereClauseItem &item) override;
@@ -174,7 +173,6 @@ private:
virtual void visit (ImplTraitType &type) override;
virtual void visit (TraitObjectType &type) override;
virtual void visit (ParenthesisedType &type) override;
- virtual void visit (ImplTraitTypeOneBound &type) override;
virtual void visit (TupleType &type) override;
virtual void visit (NeverType &type) override;
virtual void visit (RawPointerType &type) override;
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc b/gcc/rust/checks/lints/rust-lint-marklive.cc
index ca26a66..af7535a 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -22,6 +22,8 @@
#include "rust-lint-marklive.h"
#include "options.h"
#include "rust-hir-full.h"
+#include "rust-hir-map.h"
+#include "rust-hir-path.h"
#include "rust-name-resolver.h"
#include "rust-immutable-name-resolution-context.h"
#include "rust-system.h"
@@ -99,15 +101,21 @@ MarkLive::visit (HIR::PathInExpression &expr)
{
// We should iterate every path segment in order to mark the struct which
// is used in expression like Foo::bar(), we should mark the Foo alive.
- expr.iterate_path_segments ([&] (HIR::PathExprSegment &seg) -> bool {
- return visit_path_segment (seg);
- });
+ if (!expr.is_lang_item ())
+ expr.iterate_path_segments ([&] (HIR::PathExprSegment &seg) -> bool {
+ return visit_path_segment (seg);
+ });
// after iterate the path segments, we should mark functions and associated
// functions alive.
NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
NodeId ref_node_id = UNKNOWN_NODEID;
- find_ref_node_id (ast_node_id, ref_node_id);
+
+ if (expr.is_lang_item ())
+ ref_node_id
+ = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
+ else
+ find_ref_node_id (ast_node_id, ref_node_id);
// node back to HIR
tl::optional<HirId> hid = mappings.lookup_node_to_hir (ref_node_id);
@@ -124,7 +132,7 @@ MarkLive::visit (HIR::PathInExpression &expr)
void
MarkLive::visit (HIR::MethodCallExpr &expr)
{
- expr.get_receiver ()->accept_vis (*this);
+ expr.get_receiver ().accept_vis (*this);
visit_path_segment (expr.get_method_name ());
for (auto &argument : expr.get_arguments ())
argument->accept_vis (*this);
@@ -182,14 +190,14 @@ void
MarkLive::visit (HIR::FieldAccessExpr &expr)
{
// visit receiver at first
- expr.get_receiver_expr ()->accept_vis (*this);
+ expr.get_receiver_expr ().accept_vis (*this);
// resolve the receiver back to ADT type
TyTy::BaseType *receiver = nullptr;
if (!tyctx->lookup_type (
- expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
+ expr.get_receiver_expr ().get_mappings ().get_hirid (), &receiver))
{
- rust_error_at (expr.get_receiver_expr ()->get_locus (),
+ rust_error_at (expr.get_receiver_expr ().get_locus (),
"unresolved type for receiver");
}
@@ -221,7 +229,7 @@ MarkLive::visit (HIR::FieldAccessExpr &expr)
rust_assert (ok);
if (index >= variant->num_fields ())
{
- rust_error_at (expr.get_receiver_expr ()->get_locus (),
+ rust_error_at (expr.get_receiver_expr ().get_locus (),
"cannot access struct %s by index: %lu",
adt->get_name ().c_str (), (unsigned long) index);
return;
@@ -236,7 +244,7 @@ void
MarkLive::visit (HIR::TupleIndexExpr &expr)
{
// TODO: unused tuple field detection
- expr.get_tuple_expr ()->accept_vis (*this);
+ expr.get_tuple_expr ().accept_vis (*this);
}
void
@@ -249,13 +257,13 @@ MarkLive::visit (HIR::TypeAlias &alias)
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
if (auto id = nr_ctx.lookup (
- alias.get_type_aliased ()->get_mappings ().get_nodeid ()))
+ alias.get_type_aliased ().get_mappings ().get_nodeid ()))
ast_node_id = *id;
}
else
{
resolver->lookup_resolved_type (
- alias.get_type_aliased ()->get_mappings ().get_nodeid (), &ast_node_id);
+ alias.get_type_aliased ().get_mappings ().get_nodeid (), &ast_node_id);
}
if (auto hid = mappings.lookup_node_to_hir (ast_node_id))
@@ -279,7 +287,7 @@ MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id)
{
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
nr_ctx.lookup (ast_node_id).map ([&ref_node_id] (NodeId resolved) {
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.h b/gcc/rust/checks/lints/rust-lint-marklive.h
index 92b4502..86d96fc 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.h
+++ b/gcc/rust/checks/lints/rust-lint-marklive.h
@@ -43,44 +43,44 @@ public:
void visit (HIR::BorrowExpr &expr) override
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void visit (HIR::DereferenceExpr &expr) override
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void visit (HIR::NegationExpr &expr) override
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void visit (HIR::LazyBooleanExpr &expr) override
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void visit (HIR::TypeCastExpr &expr) override
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void visit (HIR::GroupedExpr &expr) override
{
- expr.get_expr_in_parens ()->accept_vis (*this);
+ expr.get_expr_in_parens ().accept_vis (*this);
}
void visit (HIR::ArrayExpr &expr) override
{
- expr.get_internal_elements ()->accept_vis (*this);
+ expr.get_internal_elements ().accept_vis (*this);
}
void visit (HIR::ArrayIndexExpr &expr) override
{
- expr.get_array_expr ()->accept_vis (*this);
- expr.get_index_expr ()->accept_vis (*this);
+ expr.get_array_expr ().accept_vis (*this);
+ expr.get_index_expr ().accept_vis (*this);
}
void visit (HIR::ArrayElemsValues &expr) override
@@ -107,57 +107,57 @@ public:
}
if (expr.has_expr ())
{
- expr.get_final_expr ()->accept_vis (*this);
+ expr.get_final_expr ().accept_vis (*this);
}
}
void visit (HIR::UnsafeBlockExpr &expr) override
{
- expr.get_block_expr ()->accept_vis (*this);
+ expr.get_block_expr ().accept_vis (*this);
}
void visit (HIR::LoopExpr &expr) override
{
- expr.get_loop_block ()->accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
}
void visit (HIR::BreakExpr &expr) override
{
if (expr.has_break_expr ())
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void visit (HIR::WhileLoopExpr &expr) override
{
- expr.get_loop_block ()->accept_vis (*this);
- expr.get_predicate_expr ()->accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
+ expr.get_predicate_expr ().accept_vis (*this);
}
void visit (HIR::Function &function) override
{
- function.get_definition ()->accept_vis (*this);
+ function.get_definition ().accept_vis (*this);
}
void visit (HIR::ReturnExpr &expr) override
{
if (expr.has_return_expr ())
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
void visit (HIR::WhileLetLoopExpr &expr) override
{
- expr.get_loop_block ()->accept_vis (*this);
- expr.get_cond ()->accept_vis (*this);
+ expr.get_loop_block ().accept_vis (*this);
+ expr.get_cond ().accept_vis (*this);
}
void visit (HIR::ExprStmt &stmt) override
{
- stmt.get_expr ()->accept_vis (*this);
+ stmt.get_expr ().accept_vis (*this);
}
void visit (HIR::CallExpr &expr) override
{
- expr.get_fnexpr ()->accept_vis (*this);
+ expr.get_fnexpr ().accept_vis (*this);
for (auto &argument : expr.get_arguments ())
argument->accept_vis (*this);
}
@@ -169,8 +169,8 @@ public:
}
void visit (HIR::ComparisonExpr &expr) override
{
- expr.get_lhs ()->accept_vis (*this);
- expr.get_rhs ()->accept_vis (*this);
+ expr.get_lhs ().accept_vis (*this);
+ expr.get_rhs ().accept_vis (*this);
}
void visit (HIR::AssignmentExpr &expr) override
@@ -187,33 +187,33 @@ public:
void visit (HIR::IfExpr &expr) override
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
}
void visit (HIR::IfExprConseqElse &expr) override
{
- expr.get_if_condition ()->accept_vis (*this);
- expr.get_if_block ()->accept_vis (*this);
- expr.get_else_block ()->accept_vis (*this);
+ expr.get_if_condition ().accept_vis (*this);
+ expr.get_if_block ().accept_vis (*this);
+ expr.get_else_block ().accept_vis (*this);
}
void visit (HIR::MatchExpr &expr) override
{
- expr.get_scrutinee_expr ()->accept_vis (*this);
+ expr.get_scrutinee_expr ().accept_vis (*this);
std::vector<HIR::MatchCase> &cases = expr.get_match_cases ();
for (auto &&caz : cases)
{
auto case_arm = caz.get_arm ();
if (case_arm.has_match_arm_guard ())
- case_arm.get_guard_expr ()->accept_vis (*this);
- caz.get_expr ()->accept_vis (*this);
+ case_arm.get_guard_expr ().accept_vis (*this);
+ caz.get_expr ().accept_vis (*this);
}
}
void visit (HIR::TraitItemFunc &item) override
{
- item.get_block_expr ()->accept_vis (*this);
+ item.get_block_expr ().accept_vis (*this);
}
void visit (HIR::ImplBlock &impl) override
@@ -228,7 +228,7 @@ public:
{
if (stmt.has_init_expr ())
{
- stmt.get_init_expr ()->accept_vis (*this);
+ stmt.get_init_expr ().accept_vis (*this);
}
}
@@ -247,18 +247,18 @@ public:
stct.get_struct_name ().accept_vis (*this);
if (stct.has_struct_base ())
{
- stct.struct_base->base_struct->accept_vis (*this);
+ stct.get_struct_base ().get_base ().accept_vis (*this);
}
}
virtual void visit (HIR::StructExprFieldIdentifierValue &field) override
{
- field.get_value ()->accept_vis (*this);
+ field.get_value ().accept_vis (*this);
}
void visit (HIR::StructExprStructBase &stct) override
{
- stct.get_struct_base ()->base_struct->accept_vis (*this);
+ stct.get_struct_base ().get_base ().accept_vis (*this);
}
void visit (HIR::Module &module) override
@@ -269,7 +269,7 @@ public:
void visit (HIR::ClosureExpr &expr) override
{
- expr.get_expr ()->accept_vis (*this);
+ expr.get_expr ().accept_vis (*this);
}
private:
diff --git a/gcc/rust/checks/lints/rust-lint-scan-deadcode.h b/gcc/rust/checks/lints/rust-lint-scan-deadcode.h
index e6ef1392..0fc203b 100644
--- a/gcc/rust/checks/lints/rust-lint-scan-deadcode.h
+++ b/gcc/rust/checks/lints/rust-lint-scan-deadcode.h
@@ -93,7 +93,8 @@ public:
{
HirId field_hir_id = field.get_mappings ().get_hirid ();
if (should_warn (field_hir_id)
- && !field.get_visibility ().is_public ())
+ && !field.get_visibility ().is_public ()
+ && field.get_field_name ().as_string ().at (0) != '_')
{
rust_warning_at (field.get_locus (), 0,
"field is never read: %qs",
diff --git a/gcc/rust/expand/rust-cfg-strip.cc b/gcc/rust/expand/rust-cfg-strip.cc
index 4e6a8ac..a8c3ca5 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -19,6 +19,7 @@
#include "rust-cfg-strip.h"
#include "rust-ast-full.h"
#include "rust-ast-visitor.h"
+#include "rust-path.h"
#include "rust-session-manager.h"
#include "rust-attribute-values.h"
@@ -434,10 +435,13 @@ CfgStrip::visit (AST::PathInExpression &path)
return;
}
- for (auto &segment : path.get_segments ())
+ if (!path.is_lang_item ())
{
- if (segment.has_generic_args ())
- maybe_strip_generic_args (segment.get_generic_args ());
+ for (auto &segment : path.get_segments ())
+ {
+ if (segment.has_generic_args ())
+ maybe_strip_generic_args (segment.get_generic_args ());
+ }
}
}
diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc
index 18436be..321fa00 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -17,7 +17,12 @@
// <http://www.gnu.org/licenses/>.
#include "rust-derive-clone.h"
+#include "rust-ast.h"
+#include "rust-expr.h"
#include "rust-item.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-system.h"
namespace Rust {
namespace AST {
@@ -28,6 +33,15 @@ DeriveClone::clone_call (std::unique_ptr<Expr> &&to_clone)
// $crate::core::clone::Clone::clone for the fully qualified path - we don't
// link with `core` yet so that might be an issue. Use `Clone::clone` for now?
// TODO: Factor this function inside the DeriveAccumulator
+
+ // Interestingly, later versions of Rust have a `clone_fn` lang item which
+ // corresponds to this. But because we are first targeting 1.49, we cannot use
+ // it yet. Once we target a new, more recent version of the language, we'll
+ // have figured out how to compile and distribute `core`, meaning we'll be
+ // able to directly call `::core::clone::Clone::clone()`
+
+ // Not sure how to call it properly in the meantime...
+
auto path = std::unique_ptr<Expr> (
new PathInExpression (builder.path_in_expression ({"Clone", "clone"})));
@@ -47,11 +61,10 @@ std::unique_ptr<AssociatedItem>
DeriveClone::clone_fn (std::unique_ptr<Expr> &&clone_expr)
{
auto block = std::unique_ptr<BlockExpr> (
- new BlockExpr ({}, std::move (clone_expr), {}, {}, AST::LoopLabel::error (),
- loc, loc));
+ new BlockExpr ({}, std::move (clone_expr), {}, {}, tl::nullopt, loc, loc));
auto big_self_type = builder.single_type_path ("Self");
- std::unique_ptr<SelfParam> self (new SelfParam (Lifetime::error (),
+ std::unique_ptr<SelfParam> self (new SelfParam (tl::nullopt,
/* is_mut */ false, loc));
std::vector<std::unique_ptr<Param>> params;
@@ -77,89 +90,19 @@ DeriveClone::clone_impl (
std::unique_ptr<AssociatedItem> &&clone_fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
- // should that be `$crate::core::clone::Clone` instead?
- auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
- segments.emplace_back (builder.type_path_segment ("Clone"));
- auto clone = TypePath (std::move (segments), loc);
-
- auto trait_items = std::vector<std::unique_ptr<AssociatedItem>> ();
- trait_items.emplace_back (std::move (clone_fn));
-
- // we need to build up the generics for this impl block which will be just a
- // clone of the types specified ones
- //
- // for example:
- //
- // #[derive(Clone)]
- // struct Be<T: Clone> { ... }
- //
- // we need to generate the impl block:
- //
- // impl<T: Clone> Clone for Be<T>
-
- std::vector<Lifetime> lifetime_args;
- std::vector<GenericArg> generic_args;
- std::vector<std::unique_ptr<GenericParam>> impl_generics;
- for (const auto &generic : type_generics)
- {
- switch (generic->get_kind ())
- {
- case GenericParam::Kind::Lifetime: {
- LifetimeParam &lifetime_param = (LifetimeParam &) *generic.get ();
-
- Lifetime l = builder.new_lifetime (lifetime_param.get_lifetime ());
- lifetime_args.push_back (std::move (l));
-
- auto impl_lifetime_param
- = builder.new_lifetime_param (lifetime_param);
- impl_generics.push_back (std::move (impl_lifetime_param));
- }
- break;
-
- case GenericParam::Kind::Type: {
- TypeParam &type_param = (TypeParam &) *generic.get ();
+ // we should have two of these, so we don't run into issues with
+ // two paths sharing a node id
+ auto clone_bound = builder.type_path (LangItem::Kind::CLONE);
+ auto clone_trait_path = builder.type_path (LangItem::Kind::CLONE);
- std::unique_ptr<Type> associated_type = builder.single_type_path (
- type_param.get_type_representation ().as_string ());
+ auto trait_items = vec (std::move (clone_fn));
- GenericArg type_arg
- = GenericArg::create_type (std::move (associated_type));
- generic_args.push_back (std::move (type_arg));
-
- auto impl_type_param = builder.new_type_param (type_param);
- impl_generics.push_back (std::move (impl_type_param));
- }
- break;
-
- case GenericParam::Kind::Const: {
- rust_unreachable ();
-
- // TODO
- // const ConstGenericParam *const_param
- // = (const ConstGenericParam *) generic.get ();
- // std::unique_ptr<Expr> const_expr = nullptr;
-
- // GenericArg type_arg
- // = GenericArg::create_const (std::move (const_expr));
- // generic_args.push_back (std::move (type_arg));
- }
- break;
- }
- }
+ auto generics = setup_impl_generics (name, type_generics,
+ builder.trait_bound (clone_bound));
- GenericArgs generic_args_for_self (lifetime_args, generic_args,
- {} /*binding args*/, loc);
- std::unique_ptr<Type> self_type_path
- = impl_generics.empty ()
- ? builder.single_type_path (name)
- : builder.single_generic_type_path (name, generic_args_for_self);
-
- return std::unique_ptr<Item> (
- new TraitImpl (clone, /* unsafe */ false,
- /* exclam */ false, std::move (trait_items),
- std::move (impl_generics), std::move (self_type_path),
- WhereClause::create_empty (), Visibility::create_private (),
- {}, {}, loc));
+ return builder.trait_impl (clone_trait_path, std::move (generics.self_type),
+ std::move (trait_items),
+ std::move (generics.impl));
}
// TODO: Create new `make_qualified_call` helper function
@@ -227,24 +170,222 @@ DeriveClone::visit_struct (StructStruct &item)
item.get_generic_params ());
}
+MatchCase
+DeriveClone::clone_enum_identifier (PathInExpression variant_path,
+ const std::unique_ptr<EnumItem> &variant)
+{
+ auto pattern = std::unique_ptr<Pattern> (new ReferencePattern (
+ std::unique_ptr<Pattern> (new PathInExpression (
+ variant_path.get_segments (), {}, variant_path.get_locus (),
+ variant_path.opening_scope_resolution ())),
+ false, false, loc));
+ auto expr = std::unique_ptr<Expr> (
+ new PathInExpression (variant_path.get_segments (), {},
+ variant_path.get_locus (),
+ variant_path.opening_scope_resolution ()));
+
+ return builder.match_case (std::move (pattern), std::move (expr));
+}
+
+MatchCase
+DeriveClone::clone_enum_tuple (PathInExpression variant_path,
+ const EnumItemTuple &variant)
+{
+ auto patterns = std::vector<std::unique_ptr<Pattern>> ();
+ auto cloned_patterns = std::vector<std::unique_ptr<Expr>> ();
+
+ for (size_t i = 0; i < variant.get_tuple_fields ().size (); i++)
+ {
+ // The pattern we're creating for each field is `self_<i>` where `i` is
+ // the index 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 clone the field.
+ auto pattern_str = "__self_" + std::to_string (i);
+
+ patterns.emplace_back (builder.identifier_pattern (pattern_str));
+
+ // Now, for each tuple's element, we create a new expression calling
+ // `clone` on it for the match case's return expression
+ cloned_patterns.emplace_back (
+ clone_call (builder.ref (builder.identifier (pattern_str))));
+ }
+
+ auto pattern_items = std::unique_ptr<TupleStructItems> (
+ new TupleStructItemsNoRange (std::move (patterns)));
+
+ auto pattern = std::unique_ptr<Pattern> (new ReferencePattern (
+ std::unique_ptr<Pattern> (new TupleStructPattern (
+ PathInExpression (variant_path.get_segments (), {},
+ variant_path.get_locus (),
+ variant_path.opening_scope_resolution ()),
+ std::move (pattern_items))),
+ false, false, loc));
+
+ auto expr = builder.call (std::unique_ptr<Expr> (new PathInExpression (
+ variant_path.get_segments (), {},
+ variant_path.get_locus (),
+ variant_path.opening_scope_resolution ())),
+ std::move (cloned_patterns));
+
+ return builder.match_case (std::move (pattern), std::move (expr));
+}
+
+MatchCase
+DeriveClone::clone_enum_struct (PathInExpression variant_path,
+ const EnumItemStruct &variant)
+{
+ auto field_patterns = std::vector<std::unique_ptr<StructPatternField>> ();
+ auto cloned_fields = std::vector<std::unique_ptr<StructExprField>> ();
+
+#if 0
+ // NOTE: We currently do not support compiling struct patterns where an
+ // identifier is assigned a new pattern, e.g. Bloop { f0: x }
+ // This is the code we should eventually produce as it mimics what rustc does
+ // - which is probably here for a good reason. In the meantime, we can just
+ // use the field's identifier as the pattern: Bloop { f0 }
+ // We can then clone the field directly instead of calling `clone()` on the
+ // new pattern.
+ // TODO: Figure out if that is actually needed and why rustc does it?
+
+ for (size_t i = 0; i < variant.get_struct_fields ().size (); i++)
+ {
+ auto &field = variant.get_struct_fields ()[i];
+
+ // Just like for tuples, the pattern we're creating for each field is
+ // `self_<i>` where `i` is the index 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 clone the field.
+ auto pattern_str = "__self_" + std::to_string (i);
+
+ field_patterns.emplace_back (
+ std::unique_ptr<StructPatternField> (new StructPatternFieldIdentPat (
+ field.get_field_name (), builder.identifier_pattern (pattern_str), {},
+ loc)));
+
+ cloned_fields.emplace_back (
+ std::unique_ptr<StructExprField> (new StructExprFieldIdentifierValue (
+ field.get_field_name (),
+ clone_call (builder.ref (builder.identifier (pattern_str))), {},
+ loc)));
+ }
+#endif
+
+ for (const auto &field : variant.get_struct_fields ())
+ {
+ // We match on the struct's fields, and then recreate an instance of that
+ // struct, cloning each field
+
+ field_patterns.emplace_back (
+ std::unique_ptr<StructPatternField> (new StructPatternFieldIdent (
+ field.get_field_name (), false /* is_ref? true? */, false, {}, loc)));
+
+ cloned_fields.emplace_back (
+ std::unique_ptr<StructExprField> (new StructExprFieldIdentifierValue (
+ field.get_field_name (),
+ clone_call (builder.ref (
+ builder.identifier (field.get_field_name ().as_string ()))),
+ {}, loc)));
+ }
+
+ auto pattern_elts = StructPatternElements (std::move (field_patterns));
+
+ auto pattern = std::unique_ptr<Pattern> (
+ new ReferencePattern (std::unique_ptr<Pattern> (new StructPattern (
+ variant_path, loc, pattern_elts)),
+ false, false, loc));
+
+ PathInExpression new_path (variant_path.get_segments (),
+ variant_path.get_outer_attrs (),
+ variant_path.get_locus (),
+ variant_path.opening_scope_resolution ());
+
+ auto expr = std::unique_ptr<Expr> (
+ new StructExprStructFields (new_path, std::move (cloned_fields), loc));
+
+ return builder.match_case (std::move (pattern), std::move (expr));
+}
+
void
DeriveClone::visit_enum (Enum &item)
{
- rust_sorry_at (item.get_locus (), "cannot derive %qs for these items yet",
- "Clone");
+ // Create an arm for each variant of the enum:
+ // - For enum item variants (simple identifiers), just create the same
+ // variant.
+ // - For struct and tuple variants, destructure the pattern and call clone for
+ // each field.
+
+ auto cases = std::vector<MatchCase> ();
+
+ for (const auto &variant : item.get_variants ())
+ {
+ auto path
+ = builder.variant_path (item.get_identifier ().as_string (),
+ variant->get_identifier ().as_string ());
+
+ switch (variant->get_enum_item_kind ())
+ {
+ // Identifiers and discriminated variants are the same for a clone - we
+ // just return the same variant
+ case EnumItem::Kind::Identifier:
+ case EnumItem::Kind::Discriminant:
+ cases.emplace_back (clone_enum_identifier (path, variant));
+ break;
+ case EnumItem::Kind::Tuple:
+ cases.emplace_back (
+ clone_enum_tuple (path, static_cast<EnumItemTuple &> (*variant)));
+ break;
+ case EnumItem::Kind::Struct:
+ cases.emplace_back (
+ clone_enum_struct (path, static_cast<EnumItemStruct &> (*variant)));
+ break;
+ }
+ }
+
+ // match self { ... }
+ auto match = builder.match (builder.identifier ("self"), std::move (cases));
+
+ expanded = clone_impl (clone_fn (std::move (match)),
+ item.get_identifier ().as_string (),
+ item.get_generic_params ());
}
void
DeriveClone::visit_union (Union &item)
{
// FIXME: Should be $crate::core::clone::AssertParamIsCopy (or similar)
+ // (Rust-GCC#3329)
+
+ auto copy_path = builder.type_path (LangItem::Kind::COPY);
+ auto sized_path = builder.type_path (LangItem::Kind::SIZED);
+
+ auto copy_bound = std::unique_ptr<TypeParamBound> (
+ new TraitBound (copy_path, item.get_locus ()));
+ auto sized_bound = std::unique_ptr<TypeParamBound> (
+ new TraitBound (sized_path, item.get_locus (), false,
+ true /* opening_question_mark */));
+
+ auto bounds = vec (std::move (copy_bound), std::move (sized_bound));
+
+ // struct AssertParamIsCopy<T: Copy + ?Sized> { _t: PhantomData<T> }
+ auto assert_param_is_copy = "AssertParamIsCopy";
+ auto t = std::unique_ptr<GenericParam> (
+ new TypeParam (Identifier ("T"), item.get_locus (), std::move (bounds)));
+ auto assert_param_is_copy_struct = builder.struct_struct (
+ assert_param_is_copy, vec (std::move (t)),
+ {StructField (
+ Identifier ("_t"),
+ builder.single_generic_type_path (
+ LangItem::Kind::PHANTOM_DATA,
+ GenericArgs (
+ {}, {GenericArg::create_type (builder.single_type_path ("T"))}, {})),
+ Visibility::create_private (), item.get_locus ())});
// <Self>
auto arg = GenericArg::create_type (builder.single_type_path ("Self"));
// AssertParamIsCopy::<Self>
auto type = std::unique_ptr<TypePathSegment> (
- new TypePathSegmentGeneric (PathIdentSegment ("AssertParamIsCopy", loc),
+ new TypePathSegmentGeneric (PathIdentSegment (assert_param_is_copy, loc),
false, GenericArgs ({}, {arg}, {}, loc), loc));
auto type_paths = std::vector<std::unique_ptr<TypePathSegment>> ();
type_paths.emplace_back (std::move (type));
@@ -252,11 +393,12 @@ DeriveClone::visit_union (Union &item)
auto full_path
= std::unique_ptr<Type> (new TypePath ({std::move (type_paths)}, loc));
- auto stmts = std::vector<std::unique_ptr<Stmt>> ();
- stmts.emplace_back (
- builder.let (builder.wildcard (), std::move (full_path), nullptr));
auto tail_expr = builder.deref (builder.identifier ("self"));
+ auto stmts
+ = vec (std::move (assert_param_is_copy_struct),
+ builder.let (builder.wildcard (), std::move (full_path), nullptr));
+
auto block = builder.block (std::move (stmts), std::move (tail_expr));
expanded = clone_impl (clone_fn (std::move (block)),
diff --git a/gcc/rust/expand/rust-derive-clone.h b/gcc/rust/expand/rust-derive-clone.h
index 4a43b2a..61224ba 100644
--- a/gcc/rust/expand/rust-derive-clone.h
+++ b/gcc/rust/expand/rust-derive-clone.h
@@ -63,6 +63,23 @@ private:
clone_impl (std::unique_ptr<AssociatedItem> &&clone_fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics);
+ /**
+ * Get the path to use for matching and creating a variant when matching on an
+ * enum. E.g. for the `Option` enum, with the `None` variant, this will create
+ * a path `Option::None`
+ */
+ PathInExpression variant_match_path (Enum &item, const Identifier &variant);
+
+ /**
+ * Implementation of clone for all possible variants of an enum
+ */
+ MatchCase clone_enum_identifier (PathInExpression variant_path,
+ const std::unique_ptr<EnumItem> &variant);
+ MatchCase clone_enum_tuple (PathInExpression variant_path,
+ const EnumItemTuple &variant);
+ 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);
diff --git a/gcc/rust/expand/rust-derive-copy.cc b/gcc/rust/expand/rust-derive-copy.cc
index 1de7290..b2971ad 100644
--- a/gcc/rust/expand/rust-derive-copy.cc
+++ b/gcc/rust/expand/rust-derive-copy.cc
@@ -17,7 +17,8 @@
// <http://www.gnu.org/licenses/>.
#include "rust-derive-copy.h"
-#include "rust-ast-full.h"
+#include "rust-hir-map.h"
+#include "rust-path.h"
namespace Rust {
namespace AST {
@@ -41,86 +42,16 @@ DeriveCopy::copy_impl (
std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
- // `$crate::core::marker::Copy` instead
- auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
- segments.emplace_back (builder.type_path_segment ("Copy"));
- auto copy = TypePath (std::move (segments), loc);
-
- // we need to build up the generics for this impl block which will be just a
- // clone of the types specified ones
- //
- // for example:
- //
- // #[derive(Copy)]
- // struct Be<T: Copy> { ... }
- //
- // we need to generate the impl block:
- //
- // impl<T: Copy> Clone for Be<T>
-
- std::vector<Lifetime> lifetime_args;
- std::vector<GenericArg> generic_args;
- std::vector<std::unique_ptr<GenericParam>> impl_generics;
- for (const auto &generic : type_generics)
- {
- switch (generic->get_kind ())
- {
- case GenericParam::Kind::Lifetime: {
- LifetimeParam &lifetime_param = (LifetimeParam &) *generic.get ();
-
- Lifetime l = builder.new_lifetime (lifetime_param.get_lifetime ());
- lifetime_args.push_back (std::move (l));
-
- auto impl_lifetime_param
- = builder.new_lifetime_param (lifetime_param);
- impl_generics.push_back (std::move (impl_lifetime_param));
- }
- break;
-
- case GenericParam::Kind::Type: {
- TypeParam &type_param = (TypeParam &) *generic.get ();
-
- std::unique_ptr<Type> associated_type = builder.single_type_path (
- type_param.get_type_representation ().as_string ());
-
- GenericArg type_arg
- = GenericArg::create_type (std::move (associated_type));
- generic_args.push_back (std::move (type_arg));
-
- auto impl_type_param = builder.new_type_param (type_param);
- impl_generics.push_back (std::move (impl_type_param));
- }
- break;
-
- case GenericParam::Kind::Const: {
- rust_unreachable ();
-
- // TODO
- // const ConstGenericParam *const_param
- // = (const ConstGenericParam *) generic.get ();
- // std::unique_ptr<Expr> const_expr = nullptr;
-
- // GenericArg type_arg
- // = GenericArg::create_const (std::move (const_expr));
- // generic_args.push_back (std::move (type_arg));
- }
- break;
- }
- }
-
- GenericArgs generic_args_for_self (lifetime_args, generic_args,
- {} /*binding args*/, loc);
- std::unique_ptr<Type> self_type_path
- = impl_generics.empty ()
- ? builder.single_type_path (name)
- : builder.single_generic_type_path (name, generic_args_for_self);
-
- return std::unique_ptr<Item> (
- new TraitImpl (copy, /* unsafe */ false,
- /* exclam */ false, /* trait items */ {},
- std::move (impl_generics), std::move (self_type_path),
- WhereClause::create_empty (), Visibility::create_private (),
- {}, {}, loc));
+ // we should have two of these, so we don't run into issues with
+ // two paths sharing a node id
+ auto copy_bound = builder.type_path (LangItem::Kind::COPY);
+ auto copy_trait_path = builder.type_path (LangItem::Kind::COPY);
+
+ auto generics = setup_impl_generics (name, type_generics,
+ builder.trait_bound (copy_bound));
+
+ return builder.trait_impl (copy_trait_path, std::move (generics.self_type),
+ {}, std::move (generics.impl));
}
void
diff --git a/gcc/rust/expand/rust-derive-debug.cc b/gcc/rust/expand/rust-derive-debug.cc
new file mode 100644
index 0000000..a0bf9d8
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-debug.cc
@@ -0,0 +1,121 @@
+// 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-debug.h"
+#include "rust-ast.h"
+#include "rust-hir-map.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+DeriveDebug::DeriveDebug (location_t loc)
+ : DeriveVisitor (loc), expanded (nullptr)
+{}
+
+std::unique_ptr<Item>
+DeriveDebug::go (Item &item)
+{
+ item.accept_vis (*this);
+
+ rust_assert (expanded);
+
+ return std::move (expanded);
+}
+
+std::unique_ptr<AssociatedItem>
+DeriveDebug::stub_debug_fn ()
+{
+ auto unit_expr = builder.tuple ();
+ auto ok_expr
+ = ptrify (builder.path_in_expression (LangItem::Kind::RESULT_OK));
+
+ auto stub_return = builder.call (std::move (ok_expr), std::move (unit_expr));
+
+ // we can't use builder.block() here as it returns a unique_ptr<Expr> and
+ // Function's constructor expects a unique_ptr<BlockExpr>
+ auto block = std::unique_ptr<BlockExpr> (
+ new BlockExpr ({}, std::move (stub_return), {}, {}, tl::nullopt, loc, loc));
+
+ auto self = builder.self_ref_param ();
+
+ auto return_type
+ = ptrify (builder.type_path ({"core", "fmt", "Result"}, true));
+
+ auto mut_fmt_type_inner
+ = ptrify (builder.type_path ({"core", "fmt", "Formatter"}, true));
+
+ auto mut_fmt_type
+ = builder.reference_type (std::move (mut_fmt_type_inner), true);
+
+ auto fmt = builder.function_param (builder.identifier_pattern ("_fmt"),
+ std::move (mut_fmt_type));
+
+ auto params = vec (std::move (self), std::move (fmt));
+
+ auto function = builder.function ("fmt", std::move (params),
+ std::move (return_type), std::move (block));
+
+ return function;
+}
+
+std::unique_ptr<Item>
+DeriveDebug::stub_derive_impl (
+ std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics)
+{
+ auto trait_items = vec (stub_debug_fn ());
+
+ auto debug = builder.type_path ({"core", "fmt", "Debug"}, true);
+ auto generics
+ = setup_impl_generics (name, type_generics, builder.trait_bound (debug));
+
+ return builder.trait_impl (debug, std::move (generics.self_type),
+ std::move (trait_items),
+ std::move (generics.impl));
+}
+
+void
+DeriveDebug::visit_struct (StructStruct &struct_item)
+{
+ expanded = stub_derive_impl (struct_item.get_identifier ().as_string (),
+ struct_item.get_generic_params ());
+}
+
+void
+DeriveDebug::visit_tuple (TupleStruct &tuple_item)
+{
+ expanded = stub_derive_impl (tuple_item.get_identifier ().as_string (),
+ tuple_item.get_generic_params ());
+}
+
+void
+DeriveDebug::visit_enum (Enum &enum_item)
+{
+ expanded = stub_derive_impl (enum_item.get_identifier ().as_string (),
+ enum_item.get_generic_params ());
+}
+
+void
+DeriveDebug::visit_union (Union &enum_item)
+{
+ rust_error_at (loc, "derive(Debug) cannot be derived for unions");
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-debug.h b/gcc/rust/expand/rust-derive-debug.h
new file mode 100644
index 0000000..14af89e
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-debug.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_DERIVE_DEBUG_H
+#define RUST_DERIVE_DEBUG_H
+
+#include "rust-derive.h"
+#include "rust-ast.h"
+
+namespace Rust {
+namespace AST {
+
+// This derive is currently incomplete and only generate a stub implementation
+// which does not do any debug formatting
+class DeriveDebug : DeriveVisitor
+{
+public:
+ DeriveDebug (location_t loc);
+
+ std::unique_ptr<Item> go (Item &);
+
+private:
+ std::unique_ptr<Item> expanded;
+
+ std::unique_ptr<AssociatedItem> stub_debug_fn ();
+
+ std::unique_ptr<Item> stub_derive_impl (
+ std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics);
+
+ virtual void visit_struct (StructStruct &struct_item) override;
+ virtual void visit_tuple (TupleStruct &tuple_item) override;
+ virtual void visit_enum (Enum &enum_item) override;
+ virtual void visit_union (Union &enum_item) override;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_DERIVE_DEBUG_H
diff --git a/gcc/rust/expand/rust-derive-default.cc b/gcc/rust/expand/rust-derive-default.cc
new file mode 100644
index 0000000..2e8b456
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-default.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-default.h"
+#include "rust-ast.h"
+#include "rust-diagnostics.h"
+#include "rust-path.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+DeriveDefault::DeriveDefault (location_t loc)
+ : DeriveVisitor (loc), expanded (nullptr)
+{}
+
+std::unique_ptr<Item>
+DeriveDefault::go (Item &item)
+{
+ item.accept_vis (*this);
+
+ rust_assert (expanded);
+
+ return std::move (expanded);
+}
+
+std::unique_ptr<Expr>
+DeriveDefault::default_call (std::unique_ptr<Type> &&type)
+{
+ auto default_trait = builder.type_path ({"core", "default", "Default"}, true);
+
+ auto default_fn
+ = builder.qualified_path_in_expression (std::move (type), default_trait,
+ builder.path_segment ("default"));
+
+ return builder.call (std::move (default_fn));
+}
+
+std::unique_ptr<AssociatedItem>
+DeriveDefault::default_fn (std::unique_ptr<Expr> &&return_expr)
+{
+ auto self_ty
+ = std::unique_ptr<Type> (new TypePath (builder.type_path ("Self")));
+
+ auto block = std::unique_ptr<BlockExpr> (
+ new BlockExpr ({}, std::move (return_expr), {}, {}, tl::nullopt, loc, loc));
+
+ return builder.function ("default", {}, std::move (self_ty),
+ std::move (block));
+}
+
+std::unique_ptr<Item>
+DeriveDefault::default_impl (
+ std::unique_ptr<AssociatedItem> &&default_fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics)
+{
+ auto default_path = builder.type_path ({"core", "default", "Default"}, true);
+
+ auto trait_items = vec (std::move (default_fn));
+
+ auto generics = setup_impl_generics (name, type_generics,
+ builder.trait_bound (default_path));
+
+ return builder.trait_impl (default_path, std::move (generics.self_type),
+ std::move (trait_items),
+ std::move (generics.impl));
+}
+
+void
+DeriveDefault::visit_struct (StructStruct &item)
+{
+ if (item.is_unit_struct ())
+ {
+ auto unit_ctor
+ = builder.struct_expr_struct (item.get_struct_name ().as_string ());
+ expanded = default_impl (default_fn (std::move (unit_ctor)),
+ item.get_struct_name ().as_string (),
+ item.get_generic_params ());
+ return;
+ }
+
+ auto cloned_fields = std::vector<std::unique_ptr<StructExprField>> ();
+ for (auto &field : item.get_fields ())
+ {
+ auto name = field.get_field_name ().as_string ();
+ auto expr = default_call (field.get_field_type ().clone_type ());
+
+ cloned_fields.emplace_back (
+ builder.struct_expr_field (std::move (name), std::move (expr)));
+ }
+
+ auto ctor = builder.struct_expr (item.get_struct_name ().as_string (),
+ std::move (cloned_fields));
+
+ expanded = default_impl (default_fn (std::move (ctor)),
+ item.get_struct_name ().as_string (),
+ item.get_generic_params ());
+}
+
+void
+DeriveDefault::visit_tuple (TupleStruct &tuple_item)
+{
+ auto defaulted_fields = std::vector<std::unique_ptr<Expr>> ();
+
+ for (auto &field : tuple_item.get_fields ())
+ {
+ auto type = field.get_field_type ().clone_type ();
+
+ defaulted_fields.emplace_back (default_call (std::move (type)));
+ }
+
+ auto return_expr
+ = builder.call (builder.identifier (
+ tuple_item.get_struct_name ().as_string ()),
+ std::move (defaulted_fields));
+
+ expanded = default_impl (default_fn (std::move (return_expr)),
+ tuple_item.get_struct_name ().as_string (),
+ tuple_item.get_generic_params ());
+}
+
+void
+DeriveDefault::visit_enum (Enum &enum_item)
+{
+ // This is no longer the case in later Rust versions where you can choose a
+ // default variant to emit using the `#[default]` attribute:
+ //
+ // ```rust
+ // #[derive(Default)]
+ // enum Baz {
+ // #[default]
+ // A,
+ // B(i32),
+ // C { a: i32 }
+ // }
+ // ```
+ //
+ // will emit the following impl
+ //
+ // ```rust
+ // impl ::core::default::Default for Baz {
+ // #[inline]
+ // fn default() -> Baz { Self::A }
+ // }
+ // ```
+ rust_error_at (loc, ErrorCode::E0665,
+ "%<Default%> cannot be derived for enums, only structs");
+}
+
+void
+DeriveDefault::visit_union (Union &enum_item)
+{
+ rust_error_at (loc, "derive(Default) cannot be used on unions");
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-default.h b/gcc/rust/expand/rust-derive-default.h
new file mode 100644
index 0000000..eae9e85
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-default.h
@@ -0,0 +1,58 @@
+// 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_DEFAULT_H
+#define RUST_DERIVE_DEFAULT_H
+
+#include "rust-derive.h"
+#include "rust-ast.h"
+
+namespace Rust {
+namespace AST {
+
+// This derive is currently incomplete and only generate a stub implementation
+// which does not do any debug formatting
+class DeriveDefault : DeriveVisitor
+{
+public:
+ DeriveDefault (location_t loc);
+
+ std::unique_ptr<Item> go (Item &);
+
+private:
+ std::unique_ptr<Item> expanded;
+
+ std::unique_ptr<Expr> default_call (std::unique_ptr<Type> &&type);
+
+ std::unique_ptr<AssociatedItem>
+ default_fn (std::unique_ptr<Expr> &&return_expr);
+
+ std::unique_ptr<Item> default_impl (
+ std::unique_ptr<AssociatedItem> &&default_fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics);
+
+ virtual void visit_struct (StructStruct &struct_item) override;
+ virtual void visit_tuple (TupleStruct &tuple_item) override;
+ virtual void visit_enum (Enum &enum_item) override;
+ virtual void visit_union (Union &enum_item) override;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_DERIVE_DEFAULT_H
diff --git a/gcc/rust/expand/rust-derive-eq.cc b/gcc/rust/expand/rust-derive-eq.cc
new file mode 100644
index 0000000..5e7a894
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-eq.cc
@@ -0,0 +1,216 @@
+// 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-eq.h"
+#include "rust-ast.h"
+#include "rust-expr.h"
+#include "rust-item.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+DeriveEq::DeriveEq (location_t loc) : DeriveVisitor (loc) {}
+
+std::vector<std::unique_ptr<AST::Item>>
+DeriveEq::go (Item &item)
+{
+ item.accept_vis (*this);
+
+ return std::move (expanded);
+}
+
+std::unique_ptr<AssociatedItem>
+DeriveEq::assert_receiver_is_total_eq_fn (
+ std::vector<std::unique_ptr<Type>> &&types)
+{
+ auto stmts = std::vector<std::unique_ptr<Stmt>> ();
+
+ stmts.emplace_back (assert_param_is_eq ());
+
+ for (auto &&type : types)
+ stmts.emplace_back (assert_type_is_eq (std::move (type)));
+
+ auto block = std::unique_ptr<BlockExpr> (
+ new BlockExpr (std::move (stmts), nullptr, {}, {}, tl::nullopt, loc, loc));
+
+ auto self = builder.self_ref_param ();
+
+ return builder.function ("assert_receiver_is_total_eq",
+ vec (std::move (self)), {}, std::move (block));
+}
+
+std::unique_ptr<Stmt>
+DeriveEq::assert_param_is_eq ()
+{
+ auto eq_bound = std::unique_ptr<TypeParamBound> (
+ new TraitBound (builder.type_path ({"core", "cmp", "Eq"}, true), loc));
+
+ auto sized_bound = std::unique_ptr<TypeParamBound> (
+ new TraitBound (builder.type_path (LangItem::Kind::SIZED), loc, false,
+ true /* opening_question_mark */));
+
+ auto bounds = vec (std::move (eq_bound), std::move (sized_bound));
+
+ auto assert_param_is_eq = "AssertParamIsEq";
+
+ auto t = std::unique_ptr<GenericParam> (
+ new TypeParam (Identifier ("T"), loc, std::move (bounds)));
+
+ return builder.struct_struct (
+ assert_param_is_eq, vec (std::move (t)),
+ {StructField (
+ Identifier ("_t"),
+ builder.single_generic_type_path (
+ LangItem::Kind::PHANTOM_DATA,
+ GenericArgs (
+ {}, {GenericArg::create_type (builder.single_type_path ("T"))}, {})),
+ Visibility::create_private (), loc)});
+}
+
+std::unique_ptr<Stmt>
+DeriveEq::assert_type_is_eq (std::unique_ptr<Type> &&type)
+{
+ auto assert_param_is_eq = "AssertParamIsEq";
+
+ // AssertParamIsCopy::<Self>
+ auto assert_param_is_eq_ty
+ = std::unique_ptr<TypePathSegment> (new TypePathSegmentGeneric (
+ PathIdentSegment (assert_param_is_eq, loc), false,
+ GenericArgs ({}, {GenericArg::create_type (std::move (type))}, {}, loc),
+ loc));
+
+ // TODO: Improve this, it's really ugly
+ auto type_paths = std::vector<std::unique_ptr<TypePathSegment>> ();
+ type_paths.emplace_back (std::move (assert_param_is_eq_ty));
+
+ auto full_path
+ = std::unique_ptr<Type> (new TypePath ({std::move (type_paths)}, loc));
+
+ return builder.let (builder.wildcard (), std::move (full_path));
+}
+
+std::vector<std::unique_ptr<Item>>
+DeriveEq::eq_impls (
+ std::unique_ptr<AssociatedItem> &&fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics)
+{
+ // We create two copies of the type-path to avoid duplicate NodeIds
+ auto eq = builder.type_path ({"core", "cmp", "Eq"}, true);
+ auto eq_bound
+ = builder.trait_bound (builder.type_path ({"core", "cmp", "Eq"}, true));
+
+ auto steq = builder.type_path (LangItem::Kind::STRUCTURAL_TEQ);
+
+ auto trait_items = vec (std::move (fn));
+
+ auto eq_generics
+ = setup_impl_generics (name, type_generics, std::move (eq_bound));
+ auto steq_generics = setup_impl_generics (name, type_generics);
+
+ auto eq_impl = builder.trait_impl (eq, std::move (eq_generics.self_type),
+ std::move (trait_items),
+ std::move (eq_generics.impl));
+ auto steq_impl
+ = builder.trait_impl (steq, std::move (steq_generics.self_type),
+ std::move (trait_items),
+ std::move (steq_generics.impl));
+
+ return vec (std::move (eq_impl), std::move (steq_impl));
+}
+
+void
+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 ());
+
+ expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
+ item.get_identifier ().as_string (),
+ item.get_generic_params ());
+}
+
+void
+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 ());
+
+ expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
+ item.get_identifier ().as_string (),
+ item.get_generic_params ());
+}
+
+void
+DeriveEq::visit_enum (Enum &item)
+{
+ auto types = std::vector<std::unique_ptr<Type>> ();
+
+ for (auto &variant : item.get_variants ())
+ {
+ switch (variant->get_enum_item_kind ())
+ {
+ case EnumItem::Kind::Identifier:
+ case EnumItem::Kind::Discriminant:
+ // nothing to do as they contain no inner types
+ continue;
+ 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 ());
+
+ break;
+ }
+ 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 ());
+
+ break;
+ }
+ }
+ }
+
+ expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
+ item.get_identifier ().as_string (),
+ item.get_generic_params ());
+}
+
+void
+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 ());
+
+ expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
+ item.get_identifier ().as_string (),
+ item.get_generic_params ());
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-eq.h b/gcc/rust/expand/rust-derive-eq.h
new file mode 100644
index 0000000..17af526
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-eq.h
@@ -0,0 +1,82 @@
+// 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_EQ_H
+#define RUST_DERIVE_EQ_H
+
+#include "rust-derive.h"
+
+namespace Rust {
+namespace AST {
+
+// FIXME: Need to figure out structuraleq marker trait
+
+class DeriveEq : DeriveVisitor
+{
+public:
+ DeriveEq (location_t loc);
+
+ std::vector<std::unique_ptr<AST::Item>> go (Item &item);
+
+private:
+ std::vector<std::unique_ptr<Item>> expanded;
+
+ /**
+ * Create the actual `assert_receiver_is_total_eq` function of the
+ * implementation, which asserts that every type contained within our targeted
+ * type also implements `Eq`.
+ */
+ std::unique_ptr<AssociatedItem>
+ assert_receiver_is_total_eq_fn (std::vector<std::unique_ptr<Type>> &&types);
+
+ /**
+ * Create the Eq trait implementation for a type
+ *
+ * impl Eq for <type> {
+ * <assert_receiver_is_total_eq>
+ * }
+ *
+ */
+ std::vector<std::unique_ptr<Item>>
+ eq_impls (std::unique_ptr<AssociatedItem> &&fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics);
+
+ /**
+ * Generate the following structure definition
+ *
+ * struct AssertParamIsEq<T: Eq + ?Sized> { _t: PhantomData<T> }
+ */
+ std::unique_ptr<Stmt> assert_param_is_eq ();
+
+ /**
+ * Generate a let statement to assert a type implements `Eq`
+ *
+ * let _: AssertParamIsEq<type>;
+ */
+ 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);
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_DERIVE_EQ_H
diff --git a/gcc/rust/expand/rust-derive-hash.cc b/gcc/rust/expand/rust-derive-hash.cc
new file mode 100644
index 0000000..0c9b0f7
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-hash.cc
@@ -0,0 +1,293 @@
+// 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-hash.h"
+#include "rust-ast.h"
+#include "rust-expr.h"
+#include "rust-item.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-stmt.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+DeriveHash::DeriveHash (location_t loc) : DeriveVisitor (loc) {}
+
+std::unique_ptr<AST::Item>
+DeriveHash::go (Item &item)
+{
+ item.accept_vis (*this);
+
+ return std::move (expanded);
+}
+
+std::unique_ptr<Expr>
+DeriveHash::hash_call (std::unique_ptr<Expr> &&value)
+{
+ auto hash
+ = builder.path_in_expression ({"core", "hash", "Hash", "hash"}, true);
+
+ return builder.call (ptrify (hash),
+ vec (std::move (value),
+ builder.identifier (DeriveHash::state)));
+}
+
+std::unique_ptr<AssociatedItem>
+DeriveHash::hash_fn (std::unique_ptr<BlockExpr> &&block)
+{
+ auto hash_calls = std::vector<std::unique_ptr<Stmt>> ();
+
+ auto state_type = std::unique_ptr<TypeNoBounds> (
+ new TypePath (builder.type_path (DeriveHash::state_type)));
+ auto state_param =
+
+ builder.function_param (builder.identifier_pattern (DeriveHash::state),
+ builder.reference_type (std::move (state_type),
+ true));
+
+ auto params = vec (builder.self_ref_param (), std::move (state_param));
+ auto bounds = vec (
+ builder.trait_bound (builder.type_path ({"core", "hash", "Hasher"}, true)));
+ auto generics = vec (
+ builder.generic_type_param (DeriveHash::state_type, std::move (bounds)));
+
+ return builder.function ("hash", std::move (params), nullptr,
+ std::move (block), std::move (generics));
+}
+
+std::unique_ptr<Item>
+DeriveHash::hash_impl (
+ std::unique_ptr<AssociatedItem> &&hash_fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics)
+{
+ auto hash_path = builder.type_path ({"core", "hash", "Hash"}, true);
+
+ auto trait_items = vec (std::move (hash_fn));
+
+ auto generics = setup_impl_generics (name, type_generics,
+ builder.trait_bound (hash_path));
+
+ return builder.trait_impl (hash_path, std::move (generics.self_type),
+ std::move (trait_items),
+ std::move (generics.impl));
+}
+
+void
+DeriveHash::visit_struct (StructStruct &item)
+{
+ auto hash_calls = std::vector<std::unique_ptr<Stmt>> ();
+
+ for (auto &field : item.get_fields ())
+ {
+ auto value = builder.ref (
+ builder.field_access (builder.identifier ("self"),
+ field.get_field_name ().as_string ()));
+
+ auto stmt = builder.statementify (hash_call (std::move (value)));
+
+ hash_calls.emplace_back (std::move (stmt));
+ }
+
+ auto block = builder.block (std::move (hash_calls));
+
+ expanded = hash_impl (hash_fn (std::move (block)),
+ item.get_identifier ().as_string (),
+ item.get_generic_params ());
+}
+
+void
+DeriveHash::visit_tuple (TupleStruct &item)
+{
+ auto hash_calls = std::vector<std::unique_ptr<Stmt>> ();
+
+ for (size_t idx = 0; idx < item.get_fields ().size (); idx++)
+ {
+ auto value = builder.ref (builder.tuple_idx ("self", idx));
+
+ auto stmt = builder.statementify (hash_call (std::move (value)));
+
+ hash_calls.emplace_back (std::move (stmt));
+ }
+
+ auto block = builder.block (std::move (hash_calls));
+
+ expanded = hash_impl (hash_fn (std::move (block)),
+ item.get_identifier ().as_string (),
+ item.get_generic_params ());
+}
+
+MatchCase
+DeriveHash::match_enum_tuple (PathInExpression variant_path,
+ const EnumItemTuple &variant)
+{
+ auto self_patterns = std::vector<std::unique_ptr<Pattern>> ();
+ auto hash_calls = std::vector<std::unique_ptr<Stmt>> ();
+
+ for (size_t i = 0; i < variant.get_tuple_fields ().size (); i++)
+ {
+ auto pattern = "__self_" + std::to_string (i);
+
+ auto call = hash_call (builder.ref (builder.identifier (pattern)));
+
+ self_patterns.emplace_back (builder.identifier_pattern (pattern));
+ hash_calls.emplace_back (builder.statementify (std::move (call)));
+ }
+
+ auto patterns_elts = std::unique_ptr<TupleStructItems> (
+ new TupleStructItemsNoRange (std::move (self_patterns)));
+ auto pattern = std::unique_ptr<Pattern> (
+ new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
+ variant_path, std::move (patterns_elts))),
+ false, false, loc));
+
+ auto block = builder.block (std::move (hash_calls));
+
+ return builder.match_case (std::move (pattern), std::move (block));
+}
+
+MatchCase
+DeriveHash::match_enum_struct (PathInExpression variant_path,
+ const EnumItemStruct &variant)
+{
+ auto field_patterns = std::vector<std::unique_ptr<StructPatternField>> ();
+ auto hash_calls = std::vector<std::unique_ptr<Stmt>> ();
+
+ for (const auto &field : variant.get_struct_fields ())
+ {
+ auto call = hash_call (builder.ref (
+ builder.identifier (field.get_field_name ().as_string ())));
+
+ field_patterns.emplace_back (
+ std::unique_ptr<StructPatternField> (new StructPatternFieldIdent (
+ field.get_field_name (), false /* is_ref? true? */, false, {}, loc)));
+
+ hash_calls.emplace_back (builder.statementify (std::move (call)));
+ }
+
+ auto pattern_elts = StructPatternElements (std::move (field_patterns));
+ auto pattern = std::unique_ptr<Pattern> (
+ new ReferencePattern (std::unique_ptr<Pattern> (new StructPattern (
+ variant_path, loc, pattern_elts)),
+ false, false, loc));
+
+ auto block = builder.block (std::move (hash_calls));
+ return builder.match_case (std::move (pattern), std::move (block));
+}
+
+void
+DeriveHash::visit_enum (Enum &item)
+{
+ // Enums are a bit different: We start by hashing the discriminant value of
+ // the enum instance, and then hash all of the data contained in each of the
+ // enum's variants. For data-less variants, we don't have any data to hash, so
+ // hashing the discriminant value is enough. To access the rest of the
+ // variants' data, we create a match and destructure each internal field and
+ // hash it.
+ //
+ // So for example with the following enum:
+ //
+ // ```rust
+ // enum Foo {
+ // A,
+ // B(i32),
+ // C { a: i32 },
+ // }
+ // ```
+ //
+ // we create the following implementation:
+ //
+ // ```rust
+ // fn hash<H: Hasher>(&self, state: &mut H) {
+ // let discriminant = intrinsics::discriminant_value(&self);
+ // Hash::hash(&discriminant, state);
+ //
+ // match self {
+ // B(self_0) => { Hash::hash(self_0, state); },
+ // C { a } => { Hash::hash(a, state); },
+ // _ => {},
+ // }
+ // }
+ // ```
+ //
+ // Note the extra wildcard pattern to satisfy the exhaust checker.
+
+ auto cases = std::vector<MatchCase> ();
+ auto type_name = item.get_identifier ().as_string ();
+
+ auto intrinsic = ptrify (
+ builder.path_in_expression ({"core", "intrinsics", "discriminant_value"},
+ true));
+
+ auto let_discr
+ = builder.let (builder.identifier_pattern (DeriveHash::discr), nullptr,
+ builder.call (std::move (intrinsic),
+ builder.identifier ("self")));
+
+ auto discr_hash = builder.statementify (
+ hash_call (builder.ref (builder.identifier (DeriveHash::discr))));
+
+ for (auto &variant : item.get_variants ())
+ {
+ auto variant_path
+ = builder.variant_path (type_name,
+ variant->get_identifier ().as_string ());
+
+ switch (variant->get_enum_item_kind ())
+ {
+ case EnumItem::Kind::Identifier:
+ case EnumItem::Kind::Discriminant:
+ // nothing to do in these cases, as we just need to hash the
+ // discriminant value
+ continue;
+ case EnumItem::Kind::Tuple:
+ cases.emplace_back (
+ match_enum_tuple (variant_path,
+ static_cast<EnumItemTuple &> (*variant)));
+ break;
+ case EnumItem::Kind::Struct:
+ cases.emplace_back (
+ match_enum_struct (variant_path,
+ static_cast<EnumItemStruct &> (*variant)));
+ break;
+ }
+ }
+
+ // The extra empty wildcard case
+ cases.emplace_back (
+ builder.match_case (builder.wildcard (), builder.block ()));
+
+ auto match = builder.match (builder.identifier ("self"), std::move (cases));
+
+ auto block
+ = builder.block (vec (std::move (let_discr), std::move (discr_hash)),
+ std::move (match));
+
+ expanded = hash_impl (hash_fn (std::move (block)), type_name,
+ item.get_generic_params ());
+}
+
+void
+DeriveHash::visit_union (Union &item)
+{
+ rust_error_at (item.get_locus (), "derive(Hash) cannot be used on unions");
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-hash.h b/gcc/rust/expand/rust-derive-hash.h
new file mode 100644
index 0000000..02b0bee
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-hash.h
@@ -0,0 +1,61 @@
+// 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_HASH_H
+#define RUST_DERIVE_HASH_H
+
+#include "rust-derive.h"
+
+namespace Rust {
+namespace AST {
+
+class DeriveHash : DeriveVisitor
+{
+public:
+ DeriveHash (location_t loc);
+
+ std::unique_ptr<AST::Item> go (Item &item);
+
+private:
+ std::unique_ptr<Item> expanded;
+
+ constexpr static const char *state = "#state";
+ constexpr static const char *state_type = "#__H";
+ constexpr static const char *discr = "#discr";
+
+ std::unique_ptr<Expr> hash_call (std::unique_ptr<Expr> &&value);
+ std::unique_ptr<AssociatedItem> hash_fn (std::unique_ptr<BlockExpr> &&block);
+ std::unique_ptr<Item>
+ hash_impl (std::unique_ptr<AssociatedItem> &&hash_fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics);
+
+ MatchCase match_enum_tuple (PathInExpression variant_path,
+ const EnumItemTuple &variant);
+ 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);
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_DERIVE_HASH_H
diff --git a/gcc/rust/expand/rust-derive-partial-eq.cc b/gcc/rust/expand/rust-derive-partial-eq.cc
new file mode 100644
index 0000000..ff66faa
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-partial-eq.cc
@@ -0,0 +1,313 @@
+// 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-partial-eq.h"
+#include "rust-ast.h"
+#include "rust-expr.h"
+#include "rust-item.h"
+#include "rust-operators.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+DerivePartialEq::DerivePartialEq (location_t loc) : DeriveVisitor (loc) {}
+
+std::vector<std::unique_ptr<AST::Item>>
+DerivePartialEq::go (Item &item)
+{
+ item.accept_vis (*this);
+
+ return std::move (expanded);
+}
+
+std::vector<std::unique_ptr<Item>>
+DerivePartialEq::partialeq_impls (
+ std::unique_ptr<AssociatedItem> &&eq_fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics)
+{
+ auto eq = builder.type_path (LangItem::Kind::EQ);
+ auto speq = builder.type_path (LangItem::Kind::STRUCTURAL_PEQ);
+
+ auto trait_items = vec (std::move (eq_fn));
+
+ // no extra bound on StructuralPeq
+ auto peq_generics
+ = setup_impl_generics (name, type_generics, builder.trait_bound (eq));
+ auto speq_generics = setup_impl_generics (name, type_generics);
+
+ auto peq = builder.trait_impl (eq, std::move (peq_generics.self_type),
+ std::move (trait_items),
+ std::move (peq_generics.impl));
+
+ auto structural_peq
+ = builder.trait_impl (speq, std::move (speq_generics.self_type), {},
+ std::move (speq_generics.impl));
+
+ return vec (std::move (peq), std::move (structural_peq));
+}
+
+std::unique_ptr<AssociatedItem>
+DerivePartialEq::eq_fn (std::unique_ptr<Expr> &&cmp_expression,
+ std::string type_name)
+{
+ auto block = builder.block (tl::nullopt, std::move (cmp_expression));
+
+ auto self_type
+ = std::unique_ptr<TypeNoBounds> (new TypePath (builder.type_path ("Self")));
+
+ auto params
+ = vec (builder.self_ref_param (),
+ builder.function_param (builder.identifier_pattern ("other"),
+ builder.reference_type (
+ std::move (self_type))));
+
+ return builder.function ("eq", std::move (params),
+ builder.single_type_path ("bool"),
+ std::move (block));
+}
+
+DerivePartialEq::SelfOther
+DerivePartialEq::tuple_indexes (int idx)
+{
+ return SelfOther{
+ builder.tuple_idx ("self", idx),
+ builder.tuple_idx ("other", idx),
+ };
+}
+
+DerivePartialEq::SelfOther
+DerivePartialEq::field_acccesses (const std::string &field_name)
+{
+ return SelfOther{
+ builder.field_access (builder.identifier ("self"), field_name),
+ builder.field_access (builder.identifier ("other"), field_name),
+ };
+}
+
+std::unique_ptr<Expr>
+DerivePartialEq::build_eq_expression (
+ std::vector<SelfOther> &&field_expressions)
+{
+ // for unit structs or empty tuples, this is always true
+ if (field_expressions.empty ())
+ return builder.literal_bool (true);
+
+ auto cmp_expression
+ = builder.comparison_expr (std::move (field_expressions.at (0).self_expr),
+ std::move (field_expressions.at (0).other_expr),
+ ComparisonOperator::EQUAL);
+
+ for (size_t i = 1; i < field_expressions.size (); i++)
+ {
+ auto tmp = builder.comparison_expr (
+ std::move (field_expressions.at (i).self_expr),
+ std::move (field_expressions.at (i).other_expr),
+ ComparisonOperator::EQUAL);
+
+ cmp_expression
+ = builder.boolean_operation (std::move (cmp_expression),
+ std::move (tmp),
+ LazyBooleanOperator::LOGICAL_AND);
+ }
+
+ return cmp_expression;
+}
+
+void
+DerivePartialEq::visit_tuple (TupleStruct &item)
+{
+ auto type_name = item.get_struct_name ().as_string ();
+ auto fields = std::vector<SelfOther> ();
+
+ for (size_t idx = 0; idx < item.get_fields ().size (); idx++)
+ fields.emplace_back (tuple_indexes (idx));
+
+ auto fn = eq_fn (build_eq_expression (std::move (fields)), type_name);
+
+ expanded
+ = partialeq_impls (std::move (fn), type_name, item.get_generic_params ());
+}
+
+void
+DerivePartialEq::visit_struct (StructStruct &item)
+{
+ auto type_name = item.get_struct_name ().as_string ();
+ auto fields = std::vector<SelfOther> ();
+
+ for (auto &field : item.get_fields ())
+ fields.emplace_back (
+ field_acccesses (field.get_field_name ().as_string ()));
+
+ auto fn = eq_fn (build_eq_expression (std::move (fields)), type_name);
+
+ expanded
+ = partialeq_impls (std::move (fn), type_name, item.get_generic_params ());
+}
+
+MatchCase
+DerivePartialEq::match_enum_identifier (
+ PathInExpression variant_path, const std::unique_ptr<EnumItem> &variant)
+{
+ auto inner_ref_patterns
+ = vec (builder.ref_pattern (
+ std::unique_ptr<Pattern> (new PathInExpression (variant_path))),
+ builder.ref_pattern (
+ std::unique_ptr<Pattern> (new PathInExpression (variant_path))));
+
+ auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ std::move (inner_ref_patterns));
+
+ auto pattern = std::make_unique<TuplePattern> (std::move (tuple_items), loc);
+
+ return builder.match_case (std::move (pattern), builder.literal_bool (true));
+}
+
+MatchCase
+DerivePartialEq::match_enum_tuple (PathInExpression variant_path,
+ const EnumItemTuple &variant)
+{
+ auto self_patterns = std::vector<std::unique_ptr<Pattern>> ();
+ auto other_patterns = std::vector<std::unique_ptr<Pattern>> ();
+
+ auto self_other_exprs = std::vector<SelfOther> ();
+
+ for (size_t i = 0; i < variant.get_tuple_fields ().size (); i++)
+ {
+ // The patterns we're creating for each field are `self_<i>` and
+ // `other_<i>` where `i` is the index 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 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 (
+ builder.identifier_pattern (other_pattern_str));
+
+ self_other_exprs.emplace_back (SelfOther{
+ builder.identifier (self_pattern_str),
+ builder.identifier (other_pattern_str),
+ });
+ }
+
+ auto self_pattern_items = std::unique_ptr<TupleStructItems> (
+ new TupleStructItemsNoRange (std::move (self_patterns)));
+ auto other_pattern_items = std::unique_ptr<TupleStructItems> (
+ new TupleStructItemsNoRange (std::move (other_patterns)));
+
+ auto self_pattern = std::unique_ptr<Pattern> (
+ new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
+ variant_path, std::move (self_pattern_items))),
+ false, false, loc));
+ auto other_pattern = std::unique_ptr<Pattern> (
+ new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
+ variant_path, std::move (other_pattern_items))),
+ 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));
+}
+
+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 ();
+}
+
+void
+DerivePartialEq::visit_enum (Enum &item)
+{
+ auto cases = std::vector<MatchCase> ();
+ auto type_name = item.get_identifier ().as_string ();
+
+ for (auto &variant : item.get_variants ())
+ {
+ auto variant_path
+ = builder.variant_path (type_name,
+ variant->get_identifier ().as_string ());
+
+ switch (variant->get_enum_item_kind ())
+ {
+ case EnumItem::Kind::Identifier:
+ case EnumItem::Kind::Discriminant:
+ cases.emplace_back (match_enum_identifier (variant_path, variant));
+ break;
+ case EnumItem::Kind::Tuple:
+ cases.emplace_back (
+ match_enum_tuple (variant_path,
+ static_cast<EnumItemTuple &> (*variant)));
+ break;
+ case EnumItem::Kind::Struct:
+ rust_sorry_at (
+ item.get_locus (),
+ "cannot derive(PartialEq) for enum struct variants yet");
+ break;
+ }
+ }
+
+ // NOTE: Mention using discriminant_value and skipping that last case, and
+ // instead skipping all identifiers/discriminant enum items and returning
+ // `true` in the wildcard case
+
+ // In case the two instances of `Self` don't have the same discriminant,
+ // automatically return false.
+ cases.emplace_back (
+ builder.match_case (builder.wildcard (), builder.literal_bool (false)));
+
+ auto match
+ = builder.match (builder.tuple (vec (builder.identifier ("self"),
+ builder.identifier ("other"))),
+ std::move (cases));
+
+ auto fn = eq_fn (std::move (match), type_name);
+
+ expanded
+ = partialeq_impls (std::move (fn), type_name, item.get_generic_params ());
+}
+
+void
+DerivePartialEq::visit_union (Union &item)
+{
+ rust_error_at (item.get_locus (),
+ "derive(PartialEq) cannot be used on unions");
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-partial-eq.h b/gcc/rust/expand/rust-derive-partial-eq.h
new file mode 100644
index 0000000..ac963a6
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-partial-eq.h
@@ -0,0 +1,85 @@
+// 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_PARTIAL_EQ_H
+#define RUST_DERIVE_PARTIAL_EQ_H
+
+#include "rust-derive.h"
+#include "rust-path.h"
+
+namespace Rust {
+namespace AST {
+
+class DerivePartialEq : DeriveVisitor
+{
+public:
+ DerivePartialEq (location_t loc);
+
+ std::vector<std::unique_ptr<AST::Item>> go (Item &item);
+
+private:
+ std::vector<std::unique_ptr<Item>> expanded;
+
+ /**
+ * Generate both an implementation of `PartialEq` and `StructuralPartialEq`
+ * for the given type
+ */
+ std::vector<std::unique_ptr<Item>> partialeq_impls (
+ std::unique_ptr<AssociatedItem> &&eq_fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics);
+
+ std::unique_ptr<AssociatedItem> eq_fn (std::unique_ptr<Expr> &&cmp_expression,
+ std::string type_name);
+
+ /**
+ * A pair of two expressions from each instance being compared. E.g. this
+ * could be `self.0` and `other.0`, or `self.field` and `other.field`
+ */
+ struct SelfOther
+ {
+ std::unique_ptr<Expr> self_expr;
+ std::unique_ptr<Expr> other_expr;
+ };
+
+ SelfOther tuple_indexes (int idx);
+ SelfOther field_acccesses (const std::string &field_name);
+
+ /**
+ * Build a suite of equality arithmetic expressions chained together by a
+ * boolean AND operator
+ */
+ std::unique_ptr<Expr>
+ build_eq_expression (std::vector<SelfOther> &&field_expressions);
+
+ MatchCase match_enum_identifier (PathInExpression variant_path,
+ const std::unique_ptr<EnumItem> &variant);
+ MatchCase match_enum_tuple (PathInExpression variant_path,
+ const EnumItemTuple &variant);
+ 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);
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_DERIVE_PARTIAL_EQ_H
diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc
index a378483..015b81e 100644
--- a/gcc/rust/expand/rust-derive.cc
+++ b/gcc/rust/expand/rust-derive.cc
@@ -19,6 +19,11 @@
#include "rust-derive.h"
#include "rust-derive-clone.h"
#include "rust-derive-copy.h"
+#include "rust-derive-debug.h"
+#include "rust-derive-default.h"
+#include "rust-derive-eq.h"
+#include "rust-derive-partial-eq.h"
+#include "rust-derive-hash.h"
namespace Rust {
namespace AST {
@@ -27,28 +32,113 @@ DeriveVisitor::DeriveVisitor (location_t loc)
: loc (loc), builder (Builder (loc))
{}
-std::unique_ptr<Item>
+std::vector<std::unique_ptr<Item>>
DeriveVisitor::derive (Item &item, const Attribute &attr,
BuiltinMacro to_derive)
{
+ auto loc = attr.get_locus ();
+
switch (to_derive)
{
case BuiltinMacro::Clone:
- return DeriveClone (attr.get_locus ()).go (item);
+ return vec (DeriveClone (loc).go (item));
case BuiltinMacro::Copy:
- return DeriveCopy (attr.get_locus ()).go (item);
+ return vec (DeriveCopy (loc).go (item));
case BuiltinMacro::Debug:
+ rust_warning_at (
+ loc, 0,
+ "derive(Debug) is not fully implemented yet and has no effect - only a "
+ "stub implementation will be generated");
+ return vec (DeriveDebug (loc).go (item));
case BuiltinMacro::Default:
+ return vec (DeriveDefault (loc).go (item));
case BuiltinMacro::Eq:
+ return DeriveEq (loc).go (item);
case BuiltinMacro::PartialEq:
+ return DerivePartialEq (loc).go (item);
+ case BuiltinMacro::Hash:
+ return vec (DeriveHash (loc).go (item));
case BuiltinMacro::Ord:
case BuiltinMacro::PartialOrd:
- case BuiltinMacro::Hash:
default:
- rust_sorry_at (attr.get_locus (), "unimplemented builtin derive macro");
- return nullptr;
+ rust_sorry_at (loc, "unimplemented builtin derive macro");
+ return {};
};
}
+DeriveVisitor::ImplGenerics
+DeriveVisitor::setup_impl_generics (
+ const std::string &type_name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics,
+ tl::optional<std::unique_ptr<TypeParamBound>> &&extra_bound) const
+{
+ std::vector<Lifetime> lifetime_args;
+ std::vector<GenericArg> generic_args;
+ std::vector<std::unique_ptr<GenericParam>> impl_generics;
+ for (const auto &generic : type_generics)
+ {
+ switch (generic->get_kind ())
+ {
+ case GenericParam::Kind::Lifetime: {
+ LifetimeParam &lifetime_param = (LifetimeParam &) *generic.get ();
+
+ Lifetime l = builder.new_lifetime (lifetime_param.get_lifetime ());
+ lifetime_args.push_back (std::move (l));
+
+ auto impl_lifetime_param
+ = builder.new_lifetime_param (lifetime_param);
+ impl_generics.push_back (std::move (impl_lifetime_param));
+ }
+ break;
+
+ case GenericParam::Kind::Type: {
+ TypeParam &type_param = (TypeParam &) *generic.get ();
+
+ std::unique_ptr<Type> associated_type = builder.single_type_path (
+ type_param.get_type_representation ().as_string ());
+
+ GenericArg type_arg
+ = GenericArg::create_type (std::move (associated_type));
+ generic_args.push_back (std::move (type_arg));
+
+ std::vector<std::unique_ptr<TypeParamBound>> extra_bounds;
+
+ if (extra_bound)
+ extra_bounds.emplace_back (std::move (*extra_bound));
+
+ auto impl_type_param
+ = builder.new_type_param (type_param, std::move (extra_bounds));
+
+ impl_generics.push_back (std::move (impl_type_param));
+ }
+ break;
+
+ case GenericParam::Kind::Const: {
+ rust_unreachable ();
+
+ // TODO
+ // const ConstGenericParam *const_param
+ // = (const ConstGenericParam *) generic.get ();
+ // std::unique_ptr<Expr> const_expr = nullptr;
+
+ // GenericArg type_arg
+ // = GenericArg::create_const (std::move (const_expr));
+ // generic_args.push_back (std::move (type_arg));
+ }
+ break;
+ }
+ }
+
+ auto generic_args_for_self
+ = GenericArgs (lifetime_args, generic_args, {} /*binding args*/, loc);
+
+ std::unique_ptr<Type> self_type_path
+ = impl_generics.empty ()
+ ? builder.single_type_path (type_name)
+ : builder.single_generic_type_path (type_name, generic_args_for_self);
+
+ return ImplGenerics{std::move (self_type_path), std::move (impl_generics)};
+}
+
} // namespace AST
} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index 967064c..5fca49c 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -34,8 +34,12 @@ namespace AST {
class DeriveVisitor : public AST::ASTVisitor
{
public:
- static std::unique_ptr<Item> derive (Item &item, const Attribute &derive,
- BuiltinMacro to_derive);
+ /**
+ * Expand a built-in derive macro on an item. This may generate multiple items
+ * which all need to be integrated to the existing AST
+ */
+ static std::vector<std::unique_ptr<Item>>
+ derive (Item &item, const Attribute &derive, BuiltinMacro to_derive);
protected:
DeriveVisitor (location_t loc);
@@ -43,6 +47,29 @@ protected:
location_t loc;
Builder builder;
+ struct ImplGenerics
+ {
+ /* The type we are deriving the impl for */
+ std::unique_ptr<Type> self_type;
+
+ /* Generics for the impl itself */
+ std::vector<std::unique_ptr<GenericParam>> impl;
+ };
+
+ /**
+ * Create the generic parameters for a derive impl block. Derived impl blocks
+ * will often share the same structure of reusing the exact same bounds as
+ * their original type, plus adding an extra one for the trait we are
+ * deriving. For example, when deriving `Clone` on `Foo<T>`, you want to make
+ * sure that you implement `Clone` only if `T: Clone` - so you add an extra
+ * `Clone` bound to all of your generics.
+ */
+ ImplGenerics setup_impl_generics (
+ const std::string &type_name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics,
+ tl::optional<std::unique_ptr<TypeParamBound>> &&extra_bound
+ = tl::nullopt) const;
+
private:
// the 4 "allowed" visitors, which a derive-visitor can specify and override
virtual void visit_struct (StructStruct &struct_item) = 0;
@@ -81,8 +108,6 @@ private:
virtual void visit (Lifetime &lifetime) override final{};
virtual void visit (LifetimeParam &lifetime_param) override final{};
virtual void visit (ConstGenericParam &const_param) override final{};
- virtual void visit (RegularPath &path) override final{};
- virtual void visit (LangItemPath &path) override final{};
virtual void visit (PathInExpression &path) override final{};
virtual void visit (TypePathSegment &segment) override final{};
virtual void visit (TypePathSegmentGeneric &segment) override final{};
@@ -146,6 +171,7 @@ private:
virtual void visit (AwaitExpr &expr) override final{};
virtual void visit (AsyncBlockExpr &expr) override final{};
virtual void visit (InlineAsm &expr) override final{};
+ virtual void visit (LlvmInlineAsm &expr) override final{};
virtual void visit (TypeParam &param) override final{};
virtual void visit (LifetimeWhereClauseItem &item) override final{};
virtual void visit (TypeBoundWhereClauseItem &item) override final{};
diff --git a/gcc/rust/expand/rust-expand-format-args.cc b/gcc/rust/expand/rust-expand-format-args.cc
index c8087ee..af6182f 100644
--- a/gcc/rust/expand/rust-expand-format-args.cc
+++ b/gcc/rust/expand/rust-expand-format-args.cc
@@ -120,7 +120,7 @@ expand_format_args (AST::FormatArgs &fmt,
auto pieces = builder.ref (builder.array (std::move (static_pieces)));
auto args_slice = builder.ref (builder.array (std::move (args_array)));
- auto final_path = make_unique<AST::PathInExpression> (
+ auto final_path = std::make_unique<AST::PathInExpression> (
builder.path_in_expression ({"core", "fmt", "Arguments", "new_v1"}));
auto final_args = std::vector<std::unique_ptr<AST::Expr>> ();
final_args.emplace_back (std::move (pieces));
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index 38399d0d..42df5e1 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -43,7 +43,7 @@ ExpandVisitor::go (AST::Crate &crate)
visit (crate);
}
-static std::unique_ptr<AST::Item>
+static std::vector<std::unique_ptr<AST::Item>>
builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
BuiltinMacro to_derive)
{
@@ -189,11 +189,12 @@ ExpandVisitor::expand_inner_items (
to_derive.get ().as_string ());
if (maybe_builtin.has_value ())
{
- auto new_item
+ auto new_items
= builtin_derive_item (item, current,
maybe_builtin.value ());
- it = items.insert (it, std::move (new_item));
+ for (auto &&new_item : new_items)
+ it = items.insert (it, std::move (new_item));
}
else
{
@@ -276,12 +277,14 @@ ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
to_derive.get ().as_string ());
if (maybe_builtin.has_value ())
{
- auto new_item
+ auto new_items
= builtin_derive_item (item, current,
maybe_builtin.value ());
+
// this inserts the derive *before* the item - is it a
// problem?
- it = stmts.insert (it, std::move (new_item));
+ for (auto &&new_item : new_items)
+ it = stmts.insert (it, std::move (new_item));
}
else
{
@@ -477,14 +480,18 @@ ExpandVisitor::visit (AST::MacroInvocation &macro_invoc)
void
ExpandVisitor::visit (AST::PathInExpression &path)
{
- for (auto &segment : path.get_segments ())
- if (segment.has_generic_args ())
- expand_generic_args (segment.get_generic_args ());
+ if (!path.is_lang_item ())
+ for (auto &segment : path.get_segments ())
+ if (segment.has_generic_args ())
+ expand_generic_args (segment.get_generic_args ());
}
void
ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
-{}
+{
+ if (segment.has_generic_args ())
+ expand_generic_args (segment.get_generic_args ());
+}
void
ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
@@ -718,6 +725,12 @@ ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
}
void
+ExpandVisitor::visit (AST::Module &module)
+{
+ expand_inner_items (module.get_items ());
+}
+
+void
ExpandVisitor::visit (AST::ExternCrate &crate)
{}
@@ -855,7 +868,7 @@ ExpandVisitor::visit (AST::Trait &trait)
std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
extractor
- = [] (AST::SingleASTNode node) { return node.take_trait_item (); };
+ = [] (AST::SingleASTNode node) { return node.take_assoc_item (); };
expand_macro_children (MacroExpander::ContextType::TRAIT,
trait.get_trait_items (), extractor);
@@ -882,7 +895,8 @@ ExpandVisitor::visit (AST::InherentImpl &impl)
expand_where_clause (impl.get_where_clause ());
std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
- extractor = [] (AST::SingleASTNode node) { return node.take_impl_item (); };
+ extractor
+ = [] (AST::SingleASTNode node) { return node.take_assoc_item (); };
expand_macro_children (MacroExpander::ContextType::IMPL,
impl.get_impl_items (), extractor);
@@ -910,7 +924,7 @@ ExpandVisitor::visit (AST::TraitImpl &impl)
std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
extractor
- = [] (AST::SingleASTNode node) { return node.take_trait_impl_item (); };
+ = [] (AST::SingleASTNode node) { return node.take_assoc_item (); };
expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
impl.get_impl_items (), extractor);
diff --git a/gcc/rust/expand/rust-expand-visitor.h b/gcc/rust/expand/rust-expand-visitor.h
index 5fc1011e..ad237c0 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -237,6 +237,7 @@ public:
void visit (AST::TypeParam &param) override;
void visit (AST::LifetimeWhereClauseItem &) override;
void visit (AST::TypeBoundWhereClauseItem &item) override;
+ void visit (AST::Module &module) override;
void visit (AST::ExternCrate &crate) override;
void visit (AST::UseTreeGlob &) override;
void visit (AST::UseTreeList &) override;
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 5ed24d6..e255729 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -17,12 +17,12 @@
// <http://www.gnu.org/licenses/>.
#include "expected.h"
-#include "rust-make-unique.h"
#include "rust-macro-builtins-asm.h"
#include "rust-ast-fragment.h"
#include "rust-ast.h"
#include "rust-fmt.h"
#include "rust-stmt.h"
+#include "rust-parse.h"
namespace Rust {
std::map<AST::InlineAsmOption, std::string> InlineAsmOptionMap{
@@ -40,16 +40,28 @@ std::map<AST::InlineAsmOption, std::string> InlineAsmOptionMap{
std::set<std::string> potentially_nonpromoted_keywords
= {"in", "out", "lateout", "inout", "inlateout", "const", "sym", "label"};
+// Helper function strips the beginning and ending double quotes from a
+// string.
std::string
strip_double_quotes (const std::string &str)
{
- // Helper function strips the beginning and ending double quotes from a
- // string.
std::string result = str;
+ rust_assert (!str.empty ());
+
+ rust_assert (str.front () == '\"');
+ rust_assert (str.back () == '\"');
+
+ // we have to special case empty strings which just contain a set of quotes
+ // so, if the string is "\"\"", just return ""
+ if (result.size () == 2)
+ return "";
+
rust_assert (result.size () >= 3);
+
result.erase (0, 1);
result.erase (result.size () - 1, 1);
+
return result;
}
@@ -241,12 +253,10 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
// Loop over and execute the parsing functions, if the parser successfullly
// parses or if the parser fails to parse while it has committed to a token,
// we propogate the result.
- int count = 0;
tl::expected<InlineAsmContext, InlineAsmParseError> parsing_operand (
inline_asm_ctx);
for (auto &parse_func : parse_funcs)
{
- count++;
auto result = parsing_operand.and_then (parse_func);
// Per rust's asm.rs's structure
@@ -324,14 +334,14 @@ parse_reg_operand_in (InlineAsmContext inline_asm_ctx)
// We are sure to be failing a test here, based on asm.rs
// https://github.com/rust-lang/rust/blob/a330e49593ee890f9197727a3a558b6e6b37f843/compiler/rustc_builtin_macros/src/asm.rs#L112
rust_unreachable ();
- return tl::unexpected<InlineAsmParseError> (COMMITTED);
+ // return tl::unexpected<InlineAsmParseError> (COMMITTED);
}
auto expr = parser.parse_expr ();
// TODO: When we've succesfully parse an expr, remember to clone_expr()
// instead of nullptr
- struct AST::InlineAsmOperand::In in (reg, std::move (expr));
+ AST::InlineAsmOperand::In in (reg, std::move (expr));
inline_asm_ctx.inline_asm.operands.emplace_back (in, locus);
return inline_asm_ctx;
}
@@ -355,7 +365,7 @@ parse_reg_operand_out (InlineAsmContext inline_asm_ctx)
// TODO: When we've succesfully parse an expr, remember to clone_expr()
// instead of nullptr
- struct AST::InlineAsmOperand::Out out (reg, false, std::move (expr));
+ AST::InlineAsmOperand::Out out (reg, false, std::move (expr));
inline_asm_ctx.inline_asm.operands.emplace_back (out, locus);
@@ -651,6 +661,15 @@ MacroBuiltin::asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
return parse_asm (invoc_locus, invoc, semicolon, is_global_asm);
}
+tl::optional<AST::Fragment>
+MacroBuiltin::llvm_asm_handler (location_t invoc_locus,
+ AST::MacroInvocData &invoc,
+ AST::InvocKind semicolon,
+ AST::AsmKind is_global_asm)
+{
+ return parse_llvm_asm (invoc_locus, invoc, semicolon, is_global_asm);
+}
+
tl::expected<InlineAsmContext, InlineAsmParseError>
parse_asm_arg (InlineAsmContext inline_asm_ctx)
{
@@ -662,6 +681,14 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
{
token = parser.peek_current_token ();
+ if (token->get_id () == COLON || token->get_id () == SCOPE_RESOLUTION)
+ {
+ rust_error_at (
+ token->get_locus (),
+ "the legacy LLVM-style %<asm!%> syntax is no longer supported");
+ return tl::unexpected<InlineAsmParseError> (COMMITTED);
+ }
+
// We accept a comma token here.
if (token->get_id () != COMMA
&& inline_asm_ctx.consumed_comma_without_formatted_string)
@@ -858,9 +885,9 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
// properly.
if (semicolon == AST::InvocKind::Semicoloned)
single_vec.emplace_back (AST::SingleASTNode (
- Rust::make_unique<AST::ExprStmt> (std::move (node), invoc_locus,
- semicolon
- == AST::InvocKind::Semicoloned)));
+ std::make_unique<AST::ExprStmt> (std::move (node), invoc_locus,
+ semicolon
+ == AST::InvocKind::Semicoloned)));
else
single_vec.emplace_back (AST::SingleASTNode (std::move (node)));
@@ -953,4 +980,223 @@ validate (InlineAsmContext inline_asm_ctx)
{
return tl::expected<InlineAsmContext, InlineAsmParseError> (inline_asm_ctx);
}
+
+tl::optional<LlvmAsmContext>
+parse_llvm_templates (LlvmAsmContext ctx)
+{
+ auto &parser = ctx.parser;
+
+ auto token = parser.peek_current_token ();
+
+ if (token->get_id () == ctx.last_token_id
+ || token->get_id () != STRING_LITERAL)
+ {
+ return tl::nullopt;
+ }
+
+ ctx.llvm_asm.get_templates ().emplace_back (token->get_locus (),
+ strip_double_quotes (
+ token->as_string ()));
+ ctx.parser.skip_token ();
+
+ token = parser.peek_current_token ();
+ if (token->get_id () != ctx.last_token_id && token->get_id () != COLON
+ && token->get_id () != SCOPE_RESOLUTION)
+ {
+ // We do not handle multiple template string, we provide minimal support
+ // for the black_box intrinsics.
+ rust_unreachable ();
+ }
+
+ return ctx;
+}
+
+tl::optional<LlvmAsmContext>
+parse_llvm_arguments (LlvmAsmContext ctx)
+{
+ auto &parser = ctx.parser;
+ enum State
+ {
+ Templates = 0,
+ Output,
+ Input,
+ Clobbers,
+ Options
+ } current_state
+ = State::Templates;
+
+ while (parser.peek_current_token ()->get_id () != ctx.last_token_id
+ && parser.peek_current_token ()->get_id () != END_OF_FILE)
+ {
+ if (parser.peek_current_token ()->get_id () == SCOPE_RESOLUTION)
+ {
+ parser.skip_token (SCOPE_RESOLUTION);
+ current_state = static_cast<State> (current_state + 2);
+ }
+ else
+ {
+ parser.skip_token (COLON);
+ current_state = static_cast<State> (current_state + 1);
+ }
+
+ switch (current_state)
+ {
+ case State::Output:
+ parse_llvm_outputs (ctx);
+ break;
+ case State::Input:
+ parse_llvm_inputs (ctx);
+ break;
+ case State::Clobbers:
+ parse_llvm_clobbers (ctx);
+ break;
+ case State::Options:
+ parse_llvm_options (ctx);
+ break;
+ case State::Templates:
+ default:
+ rust_unreachable ();
+ }
+ }
+
+ return ctx;
+}
+
+void
+parse_llvm_operands (LlvmAsmContext &ctx, std::vector<AST::LlvmOperand> &result)
+{
+ auto &parser = ctx.parser;
+ auto token = parser.peek_current_token ();
+ while (token->get_id () != COLON && token->get_id () != SCOPE_RESOLUTION
+ && token->get_id () != ctx.last_token_id)
+ {
+ std::string constraint;
+ if (token->get_id () == STRING_LITERAL)
+ {
+ constraint = strip_double_quotes (token->as_string ());
+ }
+ parser.skip_token (STRING_LITERAL);
+ parser.skip_token (LEFT_PAREN);
+
+ token = parser.peek_current_token ();
+
+ ParseRestrictions restrictions;
+ restrictions.expr_can_be_null = true;
+ auto expr = parser.parse_expr ();
+
+ parser.skip_token (RIGHT_PAREN);
+
+ result.emplace_back (constraint, std::move (expr));
+
+ if (parser.peek_current_token ()->get_id () == COMMA)
+ parser.skip_token (COMMA);
+
+ token = parser.peek_current_token ();
+ }
+}
+
+void
+parse_llvm_outputs (LlvmAsmContext &ctx)
+{
+ parse_llvm_operands (ctx, ctx.llvm_asm.get_outputs ());
+}
+
+void
+parse_llvm_inputs (LlvmAsmContext &ctx)
+{
+ parse_llvm_operands (ctx, ctx.llvm_asm.get_inputs ());
+}
+
+void
+parse_llvm_clobbers (LlvmAsmContext &ctx)
+{
+ auto &parser = ctx.parser;
+ auto token = parser.peek_current_token ();
+ while (token->get_id () != COLON && token->get_id () != ctx.last_token_id)
+ {
+ if (token->get_id () == STRING_LITERAL)
+ {
+ ctx.llvm_asm.get_clobbers ().push_back (
+ {strip_double_quotes (token->as_string ()), token->get_locus ()});
+ }
+ parser.skip_token (STRING_LITERAL);
+ token = parser.peek_current_token ();
+ }
+}
+
+void
+parse_llvm_options (LlvmAsmContext &ctx)
+{
+ auto &parser = ctx.parser;
+ auto token = parser.peek_current_token ();
+
+ while (token->get_id () != ctx.last_token_id)
+ {
+ if (token->get_id () == STRING_LITERAL)
+ {
+ auto token_str = strip_double_quotes (token->as_string ());
+
+ if (token_str == "volatile")
+ ctx.llvm_asm.set_volatile (true);
+ else if (token_str == "alignstack")
+ ctx.llvm_asm.set_align_stack (true);
+ else if (token_str == "intel")
+ ctx.llvm_asm.set_dialect (AST::LlvmInlineAsm::Dialect::Intel);
+ else
+ rust_error_at (token->get_locus (),
+ "Unknown llvm assembly option %qs",
+ token_str.c_str ());
+ }
+ parser.skip_token (STRING_LITERAL);
+
+ token = parser.peek_current_token ();
+
+ if (token->get_id () == ctx.last_token_id)
+ continue;
+ parser.skip_token (COMMA);
+ }
+
+ parser.skip_token ();
+}
+
+tl::optional<AST::Fragment>
+parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
+ AST::InvocKind semicolon, AST::AsmKind is_global_asm)
+{
+ MacroInvocLexer lex (invoc.get_delim_tok_tree ().to_token_stream ());
+ Parser<MacroInvocLexer> parser (lex);
+ auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
+
+ AST::LlvmInlineAsm llvm_asm{invoc_locus};
+
+ auto asm_ctx = LlvmAsmContext (llvm_asm, parser, last_token_id);
+
+ auto resulting_context
+ = parse_llvm_templates (asm_ctx).and_then (parse_llvm_arguments);
+
+ if (resulting_context)
+ {
+ auto node = (*resulting_context).llvm_asm.clone_expr_without_block ();
+
+ std::vector<AST::SingleASTNode> single_vec = {};
+
+ // If the macro invocation has a semicolon (`asm!("...");`), then we
+ // need to make it a statement. This way, it will be expanded
+ // properly.
+ if (semicolon == AST::InvocKind::Semicoloned)
+ single_vec.emplace_back (AST::SingleASTNode (
+ std::make_unique<AST::ExprStmt> (std::move (node), invoc_locus,
+ semicolon
+ == AST::InvocKind::Semicoloned)));
+ else
+ single_vec.emplace_back (AST::SingleASTNode (std::move (node)));
+
+ AST::Fragment fragment_ast
+ = AST::Fragment (single_vec,
+ std::vector<std::unique_ptr<AST::Token>> ());
+ return fragment_ast;
+ }
+ return tl::nullopt;
+}
+
} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h b/gcc/rust/expand/rust-macro-builtins-asm.h
index 8081dae..bd64a7f 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -172,4 +172,36 @@ tl::optional<std::string>
parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
InlineAsmContext &inline_asm_ctx);
+// LLVM ASM bits
+
+class LlvmAsmContext
+{
+public:
+ AST::LlvmInlineAsm &llvm_asm;
+ Parser<MacroInvocLexer> &parser;
+ int last_token_id;
+
+public:
+ LlvmAsmContext (AST::LlvmInlineAsm &llvm_asm, Parser<MacroInvocLexer> &parser,
+ int last_token_id)
+ : llvm_asm (llvm_asm), parser (parser), last_token_id (last_token_id)
+ {}
+};
+
+void
+parse_llvm_outputs (LlvmAsmContext &ctx);
+
+void
+parse_llvm_inputs (LlvmAsmContext &ctx);
+
+void
+parse_llvm_clobbers (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,
+ AST::InvocKind semicolon, AST::AsmKind is_global_asm);
+
} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins-format-args.cc b/gcc/rust/expand/rust-macro-builtins-format-args.cc
index 8eb32d5..3e1249d 100644
--- a/gcc/rust/expand/rust-macro-builtins-format-args.cc
+++ b/gcc/rust/expand/rust-macro-builtins-format-args.cc
@@ -55,6 +55,8 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
if (parser.peek_current_token ()->get_id () == STRING_LITERAL)
format_expr = parser.parse_literal_expr ();
+ rust_assert (format_expr);
+
// TODO(Arthur): Clean this up - if we haven't parsed a string literal but a
// macro invocation, what do we do here? return a tl::unexpected?
auto format_str = static_cast<AST::LiteralExpr &> (*format_expr)
@@ -81,6 +83,11 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
{
parser.skip_token (COMMA);
+ // Check in case of an extraneous comma in the args list, which is
+ // allowed - format_args!("fmt", arg, arg2,)
+ if (parser.peek_current_token ()->get_id () == last_token_id)
+ break;
+
if (parser.peek_current_token ()->get_id () == IDENTIFIER
&& parser.peek (1)->get_id () == EQUAL)
{
diff --git a/gcc/rust/expand/rust-macro-builtins-helpers.cc b/gcc/rust/expand/rust-macro-builtins-helpers.cc
index 55d113c..864379a 100644
--- a/gcc/rust/expand/rust-macro-builtins-helpers.cc
+++ b/gcc/rust/expand/rust-macro-builtins-helpers.cc
@@ -36,7 +36,7 @@ check_for_eager_invocations (
std::vector<std::unique_ptr<AST::MacroInvocation>> pending;
for (auto &expr : expressions)
- if (expr->get_ast_kind () == AST::Kind::MACRO_INVOCATION)
+ if (expr->get_expr_kind () == AST::Expr::Kind::MacroInvocation)
pending.emplace_back (std::unique_ptr<AST::MacroInvocation> (
static_cast<AST::MacroInvocation *> (expr->clone_expr ().release ())));
diff --git a/gcc/rust/expand/rust-macro-builtins-helpers.h b/gcc/rust/expand/rust-macro-builtins-helpers.h
index ee5cae7..429537e 100644
--- a/gcc/rust/expand/rust-macro-builtins-helpers.h
+++ b/gcc/rust/expand/rust-macro-builtins-helpers.h
@@ -29,7 +29,6 @@
#include "rust-macro-invoc-lexer.h"
#include "rust-macro.h"
#include "rust-parse.h"
-#include "rust-session-manager.h"
#include "rust-system.h"
#include "rust-token.h"
namespace Rust {
diff --git a/gcc/rust/expand/rust-macro-builtins-include.cc b/gcc/rust/expand/rust-macro-builtins-include.cc
index 4719b0e..2ab2a3a 100644
--- a/gcc/rust/expand/rust-macro-builtins-include.cc
+++ b/gcc/rust/expand/rust-macro-builtins-include.cc
@@ -20,6 +20,7 @@
#include "rust-common.h"
#include "rust-macro-builtins.h"
#include "rust-macro-builtins-helpers.h"
+#include "rust-session-manager.h"
#include "optional.h"
namespace Rust {
/* Expand builtin macro include_bytes!("filename"), which includes the contents
diff --git a/gcc/rust/expand/rust-macro-builtins-log-debug.cc b/gcc/rust/expand/rust-macro-builtins-log-debug.cc
index 49670d2..3d7b54f 100644
--- a/gcc/rust/expand/rust-macro-builtins-log-debug.cc
+++ b/gcc/rust/expand/rust-macro-builtins-log-debug.cc
@@ -30,4 +30,4 @@ MacroBuiltin::assert_handler (location_t invoc_locus,
return AST::Fragment::create_error ();
}
-} // namespace Rust \ No newline at end of file
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins-utility.cc b/gcc/rust/expand/rust-macro-builtins-utility.cc
index 2da7d18..b20b479 100644
--- a/gcc/rust/expand/rust-macro-builtins-utility.cc
+++ b/gcc/rust/expand/rust-macro-builtins-utility.cc
@@ -17,8 +17,10 @@
// <http://www.gnu.org/licenses/>.
#include "rust-fmt.h"
+#include "rust-ast-builder.h"
#include "rust-macro-builtins.h"
#include "rust-macro-builtins-helpers.h"
+#include "rust-session-manager.h"
namespace Rust {
@@ -117,7 +119,7 @@ MacroBuiltin::concat_handler (location_t invoc_locus,
for (auto &expr : expanded_expr)
{
if (!expr->is_literal ()
- && expr->get_ast_kind () != AST::Kind::MACRO_INVOCATION)
+ && expr->get_expr_kind () != AST::Expr::Kind::MacroInvocation)
{
has_error = true;
rust_error_at (expr->get_locus (), "expected a literal");
@@ -226,6 +228,83 @@ MacroBuiltin::env_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
return AST::Fragment ({node}, std::move (tok));
}
+/* Expand builtin macro option_env!(), which inspects an environment variable at
+ compile time. */
+tl::optional<AST::Fragment>
+MacroBuiltin::option_env_handler (location_t invoc_locus,
+ AST::MacroInvocData &invoc,
+ AST::InvocKind semicolon)
+{
+ auto invoc_token_tree = invoc.get_delim_tok_tree ();
+ MacroInvocLexer lex (invoc_token_tree.to_token_stream ());
+ Parser<MacroInvocLexer> parser (lex);
+
+ auto last_token_id = macro_end_token (invoc_token_tree, parser);
+ std::unique_ptr<AST::LiteralExpr> lit_expr = nullptr;
+ bool has_error = false;
+
+ auto start = lex.get_offs ();
+ auto expanded_expr = try_expand_many_expr (parser, last_token_id,
+ invoc.get_expander (), has_error);
+ auto end = lex.get_offs ();
+
+ auto tokens = lex.get_token_slice (start, end);
+
+ if (has_error)
+ return AST::Fragment::create_error ();
+
+ auto pending = check_for_eager_invocations (expanded_expr);
+ if (!pending.empty ())
+ return make_eager_builtin_invocation (BuiltinMacro::OptionEnv, invoc_locus,
+ invoc_token_tree,
+ std::move (pending));
+
+ if (expanded_expr.size () != 1)
+ {
+ rust_error_at (invoc_locus, "%<option_env!%> takes 1 argument");
+ return AST::Fragment::create_error ();
+ }
+
+ if (expanded_expr.size () > 0)
+ if (!(lit_expr
+ = try_extract_string_literal_from_fragment (invoc_locus,
+ expanded_expr[0])))
+ return AST::Fragment::create_error ();
+
+ parser.skip_token (last_token_id);
+
+ auto env_value = getenv (lit_expr->as_string ().c_str ());
+ AST::Builder b (invoc_locus);
+
+ if (env_value == nullptr)
+ {
+ auto none_expr = std::unique_ptr<AST::Expr> (
+ new AST::PathInExpression (LangItem::Kind::OPTION_NONE, {},
+ invoc_locus));
+
+ auto node = AST::SingleASTNode (std::move (none_expr));
+ std::vector<AST::SingleASTNode> nodes;
+ nodes.push_back (node);
+
+ return AST::Fragment (nodes, std::vector<std::unique_ptr<AST::Token>> ());
+ }
+ std::vector<std::unique_ptr<AST::Expr>> args;
+ args.push_back (b.literal_string (env_value));
+
+ std::unique_ptr<AST::Expr> some_expr
+ = b.call (std::unique_ptr<AST::Expr> (
+ new AST::PathInExpression (LangItem::Kind::OPTION_SOME, {},
+ invoc_locus)),
+ std::move (args));
+
+ auto node = AST::SingleASTNode (std::move (some_expr));
+
+ std::vector<AST::SingleASTNode> nodes;
+ nodes.push_back (node);
+
+ return AST::Fragment (nodes, std::vector<std::unique_ptr<AST::Token>> ());
+}
+
tl::optional<AST::Fragment>
MacroBuiltin::cfg_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
AST::InvocKind semicolon)
@@ -296,4 +375,4 @@ MacroBuiltin::stringify_handler (location_t invoc_locus,
return AST::Fragment ({node}, std::move (token));
}
-} // namespace Rust \ No newline at end of file
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 2457bc0..b58ed71 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -62,6 +62,8 @@ const BiMap<std::string, BuiltinMacro> MacroBuiltin::builtins = {{
{"concat_idents", BuiltinMacro::ConcatIdents},
{"module_path", BuiltinMacro::ModulePath},
{"asm", BuiltinMacro::Asm},
+ // FIXME: Is that okay
+ {"llvm_asm", BuiltinMacro::Asm},
{"global_asm", BuiltinMacro::GlobalAsm},
{"log_syntax", BuiltinMacro::LogSyntax},
{"trace_macros", BuiltinMacro::TraceMacros},
@@ -81,7 +83,6 @@ const BiMap<std::string, BuiltinMacro> MacroBuiltin::builtins = {{
{"Ord", BuiltinMacro::Ord},
{"PartialOrd", BuiltinMacro::PartialOrd},
{"Hash", BuiltinMacro::Hash},
-
}};
AST::MacroTranscriberFunc
@@ -102,6 +103,15 @@ inline_asm_maker (AST::AsmKind global_asm)
};
}
+AST::MacroTranscriberFunc
+inline_llvm_asm_maker (AST::AsmKind global_asm)
+{
+ return [global_asm] (location_t loc, AST::MacroInvocData &invoc,
+ AST::InvocKind semicolon) {
+ return MacroBuiltin::llvm_asm_handler (loc, invoc, semicolon, global_asm);
+ };
+}
+
std::unordered_map<std::string, AST::MacroTranscriberFunc>
MacroBuiltin::builtin_transcribers = {
{"assert", MacroBuiltin::assert_handler},
@@ -119,9 +129,11 @@ std::unordered_map<std::string, AST::MacroTranscriberFunc>
{"format_args", format_args_maker (AST::FormatArgs::Newline::No)},
{"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)},
{"asm", inline_asm_maker (AST::AsmKind::Inline)},
+ // FIXME: Is that okay?
+ {"llvm_asm", inline_llvm_asm_maker (AST::AsmKind::Inline)},
{"global_asm", inline_asm_maker (AST::AsmKind::Global)},
+ {"option_env", MacroBuiltin::option_env_handler},
/* Unimplemented macro builtins */
- {"option_env", MacroBuiltin::sorry},
{"concat_idents", MacroBuiltin::sorry},
{"module_path", MacroBuiltin::sorry},
{"log_syntax", MacroBuiltin::sorry},
@@ -133,6 +145,7 @@ std::unordered_map<std::string, AST::MacroTranscriberFunc>
{"cfg_accessible", MacroBuiltin::sorry},
{"rustc_const_stable", MacroBuiltin::sorry},
{"rustc_const_unstable", MacroBuiltin::sorry},
+ {"track_caller", MacroBuiltin::sorry},
/* Derive builtins do not need a real transcriber, but still need one. It
should however never be called since builtin derive macros get expanded
differently, and benefit from knowing on what kind of items they are
diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h
index 6a9b31c..541e956 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -159,6 +159,10 @@ public:
AST::MacroInvocData &invoc,
AST::InvocKind semicolon);
+ static tl::optional<AST::Fragment>
+ option_env_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
+ AST::InvocKind semicolon);
+
static tl::optional<AST::Fragment> cfg_handler (location_t invoc_locus,
AST::MacroInvocData &invoc,
AST::InvocKind semicolon);
@@ -177,6 +181,10 @@ public:
AST::AsmKind is_global_asm);
static tl::optional<AST::Fragment>
+ llvm_asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
+ AST::InvocKind semicolon, AST::AsmKind is_global_asm);
+
+ static tl::optional<AST::Fragment>
format_args_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
AST::InvocKind semicolon, AST::FormatArgs::Newline nl);
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index e86bfcb..673b8fb 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -23,11 +23,12 @@
#include "rust-ast-full.h"
#include "rust-ast-visitor.h"
#include "rust-diagnostics.h"
+#include "rust-macro.h"
#include "rust-parse.h"
#include "rust-cfg-strip.h"
#include "rust-early-name-resolver.h"
-#include "rust-session-manager.h"
#include "rust-proc-macro.h"
+#include "rust-token-tree-desugar.h"
namespace Rust {
@@ -78,7 +79,10 @@ MacroExpander::expand_decl_macro (location_t invoc_locus,
* trees.
*/
- AST::DelimTokenTree &invoc_token_tree = invoc.get_delim_tok_tree ();
+ AST::DelimTokenTree &invoc_token_tree_sugar = invoc.get_delim_tok_tree ();
+
+ // We must first desugar doc comments into proper attributes
+ auto invoc_token_tree = AST::TokenTreeDesugar ().go (invoc_token_tree_sugar);
// find matching arm
AST::MacroRule *matched_rule = nullptr;
@@ -119,7 +123,7 @@ MacroExpander::expand_decl_macro (location_t invoc_locus,
for (auto &ent : matched_fragments)
matched_fragments_ptr.emplace (ent.first, ent.second.get ());
- return transcribe_rule (*matched_rule, invoc_token_tree,
+ return transcribe_rule (rules_def, *matched_rule, invoc_token_tree,
matched_fragments_ptr, semicolon, peek_context ());
}
@@ -621,9 +625,10 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
// matched fragment get the offset in the token stream
size_t offs_end = source.get_offs ();
- sub_stack.insert_metavar (
- MatchedFragment (fragment->get_ident ().as_string (),
- offs_begin, offs_end));
+ if (valid_current_match)
+ sub_stack.insert_metavar (
+ MatchedFragment (fragment->get_ident ().as_string (),
+ offs_begin, offs_end));
}
break;
@@ -650,15 +655,15 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
}
auto old_stack = sub_stack.pop ();
- // nest metavars into repetitions
- for (auto &ent : old_stack)
- sub_stack.append_fragment (ent.first, std::move (ent.second));
-
// If we've encountered an error once, stop trying to match more
// repetitions
if (!valid_current_match)
break;
+ // nest metavars into repetitions
+ for (auto &ent : old_stack)
+ sub_stack.append_fragment (ent.first, std::move (ent.second));
+
match_amount++;
// Break early if we notice there's too many expressions already
@@ -1024,7 +1029,8 @@ tokens_to_str (std::vector<std::unique_ptr<AST::Token>> &tokens)
AST::Fragment
MacroExpander::transcribe_rule (
- AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree,
+ AST::MacroRulesDefinition &definition, AST::MacroRule &match_rule,
+ AST::DelimTokenTree &invoc_token_tree,
std::map<std::string, MatchedFragmentContainer *> &matched_fragments,
AST::InvocKind invoc_kind, ContextType ctx)
{
@@ -1038,8 +1044,8 @@ MacroExpander::transcribe_rule (
auto invoc_stream = invoc_token_tree.to_token_stream ();
auto macro_rule_tokens = transcribe_tree.to_token_stream ();
- auto substitute_context
- = SubstituteCtx (invoc_stream, macro_rule_tokens, matched_fragments);
+ auto substitute_context = SubstituteCtx (invoc_stream, macro_rule_tokens,
+ matched_fragments, definition);
std::vector<std::unique_ptr<AST::Token>> substituted_tokens
= substitute_context.substitute_tokens ();
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index 5e12790..360294c 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -331,7 +331,8 @@ struct MacroExpander
AST::DelimTokenTree &invoc_token_tree);
AST::Fragment transcribe_rule (
- AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree,
+ AST::MacroRulesDefinition &definition, AST::MacroRule &match_rule,
+ AST::DelimTokenTree &invoc_token_tree,
std::map<std::string, MatchedFragmentContainer *> &matched_fragments,
AST::InvocKind invoc_kind, ContextType ctx);
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc
index a06f831..02e4e3b 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.cc
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc
@@ -17,10 +17,47 @@
// <http://www.gnu.org/licenses/>.
#include "rust-macro-substitute-ctx.h"
+#include "input.h"
+#include "rust-hir-map.h"
+#include "rust-token.h"
namespace Rust {
bool
+SubstituteCtx::substitute_dollar_crate (
+ std::vector<std::unique_ptr<AST::Token>> &expanded)
+{
+ auto &mappings = Analysis::Mappings::get ();
+
+ auto def_crate = mappings.lookup_macro_def_crate (definition.get_node_id ());
+ auto current_crate = mappings.get_current_crate ();
+
+ rust_assert (def_crate);
+
+ // If we're expanding a macro defined in the current crate which uses $crate,
+ // we can just replace the metavar with the `crate` path segment. Otherwise,
+ // use the fully qualified extern-crate lookup path `::<crate_name>`
+ if (*def_crate == current_crate)
+ {
+ expanded.push_back (std::make_unique<AST::Token> (
+ Rust::Token::make_identifier (UNKNOWN_LOCATION, "crate")));
+ }
+ else
+ {
+ auto name = mappings.get_crate_name (*def_crate);
+
+ rust_assert (name);
+
+ expanded.push_back (std::make_unique<AST::Token> (
+ Rust::Token::make (SCOPE_RESOLUTION, UNKNOWN_LOCATION)));
+ expanded.push_back (std::make_unique<AST::Token> (
+ Rust::Token::make_identifier (UNKNOWN_LOCATION, std::string (*name))));
+ }
+
+ return true;
+}
+
+bool
SubstituteCtx::substitute_metavar (
std::unique_ptr<AST::Token> &metavar,
std::vector<std::unique_ptr<AST::Token>> &expanded)
@@ -30,14 +67,15 @@ SubstituteCtx::substitute_metavar (
auto it = fragments.find (metavar_name);
if (it == fragments.end ())
{
- // fail to substitute
+ // fail to substitute, unless we are dealing with a special-case metavar
+ // like $crate
- // HACK: substitute ($ crate) => (crate)
- if (metavar->get_id () != CRATE)
- return false;
+ if (metavar->get_id () == CRATE)
+ return substitute_dollar_crate (expanded);
expanded.push_back (metavar->clone_token ());
- return true;
+
+ return false;
}
else
{
@@ -187,7 +225,8 @@ SubstituteCtx::substitute_repetition (
kv_match.second->get_fragments ().at (i).get ());
}
- auto substitute_context = SubstituteCtx (input, new_macro, sub_map);
+ auto substitute_context
+ = SubstituteCtx (input, new_macro, sub_map, definition);
auto new_tokens = substitute_context.substitute_tokens ();
// Skip the first repetition, but add the separator to the expanded
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.h b/gcc/rust/expand/rust-macro-substitute-ctx.h
index e3100a3..c5c4956 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.h
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.h
@@ -18,6 +18,7 @@
#include "rust-ast.h"
#include "rust-macro-expand.h"
+#include "rust-macro.h"
namespace Rust {
class SubstituteCtx
@@ -25,6 +26,7 @@ class SubstituteCtx
std::vector<std::unique_ptr<AST::Token>> &input;
std::vector<std::unique_ptr<AST::Token>> &macro;
std::map<std::string, MatchedFragmentContainer *> &fragments;
+ AST::MacroRulesDefinition &definition;
/**
* Find the repetition amount to use when expanding a repetition, and
@@ -40,11 +42,28 @@ class SubstituteCtx
public:
SubstituteCtx (std::vector<std::unique_ptr<AST::Token>> &input,
std::vector<std::unique_ptr<AST::Token>> &macro,
- std::map<std::string, MatchedFragmentContainer *> &fragments)
- : input (input), macro (macro), fragments (fragments)
+ std::map<std::string, MatchedFragmentContainer *> &fragments,
+ AST::MacroRulesDefinition &definition)
+ : input (input), macro (macro), fragments (fragments),
+ definition (definition)
{}
/**
+ * Special-case the $crate metavar to expand to the name of the crate in which
+ * the macro was defined.
+ *
+ * https://doc.rust-lang.org/reference/macros-by-example.html#r-macro.decl.hygiene.crate
+ *
+ *
+ * @param expanded Reference to a vector upon which expanded tokens will be
+ * pushed
+ *
+ * @return True if the substitution succeeded
+ */
+ bool
+ substitute_dollar_crate (std::vector<std::unique_ptr<AST::Token>> &expanded);
+
+ /**
* Substitute a metavariable by its given fragment in a transcribing context,
* i.e. replacing $var with the associated fragment.
*
@@ -52,7 +71,7 @@ public:
* @param expanded Reference to a vector upon which expanded tokens will be
* pushed
*
- * @return True iff the substitution succeeded
+ * @return True if the substitution succeeded
*/
bool substitute_metavar (std::unique_ptr<AST::Token> &metavar,
std::vector<std::unique_ptr<AST::Token>> &expanded);
diff --git a/gcc/rust/expand/rust-token-tree-desugar.cc b/gcc/rust/expand/rust-token-tree-desugar.cc
new file mode 100644
index 0000000..3b47180
--- /dev/null
+++ b/gcc/rust/expand/rust-token-tree-desugar.cc
@@ -0,0 +1,72 @@
+// 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-token-tree-desugar.h"
+#include "rust-ast.h"
+#include "rust-token.h"
+
+namespace Rust {
+namespace AST {
+
+DelimTokenTree
+TokenTreeDesugar::go (DelimTokenTree &tts)
+{
+ tts.accept_vis (*this);
+
+ return DelimTokenTree (tts.get_delim_type (), std::move (desugared),
+ tts.get_locus ());
+}
+
+void
+TokenTreeDesugar::append (TokenPtr &&new_token)
+{
+ desugared.emplace_back (std::make_unique<Token> (std::move (new_token)));
+}
+
+void
+TokenTreeDesugar::append (std::unique_ptr<TokenTree> &&new_token)
+{
+ desugared.emplace_back (std::move (new_token));
+}
+
+void
+TokenTreeDesugar::visit (Token &tts)
+{
+ if (tts.get_id () == TokenId::OUTER_DOC_COMMENT
+ || tts.get_id () == TokenId::INNER_DOC_COMMENT)
+ {
+ append (Rust::Token::make (TokenId::HASH, tts.get_locus ()));
+
+ if (tts.get_id () == TokenId::INNER_DOC_COMMENT)
+ append (Rust::Token::make (EXCLAM, tts.get_locus ()));
+
+ append (Rust::Token::make (TokenId::LEFT_SQUARE, tts.get_locus ()));
+ append (Rust::Token::make_identifier (tts.get_locus (), "doc"));
+ append (Rust::Token::make (TokenId::EQUAL, tts.get_locus ()));
+ append (Rust::Token::make_string (tts.get_locus (),
+ std::string (tts.get_str ())));
+ append (Rust::Token::make (TokenId::RIGHT_SQUARE, tts.get_locus ()));
+ }
+ else
+ {
+ append (tts.clone_token ());
+ }
+}
+
+}; // namespace AST
+}; // namespace Rust
diff --git a/gcc/rust/expand/rust-token-tree-desugar.h b/gcc/rust/expand/rust-token-tree-desugar.h
new file mode 100644
index 0000000..ccba53b
--- /dev/null
+++ b/gcc/rust/expand/rust-token-tree-desugar.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_TOKEN_TREE_DESUGAR_H
+#define RUST_TOKEN_TREE_DESUGAR_H
+
+#include "rust-ast-visitor.h"
+#include "rust-system.h"
+#include "rust-ast.h"
+
+namespace Rust {
+namespace AST {
+
+/**
+ * Desugar a given token-tree before parsing it for a macro invocation. At the
+ * moment, the sole purpose of this desugar is to transform doc-comments into
+ * their attribute form (/// comment -> #[doc = "comment"])
+ */
+class TokenTreeDesugar : public DefaultASTVisitor
+{
+public:
+ TokenTreeDesugar () : desugared (std::vector<std::unique_ptr<TokenTree>> ())
+ {}
+
+ DelimTokenTree go (DelimTokenTree &tts);
+
+private:
+ std::vector<std::unique_ptr<TokenTree>> desugared;
+ void append (TokenPtr &&new_token);
+ void append (std::unique_ptr<TokenTree> &&new_token);
+
+ using DefaultASTVisitor::visit;
+
+ virtual void visit (Token &tts) override;
+};
+
+}; // namespace AST
+}; // namespace Rust
+
+#endif //! RUST_TOKEN_TREE_DESUGAR_H
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index 18e6fff..2d9a445 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -23,13 +23,30 @@
#include "rust-ast.h"
#include "rust-attribute-values.h"
#include "rust-diagnostics.h"
+#include "rust-expr.h"
#include "rust-item.h"
#include "rust-system.h"
+#include "rust-attributes.h"
namespace Rust {
namespace HIR {
void
+ASTLoweringBase::visit (AST::MacroInvocation &invoc)
+{
+ rust_fatal_error (invoc.get_locus (), "rogue macro detected during lowering");
+ rust_unreachable ();
+}
+
+void
+ASTLoweringBase::visit (AST::ErrorPropagationExpr &expr)
+{
+ rust_fatal_error (expr.get_locus (),
+ "missing desugar for question mark operator");
+ rust_unreachable ();
+}
+
+void
ASTLoweringBase::visit (AST::Token &)
{}
void
@@ -63,12 +80,6 @@ ASTLoweringBase::visit (AST::ConstGenericParam &)
// rust-path.h
void
-ASTLoweringBase::visit (AST::RegularPath &)
-{}
-void
-ASTLoweringBase::visit (AST::LangItemPath &)
-{}
-void
ASTLoweringBase::visit (AST::PathInExpression &)
{}
void
@@ -113,9 +124,6 @@ void
ASTLoweringBase::visit (AST::DereferenceExpr &)
{}
void
-ASTLoweringBase::visit (AST::ErrorPropagationExpr &)
-{}
-void
ASTLoweringBase::visit (AST::NegationExpr &)
{}
void
@@ -259,6 +267,10 @@ void
ASTLoweringBase::visit (AST::InlineAsm &)
{}
+void
+ASTLoweringBase::visit (AST::LlvmInlineAsm &)
+{}
+
// void ASTLoweringBase::visit(MatchCasematch_case) {}
// void ASTLoweringBase:: (AST::MatchCaseBlockExpr &) {}
// void ASTLoweringBase:: (AST::MatchCaseExpr &) {}
@@ -378,9 +390,6 @@ void
ASTLoweringBase::visit (AST::MacroRulesDefinition &)
{}
void
-ASTLoweringBase::visit (AST::MacroInvocation &)
-{}
-void
ASTLoweringBase::visit (AST::MetaItemPath &)
{}
void
@@ -671,6 +680,7 @@ ASTLoweringBase::lower_self (AST::Param &param)
Analysis::NodeMapping mapping (crate_num, self.get_node_id (),
mappings.get_next_hir_id (crate_num),
mappings.get_next_localdef_id (crate_num));
+ mappings.insert_location (mapping.get_hirid (), param.get_locus ());
if (self.has_type ())
{
@@ -684,8 +694,12 @@ ASTLoweringBase::lower_self (AST::Param &param)
self.get_is_mut (), self.get_locus ());
}
- AST::Lifetime l = self.get_lifetime ();
- return HIR::SelfParam (mapping, lower_lifetime (l), self.get_is_mut (),
+ tl::optional<HIR::Lifetime> lifetime = tl::nullopt;
+
+ if (self.has_lifetime ())
+ lifetime = lower_lifetime (self.get_lifetime ());
+
+ return HIR::SelfParam (mapping, lifetime, self.get_is_mut (),
self.get_locus ());
}
@@ -751,7 +765,7 @@ ASTLoweringBase::handle_outer_attributes (const ItemWrapper &item)
for (const auto &attr : item.get_outer_attrs ())
{
const auto &str_path = attr.get_path ().as_string ();
- if (!is_known_attribute (str_path))
+ if (!Analysis::Attributes::is_known (str_path))
{
rust_error_at (attr.get_locus (), "unknown attribute");
continue;
@@ -815,13 +829,6 @@ ASTLoweringBase::handle_lang_item_attribute (const ItemWrapper &item,
}
bool
-ASTLoweringBase::is_known_attribute (const std::string &attribute_path) const
-{
- const auto &lookup = attr_mappings->lookup_builtin (attribute_path);
- return !lookup.is_error ();
-}
-
-bool
ASTLoweringBase::attribute_handled_in_another_pass (
const std::string &attribute_path) const
{
@@ -934,8 +941,8 @@ ASTLoweringBase::lower_literal (const AST::Literal &literal)
case AST::Literal::LitType::BYTE_STRING:
type = HIR::Literal::LitType::BYTE_STRING;
break;
- case AST::Literal::LitType::RAW_STRING: // TODO: Lower raw string literals.
- rust_unreachable ();
+ case AST::Literal::LitType::RAW_STRING:
+ type = HIR::Literal::LitType::STRING;
break;
case AST::Literal::LitType::INT:
type = HIR::Literal::LitType::INT;
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index 4cb098b..3116181 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -60,204 +60,205 @@ class ASTLoweringBase : public AST::ASTVisitor
public:
virtual ~ASTLoweringBase () {}
+ // Special casing nodes that should never reach the HIR lowering stage
+ virtual void visit (AST::MacroInvocation &) override final;
+ virtual void visit (AST::ErrorPropagationExpr &) override final;
+
// visitor impl
// rust-ast.h
// virtual void visit(AttrInput& attr_input);
// virtual void visit(TokenTree& token_tree);
// virtual void visit(MacroMatch& macro_match);
- virtual void visit (AST::Token &tok);
- virtual void visit (AST::DelimTokenTree &delim_tok_tree);
- virtual void visit (AST::AttrInputMetaItemContainer &input);
- // virtual void visit(MetaItem& meta_item);
- // void vsit(Stmt& stmt);
- // virtual void visit(Expr& expr);
- virtual void visit (AST::IdentifierExpr &ident_expr);
- // virtual void visit(Pattern& pattern);
- // virtual void visit(Type& type);
- // virtual void visit(TypeParamBound& type_param_bound);
- virtual void visit (AST::Lifetime &lifetime);
- // virtual void visit(GenericParam& generic_param);
- virtual void visit (AST::LifetimeParam &lifetime_param);
- virtual void visit (AST::ConstGenericParam &const_param);
- // virtual void visit(TraitItem& trait_item);
- // virtual void visit(InherentImplItem& inherent_impl_item);
- // virtual void visit(TraitImplItem& trait_impl_item);
+ virtual void visit (AST::Token &tok) override;
+ virtual void visit (AST::DelimTokenTree &delim_tok_tree) override;
+ virtual void visit (AST::AttrInputMetaItemContainer &input) override;
+ // virtual void visit(MetaItem& meta_item) override;
+ // void vsit(Stmt& stmt) override;
+ // virtual void visit(Expr& expr) override;
+ virtual void visit (AST::IdentifierExpr &ident_expr) override;
+ // virtual void visit(Pattern& pattern) override;
+ // virtual void visit(Type& type) override;
+ // virtual void visit(TypeParamBound& type_param_bound) override;
+ virtual void visit (AST::Lifetime &lifetime) override;
+ // virtual void visit(GenericParam& generic_param) override;
+ virtual void visit (AST::LifetimeParam &lifetime_param) override;
+ virtual void visit (AST::ConstGenericParam &const_param) override;
+ // virtual void visit(TraitItem& trait_item) override;
+ // virtual void visit(InherentImplItem& inherent_impl_item) override;
+ // virtual void visit(TraitImplItem& trait_impl_item) override;
// rust-path.h
- virtual void visit (AST::RegularPath &path);
- virtual void visit (AST::LangItemPath &path);
- virtual void visit (AST::PathInExpression &path);
- virtual void visit (AST::TypePathSegment &segment);
- virtual void visit (AST::TypePathSegmentGeneric &segment);
- virtual void visit (AST::TypePathSegmentFunction &segment);
- virtual void visit (AST::TypePath &path);
- virtual void visit (AST::QualifiedPathInExpression &path);
- virtual void visit (AST::QualifiedPathInType &path);
+ virtual void visit (AST::PathInExpression &path) override;
+ virtual void visit (AST::TypePathSegment &segment) override;
+ virtual void visit (AST::TypePathSegmentGeneric &segment) override;
+ virtual void visit (AST::TypePathSegmentFunction &segment) override;
+ virtual void visit (AST::TypePath &path) override;
+ virtual void visit (AST::QualifiedPathInExpression &path) override;
+ virtual void visit (AST::QualifiedPathInType &path) override;
// rust-expr.h
- virtual void visit (AST::LiteralExpr &expr);
- virtual void visit (AST::AttrInputLiteral &attr_input);
- virtual void visit (AST::AttrInputMacro &attr_input);
- virtual void visit (AST::MetaItemLitExpr &meta_item);
- virtual void visit (AST::MetaItemPathLit &meta_item);
- virtual void visit (AST::BorrowExpr &expr);
- virtual void visit (AST::DereferenceExpr &expr);
- virtual void visit (AST::ErrorPropagationExpr &expr);
- virtual void visit (AST::NegationExpr &expr);
- virtual void visit (AST::ArithmeticOrLogicalExpr &expr);
- virtual void visit (AST::ComparisonExpr &expr);
- virtual void visit (AST::LazyBooleanExpr &expr);
- virtual void visit (AST::TypeCastExpr &expr);
- virtual void visit (AST::AssignmentExpr &expr);
- virtual void visit (AST::CompoundAssignmentExpr &expr);
- virtual void visit (AST::GroupedExpr &expr);
- // virtual void visit(ArrayElems& elems);
- virtual void visit (AST::ArrayElemsValues &elems);
- virtual void visit (AST::ArrayElemsCopied &elems);
- virtual void visit (AST::ArrayExpr &expr);
- virtual void visit (AST::ArrayIndexExpr &expr);
- virtual void visit (AST::TupleExpr &expr);
- virtual void visit (AST::TupleIndexExpr &expr);
- virtual void visit (AST::StructExprStruct &expr);
- // virtual void visit(StructExprField& field);
- virtual void visit (AST::StructExprFieldIdentifier &field);
- virtual void visit (AST::StructExprFieldIdentifierValue &field);
- virtual void visit (AST::StructExprFieldIndexValue &field);
- virtual void visit (AST::StructExprStructFields &expr);
- virtual void visit (AST::StructExprStructBase &expr);
- virtual void visit (AST::CallExpr &expr);
- virtual void visit (AST::MethodCallExpr &expr);
- virtual void visit (AST::FieldAccessExpr &expr);
- virtual void visit (AST::ClosureExprInner &expr);
- virtual void visit (AST::BlockExpr &expr);
- virtual void visit (AST::ClosureExprInnerTyped &expr);
- virtual void visit (AST::ContinueExpr &expr);
- virtual void visit (AST::BreakExpr &expr);
- virtual void visit (AST::RangeFromToExpr &expr);
- virtual void visit (AST::RangeFromExpr &expr);
- virtual void visit (AST::RangeToExpr &expr);
- virtual void visit (AST::RangeFullExpr &expr);
- virtual void visit (AST::RangeFromToInclExpr &expr);
- virtual void visit (AST::RangeToInclExpr &expr);
- virtual void visit (AST::BoxExpr &expr);
- virtual void visit (AST::ReturnExpr &expr);
- virtual void visit (AST::UnsafeBlockExpr &expr);
- virtual void visit (AST::LoopExpr &expr);
- virtual void visit (AST::WhileLoopExpr &expr);
- virtual void visit (AST::WhileLetLoopExpr &expr);
- virtual void visit (AST::ForLoopExpr &expr);
- virtual void visit (AST::IfExpr &expr);
- virtual void visit (AST::IfExprConseqElse &expr);
- virtual void visit (AST::IfLetExpr &expr);
- virtual void visit (AST::IfLetExprConseqElse &expr);
- virtual void visit (AST::InlineAsm &expr);
- // virtual void visit(MatchCase& match_case);
- // virtual void visit (AST::MatchCaseBlockExpr &match_case);
- // virtual void visit (AST::MatchCaseExpr &match_case);
- virtual void visit (AST::MatchExpr &expr);
- virtual void visit (AST::AwaitExpr &expr);
- virtual void visit (AST::AsyncBlockExpr &expr);
+ virtual void visit (AST::LiteralExpr &expr) override;
+ virtual void visit (AST::AttrInputLiteral &attr_input) override;
+ virtual void visit (AST::AttrInputMacro &attr_input) override;
+ virtual void visit (AST::MetaItemLitExpr &meta_item) override;
+ virtual void visit (AST::MetaItemPathLit &meta_item) override;
+ virtual void visit (AST::BorrowExpr &expr) override;
+ virtual void visit (AST::DereferenceExpr &expr) override;
+ virtual void visit (AST::NegationExpr &expr) override;
+ virtual void visit (AST::ArithmeticOrLogicalExpr &expr) override;
+ virtual void visit (AST::ComparisonExpr &expr) override;
+ virtual void visit (AST::LazyBooleanExpr &expr) override;
+ virtual void visit (AST::TypeCastExpr &expr) override;
+ virtual void visit (AST::AssignmentExpr &expr) override;
+ virtual void visit (AST::CompoundAssignmentExpr &expr) override;
+ virtual void visit (AST::GroupedExpr &expr) override;
+ // virtual void visit(ArrayElems& elems) override;
+ virtual void visit (AST::ArrayElemsValues &elems) override;
+ virtual void visit (AST::ArrayElemsCopied &elems) override;
+ virtual void visit (AST::ArrayExpr &expr) override;
+ virtual void visit (AST::ArrayIndexExpr &expr) override;
+ virtual void visit (AST::TupleExpr &expr) override;
+ virtual void visit (AST::TupleIndexExpr &expr) override;
+ virtual void visit (AST::StructExprStruct &expr) override;
+ // virtual void visit(StructExprField& field) override;
+ virtual void visit (AST::StructExprFieldIdentifier &field) override;
+ virtual void visit (AST::StructExprFieldIdentifierValue &field) override;
+ virtual void visit (AST::StructExprFieldIndexValue &field) override;
+ virtual void visit (AST::StructExprStructFields &expr) override;
+ virtual void visit (AST::StructExprStructBase &expr) override;
+ virtual void visit (AST::CallExpr &expr) override;
+ virtual void visit (AST::MethodCallExpr &expr) override;
+ 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::ClosureExprInnerTyped &expr) override;
+ virtual void visit (AST::ContinueExpr &expr) override;
+ virtual void visit (AST::BreakExpr &expr) override;
+ virtual void visit (AST::RangeFromToExpr &expr) override;
+ virtual void visit (AST::RangeFromExpr &expr) override;
+ virtual void visit (AST::RangeToExpr &expr) override;
+ virtual void visit (AST::RangeFullExpr &expr) override;
+ virtual void visit (AST::RangeFromToInclExpr &expr) override;
+ virtual void visit (AST::RangeToInclExpr &expr) override;
+ virtual void visit (AST::BoxExpr &expr) override;
+ virtual void visit (AST::ReturnExpr &expr) override;
+ virtual void visit (AST::UnsafeBlockExpr &expr) override;
+ virtual void visit (AST::LoopExpr &expr) override;
+ virtual void visit (AST::WhileLoopExpr &expr) override;
+ virtual void visit (AST::WhileLetLoopExpr &expr) override;
+ virtual void visit (AST::ForLoopExpr &expr) override;
+ virtual void visit (AST::IfExpr &expr) override;
+ virtual void visit (AST::IfExprConseqElse &expr) override;
+ virtual void visit (AST::IfLetExpr &expr) override;
+ virtual void visit (AST::IfLetExprConseqElse &expr) override;
+ virtual void visit (AST::InlineAsm &expr) override;
+ virtual void visit (AST::LlvmInlineAsm &expr) override;
+ // virtual void visit(MatchCase& match_case) override;
+ // virtual void visit (AST::MatchCaseBlockExpr &match_case) override;
+ // virtual void visit (AST::MatchCaseExpr &match_case) override;
+ virtual void visit (AST::MatchExpr &expr) override;
+ virtual void visit (AST::AwaitExpr &expr) override;
+ virtual void visit (AST::AsyncBlockExpr &expr) override;
// rust-item.h
- virtual void visit (AST::TypeParam &param);
- // virtual void visit(WhereClauseItem& item);
- virtual void visit (AST::LifetimeWhereClauseItem &item);
- virtual void visit (AST::TypeBoundWhereClauseItem &item);
- virtual void visit (AST::Module &module);
- virtual void visit (AST::ExternCrate &crate);
- // virtual void visit(UseTree& use_tree);
- virtual void visit (AST::UseTreeGlob &use_tree);
- virtual void visit (AST::UseTreeList &use_tree);
- virtual void visit (AST::UseTreeRebind &use_tree);
- virtual void visit (AST::UseDeclaration &use_decl);
- virtual void visit (AST::Function &function);
- virtual void visit (AST::TypeAlias &type_alias);
- virtual void visit (AST::StructStruct &struct_item);
- virtual void visit (AST::TupleStruct &tuple_struct);
- virtual void visit (AST::EnumItem &item);
- virtual void visit (AST::EnumItemTuple &item);
- virtual void visit (AST::EnumItemStruct &item);
- virtual void visit (AST::EnumItemDiscriminant &item);
- virtual void visit (AST::Enum &enum_item);
- virtual void visit (AST::Union &union_item);
- virtual void visit (AST::ConstantItem &const_item);
- virtual void visit (AST::StaticItem &static_item);
- virtual void visit (AST::TraitItemConst &item);
- virtual void visit (AST::TraitItemType &item);
- virtual void visit (AST::Trait &trait);
- virtual void visit (AST::InherentImpl &impl);
- virtual void visit (AST::TraitImpl &impl);
- // virtual void visit(ExternalItem& item);
- virtual void visit (AST::ExternalTypeItem &item);
- virtual void visit (AST::ExternalStaticItem &item);
- virtual void visit (AST::ExternBlock &block);
+ virtual void visit (AST::TypeParam &param) override;
+ // virtual void visit(WhereClauseItem& item) override;
+ virtual void visit (AST::LifetimeWhereClauseItem &item) override;
+ virtual void visit (AST::TypeBoundWhereClauseItem &item) override;
+ virtual void visit (AST::Module &module) override;
+ virtual void visit (AST::ExternCrate &crate) override;
+ // virtual void visit(UseTree& use_tree) override;
+ virtual void visit (AST::UseTreeGlob &use_tree) override;
+ virtual void visit (AST::UseTreeList &use_tree) override;
+ virtual void visit (AST::UseTreeRebind &use_tree) override;
+ virtual void visit (AST::UseDeclaration &use_decl) override;
+ virtual void visit (AST::Function &function) override;
+ virtual void visit (AST::TypeAlias &type_alias) override;
+ virtual void visit (AST::StructStruct &struct_item) override;
+ virtual void visit (AST::TupleStruct &tuple_struct) override;
+ virtual void visit (AST::EnumItem &item) override;
+ virtual void visit (AST::EnumItemTuple &item) override;
+ virtual void visit (AST::EnumItemStruct &item) override;
+ virtual void visit (AST::EnumItemDiscriminant &item) override;
+ virtual void visit (AST::Enum &enum_item) override;
+ virtual void visit (AST::Union &union_item) override;
+ virtual void visit (AST::ConstantItem &const_item) override;
+ virtual void visit (AST::StaticItem &static_item) override;
+ virtual void visit (AST::TraitItemConst &item) override;
+ virtual void visit (AST::TraitItemType &item) override;
+ virtual void visit (AST::Trait &trait) override;
+ virtual void visit (AST::InherentImpl &impl) override;
+ virtual void visit (AST::TraitImpl &impl) override;
+ // virtual void visit(ExternalItem& item) override;
+ virtual void visit (AST::ExternalTypeItem &item) override;
+ virtual void visit (AST::ExternalStaticItem &item) override;
+ virtual void visit (AST::ExternBlock &block) override;
// rust-macro.h
- virtual void visit (AST::MacroMatchFragment &match);
- virtual void visit (AST::MacroMatchRepetition &match);
- virtual void visit (AST::MacroMatcher &matcher);
- virtual void visit (AST::MacroRulesDefinition &rules_def);
- virtual void visit (AST::MacroInvocation &macro_invoc);
- virtual void visit (AST::MetaItemPath &meta_item);
- virtual void visit (AST::MetaItemSeq &meta_item);
- virtual void visit (AST::MetaWord &meta_item);
- virtual void visit (AST::MetaNameValueStr &meta_item);
- virtual void visit (AST::MetaListPaths &meta_item);
- virtual void visit (AST::MetaListNameValueStr &meta_item);
+ virtual void visit (AST::MacroMatchFragment &match) override;
+ virtual void visit (AST::MacroMatchRepetition &match) override;
+ virtual void visit (AST::MacroMatcher &matcher) override;
+ virtual void visit (AST::MacroRulesDefinition &rules_def) override;
+ virtual void visit (AST::MetaItemPath &meta_item) override;
+ virtual void visit (AST::MetaItemSeq &meta_item) override;
+ virtual void visit (AST::MetaWord &meta_item) override;
+ virtual void visit (AST::MetaNameValueStr &meta_item) override;
+ virtual void visit (AST::MetaListPaths &meta_item) override;
+ virtual void visit (AST::MetaListNameValueStr &meta_item) override;
// rust-pattern.h
- virtual void visit (AST::LiteralPattern &pattern);
- virtual void visit (AST::IdentifierPattern &pattern);
- virtual void visit (AST::WildcardPattern &pattern);
- virtual void visit (AST::RestPattern &pattern);
- // virtual void visit(RangePatternBound& bound);
- virtual void visit (AST::RangePatternBoundLiteral &bound);
- virtual void visit (AST::RangePatternBoundPath &bound);
- virtual void visit (AST::RangePatternBoundQualPath &bound);
- virtual void visit (AST::RangePattern &pattern);
- virtual void visit (AST::ReferencePattern &pattern);
- // virtual void visit(StructPatternField& field);
- virtual void visit (AST::StructPatternFieldTuplePat &field);
- virtual void visit (AST::StructPatternFieldIdentPat &field);
- virtual void visit (AST::StructPatternFieldIdent &field);
- virtual void visit (AST::StructPattern &pattern);
- // virtual void visit(TupleStructItems& tuple_items);
- virtual void visit (AST::TupleStructItemsNoRange &tuple_items);
- virtual void visit (AST::TupleStructItemsRange &tuple_items);
- virtual void visit (AST::TupleStructPattern &pattern);
- // virtual void visit(TuplePatternItems& tuple_items);
- virtual void visit (AST::TuplePatternItemsMultiple &tuple_items);
- virtual void visit (AST::TuplePatternItemsRanged &tuple_items);
- virtual void visit (AST::TuplePattern &pattern);
- virtual void visit (AST::GroupedPattern &pattern);
- virtual void visit (AST::SlicePattern &pattern);
- virtual void visit (AST::AltPattern &pattern);
+ virtual void visit (AST::LiteralPattern &pattern) override;
+ virtual void visit (AST::IdentifierPattern &pattern) override;
+ virtual void visit (AST::WildcardPattern &pattern) override;
+ virtual void visit (AST::RestPattern &pattern) override;
+ // virtual void visit(RangePatternBound& bound) override;
+ virtual void visit (AST::RangePatternBoundLiteral &bound) override;
+ virtual void visit (AST::RangePatternBoundPath &bound) override;
+ virtual void visit (AST::RangePatternBoundQualPath &bound) override;
+ virtual void visit (AST::RangePattern &pattern) override;
+ virtual void visit (AST::ReferencePattern &pattern) override;
+ // virtual void visit(StructPatternField& field) override;
+ virtual void visit (AST::StructPatternFieldTuplePat &field) override;
+ virtual void visit (AST::StructPatternFieldIdentPat &field) override;
+ virtual void visit (AST::StructPatternFieldIdent &field) override;
+ virtual void visit (AST::StructPattern &pattern) override;
+ // virtual void visit(TupleStructItems& tuple_items) override;
+ virtual void visit (AST::TupleStructItemsNoRange &tuple_items) override;
+ virtual void visit (AST::TupleStructItemsRange &tuple_items) override;
+ virtual void visit (AST::TupleStructPattern &pattern) override;
+ // virtual void visit(TuplePatternItems& tuple_items) override;
+ virtual void visit (AST::TuplePatternItemsMultiple &tuple_items) override;
+ virtual void visit (AST::TuplePatternItemsRanged &tuple_items) override;
+ virtual void visit (AST::TuplePattern &pattern) override;
+ virtual void visit (AST::GroupedPattern &pattern) override;
+ virtual void visit (AST::SlicePattern &pattern) override;
+ virtual void visit (AST::AltPattern &pattern) override;
// rust-stmt.h
- virtual void visit (AST::EmptyStmt &stmt);
- virtual void visit (AST::LetStmt &stmt);
- virtual void visit (AST::ExprStmt &stmt);
+ virtual void visit (AST::EmptyStmt &stmt) override;
+ virtual void visit (AST::LetStmt &stmt) override;
+ virtual void visit (AST::ExprStmt &stmt) override;
// rust-type.h
- virtual void visit (AST::TraitBound &bound);
- virtual void visit (AST::ImplTraitType &type);
- virtual void visit (AST::TraitObjectType &type);
- virtual void visit (AST::ParenthesisedType &type);
- virtual void visit (AST::ImplTraitTypeOneBound &type);
- virtual void visit (AST::TraitObjectTypeOneBound &type);
- virtual void visit (AST::TupleType &type);
- virtual void visit (AST::NeverType &type);
- virtual void visit (AST::RawPointerType &type);
- virtual void visit (AST::ReferenceType &type);
- virtual void visit (AST::ArrayType &type);
- virtual void visit (AST::SliceType &type);
- virtual void visit (AST::InferredType &type);
- virtual void visit (AST::BareFunctionType &type);
- virtual void visit (AST::FunctionParam &param);
- virtual void visit (AST::VariadicParam &param);
- virtual void visit (AST::SelfParam &param);
-
- virtual void visit (AST::FormatArgs &fmt);
+ virtual void visit (AST::TraitBound &bound) override;
+ virtual void visit (AST::ImplTraitType &type) override;
+ virtual void visit (AST::TraitObjectType &type) override;
+ virtual void visit (AST::ParenthesisedType &type) override;
+ virtual void visit (AST::ImplTraitTypeOneBound &type) override;
+ virtual void visit (AST::TraitObjectTypeOneBound &type) override;
+ virtual void visit (AST::TupleType &type) override;
+ virtual void visit (AST::NeverType &type) override;
+ virtual void visit (AST::RawPointerType &type) override;
+ virtual void visit (AST::ReferenceType &type) override;
+ virtual void visit (AST::ArrayType &type) override;
+ virtual void visit (AST::SliceType &type) override;
+ virtual void visit (AST::InferredType &type) override;
+ virtual void visit (AST::BareFunctionType &type) override;
+ virtual void visit (AST::FunctionParam &param) override;
+ virtual void visit (AST::VariadicParam &param) override;
+ virtual void visit (AST::SelfParam &param) override;
+
+ virtual void visit (AST::FormatArgs &fmt) override;
protected:
ASTLoweringBase ()
diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h
index be6ca64..93cd443 100644
--- a/gcc/rust/hir/rust-ast-lower-block.h
+++ b/gcc/rust/hir/rust-ast-lower-block.h
@@ -115,7 +115,7 @@ class ASTLoweringIfLetBlock : public ASTLoweringBase
using Rust::HIR::ASTLoweringBase::visit;
public:
- static HIR::IfLetExpr *translate (AST::IfLetExpr &expr)
+ static HIR::MatchExpr *translate (AST::IfLetExpr &expr)
{
ASTLoweringIfLetBlock resolver;
expr.accept_vis (resolver);
@@ -135,7 +135,10 @@ public:
private:
ASTLoweringIfLetBlock () : ASTLoweringBase (), translated (nullptr) {}
- HIR::IfLetExpr *translated;
+ void desugar_iflet (AST::IfLetExpr &, HIR::Expr **, HIR::Expr *,
+ std::vector<HIR::MatchCase> &);
+
+ HIR::MatchExpr *translated;
};
class ASTLoweringExprWithBlock : public ASTLoweringBase
@@ -149,9 +152,7 @@ public:
ASTLoweringExprWithBlock resolver;
expr.accept_vis (resolver);
if (resolver.translated != nullptr)
- {
- resolver.mappings.insert_hir_expr (resolver.translated);
- }
+ resolver.mappings.insert_hir_expr (resolver.translated);
*terminated = resolver.terminated;
return resolver.translated;
@@ -194,7 +195,9 @@ public:
HIR::BlockExpr *loop_block
= ASTLoweringBlock::translate (expr.get_loop_block (), &terminated);
- HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ());
+ tl::optional<HIR::LoopLabel> loop_label = tl::nullopt;
+ if (expr.has_loop_label ())
+ loop_label = lower_loop_label (expr.get_loop_label ());
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc
index 9dd88b4..07d0c835 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-ast-lower-expr.h"
+#include "optional.h"
#include "rust-ast-lower-base.h"
#include "rust-ast-lower-block.h"
#include "rust-ast-lower-struct-field-expr.h"
@@ -77,7 +78,7 @@ ASTLoweringExpr::visit (AST::TupleIndexExpr &expr)
void
ASTLoweringExpr::visit (AST::TupleExpr &expr)
{
- std::vector<std::unique_ptr<HIR::Expr> > tuple_elements;
+ std::vector<std::unique_ptr<HIR::Expr>> tuple_elements;
for (auto &e : expr.get_tuple_elems ())
{
HIR::Expr *t = ASTLoweringExpr::translate (*e);
@@ -174,7 +175,7 @@ ASTLoweringExpr::visit (AST::CallExpr &expr)
HIR::Expr *func = ASTLoweringExpr::translate (expr.get_function_expr ());
auto const &in_params = expr.get_params ();
- std::vector<std::unique_ptr<HIR::Expr> > params;
+ std::vector<std::unique_ptr<HIR::Expr>> params;
for (auto &param : in_params)
{
auto trans = ASTLoweringExpr::translate (*param);
@@ -200,7 +201,7 @@ ASTLoweringExpr::visit (AST::MethodCallExpr &expr)
HIR::Expr *receiver = ASTLoweringExpr::translate (expr.get_receiver_expr ());
auto const &in_params = expr.get_params ();
- std::vector<std::unique_ptr<HIR::Expr> > params;
+ std::vector<std::unique_ptr<HIR::Expr>> params;
for (auto &param : in_params)
{
auto trans = ASTLoweringExpr::translate (*param);
@@ -290,7 +291,7 @@ ASTLoweringExpr::visit (AST::ArrayIndexExpr &expr)
void
ASTLoweringExpr::visit (AST::ArrayElemsValues &elems)
{
- std::vector<std::unique_ptr<HIR::Expr> > elements;
+ std::vector<std::unique_ptr<HIR::Expr>> elements;
for (auto &elem : elems.get_values ())
{
HIR::Expr *translated_elem = ASTLoweringExpr::translate (*elem);
@@ -511,16 +512,18 @@ ASTLoweringExpr::visit (AST::StructExprStructFields &struct_expr)
HIR::PathInExpression copied_path (*path);
delete path;
- HIR::StructBase *base = nullptr;
+ tl::optional<std::unique_ptr<HIR::StructBase>> base = tl::nullopt;
if (struct_expr.has_struct_base ())
{
HIR::Expr *translated_base = ASTLoweringExpr::translate (
struct_expr.get_struct_base ().get_base_struct ());
- base = new HIR::StructBase (std::unique_ptr<HIR::Expr> (translated_base));
+ base = tl::optional<std::unique_ptr<HIR::StructBase>> (
+ std::make_unique<StructBase> (
+ std::unique_ptr<HIR::Expr> (translated_base)));
}
auto const &in_fields = struct_expr.get_fields ();
- std::vector<std::unique_ptr<HIR::StructExprField> > fields;
+ std::vector<std::unique_ptr<HIR::StructExprField>> fields;
for (auto &field : in_fields)
{
HIR::StructExprField *translated
@@ -535,7 +538,8 @@ ASTLoweringExpr::visit (AST::StructExprStructFields &struct_expr)
translated
= new HIR::StructExprStructFields (mapping, copied_path, std::move (fields),
- struct_expr.get_locus (), base,
+ struct_expr.get_locus (),
+ std::move (base),
struct_expr.get_inner_attrs (),
struct_expr.get_outer_attrs ());
}
@@ -587,14 +591,16 @@ ASTLoweringExpr::visit (AST::WhileLoopExpr &expr)
void
ASTLoweringExpr::visit (AST::ForLoopExpr &expr)
{
- translated = ASTLoweringExprWithBlock::translate (expr, &terminated);
+ rust_unreachable ();
}
void
ASTLoweringExpr::visit (AST::BreakExpr &expr)
{
- HIR::Lifetime break_label
- = lower_lifetime (expr.get_label ().get_lifetime ());
+ tl::optional<HIR::Lifetime> break_label = tl::nullopt;
+ if (expr.has_label ())
+ break_label = lower_lifetime (expr.get_label_unchecked ().get_lifetime ());
+
HIR::Expr *break_expr
= expr.has_break_expr ()
? ASTLoweringExpr::translate (expr.get_break_expr ())
@@ -614,7 +620,9 @@ ASTLoweringExpr::visit (AST::BreakExpr &expr)
void
ASTLoweringExpr::visit (AST::ContinueExpr &expr)
{
- HIR::Lifetime break_label = lower_lifetime (expr.get_label ());
+ tl::optional<HIR::Lifetime> break_label;
+ if (expr.has_label ())
+ break_label = lower_lifetime (expr.get_label_unchecked ());
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
@@ -629,9 +637,6 @@ ASTLoweringExpr::visit (AST::ContinueExpr &expr)
void
ASTLoweringExpr::visit (AST::BorrowExpr &expr)
{
- if (expr.is_raw_borrow ())
- rust_unreachable ();
-
HIR::Expr *borrow_lvalue
= ASTLoweringExpr::translate (expr.get_borrowed_expr ());
@@ -642,8 +647,8 @@ ASTLoweringExpr::visit (AST::BorrowExpr &expr)
auto *borrow_expr
= new HIR::BorrowExpr (mapping, std::unique_ptr<HIR::Expr> (borrow_lvalue),
- expr.get_mutability (), expr.get_outer_attrs (),
- expr.get_locus ());
+ expr.get_mutability (), expr.is_raw_borrow (),
+ expr.get_outer_attrs (), expr.get_locus ());
if (expr.get_is_double_borrow ())
{
@@ -655,8 +660,8 @@ ASTLoweringExpr::visit (AST::BorrowExpr &expr)
borrow_expr
= new HIR::BorrowExpr (mapping,
std::unique_ptr<HIR::Expr> (borrow_expr),
- expr.get_mutability (), expr.get_outer_attrs (),
- expr.get_locus ());
+ expr.get_mutability (), expr.is_raw_borrow (),
+ expr.get_outer_attrs (), expr.get_locus ());
}
translated = borrow_expr;
@@ -680,21 +685,6 @@ ASTLoweringExpr::visit (AST::DereferenceExpr &expr)
}
void
-ASTLoweringExpr::visit (AST::ErrorPropagationExpr &expr)
-{
- HIR::Expr *propagating_expr
- = ASTLoweringExpr::translate (expr.get_propagating_expr ());
-
- auto crate_num = mappings.get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
- mappings.get_next_hir_id (crate_num),
- UNKNOWN_LOCAL_DEFID);
- translated = new HIR::ErrorPropagationExpr (
- mapping, std::unique_ptr<HIR::Expr> (propagating_expr),
- expr.get_outer_attrs (), expr.get_locus ());
-}
-
-void
ASTLoweringExpr::visit (AST::MatchExpr &expr)
{
translated = ASTLoweringExprWithBlock::translate (expr, &terminated);
@@ -965,6 +955,50 @@ ASTLoweringExpr::visit (AST::InlineAsm &expr)
hir_operands, expr.get_clobber_abi (),
expr.get_options (), mapping);
}
+
+void
+ASTLoweringExpr::visit (AST::LlvmInlineAsm &expr)
+{
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ mappings.get_next_localdef_id (crate_num));
+
+ std::vector<LlvmOperand> inputs;
+ std::vector<LlvmOperand> outputs;
+
+ for (auto i : expr.get_inputs ())
+ {
+ std::unique_ptr<Expr> inner_expr
+ = std::unique_ptr<Expr> (translate (*i.expr.get ()));
+ inputs.emplace_back (i.constraint, std::move (inner_expr));
+ }
+
+ for (auto o : expr.get_outputs ())
+ {
+ std::unique_ptr<Expr> inner_expr
+ = std::unique_ptr<Expr> (translate (*o.expr.get ()));
+ outputs.emplace_back (o.constraint, std::move (inner_expr));
+ }
+
+ HIR::LlvmInlineAsm::Options options{expr.is_volatile (),
+ expr.is_stack_aligned (),
+ expr.get_dialect ()};
+
+ // We're not really supporting llvm_asm, only the bare minimum
+ // we're quite conservative here as the current code support more usecase.
+ rust_assert (outputs.size () == 0);
+ rust_assert (inputs.size () <= 1);
+ rust_assert (expr.get_clobbers ().size () <= 1);
+ rust_assert (expr.get_templates ().size () == 1);
+ rust_assert (expr.get_templates ()[0].symbol == "");
+
+ translated
+ = new HIR::LlvmInlineAsm (expr.get_locus (), inputs, outputs,
+ expr.get_templates (), expr.get_clobbers (),
+ options, expr.get_outer_attrs (), mapping);
+}
+
void
ASTLoweringExpr::visit (AST::FormatArgs &fmt)
{
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index fc53786..adedeb3 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -113,7 +113,6 @@ public:
void visit (AST::ContinueExpr &expr) override;
void visit (AST::BorrowExpr &expr) override;
void visit (AST::DereferenceExpr &expr) override;
- void visit (AST::ErrorPropagationExpr &expr) override;
void visit (AST::MatchExpr &expr) override;
void visit (AST::RangeFromToExpr &expr) override;
void visit (AST::RangeFromExpr &expr) override;
@@ -123,6 +122,7 @@ public:
void visit (AST::ClosureExprInner &expr) override;
void visit (AST::ClosureExprInnerTyped &expr) override;
void visit (AST::InlineAsm &expr) override;
+ void visit (AST::LlvmInlineAsm &expr) override;
// Extra visitor for FormatArgs nodes
void visit (AST::FormatArgs &fmt) override;
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc
index 5380d25..d815a71 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.cc
+++ b/gcc/rust/hir/rust-ast-lower-implitem.cc
@@ -22,6 +22,7 @@
#include "rust-ast-lower-expr.h"
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-block.h"
+#include "rust-hir-item.h"
#include "rust-item.h"
namespace Rust {
@@ -131,7 +132,7 @@ ASTLowerImplItem::visit (AST::Function &function)
Identifier function_name = function.get_function_name ();
location_t locus = function.get_locus ();
- HIR::SelfParam self_param = HIR::SelfParam::error ();
+ tl::optional<HIR::SelfParam> self_param = tl::nullopt;
if (function.has_self_param ())
self_param = lower_self (function.get_self_param ());
@@ -140,6 +141,9 @@ ASTLowerImplItem::visit (AST::Function &function)
ASTLoweringType::translate (function.get_return_type ()))
: nullptr;
+ Defaultness defaultness
+ = function.is_default () ? Defaultness::Default : Defaultness::Final;
+
std::vector<HIR::FunctionParam> function_params;
for (auto &p : function.get_function_params ())
{
@@ -183,15 +187,15 @@ ASTLowerImplItem::visit (AST::Function &function)
std::move (function_params), std::move (return_type),
std::move (where_clause), std::move (function_body),
std::move (vis), function.get_outer_attrs (),
- std::move (self_param), locus);
+ std::move (self_param), defaultness, locus);
- if (!fn->get_self_param ().is_error ())
+ if (fn->is_method ())
{
// insert mappings for self
- mappings.insert_hir_self_param (&fn->get_self_param ());
+ mappings.insert_hir_self_param (&fn->get_self_param_unchecked ());
mappings.insert_location (
- fn->get_self_param ().get_mappings ().get_hirid (),
- fn->get_self_param ().get_locus ());
+ fn->get_self_param_unchecked ().get_mappings ().get_hirid (),
+ fn->get_self_param_unchecked ().get_locus ());
}
// add the mappings for the function params at the end
@@ -245,9 +249,9 @@ ASTLowerTraitItem::visit (AST::Function &func)
// set self parameter to error if this is a method
// else lower to hir
- HIR::SelfParam self_param = func.has_self_param ()
- ? lower_self (func.get_self_param ())
- : HIR::SelfParam::error ();
+ tl::optional<HIR::SelfParam> self_param = tl::nullopt;
+ if (func.has_self_param ())
+ self_param = lower_self (func.get_self_param ());
std::vector<HIR::FunctionParam> function_params;
for (auto &p : func.get_function_params ())
@@ -299,9 +303,10 @@ ASTLowerTraitItem::visit (AST::Function &func)
if (func.has_self_param ())
{
// insert mappings for self
- mappings.insert_hir_self_param (&self_param);
- mappings.insert_location (self_param.get_mappings ().get_hirid (),
- self_param.get_locus ());
+ // TODO: Is this correct ? Looks fishy
+ mappings.insert_hir_self_param (&*self_param);
+ mappings.insert_location (self_param->get_mappings ().get_hirid (),
+ self_param->get_locus ());
}
// add the mappings for the function params at the end
diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc
index 171737a..f4396b5 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -451,13 +451,16 @@ ASTLoweringItem::visit (AST::Function &function)
mappings.insert_location (function_body->get_mappings ().get_hirid (),
function.get_locus ());
+ Defaultness defaultness
+ = function.is_default () ? Defaultness::Default : Defaultness::Final;
+
auto fn
= new HIR::Function (mapping, std::move (function_name),
std::move (qualifiers), std::move (generic_params),
std::move (function_params), std::move (return_type),
std::move (where_clause), std::move (function_body),
std::move (vis), function.get_outer_attrs (),
- HIR::SelfParam::error (), locus);
+ tl::nullopt, defaultness, locus);
// add the mappings for the function params at the end
for (auto &param : fn->get_function_params ())
@@ -572,6 +575,12 @@ ASTLoweringItem::visit (AST::Trait &trait)
generic_params = lower_generic_params (trait.get_generic_params ());
}
+ // TODO: separate "Self" from normal generic parameters
+ // in HIR as well as in AST?
+ HIR::GenericParam *self_param
+ = ASTLowerGenericParam::translate (trait.get_implicit_self ());
+ generic_params.emplace (generic_params.begin (), self_param);
+
std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
if (trait.has_type_param_bounds ())
{
@@ -600,17 +609,18 @@ ASTLoweringItem::visit (AST::Trait &trait)
mappings.get_next_hir_id (crate_num),
mappings.get_next_localdef_id (crate_num));
- auto trait_unsafety = Unsafety::Normal;
- if (trait.is_unsafe ())
- {
- trait_unsafety = Unsafety::Unsafe;
- }
+ auto trait_unsafety
+ = trait.is_unsafe () ? Unsafety::Unsafe : Unsafety::Normal;
HIR::Trait *hir_trait
= new HIR::Trait (mapping, trait.get_identifier (), trait_unsafety,
std::move (generic_params), std::move (type_param_bounds),
where_clause, std::move (trait_items), vis,
trait.get_outer_attrs (), trait.get_locus ());
+
+ if (trait.is_auto ())
+ mappings.insert_auto_trait (hir_trait);
+
translated = hir_trait;
for (auto trait_item_id : trait_item_ids)
diff --git a/gcc/rust/hir/rust-ast-lower-stmt.cc b/gcc/rust/hir/rust-ast-lower-stmt.cc
index c359459..dbb1723 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.cc
+++ b/gcc/rust/hir/rust-ast-lower-stmt.cc
@@ -16,6 +16,7 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "optional.h"
#include "rust-ast-lower-item.h"
#include "rust-ast-lower-stmt.h"
#include "rust-ast-lower-type.h"
@@ -68,12 +69,23 @@ ASTLoweringStmt::visit (AST::LetStmt &stmt)
{
HIR::Pattern *variables
= ASTLoweringPattern::translate (stmt.get_pattern (), true);
- HIR::Type *type = stmt.has_type ()
- ? ASTLoweringType::translate (stmt.get_type ())
- : nullptr;
- HIR::Expr *init_expression
- = stmt.has_init_expr () ? ASTLoweringExpr::translate (stmt.get_init_expr ())
- : nullptr;
+
+ tl::optional<std::unique_ptr<Type>> type = tl::nullopt;
+
+ if (stmt.has_type ())
+ type
+ = std::unique_ptr<Type> (ASTLoweringType::translate (stmt.get_type ()));
+
+ tl::optional<std::unique_ptr<HIR::Expr>> init_expr = tl::nullopt;
+ tl::optional<std::unique_ptr<HIR::Expr>> else_expr = tl::nullopt;
+
+ if (stmt.has_init_expr ())
+ init_expr = std::unique_ptr<HIR::Expr> (
+ ASTLoweringExpr::translate (stmt.get_init_expr ()));
+
+ if (stmt.has_else_expr ())
+ else_expr = std::unique_ptr<HIR::Expr> (
+ ASTLoweringExpr::translate (stmt.get_else_expr ()));
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (),
@@ -81,9 +93,9 @@ ASTLoweringStmt::visit (AST::LetStmt &stmt)
UNKNOWN_LOCAL_DEFID);
translated
= new HIR::LetStmt (mapping, std::unique_ptr<HIR::Pattern> (variables),
- std::unique_ptr<HIR::Expr> (init_expression),
- std::unique_ptr<HIR::Type> (type),
- stmt.get_outer_attrs (), stmt.get_locus ());
+ std::move (init_expr), std::move (else_expr),
+ std::move (type), stmt.get_outer_attrs (),
+ stmt.get_locus ());
}
void
@@ -157,5 +169,11 @@ ASTLoweringStmt::visit (AST::TraitImpl &impl_block)
translated = ASTLoweringItem::translate (impl_block);
}
+void
+ASTLoweringStmt::visit (AST::StaticItem &var)
+{
+ translated = ASTLoweringItem::translate (var);
+}
+
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h
index 5b1e1b9..737a5f8 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.h
+++ b/gcc/rust/hir/rust-ast-lower-stmt.h
@@ -45,6 +45,7 @@ public:
void visit (AST::Trait &trait) override;
void visit (AST::InherentImpl &impl_block) override;
void visit (AST::TraitImpl &impl_block) override;
+ void visit (AST::StaticItem &var) override;
private:
ASTLoweringStmt () : translated (nullptr), terminated (false) {}
diff --git a/gcc/rust/hir/rust-ast-lower-type.cc b/gcc/rust/hir/rust-ast-lower-type.cc
index 7d6ac5d..a678f18 100644
--- a/gcc/rust/hir/rust-ast-lower-type.cc
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -17,7 +17,11 @@
// <http://www.gnu.org/licenses/>.
#include "rust-ast-lower-type.h"
-#include "rust-attribute-values.h"
+#include "rust-hir-map.h"
+#include "rust-hir-path.h"
+#include "rust-hir-type.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
namespace Rust {
namespace HIR {
@@ -70,11 +74,20 @@ ASTLowerTypePath::visit (AST::TypePathSegment &segment)
Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
UNKNOWN_LOCAL_DEFID);
- HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ());
- translated_segment
- = new HIR::TypePathSegment (std::move (mapping), ident,
- segment.get_separating_scope_resolution (),
- segment.get_locus ());
+ if (segment.is_lang_item ())
+ {
+ translated_segment = new HIR::TypePathSegment (std::move (mapping),
+ segment.get_lang_item (),
+ segment.get_locus ());
+ }
+ else
+ {
+ HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ());
+ translated_segment
+ = new HIR::TypePathSegment (std::move (mapping), ident,
+ segment.get_separating_scope_resolution (),
+ segment.get_locus ());
+ }
}
void
@@ -82,10 +95,6 @@ ASTLowerTypePath::visit (AST::TypePathSegmentGeneric &segment)
{
std::vector<HIR::GenericArgsBinding> binding_args; // TODO
- std::string segment_name = segment.get_ident_segment ().as_string ();
- bool has_separating_scope_resolution
- = segment.get_separating_scope_resolution ();
-
auto generic_args = lower_generic_args (segment.get_generic_args ());
auto crate_num = mappings.get_current_crate ();
@@ -93,10 +102,24 @@ ASTLowerTypePath::visit (AST::TypePathSegmentGeneric &segment)
Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
UNKNOWN_LOCAL_DEFID);
- translated_segment
- = new HIR::TypePathSegmentGeneric (std::move (mapping), segment_name,
- has_separating_scope_resolution,
- generic_args, segment.get_locus ());
+ if (segment.is_lang_item ())
+ {
+ translated_segment
+ = new HIR::TypePathSegmentGeneric (std::move (mapping),
+ segment.get_lang_item (),
+ generic_args, segment.get_locus ());
+ }
+ else
+ {
+ std::string segment_name = segment.get_ident_segment ().as_string ();
+ bool has_separating_scope_resolution
+ = segment.get_separating_scope_resolution ();
+
+ translated_segment
+ = new HIR::TypePathSegmentGeneric (std::move (mapping), segment_name,
+ has_separating_scope_resolution,
+ generic_args, segment.get_locus ());
+ }
}
void
@@ -436,6 +459,60 @@ ASTLoweringType::visit (AST::TraitObjectType &type)
type.get_locus (), type.is_dyn ());
}
+void
+ASTLoweringType::visit (AST::ParenthesisedType &type)
+{
+ auto *inner = ASTLoweringType::translate (*type.get_type_in_parens (),
+ default_to_static_lifetime);
+
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ mappings.get_next_localdef_id (crate_num));
+
+ // FIXME: Do we actually need to know if a type is parenthesized in the HIR?
+ // or can we just use the type in parens?
+ translated
+ = new HIR::ParenthesisedType (mapping, std::unique_ptr<HIR::Type> (inner),
+ type.get_locus ());
+}
+
+void
+ASTLoweringType::visit (AST::ImplTraitType &type)
+{
+ std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds;
+ for (auto &bound : type.get_type_param_bounds ())
+ {
+ auto b = ASTLoweringTypeBounds::translate (*bound.get ());
+ bounds.push_back (std::unique_ptr<HIR::TypeParamBound> (b));
+ }
+
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ mappings.get_next_localdef_id (crate_num));
+
+ translated
+ = new HIR::ImplTraitType (mapping, std::move (bounds), type.get_locus ());
+}
+
+void
+ASTLoweringType::visit (AST::ImplTraitTypeOneBound &type)
+{
+ std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds;
+
+ auto b = ASTLoweringTypeBounds::translate (type.get_trait_bound ());
+ bounds.push_back (std::unique_ptr<HIR::TypeParamBound> (b));
+
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ mappings.get_next_localdef_id (crate_num));
+
+ translated
+ = new HIR::ImplTraitType (mapping, std::move (bounds), type.get_locus ());
+}
+
HIR::GenericParam *
ASTLowerGenericParam::translate (AST::GenericParam &param)
{
@@ -480,7 +557,7 @@ ASTLowerGenericParam::visit (AST::ConstGenericParam &param)
HIR::Expr *default_expr = nullptr;
if (param.has_default_value ())
default_expr = ASTLoweringExpr::translate (
- param.get_default_value ().get_expression ());
+ param.get_default_value_unchecked ().get_expression ());
translated = new HIR::ConstGenericParam (param.get_name ().as_string (),
std::unique_ptr<Type> (type),
@@ -502,9 +579,11 @@ ASTLowerGenericParam::visit (AST::TypeParam &param)
}
}
- HIR::Type *type = param.has_type ()
- ? ASTLoweringType::translate (param.get_type ())
- : nullptr;
+ tl::optional<std::unique_ptr<HIR::Type>> type = tl::nullopt;
+ if (param.has_type ())
+ type
+ = tl::optional<std::unique_ptr<HIR::Type>> (std::unique_ptr<HIR::Type> (
+ ASTLoweringType::translate (param.get_type ())));
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
@@ -514,8 +593,7 @@ ASTLowerGenericParam::visit (AST::TypeParam &param)
translated
= new HIR::TypeParam (mapping, param.get_type_representation (),
param.get_locus (), std::move (type_param_bounds),
- std::unique_ptr<Type> (type),
- param.get_outer_attrs ());
+ std::move (type), param.get_outer_attrs ());
}
HIR::TypeParamBound *
diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
index 5bb9a7e..4efaeee 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -21,6 +21,8 @@
#include "rust-ast-lower-base.h"
#include "rust-ast-lower-expr.h"
+#include "rust-hir-path.h"
+#include "rust-type.h"
namespace Rust {
namespace HIR {
@@ -78,6 +80,10 @@ public:
void visit (AST::NeverType &type) override;
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;
private:
ASTLoweringType (bool default_to_static_lifetime)
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index 5a5c93f..76bd135 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -24,6 +24,8 @@
#include "rust-ast-lower-type.h"
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-struct-field-expr.h"
+#include "rust-expr.h"
+#include "rust-hir-expr.h"
namespace Rust {
namespace HIR {
@@ -95,14 +97,22 @@ ASTLowering::go ()
void
ASTLoweringBlock::visit (AST::BlockExpr &expr)
{
- auto label = lower_loop_label (expr.get_label ());
+ tl::optional<HIR::LoopLabel> label;
+ if (expr.has_label ())
+ label = lower_loop_label (expr.get_label ());
+ else
+ label = tl::nullopt;
std::vector<std::unique_ptr<HIR::Stmt>> block_stmts;
bool block_did_terminate = false;
for (auto &s : expr.get_statements ())
{
- if (s->get_ast_kind () == AST::Kind::MACRO_INVOCATION)
+ // FIXME: We basically need to do that check for *every* single node in
+ // the AST. this isn't realistic and this should be turned into an
+ // optional, debug-visitor instead, which goes through the entire AST and
+ // checks if any of the nodes are macro invocations
+ if (s->get_stmt_kind () == AST::Stmt::Kind::MacroInvocation)
rust_fatal_error (
s->get_locus (),
"macro invocations should not get lowered to HIR - At "
@@ -198,62 +208,144 @@ ASTLoweringIfBlock::visit (AST::IfExprConseqElse &expr)
std::unique_ptr<HIR::ExprWithBlock> (else_block), expr.get_locus ());
}
+/**
+ * Lowers the common part "if let 'pattern' = 'expr' { 'if_block' }" of
+ * IfLetExpr[ConseqElse]:
+ * - 'expr' is lowered into *BRANCH_VALUE
+ * - 'pattern' + 'if_block' are lowered and resulting ARM pushed in MATCH_ARMS
+ * - 'KASE_ELSE_EXPR' is the lowered HIR to be used in the else part.
+ *
+ * Looks like:
+ *
+ * match (expr) {
+ * pattern => {if_block}
+ * _ => kase_else_expr
+ * }
+ *
+ */
void
-ASTLoweringIfLetBlock::visit (AST::IfLetExpr &expr)
+ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr &expr,
+ HIR::Expr **branch_value,
+ HIR::Expr *kase_else_expr,
+ std::vector<HIR::MatchCase> &match_arms)
{
- std::vector<std::unique_ptr<HIR::Pattern>> patterns;
+ HIR::Expr *kase_expr;
+ std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns;
+
+ *branch_value = ASTLoweringExpr::translate (expr.get_value_expr ());
+ kase_expr = ASTLoweringExpr::translate (expr.get_if_block ());
+
+ // (stable) if let only accepts a single pattern, but (unstable) if let chains
+ // need more than one pattern.
+ // We don't support if let chains, so only support a single pattern.
+ rust_assert (expr.get_patterns ().size () == 1);
+
for (auto &pattern : expr.get_patterns ())
{
HIR::Pattern *ptrn = ASTLoweringPattern::translate (*pattern);
- patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
+ match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
}
- HIR::Expr *value_ptr = ASTLoweringExpr::translate (expr.get_value_expr ());
- bool ignored_terminated = false;
- HIR::BlockExpr *block
- = ASTLoweringBlock::translate (expr.get_if_block (), &ignored_terminated);
+ // The match arm corresponding to the if let pattern when it matches.
+ HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (), nullptr,
+ {});
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- translated = new HIR::IfLetExpr (mapping, std::move (patterns),
- std::unique_ptr<HIR::Expr> (value_ptr),
- std::unique_ptr<HIR::BlockExpr> (block),
- expr.get_locus ());
+ HIR::MatchCase kase (std::move (mapping), std::move (arm),
+ std::unique_ptr<HIR::Expr> (kase_expr));
+ match_arms.push_back (std::move (kase));
+
+ // The default match arm when the if let pattern does not match
+ std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns_wildcard;
+ Analysis::NodeMapping mapping_default (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ std::unique_ptr<HIR::WildcardPattern> wc
+ = std::unique_ptr<HIR::WildcardPattern> (
+ new HIR::WildcardPattern (mapping_default, expr.get_locus ()));
+
+ match_arm_patterns_wildcard.push_back (std::move (wc));
+
+ HIR::MatchArm arm_default (std::move (match_arm_patterns_wildcard),
+ expr.get_locus (), nullptr, {});
+
+ HIR::MatchCase kase_else (std::move (mapping_default),
+ std::move (arm_default),
+ std::unique_ptr<HIR::Expr> (kase_else_expr));
+ match_arms.push_back (std::move (kase_else));
}
void
-ASTLoweringIfLetBlock::visit (AST::IfLetExprConseqElse &expr)
+ASTLoweringIfLetBlock::visit (AST::IfLetExpr &expr)
{
- std::vector<std::unique_ptr<HIR::Pattern>> patterns;
- for (auto &pattern : expr.get_patterns ())
- {
- HIR::Pattern *ptrn = ASTLoweringPattern::translate (*pattern);
- patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
- }
- HIR::Expr *value_ptr = ASTLoweringExpr::translate (expr.get_value_expr ());
+ // Desugar:
+ // if let Some(y) = some_value {
+ // bar();
+ // }
+ //
+ // into:
+ //
+ // match some_value {
+ // Some(y) => {bar();},
+ // _ => ()
+ // }
+
+ HIR::Expr *branch_value;
- bool ignored_terminated = false;
- HIR::BlockExpr *block
- = ASTLoweringBlock::translate (expr.get_if_block (), &ignored_terminated);
+ std::vector<HIR::MatchCase> match_arms;
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
- HIR::ExprWithBlock *else_block
- = ASTLoweringExprWithBlock::translate (expr.get_else_block (),
- &ignored_terminated);
+ HIR::TupleExpr *unit
+ = new HIR::TupleExpr (mapping, {}, {}, {}, expr.get_locus ());
- rust_assert (else_block);
+ desugar_iflet (expr, &branch_value, unit, match_arms);
+
+ translated
+ = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
+ std::move (match_arms), {}, {}, expr.get_locus ());
+}
+
+void
+ASTLoweringIfLetBlock::visit (AST::IfLetExprConseqElse &expr)
+{
+ // desugar:
+ // if let Some(y) = some_value {
+ // bar();
+ // } else {
+ // baz();
+ // }
+ //
+ // into
+ // match some_value {
+ // Some(y) => {bar();},
+ // _ => {baz();}
+ // }
+ //
+
+ HIR::Expr *branch_value;
+ std::vector<HIR::MatchCase> match_arms;
+
+ HIR::Expr *kase_else_expr
+ = ASTLoweringExpr::translate (expr.get_else_block ());
+
+ desugar_iflet (expr, &branch_value, kase_else_expr, match_arms);
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- translated = new HIR::IfLetExprConseqElse (
- mapping, std::move (patterns), std::unique_ptr<HIR::Expr> (value_ptr),
- std::unique_ptr<HIR::BlockExpr> (block),
- std::unique_ptr<HIR::ExprWithBlock> (else_block), expr.get_locus ());
+ translated
+ = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
+ std::move (match_arms), {}, {}, expr.get_locus ());
}
// rust-ast-lower-struct-field-expr.h
@@ -310,7 +402,10 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr)
HIR::BlockExpr *loop_block
= ASTLoweringBlock::translate (expr.get_loop_block (), &terminated);
- HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ());
+ tl::optional<HIR::LoopLabel> loop_label;
+ if (expr.has_loop_label ())
+ loop_label = lower_loop_label (expr.get_loop_label ());
+
HIR::Expr *loop_condition
= ASTLoweringExpr::translate (expr.get_predicate_expr (), &terminated);
@@ -330,24 +425,7 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr)
void
ASTLoweringExprWithBlock::visit (AST::ForLoopExpr &expr)
{
- // TODO FIXME
-
- // HIR::BlockExpr *loop_block
- // = ASTLoweringBlock::translate (expr.get_loop_block ().get (),
- // &terminated);
- // HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ());
- // HIR::Expr *iterator_expr
- // = ASTLoweringExpr::translate (expr.get_iterator_expr ().get (),
- // &terminated);
- // HIR::Pattern *loop_pattern
- // = ASTLoweringPattern::translate (expr.get_pattern ().get ());
-
- // auto crate_num = mappings->get_current_crate ();
- // Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
- // mappings->get_next_hir_id (crate_num),
- // UNKNOWN_LOCAL_DEFID);
-
- gcc_unreachable ();
+ rust_unreachable ();
}
void
@@ -406,6 +484,18 @@ ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
void
ASTLowerPathInExpression::visit (AST::PathInExpression &expr)
{
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ if (expr.is_lang_item ())
+ {
+ translated = new HIR::PathInExpression (mapping, expr.get_lang_item (),
+ expr.get_locus (), false);
+ return;
+ }
+
std::vector<HIR::PathExprSegment> path_segments;
auto &segments = expr.get_segments ();
for (auto &s : segments)
@@ -416,10 +506,6 @@ ASTLowerPathInExpression::visit (AST::PathInExpression &expr)
HIR::PathExprSegment *lowered_seg = &path_segments.back ();
mappings.insert_hir_path_expr_seg (lowered_seg);
}
- auto crate_num = mappings.get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
- mappings.get_next_hir_id (crate_num),
- UNKNOWN_LOCAL_DEFID);
translated = new HIR::PathInExpression (mapping, std::move (path_segments),
expr.get_locus (),
diff --git a/gcc/rust/hir/rust-ast-lower.h b/gcc/rust/hir/rust-ast-lower.h
index 079ffa9..cc74082 100644
--- a/gcc/rust/hir/rust-ast-lower.h
+++ b/gcc/rust/hir/rust-ast-lower.h
@@ -39,6 +39,11 @@ struct_field_name_exists (std::vector<HIR::StructField> &fields,
Visibility
translate_visibility (const AST::Visibility &vis);
+/**
+ * Main base class used for lowering AST to HIR.
+ *
+ * Every subclass should provide a translate() method that takes an AST node and
+ * lowers it to some HIR stored in the TRANSLATED member. */
class ASTLowering
{
public:
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index b441377..cb32f68 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -22,9 +22,9 @@
#include "rust-hir-path.h"
#include "rust-hir-type.h"
#include "rust-hir.h"
-#include <string>
#include "rust-attribute-values.h"
#include "tree/rust-hir-expr.h"
+#include "rust-system.h"
namespace Rust {
namespace HIR {
@@ -315,6 +315,14 @@ Dump::do_functionparam (FunctionParam &e)
void
Dump::do_pathpattern (PathPattern &e)
{
+ if (e.get_path_kind () == PathPattern::Kind::LangItem)
+ {
+ put_field ("segments", "#[lang = \""
+ + LangItem::ToString (e.get_lang_item ())
+ + "\"]");
+ return;
+ }
+
std::string str = "";
for (const auto &segment : e.get_segments ())
@@ -359,7 +367,8 @@ Dump::do_matcharm (MatchArm &e)
// FIXME Can't remember how to handle that. Let's see later.
// do_outer_attrs(e);
visit_collection ("match_arm_patterns", e.get_patterns ());
- visit_field ("guard_expr", e.get_guard_expr ());
+ if (e.has_match_arm_guard ())
+ visit_field ("guard_expr", e.get_guard_expr ());
end ("MatchArm");
}
@@ -387,7 +396,10 @@ void
Dump::do_typepathsegment (TypePathSegment &e)
{
do_mappings (e.get_mappings ());
- put_field ("ident_segment", e.get_ident_segment ().as_string ());
+ if (e.is_lang_item ())
+ put_field ("ident_segment", LangItem::PrettyString (e.get_lang_item ()));
+ else
+ put_field ("ident_segment", e.get_ident_segment ().as_string ());
}
void
@@ -401,9 +413,13 @@ void
Dump::do_qualifiedpathtype (QualifiedPathType &e)
{
do_mappings (e.get_mappings ());
- visit_field ("type", e.get_type ());
+ if (e.has_type ())
+ visit_field ("type", e.get_type ());
+ else
+ put_field ("type", "none");
- visit_field ("trait", e.get_trait ());
+ if (e.has_trait ())
+ visit_field ("trait", e.get_trait ());
}
void
@@ -464,17 +480,6 @@ Dump::do_baseloopexpr (BaseLoopExpr &e)
}
void
-Dump::do_ifletexpr (IfLetExpr &e)
-{
- do_expr (e);
-
- visit_collection ("match_arm_patterns", e.get_patterns ());
-
- visit_field ("value", e.get_scrutinee_expr ());
- visit_field ("if_block", e.get_if_block ());
-}
-
-void
Dump::do_struct (Struct &e)
{
do_vis_item (e);
@@ -531,14 +536,18 @@ Dump::do_traitfunctiondecl (TraitFunctionDecl &e)
else
put_field ("function_params", "empty");
- visit_field ("return_type", e.get_return_type ());
+ if (e.has_return_type ())
+ visit_field ("return_type", e.get_return_type ());
+ else
+ put_field ("return_type", "none");
if (e.has_where_clause ())
put_field ("where_clause", e.get_where_clause ().as_string ());
else
put_field ("where_clause", "none");
- put_field ("self", e.get_self ().as_string ());
+ if (e.is_method ())
+ put_field ("self", e.get_self_unchecked ().as_string ());
end ("TraitFunctionDecl");
}
@@ -811,7 +820,7 @@ Dump::visit (QualifiedPathInType &e)
end_field ("path_type");
begin_field ("associated_segment");
- do_typepathsegment (*e.get_associated_segment ());
+ do_typepathsegment (e.get_associated_segment ());
end_field ("associated_segment");
visit_collection ("segments", e.get_segments ());
@@ -922,7 +931,7 @@ Dump::visit (ArithmeticOrLogicalExpr &e)
}
put_field ("expr_type", str);
do_operatorexpr (e);
- visit_field ("right_expr", *e.get_rhs ());
+ visit_field ("right_expr", e.get_rhs ());
end ("ArithmeticOrLogicalExpr");
}
@@ -957,7 +966,7 @@ Dump::visit (ComparisonExpr &e)
}
put_field ("expr_type", str);
do_operatorexpr (e);
- visit_field ("right_expr", *e.get_rhs ());
+ visit_field ("right_expr", e.get_rhs ());
end ("ComparisonExpr");
}
@@ -980,7 +989,7 @@ Dump::visit (LazyBooleanExpr &e)
}
do_operatorexpr (e);
- visit_field ("right_expr", *e.get_rhs ());
+ visit_field ("right_expr", e.get_rhs ());
end ("LazyBooleanExpr");
}
@@ -998,7 +1007,7 @@ Dump::visit (AssignmentExpr &e)
{
begin ("AssignmentExpr");
do_operatorexpr (e);
- visit_field ("right_expr", *e.get_rhs ());
+ visit_field ("right_expr", e.get_rhs ());
end ("AssignmentExpr");
}
@@ -1008,7 +1017,7 @@ Dump::visit (CompoundAssignmentExpr &e)
begin ("CompoundAssignmentExpr");
do_operatorexpr (e);
- visit_field ("right_expr", *e.get_rhs ());
+ visit_field ("right_expr", e.get_rhs ());
std::string str;
@@ -1182,7 +1191,7 @@ Dump::visit (StructExprStructFields &e)
if (!e.has_struct_base ())
put_field ("struct_base", "none");
else
- put_field ("struct_base", e.get_struct_base ()->as_string ());
+ put_field ("struct_base", e.get_struct_base ().as_string ());
end ("StructExprStructFields");
}
@@ -1193,7 +1202,7 @@ Dump::visit (StructExprStructBase &e)
begin ("StructExprStructBase");
do_structexprstruct (e);
- put_field ("struct_base", e.get_struct_base ()->as_string ());
+ put_field ("struct_base", e.get_struct_base ().as_string ());
end ("StructExprStructBase");
}
@@ -1252,13 +1261,17 @@ Dump::visit (ClosureExpr &e)
auto oa = param.get_outer_attrs ();
do_outer_attrs (oa);
visit_field ("pattern", param.get_pattern ());
- visit_field ("type", param.get_type ());
+
+ if (param.has_type_given ())
+ visit_field ("type", param.get_type ());
+
end ("ClosureParam");
}
end_field ("params");
}
- visit_field ("return_type", e.get_return_type ());
+ if (e.has_return_type ())
+ visit_field ("return_type", e.get_return_type ());
visit_field ("expr", e.get_expr ());
end ("ClosureExpr");
@@ -1271,11 +1284,14 @@ Dump::visit (BlockExpr &e)
do_expr (e);
do_inner_attrs (e);
put_field ("tail_reachable", std::to_string (e.is_tail_reachable ()));
- put_field ("label", e.get_label ().as_string ());
+
+ if (e.has_label ())
+ put_field ("label", e.get_label ().as_string ());
visit_collection ("statements", e.get_statements ());
- visit_field ("expr", e.get_final_expr ());
+ if (e.has_final_expr ())
+ visit_field ("expr", e.get_final_expr ());
end ("BlockExpr");
}
@@ -1304,7 +1320,10 @@ Dump::visit (BreakExpr &e)
else
put_field ("label", "none");
- visit_field ("break_expr ", e.get_expr ());
+ if (e.has_break_expr ())
+ visit_field ("break_expr ", e.get_expr ());
+ else
+ put_field ("break_expr", "none");
end ("BreakExpr");
}
@@ -1374,7 +1393,8 @@ Dump::visit (ReturnExpr &e)
begin ("ReturnExpr");
do_mappings (e.get_mappings ());
- visit_field ("return_expr", e.get_expr ());
+ if (e.has_return_expr ())
+ visit_field ("return_expr", e.get_expr ());
end ("ReturnExpr");
}
@@ -1442,23 +1462,6 @@ Dump::visit (IfExprConseqElse &e)
}
void
-Dump::visit (IfLetExpr &e)
-{
- begin ("IfLetExpr");
- do_ifletexpr (e);
- end ("IfLetExpr");
-}
-
-void
-Dump::visit (IfLetExprConseqElse &e)
-{
- begin ("IfLetExprConseqElse");
- do_ifletexpr (e);
- visit_field ("else_block", e.get_else_block ());
- end ("IfLetExprConseqElse");
-}
-
-void
Dump::visit (MatchExpr &e)
{
begin ("MatchExpr");
@@ -1507,6 +1510,10 @@ Dump::visit (InlineAsm &e)
{}
void
+Dump::visit (LlvmInlineAsm &e)
+{}
+
+void
Dump::visit (TypeParam &e)
{
begin ("TypeParam");
@@ -1517,7 +1524,8 @@ Dump::visit (TypeParam &e)
visit_collection ("type_param_bounds", e.get_type_param_bounds ());
- visit_field ("type", e.get_type ());
+ if (e.has_type ())
+ visit_field ("type", e.get_type ());
end ("TypeParam");
}
@@ -1683,7 +1691,8 @@ Dump::visit (Function &e)
put_field ("function_params", "empty");
}
- visit_field ("return_type", e.get_return_type ());
+ if (e.has_function_return_type ())
+ visit_field ("return_type", e.get_return_type ());
if (!e.has_where_clause ())
put_field ("where_clause", "none");
@@ -1691,7 +1700,8 @@ Dump::visit (Function &e)
put_field ("where clause", e.get_where_clause ().as_string ());
visit_field ("function_body", e.get_definition ());
- put_field ("self", e.get_self_param ().as_string ());
+ if (e.is_method ())
+ put_field ("self", e.get_self_param_unchecked ().as_string ());
end ("Function");
}
@@ -1712,7 +1722,7 @@ Dump::visit (TypeAlias &e)
else
put_field ("where clause", e.get_where_clause ().as_string ());
- put_field ("type", e.get_type_aliased ()->as_string ());
+ put_field ("type", e.get_type_aliased ().as_string ());
end ("TypeAlias");
}
@@ -1916,7 +1926,8 @@ Dump::visit (TraitItemFunc &e)
do_traitfunctiondecl (e.get_decl ());
- visit_field ("block_expr", e.get_block_expr ());
+ if (e.has_definition ())
+ visit_field ("block_expr", e.get_block_expr ());
end ("TraitItemFunc");
}
@@ -1929,7 +1940,9 @@ Dump::visit (TraitItemConst &e)
put_field ("name", e.get_name ().as_string ());
visit_field ("type", e.get_type ());
- visit_field ("expr", e.get_expr ());
+ if (e.has_expr ())
+ visit_field ("expr", e.get_expr ());
+
end ("TraitItemConst");
}
@@ -2031,7 +2044,8 @@ Dump::visit (ExternalFunctionItem &e)
put_field ("has_variadics", std::to_string (e.is_variadic ()));
- visit_field ("return_type", e.get_return_type ());
+ if (e.has_return_type ())
+ visit_field ("return_type", e.get_return_type ());
end ("ExternalFunctionItem");
}
@@ -2078,7 +2092,7 @@ Dump::visit (IdentifierPattern &e)
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 ());
+ put_field ("to_bind", e.get_to_bind ().as_string ());
else
put_field ("to_bind", "none");
@@ -2122,8 +2136,8 @@ Dump::visit (RangePattern &e)
{
begin ("RangePattern");
do_mappings (e.get_mappings ());
- put_field ("lower", e.get_lower_bound ()->as_string ());
- put_field ("upper", e.get_upper_bound ()->as_string ());
+ put_field ("lower", e.get_lower_bound ().as_string ());
+ put_field ("upper", e.get_upper_bound ().as_string ());
put_field ("has_ellipsis_syntax",
std::to_string (e.get_has_ellipsis_syntax ()));
end ("RangePattern");
@@ -2135,7 +2149,7 @@ Dump::visit (ReferencePattern &e)
begin ("ReferencePattern");
do_mappings (e.get_mappings ());
put_field ("mut", std::to_string (e.is_mut ()));
- put_field ("pattern", e.get_referenced_pattern ()->as_string ());
+ put_field ("pattern", e.get_referenced_pattern ().as_string ());
end ("ReferencePattern");
}
@@ -2147,7 +2161,7 @@ Dump::visit (StructPatternFieldTuplePat &e)
auto oa = e.get_outer_attrs ();
do_outer_attrs (oa);
put_field ("index", std::to_string (e.get_index ()));
- put_field ("tuple_pattern", e.get_tuple_pattern ()->as_string ());
+ put_field ("tuple_pattern", e.get_tuple_pattern ().as_string ());
end ("StructPatternFieldTuplePat");
}
@@ -2158,7 +2172,7 @@ Dump::visit (StructPatternFieldIdentPat &e)
auto oa = e.get_outer_attrs ();
do_outer_attrs (oa);
put_field ("ident", e.get_identifier ().as_string ());
- put_field ("ident_pattern", e.get_pattern ()->as_string ());
+ put_field ("ident_pattern", e.get_pattern ().as_string ());
end ("StructPatternFieldIdentPat");
}
@@ -2276,10 +2290,12 @@ Dump::visit (LetStmt &e)
auto oa = e.get_outer_attrs ();
do_outer_attrs (oa);
- put_field ("variable_pattern", e.get_pattern ()->as_string ());
+ put_field ("variable_pattern", e.get_pattern ().as_string ());
- visit_field ("type", e.get_type ());
- visit_field ("init_expr", e.get_init_expr ());
+ if (e.has_type ())
+ visit_field ("type", e.get_type ());
+ if (e.has_init_expr ())
+ visit_field ("init_expr", e.get_init_expr ());
end ("LetStmt");
}
@@ -2337,20 +2353,11 @@ Dump::visit (ParenthesisedType &e)
{
begin ("ParenthesisedType");
do_type (e);
- put_field ("type_in_parens", e.get_type_in_parens ()->as_string ());
+ put_field ("type_in_parens", e.get_type_in_parens ().as_string ());
end ("ParenthesisedType");
}
void
-Dump::visit (ImplTraitTypeOneBound &e)
-{
- begin ("ImplTraitTypeOneBound");
- do_type (e);
- visit_field ("trait_bound", e.get_trait_bound ());
- end ("ImplTraitTypeOneBound");
-}
-
-void
Dump::visit (TupleType &e)
{
begin ("TupleType");
@@ -2373,7 +2380,7 @@ Dump::visit (RawPointerType &e)
begin ("RawPointerType");
do_type (e);
put_field ("mut", Rust::enum_to_str (e.get_mut ()));
- put_field ("type", e.get_type ()->as_string ());
+ put_field ("type", e.get_type ().as_string ());
end ("RawPointerType");
}
@@ -2384,7 +2391,7 @@ Dump::visit (ReferenceType &e)
do_type (e);
put_field ("lifetime", e.get_lifetime ().as_string ());
put_field ("mut", enum_to_str (e.get_mut ()));
- put_field ("type", e.get_base_type ()->as_string ());
+ put_field ("type", e.get_base_type ().as_string ());
end ("ReferenceType");
}
@@ -2441,7 +2448,9 @@ Dump::visit (BareFunctionType &e)
end_field ("params");
}
- visit_field ("return_type", e.get_return_type ());
+ if (e.has_return_type ())
+ visit_field ("return_type", e.get_return_type ());
+
put_field ("is_variadic", std::to_string (e.get_is_variadic ()));
end ("BareFunctionType");
}
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index b3a2020..45b1708 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -80,7 +80,6 @@ private:
void do_type (Type &);
void do_expr (Expr &);
void do_ifexpr (IfExpr &);
- void do_ifletexpr (IfLetExpr &);
void do_pathexpr (PathExpr &);
void do_pathpattern (PathPattern &);
void do_genericargs (GenericArgs &);
@@ -162,13 +161,12 @@ private:
virtual void visit (WhileLetLoopExpr &) override;
virtual void visit (IfExpr &) override;
virtual void visit (IfExprConseqElse &) override;
- virtual void visit (IfLetExpr &) override;
- virtual void visit (IfLetExprConseqElse &) override;
virtual void visit (MatchExpr &) override;
virtual void visit (AwaitExpr &) override;
virtual void visit (AsyncBlockExpr &) override;
virtual void visit (InlineAsm &) override;
+ virtual void visit (LlvmInlineAsm &) override;
virtual void visit (TypeParam &) override;
virtual void visit (ConstGenericParam &) override;
@@ -240,7 +238,6 @@ private:
virtual void visit (ImplTraitType &) override;
virtual void visit (TraitObjectType &) override;
virtual void visit (ParenthesisedType &) override;
- virtual void visit (ImplTraitTypeOneBound &) override;
virtual void visit (TupleType &) override;
virtual void visit (NeverType &) override;
virtual void visit (RawPointerType &) override;
diff --git a/gcc/rust/hir/tree/rust-hir-attrs.h b/gcc/rust/hir/tree/rust-hir-attrs.h
new file mode 100644
index 0000000..3e2b1d8
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-attrs.h
@@ -0,0 +1,56 @@
+
+// Copyright (C) 2020-2024 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_HIR_ATTRS_H
+#define RUST_HIR_ATTRS_H
+
+#include "rust-ast.h"
+
+namespace Rust {
+namespace HIR {
+
+class WithOuterAttrs
+{
+protected:
+ AST::AttrVec outer_attrs;
+
+public:
+ AST::AttrVec &get_outer_attrs () { return outer_attrs; }
+ const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
+
+ WithOuterAttrs (AST::AttrVec outer_attrs)
+ : outer_attrs (std::move (outer_attrs)){};
+};
+
+class WithInnerAttrs
+{
+protected:
+ AST::AttrVec inner_attrs;
+
+public:
+ AST::AttrVec get_inner_attrs () const { return inner_attrs; }
+
+ WithInnerAttrs (AST::AttrVec inner_attrs)
+ : inner_attrs (std::move (inner_attrs)){};
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-bound-abstract.h b/gcc/rust/hir/tree/rust-hir-bound-abstract.h
new file mode 100644
index 0000000..ffc915b
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-bound-abstract.h
@@ -0,0 +1,65 @@
+// Copyright (C) 2020-2024 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_HIR_BOUND_ABSTRACT_H
+#define RUST_HIR_BOUND_ABSTRACT_H
+
+#include "rust-hir-visitable.h"
+#include "rust-system.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace HIR {
+
+/* Abstract base class representing a type param bound - Lifetime and TraitBound
+ * extends it */
+class TypeParamBound : public FullVisitable
+{
+public:
+ using FullVisitable::accept_vis;
+ enum BoundType
+ {
+ LIFETIME,
+ TRAITBOUND
+ };
+
+ virtual ~TypeParamBound () {}
+
+ // Unique pointer custom clone function
+ std::unique_ptr<TypeParamBound> clone_type_param_bound () const
+ {
+ return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
+ }
+
+ virtual std::string as_string () const = 0;
+
+ virtual Analysis::NodeMapping get_mappings () const = 0;
+
+ virtual location_t get_locus () const = 0;
+
+ virtual BoundType get_bound_type () const = 0;
+
+protected:
+ // Clone function implementation as pure virtual method
+ virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-bound.h b/gcc/rust/hir/tree/rust-hir-bound.h
new file mode 100644
index 0000000..8fa6a22
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-bound.h
@@ -0,0 +1,82 @@
+// Copyright (C) 2020-2024 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_HIR_BOUND_H
+#define RUST_HIR_BOUND_H
+
+#include "rust-hir-bound-abstract.h"
+#include "rust-common.h"
+#include "rust-hir-path.h"
+
+namespace Rust {
+namespace HIR {
+
+// Represents a lifetime (and is also a kind of type param bound)
+class Lifetime : public TypeParamBound
+{
+private:
+ AST::Lifetime::LifetimeType lifetime_type;
+ std::string lifetime_name;
+ location_t locus;
+ Analysis::NodeMapping mappings;
+
+public:
+ // Constructor
+ Lifetime (Analysis::NodeMapping mapping, AST::Lifetime::LifetimeType type,
+ std::string name, location_t locus)
+ : lifetime_type (type), lifetime_name (std::move (name)), locus (locus),
+ mappings (mapping)
+ {}
+
+ // Returns true if the lifetime is in an error state.
+ std::string as_string () const override;
+
+ void accept_vis (HIRFullVisitor &vis) override;
+
+ WARN_UNUSED_RESULT const std::string &get_name () const
+ {
+ return lifetime_name;
+ }
+
+ AST::Lifetime::LifetimeType get_lifetime_type () const
+ {
+ return lifetime_type;
+ }
+
+ location_t get_locus () const override final { return locus; }
+
+ Analysis::NodeMapping get_mappings () const override final
+ {
+ return mappings;
+ }
+
+ BoundType get_bound_type () const final override { return LIFETIME; }
+
+protected:
+ /* Use covariance to implement clone function as returning this object rather
+ * than base */
+ Lifetime *clone_type_param_bound_impl () const override
+ {
+ return new Lifetime (*this);
+ }
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-expr-abstract.h b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
new file mode 100644
index 0000000..5bc5d89
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
@@ -0,0 +1,175 @@
+// Copyright (C) 2020-2024 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_HIR_EXPR_ABSTRACT_H
+#define RUST_HIR_EXPR_ABSTRACT_H
+
+#include "rust-ast.h"
+#include "rust-hir-visitable.h"
+#include "rust-hir-node.h"
+
+namespace Rust {
+namespace HIR {
+
+// Base expression HIR node - abstract
+class Expr : public Node, virtual public FullVisitable
+{
+public:
+ using FullVisitable::accept_vis;
+
+protected:
+ AST::AttrVec outer_attrs;
+ Analysis::NodeMapping mappings;
+
+public:
+ enum BlockType
+ {
+ WITH_BLOCK,
+ WITHOUT_BLOCK,
+ };
+
+ enum ExprType
+ {
+ Lit,
+ Operator,
+ Grouped,
+ Array,
+ ArrayIndex,
+ Tuple,
+ TupleIdx,
+ Struct,
+ Call,
+ MethodCall,
+ FieldAccess,
+ Closure,
+ Block,
+ Continue,
+ Break,
+ Range,
+ Return,
+ UnsafeBlock,
+ BaseLoop,
+ If,
+ IfLet,
+ Match,
+ Await,
+ AsyncBlock,
+ Path,
+ InlineAsm,
+ LlvmInlineAsm,
+ };
+
+ BaseKind get_hir_kind () override final { return Node::BaseKind::EXPR; }
+
+ const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
+
+ // Unique pointer custom clone function
+ std::unique_ptr<Expr> clone_expr () const
+ {
+ return std::unique_ptr<Expr> (clone_expr_impl ());
+ }
+
+ // TODO: make pure virtual if move out outer attributes to derived classes
+ virtual std::string as_string () const;
+
+ virtual ~Expr () {}
+
+ virtual location_t get_locus () const = 0;
+
+ const Analysis::NodeMapping &get_mappings () const { return mappings; }
+
+ // Clone function implementation as pure virtual method
+ virtual Expr *clone_expr_impl () const = 0;
+
+ virtual BlockType get_block_expr_type () const = 0;
+
+ virtual ExprType get_expression_type () const = 0;
+
+ virtual void accept_vis (HIRExpressionVisitor &vis) = 0;
+
+protected:
+ // Constructor
+ Expr (Analysis::NodeMapping mappings,
+ AST::AttrVec outer_attribs = AST::AttrVec ());
+
+ // TODO: think of less hacky way to implement this kind of thing
+ // Sets outer attributes.
+ void set_outer_attrs (AST::AttrVec outer_attrs_to_set)
+ {
+ outer_attrs = std::move (outer_attrs_to_set);
+ }
+};
+
+// HIR node for an expression without an accompanying block - abstract
+class ExprWithoutBlock : public Expr
+{
+protected:
+ // Constructor
+ ExprWithoutBlock (Analysis::NodeMapping mappings,
+ AST::AttrVec outer_attribs = AST::AttrVec ());
+
+ // pure virtual clone implementation
+ virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0;
+
+ /* Save having to specify two clone methods in derived classes by making expr
+ * clone return exprwithoutblock clone. Hopefully won't affect performance too
+ * much. */
+ ExprWithoutBlock *clone_expr_impl () const override
+ {
+ return clone_expr_without_block_impl ();
+ }
+
+public:
+ // Unique pointer custom clone function
+ std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const
+ {
+ return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ());
+ }
+
+ BlockType get_block_expr_type () const final override
+ {
+ return BlockType::WITHOUT_BLOCK;
+ };
+};
+
+// Base path expression HIR node - abstract
+class PathExpr : public ExprWithoutBlock
+{
+protected:
+ PathExpr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs))
+ {}
+
+public:
+ /* Replaces the outer attributes of this path expression with the given outer
+ * attributes. */
+ void replace_outer_attrs (AST::AttrVec outer_attrs)
+ {
+ set_outer_attrs (std::move (outer_attrs));
+ }
+
+ ExprType get_expression_type () const final override
+ {
+ return ExprType::Path;
+ }
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc b/gcc/rust/hir/tree/rust-hir-expr.cc
new file mode 100644
index 0000000..266c79c
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-expr.cc
@@ -0,0 +1,1490 @@
+// Copyright (C) 2020-2024 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-hir-expr.h"
+#include "rust-operators.h"
+#include "rust-hir-stmt.h"
+
+namespace Rust {
+namespace HIR {
+
+Expr::Expr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs)
+ : outer_attrs (std::move (outer_attribs)), mappings (std::move (mappings))
+{}
+
+ExprWithoutBlock::ExprWithoutBlock (Analysis::NodeMapping mappings,
+ AST::AttrVec outer_attribs)
+ : Expr (std::move (mappings), std::move (outer_attribs))
+{}
+
+LoopLabel::LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label,
+ location_t locus)
+ : label (std::move (loop_label)), locus (locus), mappings (mapping)
+{}
+
+ExprWithBlock::ExprWithBlock (Analysis::NodeMapping mappings,
+ AST::AttrVec outer_attrs)
+ : Expr (std::move (mappings), std::move (outer_attrs))
+{}
+
+LiteralExpr::LiteralExpr (Analysis::NodeMapping mappings,
+ std::string value_as_string, Literal::LitType type,
+ PrimitiveCoreType type_hint, location_t locus,
+ AST::AttrVec outer_attrs)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
+ literal (std::move (value_as_string), type, type_hint), locus (locus)
+{}
+
+LiteralExpr::LiteralExpr (Analysis::NodeMapping mappings, Literal literal,
+ location_t locus, AST::AttrVec outer_attrs)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
+ literal (std::move (literal)), locus (locus)
+{}
+
+OperatorExpr::OperatorExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> main_or_left_expr,
+ AST::AttrVec outer_attribs, location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ locus (locus), main_or_left_expr (std::move (main_or_left_expr))
+{}
+
+OperatorExpr::OperatorExpr (OperatorExpr const &other)
+ : ExprWithoutBlock (other), locus (other.locus),
+ main_or_left_expr (other.main_or_left_expr->clone_expr ())
+{}
+
+OperatorExpr &
+OperatorExpr::operator= (OperatorExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ main_or_left_expr = other.main_or_left_expr->clone_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+BorrowExpr::BorrowExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> borrow_lvalue, Mutability mut,
+ bool raw, AST::AttrVec outer_attribs, location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (borrow_lvalue),
+ std::move (outer_attribs), locus),
+ mut (mut), raw (raw)
+{}
+
+DereferenceExpr::DereferenceExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> deref_lvalue,
+ AST::AttrVec outer_attribs, location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (deref_lvalue),
+ std::move (outer_attribs), locus)
+{}
+
+ErrorPropagationExpr::ErrorPropagationExpr (
+ Analysis::NodeMapping mappings, std::unique_ptr<Expr> potential_error_value,
+ AST::AttrVec outer_attribs, location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (potential_error_value),
+ std::move (outer_attribs), locus)
+{}
+
+NegationExpr::NegationExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> negated_value,
+ ExprType expr_kind, AST::AttrVec outer_attribs,
+ location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (negated_value),
+ std::move (outer_attribs), locus),
+ expr_type (expr_kind)
+{}
+
+ArithmeticOrLogicalExpr::ArithmeticOrLogicalExpr (
+ Analysis::NodeMapping mappings, std::unique_ptr<Expr> left_value,
+ std::unique_ptr<Expr> right_value, ExprType expr_kind, location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (left_value), AST::AttrVec (),
+ locus),
+ expr_type (expr_kind), right_expr (std::move (right_value))
+{}
+
+ArithmeticOrLogicalExpr::ArithmeticOrLogicalExpr (
+ ArithmeticOrLogicalExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+{}
+
+ArithmeticOrLogicalExpr &
+ArithmeticOrLogicalExpr::operator= (ArithmeticOrLogicalExpr const &other)
+{
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+
+ return *this;
+}
+
+ComparisonExpr::ComparisonExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> left_value,
+ std::unique_ptr<Expr> right_value,
+ ExprType comparison_kind, location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (left_value), AST::AttrVec (),
+ locus),
+ expr_type (comparison_kind), right_expr (std::move (right_value))
+{}
+
+ComparisonExpr::ComparisonExpr (ComparisonExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+{}
+
+ComparisonExpr &
+ComparisonExpr::operator= (ComparisonExpr const &other)
+{
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+LazyBooleanExpr::LazyBooleanExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> left_bool_expr,
+ std::unique_ptr<Expr> right_bool_expr,
+ ExprType expr_kind, location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (left_bool_expr),
+ AST::AttrVec (), locus),
+ expr_type (expr_kind), right_expr (std::move (right_bool_expr))
+{}
+
+LazyBooleanExpr::LazyBooleanExpr (LazyBooleanExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+{}
+
+LazyBooleanExpr &
+LazyBooleanExpr::operator= (LazyBooleanExpr const &other)
+{
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+
+ return *this;
+}
+
+TypeCastExpr::TypeCastExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> expr_to_cast,
+ std::unique_ptr<Type> type_to_cast_to,
+ location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (expr_to_cast),
+ AST::AttrVec (), locus),
+ type_to_convert_to (std::move (type_to_cast_to))
+{}
+
+TypeCastExpr::TypeCastExpr (TypeCastExpr const &other)
+ : OperatorExpr (other),
+ type_to_convert_to (other.type_to_convert_to->clone_type ())
+{}
+
+TypeCastExpr &
+TypeCastExpr::operator= (TypeCastExpr const &other)
+{
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ type_to_convert_to = other.type_to_convert_to->clone_type ();
+
+ return *this;
+}
+
+AssignmentExpr::AssignmentExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> value_to_assign_to,
+ std::unique_ptr<Expr> value_to_assign,
+ location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
+ AST::AttrVec (), locus),
+ right_expr (std::move (value_to_assign))
+{}
+
+AssignmentExpr::AssignmentExpr (AssignmentExpr const &other)
+ : OperatorExpr (other), right_expr (other.right_expr->clone_expr ())
+{}
+
+AssignmentExpr &
+AssignmentExpr::operator= (AssignmentExpr const &other)
+{
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+CompoundAssignmentExpr::CompoundAssignmentExpr (
+ Analysis::NodeMapping mappings, std::unique_ptr<Expr> value_to_assign_to,
+ std::unique_ptr<Expr> value_to_assign, ExprType expr_kind, location_t locus)
+ : OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
+ AST::AttrVec (), locus),
+ expr_type (expr_kind), right_expr (std::move (value_to_assign))
+{}
+
+CompoundAssignmentExpr::CompoundAssignmentExpr (
+ CompoundAssignmentExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+{}
+
+CompoundAssignmentExpr &
+CompoundAssignmentExpr::operator= (CompoundAssignmentExpr const &other)
+{
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+GroupedExpr::GroupedExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> parenthesised_expr,
+ AST::AttrVec inner_attribs,
+ AST::AttrVec outer_attribs, location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ WithInnerAttrs (std::move (inner_attribs)),
+ expr_in_parens (std::move (parenthesised_expr)), locus (locus)
+{}
+
+GroupedExpr::GroupedExpr (GroupedExpr const &other)
+ : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs),
+ expr_in_parens (other.expr_in_parens->clone_expr ()), locus (other.locus)
+{}
+
+GroupedExpr &
+GroupedExpr::operator= (GroupedExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ inner_attrs = other.inner_attrs;
+ expr_in_parens = other.expr_in_parens->clone_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+ArrayElemsValues::ArrayElemsValues (Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<Expr>> elems)
+ : ArrayElems (mappings), values (std::move (elems))
+{}
+
+ArrayElemsValues::ArrayElemsValues (ArrayElemsValues const &other)
+ : ArrayElems (other)
+{
+ values.reserve (other.values.size ());
+ for (const auto &e : other.values)
+ values.push_back (e->clone_expr ());
+}
+
+ArrayElemsValues &
+ArrayElemsValues::operator= (ArrayElemsValues const &other)
+{
+ values.reserve (other.values.size ());
+ for (const auto &e : other.values)
+ values.push_back (e->clone_expr ());
+
+ return *this;
+}
+
+ArrayElemsCopied::ArrayElemsCopied (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> copied_elem,
+ std::unique_ptr<Expr> copy_amount)
+ : ArrayElems (mappings), elem_to_copy (std::move (copied_elem)),
+ num_copies (std::move (copy_amount))
+{}
+
+ArrayElemsCopied::ArrayElemsCopied (ArrayElemsCopied const &other)
+ : ArrayElems (other), elem_to_copy (other.elem_to_copy->clone_expr ()),
+ num_copies (other.num_copies->clone_expr ())
+{}
+
+ArrayElemsCopied &
+ArrayElemsCopied::operator= (ArrayElemsCopied const &other)
+{
+ elem_to_copy = other.elem_to_copy->clone_expr ();
+ num_copies = other.num_copies->clone_expr ();
+
+ return *this;
+}
+
+ArrayExpr::ArrayExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<ArrayElems> array_elems,
+ AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
+ location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ WithInnerAttrs (std::move (inner_attribs)),
+ internal_elements (std::move (array_elems)), locus (locus)
+{}
+
+ArrayExpr::ArrayExpr (ArrayExpr const &other)
+ : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs),
+ locus (other.locus)
+{
+ if (other.has_array_elems ())
+ internal_elements = other.internal_elements->clone_array_elems ();
+}
+
+ArrayExpr &
+ArrayExpr::operator= (ArrayExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ inner_attrs = other.inner_attrs;
+ if (other.has_array_elems ())
+ internal_elements = other.internal_elements->clone_array_elems ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+ArrayIndexExpr::ArrayIndexExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> array_expr,
+ std::unique_ptr<Expr> array_index_expr,
+ AST::AttrVec outer_attribs, location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ array_expr (std::move (array_expr)),
+ index_expr (std::move (array_index_expr)), locus (locus)
+{}
+
+ArrayIndexExpr::ArrayIndexExpr (ArrayIndexExpr const &other)
+ : ExprWithoutBlock (other), array_expr (other.array_expr->clone_expr ()),
+ index_expr (other.index_expr->clone_expr ()), locus (other.locus)
+{}
+
+ArrayIndexExpr &
+ArrayIndexExpr::operator= (ArrayIndexExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ array_expr = other.array_expr->clone_expr ();
+ index_expr = other.index_expr->clone_expr ();
+ // outer_attrs = other.outer_attrs;
+ locus = other.locus;
+
+ return *this;
+}
+
+TupleExpr::TupleExpr (Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<Expr>> tuple_elements,
+ AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
+ location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ WithInnerAttrs (std::move (inner_attribs)),
+ tuple_elems (std::move (tuple_elements)), locus (locus)
+{}
+
+TupleExpr::TupleExpr (TupleExpr const &other)
+ : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs),
+ locus (other.locus)
+{
+ tuple_elems.reserve (other.tuple_elems.size ());
+ for (const auto &e : other.tuple_elems)
+ tuple_elems.push_back (e->clone_expr ());
+}
+
+TupleExpr &
+TupleExpr::operator= (TupleExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ inner_attrs = other.inner_attrs;
+ locus = other.locus;
+
+ tuple_elems.reserve (other.tuple_elems.size ());
+ for (const auto &e : other.tuple_elems)
+ tuple_elems.push_back (e->clone_expr ());
+
+ return *this;
+}
+
+TupleIndexExpr::TupleIndexExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> tuple_expr,
+ TupleIndex index, AST::AttrVec outer_attribs,
+ location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus)
+{}
+
+TupleIndexExpr::TupleIndexExpr (TupleIndexExpr const &other)
+ : ExprWithoutBlock (other), tuple_expr (other.tuple_expr->clone_expr ()),
+ tuple_index (other.tuple_index), locus (other.locus)
+{}
+
+TupleIndexExpr &
+TupleIndexExpr::operator= (TupleIndexExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ tuple_expr = other.tuple_expr->clone_expr ();
+ tuple_index = other.tuple_index;
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+StructExpr::StructExpr (Analysis::NodeMapping mappings,
+ PathInExpression struct_path,
+ AST::AttrVec outer_attribs)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ struct_name (std::move (struct_path))
+{}
+
+StructExprStruct::StructExprStruct (Analysis::NodeMapping mappings,
+ PathInExpression struct_path,
+ AST::AttrVec inner_attribs,
+ AST::AttrVec outer_attribs,
+ location_t locus)
+ : StructExpr (std::move (mappings), std::move (struct_path),
+ std::move (outer_attribs)),
+ WithInnerAttrs (std::move (inner_attribs)), locus (locus)
+{}
+
+StructBase::StructBase (std::unique_ptr<Expr> base_struct_ptr)
+ : base_struct (std::move (base_struct_ptr))
+{}
+
+StructBase::StructBase (StructBase const &other)
+{
+ /* HACK: gets around base_struct pointer being null (e.g. if no struct base
+ * exists) */
+ if (other.base_struct != nullptr)
+ other.base_struct->clone_expr ();
+}
+
+StructBase &
+StructBase::operator= (StructBase const &other)
+{
+ base_struct = other.base_struct->clone_expr ();
+
+ return *this;
+}
+
+StructExprField::StructExprField (Analysis::NodeMapping mapping,
+ location_t locus)
+ : mappings (mapping), locus (locus)
+{}
+
+StructExprFieldIdentifier::StructExprFieldIdentifier (
+ Analysis::NodeMapping mapping, Identifier field_identifier, location_t locus)
+ : StructExprField (mapping, locus), field_name (std::move (field_identifier))
+{}
+
+StructExprFieldWithVal::StructExprFieldWithVal (
+ Analysis::NodeMapping mapping, std::unique_ptr<Expr> field_value,
+ location_t locus)
+ : StructExprField (mapping, locus), value (std::move (field_value))
+{}
+
+StructExprFieldWithVal::StructExprFieldWithVal (
+ StructExprFieldWithVal const &other)
+ : StructExprField (other.mappings, other.locus),
+ value (other.value->clone_expr ())
+{}
+
+StructExprFieldWithVal &
+StructExprFieldWithVal::operator= (StructExprFieldWithVal const &other)
+{
+ value = other.value->clone_expr ();
+ mappings = other.mappings;
+ locus = other.locus;
+
+ return *this;
+}
+
+StructExprFieldIdentifierValue::StructExprFieldIdentifierValue (
+ Analysis::NodeMapping mapping, Identifier field_identifier,
+ std::unique_ptr<Expr> field_value, location_t locus)
+ : StructExprFieldWithVal (mapping, std::move (field_value), locus),
+ field_name (std::move (field_identifier))
+{}
+
+StructExprFieldIndexValue::StructExprFieldIndexValue (
+ Analysis::NodeMapping mapping, TupleIndex tuple_index,
+ std::unique_ptr<Expr> field_value, location_t locus)
+ : StructExprFieldWithVal (mapping, std::move (field_value), locus),
+ index (tuple_index)
+{}
+
+StructExprStructFields::StructExprStructFields (
+ Analysis::NodeMapping mappings, PathInExpression struct_path,
+ std::vector<std::unique_ptr<StructExprField>> expr_fields, location_t locus,
+ tl::optional<std::unique_ptr<StructBase>> base_struct,
+ AST::AttrVec inner_attribs = AST::AttrVec (),
+ AST::AttrVec outer_attribs = AST::AttrVec ())
+ : StructExprStruct (std::move (mappings), std::move (struct_path),
+ std::move (inner_attribs), std::move (outer_attribs),
+ locus),
+ fields (std::move (expr_fields)), struct_base (std::move (base_struct))
+{}
+
+StructExprStructFields::StructExprStructFields (
+ StructExprStructFields const &other)
+ : StructExprStruct (other),
+ struct_base (other.has_struct_base ()
+ ? tl::optional<std::unique_ptr<StructBase>> (
+ std::make_unique<StructBase> (*other.struct_base.value ()))
+ : tl::nullopt),
+ union_index (other.union_index)
+{
+ fields.reserve (other.fields.size ());
+ for (const auto &e : other.fields)
+ fields.push_back (e->clone_struct_expr_field ());
+}
+
+StructExprStructFields &
+StructExprStructFields::operator= (StructExprStructFields const &other)
+{
+ StructExprStruct::operator= (other);
+ struct_base = other.has_struct_base ()
+ ? tl::optional<std::unique_ptr<StructBase>> (
+ std::make_unique<StructBase> (*other.struct_base.value ()))
+ : tl::nullopt;
+ union_index = other.union_index;
+
+ fields.reserve (other.fields.size ());
+ for (const auto &e : other.fields)
+ fields.push_back (e->clone_struct_expr_field ());
+
+ return *this;
+}
+
+StructExprStructBase::StructExprStructBase (Analysis::NodeMapping mappings,
+ PathInExpression struct_path,
+ StructBase base_struct,
+ AST::AttrVec inner_attribs,
+ AST::AttrVec outer_attribs,
+ location_t locus)
+ : StructExprStruct (std::move (mappings), std::move (struct_path),
+ std::move (inner_attribs), std::move (outer_attribs),
+ locus),
+ struct_base (std::move (base_struct))
+{}
+
+CallExpr::CallExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> function_expr,
+ std::vector<std::unique_ptr<Expr>> function_params,
+ AST::AttrVec outer_attribs, location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ function (std::move (function_expr)), params (std::move (function_params)),
+ locus (locus)
+{}
+
+CallExpr::CallExpr (CallExpr const &other)
+ : ExprWithoutBlock (other), function (other.function->clone_expr ()),
+ locus (other.locus)
+/*, params(other.params),*/ {
+ params.reserve (other.params.size ());
+ for (const auto &e : other.params)
+ params.push_back (e->clone_expr ());
+}
+
+CallExpr &
+CallExpr::operator= (CallExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ function = other.function->clone_expr ();
+ locus = other.locus;
+ // params = other.params;
+ // outer_attrs = other.outer_attrs;
+
+ params.reserve (other.params.size ());
+ for (const auto &e : other.params)
+ params.push_back (e->clone_expr ());
+
+ return *this;
+}
+
+MethodCallExpr::MethodCallExpr (
+ Analysis::NodeMapping mappings, std::unique_ptr<Expr> call_receiver,
+ PathExprSegment method_path, std::vector<std::unique_ptr<Expr>> method_params,
+ AST::AttrVec outer_attribs, location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ receiver (std::move (call_receiver)), method_name (std::move (method_path)),
+ params (std::move (method_params)), locus (locus)
+{}
+
+MethodCallExpr::MethodCallExpr (MethodCallExpr const &other)
+ : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
+ method_name (other.method_name), locus (other.locus)
+/*, params(other.params),*/ {
+ params.reserve (other.params.size ());
+ for (const auto &e : other.params)
+ params.push_back (e->clone_expr ());
+}
+
+MethodCallExpr &
+MethodCallExpr::operator= (MethodCallExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ receiver = other.receiver->clone_expr ();
+ method_name = other.method_name;
+ locus = other.locus;
+ // params = other.params;
+ // outer_attrs = other.outer_attrs;
+
+ params.reserve (other.params.size ());
+ for (const auto &e : other.params)
+ params.push_back (e->clone_expr ());
+
+ return *this;
+}
+
+FieldAccessExpr::FieldAccessExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> field_access_receiver,
+ Identifier field_name,
+ AST::AttrVec outer_attribs, location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ receiver (std::move (field_access_receiver)),
+ field (std::move (field_name)), locus (locus)
+{}
+
+FieldAccessExpr::FieldAccessExpr (FieldAccessExpr const &other)
+ : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
+ field (other.field), locus (other.locus)
+{}
+
+FieldAccessExpr &
+FieldAccessExpr::operator= (FieldAccessExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ receiver = other.receiver->clone_expr ();
+ field = other.field;
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+ClosureParam::ClosureParam (std::unique_ptr<Pattern> param_pattern,
+ location_t locus, std::unique_ptr<Type> param_type,
+ std::vector<AST::Attribute> outer_attrs)
+ : outer_attrs (std::move (outer_attrs)), pattern (std::move (param_pattern)),
+ type (std::move (param_type)), locus (locus)
+{}
+
+ClosureParam::ClosureParam (ClosureParam const &other)
+ : pattern (other.pattern->clone_pattern ())
+{
+ // guard to protect from null pointer dereference
+ if (other.pattern != nullptr)
+ pattern = other.pattern->clone_pattern ();
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+}
+
+ClosureParam &
+ClosureParam::operator= (ClosureParam const &other)
+{
+ outer_attrs = other.outer_attrs;
+
+ // guard to protect from null pointer dereference
+ if (other.pattern != nullptr)
+ pattern = other.pattern->clone_pattern ();
+ else
+ pattern = nullptr;
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ else
+ type = nullptr;
+
+ return *this;
+}
+
+ClosureExpr::ClosureExpr (Analysis::NodeMapping mappings,
+ std::vector<ClosureParam> closure_params,
+ std::unique_ptr<Type> closure_return_type,
+ std::unique_ptr<Expr> closure_expr, bool has_move,
+ AST::AttrVec outer_attribs, location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ has_move (has_move), params (std::move (closure_params)), locus (locus),
+ return_type (std::move (closure_return_type)),
+ expr (std::move (closure_expr))
+{}
+
+ClosureExpr::ClosureExpr (ClosureExpr const &other)
+ : ExprWithoutBlock (other.get_mappings (), other.get_outer_attrs ())
+{
+ return_type
+ = other.has_return_type () ? other.return_type->clone_type () : nullptr;
+ expr = other.expr->clone_expr ();
+ params = other.params;
+ has_move = other.has_move;
+}
+
+ClosureExpr &
+ClosureExpr::operator= (ClosureExpr const &other)
+{
+ mappings = other.mappings;
+ return_type
+ = other.has_return_type () ? other.return_type->clone_type () : nullptr;
+ expr = other.expr->clone_expr ();
+ params = other.params;
+ has_move = other.has_move;
+
+ return *this;
+}
+
+BlockExpr::BlockExpr (Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<Stmt>> block_statements,
+ std::unique_ptr<Expr> block_expr, bool tail_reachable,
+ AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
+ tl::optional<LoopLabel> label, location_t start_locus,
+ location_t end_locus)
+ : ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
+ WithInnerAttrs (std::move (inner_attribs)),
+ statements (std::move (block_statements)), expr (std::move (block_expr)),
+ tail_reachable (tail_reachable), label (std::move (label)),
+ start_locus (start_locus), end_locus (end_locus)
+{}
+
+BlockExpr::BlockExpr (BlockExpr const &other)
+ : ExprWithBlock (other), /*statements(other.statements),*/
+ WithInnerAttrs (other.inner_attrs), label (other.label),
+ start_locus (other.start_locus), end_locus (other.end_locus)
+{
+ // guard to protect from null pointer dereference
+ if (other.expr != nullptr)
+ expr = other.expr->clone_expr ();
+
+ statements.reserve (other.statements.size ());
+ for (const auto &e : other.statements)
+ statements.push_back (e->clone_stmt ());
+}
+
+BlockExpr &
+BlockExpr::operator= (BlockExpr const &other)
+{
+ ExprWithBlock::operator= (other);
+ // statements = other.statements;
+ expr = other.expr->clone_expr ();
+ inner_attrs = other.inner_attrs;
+ start_locus = other.end_locus;
+ end_locus = other.end_locus;
+ // outer_attrs = other.outer_attrs;
+
+ statements.reserve (other.statements.size ());
+ for (const auto &e : other.statements)
+ statements.push_back (e->clone_stmt ());
+
+ return *this;
+}
+
+ContinueExpr::ContinueExpr (Analysis::NodeMapping mappings, location_t locus,
+ tl::optional<Lifetime> label,
+ AST::AttrVec outer_attribs)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ label (std::move (label)), locus (locus)
+{}
+
+BreakExpr::BreakExpr (Analysis::NodeMapping mappings, location_t locus,
+ tl::optional<Lifetime> break_label,
+ std::unique_ptr<Expr> expr_in_break,
+ AST::AttrVec outer_attribs)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ label (std::move (break_label)), break_expr (std::move (expr_in_break)),
+ locus (locus)
+{}
+
+BreakExpr::BreakExpr (BreakExpr const &other)
+ : ExprWithoutBlock (other), label (other.label), locus (other.locus)
+{
+ // guard to protect from null pointer dereference
+ if (other.break_expr != nullptr)
+ break_expr = other.break_expr->clone_expr ();
+}
+
+BreakExpr &
+BreakExpr::operator= (BreakExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ label = other.label;
+ break_expr = other.break_expr->clone_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+RangeExpr::RangeExpr (Analysis::NodeMapping mappings, location_t locus)
+ : ExprWithoutBlock (std::move (mappings), AST::AttrVec ()), locus (locus)
+{}
+
+RangeFromToExpr::RangeFromToExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> range_from,
+ std::unique_ptr<Expr> range_to,
+ location_t locus)
+ : RangeExpr (std::move (mappings), locus), from (std::move (range_from)),
+ to (std::move (range_to))
+{}
+
+RangeFromToExpr::RangeFromToExpr (RangeFromToExpr const &other)
+ : RangeExpr (other), from (other.from->clone_expr ()),
+ to (other.to->clone_expr ())
+{}
+
+RangeFromToExpr &
+RangeFromToExpr::operator= (RangeFromToExpr const &other)
+{
+ RangeExpr::operator= (other);
+ from = other.from->clone_expr ();
+ to = other.to->clone_expr ();
+
+ return *this;
+}
+
+RangeFromExpr::RangeFromExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> range_from,
+ location_t locus)
+ : RangeExpr (std::move (mappings), locus), from (std::move (range_from))
+{}
+
+RangeFromExpr::RangeFromExpr (RangeFromExpr const &other)
+ : RangeExpr (other), from (other.from->clone_expr ())
+{}
+
+RangeFromExpr &
+RangeFromExpr::operator= (RangeFromExpr const &other)
+{
+ RangeExpr::operator= (other);
+ from = other.from->clone_expr ();
+
+ return *this;
+}
+
+RangeToExpr::RangeToExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> range_to, location_t locus)
+ : RangeExpr (std::move (mappings), locus), to (std::move (range_to))
+{}
+
+RangeToExpr::RangeToExpr (RangeToExpr const &other)
+ : RangeExpr (other), to (other.to->clone_expr ())
+{}
+
+RangeToExpr &
+RangeToExpr::operator= (RangeToExpr const &other)
+{
+ RangeExpr::operator= (other);
+ to = other.to->clone_expr ();
+
+ return *this;
+}
+
+RangeFullExpr::RangeFullExpr (Analysis::NodeMapping mappings, location_t locus)
+ : RangeExpr (std::move (mappings), locus)
+{}
+
+RangeFromToInclExpr::RangeFromToInclExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> range_from,
+ std::unique_ptr<Expr> range_to,
+ location_t locus)
+ : RangeExpr (std::move (mappings), locus), from (std::move (range_from)),
+ to (std::move (range_to))
+{}
+
+RangeFromToInclExpr::RangeFromToInclExpr (RangeFromToInclExpr const &other)
+ : RangeExpr (other), from (other.from->clone_expr ()),
+ to (other.to->clone_expr ())
+{}
+
+RangeFromToInclExpr &
+RangeFromToInclExpr::operator= (RangeFromToInclExpr const &other)
+{
+ RangeExpr::operator= (other);
+ from = other.from->clone_expr ();
+ to = other.to->clone_expr ();
+
+ return *this;
+}
+
+RangeToInclExpr::RangeToInclExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> range_to,
+ location_t locus)
+ : RangeExpr (std::move (mappings), locus), to (std::move (range_to))
+{}
+
+RangeToInclExpr::RangeToInclExpr (RangeToInclExpr const &other)
+ : RangeExpr (other), to (other.to->clone_expr ())
+{}
+
+RangeToInclExpr &
+RangeToInclExpr::operator= (RangeToInclExpr const &other)
+{
+ RangeExpr::operator= (other);
+ to = other.to->clone_expr ();
+
+ return *this;
+}
+
+ReturnExpr::ReturnExpr (Analysis::NodeMapping mappings, location_t locus,
+ std::unique_ptr<Expr> returned_expr,
+ AST::AttrVec outer_attribs)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ return_expr (std::move (returned_expr)), locus (locus)
+{}
+
+ReturnExpr::ReturnExpr (ReturnExpr const &other)
+ : ExprWithoutBlock (other), locus (other.locus)
+{
+ // guard to protect from null pointer dereference
+ if (other.return_expr != nullptr)
+ return_expr = other.return_expr->clone_expr ();
+}
+
+ReturnExpr &
+ReturnExpr::operator= (ReturnExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ return_expr = other.return_expr->clone_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+UnsafeBlockExpr::UnsafeBlockExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<BlockExpr> block_expr,
+ AST::AttrVec outer_attribs, location_t locus)
+ : ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
+ expr (std::move (block_expr)), locus (locus)
+{}
+
+UnsafeBlockExpr::UnsafeBlockExpr (UnsafeBlockExpr const &other)
+ : ExprWithBlock (other), expr (other.expr->clone_block_expr ()),
+ locus (other.locus)
+{}
+
+UnsafeBlockExpr &
+UnsafeBlockExpr::operator= (UnsafeBlockExpr const &other)
+{
+ ExprWithBlock::operator= (other);
+ expr = other.expr->clone_block_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+BaseLoopExpr::BaseLoopExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<BlockExpr> loop_block,
+ location_t locus,
+ tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs)
+ : ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
+ loop_label (std::move (loop_label)), loop_block (std::move (loop_block)),
+ locus (locus)
+{}
+
+BaseLoopExpr::BaseLoopExpr (BaseLoopExpr const &other)
+ : ExprWithBlock (other), loop_label (other.loop_label),
+ loop_block (other.loop_block->clone_block_expr ()), locus (other.locus)
+{}
+
+BaseLoopExpr &
+BaseLoopExpr::operator= (BaseLoopExpr const &other)
+{
+ ExprWithBlock::operator= (other);
+ loop_block = other.loop_block->clone_block_expr ();
+ loop_label = other.loop_label;
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+LoopExpr::LoopExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<BlockExpr> loop_block, location_t locus,
+ tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs)
+ : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
+ std::move (loop_label), std::move (outer_attribs))
+{}
+
+WhileLoopExpr::WhileLoopExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> loop_condition,
+ std::unique_ptr<BlockExpr> loop_block,
+ location_t locus,
+ tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs)
+ : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
+ std::move (loop_label), std::move (outer_attribs)),
+ condition (std::move (loop_condition))
+{}
+
+WhileLoopExpr::WhileLoopExpr (WhileLoopExpr const &other)
+ : BaseLoopExpr (other), condition (other.condition->clone_expr ())
+{}
+
+WhileLoopExpr &
+WhileLoopExpr::operator= (WhileLoopExpr const &other)
+{
+ BaseLoopExpr::operator= (other);
+ condition = other.condition->clone_expr ();
+ // loop_block = other.loop_block->clone_block_expr();
+ // loop_label = other.loop_label;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+WhileLetLoopExpr::WhileLetLoopExpr (
+ Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
+ std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> loop_block,
+ location_t locus, tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs)
+ : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
+ std::move (loop_label), std::move (outer_attribs)),
+ match_arm_patterns (std::move (match_arm_patterns)),
+ condition (std::move (condition))
+{}
+
+WhileLetLoopExpr::WhileLetLoopExpr (WhileLetLoopExpr const &other)
+ : BaseLoopExpr (other),
+ /*match_arm_patterns(other.match_arm_patterns),*/ condition (
+ other.condition->clone_expr ())
+{
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+ for (const auto &e : other.match_arm_patterns)
+ match_arm_patterns.push_back (e->clone_pattern ());
+}
+
+WhileLetLoopExpr &
+WhileLetLoopExpr::operator= (WhileLetLoopExpr const &other)
+{
+ BaseLoopExpr::operator= (other);
+ // match_arm_patterns = other.match_arm_patterns;
+ condition = other.condition->clone_expr ();
+ // loop_block = other.loop_block->clone_block_expr();
+ // loop_label = other.loop_label;
+ // outer_attrs = other.outer_attrs;
+
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+ for (const auto &e : other.match_arm_patterns)
+ match_arm_patterns.push_back (e->clone_pattern ());
+
+ return *this;
+}
+
+IfExpr::IfExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> condition,
+ std::unique_ptr<BlockExpr> if_block, location_t locus)
+ : ExprWithBlock (std::move (mappings), AST::AttrVec ()),
+ condition (std::move (condition)), if_block (std::move (if_block)),
+ locus (locus)
+{}
+
+IfExpr::IfExpr (IfExpr const &other)
+ : ExprWithBlock (other), condition (other.condition->clone_expr ()),
+ if_block (other.if_block->clone_block_expr ()), locus (other.locus)
+{}
+
+IfExpr &
+IfExpr::operator= (IfExpr const &other)
+{
+ ExprWithBlock::operator= (other);
+ condition = other.condition->clone_expr ();
+ if_block = other.if_block->clone_block_expr ();
+ locus = other.locus;
+
+ return *this;
+}
+
+IfExprConseqElse::IfExprConseqElse (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> condition,
+ std::unique_ptr<BlockExpr> if_block,
+ std::unique_ptr<ExprWithBlock> else_block,
+ location_t locus)
+ : IfExpr (std::move (mappings), std::move (condition), std::move (if_block),
+ locus),
+ else_block (std::move (else_block))
+{}
+
+IfExprConseqElse::IfExprConseqElse (IfExprConseqElse const &other)
+ : IfExpr (other), else_block (other.else_block->clone_expr_with_block ())
+{}
+
+IfExprConseqElse &
+IfExprConseqElse::operator= (IfExprConseqElse const &other)
+{
+ IfExpr::operator= (other);
+ // condition = other.condition->clone_expr();
+ // if_block = other.if_block->clone_block_expr();
+ else_block = other.else_block->clone_expr_with_block ();
+
+ return *this;
+}
+
+MatchArm::MatchArm (std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
+ location_t locus, std::unique_ptr<Expr> guard_expr,
+ AST::AttrVec outer_attrs)
+ : outer_attrs (std::move (outer_attrs)),
+ match_arm_patterns (std::move (match_arm_patterns)),
+ guard_expr (std::move (guard_expr)), locus (locus)
+{}
+
+MatchArm::MatchArm (MatchArm const &other) : outer_attrs (other.outer_attrs)
+{
+ // guard to protect from null pointer dereference
+ if (other.guard_expr != nullptr)
+ guard_expr = other.guard_expr->clone_expr ();
+
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+ for (const auto &e : other.match_arm_patterns)
+ match_arm_patterns.push_back (e->clone_pattern ());
+
+ locus = other.locus;
+}
+
+MatchArm &
+MatchArm::operator= (MatchArm const &other)
+{
+ outer_attrs = other.outer_attrs;
+
+ if (other.guard_expr != nullptr)
+ guard_expr = other.guard_expr->clone_expr ();
+
+ match_arm_patterns.clear ();
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+ for (const auto &e : other.match_arm_patterns)
+ match_arm_patterns.push_back (e->clone_pattern ());
+
+ return *this;
+}
+
+MatchCase::MatchCase (Analysis::NodeMapping mappings, MatchArm arm,
+ std::unique_ptr<Expr> expr)
+ : mappings (mappings), arm (std::move (arm)), expr (std::move (expr))
+{}
+
+MatchCase::MatchCase (const MatchCase &other)
+ : mappings (other.mappings), arm (other.arm), expr (other.expr->clone_expr ())
+{}
+
+MatchCase &
+MatchCase::operator= (const MatchCase &other)
+{
+ mappings = other.mappings;
+ arm = other.arm;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+}
+
+MatchExpr::MatchExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> branch_value,
+ std::vector<MatchCase> match_arms,
+ AST::AttrVec inner_attrs, AST::AttrVec outer_attrs,
+ location_t locus)
+ : ExprWithBlock (std::move (mappings), std::move (outer_attrs)),
+ WithInnerAttrs (std::move (inner_attrs)),
+ branch_value (std::move (branch_value)),
+ match_arms (std::move (match_arms)), locus (locus)
+{}
+
+MatchExpr::MatchExpr (MatchExpr const &other)
+ : ExprWithBlock (other), WithInnerAttrs (other.inner_attrs),
+ branch_value (other.branch_value->clone_expr ()),
+ match_arms (other.match_arms), locus (other.locus)
+{
+ /*match_arms.reserve (other.match_arms.size ());
+ for (const auto &e : other.match_arms)
+ match_arms.push_back (e->clone_match_case ());*/
+}
+
+MatchExpr &
+MatchExpr::operator= (MatchExpr const &other)
+{
+ ExprWithBlock::operator= (other);
+ branch_value = other.branch_value->clone_expr ();
+ inner_attrs = other.inner_attrs;
+ match_arms = other.match_arms;
+ // outer_attrs = other.outer_attrs;
+ locus = other.locus;
+
+ /*match_arms.reserve (other.match_arms.size ());
+ for (const auto &e : other.match_arms)
+ match_arms.push_back (e->clone_match_case ());*/
+
+ return *this;
+}
+
+AwaitExpr::AwaitExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> awaited_expr,
+ AST::AttrVec outer_attrs, location_t locus)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
+ awaited_expr (std::move (awaited_expr)), locus (locus)
+{}
+
+AwaitExpr::AwaitExpr (AwaitExpr const &other)
+ : ExprWithoutBlock (other), awaited_expr (other.awaited_expr->clone_expr ()),
+ locus (other.locus)
+{}
+
+AwaitExpr &
+AwaitExpr::operator= (AwaitExpr const &other)
+{
+ ExprWithoutBlock::operator= (other);
+ awaited_expr = other.awaited_expr->clone_expr ();
+ locus = other.locus;
+
+ return *this;
+}
+
+AsyncBlockExpr::AsyncBlockExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<BlockExpr> block_expr,
+ bool has_move, AST::AttrVec outer_attrs,
+ location_t locus)
+ : ExprWithBlock (std::move (mappings), std::move (outer_attrs)),
+ has_move (has_move), block_expr (std::move (block_expr)), locus (locus)
+{}
+
+AsyncBlockExpr::AsyncBlockExpr (AsyncBlockExpr const &other)
+ : ExprWithBlock (other), has_move (other.has_move),
+ block_expr (other.block_expr->clone_block_expr ()), locus (other.locus)
+{}
+
+AsyncBlockExpr &
+AsyncBlockExpr::operator= (AsyncBlockExpr const &other)
+{
+ ExprWithBlock::operator= (other);
+ has_move = other.has_move;
+ block_expr = other.block_expr->clone_block_expr ();
+ locus = other.locus;
+
+ return *this;
+}
+
+OperatorExprMeta::OperatorExprMeta (HIR::CompoundAssignmentExpr &expr)
+ : node_mappings (expr.get_mappings ()),
+ lvalue_mappings (expr.get_expr ().get_mappings ()),
+ locus (expr.get_locus ())
+{}
+
+OperatorExprMeta::OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr)
+ : node_mappings (expr.get_mappings ()),
+ lvalue_mappings (expr.get_expr ().get_mappings ()),
+ locus (expr.get_locus ())
+{}
+
+OperatorExprMeta::OperatorExprMeta (HIR::NegationExpr &expr)
+ : node_mappings (expr.get_mappings ()),
+ lvalue_mappings (expr.get_expr ().get_mappings ()),
+ locus (expr.get_locus ())
+{}
+
+OperatorExprMeta::OperatorExprMeta (HIR::DereferenceExpr &expr)
+ : node_mappings (expr.get_mappings ()),
+ lvalue_mappings (expr.get_expr ().get_mappings ()),
+ locus (expr.get_locus ())
+{}
+
+OperatorExprMeta::OperatorExprMeta (HIR::ArrayIndexExpr &expr)
+ : node_mappings (expr.get_mappings ()),
+ lvalue_mappings (expr.get_array_expr ().get_mappings ()),
+ locus (expr.get_locus ())
+{}
+
+OperatorExprMeta::OperatorExprMeta (HIR::ComparisonExpr &expr)
+ : node_mappings (expr.get_mappings ()),
+ lvalue_mappings (expr.get_expr ().get_mappings ()),
+ 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)
+ : reg (reg), expr (std::move (expr))
+{
+ rust_assert (this->expr != nullptr);
+}
+
+InlineAsmOperand::In::In (const struct In &other)
+{
+ reg = other.reg;
+
+ expr = other.expr->clone_expr ();
+}
+
+InlineAsmOperand::In
+InlineAsmOperand::In::operator= (const struct In &other)
+{
+ reg = other.reg;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+}
+
+InlineAsmOperand::Out::Out (
+ tl::optional<struct AST::InlineAsmRegOrRegClass> &reg, bool late,
+ std::unique_ptr<Expr> expr)
+ : reg (reg), late (late), expr (std::move (expr))
+{
+ rust_assert (this->expr != nullptr);
+}
+
+InlineAsmOperand::Out::Out (const struct Out &other)
+{
+ reg = other.reg;
+ late = other.late;
+ expr = other.expr->clone_expr ();
+}
+
+InlineAsmOperand::Out
+InlineAsmOperand::Out::operator= (const struct Out &other)
+{
+ reg = other.reg;
+ late = other.late;
+ expr = other.expr->clone_expr ();
+ return *this;
+}
+
+InlineAsmOperand::InOut::InOut (
+ tl::optional<struct AST::InlineAsmRegOrRegClass> &reg, bool late,
+ std::unique_ptr<Expr> expr)
+ : reg (reg), late (late), expr (std::move (expr))
+{
+ rust_assert (this->expr != nullptr);
+}
+
+InlineAsmOperand::InOut::InOut (const struct InOut &other)
+{
+ reg = other.reg;
+ late = other.late;
+ expr = other.expr->clone_expr ();
+}
+
+InlineAsmOperand::InOut
+InlineAsmOperand::InOut::operator= (const struct InOut &other)
+{
+ reg = other.reg;
+ late = other.late;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+}
+
+InlineAsmOperand::SplitInOut::SplitInOut (
+ tl::optional<struct AST::InlineAsmRegOrRegClass> &reg, bool late,
+ std::unique_ptr<Expr> in_expr, std::unique_ptr<Expr> out_expr)
+ : reg (reg), late (late), in_expr (std::move (in_expr)),
+ out_expr (std::move (out_expr))
+{
+ rust_assert (this->in_expr != nullptr);
+ rust_assert (this->out_expr != nullptr);
+}
+
+InlineAsmOperand::SplitInOut::SplitInOut (const struct SplitInOut &other)
+{
+ reg = other.reg;
+ late = other.late;
+ in_expr = other.in_expr->clone_expr ();
+ out_expr = other.out_expr->clone_expr ();
+}
+
+InlineAsmOperand::SplitInOut
+InlineAsmOperand::SplitInOut::operator= (const struct SplitInOut &other)
+{
+ reg = other.reg;
+ late = other.late;
+ in_expr = other.in_expr->clone_expr ();
+ out_expr = other.out_expr->clone_expr ();
+
+ return *this;
+}
+
+InlineAsmOperand::Sym::Sym (std::unique_ptr<Expr> expr)
+ : expr (std::move (expr))
+{
+ rust_assert (this->expr != nullptr);
+}
+
+InlineAsmOperand::Sym::Sym (const struct Sym &other)
+{
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+}
+
+InlineAsmOperand::Sym
+InlineAsmOperand::Sym::operator= (const struct Sym &other)
+{
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+ return *this;
+}
+
+InlineAsmOperand::Label::Label (tl::optional<std::string> label_name,
+ std::unique_ptr<Expr> expr)
+ : expr (std::move (expr))
+{
+ rust_assert (this->expr != nullptr);
+ if (label_name.has_value ())
+ this->label_name = label_name.value ();
+}
+
+InlineAsmOperand::Label::Label (const struct Label &other)
+{
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+}
+
+InlineAsmOperand::Label
+InlineAsmOperand::Label::operator= (const struct Label &other)
+{
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+ return *this;
+}
+
+InlineAsm::InlineAsm (location_t locus, bool is_global_asm,
+ std::vector<AST::InlineAsmTemplatePiece> template_,
+ std::vector<AST::TupleTemplateStr> template_strs,
+ std::vector<HIR::InlineAsmOperand> operands,
+ std::vector<AST::TupleClobber> clobber_abi,
+ std::set<AST::InlineAsmOption> options,
+ Analysis::NodeMapping mappings,
+ AST::AttrVec outer_attribs)
+ : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
+ locus (locus), is_global_asm (is_global_asm),
+ template_ (std::move (template_)),
+ template_strs (std::move (template_strs)), operands (std::move (operands)),
+ clobber_abi (std::move (clobber_abi)), options (std::move (options))
+{}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 1ee1066..375f474 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -19,12 +19,13 @@
#ifndef RUST_HIR_EXPR_H
#define RUST_HIR_EXPR_H
+#include "rust-hir-expr-abstract.h"
+#include "rust-hir-literal.h"
#include "rust-common.h"
-#include "rust-ast-full-decls.h"
-#include "rust-hir.h"
-#include "rust-hir-path.h"
-#include "rust-operators.h"
+#include "rust-hir-bound.h"
+#include "rust-hir-attrs.h"
#include "rust-expr.h"
+
namespace Rust {
namespace HIR {
@@ -32,7 +33,7 @@ namespace HIR {
// TODO: inline?
class LoopLabel /*: public Node*/
{
- Lifetime label; // or type LIFETIME_OR_LABEL
+ Lifetime label; // of type LIFETIME_OR_LABEL
location_t locus;
@@ -42,12 +43,7 @@ public:
std::string as_string () const;
LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label,
- location_t locus)
- : label (std::move (loop_label)), locus (locus), mappings (mapping)
- {}
-
- // Returns whether the LoopLabel is in an error state.
- bool is_error () const { return label.is_error (); }
+ location_t locus);
location_t get_locus () const { return locus; }
@@ -62,9 +58,7 @@ class ExprWithBlock : public Expr
// TODO: should this mean that a BlockExpr should be a member variable?
protected:
ExprWithBlock (Analysis::NodeMapping mappings,
- AST::AttrVec outer_attrs = AST::AttrVec ())
- : Expr (std::move (mappings), std::move (outer_attrs))
- {}
+ AST::AttrVec outer_attrs = AST::AttrVec ());
// pure virtual clone implementation
virtual ExprWithBlock *clone_expr_with_block_impl () const = 0;
@@ -106,16 +100,10 @@ public:
LiteralExpr (Analysis::NodeMapping mappings, std::string value_as_string,
Literal::LitType type, PrimitiveCoreType type_hint,
- location_t locus, AST::AttrVec outer_attrs)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
- literal (std::move (value_as_string), type, type_hint), locus (locus)
- {}
+ location_t locus, AST::AttrVec outer_attrs);
LiteralExpr (Analysis::NodeMapping mappings, Literal literal,
- location_t locus, AST::AttrVec outer_attrs)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
- literal (std::move (literal)), locus (locus)
- {}
+ location_t locus, AST::AttrVec outer_attrs);
// Unique pointer custom clone function
std::unique_ptr<LiteralExpr> clone_literal_expr () const
@@ -180,27 +168,13 @@ protected:
// Constructor (only for initialisation of expr purposes)
OperatorExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> main_or_left_expr,
- AST::AttrVec outer_attribs, location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- locus (locus), main_or_left_expr (std::move (main_or_left_expr))
- {}
+ AST::AttrVec outer_attribs, location_t locus);
// Copy constructor (only for initialisation of expr purposes)
- OperatorExpr (OperatorExpr const &other)
- : ExprWithoutBlock (other), locus (other.locus),
- main_or_left_expr (other.main_or_left_expr->clone_expr ())
- {}
+ OperatorExpr (OperatorExpr const &other);
// Overload assignment operator to deep copy expr
- OperatorExpr &operator= (OperatorExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- main_or_left_expr = other.main_or_left_expr->clone_expr ();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ OperatorExpr &operator= (OperatorExpr const &other);
// move constructors
OperatorExpr (OperatorExpr &&other) = default;
@@ -209,7 +183,7 @@ protected:
public:
location_t get_locus () const override final { return locus; }
- std::unique_ptr<Expr> &get_expr () { return main_or_left_expr; }
+ Expr &get_expr () { return *main_or_left_expr; }
ExprType get_expression_type () const override final
{
@@ -222,23 +196,21 @@ public:
class BorrowExpr : public OperatorExpr
{
Mutability mut;
+ bool raw;
public:
std::string as_string () const override;
BorrowExpr (Analysis::NodeMapping mappings,
- std::unique_ptr<Expr> borrow_lvalue, Mutability mut,
- AST::AttrVec outer_attribs, location_t locus)
- : OperatorExpr (std::move (mappings), std::move (borrow_lvalue),
- std::move (outer_attribs), locus),
- mut (mut)
- {}
+ std::unique_ptr<Expr> borrow_lvalue, Mutability mut, bool raw,
+ AST::AttrVec outer_attribs, location_t locus);
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
Mutability get_mut () const { return mut; }
bool is_mut () const { return mut == Mutability::Mut; }
+ bool is_raw_borrow () const { return raw; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -265,10 +237,7 @@ public:
// Constructor calls OperatorExpr's protected constructor
DereferenceExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> deref_lvalue,
- AST::AttrVec outer_attribs, location_t locus)
- : OperatorExpr (std::move (mappings), std::move (deref_lvalue),
- std::move (outer_attribs), locus)
- {}
+ AST::AttrVec outer_attribs, location_t locus);
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
@@ -298,10 +267,7 @@ public:
// Constructor calls OperatorExpr's protected constructor
ErrorPropagationExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> potential_error_value,
- AST::AttrVec outer_attribs, location_t locus)
- : OperatorExpr (std::move (mappings), std::move (potential_error_value),
- std::move (outer_attribs), locus)
- {}
+ AST::AttrVec outer_attribs, location_t locus);
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
@@ -342,11 +308,7 @@ public:
// Constructor calls OperatorExpr's protected constructor
NegationExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> negated_value, ExprType expr_kind,
- AST::AttrVec outer_attribs, location_t locus)
- : OperatorExpr (std::move (mappings), std::move (negated_value),
- std::move (outer_attribs), locus),
- expr_type (expr_kind)
- {}
+ AST::AttrVec outer_attribs, location_t locus);
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
@@ -388,29 +350,14 @@ public:
ArithmeticOrLogicalExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> left_value,
std::unique_ptr<Expr> right_value,
- ExprType expr_kind, location_t locus)
- : OperatorExpr (std::move (mappings), std::move (left_value),
- AST::AttrVec (), locus),
- expr_type (expr_kind), right_expr (std::move (right_value))
- {}
+ ExprType expr_kind, location_t locus);
// outer attributes not allowed
// Copy constructor - probably required due to unique pointer
- ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr const &other)
- : OperatorExpr (other), expr_type (other.expr_type),
- right_expr (other.right_expr->clone_expr ())
- {}
+ ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr const &other);
// Overload assignment operator
- ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr const &other)
- {
- OperatorExpr::operator= (other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr ();
- expr_type = other.expr_type;
-
- return *this;
- }
+ ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr const &other);
// move constructors
ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr &&other) = default;
@@ -423,8 +370,8 @@ public:
void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
- std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
- std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+ Expr &get_lhs () { return *main_or_left_expr; }
+ Expr &get_rhs () { return *right_expr; }
std::string get_operator_str () const;
@@ -465,30 +412,14 @@ public:
ComparisonExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> left_value,
std::unique_ptr<Expr> right_value, ExprType comparison_kind,
- location_t locus)
- : OperatorExpr (std::move (mappings), std::move (left_value),
- AST::AttrVec (), locus),
- expr_type (comparison_kind), right_expr (std::move (right_value))
- {}
+ location_t locus);
// outer attributes not allowed
// Copy constructor also calls OperatorExpr's protected constructor
- ComparisonExpr (ComparisonExpr const &other)
- : OperatorExpr (other), expr_type (other.expr_type),
- right_expr (other.right_expr->clone_expr ())
- {}
+ ComparisonExpr (ComparisonExpr const &other);
// Overload assignment operator to deep copy
- ComparisonExpr &operator= (ComparisonExpr const &other)
- {
- OperatorExpr::operator= (other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr ();
- expr_type = other.expr_type;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ ComparisonExpr &operator= (ComparisonExpr const &other);
// move constructors
ComparisonExpr (ComparisonExpr &&other) = default;
@@ -497,8 +428,8 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
- std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+ Expr &get_lhs () { return *main_or_left_expr; }
+ Expr &get_rhs () { return *right_expr; }
ExprType get_kind () { return expr_type; }
@@ -536,29 +467,14 @@ public:
LazyBooleanExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> left_bool_expr,
std::unique_ptr<Expr> right_bool_expr, ExprType expr_kind,
- location_t locus)
- : OperatorExpr (std::move (mappings), std::move (left_bool_expr),
- AST::AttrVec (), locus),
- expr_type (expr_kind), right_expr (std::move (right_bool_expr))
- {}
+ location_t locus);
// outer attributes not allowed
// Copy constructor also calls OperatorExpr's protected constructor
- LazyBooleanExpr (LazyBooleanExpr const &other)
- : OperatorExpr (other), expr_type (other.expr_type),
- right_expr (other.right_expr->clone_expr ())
- {}
+ LazyBooleanExpr (LazyBooleanExpr const &other);
// Overload assignment operator to deep copy
- LazyBooleanExpr &operator= (LazyBooleanExpr const &other)
- {
- OperatorExpr::operator= (other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr ();
- expr_type = other.expr_type;
-
- return *this;
- }
+ LazyBooleanExpr &operator= (LazyBooleanExpr const &other);
// move constructors
LazyBooleanExpr (LazyBooleanExpr &&other) = default;
@@ -571,8 +487,8 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
- std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+ Expr &get_lhs () { return *main_or_left_expr; }
+ Expr &get_rhs () { return *right_expr; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -602,28 +518,14 @@ public:
// Constructor requires calling protected constructor of OperatorExpr
TypeCastExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> expr_to_cast,
- std::unique_ptr<Type> type_to_cast_to, location_t locus)
- : OperatorExpr (std::move (mappings), std::move (expr_to_cast),
- AST::AttrVec (), locus),
- type_to_convert_to (std::move (type_to_cast_to))
- {}
+ std::unique_ptr<Type> type_to_cast_to, location_t locus);
// outer attributes not allowed
// Copy constructor also requires calling protected constructor
- TypeCastExpr (TypeCastExpr const &other)
- : OperatorExpr (other),
- type_to_convert_to (other.type_to_convert_to->clone_type ())
- {}
+ TypeCastExpr (TypeCastExpr const &other);
// Overload assignment operator to deep copy
- TypeCastExpr &operator= (TypeCastExpr const &other)
- {
- OperatorExpr::operator= (other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- type_to_convert_to = other.type_to_convert_to->clone_type ();
-
- return *this;
- }
+ TypeCastExpr &operator= (TypeCastExpr const &other);
// move constructors as not supported in c++03
TypeCastExpr (TypeCastExpr &&other) = default;
@@ -633,12 +535,9 @@ public:
void accept_vis (HIRExpressionVisitor &vis) override;
// FIXME: isn't it the same as get_expr() from parent?
- std::unique_ptr<Expr> &get_casted_expr () { return main_or_left_expr; }
+ Expr &get_casted_expr () { return *main_or_left_expr; }
- std::unique_ptr<Type> &get_type_to_convert_to ()
- {
- return type_to_convert_to;
- }
+ Type &get_type_to_convert_to () { return *type_to_convert_to; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -667,28 +566,14 @@ public:
// Call OperatorExpr constructor to initialise left_expr
AssignmentExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> value_to_assign_to,
- std::unique_ptr<Expr> value_to_assign, location_t locus)
- : OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
- AST::AttrVec (), locus),
- right_expr (std::move (value_to_assign))
- {}
+ std::unique_ptr<Expr> value_to_assign, location_t locus);
// outer attributes not allowed
// Call OperatorExpr constructor in copy constructor, as well as clone
- AssignmentExpr (AssignmentExpr const &other)
- : OperatorExpr (other), right_expr (other.right_expr->clone_expr ())
- {}
+ AssignmentExpr (AssignmentExpr const &other);
// Overload assignment operator to clone unique_ptr right_expr
- AssignmentExpr &operator= (AssignmentExpr const &other)
- {
- OperatorExpr::operator= (other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr ();
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ AssignmentExpr &operator= (AssignmentExpr const &other);
// move constructors
AssignmentExpr (AssignmentExpr &&other) = default;
@@ -700,8 +585,8 @@ public:
void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
- std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
- std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+ Expr &get_lhs () { return *main_or_left_expr; }
+ Expr &get_rhs () { return *right_expr; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -738,30 +623,14 @@ public:
CompoundAssignmentExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> value_to_assign_to,
std::unique_ptr<Expr> value_to_assign,
- ExprType expr_kind, location_t locus)
- : OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
- AST::AttrVec (), locus),
- expr_type (expr_kind), right_expr (std::move (value_to_assign))
- {}
+ ExprType expr_kind, location_t locus);
// outer attributes not allowed
// Have clone in copy constructor
- CompoundAssignmentExpr (CompoundAssignmentExpr const &other)
- : OperatorExpr (other), expr_type (other.expr_type),
- right_expr (other.right_expr->clone_expr ())
- {}
+ CompoundAssignmentExpr (CompoundAssignmentExpr const &other);
// Overload assignment operator to clone
- CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other)
- {
- OperatorExpr::operator= (other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr ();
- expr_type = other.expr_type;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other);
// move constructors
CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default;
@@ -770,9 +639,9 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; }
+ Expr &get_lhs () { return *main_or_left_expr; }
- std::unique_ptr<Expr> &get_rhs () { return right_expr; }
+ Expr &get_rhs () { return *right_expr; }
void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
@@ -801,29 +670,13 @@ public:
GroupedExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> parenthesised_expr,
AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
- location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- WithInnerAttrs (std::move (inner_attribs)),
- expr_in_parens (std::move (parenthesised_expr)), locus (locus)
- {}
+ location_t locus);
// Copy constructor includes clone for expr_in_parens
- GroupedExpr (GroupedExpr const &other)
- : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs),
- expr_in_parens (other.expr_in_parens->clone_expr ()), locus (other.locus)
- {}
+ GroupedExpr (GroupedExpr const &other);
// Overloaded assignment operator to clone expr_in_parens
- GroupedExpr &operator= (GroupedExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- inner_attrs = other.inner_attrs;
- expr_in_parens = other.expr_in_parens->clone_expr ();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ GroupedExpr &operator= (GroupedExpr const &other);
// move constructors
GroupedExpr (GroupedExpr &&other) = default;
@@ -834,7 +687,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_expr_in_parens () { return expr_in_parens; }
+ Expr &get_expr_in_parens () { return *expr_in_parens; }
ExprType get_expression_type () const override final
{
@@ -896,33 +749,19 @@ protected:
// Value array elements
class ArrayElemsValues : public ArrayElems
{
- std::vector<std::unique_ptr<Expr> > values;
+ std::vector<std::unique_ptr<Expr>> values;
// TODO: should this store location data?
public:
ArrayElemsValues (Analysis::NodeMapping mappings,
- std::vector<std::unique_ptr<Expr> > elems)
- : ArrayElems (mappings), values (std::move (elems))
- {}
+ std::vector<std::unique_ptr<Expr>> elems);
// copy constructor with vector clone
- ArrayElemsValues (ArrayElemsValues const &other) : ArrayElems (other)
- {
- values.reserve (other.values.size ());
- for (const auto &e : other.values)
- values.push_back (e->clone_expr ());
- }
+ ArrayElemsValues (ArrayElemsValues const &other);
// overloaded assignment operator with vector clone
- ArrayElemsValues &operator= (ArrayElemsValues const &other)
- {
- values.reserve (other.values.size ());
- for (const auto &e : other.values)
- values.push_back (e->clone_expr ());
-
- return *this;
- }
+ ArrayElemsValues &operator= (ArrayElemsValues const &other);
// move constructors
ArrayElemsValues (ArrayElemsValues &&other) = default;
@@ -934,7 +773,7 @@ public:
size_t get_num_elements () const { return values.size (); }
- std::vector<std::unique_ptr<Expr> > &get_values () { return values; }
+ std::vector<std::unique_ptr<Expr>> &get_values () { return values; }
ArrayElems::ArrayExprType get_array_expr_type () const override final
{
@@ -958,25 +797,13 @@ public:
// Constructor requires pointers for polymorphism
ArrayElemsCopied (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> copied_elem,
- std::unique_ptr<Expr> copy_amount)
- : ArrayElems (mappings), elem_to_copy (std::move (copied_elem)),
- num_copies (std::move (copy_amount))
- {}
+ std::unique_ptr<Expr> copy_amount);
// Copy constructor required due to unique_ptr - uses custom clone
- ArrayElemsCopied (ArrayElemsCopied const &other)
- : ArrayElems (other), elem_to_copy (other.elem_to_copy->clone_expr ()),
- num_copies (other.num_copies->clone_expr ())
- {}
+ ArrayElemsCopied (ArrayElemsCopied const &other);
// Overloaded assignment operator for deep copying
- ArrayElemsCopied &operator= (ArrayElemsCopied const &other)
- {
- elem_to_copy = other.elem_to_copy->clone_expr ();
- num_copies = other.num_copies->clone_expr ();
-
- return *this;
- }
+ ArrayElemsCopied &operator= (ArrayElemsCopied const &other);
// move constructors
ArrayElemsCopied (ArrayElemsCopied &&other) = default;
@@ -986,9 +813,9 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
- std::unique_ptr<Expr> &get_elem_to_copy () { return elem_to_copy; }
+ Expr &get_elem_to_copy () { return *elem_to_copy; }
- std::unique_ptr<Expr> &get_num_copies_expr () { return num_copies; }
+ Expr &get_num_copies_expr () { return *num_copies; }
ArrayElems::ArrayExprType get_array_expr_type () const override final
{
@@ -1019,33 +846,13 @@ public:
ArrayExpr (Analysis::NodeMapping mappings,
std::unique_ptr<ArrayElems> array_elems,
AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
- location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- WithInnerAttrs (std::move (inner_attribs)),
- internal_elements (std::move (array_elems)), locus (locus)
- {}
+ location_t locus);
// Copy constructor requires cloning ArrayElems for polymorphism to hold
- ArrayExpr (ArrayExpr const &other)
- : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs),
- locus (other.locus)
- {
- if (other.has_array_elems ())
- internal_elements = other.internal_elements->clone_array_elems ();
- }
+ ArrayExpr (ArrayExpr const &other);
// Overload assignment operator to clone internal_elements
- ArrayExpr &operator= (ArrayExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- inner_attrs = other.inner_attrs;
- if (other.has_array_elems ())
- internal_elements = other.internal_elements->clone_array_elems ();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ ArrayExpr &operator= (ArrayExpr const &other);
// move constructors
ArrayExpr (ArrayExpr &&other) = default;
@@ -1056,10 +863,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<ArrayElems> &get_internal_elements ()
- {
- return internal_elements;
- };
+ ArrayElems &get_internal_elements () { return *internal_elements; };
ExprType get_expression_type () const override final
{
@@ -1092,29 +896,13 @@ public:
ArrayIndexExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> array_expr,
std::unique_ptr<Expr> array_index_expr,
- AST::AttrVec outer_attribs, location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- array_expr (std::move (array_expr)),
- index_expr (std::move (array_index_expr)), locus (locus)
- {}
+ AST::AttrVec outer_attribs, location_t locus);
// Copy constructor requires special cloning due to unique_ptr
- ArrayIndexExpr (ArrayIndexExpr const &other)
- : ExprWithoutBlock (other), array_expr (other.array_expr->clone_expr ()),
- index_expr (other.index_expr->clone_expr ()), locus (other.locus)
- {}
+ ArrayIndexExpr (ArrayIndexExpr const &other);
// Overload assignment operator to clone unique_ptrs
- ArrayIndexExpr &operator= (ArrayIndexExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- array_expr = other.array_expr->clone_expr ();
- index_expr = other.index_expr->clone_expr ();
- // outer_attrs = other.outer_attrs;
- locus = other.locus;
-
- return *this;
- }
+ ArrayIndexExpr &operator= (ArrayIndexExpr const &other);
// move constructors
ArrayIndexExpr (ArrayIndexExpr &&other) = default;
@@ -1125,8 +913,8 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_array_expr () { return array_expr; }
- std::unique_ptr<Expr> &get_index_expr () { return index_expr; }
+ Expr &get_array_expr () { return *array_expr; }
+ Expr &get_index_expr () { return *index_expr; }
ExprType get_expression_type () const override final
{
@@ -1152,7 +940,7 @@ protected:
// HIR representation of a tuple
class TupleExpr : public ExprWithoutBlock, public WithInnerAttrs
{
- std::vector<std::unique_ptr<Expr> > tuple_elems;
+ std::vector<std::unique_ptr<Expr>> tuple_elems;
// replaces (inlined version of) TupleElements
location_t locus;
@@ -1161,37 +949,15 @@ public:
std::string as_string () const override;
TupleExpr (Analysis::NodeMapping mappings,
- std::vector<std::unique_ptr<Expr> > tuple_elements,
+ std::vector<std::unique_ptr<Expr>> tuple_elements,
AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
- location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- WithInnerAttrs (std::move (inner_attribs)),
- tuple_elems (std::move (tuple_elements)), locus (locus)
- {}
+ location_t locus);
// copy constructor with vector clone
- TupleExpr (TupleExpr const &other)
- : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs),
- locus (other.locus)
- {
- tuple_elems.reserve (other.tuple_elems.size ());
- for (const auto &e : other.tuple_elems)
- tuple_elems.push_back (e->clone_expr ());
- }
+ TupleExpr (TupleExpr const &other);
// overloaded assignment operator to vector clone
- TupleExpr &operator= (TupleExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- inner_attrs = other.inner_attrs;
- locus = other.locus;
-
- tuple_elems.reserve (other.tuple_elems.size ());
- for (const auto &e : other.tuple_elems)
- tuple_elems.push_back (e->clone_expr ());
-
- return *this;
- }
+ TupleExpr &operator= (TupleExpr const &other);
// move constructors
TupleExpr (TupleExpr &&other) = default;
@@ -1205,14 +971,11 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- const std::vector<std::unique_ptr<Expr> > &get_tuple_elems () const
- {
- return tuple_elems;
- }
- std::vector<std::unique_ptr<Expr> > &get_tuple_elems ()
+ const std::vector<std::unique_ptr<Expr>> &get_tuple_elems () const
{
return tuple_elems;
}
+ std::vector<std::unique_ptr<Expr>> &get_tuple_elems () { return tuple_elems; }
bool is_unit () const { return tuple_elems.size () == 0; }
@@ -1247,28 +1010,13 @@ public:
TupleIndexExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> tuple_expr, TupleIndex index,
- AST::AttrVec outer_attribs, location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus)
- {}
+ AST::AttrVec outer_attribs, location_t locus);
// Copy constructor requires a clone for tuple_expr
- TupleIndexExpr (TupleIndexExpr const &other)
- : ExprWithoutBlock (other), tuple_expr (other.tuple_expr->clone_expr ()),
- tuple_index (other.tuple_index), locus (other.locus)
- {}
+ TupleIndexExpr (TupleIndexExpr const &other);
// Overload assignment operator in order to clone
- TupleIndexExpr &operator= (TupleIndexExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- tuple_expr = other.tuple_expr->clone_expr ();
- tuple_index = other.tuple_index;
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ TupleIndexExpr &operator= (TupleIndexExpr const &other);
// move constructors
TupleIndexExpr (TupleIndexExpr &&other) = default;
@@ -1279,7 +1027,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_tuple_expr () { return tuple_expr; }
+ Expr &get_tuple_expr () { return *tuple_expr; }
ExprType get_expression_type () const override final
{
@@ -1310,10 +1058,7 @@ protected:
// Protected constructor to allow initialising struct_name
StructExpr (Analysis::NodeMapping mappings, PathInExpression struct_path,
- AST::AttrVec outer_attribs)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- struct_name (std::move (struct_path))
- {}
+ AST::AttrVec outer_attribs);
public:
PathInExpression &get_struct_name () { return struct_name; }
@@ -1337,11 +1082,7 @@ public:
// Constructor has to call protected constructor of base class
StructExprStruct (Analysis::NodeMapping mappings,
PathInExpression struct_path, AST::AttrVec inner_attribs,
- AST::AttrVec outer_attribs, location_t locus)
- : StructExpr (std::move (mappings), std::move (struct_path),
- std::move (outer_attribs)),
- WithInnerAttrs (std::move (inner_attribs)), locus (locus)
- {}
+ AST::AttrVec outer_attribs, location_t locus);
location_t get_locus () const override final { return locus; }
@@ -1368,33 +1109,21 @@ protected:
* struct */
struct StructBase
{
-public:
+private:
std::unique_ptr<Expr> base_struct;
+public:
// TODO: should this store location data?
- StructBase (std::unique_ptr<Expr> base_struct_ptr)
- : base_struct (std::move (base_struct_ptr))
- {}
+ StructBase (std::unique_ptr<Expr> base_struct_ptr);
// Copy constructor requires clone
- StructBase (StructBase const &other)
- {
- /* HACK: gets around base_struct pointer being null (e.g. if no struct base
- * exists) */
- if (other.base_struct != nullptr)
- other.base_struct->clone_expr ();
- }
+ StructBase (StructBase const &other);
// Destructor
~StructBase () = default;
// Overload assignment operator to clone base_struct
- StructBase &operator= (StructBase const &other)
- {
- base_struct = other.base_struct->clone_expr ();
-
- return *this;
- }
+ StructBase &operator= (StructBase const &other);
// move constructors
StructBase (StructBase &&other) = default;
@@ -1408,7 +1137,7 @@ public:
std::string as_string () const;
- Expr *get_base () { return base_struct.get (); }
+ Expr &get_base () { return *base_struct; }
};
/* Base HIR node for a single struct expression field (in struct instance
@@ -1446,9 +1175,7 @@ protected:
// pure virtual clone implementation
virtual StructExprField *clone_struct_expr_field_impl () const = 0;
- StructExprField (Analysis::NodeMapping mapping, location_t locus)
- : mappings (mapping), locus (locus)
- {}
+ StructExprField (Analysis::NodeMapping mapping, location_t locus);
Analysis::NodeMapping mappings;
location_t locus;
@@ -1463,10 +1190,7 @@ private:
// TODO: should this store location data?
public:
StructExprFieldIdentifier (Analysis::NodeMapping mapping,
- Identifier field_identifier, location_t locus)
- : StructExprField (mapping, locus),
- field_name (std::move (field_identifier))
- {}
+ Identifier field_identifier, location_t locus);
std::string as_string () const override { return field_name.as_string (); }
@@ -1497,25 +1221,13 @@ class StructExprFieldWithVal : public StructExprField
protected:
StructExprFieldWithVal (Analysis::NodeMapping mapping,
- std::unique_ptr<Expr> field_value, location_t locus)
- : StructExprField (mapping, locus), value (std::move (field_value))
- {}
+ std::unique_ptr<Expr> field_value, location_t locus);
// Copy constructor requires clone
- StructExprFieldWithVal (StructExprFieldWithVal const &other)
- : StructExprField (other.mappings, other.locus),
- value (other.value->clone_expr ())
- {}
+ StructExprFieldWithVal (StructExprFieldWithVal const &other);
// Overload assignment operator to clone unique_ptr
- StructExprFieldWithVal &operator= (StructExprFieldWithVal const &other)
- {
- value = other.value->clone_expr ();
- mappings = other.mappings;
- locus = other.locus;
-
- return *this;
- }
+ StructExprFieldWithVal &operator= (StructExprFieldWithVal const &other);
// move constructors
StructExprFieldWithVal (StructExprFieldWithVal &&other) = default;
@@ -1524,7 +1236,7 @@ protected:
public:
std::string as_string () const override;
- std::unique_ptr<Expr> &get_value () { return value; }
+ Expr &get_value () { return *value; }
};
// Identifier and value variant of StructExprField HIR node
@@ -1538,10 +1250,7 @@ public:
StructExprFieldIdentifierValue (Analysis::NodeMapping mapping,
Identifier field_identifier,
std::unique_ptr<Expr> field_value,
- location_t locus)
- : StructExprFieldWithVal (mapping, std::move (field_value), locus),
- field_name (std::move (field_identifier))
- {}
+ location_t locus);
std::string as_string () const override;
@@ -1575,10 +1284,7 @@ public:
StructExprFieldIndexValue (Analysis::NodeMapping mapping,
TupleIndex tuple_index,
std::unique_ptr<Expr> field_value,
- location_t locus)
- : StructExprFieldWithVal (mapping, std::move (field_value), locus),
- index (tuple_index)
- {}
+ location_t locus);
std::string as_string () const override;
@@ -1604,58 +1310,31 @@ protected:
// HIR node of a struct creator with fields
class StructExprStructFields : public StructExprStruct
{
-public:
// std::vector<StructExprField> fields;
- std::vector<std::unique_ptr<StructExprField> > fields;
-
- // bool has_struct_base;
- // FIXME make unique_ptr
- StructBase *struct_base;
+ std::vector<std::unique_ptr<StructExprField>> fields;
+ tl::optional<std::unique_ptr<StructBase>> struct_base;
+public:
// For unions there is just one field, the index
// is set when type checking
int union_index = -1;
std::string as_string () const override;
- bool has_struct_base () const { return struct_base != nullptr; }
+ bool has_struct_base () const { return struct_base.has_value (); }
// Constructor for StructExprStructFields when no struct base is used
StructExprStructFields (
Analysis::NodeMapping mappings, PathInExpression struct_path,
- std::vector<std::unique_ptr<StructExprField> > expr_fields,
- location_t locus, StructBase *base_struct,
- AST::AttrVec inner_attribs = AST::AttrVec (),
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : StructExprStruct (std::move (mappings), std::move (struct_path),
- std::move (inner_attribs), std::move (outer_attribs),
- locus),
- fields (std::move (expr_fields)), struct_base (base_struct)
- {}
+ std::vector<std::unique_ptr<StructExprField>> expr_fields, location_t locus,
+ tl::optional<std::unique_ptr<StructBase>> base_struct,
+ AST::AttrVec inner_attribs, AST::AttrVec outer_attribs);
// copy constructor with vector clone
- StructExprStructFields (StructExprStructFields const &other)
- : StructExprStruct (other), struct_base (other.struct_base),
- union_index (other.union_index)
- {
- fields.reserve (other.fields.size ());
- for (const auto &e : other.fields)
- fields.push_back (e->clone_struct_expr_field ());
- }
+ StructExprStructFields (StructExprStructFields const &other);
// overloaded assignment operator with vector clone
- StructExprStructFields &operator= (StructExprStructFields const &other)
- {
- StructExprStruct::operator= (other);
- struct_base = other.struct_base;
- union_index = other.union_index;
-
- fields.reserve (other.fields.size ());
- for (const auto &e : other.fields)
- fields.push_back (e->clone_struct_expr_field ());
-
- return *this;
- }
+ StructExprStructFields &operator= (StructExprStructFields const &other);
// move constructors
StructExprStructFields (StructExprStructFields &&other) = default;
@@ -1664,20 +1343,20 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::vector<std::unique_ptr<StructExprField> > &get_fields ()
+ std::vector<std::unique_ptr<StructExprField>> &get_fields ()
{
return fields;
};
- const std::vector<std::unique_ptr<StructExprField> > &get_fields () const
+ const std::vector<std::unique_ptr<StructExprField>> &get_fields () const
{
return fields;
};
- StructBase *get_struct_base () { return struct_base; }
+ StructBase &get_struct_base () { return *struct_base.value (); }
- void set_fields_as_owner (
- std::vector<std::unique_ptr<StructExprField> > new_fields)
+ void
+ set_fields_as_owner (std::vector<std::unique_ptr<StructExprField>> new_fields)
{
fields = std::move (new_fields);
}
@@ -1704,26 +1383,15 @@ class StructExprStructBase : public StructExprStruct
StructBase struct_base;
public:
- std::string as_string () const override;
-
- /*inline StructBase get_struct_base() const {
- return struct_base;
- }*/
-
StructExprStructBase (Analysis::NodeMapping mappings,
PathInExpression struct_path, StructBase base_struct,
AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
- location_t locus)
- : StructExprStruct (std::move (mappings), std::move (struct_path),
- std::move (inner_attribs), std::move (outer_attribs),
- locus),
- struct_base (std::move (base_struct))
- {}
+ location_t locus);
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- StructBase *get_struct_base () { return &struct_base; }
+ StructBase &get_struct_base () { return struct_base; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -1745,45 +1413,21 @@ protected:
class CallExpr : public ExprWithoutBlock
{
std::unique_ptr<Expr> function;
- std::vector<std::unique_ptr<Expr> > params;
+ std::vector<std::unique_ptr<Expr>> params;
location_t locus;
public:
std::string as_string () const override;
CallExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> function_expr,
- std::vector<std::unique_ptr<Expr> > function_params,
- AST::AttrVec outer_attribs, location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- function (std::move (function_expr)),
- params (std::move (function_params)), locus (locus)
- {}
+ std::vector<std::unique_ptr<Expr>> function_params,
+ AST::AttrVec outer_attribs, location_t locus);
// copy constructor requires clone
- CallExpr (CallExpr const &other)
- : ExprWithoutBlock (other), function (other.function->clone_expr ()),
- locus (other.locus)
- /*, params(other.params),*/ {
- params.reserve (other.params.size ());
- for (const auto &e : other.params)
- params.push_back (e->clone_expr ());
- }
+ CallExpr (CallExpr const &other);
// Overload assignment operator to clone
- CallExpr &operator= (CallExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- function = other.function->clone_expr ();
- locus = other.locus;
- // params = other.params;
- // outer_attrs = other.outer_attrs;
-
- params.reserve (other.params.size ());
- for (const auto &e : other.params)
- params.push_back (e->clone_expr ());
-
- return *this;
- }
+ CallExpr &operator= (CallExpr const &other);
// move constructors
CallExpr (CallExpr &&other) = default;
@@ -1797,13 +1441,14 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_fnexpr () { return function; }
+ bool has_fnexpr () const { return function != nullptr; }
+ Expr &get_fnexpr () { return *function; }
size_t num_params () const { return params.size (); }
- std::vector<std::unique_ptr<Expr> > &get_arguments () { return params; }
+ std::vector<std::unique_ptr<Expr>> &get_arguments () { return params; }
- const std::vector<std::unique_ptr<Expr> > &get_arguments () const
+ const std::vector<std::unique_ptr<Expr>> &get_arguments () const
{
return params;
}
@@ -1831,7 +1476,7 @@ class MethodCallExpr : public ExprWithoutBlock
{
std::unique_ptr<Expr> receiver;
PathExprSegment method_name;
- std::vector<std::unique_ptr<Expr> > params;
+ std::vector<std::unique_ptr<Expr>> params;
location_t locus;
public:
@@ -1840,40 +1485,14 @@ public:
MethodCallExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> call_receiver,
PathExprSegment method_path,
- std::vector<std::unique_ptr<Expr> > method_params,
- AST::AttrVec outer_attribs, location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- receiver (std::move (call_receiver)),
- method_name (std::move (method_path)), params (std::move (method_params)),
- locus (locus)
- {}
+ std::vector<std::unique_ptr<Expr>> method_params,
+ AST::AttrVec outer_attribs, location_t locus);
// copy constructor required due to cloning
- MethodCallExpr (MethodCallExpr const &other)
- : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
- method_name (other.method_name), locus (other.locus)
- /*, params(other.params),*/ {
- params.reserve (other.params.size ());
- for (const auto &e : other.params)
- params.push_back (e->clone_expr ());
- }
+ MethodCallExpr (MethodCallExpr const &other);
// Overload assignment operator to clone receiver object
- MethodCallExpr &operator= (MethodCallExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- receiver = other.receiver->clone_expr ();
- method_name = other.method_name;
- locus = other.locus;
- // params = other.params;
- // outer_attrs = other.outer_attrs;
-
- params.reserve (other.params.size ());
- for (const auto &e : other.params)
- params.push_back (e->clone_expr ());
-
- return *this;
- }
+ MethodCallExpr &operator= (MethodCallExpr const &other);
// move constructors
MethodCallExpr (MethodCallExpr &&other) = default;
@@ -1884,7 +1503,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_receiver () { return receiver; }
+ Expr &get_receiver () { return *receiver; }
PathExprSegment &get_method_name () { return method_name; };
const PathExprSegment &get_method_name () const { return method_name; };
@@ -1892,9 +1511,9 @@ public:
bool has_params () const { return !params.empty (); }
size_t num_params () const { return params.size (); }
- std::vector<std::unique_ptr<Expr> > &get_arguments () { return params; }
+ std::vector<std::unique_ptr<Expr>> &get_arguments () { return params; }
- const std::vector<std::unique_ptr<Expr> > &get_arguments () const
+ const std::vector<std::unique_ptr<Expr>> &get_arguments () const
{
return params;
}
@@ -1935,29 +1554,13 @@ public:
FieldAccessExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> field_access_receiver,
Identifier field_name, AST::AttrVec outer_attribs,
- location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- receiver (std::move (field_access_receiver)),
- field (std::move (field_name)), locus (locus)
- {}
+ location_t locus);
// Copy constructor required due to unique_ptr cloning
- FieldAccessExpr (FieldAccessExpr const &other)
- : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
- field (other.field), locus (other.locus)
- {}
+ FieldAccessExpr (FieldAccessExpr const &other);
// Overload assignment operator to clone unique_ptr
- FieldAccessExpr &operator= (FieldAccessExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- receiver = other.receiver->clone_expr ();
- field = other.field;
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ FieldAccessExpr &operator= (FieldAccessExpr const &other);
// move constructors
FieldAccessExpr (FieldAccessExpr &&other) = default;
@@ -1968,7 +1571,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_receiver_expr () { return receiver; }
+ Expr &get_receiver_expr () { return *receiver; }
Identifier get_field_name () const { return field; }
@@ -2009,42 +1612,15 @@ public:
// Constructor for closure parameter
ClosureParam (std::unique_ptr<Pattern> param_pattern, location_t locus,
std::unique_ptr<Type> param_type = nullptr,
- std::vector<AST::Attribute> outer_attrs = {})
- : outer_attrs (std::move (outer_attrs)),
- pattern (std::move (param_pattern)), type (std::move (param_type)),
- locus (locus)
- {}
+ std::vector<AST::Attribute> outer_attrs = {});
// Copy constructor required due to cloning as a result of unique_ptrs
- ClosureParam (ClosureParam const &other)
- : pattern (other.pattern->clone_pattern ())
- {
- // guard to protect from null pointer dereference
- if (other.pattern != nullptr)
- pattern = other.pattern->clone_pattern ();
- if (other.type != nullptr)
- type = other.type->clone_type ();
- }
+ ClosureParam (ClosureParam const &other);
~ClosureParam () = default;
// Assignment operator must be overloaded to clone as well
- ClosureParam &operator= (ClosureParam const &other)
- {
- outer_attrs = other.outer_attrs;
-
- // guard to protect from null pointer dereference
- if (other.pattern != nullptr)
- pattern = other.pattern->clone_pattern ();
- else
- pattern = nullptr;
- if (other.type != nullptr)
- type = other.type->clone_type ();
- else
- type = nullptr;
-
- return *this;
- }
+ ClosureParam &operator= (ClosureParam const &other);
// move constructors
ClosureParam (ClosureParam &&other) = default;
@@ -2058,9 +1634,9 @@ public:
}
std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
- std::unique_ptr<Pattern> &get_pattern () { return pattern; }
+ Pattern &get_pattern () { return *pattern; }
- std::unique_ptr<Type> &get_type () { return type; }
+ Type &get_type () { return *type; }
location_t get_locus () const { return locus; }
};
@@ -2080,36 +1656,13 @@ public:
std::vector<ClosureParam> closure_params,
std::unique_ptr<Type> closure_return_type,
std::unique_ptr<Expr> closure_expr, bool has_move,
- AST::AttrVec outer_attribs, location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- has_move (has_move), params (std::move (closure_params)), locus (locus),
- return_type (std::move (closure_return_type)),
- expr (std::move (closure_expr))
- {}
+ AST::AttrVec outer_attribs, location_t locus);
// Copy constructor requires cloning
- ClosureExpr (ClosureExpr const &other)
- : ExprWithoutBlock (other.get_mappings (), other.get_outer_attrs ())
- {
- return_type
- = other.has_return_type () ? other.return_type->clone_type () : nullptr;
- expr = other.expr->clone_expr ();
- params = other.params;
- has_move = other.has_move;
- }
+ ClosureExpr (ClosureExpr const &other);
// Overload assignment operator to clone unique_ptrs
- ClosureExpr &operator= (ClosureExpr const &other)
- {
- mappings = other.mappings;
- return_type
- = other.has_return_type () ? other.return_type->clone_type () : nullptr;
- expr = other.expr->clone_expr ();
- params = other.params;
- has_move = other.has_move;
-
- return *this;
- }
+ ClosureExpr &operator= (ClosureExpr const &other);
// move constructors
ClosureExpr (ClosureExpr &&other) = default;
@@ -2128,8 +1681,8 @@ public:
bool has_return_type () const { return return_type != nullptr; }
- std::unique_ptr<Type> &get_return_type () { return return_type; };
- std::unique_ptr<Expr> &get_expr () { return expr; }
+ Type &get_return_type () { return *return_type; };
+ Expr &get_expr () { return *expr; }
bool has_params () const { return !params.empty (); }
std::vector<ClosureParam> &get_params () { return params; }
@@ -2158,10 +1711,10 @@ class BlockExpr : public ExprWithBlock, public WithInnerAttrs
{
// FIXME this should be private + get/set
public:
- std::vector<std::unique_ptr<Stmt> > statements;
+ std::vector<std::unique_ptr<Stmt>> statements;
std::unique_ptr<Expr> expr;
bool tail_reachable;
- LoopLabel label;
+ tl::optional<LoopLabel> label;
location_t start_locus;
location_t end_locus;
@@ -2178,49 +1731,17 @@ public:
bool is_tail_reachable () const { return tail_reachable; }
BlockExpr (Analysis::NodeMapping mappings,
- std::vector<std::unique_ptr<Stmt> > block_statements,
+ std::vector<std::unique_ptr<Stmt>> block_statements,
std::unique_ptr<Expr> block_expr, bool tail_reachable,
AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
- LoopLabel label, location_t start_locus, location_t end_locus)
- : ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
- WithInnerAttrs (std::move (inner_attribs)),
- statements (std::move (block_statements)), expr (std::move (block_expr)),
- tail_reachable (tail_reachable), label (std::move (label)),
- start_locus (start_locus), end_locus (end_locus)
- {}
+ tl::optional<LoopLabel> label, location_t start_locus,
+ location_t end_locus);
// Copy constructor with clone
- BlockExpr (BlockExpr const &other)
- : ExprWithBlock (other), /*statements(other.statements),*/
- WithInnerAttrs (other.inner_attrs), label (other.label),
- start_locus (other.start_locus), end_locus (other.end_locus)
- {
- // guard to protect from null pointer dereference
- if (other.expr != nullptr)
- expr = other.expr->clone_expr ();
-
- statements.reserve (other.statements.size ());
- for (const auto &e : other.statements)
- statements.push_back (e->clone_stmt ());
- }
+ BlockExpr (BlockExpr const &other);
// Overloaded assignment operator to clone pointer
- BlockExpr &operator= (BlockExpr const &other)
- {
- ExprWithBlock::operator= (other);
- // statements = other.statements;
- expr = other.expr->clone_expr ();
- inner_attrs = other.inner_attrs;
- start_locus = other.end_locus;
- end_locus = other.end_locus;
- // outer_attrs = other.outer_attrs;
-
- statements.reserve (other.statements.size ());
- for (const auto &e : other.statements)
- statements.push_back (e->clone_stmt ());
-
- return *this;
- }
+ BlockExpr &operator= (BlockExpr const &other);
// move constructors
BlockExpr (BlockExpr &&other) = default;
@@ -2243,17 +1764,18 @@ public:
bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; }
- std::unique_ptr<Expr> &get_final_expr () { return expr; }
+ bool has_final_expr () { return expr != nullptr; }
+ Expr &get_final_expr () { return *expr; }
- std::vector<std::unique_ptr<Stmt> > &get_statements () { return statements; }
+ std::vector<std::unique_ptr<Stmt>> &get_statements () { return statements; }
ExprType get_expression_type () const final override
{
return ExprType::Block;
}
- bool has_label () const { return !label.is_error (); }
- LoopLabel &get_label () { return label; }
+ bool has_label () const { return label.has_value (); }
+ LoopLabel &get_label () { return label.value (); }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -2281,28 +1803,27 @@ protected:
// HIR node representing continue expression within loops
class ContinueExpr : public ExprWithoutBlock
{
- Lifetime label;
+ tl::optional<Lifetime> label;
location_t locus;
public:
std::string as_string () const override;
// Returns true if the continue expr has a label.
- bool has_label () const { return !label.is_error (); }
+ bool has_label () const { return label.has_value (); }
// Constructor for a ContinueExpr with a label.
ContinueExpr (Analysis::NodeMapping mappings, location_t locus,
- Lifetime label, AST::AttrVec outer_attribs = AST::AttrVec ())
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- label (std::move (label)), locus (locus)
- {}
+ tl::optional<Lifetime> label,
+ AST::AttrVec outer_attribs = AST::AttrVec ());
location_t get_locus () const override final { return locus; }
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- Lifetime &get_label () { return label; }
+ Lifetime &get_label () { return label.value (); }
+ const Lifetime &get_label () const { return label.value (); }
ExprType get_expression_type () const final override
{
@@ -2329,7 +1850,7 @@ protected:
class BreakExpr : public ExprWithoutBlock
{
// bool has_label;
- Lifetime label;
+ tl::optional<Lifetime> label;
// bool has_break_expr;
std::unique_ptr<Expr> break_expr;
@@ -2340,7 +1861,7 @@ public:
std::string as_string () const override;
// Returns whether the break expression has a label or not.
- bool has_label () const { return !label.is_error (); }
+ bool has_label () const { return label.has_value (); }
/* Returns whether the break expression has an expression used in the break or
* not. */
@@ -2348,34 +1869,15 @@ public:
// Constructor for a break expression
BreakExpr (Analysis::NodeMapping mappings, location_t locus,
- Lifetime break_label,
+ tl::optional<Lifetime> break_label,
std::unique_ptr<Expr> expr_in_break = nullptr,
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- label (std::move (break_label)), break_expr (std::move (expr_in_break)),
- locus (locus)
- {}
+ AST::AttrVec outer_attribs = AST::AttrVec ());
// Copy constructor defined to use clone for unique pointer
- BreakExpr (BreakExpr const &other)
- : ExprWithoutBlock (other), label (other.label), locus (other.locus)
- {
- // guard to protect from null pointer dereference
- if (other.break_expr != nullptr)
- break_expr = other.break_expr->clone_expr ();
- }
+ BreakExpr (BreakExpr const &other);
// Overload assignment operator to clone unique pointer
- BreakExpr &operator= (BreakExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- label = other.label;
- break_expr = other.break_expr->clone_expr ();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ BreakExpr &operator= (BreakExpr const &other);
// move constructors
BreakExpr (BreakExpr &&other) = default;
@@ -2386,9 +1888,10 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- Lifetime &get_label () { return label; }
+ Lifetime &get_label () { return label.value (); }
+ const Lifetime &get_label () const { return label.value (); }
- std::unique_ptr<Expr> &get_expr () { return break_expr; }
+ Expr &get_expr () { return *break_expr; }
ExprType get_expression_type () const override final
{
@@ -2415,9 +1918,7 @@ class RangeExpr : public ExprWithoutBlock
protected:
// outer attributes not allowed before range expressions
- RangeExpr (Analysis::NodeMapping mappings, location_t locus)
- : ExprWithoutBlock (std::move (mappings), AST::AttrVec ()), locus (locus)
- {}
+ RangeExpr (Analysis::NodeMapping mappings, location_t locus);
public:
location_t get_locus () const override final { return locus; }
@@ -2440,26 +1941,13 @@ public:
RangeFromToExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> range_from,
- std::unique_ptr<Expr> range_to, location_t locus)
- : RangeExpr (std::move (mappings), locus), from (std::move (range_from)),
- to (std::move (range_to))
- {}
+ std::unique_ptr<Expr> range_to, location_t locus);
// Copy constructor with cloning
- RangeFromToExpr (RangeFromToExpr const &other)
- : RangeExpr (other), from (other.from->clone_expr ()),
- to (other.to->clone_expr ())
- {}
+ RangeFromToExpr (RangeFromToExpr const &other);
// Overload assignment operator to clone unique pointers
- RangeFromToExpr &operator= (RangeFromToExpr const &other)
- {
- RangeExpr::operator= (other);
- from = other.from->clone_expr ();
- to = other.to->clone_expr ();
-
- return *this;
- }
+ RangeFromToExpr &operator= (RangeFromToExpr const &other);
// move constructors
RangeFromToExpr (RangeFromToExpr &&other) = default;
@@ -2468,8 +1956,8 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_from_expr () { return from; }
- std::unique_ptr<Expr> &get_to_expr () { return to; }
+ Expr &get_from_expr () { return *from; }
+ Expr &get_to_expr () { return *to; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -2497,23 +1985,13 @@ public:
std::string as_string () const override;
RangeFromExpr (Analysis::NodeMapping mappings,
- std::unique_ptr<Expr> range_from, location_t locus)
- : RangeExpr (std::move (mappings), locus), from (std::move (range_from))
- {}
+ std::unique_ptr<Expr> range_from, location_t locus);
// Copy constructor with clone
- RangeFromExpr (RangeFromExpr const &other)
- : RangeExpr (other), from (other.from->clone_expr ())
- {}
+ RangeFromExpr (RangeFromExpr const &other);
// Overload assignment operator to clone unique_ptr
- RangeFromExpr &operator= (RangeFromExpr const &other)
- {
- RangeExpr::operator= (other);
- from = other.from->clone_expr ();
-
- return *this;
- }
+ RangeFromExpr &operator= (RangeFromExpr const &other);
// move constructors
RangeFromExpr (RangeFromExpr &&other) = default;
@@ -2522,7 +2000,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_from_expr () { return from; }
+ Expr &get_from_expr () { return *from; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -2551,23 +2029,13 @@ public:
// outer attributes not allowed
RangeToExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> range_to,
- location_t locus)
- : RangeExpr (std::move (mappings), locus), to (std::move (range_to))
- {}
+ location_t locus);
// Copy constructor with clone
- RangeToExpr (RangeToExpr const &other)
- : RangeExpr (other), to (other.to->clone_expr ())
- {}
+ RangeToExpr (RangeToExpr const &other);
// Overload assignment operator to clone unique_ptr
- RangeToExpr &operator= (RangeToExpr const &other)
- {
- RangeExpr::operator= (other);
- to = other.to->clone_expr ();
-
- return *this;
- }
+ RangeToExpr &operator= (RangeToExpr const &other);
// move constructors
RangeToExpr (RangeToExpr &&other) = default;
@@ -2576,7 +2044,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_to_expr () { return to; }
+ Expr &get_to_expr () { return *to; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -2601,9 +2069,7 @@ class RangeFullExpr : public RangeExpr
public:
std::string as_string () const override;
- RangeFullExpr (Analysis::NodeMapping mappings, location_t locus)
- : RangeExpr (std::move (mappings), locus)
- {}
+ RangeFullExpr (Analysis::NodeMapping mappings, location_t locus);
// outer attributes not allowed
void accept_vis (HIRFullVisitor &vis) override;
@@ -2637,27 +2103,14 @@ public:
RangeFromToInclExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> range_from,
- std::unique_ptr<Expr> range_to, location_t locus)
- : RangeExpr (std::move (mappings), locus), from (std::move (range_from)),
- to (std::move (range_to))
- {}
+ std::unique_ptr<Expr> range_to, location_t locus);
// outer attributes not allowed
// Copy constructor with clone
- RangeFromToInclExpr (RangeFromToInclExpr const &other)
- : RangeExpr (other), from (other.from->clone_expr ()),
- to (other.to->clone_expr ())
- {}
+ RangeFromToInclExpr (RangeFromToInclExpr const &other);
// Overload assignment operator to use clone
- RangeFromToInclExpr &operator= (RangeFromToInclExpr const &other)
- {
- RangeExpr::operator= (other);
- from = other.from->clone_expr ();
- to = other.to->clone_expr ();
-
- return *this;
- }
+ RangeFromToInclExpr &operator= (RangeFromToInclExpr const &other);
// move constructors
RangeFromToInclExpr (RangeFromToInclExpr &&other) = default;
@@ -2666,8 +2119,8 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_from_expr () { return from; }
- std::unique_ptr<Expr> &get_to_expr () { return to; }
+ Expr &get_from_expr () { return *from; }
+ Expr &get_to_expr () { return *to; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -2695,24 +2148,14 @@ public:
std::string as_string () const override;
RangeToInclExpr (Analysis::NodeMapping mappings,
- std::unique_ptr<Expr> range_to, location_t locus)
- : RangeExpr (std::move (mappings), locus), to (std::move (range_to))
- {}
+ std::unique_ptr<Expr> range_to, location_t locus);
// outer attributes not allowed
// Copy constructor with clone
- RangeToInclExpr (RangeToInclExpr const &other)
- : RangeExpr (other), to (other.to->clone_expr ())
- {}
+ RangeToInclExpr (RangeToInclExpr const &other);
// Overload assignment operator to clone pointer
- RangeToInclExpr &operator= (RangeToInclExpr const &other)
- {
- RangeExpr::operator= (other);
- to = other.to->clone_expr ();
-
- return *this;
- }
+ RangeToInclExpr &operator= (RangeToInclExpr const &other);
// move constructors
RangeToInclExpr (RangeToInclExpr &&other) = default;
@@ -2721,7 +2164,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_to_expr () { return to; };
+ Expr &get_to_expr () { return *to; };
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -2756,30 +2199,13 @@ public:
// Constructor for ReturnExpr.
ReturnExpr (Analysis::NodeMapping mappings, location_t locus,
std::unique_ptr<Expr> returned_expr = nullptr,
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- return_expr (std::move (returned_expr)), locus (locus)
- {}
+ AST::AttrVec outer_attribs = AST::AttrVec ());
// Copy constructor with clone
- ReturnExpr (ReturnExpr const &other)
- : ExprWithoutBlock (other), locus (other.locus)
- {
- // guard to protect from null pointer dereference
- if (other.return_expr != nullptr)
- return_expr = other.return_expr->clone_expr ();
- }
+ ReturnExpr (ReturnExpr const &other);
// Overloaded assignment operator to clone return_expr pointer
- ReturnExpr &operator= (ReturnExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- return_expr = other.return_expr->clone_expr ();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ ReturnExpr &operator= (ReturnExpr const &other);
// move constructors
ReturnExpr (ReturnExpr &&other) = default;
@@ -2790,7 +2216,8 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_expr () { return return_expr; }
+ bool has_expr () { return return_expr != nullptr; }
+ Expr &get_expr () { return *return_expr; }
ExprType get_expression_type () const override final
{
@@ -2825,27 +2252,13 @@ public:
UnsafeBlockExpr (Analysis::NodeMapping mappings,
std::unique_ptr<BlockExpr> block_expr,
- AST::AttrVec outer_attribs, location_t locus)
- : ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
- expr (std::move (block_expr)), locus (locus)
- {}
+ AST::AttrVec outer_attribs, location_t locus);
// Copy constructor with clone
- UnsafeBlockExpr (UnsafeBlockExpr const &other)
- : ExprWithBlock (other), expr (other.expr->clone_block_expr ()),
- locus (other.locus)
- {}
+ UnsafeBlockExpr (UnsafeBlockExpr const &other);
// Overloaded assignment operator to clone
- UnsafeBlockExpr &operator= (UnsafeBlockExpr const &other)
- {
- ExprWithBlock::operator= (other);
- expr = other.expr->clone_block_expr ();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ UnsafeBlockExpr &operator= (UnsafeBlockExpr const &other);
// move constructors
UnsafeBlockExpr (UnsafeBlockExpr &&other) = default;
@@ -2856,7 +2269,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<BlockExpr> &get_block_expr () { return expr; }
+ BlockExpr &get_block_expr () { return *expr; }
ExprType get_expression_type () const override final
{
@@ -2883,7 +2296,7 @@ protected:
class BaseLoopExpr : public ExprWithBlock
{
protected:
- LoopLabel loop_label;
+ tl::optional<LoopLabel> loop_label;
std::unique_ptr<BlockExpr> loop_block;
private:
@@ -2893,30 +2306,14 @@ protected:
// Constructor for BaseLoopExpr
BaseLoopExpr (Analysis::NodeMapping mappings,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label,
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
- loop_label (std::move (loop_label)), loop_block (std::move (loop_block)),
- locus (locus)
- {}
+ tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs = AST::AttrVec ());
// Copy constructor for BaseLoopExpr with clone
- BaseLoopExpr (BaseLoopExpr const &other)
- : ExprWithBlock (other), loop_label (other.loop_label),
- loop_block (other.loop_block->clone_block_expr ()), locus (other.locus)
- {}
+ BaseLoopExpr (BaseLoopExpr const &other);
// Overloaded assignment operator to clone
- BaseLoopExpr &operator= (BaseLoopExpr const &other)
- {
- ExprWithBlock::operator= (other);
- loop_block = other.loop_block->clone_block_expr ();
- loop_label = other.loop_label;
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ BaseLoopExpr &operator= (BaseLoopExpr const &other);
// move constructors
BaseLoopExpr (BaseLoopExpr &&other) = default;
@@ -2928,13 +2325,14 @@ protected:
}
public:
- bool has_loop_label () const { return !loop_label.is_error (); }
+ bool has_loop_label () const { return loop_label.has_value (); }
location_t get_locus () const override final { return locus; }
- std::unique_ptr<HIR::BlockExpr> &get_loop_block () { return loop_block; };
+ HIR::BlockExpr &get_loop_block () { return *loop_block; };
- LoopLabel &get_loop_label () { return loop_label; }
+ LoopLabel &get_loop_label () { return loop_label.value (); }
+ const LoopLabel &get_loop_label () const { return loop_label.value (); }
};
// 'Loop' expression (i.e. the infinite loop) HIR node
@@ -2946,10 +2344,8 @@ public:
// Constructor for LoopExpr
LoopExpr (Analysis::NodeMapping mappings,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label, AST::AttrVec outer_attribs = AST::AttrVec ())
- : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
- std::move (loop_label), std::move (outer_attribs))
- {}
+ tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs = AST::AttrVec ());
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
@@ -2979,29 +2375,14 @@ public:
WhileLoopExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> loop_condition,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label,
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
- std::move (loop_label), std::move (outer_attribs)),
- condition (std::move (loop_condition))
- {}
+ tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs = AST::AttrVec ());
// Copy constructor with clone
- WhileLoopExpr (WhileLoopExpr const &other)
- : BaseLoopExpr (other), condition (other.condition->clone_expr ())
- {}
+ WhileLoopExpr (WhileLoopExpr const &other);
// Overloaded assignment operator to clone
- WhileLoopExpr &operator= (WhileLoopExpr const &other)
- {
- BaseLoopExpr::operator= (other);
- condition = other.condition->clone_expr ();
- // loop_block = other.loop_block->clone_block_expr();
- // loop_label = other.loop_label;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ WhileLoopExpr &operator= (WhileLoopExpr const &other);
// move constructors
WhileLoopExpr (WhileLoopExpr &&other) = default;
@@ -3010,7 +2391,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_predicate_expr () { return condition; }
+ Expr &get_predicate_expr () { return *condition; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -3032,7 +2413,7 @@ protected:
class WhileLetLoopExpr : public BaseLoopExpr
{
// MatchArmPatterns patterns;
- std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined
+ std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined
std::unique_ptr<Expr> condition;
public:
@@ -3040,44 +2421,17 @@ public:
// Constructor with a loop label
WhileLetLoopExpr (Analysis::NodeMapping mappings,
- std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
+ std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
std::unique_ptr<Expr> condition,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label,
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
- std::move (loop_label), std::move (outer_attribs)),
- match_arm_patterns (std::move (match_arm_patterns)),
- condition (std::move (condition))
- {}
+ tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs = AST::AttrVec ());
// Copy constructor with clone
- WhileLetLoopExpr (WhileLetLoopExpr const &other)
- : BaseLoopExpr (other),
- /*match_arm_patterns(other.match_arm_patterns),*/ condition (
- other.condition->clone_expr ())
- {
- match_arm_patterns.reserve (other.match_arm_patterns.size ());
- for (const auto &e : other.match_arm_patterns)
- match_arm_patterns.push_back (e->clone_pattern ());
- }
+ WhileLetLoopExpr (WhileLetLoopExpr const &other);
// Overloaded assignment operator to clone pointers
- WhileLetLoopExpr &operator= (WhileLetLoopExpr const &other)
- {
- BaseLoopExpr::operator= (other);
- // match_arm_patterns = other.match_arm_patterns;
- condition = other.condition->clone_expr ();
- // loop_block = other.loop_block->clone_block_expr();
- // loop_label = other.loop_label;
- // outer_attrs = other.outer_attrs;
-
- match_arm_patterns.reserve (other.match_arm_patterns.size ());
- for (const auto &e : other.match_arm_patterns)
- match_arm_patterns.push_back (e->clone_pattern ());
-
- return *this;
- }
+ WhileLetLoopExpr &operator= (WhileLetLoopExpr const &other);
// move constructors
WhileLetLoopExpr (WhileLetLoopExpr &&other) = default;
@@ -3086,8 +2440,8 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_cond () { return condition; }
- std::vector<std::unique_ptr<Pattern> > &get_patterns ()
+ Expr &get_cond () { return *condition; }
+ std::vector<std::unique_ptr<Pattern>> &get_patterns ()
{
return match_arm_patterns;
}
@@ -3108,9 +2462,6 @@ protected:
}
};
-// forward decl for IfExpr
-class IfLetExpr;
-
// Base if expression with no "else" or "if let" HIR node
class IfExpr : public ExprWithBlock
{
@@ -3123,29 +2474,14 @@ public:
std::string as_string () const override;
IfExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> condition,
- std::unique_ptr<BlockExpr> if_block, location_t locus)
- : ExprWithBlock (std::move (mappings), AST::AttrVec ()),
- condition (std::move (condition)), if_block (std::move (if_block)),
- locus (locus)
- {}
+ std::unique_ptr<BlockExpr> if_block, location_t locus);
// outer attributes are never allowed on IfExprs
// Copy constructor with clone
- IfExpr (IfExpr const &other)
- : ExprWithBlock (other), condition (other.condition->clone_expr ()),
- if_block (other.if_block->clone_block_expr ()), locus (other.locus)
- {}
+ IfExpr (IfExpr const &other);
// Overloaded assignment operator to clone expressions
- IfExpr &operator= (IfExpr const &other)
- {
- ExprWithBlock::operator= (other);
- condition = other.condition->clone_expr ();
- if_block = other.if_block->clone_block_expr ();
- locus = other.locus;
-
- return *this;
- }
+ IfExpr &operator= (IfExpr const &other);
// move constructors
IfExpr (IfExpr &&other) = default;
@@ -3169,8 +2505,8 @@ public:
void vis_if_condition (HIRFullVisitor &vis) { condition->accept_vis (vis); }
void vis_if_block (HIRFullVisitor &vis) { if_block->accept_vis (vis); }
- std::unique_ptr<Expr> &get_if_condition () { return condition; }
- std::unique_ptr<BlockExpr> &get_if_block () { return if_block; }
+ Expr &get_if_condition () { return *condition; }
+ BlockExpr &get_if_block () { return *if_block; }
ExprType get_expression_type () const final override { return ExprType::If; }
@@ -3201,28 +2537,15 @@ public:
IfExprConseqElse (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> condition,
std::unique_ptr<BlockExpr> if_block,
- std::unique_ptr<ExprWithBlock> else_block, location_t locus)
- : IfExpr (std::move (mappings), std::move (condition), std::move (if_block),
- locus),
- else_block (std::move (else_block))
- {}
+ std::unique_ptr<ExprWithBlock> else_block,
+ location_t locus);
// again, outer attributes not allowed
// Copy constructor with clone
- IfExprConseqElse (IfExprConseqElse const &other)
- : IfExpr (other), else_block (other.else_block->clone_expr_with_block ())
- {}
+ IfExprConseqElse (IfExprConseqElse const &other);
// Overloaded assignment operator with cloning
- IfExprConseqElse &operator= (IfExprConseqElse const &other)
- {
- IfExpr::operator= (other);
- // condition = other.condition->clone_expr();
- // if_block = other.if_block->clone_block_expr();
- else_block = other.else_block->clone_expr_with_block ();
-
- return *this;
- }
+ IfExprConseqElse &operator= (IfExprConseqElse const &other);
// move constructors
IfExprConseqElse (IfExprConseqElse &&other) = default;
@@ -3233,7 +2556,7 @@ public:
void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); }
- std::unique_ptr<ExprWithBlock> &get_else_block () { return else_block; }
+ ExprWithBlock &get_else_block () { return *else_block; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -3258,183 +2581,12 @@ protected:
}
};
-// Basic "if let" expression HIR node with no else
-class IfLetExpr : public ExprWithBlock
-{
- // MatchArmPatterns patterns;
- std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined
- std::unique_ptr<Expr> value;
- std::unique_ptr<BlockExpr> if_block;
-
- location_t locus;
-
-public:
- std::string as_string () const override;
-
- IfLetExpr (Analysis::NodeMapping mappings,
- std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
- std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block,
- location_t locus)
- : ExprWithBlock (std::move (mappings), AST::AttrVec ()),
- match_arm_patterns (std::move (match_arm_patterns)),
- value (std::move (value)), if_block (std::move (if_block)), locus (locus)
- {}
- // outer attributes not allowed on if let exprs either
-
- // copy constructor with clone
- IfLetExpr (IfLetExpr const &other)
- : ExprWithBlock (other),
- /*match_arm_patterns(other.match_arm_patterns),*/ value (
- other.value->clone_expr ()),
- if_block (other.if_block->clone_block_expr ()), locus (other.locus)
- {
- match_arm_patterns.reserve (other.match_arm_patterns.size ());
- for (const auto &e : other.match_arm_patterns)
- match_arm_patterns.push_back (e->clone_pattern ());
- }
-
- // overload assignment operator to clone
- IfLetExpr &operator= (IfLetExpr const &other)
- {
- ExprWithBlock::operator= (other);
- // match_arm_patterns = other.match_arm_patterns;
- value = other.value->clone_expr ();
- if_block = other.if_block->clone_block_expr ();
- locus = other.locus;
-
- match_arm_patterns.reserve (other.match_arm_patterns.size ());
- for (const auto &e : other.match_arm_patterns)
- match_arm_patterns.push_back (e->clone_pattern ());
-
- return *this;
- }
-
- // move constructors
- IfLetExpr (IfLetExpr &&other) = default;
- IfLetExpr &operator= (IfLetExpr &&other) = default;
-
- // Unique pointer custom clone function
- std::unique_ptr<IfLetExpr> clone_if_let_expr () const
- {
- return std::unique_ptr<IfLetExpr> (clone_if_let_expr_impl ());
- }
-
- location_t get_locus () const override final { return locus; }
-
- void accept_vis (HIRFullVisitor &vis) override;
- void accept_vis (HIRExpressionVisitor &vis) override;
-
- std::unique_ptr<Expr> &get_scrutinee_expr () { return value; }
-
- std::vector<std::unique_ptr<Pattern> > &get_patterns ()
- {
- return match_arm_patterns;
- }
-
- std::unique_ptr<BlockExpr> &get_if_block () { return if_block; }
-
- ExprType get_expression_type () const final override
- {
- return ExprType::IfLet;
- }
-
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExpr *clone_expr_impl () const override { return new IfLetExpr (*this); }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExpr *clone_expr_with_block_impl () const override
- {
- return new IfLetExpr (*this);
- }
-
- // Base clone function but still concrete as concrete base class
- virtual IfLetExpr *clone_if_let_expr_impl () const
- {
- return new IfLetExpr (*this);
- }
-};
-
-/* HIR node representing "if let" expression with an "else" expression at the
- * end */
-class IfLetExprConseqElse : public IfLetExpr
-{
- std::unique_ptr<ExprWithBlock> else_block;
-
-public:
- std::string as_string () const override;
-
- IfLetExprConseqElse (
- Analysis::NodeMapping mappings,
- std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
- std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block,
- std::unique_ptr<ExprWithBlock> else_block, location_t locus)
- : IfLetExpr (std::move (mappings), std::move (match_arm_patterns),
- std::move (value), std::move (if_block), locus),
- else_block (std::move (else_block))
- {}
- // outer attributes not allowed
-
- // copy constructor with clone
- IfLetExprConseqElse (IfLetExprConseqElse const &other)
- : IfLetExpr (other), else_block (other.else_block->clone_expr_with_block ())
- {}
-
- // overload assignment operator to clone
- IfLetExprConseqElse &operator= (IfLetExprConseqElse const &other)
- {
- IfLetExpr::operator= (other);
- // match_arm_patterns = other.match_arm_patterns;
- // value = other.value->clone_expr();
- // if_block = other.if_block->clone_block_expr();
- else_block = other.else_block->clone_expr_with_block ();
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- IfLetExprConseqElse (IfLetExprConseqElse &&other) = default;
- IfLetExprConseqElse &operator= (IfLetExprConseqElse &&other) = default;
-
- void accept_vis (HIRFullVisitor &vis) override;
- void accept_vis (HIRExpressionVisitor &vis) override;
-
- void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); }
-
- std::unique_ptr<ExprWithBlock> &get_else_block () { return else_block; }
-
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExprConseqElse *clone_expr_impl () const override
- {
- return new IfLetExprConseqElse (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExprConseqElse *clone_expr_with_block_impl () const override
- {
- return new IfLetExprConseqElse (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExprConseqElse *clone_if_let_expr_impl () const override
- {
- return new IfLetExprConseqElse (*this);
- }
-};
-
// Match arm expression
struct MatchArm
{
private:
AST::AttrVec outer_attrs;
- std::vector<std::unique_ptr<Pattern> > match_arm_patterns;
+ std::vector<std::unique_ptr<Pattern>> match_arm_patterns;
std::unique_ptr<Expr> guard_expr;
location_t locus;
@@ -3443,45 +2595,17 @@ public:
bool has_match_arm_guard () const { return guard_expr != nullptr; }
// Constructor for match arm with a guard expression
- MatchArm (std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
+ MatchArm (std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
location_t locus, std::unique_ptr<Expr> guard_expr = nullptr,
- AST::AttrVec outer_attrs = AST::AttrVec ())
- : outer_attrs (std::move (outer_attrs)),
- match_arm_patterns (std::move (match_arm_patterns)),
- guard_expr (std::move (guard_expr)), locus (locus)
- {}
+ AST::AttrVec outer_attrs = AST::AttrVec ());
// Copy constructor with clone
- MatchArm (MatchArm const &other) : outer_attrs (other.outer_attrs)
- {
- // guard to protect from null pointer dereference
- if (other.guard_expr != nullptr)
- guard_expr = other.guard_expr->clone_expr ();
-
- match_arm_patterns.reserve (other.match_arm_patterns.size ());
- for (const auto &e : other.match_arm_patterns)
- match_arm_patterns.push_back (e->clone_pattern ());
-
- locus = other.locus;
- }
+ MatchArm (MatchArm const &other);
~MatchArm () = default;
// Overload assignment operator to clone
- MatchArm &operator= (MatchArm const &other)
- {
- outer_attrs = other.outer_attrs;
-
- if (other.guard_expr != nullptr)
- guard_expr = other.guard_expr->clone_expr ();
-
- match_arm_patterns.clear ();
- match_arm_patterns.reserve (other.match_arm_patterns.size ());
- for (const auto &e : other.match_arm_patterns)
- match_arm_patterns.push_back (e->clone_pattern ());
-
- return *this;
- }
+ MatchArm &operator= (MatchArm const &other);
// move constructors
MatchArm (MatchArm &&other) = default;
@@ -3494,17 +2618,17 @@ public:
static MatchArm create_error ()
{
location_t locus = UNDEF_LOCATION;
- return MatchArm (std::vector<std::unique_ptr<Pattern> > (), locus);
+ return MatchArm (std::vector<std::unique_ptr<Pattern>> (), locus);
}
std::string as_string () const;
- std::vector<std::unique_ptr<Pattern> > &get_patterns ()
+ std::vector<std::unique_ptr<Pattern>> &get_patterns ()
{
return match_arm_patterns;
}
- std::unique_ptr<Expr> &get_guard_expr () { return guard_expr; }
+ Expr &get_guard_expr () { return *guard_expr; }
location_t get_locus () const { return locus; }
};
@@ -3520,23 +2644,11 @@ private:
public:
MatchCase (Analysis::NodeMapping mappings, MatchArm arm,
- std::unique_ptr<Expr> expr)
- : mappings (mappings), arm (std::move (arm)), expr (std::move (expr))
- {}
+ std::unique_ptr<Expr> expr);
- MatchCase (const MatchCase &other)
- : mappings (other.mappings), arm (other.arm),
- expr (other.expr->clone_expr ())
- {}
+ MatchCase (const MatchCase &other);
- MatchCase &operator= (const MatchCase &other)
- {
- mappings = other.mappings;
- arm = other.arm;
- expr = other.expr->clone_expr ();
-
- return *this;
- }
+ MatchCase &operator= (const MatchCase &other);
MatchCase (MatchCase &&other) = default;
MatchCase &operator= (MatchCase &&other) = default;
@@ -3548,7 +2660,7 @@ public:
Analysis::NodeMapping get_mappings () const { return mappings; }
MatchArm &get_arm () { return arm; }
- std::unique_ptr<Expr> &get_expr () { return expr; }
+ Expr &get_expr () { return *expr; }
};
// Match expression HIR node
@@ -3565,40 +2677,13 @@ public:
MatchExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> branch_value,
std::vector<MatchCase> match_arms, AST::AttrVec inner_attrs,
- AST::AttrVec outer_attrs, location_t locus)
- : ExprWithBlock (std::move (mappings), std::move (outer_attrs)),
- WithInnerAttrs (std::move (inner_attrs)),
- branch_value (std::move (branch_value)),
- match_arms (std::move (match_arms)), locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// Copy constructor requires clone due to unique_ptr
- MatchExpr (MatchExpr const &other)
- : ExprWithBlock (other), WithInnerAttrs (other.inner_attrs),
- branch_value (other.branch_value->clone_expr ()),
- match_arms (other.match_arms), locus (other.locus)
- {
- /*match_arms.reserve (other.match_arms.size ());
- for (const auto &e : other.match_arms)
- match_arms.push_back (e->clone_match_case ());*/
- }
+ MatchExpr (MatchExpr const &other);
// Overloaded assignment operator to clone due to unique_ptr
- MatchExpr &operator= (MatchExpr const &other)
- {
- ExprWithBlock::operator= (other);
- branch_value = other.branch_value->clone_expr ();
- inner_attrs = other.inner_attrs;
- match_arms = other.match_arms;
- // outer_attrs = other.outer_attrs;
- locus = other.locus;
-
- /*match_arms.reserve (other.match_arms.size ());
- for (const auto &e : other.match_arms)
- match_arms.push_back (e->clone_match_case ());*/
-
- return *this;
- }
+ MatchExpr &operator= (MatchExpr const &other);
// move constructors
MatchExpr (MatchExpr &&other) = default;
@@ -3609,7 +2694,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_scrutinee_expr () { return branch_value; }
+ Expr &get_scrutinee_expr () { return *branch_value; }
AST::AttrVec get_inner_attrs () const { return inner_attrs; }
const std::vector<MatchCase> &get_match_cases () const { return match_arms; }
std::vector<MatchCase> &get_match_cases () { return match_arms; }
@@ -3641,26 +2726,13 @@ class AwaitExpr : public ExprWithoutBlock
public:
// TODO: ensure outer attributes are actually allowed
AwaitExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> awaited_expr,
- AST::AttrVec outer_attrs, location_t locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
- awaited_expr (std::move (awaited_expr)), locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// copy constructor with clone
- AwaitExpr (AwaitExpr const &other)
- : ExprWithoutBlock (other),
- awaited_expr (other.awaited_expr->clone_expr ()), locus (other.locus)
- {}
+ AwaitExpr (AwaitExpr const &other);
// overloaded assignment operator with clone
- AwaitExpr &operator= (AwaitExpr const &other)
- {
- ExprWithoutBlock::operator= (other);
- awaited_expr = other.awaited_expr->clone_expr ();
- locus = other.locus;
-
- return *this;
- }
+ AwaitExpr &operator= (AwaitExpr const &other);
// move constructors
AwaitExpr (AwaitExpr &&other) = default;
@@ -3673,7 +2745,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- std::unique_ptr<Expr> &get_awaited_expr () { return awaited_expr; }
+ Expr &get_awaited_expr () { return *awaited_expr; }
ExprType get_expression_type () const final override
{
@@ -3699,27 +2771,13 @@ class AsyncBlockExpr : public ExprWithBlock
public:
AsyncBlockExpr (Analysis::NodeMapping mappings,
std::unique_ptr<BlockExpr> block_expr, bool has_move,
- AST::AttrVec outer_attrs, location_t locus)
- : ExprWithBlock (std::move (mappings), std::move (outer_attrs)),
- has_move (has_move), block_expr (std::move (block_expr)), locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// copy constructor with clone
- AsyncBlockExpr (AsyncBlockExpr const &other)
- : ExprWithBlock (other), has_move (other.has_move),
- block_expr (other.block_expr->clone_block_expr ()), locus (other.locus)
- {}
+ AsyncBlockExpr (AsyncBlockExpr const &other);
// overloaded assignment operator to clone
- AsyncBlockExpr &operator= (AsyncBlockExpr const &other)
- {
- ExprWithBlock::operator= (other);
- has_move = other.has_move;
- block_expr = other.block_expr->clone_block_expr ();
- locus = other.locus;
-
- return *this;
- }
+ AsyncBlockExpr &operator= (AsyncBlockExpr const &other);
// move constructors
AsyncBlockExpr (AsyncBlockExpr &&other) = default;
@@ -3730,7 +2788,7 @@ public:
location_t get_locus () const override final { return locus; }
bool get_has_move () const { return has_move; }
- std::unique_ptr<BlockExpr> &get_block_expr () { return block_expr; }
+ BlockExpr &get_block_expr () { return *block_expr; }
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
@@ -3753,35 +2811,17 @@ protected:
class OperatorExprMeta
{
public:
- OperatorExprMeta (HIR::CompoundAssignmentExpr &expr)
- : node_mappings (expr.get_mappings ()),
- lvalue_mappings (expr.get_expr ()->get_mappings ()),
- locus (expr.get_locus ())
- {}
+ OperatorExprMeta (HIR::CompoundAssignmentExpr &expr);
- OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr)
- : node_mappings (expr.get_mappings ()),
- lvalue_mappings (expr.get_expr ()->get_mappings ()),
- locus (expr.get_locus ())
- {}
+ OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr);
- OperatorExprMeta (HIR::NegationExpr &expr)
- : node_mappings (expr.get_mappings ()),
- lvalue_mappings (expr.get_expr ()->get_mappings ()),
- locus (expr.get_locus ())
- {}
+ OperatorExprMeta (HIR::NegationExpr &expr);
- OperatorExprMeta (HIR::DereferenceExpr &expr)
- : node_mappings (expr.get_mappings ()),
- lvalue_mappings (expr.get_expr ()->get_mappings ()),
- locus (expr.get_locus ())
- {}
+ OperatorExprMeta (HIR::DereferenceExpr &expr);
- OperatorExprMeta (HIR::ArrayIndexExpr &expr)
- : node_mappings (expr.get_mappings ()),
- lvalue_mappings (expr.get_array_expr ()->get_mappings ()),
- locus (expr.get_locus ())
- {}
+ OperatorExprMeta (HIR::ArrayIndexExpr &expr);
+
+ OperatorExprMeta (HIR::ComparisonExpr &expr);
const Analysis::NodeMapping &get_mappings () const { return node_mappings; }
@@ -3856,25 +2896,13 @@ 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;
- }
+ AnonConst (NodeId id, std::unique_ptr<Expr> expr);
+
+ AnonConst (const AnonConst &other);
+
+ AnonConst operator= (const AnonConst &other);
};
-;
class InlineAsmOperand
{
@@ -3885,26 +2913,11 @@ public:
std::unique_ptr<Expr> expr;
In (const tl::optional<struct AST::InlineAsmRegOrRegClass> &reg,
- std::unique_ptr<Expr> expr)
- : reg (reg), expr (std::move (expr))
- {
- rust_assert (this->expr != nullptr);
- }
-
- In (const struct In &other)
- {
- reg = other.reg;
-
- expr = other.expr->clone_expr ();
- }
-
- In operator= (const struct In &other)
- {
- reg = other.reg;
- expr = other.expr->clone_expr ();
-
- return *this;
- }
+ std::unique_ptr<Expr> expr);
+
+ In (const struct In &other);
+
+ In operator= (const struct In &other);
};
struct Out
@@ -3914,26 +2927,11 @@ public:
std::unique_ptr<Expr> expr; // can be null
Out (tl::optional<struct AST::InlineAsmRegOrRegClass> &reg, bool late,
- std::unique_ptr<Expr> expr)
- : reg (reg), late (late), expr (std::move (expr))
- {
- rust_assert (this->expr != nullptr);
- }
-
- Out (const struct Out &other)
- {
- reg = other.reg;
- late = other.late;
- expr = other.expr->clone_expr ();
- }
-
- Out operator= (const struct Out &other)
- {
- reg = other.reg;
- late = other.late;
- expr = other.expr->clone_expr ();
- return *this;
- }
+ std::unique_ptr<Expr> expr);
+
+ Out (const struct Out &other);
+
+ Out operator= (const struct Out &other);
};
struct InOut
@@ -3943,27 +2941,11 @@ public:
std::unique_ptr<Expr> expr; // this can't be null
InOut (tl::optional<struct AST::InlineAsmRegOrRegClass> &reg, bool late,
- std::unique_ptr<Expr> expr)
- : reg (reg), late (late), expr (std::move (expr))
- {
- rust_assert (this->expr != nullptr);
- }
-
- InOut (const struct InOut &other)
- {
- reg = other.reg;
- late = other.late;
- expr = other.expr->clone_expr ();
- }
-
- InOut operator= (const struct InOut &other)
- {
- reg = other.reg;
- late = other.late;
- expr = other.expr->clone_expr ();
-
- return *this;
- }
+ std::unique_ptr<Expr> expr);
+
+ InOut (const struct InOut &other);
+
+ InOut operator= (const struct InOut &other);
};
struct SplitInOut
@@ -3975,31 +2957,11 @@ public:
SplitInOut (tl::optional<struct AST::InlineAsmRegOrRegClass> &reg,
bool late, std::unique_ptr<Expr> in_expr,
- std::unique_ptr<Expr> out_expr)
- : reg (reg), late (late), in_expr (std::move (in_expr)),
- out_expr (std::move (out_expr))
- {
- rust_assert (this->in_expr != nullptr);
- rust_assert (this->out_expr != nullptr);
- }
-
- SplitInOut (const struct SplitInOut &other)
- {
- reg = other.reg;
- late = other.late;
- in_expr = other.in_expr->clone_expr ();
- out_expr = other.out_expr->clone_expr ();
- }
-
- SplitInOut operator= (const struct SplitInOut &other)
- {
- reg = other.reg;
- late = other.late;
- in_expr = other.in_expr->clone_expr ();
- out_expr = other.out_expr->clone_expr ();
-
- return *this;
- }
+ std::unique_ptr<Expr> out_expr);
+
+ SplitInOut (const struct SplitInOut &other);
+
+ SplitInOut operator= (const struct SplitInOut &other);
};
struct Const
@@ -4011,20 +2973,11 @@ public:
{
std::unique_ptr<Expr> expr;
- Sym (std::unique_ptr<Expr> expr) : expr (std::move (expr))
- {
- rust_assert (this->expr != nullptr);
- }
- Sym (const struct Sym &other)
- {
- expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
- }
-
- Sym operator= (const struct Sym &other)
- {
- expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
- return *this;
- }
+ Sym (std::unique_ptr<Expr> expr);
+
+ Sym (const struct Sym &other);
+
+ Sym operator= (const struct Sym &other);
};
struct Label
@@ -4032,23 +2985,11 @@ public:
std::string label_name;
std::unique_ptr<Expr> expr;
- Label (tl::optional<std::string> label_name, std::unique_ptr<Expr> expr)
- : expr (std::move (expr))
- {
- rust_assert (this->expr != nullptr);
- if (label_name.has_value ())
- this->label_name = label_name.value ();
- }
- Label (const struct Label &other)
- {
- expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
- }
-
- Label operator= (const struct Label &other)
- {
- expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
- return *this;
- }
+ Label (tl::optional<std::string> label_name, std::unique_ptr<Expr> expr);
+
+ Label (const struct Label &other);
+
+ Label operator= (const struct Label &other);
};
private:
@@ -4062,7 +3003,6 @@ private:
tl::optional<struct Const> cnst;
tl::optional<struct Sym> sym;
tl::optional<struct Label> label;
- location_t locus;
public:
InlineAsmOperand (const InlineAsmOperand &other)
@@ -4105,6 +3045,7 @@ public:
struct Sym get_sym () const { return sym.value (); }
struct Label get_label () const { return label.value (); }
};
+
// Inline Assembly Node
class InlineAsm : public ExprWithoutBlock
{
@@ -4166,6 +3107,7 @@ public:
// INFO: An inline asm is asm!, which is the opposite of a global_asm()
return !this->is_global_asm;
}
+
InlineAsm (location_t locus, bool is_global_asm,
std::vector<AST::InlineAsmTemplatePiece> template_,
std::vector<AST::TupleTemplateStr> template_strs,
@@ -4173,16 +3115,83 @@ public:
std::vector<AST::TupleClobber> clobber_abi,
std::set<AST::InlineAsmOption> options,
Analysis::NodeMapping mappings,
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
- locus (locus), is_global_asm (is_global_asm),
- template_ (std::move (template_)),
- template_strs (std::move (template_strs)),
- operands (std::move (operands)), clobber_abi (std::move (clobber_abi)),
- options (std::move (options))
+ AST::AttrVec outer_attribs = AST::AttrVec ());
+};
+
+struct LlvmOperand
+{
+ std::string constraint;
+ std::unique_ptr<Expr> expr;
+
+ LlvmOperand (std::string constraint, std::unique_ptr<Expr> &&expr)
+ : constraint (constraint), expr (std::move (expr))
+ {}
+
+ LlvmOperand (const LlvmOperand &other)
+ : constraint (other.constraint), expr (other.expr->clone_expr ())
+ {}
+ LlvmOperand &operator= (const LlvmOperand &other)
+ {
+ constraint = other.constraint;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+ }
+};
+class LlvmInlineAsm : public ExprWithoutBlock
+{
+public:
+ struct Options
+ {
+ bool is_volatile;
+ bool align_stack;
+ AST::LlvmInlineAsm::Dialect dialect;
+ };
+
+ location_t locus;
+ AST::AttrVec outer_attrs;
+ std::vector<LlvmOperand> inputs;
+ std::vector<LlvmOperand> outputs;
+ std::vector<AST::TupleTemplateStr> templates;
+ std::vector<AST::TupleClobber> clobbers;
+ Options options;
+
+ LlvmInlineAsm (location_t locus, std::vector<LlvmOperand> inputs,
+ std::vector<LlvmOperand> outputs,
+ std::vector<AST::TupleTemplateStr> templates,
+ std::vector<AST::TupleClobber> clobbers, Options options,
+ AST::AttrVec outer_attrs, Analysis::NodeMapping mappings)
+ : ExprWithoutBlock (mappings, std::move (outer_attrs)), locus (locus),
+ inputs (std::move (inputs)), outputs (std::move (outputs)),
+ templates (std::move (templates)), clobbers (std::move (clobbers)),
+ options (options)
{}
+
+ AST::LlvmInlineAsm::Dialect get_dialect () { return options.dialect; }
+
+ location_t get_locus () const override { return locus; }
+
+ std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
+
+ void accept_vis (HIRFullVisitor &vis) override;
+ void accept_vis (HIRExpressionVisitor &vis) override;
+
+ LlvmInlineAsm *clone_expr_without_block_impl () const override
+ {
+ return new LlvmInlineAsm (*this);
+ }
+
+ std::vector<AST::TupleTemplateStr> &get_templates () { return templates; }
+
+ Expr::ExprType get_expression_type () const override
+ {
+ return Expr::ExprType::LlvmInlineAsm;
+ }
+
+ std::vector<AST::TupleClobber> get_clobbers () { return clobbers; }
};
+
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 64be7bf..1e313ec 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -113,8 +113,6 @@ class WhileLoopExpr;
class WhileLetLoopExpr;
class IfExpr;
class IfExprConseqElse;
-class IfLetExpr;
-class IfLetExprConseqElse;
struct MatchArm;
// class MatchCase;
// class MatchCaseBlockExpr;
@@ -128,6 +126,7 @@ class InlineAsmRegClass;
struct AnonConst;
class InlineAsmOperand;
class InlineAsm;
+class LlvmInlineAsm;
// rust-stmt.h
class EmptyStmt;
@@ -213,7 +212,6 @@ class TraitBound;
class ImplTraitType;
class TraitObjectType;
class ParenthesisedType;
-class ImplTraitTypeOneBound;
class TupleType;
class NeverType;
class RawPointerType;
diff --git a/gcc/rust/hir/tree/rust-hir-generic-param.cc b/gcc/rust/hir/tree/rust-hir-generic-param.cc
new file mode 100644
index 0000000..e5afa8e
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-generic-param.cc
@@ -0,0 +1,95 @@
+// Copyright (C) 2020-2024 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-hir-generic-param.h"
+
+namespace Rust {
+namespace HIR {
+
+GenericParam::GenericParam (Analysis::NodeMapping mapping,
+ enum GenericKind kind)
+ : mappings (mapping), kind (kind)
+{}
+
+LifetimeParam::LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime,
+ location_t locus,
+ std::vector<Lifetime> lifetime_bounds,
+ AST::AttrVec outer_attrs)
+ : GenericParam (mappings, GenericKind::LIFETIME),
+ lifetime (std::move (lifetime)),
+ lifetime_bounds (std::move (lifetime_bounds)),
+ outer_attrs (std::move (outer_attrs)), locus (locus)
+{}
+
+LifetimeParam::LifetimeParam (LifetimeParam const &other)
+ : GenericParam (other.mappings, GenericKind::LIFETIME),
+ lifetime (other.lifetime), lifetime_bounds (other.lifetime_bounds),
+ outer_attrs (other.outer_attrs), locus (other.locus)
+{}
+
+LifetimeParam &
+LifetimeParam::operator= (LifetimeParam const &other)
+{
+ lifetime = other.lifetime;
+ lifetime_bounds = other.lifetime_bounds;
+ outer_attrs = other.outer_attrs;
+ locus = other.locus;
+ mappings = other.mappings;
+
+ return *this;
+}
+
+ConstGenericParam::ConstGenericParam (std::string name,
+ std::unique_ptr<Type> type,
+ std::unique_ptr<Expr> default_expression,
+ Analysis::NodeMapping mapping,
+ location_t locus)
+ : GenericParam (mapping, GenericKind::CONST), name (std::move (name)),
+ type (std::move (type)),
+ default_expression (std::move (default_expression)), locus (locus)
+{}
+
+ConstGenericParam::ConstGenericParam (const ConstGenericParam &other)
+ : GenericParam (other)
+{
+ name = other.name;
+ locus = other.locus;
+
+ if (other.type)
+ type = other.type->clone_type ();
+ if (other.default_expression)
+ default_expression = other.default_expression->clone_expr ();
+}
+
+std::string
+ConstGenericParam::as_string () const
+{
+ auto result = "ConstGenericParam: " + name + " : " + type->as_string ();
+
+ if (default_expression)
+ result += " = " + default_expression->as_string ();
+
+ return result;
+}
+
+void
+ConstGenericParam::accept_vis (HIRFullVisitor &)
+{}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-generic-param.h b/gcc/rust/hir/tree/rust-hir-generic-param.h
new file mode 100644
index 0000000..960de56
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-generic-param.h
@@ -0,0 +1,187 @@
+
+// Copyright (C) 2020-2024 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_HIR_GENERIC_PARAM_H
+#define RUST_HIR_GENERIC_PARAM_H
+
+#include "rust-hir-visitable.h"
+#include "rust-hir-bound.h"
+
+namespace Rust {
+namespace HIR {
+
+/* Base generic parameter in HIR. Abstract - can be represented by a Lifetime or
+ * Type param */
+class GenericParam : public FullVisitable
+{
+public:
+ using FullVisitable::accept_vis;
+
+ virtual ~GenericParam () {}
+
+ enum class GenericKind
+ {
+ TYPE,
+ LIFETIME,
+ CONST,
+ };
+
+ virtual AST::AttrVec &get_outer_attrs () = 0;
+ virtual bool has_outer_attribute () const = 0;
+
+ // Unique pointer custom clone function
+ std::unique_ptr<GenericParam> clone_generic_param () const
+ {
+ return std::unique_ptr<GenericParam> (clone_generic_param_impl ());
+ }
+
+ virtual std::string as_string () const = 0;
+
+ virtual location_t get_locus () const = 0;
+
+ Analysis::NodeMapping get_mappings () const { return mappings; }
+
+ enum GenericKind get_kind () const { return kind; }
+
+protected:
+ // Clone function implementation as pure virtual method
+ virtual GenericParam *clone_generic_param_impl () const = 0;
+
+ Analysis::NodeMapping mappings;
+
+ enum GenericKind kind;
+
+ GenericParam (Analysis::NodeMapping mapping,
+ enum GenericKind kind = GenericKind::TYPE);
+};
+
+// A lifetime generic parameter (as opposed to a type generic parameter)
+class LifetimeParam : public GenericParam
+{
+ Lifetime lifetime;
+
+ // bool has_lifetime_bounds;
+ // LifetimeBounds lifetime_bounds;
+ std::vector<Lifetime> lifetime_bounds; // inlined LifetimeBounds
+
+ AST::AttrVec outer_attrs;
+
+ location_t locus;
+
+public:
+ Lifetime get_lifetime () { return lifetime; }
+
+ // Returns whether the lifetime param has any lifetime bounds.
+ bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
+
+ std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
+
+ // Returns whether the lifetime param has an outer attribute.
+ bool has_outer_attribute () const override { return outer_attrs.size () > 1; }
+
+ AST::AttrVec &get_outer_attrs () override { return outer_attrs; }
+
+ // Constructor
+ LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime,
+ location_t locus = UNDEF_LOCATION,
+ std::vector<Lifetime> lifetime_bounds
+ = std::vector<Lifetime> (),
+ AST::AttrVec outer_attrs = std::vector<AST::Attribute> ());
+
+ // TODO: remove copy and assignment operator definitions - not required
+
+ // Copy constructor with clone
+ LifetimeParam (LifetimeParam const &other);
+
+ // Overloaded assignment operator to clone attribute
+ LifetimeParam &operator= (LifetimeParam const &other);
+
+ // move constructors
+ LifetimeParam (LifetimeParam &&other) = default;
+ LifetimeParam &operator= (LifetimeParam &&other) = default;
+
+ std::string as_string () const override;
+
+ void accept_vis (HIRFullVisitor &vis) override;
+
+ location_t get_locus () const override final { return locus; }
+
+protected:
+ /* Use covariance to implement clone function as returning this object rather
+ * than base */
+ LifetimeParam *clone_generic_param_impl () const override
+ {
+ return new LifetimeParam (*this);
+ }
+};
+
+class ConstGenericParam : public GenericParam
+{
+public:
+ ConstGenericParam (std::string name, std::unique_ptr<Type> type,
+ std::unique_ptr<Expr> default_expression,
+ Analysis::NodeMapping mapping, location_t locus);
+
+ ConstGenericParam (const ConstGenericParam &other);
+
+ bool has_outer_attribute () const override { return false; }
+
+ AST::AttrVec &get_outer_attrs () override { return outer_attrs; }
+
+ std::string as_string () const override final;
+
+ void accept_vis (HIRFullVisitor &vis) override final;
+
+ location_t get_locus () const override final { return locus; };
+
+ bool has_default_expression () { return default_expression != nullptr; }
+
+ std::string get_name () { return name; }
+ Type &get_type ()
+ {
+ rust_assert (type);
+ return *type;
+ }
+ Expr &get_default_expression () { return *default_expression; }
+
+protected:
+ /* Use covariance to implement clone function as returning this object rather
+ * than base */
+ ConstGenericParam *clone_generic_param_impl () const override
+ {
+ return new ConstGenericParam (*this);
+ }
+
+private:
+ std::string name;
+ std::unique_ptr<Type> type;
+
+ /* const params have no outer attrs, should be empty */
+ AST::AttrVec outer_attrs = std::vector<AST::Attribute> ();
+
+ /* Optional - can be a null pointer if there is no default expression */
+ std::unique_ptr<Expr> default_expression;
+
+ location_t locus;
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-item.cc b/gcc/rust/hir/tree/rust-hir-item.cc
new file mode 100644
index 0000000..160f710
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-item.cc
@@ -0,0 +1,1024 @@
+// Copyright (C) 2020-2024 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-hir-item.h"
+#include "optional.h"
+
+namespace Rust {
+namespace HIR {
+
+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)
+ : 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)
+{}
+
+TypeParam::TypeParam (TypeParam const &other)
+ : GenericParam (other.mappings), outer_attrs (other.outer_attrs),
+ type_representation (other.type_representation), locus (other.locus)
+{
+ // guard to prevent null pointer dereference
+ if (other.has_type ())
+ type = {other.type.value ()->clone_type ()};
+ else
+ type = tl::nullopt;
+
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+}
+
+TypeParam &
+TypeParam::operator= (TypeParam const &other)
+{
+ type_representation = other.type_representation;
+ outer_attrs = other.outer_attrs;
+ locus = other.locus;
+ mappings = other.mappings;
+
+ // guard to prevent null pointer dereference
+ if (other.has_type ())
+ type = {other.type.value ()->clone_type ()};
+ else
+ type = tl::nullopt;
+
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+
+ return *this;
+}
+
+Analysis::NodeMapping
+TypeParam::get_type_mappings () const
+{
+ rust_assert (type.has_value ());
+ return type.value ()->get_mappings ();
+}
+
+std::vector<std::unique_ptr<TypeParamBound>> &
+TypeParam::get_type_param_bounds ()
+{
+ return type_param_bounds;
+}
+
+TypeBoundWhereClauseItem::TypeBoundWhereClauseItem (
+ Analysis::NodeMapping mappings, std::vector<LifetimeParam> for_lifetimes,
+ std::unique_ptr<Type> bound_type,
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
+ location_t locus)
+ : for_lifetimes (std::move (for_lifetimes)),
+ bound_type (std::move (bound_type)),
+ type_param_bounds (std::move (type_param_bounds)),
+ mappings (std::move (mappings)), locus (locus)
+{}
+
+TypeBoundWhereClauseItem::TypeBoundWhereClauseItem (
+ TypeBoundWhereClauseItem const &other)
+ : for_lifetimes (other.for_lifetimes),
+ bound_type (other.bound_type->clone_type ()), mappings (other.mappings)
+{
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+}
+
+TypeBoundWhereClauseItem &
+TypeBoundWhereClauseItem::operator= (TypeBoundWhereClauseItem const &other)
+{
+ mappings = other.mappings;
+ for_lifetimes = other.for_lifetimes;
+ bound_type = other.bound_type->clone_type ();
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+
+ return *this;
+}
+
+std::vector<std::unique_ptr<TypeParamBound>> &
+TypeBoundWhereClauseItem::get_type_param_bounds ()
+{
+ return type_param_bounds;
+}
+
+SelfParam::SelfParam (Analysis::NodeMapping mappings,
+ ImplicitSelfKind self_kind,
+ tl::optional<Lifetime> lifetime, Type *type)
+ : self_kind (self_kind), lifetime (std::move (lifetime)), type (type),
+ mappings (mappings)
+{}
+
+SelfParam::SelfParam (Analysis::NodeMapping mappings,
+ std::unique_ptr<Type> type, bool is_mut, location_t locus)
+ : self_kind (is_mut ? ImplicitSelfKind::MUT : ImplicitSelfKind::IMM),
+ lifetime (tl::nullopt), type (std::move (type)), locus (locus),
+ mappings (mappings)
+{}
+
+SelfParam::SelfParam (Analysis::NodeMapping mappings,
+ tl::optional<Lifetime> lifetime, bool is_mut,
+ location_t locus)
+ : self_kind (is_mut ? ImplicitSelfKind::MUT_REF : ImplicitSelfKind::IMM_REF),
+ lifetime (std::move (lifetime)), locus (locus), mappings (mappings)
+{}
+
+SelfParam::SelfParam (SelfParam const &other)
+ : self_kind (other.self_kind), lifetime (other.lifetime), locus (other.locus),
+ mappings (other.mappings)
+{
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+}
+
+SelfParam &
+SelfParam::operator= (SelfParam const &other)
+{
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+
+ self_kind = other.self_kind;
+ lifetime = other.lifetime;
+ locus = other.locus;
+ mappings = other.mappings;
+
+ return *this;
+}
+
+Mutability
+SelfParam::get_mut () const
+{
+ return (self_kind == ImplicitSelfKind::MUT
+ || self_kind == ImplicitSelfKind::MUT_REF)
+ ? Mutability::Mut
+ : Mutability::Imm;
+}
+
+bool
+SelfParam::is_mut () const
+{
+ return self_kind == ImplicitSelfKind::MUT
+ || self_kind == ImplicitSelfKind::MUT_REF;
+}
+
+bool
+SelfParam::is_ref () const
+{
+ return self_kind == ImplicitSelfKind::IMM_REF
+ || self_kind == ImplicitSelfKind::MUT_REF;
+}
+
+FunctionParam::FunctionParam (Analysis::NodeMapping mappings,
+ std::unique_ptr<Pattern> param_name,
+ std::unique_ptr<Type> param_type,
+ location_t locus)
+ : param_name (std::move (param_name)), type (std::move (param_type)),
+ locus (locus), mappings (mappings)
+{}
+
+FunctionParam::FunctionParam (FunctionParam const &other)
+ : param_name (other.param_name->clone_pattern ()),
+ type (other.type->clone_type ()), locus (other.locus),
+ mappings (other.mappings)
+{}
+
+FunctionParam &
+FunctionParam::operator= (FunctionParam const &other)
+{
+ param_name = other.param_name->clone_pattern ();
+ type = other.type->clone_type ();
+ locus = other.locus;
+ mappings = other.mappings;
+
+ return *this;
+}
+
+VisItem &
+VisItem::operator= (VisItem const &other)
+{
+ Item::operator= (other);
+ visibility = other.visibility;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+VisItem::VisItem (VisItem const &other)
+ : Item (other), visibility (other.visibility)
+{}
+
+Module::Module (Analysis::NodeMapping mappings, Identifier module_name,
+ location_t locus, std::vector<std::unique_ptr<Item>> items,
+ Visibility visibility, AST::AttrVec inner_attrs,
+ AST::AttrVec outer_attrs)
+ : VisItem (std::move (mappings), std::move (visibility),
+ std::move (outer_attrs)),
+ WithInnerAttrs (std::move (inner_attrs)), module_name (module_name),
+ locus (locus), items (std::move (items))
+{}
+
+Module::Module (Module const &other)
+ : VisItem (other), WithInnerAttrs (other.inner_attrs), module_name ("")
+{
+ items.reserve (other.items.size ());
+ for (const auto &e : other.items)
+ items.push_back (e->clone_item ());
+}
+
+Module &
+Module::operator= (Module const &other)
+{
+ VisItem::operator= (other);
+ inner_attrs = other.inner_attrs;
+
+ items.reserve (other.items.size ());
+ for (const auto &e : other.items)
+ items.push_back (e->clone_item ());
+
+ return *this;
+}
+
+Function::Function (Analysis::NodeMapping mappings, Identifier function_name,
+ FunctionQualifiers qualifiers,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ std::vector<FunctionParam> function_params,
+ std::unique_ptr<Type> return_type, WhereClause where_clause,
+ std::unique_ptr<BlockExpr> function_body, Visibility vis,
+ AST::AttrVec outer_attrs, tl::optional<SelfParam> self,
+ Defaultness defaultness, location_t locus)
+ : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
+ qualifiers (std::move (qualifiers)),
+ function_name (std::move (function_name)),
+ generic_params (std::move (generic_params)),
+ function_params (std::move (function_params)),
+ return_type (std::move (return_type)),
+ where_clause (std::move (where_clause)),
+ function_body (std::move (function_body)), self (std::move (self)),
+ locus (locus), defaultness (defaultness)
+{}
+
+Function::Function (Function const &other)
+ : VisItem (other), qualifiers (other.qualifiers),
+ function_name (other.function_name),
+ function_params (other.function_params), where_clause (other.where_clause),
+ function_body (other.function_body->clone_block_expr ()), self (other.self),
+ locus (other.locus), defaultness (other.defaultness)
+{
+ // guard to prevent null dereference (always required)
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type ();
+ else
+ return_type = nullptr;
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+}
+
+Function &
+Function::operator= (Function const &other)
+{
+ VisItem::operator= (other);
+ function_name = other.function_name;
+ qualifiers = other.qualifiers;
+ function_params = other.function_params;
+
+ // guard to prevent null dereference (always required)
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type ();
+ else
+ return_type = nullptr;
+
+ where_clause = other.where_clause;
+ function_body = other.function_body->clone_block_expr ();
+ locus = other.locus;
+ self = other.self;
+
+ defaultness = other.defaultness;
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ return *this;
+}
+
+TypeAlias::TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ WhereClause where_clause,
+ std::unique_ptr<Type> existing_type, Visibility vis,
+ AST::AttrVec outer_attrs, location_t locus)
+ : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
+ new_type_name (std::move (new_type_name)),
+ generic_params (std::move (generic_params)),
+ where_clause (std::move (where_clause)),
+ existing_type (std::move (existing_type)), locus (locus)
+{}
+
+TypeAlias::TypeAlias (TypeAlias const &other)
+ : VisItem (other), new_type_name (other.new_type_name),
+ where_clause (other.where_clause),
+ existing_type (other.existing_type->clone_type ()), locus (other.locus)
+{
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+}
+
+TypeAlias &
+TypeAlias::operator= (TypeAlias const &other)
+{
+ VisItem::operator= (other);
+ new_type_name = other.new_type_name;
+ where_clause = other.where_clause;
+ existing_type = other.existing_type->clone_type ();
+ locus = other.locus;
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ return *this;
+}
+
+StructField::StructField (Analysis::NodeMapping mappings, Identifier field_name,
+ std::unique_ptr<Type> field_type, Visibility vis,
+ location_t locus, AST::AttrVec outer_attrs)
+ : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
+ field_name (std::move (field_name)), field_type (std::move (field_type)),
+ mappings (mappings), locus (locus)
+{}
+
+StructField::StructField (StructField const &other)
+ : outer_attrs (other.outer_attrs), visibility (other.visibility),
+ field_name (other.field_name), field_type (other.field_type->clone_type ()),
+ mappings (other.mappings)
+{}
+
+StructField &
+StructField::operator= (StructField const &other)
+{
+ field_name = other.field_name;
+ field_type = other.field_type->clone_type ();
+ visibility = other.visibility;
+ outer_attrs = other.outer_attrs;
+ mappings = other.mappings;
+
+ return *this;
+}
+
+TupleField::TupleField (Analysis::NodeMapping mapping,
+ std::unique_ptr<Type> field_type, Visibility vis,
+ location_t locus, AST::AttrVec outer_attrs)
+ : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
+ field_type (std::move (field_type)), locus (locus), mappings (mapping)
+{}
+
+TupleField::TupleField (TupleField const &other)
+ : outer_attrs (other.outer_attrs), visibility (other.visibility),
+ field_type (other.field_type->clone_type ()), locus (other.locus),
+ mappings (other.mappings)
+{}
+
+TupleField &
+TupleField::operator= (TupleField const &other)
+{
+ field_type = other.field_type->clone_type ();
+ visibility = other.visibility;
+ outer_attrs = other.outer_attrs;
+ locus = other.locus;
+ mappings = other.mappings;
+
+ return *this;
+}
+
+TupleStruct::TupleStruct (
+ Analysis::NodeMapping mappings, std::vector<TupleField> fields,
+ Identifier struct_name,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ WhereClause where_clause, Visibility vis, AST::AttrVec outer_attrs,
+ location_t locus)
+ : Struct (std::move (mappings), std::move (struct_name),
+ std::move (generic_params), std::move (where_clause),
+ std::move (vis), locus, std::move (outer_attrs)),
+ fields (std::move (fields))
+{}
+
+EnumItem::EnumItem (Analysis::NodeMapping mappings, Identifier variant_name,
+ AST::AttrVec outer_attrs, location_t locus)
+ : Item (std::move (mappings), std::move (outer_attrs)),
+ variant_name (std::move (variant_name)), locus (locus)
+{}
+
+EnumItemTuple::EnumItemTuple (Analysis::NodeMapping mappings,
+ Identifier variant_name,
+ std::vector<TupleField> tuple_fields,
+ AST::AttrVec outer_attrs, location_t locus)
+ : EnumItem (std::move (mappings), std::move (variant_name),
+ std::move (outer_attrs), locus),
+ tuple_fields (std::move (tuple_fields))
+{}
+
+EnumItemStruct::EnumItemStruct (Analysis::NodeMapping mappings,
+ Identifier variant_name,
+ std::vector<StructField> struct_fields,
+ AST::AttrVec outer_attrs, location_t locus)
+ : EnumItem (std::move (mappings), std::move (variant_name),
+ std::move (outer_attrs), locus),
+ struct_fields (std::move (struct_fields))
+{}
+
+EnumItemDiscriminant::EnumItemDiscriminant (Analysis::NodeMapping mappings,
+ Identifier variant_name,
+ std::unique_ptr<Expr> expr,
+ AST::AttrVec outer_attrs,
+ location_t locus)
+ : EnumItem (std::move (mappings), std::move (variant_name),
+ std::move (outer_attrs), locus),
+ expression (std::move (expr))
+{}
+
+EnumItemDiscriminant::EnumItemDiscriminant (EnumItemDiscriminant const &other)
+ : EnumItem (other), expression (other.expression->clone_expr ())
+{}
+
+EnumItemDiscriminant &
+EnumItemDiscriminant::operator= (EnumItemDiscriminant const &other)
+{
+ EnumItem::operator= (other);
+ expression = other.expression->clone_expr ();
+ // variant_name = other.variant_name;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+}
+
+Enum::Enum (Analysis::NodeMapping mappings, Identifier enum_name,
+ Visibility vis,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ WhereClause where_clause,
+ std::vector<std::unique_ptr<EnumItem>> items,
+ AST::AttrVec outer_attrs, location_t locus)
+ : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
+ enum_name (std::move (enum_name)),
+ generic_params (std::move (generic_params)),
+ where_clause (std::move (where_clause)), items (std::move (items)),
+ locus (locus)
+{}
+
+Enum::Enum (Enum const &other)
+ : VisItem (other), enum_name (other.enum_name),
+ where_clause (other.where_clause), locus (other.locus)
+{
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ items.reserve (other.items.size ());
+ for (const auto &e : other.items)
+ items.push_back (e->clone_enum_item ());
+}
+
+Enum &
+Enum::operator= (Enum const &other)
+{
+ VisItem::operator= (other);
+ enum_name = other.enum_name;
+ where_clause = other.where_clause;
+ locus = other.locus;
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ items.reserve (other.items.size ());
+ for (const auto &e : other.items)
+ items.push_back (e->clone_enum_item ());
+
+ return *this;
+}
+
+Union::Union (Analysis::NodeMapping mappings, Identifier union_name,
+ Visibility vis,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ WhereClause where_clause, std::vector<StructField> variants,
+ AST::AttrVec outer_attrs, location_t locus)
+ : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
+ union_name (std::move (union_name)),
+ generic_params (std::move (generic_params)),
+ where_clause (std::move (where_clause)), variants (std::move (variants)),
+ locus (locus)
+{}
+
+Union::Union (Union const &other)
+ : VisItem (other), union_name (other.union_name),
+ where_clause (other.where_clause), variants (other.variants),
+ locus (other.locus)
+{
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+}
+
+Union &
+Union::operator= (Union const &other)
+{
+ VisItem::operator= (other);
+ union_name = other.union_name;
+ where_clause = other.where_clause;
+ variants = other.variants;
+ locus = other.locus;
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ return *this;
+}
+
+ConstantItem::ConstantItem (Analysis::NodeMapping mappings, Identifier ident,
+ Visibility vis, std::unique_ptr<Type> type,
+ std::unique_ptr<Expr> const_expr,
+ AST::AttrVec outer_attrs, location_t locus)
+ : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
+ identifier (std::move (ident)), type (std::move (type)),
+ const_expr (std::move (const_expr)), locus (locus)
+{}
+
+ConstantItem::ConstantItem (ConstantItem const &other)
+ : VisItem (other), identifier (other.identifier),
+ type (other.type->clone_type ()),
+ const_expr (other.const_expr->clone_expr ()), locus (other.locus)
+{}
+
+ConstantItem &
+ConstantItem::operator= (ConstantItem const &other)
+{
+ VisItem::operator= (other);
+ identifier = other.identifier;
+ type = other.type->clone_type ();
+ const_expr = other.const_expr->clone_expr ();
+ locus = other.locus;
+
+ return *this;
+}
+
+StaticItem::StaticItem (Analysis::NodeMapping mappings, Identifier name,
+ Mutability mut, std::unique_ptr<Type> type,
+ std::unique_ptr<Expr> expr, Visibility vis,
+ AST::AttrVec outer_attrs, location_t locus)
+ : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
+ mut (mut), name (std::move (name)), type (std::move (type)),
+ expr (std::move (expr)), locus (locus)
+{}
+
+StaticItem::StaticItem (StaticItem const &other)
+ : VisItem (other), mut (other.mut), name (other.name),
+ type (other.type->clone_type ()), expr (other.expr->clone_expr ()),
+ locus (other.locus)
+{}
+
+StaticItem &
+StaticItem::operator= (StaticItem const &other)
+{
+ VisItem::operator= (other);
+ name = other.name;
+ mut = other.mut;
+ type = other.type->clone_type ();
+ expr = other.expr->clone_expr ();
+ locus = other.locus;
+
+ return *this;
+}
+
+TraitFunctionDecl::TraitFunctionDecl (
+ Identifier function_name, FunctionQualifiers qualifiers,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ tl::optional<SelfParam> self, std::vector<FunctionParam> function_params,
+ std::unique_ptr<Type> return_type, WhereClause where_clause)
+ : qualifiers (std::move (qualifiers)),
+ function_name (std::move (function_name)),
+ generic_params (std::move (generic_params)),
+ function_params (std::move (function_params)),
+ return_type (std::move (return_type)),
+ where_clause (std::move (where_clause)), self (std::move (self))
+{}
+
+TraitFunctionDecl::TraitFunctionDecl (TraitFunctionDecl const &other)
+ : qualifiers (other.qualifiers), function_name (other.function_name),
+ function_params (other.function_params),
+ return_type (other.return_type->clone_type ()),
+ where_clause (other.where_clause), self (other.self)
+{
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+}
+
+TraitFunctionDecl &
+TraitFunctionDecl::operator= (TraitFunctionDecl const &other)
+{
+ function_name = other.function_name;
+ qualifiers = other.qualifiers;
+ function_params = other.function_params;
+ return_type = other.return_type->clone_type ();
+ where_clause = other.where_clause;
+ self = other.self;
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ return *this;
+}
+
+TraitItemFunc::TraitItemFunc (Analysis::NodeMapping mappings,
+ TraitFunctionDecl decl,
+ std::unique_ptr<BlockExpr> block_expr,
+ AST::AttrVec outer_attrs, location_t locus)
+ : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
+ decl (std::move (decl)), block_expr (std::move (block_expr)), locus (locus)
+{}
+
+TraitItemFunc::TraitItemFunc (TraitItemFunc const &other)
+ : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
+ decl (other.decl), locus (other.locus)
+{
+ if (other.block_expr != nullptr)
+ block_expr = other.block_expr->clone_block_expr ();
+}
+
+TraitItemFunc &
+TraitItemFunc::operator= (TraitItemFunc const &other)
+{
+ TraitItem::operator= (other);
+ outer_attrs = other.outer_attrs;
+ decl = other.decl;
+ locus = other.locus;
+ mappings = other.mappings;
+ if (other.block_expr != nullptr)
+ block_expr = other.block_expr->clone_block_expr ();
+
+ return *this;
+}
+
+TraitItemConst::TraitItemConst (Analysis::NodeMapping mappings, Identifier name,
+ std::unique_ptr<Type> type,
+ std::unique_ptr<Expr> expr,
+ AST::AttrVec outer_attrs, location_t locus)
+ : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
+ name (std::move (name)), type (std::move (type)), expr (std::move (expr)),
+ locus (locus)
+{}
+
+TraitItemConst::TraitItemConst (TraitItemConst const &other)
+ : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
+ name (other.name), type (other.type->clone_type ()),
+ expr (other.expr->clone_expr ()), locus (other.locus)
+{}
+
+TraitItemConst &
+TraitItemConst::operator= (TraitItemConst const &other)
+{
+ TraitItem::operator= (other);
+ outer_attrs = other.outer_attrs;
+ name = other.name;
+ type = other.type->clone_type ();
+ expr = other.expr->clone_expr ();
+ locus = other.locus;
+ mappings = other.mappings;
+
+ return *this;
+}
+
+TraitItemType::TraitItemType (
+ Analysis::NodeMapping mappings, Identifier name,
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
+ AST::AttrVec outer_attrs, location_t locus)
+ : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
+ name (std::move (name)), type_param_bounds (std::move (type_param_bounds)),
+ locus (locus)
+{}
+
+TraitItemType::TraitItemType (TraitItemType const &other)
+ : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
+ name (other.name), locus (other.locus)
+{
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+}
+
+TraitItemType &
+TraitItemType::operator= (TraitItemType const &other)
+{
+ TraitItem::operator= (other);
+ outer_attrs = other.outer_attrs;
+ name = other.name;
+ locus = other.locus;
+ mappings = other.mappings;
+
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+
+ return *this;
+}
+
+Trait::Trait (Analysis::NodeMapping mappings, Identifier name,
+ Unsafety unsafety,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
+ WhereClause where_clause,
+ std::vector<std::unique_ptr<TraitItem>> trait_items,
+ Visibility vis, AST::AttrVec outer_attrs, location_t locus)
+ : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
+ unsafety (unsafety), name (std::move (name)),
+ generic_params (std::move (generic_params)),
+ type_param_bounds (std::move (type_param_bounds)),
+ where_clause (std::move (where_clause)),
+ trait_items (std::move (trait_items)), locus (locus)
+{}
+
+Trait::Trait (Trait const &other)
+ : VisItem (other), unsafety (other.unsafety), name (other.name),
+ where_clause (other.where_clause), locus (other.locus)
+{
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+
+ trait_items.reserve (other.trait_items.size ());
+ for (const auto &e : other.trait_items)
+ trait_items.push_back (e->clone_trait_item ());
+}
+
+Trait &
+Trait::operator= (Trait const &other)
+{
+ VisItem::operator= (other);
+ name = other.name;
+ unsafety = other.unsafety;
+ where_clause = other.where_clause;
+ locus = other.locus;
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+
+ trait_items.reserve (other.trait_items.size ());
+ for (const auto &e : other.trait_items)
+ trait_items.push_back (e->clone_trait_item ());
+
+ return *this;
+}
+
+ImplBlock::ImplBlock (Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<ImplItem>> impl_items,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ std::unique_ptr<Type> impl_type,
+ std::unique_ptr<TypePath> trait_ref,
+ WhereClause where_clause, BoundPolarity polarity,
+ Visibility vis, AST::AttrVec inner_attrs,
+ AST::AttrVec outer_attrs, location_t locus, bool unsafe)
+ : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
+ WithInnerAttrs (std::move (inner_attrs)),
+ generic_params (std::move (generic_params)),
+ impl_type (std::move (impl_type)), trait_ref (std::move (trait_ref)),
+ where_clause (std::move (where_clause)), polarity (polarity), locus (locus),
+ impl_items (std::move (impl_items)), unsafe (unsafe)
+{}
+
+ImplBlock::ImplBlock (ImplBlock const &other)
+ : VisItem (other), WithInnerAttrs (other.inner_attrs),
+ impl_type (other.impl_type->clone_type ()),
+ where_clause (other.where_clause), polarity (other.polarity),
+ locus (other.locus), unsafe (other.unsafe)
+{
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ impl_items.reserve (other.impl_items.size ());
+ for (const auto &e : other.impl_items)
+ impl_items.push_back (e->clone_inherent_impl_item ());
+}
+
+ImplBlock &
+ImplBlock::operator= (ImplBlock const &other)
+{
+ VisItem::operator= (other);
+ impl_type = other.impl_type->clone_type ();
+ where_clause = other.where_clause;
+ polarity = other.polarity;
+ inner_attrs = other.inner_attrs;
+ locus = other.locus;
+ unsafe = other.unsafe;
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ impl_items.reserve (other.impl_items.size ());
+ for (const auto &e : other.impl_items)
+ impl_items.push_back (e->clone_inherent_impl_item ());
+
+ return *this;
+}
+
+ExternalItem::ExternalItem (Analysis::NodeMapping mappings,
+ Identifier item_name, Visibility vis,
+ AST::AttrVec outer_attrs, location_t locus)
+ : mappings (mappings), outer_attrs (std::move (outer_attrs)),
+ visibility (std::move (vis)), item_name (std::move (item_name)),
+ locus (locus)
+{}
+
+ExternalItem::ExternalItem (ExternalItem const &other)
+ : mappings (other.mappings), outer_attrs (other.outer_attrs),
+ visibility (other.visibility), item_name (other.item_name),
+ locus (other.locus)
+{}
+
+ExternalItem &
+ExternalItem::operator= (ExternalItem const &other)
+{
+ mappings = other.mappings;
+ item_name = other.item_name;
+ visibility = other.visibility;
+ outer_attrs = other.outer_attrs;
+ locus = other.locus;
+
+ return *this;
+}
+
+ExternalStaticItem::ExternalStaticItem (Analysis::NodeMapping mappings,
+ Identifier item_name,
+ std::unique_ptr<Type> item_type,
+ Mutability mut, Visibility vis,
+ AST::AttrVec outer_attrs,
+ location_t locus)
+ : ExternalItem (std::move (mappings), std::move (item_name), std::move (vis),
+ std::move (outer_attrs), locus),
+ mut (mut), item_type (std::move (item_type))
+{}
+
+ExternalStaticItem::ExternalStaticItem (ExternalStaticItem const &other)
+ : ExternalItem (other), mut (other.mut),
+ item_type (other.item_type->clone_type ())
+{}
+
+ExternalStaticItem &
+ExternalStaticItem::operator= (ExternalStaticItem const &other)
+{
+ ExternalItem::operator= (other);
+ item_type = other.item_type->clone_type ();
+ mut = other.mut;
+
+ return *this;
+}
+
+NamedFunctionParam::NamedFunctionParam (Analysis::NodeMapping mappings,
+ Identifier name,
+ std::unique_ptr<Type> param_type)
+ : name (std::move (name)), param_type (std::move (param_type)),
+ mappings (std::move (mappings))
+{}
+
+NamedFunctionParam::NamedFunctionParam (NamedFunctionParam const &other)
+ : name (other.name), param_type (other.param_type->clone_type ()),
+ mappings (other.mappings)
+{}
+
+NamedFunctionParam &
+NamedFunctionParam::operator= (NamedFunctionParam const &other)
+{
+ mappings = other.mappings;
+ name = other.name;
+ param_type = other.param_type->clone_type ();
+ // has_name = other.has_name;
+
+ return *this;
+}
+
+ExternalFunctionItem::ExternalFunctionItem (
+ Analysis::NodeMapping mappings, Identifier item_name,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ std::unique_ptr<Type> return_type, WhereClause where_clause,
+ std::vector<NamedFunctionParam> function_params, bool has_variadics,
+ Visibility vis, AST::AttrVec outer_attrs, location_t locus)
+ : ExternalItem (std::move (mappings), std::move (item_name), std::move (vis),
+ std::move (outer_attrs), locus),
+ generic_params (std::move (generic_params)),
+ return_type (std::move (return_type)),
+ where_clause (std::move (where_clause)),
+ function_params (std::move (function_params)), has_variadics (has_variadics)
+{}
+
+ExternalFunctionItem::ExternalFunctionItem (ExternalFunctionItem const &other)
+ : ExternalItem (other), where_clause (other.where_clause),
+ function_params (other.function_params), has_variadics (other.has_variadics)
+{
+ if (other.return_type)
+ return_type = other.return_type->clone_type ();
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+}
+
+ExternalFunctionItem &
+ExternalFunctionItem::operator= (ExternalFunctionItem const &other)
+{
+ ExternalItem::operator= (other);
+
+ where_clause = other.where_clause;
+ function_params = other.function_params;
+ has_variadics = other.has_variadics;
+
+ if (other.return_type)
+ return_type = other.return_type->clone_type ();
+
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ return *this;
+}
+
+ExternalTypeItem::ExternalTypeItem (Analysis::NodeMapping mappings,
+ Identifier item_name, Visibility vis,
+ location_t locus)
+ : ExternalItem (std::move (mappings), std::move (item_name),
+ Visibility (std::move (vis)),
+ /* FIXME: Is that correct? */
+ {}, locus)
+{}
+
+ExternalTypeItem::ExternalTypeItem (ExternalTypeItem const &other)
+ : ExternalItem (other)
+{}
+
+ExternBlock::ExternBlock (
+ Analysis::NodeMapping mappings, ABI abi,
+ std::vector<std::unique_ptr<ExternalItem>> extern_items, Visibility vis,
+ AST::AttrVec inner_attrs, AST::AttrVec outer_attrs, location_t locus)
+ : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
+ WithInnerAttrs (std::move (inner_attrs)), abi (abi),
+ extern_items (std::move (extern_items)), locus (locus)
+{}
+
+ExternBlock::ExternBlock (ExternBlock const &other)
+ : VisItem (other), WithInnerAttrs (other.inner_attrs), abi (other.abi),
+ locus (other.locus)
+{
+ extern_items.reserve (other.extern_items.size ());
+ for (const auto &e : other.extern_items)
+ extern_items.push_back (e->clone_external_item ());
+}
+
+ExternBlock &
+ExternBlock::operator= (ExternBlock const &other)
+{
+ VisItem::operator= (other);
+ abi = other.abi;
+ inner_attrs = other.inner_attrs;
+ locus = other.locus;
+
+ extern_items.reserve (other.extern_items.size ());
+ for (const auto &e : other.extern_items)
+ extern_items.push_back (e->clone_external_item ());
+
+ return *this;
+}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 1f53e85..37f599c 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -19,18 +19,77 @@
#ifndef RUST_HIR_ITEM_H
#define RUST_HIR_ITEM_H
+#include "optional.h"
#include "rust-abi.h"
-#include "rust-ast-full-decls.h"
+#include "rust-hir-stmt.h"
#include "rust-common.h"
-#include "rust-hir-expr.h"
-#include "rust-hir.h"
-#include "rust-hir-path.h"
+#include "rust-hir-visibility.h"
+#include "rust-hir-generic-param.h"
+#include "rust-system.h"
namespace Rust {
namespace HIR {
-// forward decls
-class BlockExpr;
-class TypePath;
+
+// Rust "item" HIR node (declaration of top-level/module-level allowed stuff)
+class Item : public Stmt, public WithOuterAttrs
+{
+ // TODO: should outer attrs be defined here or in each derived class?
+public:
+ enum class ItemKind
+ {
+ Static,
+ Constant,
+ TypeAlias,
+ Function,
+ UseDeclaration,
+ ExternBlock,
+ ExternCrate,
+ Struct,
+ Union,
+ Enum,
+ EnumItem, // FIXME: ARTHUR: Do we need that?
+ Trait,
+ Impl,
+ Module,
+ };
+
+ static std::string item_kind_string (ItemKind kind);
+
+ virtual ItemKind get_item_kind () const = 0;
+
+ // Unique pointer custom clone function
+ std::unique_ptr<Item> clone_item () const
+ {
+ return std::unique_ptr<Item> (clone_item_impl ());
+ }
+
+ BaseKind get_hir_kind () override { return Node::BaseKind::ITEM; }
+
+ std::string as_string () const override;
+
+ /* Adds crate names to the vector passed by reference, if it can
+ * (polymorphism). */
+ virtual void
+ add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
+ {}
+
+ bool is_item () const override final { return true; }
+
+protected:
+ // Constructor
+ Item (Analysis::NodeMapping mappings,
+ AST::AttrVec outer_attribs = AST::AttrVec ())
+ : Stmt (std::move (mappings)), WithOuterAttrs (std::move (outer_attribs))
+ {}
+
+ // Clone function implementation as pure virtual method
+ virtual Item *clone_item_impl () const = 0;
+
+ /* Save having to specify two clone methods in derived classes by making
+ * statement clone return item clone. Hopefully won't affect performance too
+ * much. */
+ Item *clone_stmt_impl () const override { return clone_item_impl (); }
+};
// A type generic parameter (as opposed to a lifetime generic parameter)
class TypeParam : public GenericParam
@@ -44,14 +103,13 @@ class TypeParam : public GenericParam
std::vector<std::unique_ptr<TypeParamBound>>
type_param_bounds; // inlined form
- // bool has_type;
- std::unique_ptr<Type> type;
+ tl::optional<std::unique_ptr<Type>> type;
location_t locus;
public:
// Returns whether the type of the type param has been specified.
- bool has_type () const { return type != nullptr; }
+ bool has_type () const { return type.has_value (); }
// Returns whether the type param has type param bounds.
bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
@@ -64,50 +122,18 @@ public:
location_t locus = UNDEF_LOCATION,
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 = std::vector<AST::Attribute> ())
- : 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)
- {}
+ tl::optional<std::unique_ptr<Type>> type = tl::nullopt,
+ AST::AttrVec outer_attrs = std::vector<AST::Attribute> ());
// Copy constructor uses clone
- TypeParam (TypeParam const &other)
- : GenericParam (other.mappings), outer_attrs (other.outer_attrs),
- type_representation (other.type_representation), locus (other.locus)
- {
- // guard to prevent null pointer dereference
- if (other.type != nullptr)
- type = other.type->clone_type ();
-
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
- }
+ TypeParam (TypeParam const &other);
// Overloaded assignment operator to clone
- TypeParam &operator= (TypeParam const &other)
- {
- type_representation = other.type_representation;
- outer_attrs = other.outer_attrs;
- locus = other.locus;
- mappings = other.mappings;
-
- // guard to prevent null pointer dereference
- if (other.type != nullptr)
- type = other.type->clone_type ();
- else
- type = nullptr;
-
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
+ TypeParam &operator= (TypeParam const &other);
- return *this;
- }
// move constructors
TypeParam (TypeParam &&other) = default;
+
TypeParam &operator= (TypeParam &&other) = default;
std::string as_string () const override;
@@ -118,18 +144,15 @@ public:
Identifier get_type_representation () const { return type_representation; }
- std::unique_ptr<Type> &get_type () { return type; }
-
- Analysis::NodeMapping get_type_mappings () const
+ Type &get_type ()
{
- rust_assert (type != nullptr);
- return type->get_mappings ();
+ rust_assert (*type);
+ return *type.value ();
}
- std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
- {
- return type_param_bounds;
- }
+ Analysis::NodeMapping get_type_mappings () const;
+
+ std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ();
protected:
// Clone function implementation as (not pure) virtual method
@@ -234,35 +257,13 @@ public:
Analysis::NodeMapping mappings, std::vector<LifetimeParam> for_lifetimes,
std::unique_ptr<Type> bound_type,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
- location_t locus)
- : for_lifetimes (std::move (for_lifetimes)),
- bound_type (std::move (bound_type)),
- type_param_bounds (std::move (type_param_bounds)),
- mappings (std::move (mappings)), locus (locus)
- {}
+ location_t locus);
// Copy constructor requires clone
- TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other)
- : for_lifetimes (other.for_lifetimes),
- bound_type (other.bound_type->clone_type ()), mappings (other.mappings)
- {
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
- }
+ TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other);
// Overload assignment operator to clone
- TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other)
- {
- mappings = other.mappings;
- for_lifetimes = other.for_lifetimes;
- bound_type = other.bound_type->clone_type ();
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
-
- return *this;
- }
+ TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other);
// move constructors
TypeBoundWhereClauseItem (TypeBoundWhereClauseItem &&other) = default;
@@ -277,12 +278,9 @@ public:
std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
- std::unique_ptr<Type> &get_bound_type () { return bound_type; }
+ Type &get_bound_type () { return *bound_type; }
- std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
- {
- return type_param_bounds;
- }
+ std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ();
Analysis::NodeMapping get_mappings () const override final
{
@@ -373,78 +371,40 @@ public:
private:
ImplicitSelfKind self_kind;
- Lifetime lifetime;
+ tl::optional<Lifetime> lifetime;
std::unique_ptr<Type> type;
location_t locus;
Analysis::NodeMapping mappings;
SelfParam (Analysis::NodeMapping mappings, ImplicitSelfKind self_kind,
- Lifetime lifetime, Type *type)
- : self_kind (self_kind), lifetime (std::move (lifetime)), type (type),
- mappings (mappings)
- {}
+ tl::optional<Lifetime> lifetime, Type *type);
public:
// Type-based self parameter (not ref, no lifetime)
SelfParam (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
- bool is_mut, location_t locus)
- : self_kind (is_mut ? ImplicitSelfKind::MUT : ImplicitSelfKind::IMM),
- lifetime (
- Lifetime (mappings, AST::Lifetime::LifetimeType::NAMED, "", locus)),
- type (std::move (type)), locus (locus), mappings (mappings)
- {}
+ bool is_mut, location_t locus);
// Lifetime-based self parameter (is ref, no type)
- SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime, bool is_mut,
- location_t locus)
- : self_kind (is_mut ? ImplicitSelfKind::MUT_REF
- : ImplicitSelfKind::IMM_REF),
- lifetime (std::move (lifetime)), locus (locus), mappings (mappings)
- {}
+ SelfParam (Analysis::NodeMapping mappings, tl::optional<Lifetime> lifetime,
+ bool is_mut, location_t locus);
// Copy constructor requires clone
- SelfParam (SelfParam const &other)
- : self_kind (other.self_kind), lifetime (other.lifetime),
- locus (other.locus), mappings (other.mappings)
- {
- if (other.type != nullptr)
- type = other.type->clone_type ();
- }
+ SelfParam (SelfParam const &other);
// Overload assignment operator to use clone
- SelfParam &operator= (SelfParam const &other)
- {
- if (other.type != nullptr)
- type = other.type->clone_type ();
-
- self_kind = other.self_kind;
- lifetime = other.lifetime;
- locus = other.locus;
- mappings = other.mappings;
-
- return *this;
- }
+ SelfParam &operator= (SelfParam const &other);
// move constructors
SelfParam (SelfParam &&other) = default;
SelfParam &operator= (SelfParam &&other) = default;
- static SelfParam error ()
- {
- return SelfParam (Analysis::NodeMapping::get_error (),
- ImplicitSelfKind::NONE, Lifetime::error (), nullptr);
- }
-
// Returns whether the self-param has a type field.
bool has_type () const { return type != nullptr; }
// Returns whether the self-param has a valid lifetime.
- bool has_lifetime () const { return !lifetime.is_error (); }
-
- const Lifetime &get_lifetime () const { return lifetime; }
+ bool has_lifetime () const { return lifetime.has_value (); }
- // Returns whether the self-param is in an error state.
- bool is_error () const { return self_kind == ImplicitSelfKind::NONE; }
+ const Lifetime &get_lifetime () const { return lifetime.value (); }
std::string as_string () const;
@@ -452,29 +412,19 @@ public:
ImplicitSelfKind get_self_kind () const { return self_kind; }
- std::unique_ptr<Type> &get_type () { return type; }
+ Type &get_type ()
+ {
+ rust_assert (type);
+ return *type;
+ }
Analysis::NodeMapping get_mappings () { return mappings; }
- Mutability get_mut () const
- {
- return (self_kind == ImplicitSelfKind::MUT
- || self_kind == ImplicitSelfKind::MUT_REF)
- ? Mutability::Mut
- : Mutability::Imm;
- }
+ Mutability get_mut () const;
- bool is_mut () const
- {
- return self_kind == ImplicitSelfKind::MUT
- || self_kind == ImplicitSelfKind::MUT_REF;
- }
+ bool is_mut () const;
- bool is_ref () const
- {
- return self_kind == ImplicitSelfKind::IMM_REF
- || self_kind == ImplicitSelfKind::MUT_REF;
- }
+ bool is_ref () const;
};
// Qualifiers for function, i.e. const, unsafe, extern etc.
@@ -516,28 +466,13 @@ struct FunctionParam
public:
FunctionParam (Analysis::NodeMapping mappings,
std::unique_ptr<Pattern> param_name,
- std::unique_ptr<Type> param_type, location_t locus)
- : param_name (std::move (param_name)), type (std::move (param_type)),
- locus (locus), mappings (mappings)
- {}
+ std::unique_ptr<Type> param_type, location_t locus);
// Copy constructor uses clone
- FunctionParam (FunctionParam const &other)
- : param_name (other.param_name->clone_pattern ()),
- type (other.type->clone_type ()), locus (other.locus),
- mappings (other.mappings)
- {}
+ FunctionParam (FunctionParam const &other);
// Overload assignment operator to use clone
- FunctionParam &operator= (FunctionParam const &other)
- {
- param_name = other.param_name->clone_pattern ();
- type = other.type->clone_type ();
- locus = other.locus;
- mappings = other.mappings;
-
- return *this;
- }
+ FunctionParam &operator= (FunctionParam const &other);
// move constructors
FunctionParam (FunctionParam &&other) = default;
@@ -547,63 +482,15 @@ public:
location_t get_locus () const { return locus; }
- std::unique_ptr<Pattern> &get_param_name () { return param_name; }
-
- std::unique_ptr<Type> &get_type () { return type; }
-
- const Analysis::NodeMapping &get_mappings () const { return mappings; }
-};
-
-// Visibility of an item
-struct Visibility
-{
-public:
- enum VisType
- {
- PRIVATE,
- PUBLIC,
- RESTRICTED,
- ERROR,
- };
-
-private:
- VisType vis_type;
- HIR::SimplePath path;
- location_t locus;
-
- // should this store location info?
-
-public:
- Visibility (VisType vis_type,
- HIR::SimplePath path = HIR::SimplePath::create_empty (),
- location_t locus = UNDEF_LOCATION)
- : vis_type (vis_type), path (std::move (path)), locus (locus)
- {}
-
- // Returns whether visibility is in an error state.
- bool is_error () const { return vis_type == ERROR; }
-
- // Does the current visibility refer to a simple `pub <item>` entirely public
- bool is_public () const { return vis_type == PUBLIC; }
+ Pattern &get_param_name () { return *param_name; }
- // Is the current visibility public restricted to a certain path
- bool is_restricted () const { return vis_type == RESTRICTED; }
-
- // Creates an error visibility.
- static Visibility create_error ()
+ Type &get_type ()
{
- return Visibility (ERROR, HIR::SimplePath::create_empty ());
+ rust_assert (type);
+ return *type;
}
- VisType get_vis_type () const { return vis_type; }
-
- const HIR::SimplePath &get_path () const
- {
- rust_assert (!is_error ());
- return path;
- }
-
- std::string as_string () const;
+ const Analysis::NodeMapping &get_mappings () const { return mappings; }
};
// Item that supports visibility - abstract base class
@@ -620,18 +507,10 @@ protected:
{}
// Visibility copy constructor
- VisItem (VisItem const &other) : Item (other), visibility (other.visibility)
- {}
+ VisItem (VisItem const &other);
// Overload assignment operator to clone
- VisItem &operator= (VisItem const &other)
- {
- Item::operator= (other);
- visibility = other.visibility;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ VisItem &operator= (VisItem const &other);
// move constructors
VisItem (VisItem &&other) = default;
@@ -673,34 +552,13 @@ public:
location_t locus, std::vector<std::unique_ptr<Item>> items,
Visibility visibility = Visibility::create_error (),
AST::AttrVec inner_attrs = AST::AttrVec (),
- AST::AttrVec outer_attrs = AST::AttrVec ())
- : VisItem (std::move (mappings), std::move (visibility),
- std::move (outer_attrs)),
- WithInnerAttrs (std::move (inner_attrs)), module_name (module_name),
- locus (locus), items (std::move (items))
- {}
+ AST::AttrVec outer_attrs = AST::AttrVec ());
// Copy constructor with vector clone
- Module (Module const &other)
- : VisItem (other), WithInnerAttrs (other.inner_attrs), module_name ("")
- {
- items.reserve (other.items.size ());
- for (const auto &e : other.items)
- items.push_back (e->clone_item ());
- }
+ Module (Module const &other);
// Overloaded assignment operator with vector clone
- Module &operator= (Module const &other)
- {
- VisItem::operator= (other);
- inner_attrs = other.inner_attrs;
-
- items.reserve (other.items.size ());
- for (const auto &e : other.items)
- items.push_back (e->clone_item ());
-
- return *this;
- }
+ Module &operator= (Module const &other);
// move constructors
Module (Module &&other) = default;
@@ -1056,7 +914,7 @@ public:
location_t get_locus () const override final { return locus; }
ItemKind get_item_kind () const override { return ItemKind::UseDeclaration; }
- std::unique_ptr<UseTree> &get_use_tree () { return use_tree; }
+ UseTree &get_use_tree () { return *use_tree; }
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRStmtVisitor &vis) override;
void accept_vis (HIRVisItemVisitor &vis) override;
@@ -1078,6 +936,12 @@ protected:
class LetStmt;
+enum class Defaultness
+{
+ Default,
+ Final,
+};
+
// Rust function declaration HIR node
class Function : public VisItem, public ImplItem
{
@@ -1088,9 +952,14 @@ class Function : public VisItem, public ImplItem
std::unique_ptr<Type> return_type;
WhereClause where_clause;
std::unique_ptr<BlockExpr> function_body;
- SelfParam self;
+ tl::optional<SelfParam> self;
location_t locus;
+ // NOTE: This should be moved to the trait item base class once we start
+ // implementing specialization for real, instead of just stubbing out the
+ // feature
+ Defaultness defaultness;
+
public:
std::string as_string () const override;
@@ -1106,6 +975,9 @@ public:
// Returns whether function has a where clause.
bool has_where_clause () const { return !where_clause.is_empty (); }
+ // Returns whether function has a default qualifier
+ bool is_default () const { return defaultness == Defaultness::Default; }
+
ImplItemType get_impl_item_type () const override final
{
return ImplItem::ImplItemType::FUNCTION;
@@ -1120,63 +992,14 @@ public:
std::vector<FunctionParam> function_params,
std::unique_ptr<Type> return_type, WhereClause where_clause,
std::unique_ptr<BlockExpr> function_body, Visibility vis,
- AST::AttrVec outer_attrs, SelfParam self, location_t locus)
- : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
- qualifiers (std::move (qualifiers)),
- function_name (std::move (function_name)),
- generic_params (std::move (generic_params)),
- function_params (std::move (function_params)),
- return_type (std::move (return_type)),
- where_clause (std::move (where_clause)),
- function_body (std::move (function_body)), self (std::move (self)),
- locus (locus)
- {}
+ AST::AttrVec outer_attrs, tl::optional<SelfParam> self,
+ Defaultness defaultness, location_t locus);
// Copy constructor with clone
- Function (Function const &other)
- : VisItem (other), qualifiers (other.qualifiers),
- function_name (other.function_name),
- function_params (other.function_params),
- where_clause (other.where_clause),
- function_body (other.function_body->clone_block_expr ()),
- self (other.self), locus (other.locus)
- {
- // guard to prevent null dereference (always required)
- if (other.return_type != nullptr)
- return_type = other.return_type->clone_type ();
- else
- return_type = nullptr;
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
- }
+ Function (Function const &other);
// Overloaded assignment operator to clone
- Function &operator= (Function const &other)
- {
- VisItem::operator= (other);
- function_name = other.function_name;
- qualifiers = other.qualifiers;
- function_params = other.function_params;
-
- // guard to prevent null dereference (always required)
- if (other.return_type != nullptr)
- return_type = other.return_type->clone_type ();
- else
- return_type = nullptr;
-
- where_clause = other.where_clause;
- function_body = other.function_body->clone_block_expr ();
- locus = other.locus;
- self = other.self;
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- return *this;
- }
+ Function &operator= (Function const &other);
// move constructors
Function (Function &&other) = default;
@@ -1210,7 +1033,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- std::unique_ptr<BlockExpr> &get_definition () { return function_body; }
+ BlockExpr &get_definition () { return *function_body; }
const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
@@ -1222,11 +1045,15 @@ public:
bool has_return_type () const { return return_type != nullptr; }
// TODO: is this better? Or is a "vis_block" better?
- std::unique_ptr<Type> &get_return_type () { return return_type; }
+ Type &get_return_type () { return *return_type; }
- bool is_method () const { return !self.is_error (); }
+ bool is_method () const { return self.has_value (); }
- SelfParam &get_self_param () { return self; }
+ tl::optional<SelfParam> &get_self_param () { return self; }
+ const tl::optional<SelfParam> &get_self_param () const { return self; }
+
+ SelfParam &get_self_param_unchecked () { return self.value (); }
+ const SelfParam &get_self_param_unchecked () const { return self.value (); }
std::string get_impl_item_name () const override final
{
@@ -1280,40 +1107,13 @@ public:
TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name,
std::vector<std::unique_ptr<GenericParam>> generic_params,
WhereClause where_clause, std::unique_ptr<Type> existing_type,
- Visibility vis, AST::AttrVec outer_attrs, location_t locus)
- : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
- new_type_name (std::move (new_type_name)),
- generic_params (std::move (generic_params)),
- where_clause (std::move (where_clause)),
- existing_type (std::move (existing_type)), locus (locus)
- {}
+ Visibility vis, AST::AttrVec outer_attrs, location_t locus);
// Copy constructor
- TypeAlias (TypeAlias const &other)
- : VisItem (other), new_type_name (other.new_type_name),
- where_clause (other.where_clause),
- existing_type (other.existing_type->clone_type ()), locus (other.locus)
- {
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
- }
+ TypeAlias (TypeAlias const &other);
// Overloaded assignment operator to clone
- TypeAlias &operator= (TypeAlias const &other)
- {
- VisItem::operator= (other);
- new_type_name = other.new_type_name;
- where_clause = other.where_clause;
- existing_type = other.existing_type->clone_type ();
- locus = other.locus;
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- return *this;
- }
+ TypeAlias &operator= (TypeAlias const &other);
// move constructors
TypeAlias (TypeAlias &&other) = default;
@@ -1337,7 +1137,11 @@ public:
WhereClause &get_where_clause () { return where_clause; }
- std::unique_ptr<Type> &get_type_aliased () { return existing_type; }
+ Type &get_type_aliased ()
+ {
+ rust_assert (existing_type);
+ return *existing_type;
+ }
Identifier get_new_type_name () const { return new_type_name; }
@@ -1468,32 +1272,15 @@ public:
StructField (Analysis::NodeMapping mappings, Identifier field_name,
std::unique_ptr<Type> field_type, Visibility vis,
- location_t locus, AST::AttrVec outer_attrs = AST::AttrVec ())
- : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
- field_name (std::move (field_name)), field_type (std::move (field_type)),
- mappings (mappings), locus (locus)
- {}
+ location_t locus, AST::AttrVec outer_attrs = AST::AttrVec ());
// Copy constructor
- StructField (StructField const &other)
- : outer_attrs (other.outer_attrs), visibility (other.visibility),
- field_name (other.field_name),
- field_type (other.field_type->clone_type ()), mappings (other.mappings)
- {}
+ StructField (StructField const &other);
~StructField () = default;
// Overloaded assignment operator to clone
- StructField &operator= (StructField const &other)
- {
- field_name = other.field_name;
- field_type = other.field_type->clone_type ();
- visibility = other.visibility;
- outer_attrs = other.outer_attrs;
- mappings = other.mappings;
-
- return *this;
- }
+ StructField &operator= (StructField const &other);
// move constructors
StructField (StructField &&other) = default;
@@ -1503,7 +1290,7 @@ public:
Identifier get_field_name () const { return field_name; }
- std::unique_ptr<Type> &get_field_type () { return field_type; }
+ Type &get_field_type () { return *field_type; }
Analysis::NodeMapping get_mappings () const { return mappings; }
@@ -1598,31 +1385,15 @@ public:
// Complete constructor
TupleField (Analysis::NodeMapping mapping, std::unique_ptr<Type> field_type,
Visibility vis, location_t locus,
- AST::AttrVec outer_attrs = AST::AttrVec ())
- : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
- field_type (std::move (field_type)), locus (locus), mappings (mapping)
- {}
+ AST::AttrVec outer_attrs = AST::AttrVec ());
// Copy constructor with clone
- TupleField (TupleField const &other)
- : outer_attrs (other.outer_attrs), visibility (other.visibility),
- field_type (other.field_type->clone_type ()), locus (other.locus),
- mappings (other.mappings)
- {}
+ TupleField (TupleField const &other);
~TupleField () = default;
// Overloaded assignment operator to clone
- TupleField &operator= (TupleField const &other)
- {
- field_type = other.field_type->clone_type ();
- visibility = other.visibility;
- outer_attrs = other.outer_attrs;
- locus = other.locus;
- mappings = other.mappings;
-
- return *this;
- }
+ TupleField &operator= (TupleField const &other);
// move constructors
TupleField (TupleField &&other) = default;
@@ -1640,7 +1411,7 @@ public:
location_t get_locus () const { return locus; }
AST::AttrVec &get_outer_attrs () { return outer_attrs; }
- std::unique_ptr<HIR::Type> &get_field_type () { return field_type; }
+ HIR::Type &get_field_type () { return *field_type; }
};
// Rust tuple declared using struct keyword HIR node
@@ -1656,12 +1427,7 @@ public:
Identifier struct_name,
std::vector<std::unique_ptr<GenericParam>> generic_params,
WhereClause where_clause, Visibility vis,
- AST::AttrVec outer_attrs, location_t locus)
- : Struct (std::move (mappings), std::move (struct_name),
- std::move (generic_params), std::move (where_clause),
- std::move (vis), locus, std::move (outer_attrs)),
- fields (std::move (fields))
- {}
+ AST::AttrVec outer_attrs, location_t locus);
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRStmtVisitor &vis) override;
@@ -1706,10 +1472,7 @@ public:
};
EnumItem (Analysis::NodeMapping mappings, Identifier variant_name,
- AST::AttrVec outer_attrs, location_t locus)
- : Item (std::move (mappings), std::move (outer_attrs)),
- variant_name (std::move (variant_name)), locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// Unique pointer custom clone function
std::unique_ptr<EnumItem> clone_enum_item () const
@@ -1752,11 +1515,7 @@ public:
EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name,
std::vector<TupleField> tuple_fields, AST::AttrVec outer_attrs,
- location_t locus)
- : EnumItem (std::move (mappings), std::move (variant_name),
- std::move (outer_attrs), locus),
- tuple_fields (std::move (tuple_fields))
- {}
+ location_t locus);
std::string as_string () const override;
@@ -1790,11 +1549,7 @@ public:
EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name,
std::vector<StructField> struct_fields,
- AST::AttrVec outer_attrs, location_t locus)
- : EnumItem (std::move (mappings), std::move (variant_name),
- std::move (outer_attrs), locus),
- struct_fields (std::move (struct_fields))
- {}
+ AST::AttrVec outer_attrs, location_t locus);
std::string as_string () const override;
@@ -1819,27 +1574,13 @@ class EnumItemDiscriminant : public EnumItem
public:
EnumItemDiscriminant (Analysis::NodeMapping mappings, Identifier variant_name,
std::unique_ptr<Expr> expr, AST::AttrVec outer_attrs,
- location_t locus)
- : EnumItem (std::move (mappings), std::move (variant_name),
- std::move (outer_attrs), locus),
- expression (std::move (expr))
- {}
+ location_t locus);
// Copy constructor with clone
- EnumItemDiscriminant (EnumItemDiscriminant const &other)
- : EnumItem (other), expression (other.expression->clone_expr ())
- {}
+ EnumItemDiscriminant (EnumItemDiscriminant const &other);
// Overloaded assignment operator to clone
- EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other)
- {
- EnumItem::operator= (other);
- expression = other.expression->clone_expr ();
- // variant_name = other.variant_name;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
+ EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other);
// move constructors
EnumItemDiscriminant (EnumItemDiscriminant &&other) = default;
@@ -1855,7 +1596,12 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRStmtVisitor &vis) override;
- std::unique_ptr<Expr> &get_discriminant_expression () { return expression; }
+ Expr &get_discriminant_expression () { return *expression; }
+
+ std::unique_ptr<Expr> take_discriminant_expression ()
+ {
+ return std::move (expression);
+ }
protected:
// Clone function implementation as (not pure) virtual method
@@ -1898,48 +1644,15 @@ public:
Enum (Analysis::NodeMapping mappings, Identifier enum_name, Visibility vis,
std::vector<std::unique_ptr<GenericParam>> generic_params,
WhereClause where_clause, std::vector<std::unique_ptr<EnumItem>> items,
- AST::AttrVec outer_attrs, location_t locus)
- : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
- enum_name (std::move (enum_name)),
- generic_params (std::move (generic_params)),
- where_clause (std::move (where_clause)), items (std::move (items)),
- locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// TODO: constructor with less arguments
// Copy constructor with vector clone
- Enum (Enum const &other)
- : VisItem (other), enum_name (other.enum_name),
- where_clause (other.where_clause), locus (other.locus)
- {
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- items.reserve (other.items.size ());
- for (const auto &e : other.items)
- items.push_back (e->clone_enum_item ());
- }
+ Enum (Enum const &other);
// Overloaded assignment operator with vector clone
- Enum &operator= (Enum const &other)
- {
- VisItem::operator= (other);
- enum_name = other.enum_name;
- where_clause = other.where_clause;
- locus = other.locus;
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- items.reserve (other.items.size ());
- for (const auto &e : other.items)
- items.push_back (e->clone_enum_item ());
-
- return *this;
- }
+ Enum &operator= (Enum const &other);
// Move constructors
Enum (Enum &&other) = default;
@@ -2007,40 +1720,13 @@ public:
Union (Analysis::NodeMapping mappings, Identifier union_name, Visibility vis,
std::vector<std::unique_ptr<GenericParam>> generic_params,
WhereClause where_clause, std::vector<StructField> variants,
- AST::AttrVec outer_attrs, location_t locus)
- : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
- union_name (std::move (union_name)),
- generic_params (std::move (generic_params)),
- where_clause (std::move (where_clause)), variants (std::move (variants)),
- locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// copy constructor with vector clone
- Union (Union const &other)
- : VisItem (other), union_name (other.union_name),
- where_clause (other.where_clause), variants (other.variants),
- locus (other.locus)
- {
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
- }
+ Union (Union const &other);
// overloaded assignment operator with vector clone
- Union &operator= (Union const &other)
- {
- VisItem::operator= (other);
- union_name = other.union_name;
- where_clause = other.where_clause;
- variants = other.variants;
- locus = other.locus;
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- return *this;
- }
+ Union &operator= (Union const &other);
// move constructors
Union (Union &&other) = default;
@@ -2084,29 +1770,12 @@ public:
ConstantItem (Analysis::NodeMapping mappings, Identifier ident,
Visibility vis, std::unique_ptr<Type> type,
std::unique_ptr<Expr> const_expr, AST::AttrVec outer_attrs,
- location_t locus)
- : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
- identifier (std::move (ident)), type (std::move (type)),
- const_expr (std::move (const_expr)), locus (locus)
- {}
+ location_t locus);
- ConstantItem (ConstantItem const &other)
- : VisItem (other), identifier (other.identifier),
- type (other.type->clone_type ()),
- const_expr (other.const_expr->clone_expr ()), locus (other.locus)
- {}
+ ConstantItem (ConstantItem const &other);
// Overload assignment operator to clone
- ConstantItem &operator= (ConstantItem const &other)
- {
- VisItem::operator= (other);
- identifier = other.identifier;
- type = other.type->clone_type ();
- const_expr = other.const_expr->clone_expr ();
- locus = other.locus;
-
- return *this;
- }
+ ConstantItem &operator= (ConstantItem const &other);
// move constructors
ConstantItem (ConstantItem &&other) = default;
@@ -2126,9 +1795,13 @@ public:
void accept_vis (HIRImplVisitor &vis) override;
void accept_vis (HIRVisItemVisitor &vis) override;
- std::unique_ptr<Type> &get_type () { return type; }
+ Type &get_type ()
+ {
+ rust_assert (type);
+ return *type;
+ }
- std::unique_ptr<Expr> &get_expr () { return const_expr; }
+ Expr &get_expr () { return *const_expr; }
Identifier get_identifier () const { return identifier; }
@@ -2180,31 +1853,13 @@ public:
StaticItem (Analysis::NodeMapping mappings, Identifier name, Mutability mut,
std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
- Visibility vis, AST::AttrVec outer_attrs, location_t locus)
- : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
- mut (mut), name (std::move (name)), type (std::move (type)),
- expr (std::move (expr)), locus (locus)
- {}
+ Visibility vis, AST::AttrVec outer_attrs, location_t locus);
// Copy constructor with clone
- StaticItem (StaticItem const &other)
- : VisItem (other), mut (other.mut), name (other.name),
- type (other.type->clone_type ()), expr (other.expr->clone_expr ()),
- locus (other.locus)
- {}
+ StaticItem (StaticItem const &other);
// Overloaded assignment operator to clone
- StaticItem &operator= (StaticItem const &other)
- {
- VisItem::operator= (other);
- name = other.name;
- mut = other.mut;
- type = other.type->clone_type ();
- expr = other.expr->clone_expr ();
- locus = other.locus;
-
- return *this;
- }
+ StaticItem &operator= (StaticItem const &other);
// move constructors
StaticItem (StaticItem &&other) = default;
@@ -2222,9 +1877,17 @@ public:
bool is_mut () const { return mut == Mutability::Mut; }
- std::unique_ptr<Expr> &get_expr () { return expr; }
+ Expr &get_expr ()
+ {
+ rust_assert (expr);
+ return *expr;
+ }
- std::unique_ptr<Type> &get_type () { return type; }
+ Type &get_type ()
+ {
+ rust_assert (type);
+ return *type;
+ }
ItemKind get_item_kind () const override { return ItemKind::Static; }
@@ -2245,53 +1908,24 @@ private:
std::vector<FunctionParam> function_params;
std::unique_ptr<Type> return_type;
WhereClause where_clause;
- SelfParam self;
+ tl::optional<SelfParam> self;
public:
// Mega-constructor
TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam>> generic_params,
- SelfParam self, std::vector<FunctionParam> function_params,
+ tl::optional<SelfParam> self,
+ std::vector<FunctionParam> function_params,
std::unique_ptr<Type> return_type,
- WhereClause where_clause)
- : qualifiers (std::move (qualifiers)),
- function_name (std::move (function_name)),
- generic_params (std::move (generic_params)),
- function_params (std::move (function_params)),
- return_type (std::move (return_type)),
- where_clause (std::move (where_clause)), self (std::move (self))
- {}
+ WhereClause where_clause);
// Copy constructor with clone
- TraitFunctionDecl (TraitFunctionDecl const &other)
- : qualifiers (other.qualifiers), function_name (other.function_name),
- function_params (other.function_params),
- return_type (other.return_type->clone_type ()),
- where_clause (other.where_clause), self (other.self)
- {
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
- }
+ TraitFunctionDecl (TraitFunctionDecl const &other);
~TraitFunctionDecl () = default;
// Overloaded assignment operator with clone
- TraitFunctionDecl &operator= (TraitFunctionDecl const &other)
- {
- function_name = other.function_name;
- qualifiers = other.qualifiers;
- function_params = other.function_params;
- return_type = other.return_type->clone_type ();
- where_clause = other.where_clause;
- self = other.self;
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- return *this;
- }
+ TraitFunctionDecl &operator= (TraitFunctionDecl const &other);
// move constructors
TraitFunctionDecl (TraitFunctionDecl &&other) = default;
@@ -2313,9 +1947,13 @@ public:
WhereClause &get_where_clause () { return where_clause; }
- bool is_method () const { return !self.is_error (); }
+ bool is_method () const { return self.has_value (); }
+
+ SelfParam &get_self_unchecked () { return self.value (); }
+ const SelfParam &get_self_unchecked () const { return self.value (); }
- SelfParam &get_self () { return self; }
+ tl::optional<SelfParam> &get_self () { return self; }
+ const tl::optional<SelfParam> &get_self () const { return self; }
Identifier get_function_name () const { return function_name; }
@@ -2324,7 +1962,7 @@ public:
return generic_params;
}
- std::unique_ptr<Type> &get_return_type () { return return_type; }
+ Type &get_return_type () { return *return_type; }
std::vector<FunctionParam> &get_function_params () { return function_params; }
@@ -2345,34 +1983,13 @@ public:
TraitItemFunc (Analysis::NodeMapping mappings, TraitFunctionDecl decl,
std::unique_ptr<BlockExpr> block_expr,
- AST::AttrVec outer_attrs, location_t locus)
- : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
- decl (std::move (decl)), block_expr (std::move (block_expr)),
- locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// Copy constructor with clone
- TraitItemFunc (TraitItemFunc const &other)
- : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
- decl (other.decl), locus (other.locus)
- {
- if (other.block_expr != nullptr)
- block_expr = other.block_expr->clone_block_expr ();
- }
+ TraitItemFunc (TraitItemFunc const &other);
// Overloaded assignment operator to clone
- TraitItemFunc &operator= (TraitItemFunc const &other)
- {
- TraitItem::operator= (other);
- outer_attrs = other.outer_attrs;
- decl = other.decl;
- locus = other.locus;
- mappings = other.mappings;
- if (other.block_expr != nullptr)
- block_expr = other.block_expr->clone_block_expr ();
-
- return *this;
- }
+ TraitItemFunc &operator= (TraitItemFunc const &other);
// move constructors
TraitItemFunc (TraitItemFunc &&other) = default;
@@ -2389,9 +2006,7 @@ public:
const TraitFunctionDecl &get_decl () const { return decl; }
- bool has_block_defined () const { return block_expr != nullptr; }
-
- std::unique_ptr<BlockExpr> &get_block_expr () { return block_expr; }
+ BlockExpr &get_block_expr () { return *block_expr; }
const std::string trait_identifier () const override final
{
@@ -2434,32 +2049,13 @@ public:
TraitItemConst (Analysis::NodeMapping mappings, Identifier name,
std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
- AST::AttrVec outer_attrs, location_t locus)
- : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
- name (std::move (name)), type (std::move (type)), expr (std::move (expr)),
- locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// Copy constructor with clones
- TraitItemConst (TraitItemConst const &other)
- : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
- name (other.name), type (other.type->clone_type ()),
- expr (other.expr->clone_expr ()), locus (other.locus)
- {}
+ TraitItemConst (TraitItemConst const &other);
// Overloaded assignment operator to clone
- TraitItemConst &operator= (TraitItemConst const &other)
- {
- TraitItem::operator= (other);
- outer_attrs = other.outer_attrs;
- name = other.name;
- type = other.type->clone_type ();
- expr = other.expr->clone_expr ();
- locus = other.locus;
- mappings = other.mappings;
-
- return *this;
- }
+ TraitItemConst &operator= (TraitItemConst const &other);
// move constructors
TraitItemConst (TraitItemConst &&other) = default;
@@ -2474,11 +2070,21 @@ public:
Identifier get_name () const { return name; }
+ bool has_type () const { return expr != nullptr; }
+
bool has_expr () const { return expr != nullptr; }
- std::unique_ptr<Type> &get_type () { return type; }
+ Type &get_type ()
+ {
+ rust_assert (type);
+ return *type;
+ }
- std::unique_ptr<Expr> &get_expr () { return expr; }
+ Expr &get_expr ()
+ {
+ rust_assert (expr);
+ return *expr;
+ }
const std::string trait_identifier () const override final
{
@@ -2522,37 +2128,13 @@ public:
TraitItemType (Analysis::NodeMapping mappings, Identifier name,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
- AST::AttrVec outer_attrs, location_t locus)
- : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
- name (std::move (name)),
- type_param_bounds (std::move (type_param_bounds)), locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// Copy constructor with vector clone
- TraitItemType (TraitItemType const &other)
- : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
- name (other.name), locus (other.locus)
- {
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
- }
+ TraitItemType (TraitItemType const &other);
// Overloaded assignment operator with vector clone
- TraitItemType &operator= (TraitItemType const &other)
- {
- TraitItem::operator= (other);
- outer_attrs = other.outer_attrs;
- name = other.name;
- locus = other.locus;
- mappings = other.mappings;
-
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
-
- return *this;
- }
+ TraitItemType &operator= (TraitItemType const &other);
// default move constructors
TraitItemType (TraitItemType &&other) = default;
@@ -2640,56 +2222,13 @@ public:
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
WhereClause where_clause,
std::vector<std::unique_ptr<TraitItem>> trait_items, Visibility vis,
- AST::AttrVec outer_attrs, location_t locus)
- : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
- unsafety (unsafety), name (std::move (name)),
- generic_params (std::move (generic_params)),
- type_param_bounds (std::move (type_param_bounds)),
- where_clause (std::move (where_clause)),
- trait_items (std::move (trait_items)), locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// Copy constructor with vector clone
- Trait (Trait const &other)
- : VisItem (other), unsafety (other.unsafety), name (other.name),
- where_clause (other.where_clause), locus (other.locus)
- {
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
-
- trait_items.reserve (other.trait_items.size ());
- for (const auto &e : other.trait_items)
- trait_items.push_back (e->clone_trait_item ());
- }
+ Trait (Trait const &other);
// Overloaded assignment operator with vector clone
- Trait &operator= (Trait const &other)
- {
- VisItem::operator= (other);
- name = other.name;
- unsafety = other.unsafety;
- where_clause = other.where_clause;
- locus = other.locus;
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
-
- trait_items.reserve (other.trait_items.size ());
- for (const auto &e : other.trait_items)
- trait_items.push_back (e->clone_trait_item ());
-
- return *this;
- }
+ Trait &operator= (Trait const &other);
// default move constructors
Trait (Trait &&other) = default;
@@ -2748,50 +2287,11 @@ public:
std::unique_ptr<Type> impl_type,
std::unique_ptr<TypePath> trait_ref, WhereClause where_clause,
BoundPolarity polarity, Visibility vis, AST::AttrVec inner_attrs,
- AST::AttrVec outer_attrs, location_t locus, bool unsafe = false)
- : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
- WithInnerAttrs (std::move (inner_attrs)),
- generic_params (std::move (generic_params)),
- impl_type (std::move (impl_type)), trait_ref (std::move (trait_ref)),
- where_clause (std::move (where_clause)), polarity (polarity),
- locus (locus), impl_items (std::move (impl_items)), unsafe (unsafe)
- {}
-
- ImplBlock (ImplBlock const &other)
- : VisItem (other), WithInnerAttrs (other.inner_attrs),
- impl_type (other.impl_type->clone_type ()),
- where_clause (other.where_clause), polarity (other.polarity),
- locus (other.locus), unsafe (other.unsafe)
- {
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
+ AST::AttrVec outer_attrs, location_t locus, bool unsafe = false);
- impl_items.reserve (other.impl_items.size ());
- for (const auto &e : other.impl_items)
- impl_items.push_back (e->clone_inherent_impl_item ());
- }
+ ImplBlock (ImplBlock const &other);
- ImplBlock &operator= (ImplBlock const &other)
- {
- VisItem::operator= (other);
- impl_type = other.impl_type->clone_type ();
- where_clause = other.where_clause;
- polarity = other.polarity;
- inner_attrs = other.inner_attrs;
- locus = other.locus;
- unsafe = other.unsafe;
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- impl_items.reserve (other.impl_items.size ());
- for (const auto &e : other.impl_items)
- impl_items.push_back (e->clone_inherent_impl_item ());
-
- return *this;
- }
+ ImplBlock &operator= (ImplBlock const &other);
ImplBlock (ImplBlock &&other) = default;
ImplBlock &operator= (ImplBlock &&other) = default;
@@ -2828,7 +2328,13 @@ public:
location_t get_locus () const override final { return locus; }
- std::unique_ptr<Type> &get_type () { return impl_type; };
+ Type &get_type ()
+ {
+ rust_assert (impl_type);
+ return *impl_type;
+ };
+
+ bool has_type () { return impl_type != nullptr; }
std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
{
@@ -2837,7 +2343,7 @@ public:
bool has_trait_ref () const { return trait_ref != nullptr; }
- std::unique_ptr<TypePath> &get_trait_ref () { return trait_ref; }
+ TypePath &get_trait_ref () { return *trait_ref; }
WhereClause &get_where_clause () { return where_clause; }
@@ -2898,30 +2404,13 @@ public:
protected:
ExternalItem (Analysis::NodeMapping mappings, Identifier item_name,
- Visibility vis, AST::AttrVec outer_attrs, location_t locus)
- : mappings (mappings), outer_attrs (std::move (outer_attrs)),
- visibility (std::move (vis)), item_name (std::move (item_name)),
- locus (locus)
- {}
+ Visibility vis, AST::AttrVec outer_attrs, location_t locus);
// Copy constructor
- ExternalItem (ExternalItem const &other)
- : mappings (other.mappings), outer_attrs (other.outer_attrs),
- visibility (other.visibility), item_name (other.item_name),
- locus (other.locus)
- {}
+ ExternalItem (ExternalItem const &other);
// Overloaded assignment operator to clone
- ExternalItem &operator= (ExternalItem const &other)
- {
- mappings = other.mappings;
- item_name = other.item_name;
- visibility = other.visibility;
- outer_attrs = other.outer_attrs;
- locus = other.locus;
-
- return *this;
- }
+ ExternalItem &operator= (ExternalItem const &other);
// move constructors
ExternalItem (ExternalItem &&other) = default;
@@ -2941,27 +2430,13 @@ public:
ExternalStaticItem (Analysis::NodeMapping mappings, Identifier item_name,
std::unique_ptr<Type> item_type, Mutability mut,
Visibility vis, AST::AttrVec outer_attrs,
- location_t locus)
- : ExternalItem (std::move (mappings), std::move (item_name),
- std::move (vis), std::move (outer_attrs), locus),
- mut (mut), item_type (std::move (item_type))
- {}
+ location_t locus);
// Copy constructor
- ExternalStaticItem (ExternalStaticItem const &other)
- : ExternalItem (other), mut (other.mut),
- item_type (other.item_type->clone_type ())
- {}
+ ExternalStaticItem (ExternalStaticItem const &other);
// Overloaded assignment operator to clone
- ExternalStaticItem &operator= (ExternalStaticItem const &other)
- {
- ExternalItem::operator= (other);
- item_type = other.item_type->clone_type ();
- mut = other.mut;
-
- return *this;
- }
+ ExternalStaticItem &operator= (ExternalStaticItem const &other);
// move constructors
ExternalStaticItem (ExternalStaticItem &&other) = default;
@@ -2976,7 +2451,7 @@ public:
Mutability get_mut () { return mut; }
- std::unique_ptr<Type> &get_item_type () { return item_type; }
+ Type &get_item_type () { return *item_type; }
ExternKind get_extern_kind () override { return ExternKind::Static; }
@@ -3001,29 +2476,15 @@ public:
bool has_name () const { return name.as_string () != "_"; }
NamedFunctionParam (Analysis::NodeMapping mappings, Identifier name,
- std::unique_ptr<Type> param_type)
- : name (std::move (name)), param_type (std::move (param_type)),
- mappings (std::move (mappings))
- {}
+ std::unique_ptr<Type> param_type);
// Copy constructor
- NamedFunctionParam (NamedFunctionParam const &other)
- : name (other.name), param_type (other.param_type->clone_type ()),
- mappings (other.mappings)
- {}
+ NamedFunctionParam (NamedFunctionParam const &other);
~NamedFunctionParam () = default;
// Overloaded assignment operator to clone
- NamedFunctionParam &operator= (NamedFunctionParam const &other)
- {
- mappings = other.mappings;
- name = other.name;
- param_type = other.param_type->clone_type ();
- // has_name = other.has_name;
-
- return *this;
- }
+ NamedFunctionParam &operator= (NamedFunctionParam const &other);
// move constructors
NamedFunctionParam (NamedFunctionParam &&other) = default;
@@ -3033,7 +2494,11 @@ public:
Identifier get_param_name () const { return name; }
- std::unique_ptr<Type> &get_type () { return param_type; }
+ Type &get_type ()
+ {
+ rust_assert (param_type);
+ return *param_type;
+ }
Analysis::NodeMapping get_mappings () const { return mappings; }
};
@@ -3075,48 +2540,13 @@ public:
std::vector<std::unique_ptr<GenericParam>> generic_params,
std::unique_ptr<Type> return_type, WhereClause where_clause,
std::vector<NamedFunctionParam> function_params, bool has_variadics,
- Visibility vis, AST::AttrVec outer_attrs, location_t locus)
- : ExternalItem (std::move (mappings), std::move (item_name),
- std::move (vis), std::move (outer_attrs), locus),
- generic_params (std::move (generic_params)),
- return_type (std::move (return_type)),
- where_clause (std::move (where_clause)),
- function_params (std::move (function_params)),
- has_variadics (has_variadics)
- {}
+ Visibility vis, AST::AttrVec outer_attrs, location_t locus);
// Copy constructor with clone
- ExternalFunctionItem (ExternalFunctionItem const &other)
- : ExternalItem (other), where_clause (other.where_clause),
- function_params (other.function_params),
- has_variadics (other.has_variadics)
- {
- if (other.return_type)
- return_type = other.return_type->clone_type ();
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
- }
+ ExternalFunctionItem (ExternalFunctionItem const &other);
// Overloaded assignment operator with clone
- ExternalFunctionItem &operator= (ExternalFunctionItem const &other)
- {
- ExternalItem::operator= (other);
-
- where_clause = other.where_clause;
- function_params = other.function_params;
- has_variadics = other.has_variadics;
-
- if (other.return_type)
- return_type = other.return_type->clone_type ();
-
- generic_params.reserve (other.generic_params.size ());
- for (const auto &e : other.generic_params)
- generic_params.push_back (e->clone_generic_param ());
-
- return *this;
- }
+ ExternalFunctionItem &operator= (ExternalFunctionItem const &other);
// move constructors
ExternalFunctionItem (ExternalFunctionItem &&other) = default;
@@ -3132,7 +2562,7 @@ public:
return generic_params;
}
- std::unique_ptr<Type> &get_return_type () { return return_type; }
+ Type &get_return_type () { return *return_type; }
std::vector<NamedFunctionParam> &get_function_params ()
{
@@ -3156,14 +2586,9 @@ class ExternalTypeItem : public ExternalItem
{
public:
ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name,
- Visibility vis, location_t locus)
- : ExternalItem (std::move (mappings), std::move (item_name),
- Visibility (std::move (vis)),
- /* FIXME: Is that correct? */
- {}, locus)
- {}
+ Visibility vis, location_t locus);
- ExternalTypeItem (ExternalTypeItem const &other) : ExternalItem (other) {}
+ ExternalTypeItem (ExternalTypeItem const &other);
ExternalTypeItem (ExternalTypeItem &&other) = default;
ExternalTypeItem &operator= (ExternalTypeItem &&other) = default;
@@ -3203,36 +2628,13 @@ public:
ExternBlock (Analysis::NodeMapping mappings, ABI abi,
std::vector<std::unique_ptr<ExternalItem>> extern_items,
Visibility vis, AST::AttrVec inner_attrs,
- AST::AttrVec outer_attrs, location_t locus)
- : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
- WithInnerAttrs (std::move (inner_attrs)), abi (abi),
- extern_items (std::move (extern_items)), locus (locus)
- {}
+ AST::AttrVec outer_attrs, location_t locus);
// Copy constructor with vector clone
- ExternBlock (ExternBlock const &other)
- : VisItem (other), WithInnerAttrs (other.inner_attrs), abi (other.abi),
- locus (other.locus)
- {
- extern_items.reserve (other.extern_items.size ());
- for (const auto &e : other.extern_items)
- extern_items.push_back (e->clone_external_item ());
- }
+ ExternBlock (ExternBlock const &other);
// Overloaded assignment operator with vector clone
- ExternBlock &operator= (ExternBlock const &other)
- {
- VisItem::operator= (other);
- abi = other.abi;
- inner_attrs = other.inner_attrs;
- locus = other.locus;
-
- extern_items.reserve (other.extern_items.size ());
- for (const auto &e : other.extern_items)
- extern_items.push_back (e->clone_external_item ());
-
- return *this;
- }
+ ExternBlock &operator= (ExternBlock const &other);
// move constructors
ExternBlock (ExternBlock &&other) = default;
diff --git a/gcc/rust/hir/tree/rust-hir-literal.h b/gcc/rust/hir/tree/rust-hir-literal.h
new file mode 100644
index 0000000..9a97e71
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-literal.h
@@ -0,0 +1,78 @@
+// Copyright (C) 2020-2024 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_HIR_LITERAL_H
+#define RUST_HIR_LITERAL_H
+
+#include "rust-token.h"
+
+namespace Rust {
+namespace HIR {
+// A literal - value with a type. Used in LiteralExpr and LiteralPattern.
+struct Literal
+{
+public:
+ enum LitType
+ {
+ CHAR,
+ STRING,
+ BYTE,
+ BYTE_STRING,
+ INT,
+ FLOAT,
+ BOOL
+ };
+
+private:
+ std::string value_as_string;
+ LitType type;
+ PrimitiveCoreType type_hint;
+
+public:
+ std::string as_string () const { return value_as_string; }
+
+ LitType get_lit_type () const { return type; }
+
+ PrimitiveCoreType get_type_hint () const { return type_hint; }
+
+ Literal (std::string value_as_string, LitType type,
+ PrimitiveCoreType type_hint)
+ : value_as_string (std::move (value_as_string)), type (type),
+ type_hint (type_hint)
+ {}
+
+ static Literal create_error ()
+ {
+ return Literal ("", CHAR, PrimitiveCoreType::CORETYPE_UNKNOWN);
+ }
+
+ void set_lit_type (LitType lt) { type = lt; }
+
+ // Returns whether literal is in an invalid state.
+ bool is_error () const { return value_as_string == ""; }
+
+ bool is_equal (Literal &other)
+ {
+ return value_as_string == other.value_as_string && type == other.type
+ && type_hint == other.type_hint;
+ }
+};
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-node.h b/gcc/rust/hir/tree/rust-hir-node.h
new file mode 100644
index 0000000..4010c23
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-node.h
@@ -0,0 +1,63 @@
+// Copyright (C) 2020-2024 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_HIR_NODE_H
+#define RUST_HIR_NODE_H
+
+namespace Rust {
+
+namespace HIR {
+
+class Node
+{
+public:
+ // Kind for downcasting various HIR nodes to other base classes when visiting
+ // them
+ enum BaseKind
+ {
+ /* class ExternalItem */
+ EXTERNAL,
+ /* class TraitItem */
+ TRAIT_ITEM,
+ /* class VisItem */
+ VIS_ITEM,
+ /* class Item */
+ ITEM,
+ /* class ImplItem */
+ IMPL,
+ /* class Type */
+ TYPE,
+ /* class Stmt */
+ STMT,
+ /* class Expr */
+ EXPR,
+ /* class Pattern */
+ PATTERN,
+ };
+
+ /**
+ * Get the kind of HIR node we are dealing with. This is useful for
+ * downcasting to more precise types when necessary, i.e going from an `Item*`
+ * to a `VisItem*`
+ */
+ virtual BaseKind get_hir_kind () = 0;
+};
+
+} // namespace HIR
+} // namespace Rust
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-path.cc b/gcc/rust/hir/tree/rust-hir-path.cc
new file mode 100644
index 0000000..ee4a572
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-path.cc
@@ -0,0 +1,420 @@
+// Copyright (C) 2020-2024 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-hir-path.h"
+#include "optional.h"
+#include "rust-hir-bound.h"
+
+namespace Rust {
+namespace HIR {
+
+GenericArgsBinding::GenericArgsBinding (Identifier ident,
+ std::unique_ptr<Type> type_ptr,
+ location_t locus)
+ : identifier (std::move (ident)), type (std::move (type_ptr)), locus (locus)
+{}
+
+GenericArgsBinding::GenericArgsBinding (GenericArgsBinding const &other)
+ : identifier (other.identifier), type (other.type->clone_type ()),
+ locus (other.locus)
+{}
+
+GenericArgsBinding &
+GenericArgsBinding::operator= (GenericArgsBinding const &other)
+{
+ identifier = other.identifier;
+ type = other.type->clone_type ();
+ locus = other.locus;
+ return *this;
+}
+
+ConstGenericArg::ConstGenericArg (std::unique_ptr<Expr> expression,
+ location_t locus)
+ : expression (std::move (expression)), locus (locus)
+{}
+
+ConstGenericArg::ConstGenericArg (const ConstGenericArg &other)
+ : locus (other.locus)
+{
+ expression = other.expression->clone_expr ();
+}
+
+ConstGenericArg
+ConstGenericArg::operator= (const ConstGenericArg &other)
+{
+ expression = other.expression->clone_expr ();
+ locus = other.locus;
+
+ return *this;
+}
+
+GenericArgs &
+GenericArgs::operator= (GenericArgs const &other)
+{
+ lifetime_args = other.lifetime_args;
+ binding_args = other.binding_args;
+ const_args = other.const_args;
+ locus = other.locus;
+
+ type_args.clear ();
+ type_args.reserve (other.type_args.size ());
+ for (const auto &e : other.type_args)
+ type_args.push_back (e->clone_type ());
+
+ return *this;
+}
+
+GenericArgs::GenericArgs (std::vector<Lifetime> lifetime_args,
+ std::vector<std::unique_ptr<Type> > type_args,
+ std::vector<GenericArgsBinding> binding_args,
+ std::vector<ConstGenericArg> const_args,
+ location_t locus)
+ : lifetime_args (std::move (lifetime_args)),
+ type_args (std::move (type_args)), binding_args (std::move (binding_args)),
+ const_args (std::move (const_args)), locus (locus)
+{}
+
+GenericArgs::GenericArgs (GenericArgs const &other)
+ : lifetime_args (other.lifetime_args), binding_args (other.binding_args),
+ const_args (other.const_args), locus (other.locus)
+{
+ type_args.clear ();
+ type_args.reserve (other.type_args.size ());
+
+ for (const auto &e : other.type_args)
+ type_args.push_back (e->clone_type ());
+}
+
+bool
+GenericArgs::is_empty () const
+{
+ return lifetime_args.size () == 0 && type_args.size () == 0
+ && binding_args.size () == 0;
+}
+
+PathExprSegment::PathExprSegment (Analysis::NodeMapping mappings,
+ PathIdentSegment segment_name,
+ location_t locus, GenericArgs generic_args)
+ : mappings (std::move (mappings)), segment_name (std::move (segment_name)),
+ generic_args (std::move (generic_args)), locus (locus)
+{}
+
+PathExprSegment::PathExprSegment (PathExprSegment const &other)
+ : mappings (other.mappings), segment_name (other.segment_name),
+ generic_args (other.generic_args), locus (other.locus)
+{}
+
+PathExprSegment &
+PathExprSegment::operator= (PathExprSegment const &other)
+{
+ mappings = other.mappings;
+ segment_name = other.segment_name;
+ generic_args = other.generic_args;
+ locus = other.locus;
+
+ return *this;
+}
+
+void
+PathPattern::iterate_path_segments (std::function<bool (PathExprSegment &)> cb)
+{
+ rust_assert (kind == Kind::Segmented);
+
+ for (auto it = segments.begin (); it != segments.end (); it++)
+ {
+ if (!cb (*it))
+ return;
+ }
+}
+
+PathInExpression::PathInExpression (Analysis::NodeMapping mappings,
+ std::vector<PathExprSegment> path_segments,
+ location_t locus,
+ bool has_opening_scope_resolution,
+ std::vector<AST::Attribute> outer_attrs)
+ : PathPattern (std::move (path_segments)),
+ PathExpr (std::move (mappings), std::move (outer_attrs)),
+ has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
+{}
+
+PathInExpression::PathInExpression (Analysis::NodeMapping mappings,
+ LangItem::Kind lang_item, location_t locus,
+ bool has_opening_scope_resolution,
+ std::vector<AST::Attribute> outer_attrs)
+ : PathPattern (lang_item),
+ PathExpr (std::move (mappings), std::move (outer_attrs)),
+ has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
+{}
+
+bool
+PathInExpression::is_self () const
+
+{
+ if (!is_single_segment ())
+ return false;
+
+ return get_final_segment ().get_segment ().as_string ().compare ("self") == 0;
+}
+
+TypePathSegment::TypePathSegment (Analysis::NodeMapping mappings,
+ PathIdentSegment ident_segment,
+ bool has_separating_scope_resolution,
+ location_t locus)
+ : mappings (std::move (mappings)), ident_segment (std::move (ident_segment)),
+ lang_item (tl::nullopt), locus (locus),
+ has_separating_scope_resolution (has_separating_scope_resolution),
+ type (SegmentType::REG)
+{}
+
+TypePathSegment::TypePathSegment (Analysis::NodeMapping mappings,
+ LangItem::Kind lang_item, location_t locus)
+ : mappings (std::move (mappings)), ident_segment (tl::nullopt),
+ lang_item (lang_item), locus (locus),
+ has_separating_scope_resolution (false), type (SegmentType::REG)
+{}
+
+TypePathSegment::TypePathSegment (Analysis::NodeMapping mappings,
+ std::string segment_name,
+ bool has_separating_scope_resolution,
+ location_t locus)
+ : mappings (std::move (mappings)),
+ ident_segment (PathIdentSegment (std::move (segment_name))),
+ lang_item (tl::nullopt), locus (locus),
+ has_separating_scope_resolution (has_separating_scope_resolution),
+ type (SegmentType::REG)
+{}
+
+TypePathSegmentGeneric::TypePathSegmentGeneric (
+ Analysis::NodeMapping mappings, PathIdentSegment ident_segment,
+ bool has_separating_scope_resolution, GenericArgs generic_args,
+ location_t locus)
+ : TypePathSegment (std::move (mappings), std::move (ident_segment),
+ has_separating_scope_resolution, locus),
+ generic_args (std::move (generic_args))
+{}
+
+TypePathSegmentGeneric::TypePathSegmentGeneric (Analysis::NodeMapping mappings,
+ LangItem::Kind lang_item,
+ GenericArgs generic_args,
+ location_t locus)
+ : TypePathSegment (std::move (mappings), lang_item, locus),
+ generic_args (std::move (generic_args))
+{}
+
+TypePathSegmentGeneric::TypePathSegmentGeneric (
+ Analysis::NodeMapping mappings, std::string segment_name,
+ bool has_separating_scope_resolution, std::vector<Lifetime> lifetime_args,
+ std::vector<std::unique_ptr<Type> > type_args,
+ std::vector<GenericArgsBinding> binding_args,
+ std::vector<ConstGenericArg> const_args, location_t locus)
+ : TypePathSegment (std::move (mappings), std::move (segment_name),
+ has_separating_scope_resolution, locus),
+ generic_args (GenericArgs (std::move (lifetime_args), std::move (type_args),
+ std::move (binding_args), std::move (const_args),
+ locus))
+{}
+
+TypePathFunction::TypePathFunction (std::vector<std::unique_ptr<Type> > inputs,
+ std::unique_ptr<Type> type)
+ : inputs (std::move (inputs)), return_type (std::move (type))
+{}
+
+TypePathFunction::TypePathFunction (TypePathFunction const &other)
+{
+ return_type = other.has_return_type ()
+ ? other.get_return_type ().clone_type ()
+ : nullptr;
+
+ inputs.reserve (other.inputs.size ());
+ for (const auto &e : other.inputs)
+ inputs.push_back (e->clone_type ());
+}
+
+TypePathFunction &
+TypePathFunction::operator= (TypePathFunction const &other)
+{
+ return_type = other.has_return_type ()
+ ? other.get_return_type ().clone_type ()
+ : nullptr;
+
+ inputs.reserve (other.inputs.size ());
+ for (const auto &e : other.inputs)
+ inputs.push_back (e->clone_type ());
+
+ return *this;
+}
+
+TypePathSegmentFunction::TypePathSegmentFunction (
+ Analysis::NodeMapping mappings, PathIdentSegment ident_segment,
+ bool has_separating_scope_resolution, TypePathFunction function_path,
+ location_t locus)
+ : TypePathSegment (std::move (mappings), std::move (ident_segment),
+ has_separating_scope_resolution, locus),
+ function_path (std::move (function_path))
+{}
+
+TypePathSegmentFunction::TypePathSegmentFunction (
+ Analysis::NodeMapping mappings, std::string segment_name,
+ bool has_separating_scope_resolution, TypePathFunction function_path,
+ location_t locus)
+ : TypePathSegment (std::move (mappings), std::move (segment_name),
+ has_separating_scope_resolution, locus),
+ function_path (std::move (function_path))
+{}
+
+TypePath::TypePath (Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<TypePathSegment> > segments,
+ location_t locus, bool has_opening_scope_resolution)
+ : TypeNoBounds (mappings, locus),
+ has_opening_scope_resolution (has_opening_scope_resolution),
+ segments (std::move (segments))
+{}
+
+TypePath::TypePath (TypePath const &other)
+ : TypeNoBounds (other.mappings, other.locus),
+ has_opening_scope_resolution (other.has_opening_scope_resolution)
+{
+ segments.reserve (other.segments.size ());
+ for (const auto &e : other.segments)
+ segments.push_back (e->clone_type_path_segment ());
+}
+
+TypePath &
+TypePath::operator= (TypePath const &other)
+{
+ has_opening_scope_resolution = other.has_opening_scope_resolution;
+ locus = other.locus;
+ mappings = other.mappings;
+
+ segments.reserve (other.segments.size ());
+ for (const auto &e : other.segments)
+ segments.push_back (e->clone_type_path_segment ());
+
+ return *this;
+}
+
+QualifiedPathType::QualifiedPathType (Analysis::NodeMapping mappings,
+ std::unique_ptr<Type> type,
+ std::unique_ptr<TypePath> trait,
+ location_t locus)
+ : type (std::move (type)), trait (std::move (trait)), locus (locus),
+ mappings (mappings)
+{}
+
+QualifiedPathType::QualifiedPathType (QualifiedPathType const &other)
+ : type (other.type->clone_type ()),
+ trait (other.has_as_clause ()
+ ? std::unique_ptr<HIR::TypePath> (new HIR::TypePath (*other.trait))
+ : nullptr),
+ locus (other.locus), mappings (other.mappings)
+{}
+
+QualifiedPathType &
+QualifiedPathType::operator= (QualifiedPathType const &other)
+{
+ type = other.type->clone_type ();
+ locus = other.locus;
+ mappings = other.mappings;
+ trait = other.has_as_clause ()
+ ? std::unique_ptr<HIR::TypePath> (new HIR::TypePath (*other.trait))
+ : nullptr;
+
+ return *this;
+}
+
+bool
+QualifiedPathType::trait_has_generic_args () const
+{
+ rust_assert (has_as_clause ());
+ bool is_generic_seg = trait->get_final_segment ().get_type ()
+ == TypePathSegment::SegmentType::GENERIC;
+ if (!is_generic_seg)
+ return false;
+
+ auto &seg
+ = static_cast<TypePathSegmentGeneric &> (trait->get_final_segment ());
+ return seg.has_generic_args ();
+}
+
+GenericArgs &
+QualifiedPathType::get_trait_generic_args ()
+{
+ rust_assert (trait_has_generic_args ());
+ auto &seg
+ = static_cast<TypePathSegmentGeneric &> (trait->get_final_segment ());
+ return seg.get_generic_args ();
+}
+
+QualifiedPathInExpression::QualifiedPathInExpression (
+ Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
+ std::vector<PathExprSegment> path_segments, location_t locus,
+ std::vector<AST::Attribute> outer_attrs)
+ : PathPattern (std::move (path_segments)),
+ PathExpr (std::move (mappings), std::move (outer_attrs)),
+ path_type (std::move (qual_path_type)), locus (locus)
+{}
+
+QualifiedPathInExpression::QualifiedPathInExpression (
+ Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
+ LangItem::Kind lang_item, location_t locus,
+ std::vector<AST::Attribute> outer_attrs)
+ : PathPattern (lang_item),
+ PathExpr (std::move (mappings), std::move (outer_attrs)),
+ path_type (std::move (qual_path_type)), locus (locus)
+{}
+
+QualifiedPathInType::QualifiedPathInType (
+ Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
+ std::unique_ptr<TypePathSegment> associated_segment,
+ std::vector<std::unique_ptr<TypePathSegment> > path_segments,
+ location_t locus)
+ : TypeNoBounds (mappings, locus), path_type (std::move (qual_path_type)),
+ associated_segment (std::move (associated_segment)),
+ segments (std::move (path_segments))
+{}
+
+QualifiedPathInType::QualifiedPathInType (QualifiedPathInType const &other)
+ : TypeNoBounds (other.mappings, other.locus), path_type (other.path_type)
+{
+ auto seg = other.associated_segment->clone_type_path_segment_impl ();
+ associated_segment = std::unique_ptr<TypePathSegment> (seg);
+
+ segments.reserve (other.segments.size ());
+ for (const auto &e : other.segments)
+ segments.push_back (e->clone_type_path_segment ());
+}
+
+QualifiedPathInType &
+QualifiedPathInType::operator= (QualifiedPathInType const &other)
+{
+ auto seg = other.associated_segment->clone_type_path_segment_impl ();
+ associated_segment = std::unique_ptr<TypePathSegment> (seg);
+
+ path_type = other.path_type;
+ locus = other.locus;
+ mappings = other.mappings;
+
+ segments.reserve (other.segments.size ());
+ for (const auto &e : other.segments)
+ segments.push_back (e->clone_type_path_segment ());
+
+ return *this;
+}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index e406d53..3ce2662 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -19,7 +19,11 @@
#ifndef RUST_HIR_PATH_H
#define RUST_HIR_PATH_H
-#include "rust-hir.h"
+#include "rust-hir-map.h"
+#include "rust-hir-simple-path.h"
+#include "rust-hir-type-no-bounds.h"
+#include "rust-hir-pattern-abstract.h"
+#include "rust-hir-expr-abstract.h"
namespace Rust {
namespace HIR {
@@ -76,27 +80,16 @@ public:
// Pointer type for type in constructor to enable polymorphism
GenericArgsBinding (Identifier ident, std::unique_ptr<Type> type_ptr,
- location_t locus = UNDEF_LOCATION)
- : identifier (std::move (ident)), type (std::move (type_ptr)), locus (locus)
- {}
+ location_t locus = UNDEF_LOCATION);
// Copy constructor has to deep copy the type as it is a unique pointer
- GenericArgsBinding (GenericArgsBinding const &other)
- : identifier (other.identifier), type (other.type->clone_type ()),
- locus (other.locus)
- {}
+ GenericArgsBinding (GenericArgsBinding const &other);
// default destructor
~GenericArgsBinding () = default;
// Overload assignment operator to deep copy the pointed-to type
- GenericArgsBinding &operator= (GenericArgsBinding const &other)
- {
- identifier = other.identifier;
- type = other.type->clone_type ();
- locus = other.locus;
- return *this;
- }
+ GenericArgsBinding &operator= (GenericArgsBinding const &other);
// move constructors
GenericArgsBinding (GenericArgsBinding &&other) = default;
@@ -107,8 +100,16 @@ public:
Identifier &get_identifier () { return identifier; }
const Identifier &get_identifier () const { return identifier; }
- std::unique_ptr<Type> &get_type () { return type; }
- const std::unique_ptr<Type> &get_type () const { return type; }
+ Type &get_type ()
+ {
+ rust_assert (type);
+ return *type;
+ }
+ const Type &get_type () const
+ {
+ rust_assert (type);
+ return *type;
+ }
location_t get_locus () const { return locus; }
};
@@ -119,22 +120,11 @@ class ConstGenericArg
// at name-resolution, hence no need for ambiguities here
public:
- ConstGenericArg (std::unique_ptr<Expr> expression, location_t locus)
- : expression (std::move (expression)), locus (locus)
- {}
-
- ConstGenericArg (const ConstGenericArg &other) : locus (other.locus)
- {
- expression = other.expression->clone_expr ();
- }
+ ConstGenericArg (std::unique_ptr<Expr> expression, location_t locus);
- ConstGenericArg operator= (const ConstGenericArg &other)
- {
- expression = other.expression->clone_expr ();
- locus = other.locus;
+ ConstGenericArg (const ConstGenericArg &other);
- return *this;
- }
+ ConstGenericArg operator= (const ConstGenericArg &other);
std::unique_ptr<Expr> &get_expression () { return expression; }
@@ -162,42 +152,15 @@ public:
GenericArgs (std::vector<Lifetime> lifetime_args,
std::vector<std::unique_ptr<Type> > type_args,
std::vector<GenericArgsBinding> binding_args,
- std::vector<ConstGenericArg> const_args, location_t locus)
- : lifetime_args (std::move (lifetime_args)),
- type_args (std::move (type_args)),
- binding_args (std::move (binding_args)),
- const_args (std::move (const_args)), locus (locus)
- {}
+ std::vector<ConstGenericArg> const_args, location_t locus);
// copy constructor with vector clone
- GenericArgs (GenericArgs const &other)
- : lifetime_args (other.lifetime_args), binding_args (other.binding_args),
- const_args (other.const_args), locus (other.locus)
- {
- type_args.clear ();
- type_args.reserve (other.type_args.size ());
-
- for (const auto &e : other.type_args)
- type_args.push_back (e->clone_type ());
- }
+ GenericArgs (GenericArgs const &other);
~GenericArgs () = default;
// overloaded assignment operator to vector clone
- GenericArgs &operator= (GenericArgs const &other)
- {
- lifetime_args = other.lifetime_args;
- binding_args = other.binding_args;
- const_args = other.const_args;
- locus = other.locus;
-
- type_args.clear ();
- type_args.reserve (other.type_args.size ());
- for (const auto &e : other.type_args)
- type_args.push_back (e->clone_type ());
-
- return *this;
- }
+ GenericArgs &operator= (GenericArgs const &other);
// move constructors
GenericArgs (GenericArgs &&other) = default;
@@ -209,11 +172,7 @@ public:
return GenericArgs ({}, {}, {}, {}, locus);
}
- bool is_empty () const
- {
- return lifetime_args.size () == 0 && type_args.size () == 0
- && binding_args.size () == 0;
- }
+ bool is_empty () const;
std::string as_string () const;
@@ -245,25 +204,11 @@ private:
public:
PathExprSegment (Analysis::NodeMapping mappings,
PathIdentSegment segment_name, location_t locus,
- GenericArgs generic_args)
- : mappings (std::move (mappings)), segment_name (std::move (segment_name)),
- generic_args (std::move (generic_args)), locus (locus)
- {}
+ GenericArgs generic_args);
- PathExprSegment (PathExprSegment const &other)
- : mappings (other.mappings), segment_name (other.segment_name),
- generic_args (other.generic_args), locus (other.locus)
- {}
+ PathExprSegment (PathExprSegment const &other);
- PathExprSegment &operator= (PathExprSegment const &other)
- {
- mappings = other.mappings;
- segment_name = other.segment_name;
- generic_args = other.generic_args;
- locus = other.locus;
-
- return *this;
- }
+ PathExprSegment &operator= (PathExprSegment const &other);
// move constructors
PathExprSegment (PathExprSegment &&other) = default;
@@ -286,15 +231,34 @@ public:
// HIR node representing a pattern that involves a "path" - abstract base class
class PathPattern : public Pattern
{
+public:
+ enum class Kind
+ {
+ Segmented,
+ LangItem
+ };
+
+private:
std::vector<PathExprSegment> segments;
+ tl::optional<LangItem::Kind> lang_item;
+ Kind kind;
protected:
PathPattern (std::vector<PathExprSegment> segments)
- : segments (std::move (segments))
+ : segments (std::move (segments)), lang_item (tl::nullopt),
+ kind (Kind::Segmented)
+ {}
+
+ PathPattern (LangItem::Kind lang_item)
+ : segments ({}), lang_item (lang_item), kind (Kind::LangItem)
{}
// Returns whether path has segments.
- bool has_segments () const { return !segments.empty (); }
+ bool has_segments () const
+ {
+ rust_assert (kind == Kind::Segmented);
+ return !segments.empty ();
+ }
/* Converts path segments to their equivalent SimplePath segments if possible,
* and creates a SimplePath from them. */
@@ -304,33 +268,61 @@ protected:
public:
/* Returns whether the path is a single segment (excluding qualified path
* initial as segment). */
- bool is_single_segment () const { return segments.size () == 1; }
+ bool is_single_segment () const
+ {
+ rust_assert (kind == Kind::Segmented);
+ return segments.size () == 1;
+ }
std::string as_string () const override;
- void iterate_path_segments (std::function<bool (PathExprSegment &)> cb)
+ void iterate_path_segments (std::function<bool (PathExprSegment &)> cb);
+
+ size_t get_num_segments () const
{
- for (auto it = segments.begin (); it != segments.end (); it++)
- {
- if (!cb (*it))
- return;
- }
+ rust_assert (kind == Kind::Segmented);
+ return segments.size ();
}
- size_t get_num_segments () const { return segments.size (); }
+ std::vector<PathExprSegment> &get_segments ()
+ {
+ rust_assert (kind == Kind::Segmented);
+ return segments;
+ }
+
+ const std::vector<PathExprSegment> &get_segments () const
+ {
+ rust_assert (kind == Kind::Segmented);
+ return segments;
+ }
- std::vector<PathExprSegment> &get_segments () { return segments; }
+ PathExprSegment &get_root_seg ()
+ {
+ rust_assert (kind == Kind::Segmented);
+ return segments.at (0);
+ }
- const std::vector<PathExprSegment> &get_segments () const { return segments; }
+ const PathExprSegment &get_final_segment () const
+ {
+ rust_assert (kind == Kind::Segmented);
+ return segments.back ();
+ }
- PathExprSegment &get_root_seg () { return segments.at (0); }
+ LangItem::Kind get_lang_item () const
+ {
+ rust_assert (kind == Kind::LangItem);
- const PathExprSegment &get_final_segment () const { return segments.back (); }
+ return *lang_item;
+ }
PatternType get_pattern_type () const override final
{
return PatternType::PATH;
}
+
+ bool is_lang_item () const { return kind == Kind::LangItem; }
+
+ Kind get_path_kind () const { return kind; }
};
/* HIR node representing a path-in-expression pattern (path that allows generic
@@ -349,11 +341,14 @@ public:
location_t locus = UNDEF_LOCATION,
bool has_opening_scope_resolution = false,
std::vector<AST::Attribute> outer_attrs
- = std::vector<AST::Attribute> ())
- : PathPattern (std::move (path_segments)),
- PathExpr (std::move (mappings), std::move (outer_attrs)),
- has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
- {}
+ = std::vector<AST::Attribute> ());
+
+ // lang-item Constructor
+ PathInExpression (Analysis::NodeMapping mappings, LangItem::Kind kind,
+ location_t locus = UNDEF_LOCATION,
+ bool has_opening_scope_resolution = false,
+ std::vector<AST::Attribute> outer_attrs
+ = std::vector<AST::Attribute> ());
// Creates an error state path in expression.
static PathInExpression create_error ()
@@ -385,14 +380,7 @@ public:
bool opening_scope_resolution () { return has_opening_scope_resolution; }
- bool is_self () const
- {
- if (!is_single_segment ())
- return false;
-
- return get_final_segment ().get_segment ().as_string ().compare ("self")
- == 0;
- }
+ bool is_self () const;
const Analysis::NodeMapping &get_mappings () const override final
{
@@ -429,7 +417,8 @@ public:
private:
Analysis::NodeMapping mappings;
- PathIdentSegment ident_segment;
+ tl::optional<PathIdentSegment> ident_segment;
+ tl::optional<LangItem::Kind> lang_item;
location_t locus;
protected:
@@ -456,27 +445,29 @@ public:
TypePathSegment (Analysis::NodeMapping mappings,
PathIdentSegment ident_segment,
- bool has_separating_scope_resolution, location_t locus)
- : mappings (std::move (mappings)),
- ident_segment (std::move (ident_segment)), locus (locus),
- has_separating_scope_resolution (has_separating_scope_resolution),
- type (SegmentType::REG)
- {}
+ bool has_separating_scope_resolution, location_t locus);
+
+ TypePathSegment (Analysis::NodeMapping mappings, LangItem::Kind lang_item,
+ location_t locus);
TypePathSegment (Analysis::NodeMapping mappings, std::string segment_name,
- bool has_separating_scope_resolution, location_t locus)
- : mappings (std::move (mappings)),
- ident_segment (PathIdentSegment (std::move (segment_name))),
- locus (locus),
- has_separating_scope_resolution (has_separating_scope_resolution),
- type (SegmentType::REG)
- {}
+ bool has_separating_scope_resolution, location_t locus);
- virtual std::string as_string () const { return ident_segment.as_string (); }
+ virtual std::string as_string () const
+ {
+ if (ident_segment)
+ return ident_segment->as_string ();
+
+ return LangItem::PrettyString (*lang_item);
+ }
/* Returns whether the type path segment is in an error state. May be virtual
* in future. */
- bool is_error () const { return ident_segment.is_error (); }
+ bool is_error () const
+ {
+ rust_assert (ident_segment);
+ return ident_segment->is_error ();
+ }
/* Returns whether segment is identifier only (as opposed to generic args or
* function). Overriden in derived classes with other segments. */
@@ -489,12 +480,24 @@ public:
const Analysis::NodeMapping &get_mappings () const { return mappings; }
- const PathIdentSegment &get_ident_segment () const { return ident_segment; }
+ const PathIdentSegment &get_ident_segment () const
+ {
+ rust_assert (ident_segment);
+ return *ident_segment;
+ }
+
+ const LangItem::Kind &get_lang_item () const
+ {
+ rust_assert (lang_item);
+ return *lang_item;
+ }
bool is_generic_segment () const
{
return get_type () == SegmentType::GENERIC;
}
+
+ bool is_lang_item () const { return lang_item.has_value (); }
};
// Segment used in type path with generic args
@@ -511,11 +514,11 @@ public:
TypePathSegmentGeneric (Analysis::NodeMapping mappings,
PathIdentSegment ident_segment,
bool has_separating_scope_resolution,
- GenericArgs generic_args, location_t locus)
- : TypePathSegment (std::move (mappings), std::move (ident_segment),
- has_separating_scope_resolution, locus),
- generic_args (std::move (generic_args))
- {}
+ GenericArgs generic_args, location_t locus);
+
+ TypePathSegmentGeneric (Analysis::NodeMapping mappings,
+ LangItem::Kind lang_item, GenericArgs generic_args,
+ location_t locus);
// Constructor from segment name and all args
TypePathSegmentGeneric (Analysis::NodeMapping mappings,
@@ -525,13 +528,7 @@ public:
std::vector<std::unique_ptr<Type> > type_args,
std::vector<GenericArgsBinding> binding_args,
std::vector<ConstGenericArg> const_args,
- location_t locus)
- : TypePathSegment (std::move (mappings), std::move (segment_name),
- has_separating_scope_resolution, locus),
- generic_args (
- GenericArgs (std::move (lifetime_args), std::move (type_args),
- std::move (binding_args), std::move (const_args), locus))
- {}
+ location_t locus);
std::string as_string () const override;
@@ -566,37 +563,15 @@ public:
// Constructor
TypePathFunction (std::vector<std::unique_ptr<Type> > inputs,
- std::unique_ptr<Type> type)
- : inputs (std::move (inputs)), return_type (std::move (type))
- {}
+ std::unique_ptr<Type> type);
// Copy constructor with clone
- TypePathFunction (TypePathFunction const &other)
- {
- return_type = other.has_return_type ()
- ? other.get_return_type ()->clone_type ()
- : nullptr;
-
- inputs.reserve (other.inputs.size ());
- for (const auto &e : other.inputs)
- inputs.push_back (e->clone_type ());
- }
+ TypePathFunction (TypePathFunction const &other);
~TypePathFunction () = default;
// Overloaded assignment operator to clone type
- TypePathFunction &operator= (TypePathFunction const &other)
- {
- return_type = other.has_return_type ()
- ? other.get_return_type ()->clone_type ()
- : nullptr;
-
- inputs.reserve (other.inputs.size ());
- for (const auto &e : other.inputs)
- inputs.push_back (e->clone_type ());
-
- return *this;
- }
+ TypePathFunction &operator= (TypePathFunction const &other);
// move constructors
TypePathFunction (TypePathFunction &&other) = default;
@@ -610,8 +585,8 @@ public:
};
std::vector<std::unique_ptr<Type> > &get_params () { return inputs; };
- const std::unique_ptr<Type> &get_return_type () const { return return_type; };
- std::unique_ptr<Type> &get_return_type () { return return_type; };
+ const Type &get_return_type () const { return *return_type; };
+ Type &get_return_type () { return *return_type; };
};
// Segment used in type path with a function argument
@@ -624,21 +599,13 @@ public:
TypePathSegmentFunction (Analysis::NodeMapping mappings,
PathIdentSegment ident_segment,
bool has_separating_scope_resolution,
- TypePathFunction function_path, location_t locus)
- : TypePathSegment (std::move (mappings), std::move (ident_segment),
- has_separating_scope_resolution, locus),
- function_path (std::move (function_path))
- {}
+ TypePathFunction function_path, location_t locus);
// Constructor with segment name and TypePathFn
TypePathSegmentFunction (Analysis::NodeMapping mappings,
std::string segment_name,
bool has_separating_scope_resolution,
- TypePathFunction function_path, location_t locus)
- : TypePathSegment (std::move (mappings), std::move (segment_name),
- has_separating_scope_resolution, locus),
- function_path (std::move (function_path))
- {}
+ TypePathFunction function_path, location_t locus);
std::string as_string () const override;
@@ -698,35 +665,13 @@ public:
// Constructor
TypePath (Analysis::NodeMapping mappings,
std::vector<std::unique_ptr<TypePathSegment> > segments,
- location_t locus, bool has_opening_scope_resolution = false)
- : TypeNoBounds (mappings, locus),
- has_opening_scope_resolution (has_opening_scope_resolution),
- segments (std::move (segments))
- {}
+ location_t locus, bool has_opening_scope_resolution = false);
// Copy constructor with vector clone
- TypePath (TypePath const &other)
- : TypeNoBounds (other.mappings, other.locus),
- has_opening_scope_resolution (other.has_opening_scope_resolution)
- {
- segments.reserve (other.segments.size ());
- for (const auto &e : other.segments)
- segments.push_back (e->clone_type_path_segment ());
- }
+ TypePath (TypePath const &other);
// Overloaded assignment operator with clone
- TypePath &operator= (TypePath const &other)
- {
- has_opening_scope_resolution = other.has_opening_scope_resolution;
- locus = other.locus;
- mappings = other.mappings;
-
- segments.reserve (other.segments.size ());
- for (const auto &e : other.segments)
- segments.push_back (e->clone_type_path_segment ());
-
- return *this;
- }
+ TypePath &operator= (TypePath const &other);
// move constructors
TypePath (TypePath &&other) = default;
@@ -739,7 +684,7 @@ public:
AST::SimplePath as_simple_path () const;
// Creates a trait bound with a clone of this type path as its only element.
- TraitBound *to_trait_bound (bool in_parens) const override;
+ std::unique_ptr<TraitBound> to_trait_bound (bool in_parens) const override;
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRTypeVisitor &vis) override;
@@ -751,10 +696,7 @@ public:
return segments;
}
- std::unique_ptr<TypePathSegment> &get_final_segment ()
- {
- return segments.back ();
- }
+ TypePathSegment &get_final_segment () { return *segments.back (); }
};
class QualifiedPathType
@@ -767,36 +709,16 @@ class QualifiedPathType
public:
// Constructor
QualifiedPathType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
- std::unique_ptr<TypePath> trait, location_t locus)
- : type (std::move (type)), trait (std::move (trait)), locus (locus),
- mappings (mappings)
- {}
+ std::unique_ptr<TypePath> trait, location_t locus);
// Copy constructor uses custom deep copy for Type to preserve polymorphism
- QualifiedPathType (QualifiedPathType const &other)
- : type (other.type->clone_type ()),
- trait (other.has_as_clause () ? std::unique_ptr<HIR::TypePath> (
- new HIR::TypePath (*other.trait))
- : nullptr),
- locus (other.locus), mappings (other.mappings)
- {}
+ QualifiedPathType (QualifiedPathType const &other);
// default destructor
~QualifiedPathType () = default;
// overload assignment operator to use custom clone method
- QualifiedPathType &operator= (QualifiedPathType const &other)
- {
- type = other.type->clone_type ();
- locus = other.locus;
- mappings = other.mappings;
- trait
- = other.has_as_clause ()
- ? std::unique_ptr<HIR::TypePath> (new HIR::TypePath (*other.trait))
- : nullptr;
-
- return *this;
- }
+ QualifiedPathType &operator= (QualifiedPathType const &other);
// move constructor
QualifiedPathType (QualifiedPathType &&other) = default;
@@ -811,30 +733,24 @@ public:
Analysis::NodeMapping get_mappings () const { return mappings; }
- std::unique_ptr<Type> &get_type () { return type; }
-
- std::unique_ptr<TypePath> &get_trait () { return trait; }
+ bool has_type () { return type != nullptr; }
+ bool has_trait () { return trait != nullptr; }
- bool trait_has_generic_args () const
+ Type &get_type ()
{
- rust_assert (has_as_clause ());
- bool is_generic_seg = trait->get_final_segment ()->get_type ()
- == TypePathSegment::SegmentType::GENERIC;
- if (!is_generic_seg)
- return false;
-
- TypePathSegmentGeneric *seg = static_cast<TypePathSegmentGeneric *> (
- trait->get_final_segment ().get ());
- return seg->has_generic_args ();
+ rust_assert (type);
+ return *type;
}
- GenericArgs &get_trait_generic_args ()
+ TypePath &get_trait ()
{
- rust_assert (trait_has_generic_args ());
- TypePathSegmentGeneric *seg = static_cast<TypePathSegmentGeneric *> (
- trait->get_final_segment ().get ());
- return seg->get_generic_args ();
+ rust_assert (trait);
+ return *trait;
}
+
+ bool trait_has_generic_args () const;
+
+ GenericArgs &get_trait_generic_args ();
};
/* HIR node representing a qualified path-in-expression pattern (path that
@@ -852,11 +768,15 @@ public:
std::vector<PathExprSegment> path_segments,
location_t locus = UNDEF_LOCATION,
std::vector<AST::Attribute> outer_attrs
- = std::vector<AST::Attribute> ())
- : PathPattern (std::move (path_segments)),
- PathExpr (std::move (mappings), std::move (outer_attrs)),
- path_type (std::move (qual_path_type)), locus (locus)
- {}
+ = std::vector<AST::Attribute> ());
+
+ // lang-item constructor
+ QualifiedPathInExpression (Analysis::NodeMapping mappings,
+ QualifiedPathType qual_path_type,
+ LangItem::Kind lang_item,
+ location_t locus = UNDEF_LOCATION,
+ std::vector<AST::Attribute> outer_attrs
+ = std::vector<AST::Attribute> ());
location_t get_locus () const override final { return locus; }
@@ -917,40 +837,13 @@ public:
Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
std::unique_ptr<TypePathSegment> associated_segment,
std::vector<std::unique_ptr<TypePathSegment> > path_segments,
- location_t locus = UNDEF_LOCATION)
- : TypeNoBounds (mappings, locus), path_type (std::move (qual_path_type)),
- associated_segment (std::move (associated_segment)),
- segments (std::move (path_segments))
- {}
+ location_t locus = UNDEF_LOCATION);
// Copy constructor with vector clone
- QualifiedPathInType (QualifiedPathInType const &other)
- : TypeNoBounds (other.mappings, other.locus), path_type (other.path_type)
- {
- auto seg = other.associated_segment->clone_type_path_segment_impl ();
- associated_segment = std::unique_ptr<TypePathSegment> (seg);
-
- segments.reserve (other.segments.size ());
- for (const auto &e : other.segments)
- segments.push_back (e->clone_type_path_segment ());
- }
+ QualifiedPathInType (QualifiedPathInType const &other);
// Overloaded assignment operator with vector clone
- QualifiedPathInType &operator= (QualifiedPathInType const &other)
- {
- auto seg = other.associated_segment->clone_type_path_segment_impl ();
- associated_segment = std::unique_ptr<TypePathSegment> (seg);
-
- path_type = other.path_type;
- locus = other.locus;
- mappings = other.mappings;
-
- segments.reserve (other.segments.size ());
- for (const auto &e : other.segments)
- segments.push_back (e->clone_type_path_segment ());
-
- return *this;
- }
+ QualifiedPathInType &operator= (QualifiedPathInType const &other);
// move constructors
QualifiedPathInType (QualifiedPathInType &&other) = default;
@@ -963,10 +856,7 @@ public:
QualifiedPathType &get_path_type () { return path_type; }
- std::unique_ptr<TypePathSegment> &get_associated_segment ()
- {
- return associated_segment;
- }
+ TypePathSegment &get_associated_segment () { return *associated_segment; }
std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
{
@@ -974,40 +864,6 @@ public:
}
};
-class SimplePathSegment
-{
- Analysis::NodeMapping mappings;
-
-public:
- SimplePathSegment (Analysis::NodeMapping mappings) : mappings (mappings) {}
-
- const Analysis::NodeMapping &get_mappings () const { return mappings; }
-};
-
-class SimplePath
-{
- std::vector<SimplePathSegment> segments;
- Analysis::NodeMapping mappings;
- location_t locus;
-
-public:
- SimplePath (std::vector<SimplePathSegment> segments,
- Analysis::NodeMapping mappings, location_t locus)
- : segments (std::move (segments)), mappings (mappings), locus (locus)
- {}
-
- static HIR::SimplePath create_empty ()
- {
- return HIR::SimplePath ({}, Analysis::NodeMapping::get_error (),
- UNDEF_LOCATION);
- }
-
- bool is_error () const { return segments.empty (); }
-
- const Analysis::NodeMapping &get_mappings () const { return mappings; }
- location_t get_locus () const { return locus; }
-};
-
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-pattern-abstract.h b/gcc/rust/hir/tree/rust-hir-pattern-abstract.h
new file mode 100644
index 0000000..b156a80
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-pattern-abstract.h
@@ -0,0 +1,82 @@
+// Copyright (C) 2020-2024 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_HIR_PATTERN_ABSTRACT_H
+#define RUST_HIR_PATTERN_ABSTRACT_H
+
+#include "rust-hir-visitable.h"
+#include "rust-hir-visitor.h"
+#include "rust-hir-node.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace HIR {
+
+// Pattern base HIR node
+class Pattern : public Node, virtual public FullVisitable
+{
+public:
+ using FullVisitable::accept_vis;
+
+ enum PatternType
+ {
+ PATH,
+ LITERAL,
+ IDENTIFIER,
+ WILDCARD,
+ RANGE,
+ REFERENCE,
+ STRUCT,
+ TUPLE_STRUCT,
+ TUPLE,
+ GROUPED,
+ SLICE,
+ ALT
+ };
+
+ BaseKind get_hir_kind () override final { return PATTERN; }
+
+ // Unique pointer custom clone function
+ std::unique_ptr<Pattern> clone_pattern () const
+ {
+ return std::unique_ptr<Pattern> (clone_pattern_impl ());
+ }
+
+ // possible virtual methods: is_refutable()
+
+ virtual ~Pattern () {}
+
+ virtual std::string as_string () const = 0;
+
+ virtual void accept_vis (HIRPatternVisitor &vis) = 0;
+
+ virtual const Analysis::NodeMapping &get_mappings () const = 0;
+
+ virtual location_t get_locus () const = 0;
+
+ virtual PatternType get_pattern_type () const = 0;
+
+protected:
+ // Clone pattern implementation as pure virtual method
+ virtual Pattern *clone_pattern_impl () const = 0;
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index e5d8371..5cc5c95 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -19,12 +19,13 @@
#ifndef RUST_HIR_PATTERN_H
#define RUST_HIR_PATTERN_H
+#include "rust-hir-pattern-abstract.h"
#include "rust-common.h"
-#include "rust-hir.h"
+#include "rust-hir-literal.h"
+#include "rust-hir-path.h"
namespace Rust {
namespace HIR {
-
// Literal pattern HIR node (comparing to a literal)
class LiteralPattern : public Pattern
{
@@ -132,7 +133,7 @@ public:
bool is_mut () const { return mut == Mutability::Mut; }
bool get_is_ref () const { return is_ref; }
- std::unique_ptr<Pattern> &get_to_bind () { return to_bind; }
+ Pattern &get_to_bind () { return *to_bind; }
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRPatternVisitor &vis) override;
@@ -405,9 +406,9 @@ public:
return PatternType::RANGE;
}
- std::unique_ptr<RangePatternBound> &get_lower_bound () { return lower; }
+ RangePatternBound &get_lower_bound () { return *lower; }
- std::unique_ptr<RangePatternBound> &get_upper_bound () { return upper; }
+ RangePatternBound &get_upper_bound () { return *upper; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -476,7 +477,7 @@ public:
return PatternType::REFERENCE;
}
- std::unique_ptr<Pattern> &get_referenced_pattern () { return pattern; }
+ Pattern &get_referenced_pattern () { return *pattern; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -572,7 +573,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
TupleIndex get_index () { return index; }
- std::unique_ptr<Pattern> &get_tuple_pattern () { return tuple_pattern; }
+ Pattern &get_tuple_pattern () { return *tuple_pattern; }
ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; }
@@ -630,7 +631,7 @@ public:
Identifier get_identifier () const { return ident; }
- std::unique_ptr<Pattern> &get_pattern () { return ident_pattern; }
+ Pattern &get_pattern () { return *ident_pattern; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -1002,7 +1003,7 @@ public:
PathInExpression &get_path () { return path; }
- std::unique_ptr<TupleStructItems> &get_items () { return items; }
+ TupleStructItems &get_items () { return *items; }
const Analysis::NodeMapping &get_mappings () const override final
{
@@ -1221,8 +1222,8 @@ public:
return PatternType::TUPLE;
}
- std::unique_ptr<TuplePatternItems> &get_items () { return items; }
- const std::unique_ptr<TuplePatternItems> &get_items () const { return items; }
+ TuplePatternItems &get_items () { return *items; }
+ const TuplePatternItems &get_items () const { return *items; }
protected:
/* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/hir/tree/rust-hir-simple-path.h b/gcc/rust/hir/tree/rust-hir-simple-path.h
new file mode 100644
index 0000000..7f832ff
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-simple-path.h
@@ -0,0 +1,64 @@
+// Copyright (C) 2020-2024 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_HIR_SIMPLE_PATH_H
+#define RUST_HIR_SIMPLE_PATH_H
+
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace HIR {
+
+class SimplePathSegment
+{
+ Analysis::NodeMapping mappings;
+
+public:
+ SimplePathSegment (Analysis::NodeMapping mappings) : mappings (mappings) {}
+
+ const Analysis::NodeMapping &get_mappings () const { return mappings; }
+};
+
+class SimplePath
+{
+ std::vector<SimplePathSegment> segments;
+ Analysis::NodeMapping mappings;
+ location_t locus;
+
+public:
+ SimplePath (std::vector<SimplePathSegment> segments,
+ Analysis::NodeMapping mappings, location_t locus)
+ : segments (std::move (segments)), mappings (mappings), locus (locus)
+ {}
+
+ static HIR::SimplePath create_empty ()
+ {
+ return HIR::SimplePath ({}, Analysis::NodeMapping::get_error (),
+ UNDEF_LOCATION);
+ }
+
+ bool is_error () const { return segments.empty (); }
+
+ const Analysis::NodeMapping &get_mappings () const { return mappings; }
+ location_t get_locus () const { return locus; }
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.cc b/gcc/rust/hir/tree/rust-hir-stmt.cc
new file mode 100644
index 0000000..fd58e29
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-stmt.cc
@@ -0,0 +1,114 @@
+// Copyright (C) 2020-2024 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-hir-stmt.h"
+#include "optional.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace HIR {
+
+LetStmt::LetStmt (Analysis::NodeMapping mappings,
+ std::unique_ptr<Pattern> variables_pattern,
+ tl::optional<std::unique_ptr<Expr>> init_expr,
+ tl::optional<std::unique_ptr<Expr>> else_expr,
+ tl::optional<std::unique_ptr<Type>> type,
+ AST::AttrVec outer_attrs, location_t locus)
+ : Stmt (std::move (mappings)), outer_attrs (std::move (outer_attrs)),
+ variables_pattern (std::move (variables_pattern)), type (std::move (type)),
+ init_expr (std::move (init_expr)), else_expr (std::move (else_expr)),
+ locus (locus)
+{}
+
+LetStmt::LetStmt (LetStmt const &other)
+ : Stmt (other.mappings), outer_attrs (other.outer_attrs), locus (other.locus)
+{
+ // guard to prevent null dereference (only required if error state)
+ if (other.variables_pattern != nullptr)
+ variables_pattern = other.variables_pattern->clone_pattern ();
+
+ // guard to prevent null dereference (always required)
+ if (other.has_init_expr ())
+ init_expr = other.get_init_expr ().clone_expr ();
+ if (other.has_else_expr ())
+ else_expr = other.get_else_expr ().clone_expr ();
+
+ if (other.has_type ())
+ type = other.get_type ().clone_type ();
+ else
+ type = tl::nullopt;
+}
+
+LetStmt &
+LetStmt::operator= (LetStmt const &other)
+{
+ outer_attrs = other.outer_attrs;
+ locus = other.locus;
+
+ // guard to prevent null dereference (only required if error state)
+ if (other.variables_pattern != nullptr)
+ variables_pattern = other.variables_pattern->clone_pattern ();
+ else
+ variables_pattern = nullptr;
+
+ // guard to prevent null dereference (always required)
+ if (other.has_init_expr ())
+ init_expr = other.get_init_expr ().clone_expr ();
+ else
+ init_expr = nullptr;
+
+ if (other.has_else_expr ())
+ else_expr = other.get_else_expr ().clone_expr ();
+ else
+ else_expr = tl::nullopt;
+
+ if (other.has_type ())
+ type = other.get_type ().clone_type ();
+ else
+ type = tl::nullopt;
+
+ return *this;
+}
+
+ExprStmt::ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr,
+ location_t locus, bool must_be_unit)
+ : Stmt (std::move (mappings)), expr (std::move (expr)), locus (locus),
+ must_be_unit (must_be_unit)
+{}
+
+ExprStmt::ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr,
+ location_t locus)
+ : ExprStmt (std::move (mappings), std::move (expr), locus, false)
+{}
+
+ExprStmt::ExprStmt (ExprStmt const &other)
+ : Stmt (other), expr (other.expr->clone_expr ()), locus (other.locus)
+{}
+
+ExprStmt &
+ExprStmt::operator= (ExprStmt const &other)
+{
+ Stmt::operator= (other);
+ expr = other.expr->clone_expr ();
+ locus = other.locus;
+
+ return *this;
+}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h
index e6e844f..9c1a9ec 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.h
+++ b/gcc/rust/hir/tree/rust-hir-stmt.h
@@ -22,9 +22,48 @@
#include "rust-hir.h"
#include "rust-hir-path.h"
#include "rust-hir-expr.h"
+#include "rust-system.h"
namespace Rust {
namespace HIR {
+/* Base statement abstract class. Note that most "statements" are not allowed in
+ * top-level module scope - only a subclass of statements called "items" are. */
+class Stmt : public Node, public FullVisitable
+{
+public:
+ using FullVisitable::accept_vis;
+
+ // Unique pointer custom clone function
+ std::unique_ptr<Stmt> clone_stmt () const
+ {
+ return std::unique_ptr<Stmt> (clone_stmt_impl ());
+ }
+
+ BaseKind get_hir_kind () override { return STMT; }
+
+ virtual ~Stmt () {}
+
+ virtual std::string as_string () const = 0;
+
+ virtual void accept_vis (HIRStmtVisitor &vis) = 0;
+
+ virtual location_t get_locus () const = 0;
+
+ virtual bool is_unit_check_needed () const { return false; }
+
+ const Analysis::NodeMapping &get_mappings () const { return mappings; }
+
+ virtual bool is_item () const = 0;
+
+protected:
+ Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {}
+
+ // Clone function implementation as pure virtual method
+ virtual Stmt *clone_stmt_impl () const = 0;
+
+ Analysis::NodeMapping mappings;
+};
+
// Just a semi-colon, which apparently is a statement.
class EmptyStmt : public Stmt
{
@@ -59,11 +98,10 @@ class LetStmt : public Stmt
std::unique_ptr<Pattern> variables_pattern;
- // bool has_type;
- std::unique_ptr<Type> type;
+ tl::optional<std::unique_ptr<Type>> type;
- // bool has_init_expr;
- std::unique_ptr<Expr> init_expr;
+ tl::optional<std::unique_ptr<Expr>> init_expr;
+ tl::optional<std::unique_ptr<Expr>> else_expr;
location_t locus;
@@ -72,62 +110,27 @@ public:
bool has_outer_attrs () const { return !outer_attrs.empty (); }
// Returns whether let statement has a given return type.
- bool has_type () const { return type != nullptr; }
+ bool has_type () const { return type.has_value (); }
// Returns whether let statement has an initialisation expression.
- bool has_init_expr () const { return init_expr != nullptr; }
+ bool has_init_expr () const { return init_expr.has_value (); }
+ // Returns whether let statement has a diverging else expression.
+ bool has_else_expr () const { return else_expr.has_value (); }
std::string as_string () const override;
LetStmt (Analysis::NodeMapping mappings,
std::unique_ptr<Pattern> variables_pattern,
- std::unique_ptr<Expr> init_expr, std::unique_ptr<Type> type,
- AST::AttrVec outer_attrs, location_t locus)
- : Stmt (std::move (mappings)), outer_attrs (std::move (outer_attrs)),
- variables_pattern (std::move (variables_pattern)),
- type (std::move (type)), init_expr (std::move (init_expr)), locus (locus)
- {}
+ tl::optional<std::unique_ptr<Expr>> init_expr,
+ tl::optional<std::unique_ptr<Expr>> else_expr,
+ tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs,
+ location_t locus);
// Copy constructor with clone
- LetStmt (LetStmt const &other)
- : Stmt (other.mappings), outer_attrs (other.outer_attrs),
- locus (other.locus)
- {
- // guard to prevent null dereference (only required if error state)
- if (other.variables_pattern != nullptr)
- variables_pattern = other.variables_pattern->clone_pattern ();
-
- // guard to prevent null dereference (always required)
- if (other.init_expr != nullptr)
- init_expr = other.init_expr->clone_expr ();
- if (other.type != nullptr)
- type = other.type->clone_type ();
- }
+ LetStmt (LetStmt const &other);
// Overloaded assignment operator to clone
- LetStmt &operator= (LetStmt const &other)
- {
- outer_attrs = other.outer_attrs;
- locus = other.locus;
-
- // guard to prevent null dereference (only required if error state)
- if (other.variables_pattern != nullptr)
- variables_pattern = other.variables_pattern->clone_pattern ();
- else
- variables_pattern = nullptr;
-
- // guard to prevent null dereference (always required)
- if (other.init_expr != nullptr)
- init_expr = other.init_expr->clone_expr ();
- else
- init_expr = nullptr;
- if (other.type != nullptr)
- type = other.type->clone_type ();
- else
- type = nullptr;
-
- return *this;
- }
+ LetStmt &operator= (LetStmt const &other);
// move constructors
LetStmt (LetStmt &&other) = default;
@@ -144,11 +147,43 @@ public:
}
std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
- std::unique_ptr<HIR::Type> &get_type () { return type; }
+ HIR::Type &get_type ()
+ {
+ rust_assert (*type);
+ return *type.value ();
+ }
+
+ const HIR::Type &get_type () const
+ {
+ rust_assert (*type);
+ return *type.value ();
+ }
- std::unique_ptr<HIR::Expr> &get_init_expr () { return init_expr; }
+ HIR::Expr &get_init_expr ()
+ {
+ rust_assert (*init_expr);
+ return *init_expr.value ();
+ }
- std::unique_ptr<HIR::Pattern> &get_pattern () { return variables_pattern; }
+ const HIR::Expr &get_init_expr () const
+ {
+ rust_assert (*init_expr);
+ return *init_expr.value ();
+ }
+
+ HIR::Expr &get_else_expr ()
+ {
+ rust_assert (*else_expr);
+ return *else_expr.value ();
+ }
+
+ const HIR::Expr &get_else_expr () const
+ {
+ rust_assert (*else_expr);
+ return *else_expr.value ();
+ }
+
+ HIR::Pattern &get_pattern () { return *variables_pattern; }
bool is_item () const override final { return false; }
@@ -167,15 +202,10 @@ class ExprStmt : public Stmt
public:
ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr,
- location_t locus, bool must_be_unit)
- : Stmt (std::move (mappings)), expr (std::move (expr)), locus (locus),
- must_be_unit (must_be_unit)
- {}
+ location_t locus, bool must_be_unit);
ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr,
- location_t locus)
- : ExprStmt (std::move (mappings), std::move (expr), locus, false)
- {}
+ location_t locus);
std::string as_string () const override;
@@ -186,22 +216,13 @@ public:
bool is_item () const override final { return false; }
- std::unique_ptr<Expr> &get_expr () { return expr; }
+ Expr &get_expr () { return *expr; }
// Copy constructor with clone
- ExprStmt (ExprStmt const &other)
- : Stmt (other), expr (other.expr->clone_expr ()), locus (other.locus)
- {}
+ ExprStmt (ExprStmt const &other);
// Overloaded assignment operator to clone
- ExprStmt &operator= (ExprStmt const &other)
- {
- Stmt::operator= (other);
- expr = other.expr->clone_expr ();
- locus = other.locus;
-
- return *this;
- }
+ ExprStmt &operator= (ExprStmt const &other);
// move constructors
ExprStmt (ExprStmt &&other) = default;
diff --git a/gcc/rust/hir/tree/rust-hir-trait-bound.h b/gcc/rust/hir/tree/rust-hir-trait-bound.h
new file mode 100644
index 0000000..d20fa79
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-trait-bound.h
@@ -0,0 +1,87 @@
+// Copyright (C) 2020-2024 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_HIR_TRAIT_BOUND_H
+#define RUST_HIR_TRAIT_BOUND_H
+
+#include "rust-hir-bound-abstract.h"
+#include "rust-hir-path.h"
+#include "rust-hir-generic-param.h"
+
+namespace Rust {
+namespace HIR {
+
+// A trait bound
+class TraitBound : public TypeParamBound
+{
+ bool in_parens;
+ BoundPolarity polarity;
+ std::vector<LifetimeParam> for_lifetimes;
+ TypePath type_path;
+ location_t locus;
+
+ Analysis::NodeMapping mappings;
+
+public:
+ // Returns whether trait bound has "for" lifetimes
+ bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
+
+ TraitBound (Analysis::NodeMapping mapping, TypePath type_path,
+ location_t locus, bool in_parens = false,
+ BoundPolarity polarity = BoundPolarity::RegularBound,
+ std::vector<LifetimeParam> for_lifetimes
+ = std::vector<LifetimeParam> ())
+ : in_parens (in_parens), polarity (polarity),
+ for_lifetimes (std::move (for_lifetimes)),
+ type_path (std::move (type_path)), locus (locus), mappings (mapping)
+ {}
+
+ std::string as_string () const override;
+
+ location_t get_locus () const override final { return locus; }
+
+ void accept_vis (HIRFullVisitor &vis) override;
+
+ Analysis::NodeMapping get_mappings () const override final
+ {
+ return mappings;
+ }
+
+ std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
+ bool get_in_parens () { return in_parens; }
+ BoundPolarity get_polarity () { return polarity; }
+
+ BoundType get_bound_type () const final override { return TRAITBOUND; }
+
+ TypePath &get_path () { return type_path; }
+
+ const TypePath &get_path () const { return type_path; }
+
+protected:
+ /* Use covariance to implement clone function as returning this object rather
+ * than base */
+ TraitBound *clone_type_param_bound_impl () const override
+ {
+ return new TraitBound (*this);
+ }
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/util/rust-make-unique.h b/gcc/rust/hir/tree/rust-hir-type-abstract.cc
index ef58991..901c603 100644
--- a/gcc/rust/util/rust-make-unique.h
+++ b/gcc/rust/hir/tree/rust-hir-type-abstract.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2025 Free Software Foundation, Inc.
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
// This file is part of GCC.
@@ -16,20 +16,17 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#ifndef RUST_MAKE_UNIQUE_H
-#define RUST_MAKE_UNIQUE_H
-
-#include "rust-system.h"
+#include "rust-hir-type-abstract.h"
+#include "rust-hir-trait-bound.h"
namespace Rust {
+namespace HIR {
-template <typename T, typename... Ts>
-std::unique_ptr<T>
-make_unique (Ts &&...params)
+std::unique_ptr<TraitBound>
+Type::to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const
{
- return std::unique_ptr<T> (new T (std::forward<Ts> (params)...));
+ return std::unique_ptr<TraitBound> (nullptr);
}
+} // namespace HIR
} // namespace Rust
-
-#endif // RUST_MAKE_UNIQUE_H
diff --git a/gcc/rust/hir/tree/rust-hir-type-abstract.h b/gcc/rust/hir/tree/rust-hir-type-abstract.h
new file mode 100644
index 0000000..6142d88
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-type-abstract.h
@@ -0,0 +1,80 @@
+// Copyright (C) 2020-2024 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_HIR_TYPE_ABSTRACT_H
+#define RUST_HIR_TYPE_ABSTRACT_H
+
+#include "rust-hir-node.h"
+#include "rust-hir-visitable.h"
+#include "rust-system.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace HIR {
+
+class TraitBound;
+
+// Base class for types as represented in HIR - abstract
+class Type : public Node, public FullVisitable
+{
+public:
+ using FullVisitable::accept_vis;
+ // Unique pointer custom clone function
+ std::unique_ptr<Type> clone_type () const
+ {
+ return std::unique_ptr<Type> (clone_type_impl ());
+ }
+
+ // virtual destructor
+ virtual ~Type () {}
+
+ BaseKind get_hir_kind () override final { return TYPE; }
+
+ virtual std::string as_string () const = 0;
+
+ /* HACK: convert to trait bound. Virtual method overriden by classes that
+ * enable this. */
+ virtual std::unique_ptr<TraitBound>
+ to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const;
+ /* as pointer, shouldn't require definition beforehand, only forward
+ * declaration. */
+
+ virtual void accept_vis (HIRTypeVisitor &vis) = 0;
+
+ virtual const Analysis::NodeMapping &get_mappings () const
+ {
+ return mappings;
+ }
+ virtual location_t get_locus () const { return locus; }
+
+protected:
+ Type (Analysis::NodeMapping mappings, location_t locus)
+ : mappings (mappings), locus (locus)
+ {}
+
+ // Clone function implementation as pure virtual method
+ virtual Type *clone_type_impl () const = 0;
+
+ Analysis::NodeMapping mappings;
+ location_t locus;
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-type-no-bounds.h b/gcc/rust/hir/tree/rust-hir-type-no-bounds.h
new file mode 100644
index 0000000..b86ff30
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-type-no-bounds.h
@@ -0,0 +1,58 @@
+
+// Copyright (C) 2020-2024 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_HIR_TYPE_NO_BOUNDS_H
+#define RUST_HIR_TYPE_NO_BOUNDS_H
+
+#include "rust-hir-type-abstract.h"
+
+namespace Rust {
+namespace HIR {
+
+// A type without parentheses? - abstract
+class TypeNoBounds : public Type
+{
+public:
+ // Unique pointer custom clone function
+ std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const
+ {
+ return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
+ }
+
+protected:
+ TypeNoBounds (Analysis::NodeMapping mappings, location_t locus)
+ : Type (mappings, locus)
+ {}
+
+ // Clone function implementation as pure virtual method
+ virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
+
+ /* Save having to specify two clone methods in derived classes by making type
+ * clone return typenobounds clone. Hopefully won't affect performance too
+ * much. */
+ TypeNoBounds *clone_type_impl () const override
+ {
+ return clone_type_no_bounds_impl ();
+ }
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-type.cc b/gcc/rust/hir/tree/rust-hir-type.cc
new file mode 100644
index 0000000..ec48425
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-type.cc
@@ -0,0 +1,290 @@
+
+// Copyright (C) 2020-2024 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-hir-type.h"
+
+namespace Rust {
+namespace HIR {
+
+ImplTraitType::ImplTraitType (
+ Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
+ location_t locus)
+ : Type (mappings, locus), type_param_bounds (std::move (type_param_bounds))
+{}
+
+ImplTraitType::ImplTraitType (ImplTraitType const &other)
+ : Type (other.mappings, other.locus)
+{
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+}
+
+ImplTraitType &
+ImplTraitType::operator= (ImplTraitType const &other)
+{
+ locus = other.locus;
+ mappings = other.mappings;
+
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+
+ return *this;
+}
+
+TraitObjectType::TraitObjectType (
+ Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
+ location_t locus, bool is_dyn_dispatch)
+ : Type (mappings, locus), has_dyn (is_dyn_dispatch),
+ type_param_bounds (std::move (type_param_bounds))
+{}
+
+TraitObjectType::TraitObjectType (TraitObjectType const &other)
+ : Type (other.mappings, other.locus), has_dyn (other.has_dyn)
+{
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+}
+
+TraitObjectType &
+TraitObjectType::operator= (TraitObjectType const &other)
+{
+ mappings = other.mappings;
+ has_dyn = other.has_dyn;
+ locus = other.locus;
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+ for (const auto &e : other.type_param_bounds)
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+
+ return *this;
+}
+
+ParenthesisedType::ParenthesisedType (Analysis::NodeMapping mappings,
+ std::unique_ptr<Type> type_inside_parens,
+ location_t locus)
+ : TypeNoBounds (mappings, locus),
+ type_in_parens (std::move (type_inside_parens))
+{}
+
+ParenthesisedType::ParenthesisedType (ParenthesisedType const &other)
+ : TypeNoBounds (other.mappings, other.locus),
+ type_in_parens (other.type_in_parens->clone_type ())
+{}
+
+ParenthesisedType &
+ParenthesisedType::operator= (ParenthesisedType const &other)
+{
+ mappings = other.mappings;
+ type_in_parens = other.type_in_parens->clone_type ();
+ locus = other.locus;
+ return *this;
+}
+
+std::unique_ptr<TraitBound>
+ParenthesisedType::to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const
+{
+ /* NOTE: obviously it is unknown whether the internal type is a trait bound
+ * due to polymorphism, so just let the internal type handle it. As
+ * parenthesised type, it must be in parentheses. */
+ return type_in_parens->to_trait_bound (true);
+}
+
+TupleType::TupleType (Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<Type>> elems,
+ location_t locus)
+ : TypeNoBounds (mappings, locus), elems (std::move (elems))
+{}
+
+TupleType::TupleType (TupleType const &other)
+ : TypeNoBounds (other.mappings, other.locus)
+{
+ mappings = other.mappings;
+ elems.reserve (other.elems.size ());
+ for (const auto &e : other.elems)
+ elems.push_back (e->clone_type ());
+}
+
+TupleType &
+TupleType::operator= (TupleType const &other)
+{
+ locus = other.locus;
+
+ elems.reserve (other.elems.size ());
+ for (const auto &e : other.elems)
+ elems.push_back (e->clone_type ());
+
+ return *this;
+}
+
+NeverType::NeverType (Analysis::NodeMapping mappings, location_t locus)
+ : TypeNoBounds (mappings, locus)
+{}
+
+RawPointerType::RawPointerType (Analysis::NodeMapping mappings, Mutability mut,
+ std::unique_ptr<Type> type, location_t locus)
+ : TypeNoBounds (mappings, locus), mut (mut), type (std::move (type))
+{}
+
+RawPointerType::RawPointerType (RawPointerType const &other)
+ : TypeNoBounds (other.mappings, other.locus), mut (other.mut),
+ type (other.type->clone_type ())
+{}
+
+RawPointerType &
+RawPointerType::operator= (RawPointerType const &other)
+{
+ mappings = other.mappings;
+ mut = other.mut;
+ type = other.type->clone_type ();
+ locus = other.locus;
+ return *this;
+}
+
+ReferenceType::ReferenceType (Analysis::NodeMapping mappings, Mutability mut,
+ std::unique_ptr<Type> type_no_bounds,
+ location_t locus, tl::optional<Lifetime> lifetime)
+ : TypeNoBounds (mappings, locus), lifetime (std::move (lifetime)), mut (mut),
+ type (std::move (type_no_bounds))
+{}
+
+ReferenceType::ReferenceType (ReferenceType const &other)
+ : TypeNoBounds (other.mappings, other.locus), lifetime (other.lifetime),
+ mut (other.mut), type (other.type->clone_type ())
+{}
+
+ReferenceType &
+ReferenceType::operator= (ReferenceType const &other)
+{
+ mappings = other.mappings;
+ lifetime = other.lifetime;
+ mut = other.mut;
+ type = other.type->clone_type ();
+ locus = other.locus;
+
+ return *this;
+}
+
+ArrayType::ArrayType (Analysis::NodeMapping mappings,
+ std::unique_ptr<Type> type,
+ std::unique_ptr<Expr> array_size, location_t locus)
+ : TypeNoBounds (mappings, locus), elem_type (std::move (type)),
+ size (std::move (array_size))
+{}
+
+ArrayType::ArrayType (ArrayType const &other)
+ : TypeNoBounds (other.mappings, other.locus),
+ elem_type (other.elem_type->clone_type ()), size (other.size->clone_expr ())
+{}
+
+ArrayType &
+ArrayType::operator= (ArrayType const &other)
+{
+ mappings = other.mappings;
+ elem_type = other.elem_type->clone_type ();
+ size = other.size->clone_expr ();
+ locus = other.locus;
+ return *this;
+}
+
+SliceType::SliceType (Analysis::NodeMapping mappings,
+ std::unique_ptr<Type> type, location_t locus)
+ : TypeNoBounds (mappings, locus), elem_type (std::move (type))
+{}
+
+SliceType::SliceType (SliceType const &other)
+ : TypeNoBounds (other.mappings, other.locus),
+ elem_type (other.elem_type->clone_type ())
+{}
+
+SliceType &
+SliceType::operator= (SliceType const &other)
+{
+ mappings = other.mappings;
+ elem_type = other.elem_type->clone_type ();
+ locus = other.locus;
+
+ return *this;
+}
+
+InferredType::InferredType (Analysis::NodeMapping mappings, location_t locus)
+ : TypeNoBounds (mappings, locus)
+{}
+
+MaybeNamedParam::MaybeNamedParam (Identifier name, ParamKind param_kind,
+ std::unique_ptr<Type> param_type,
+ location_t locus)
+ : param_type (std::move (param_type)), param_kind (param_kind),
+ name (std::move (name)), locus (locus)
+{}
+
+MaybeNamedParam::MaybeNamedParam (MaybeNamedParam const &other)
+ : param_type (other.param_type->clone_type ()), param_kind (other.param_kind),
+ name (other.name), locus (other.locus)
+{}
+
+MaybeNamedParam &
+MaybeNamedParam::operator= (MaybeNamedParam const &other)
+{
+ name = other.name;
+ param_kind = other.param_kind;
+ param_type = other.param_type->clone_type ();
+ locus = other.locus;
+
+ return *this;
+}
+
+BareFunctionType::BareFunctionType (
+ Analysis::NodeMapping mappings, std::vector<LifetimeParam> lifetime_params,
+ FunctionQualifiers qualifiers, std::vector<MaybeNamedParam> named_params,
+ bool is_variadic, std::unique_ptr<Type> type, location_t locus)
+ : TypeNoBounds (mappings, locus), for_lifetimes (std::move (lifetime_params)),
+ function_qualifiers (std::move (qualifiers)),
+ params (std::move (named_params)), is_variadic (is_variadic),
+ return_type (std::move (type))
+{}
+
+BareFunctionType::BareFunctionType (BareFunctionType const &other)
+ : TypeNoBounds (other.mappings, other.locus),
+ for_lifetimes (other.for_lifetimes),
+ function_qualifiers (other.function_qualifiers), params (other.params),
+ is_variadic (other.is_variadic),
+ return_type (other.has_return_type () ? other.return_type->clone_type ()
+ : nullptr)
+{}
+
+BareFunctionType &
+BareFunctionType::operator= (BareFunctionType const &other)
+{
+ mappings = other.mappings;
+ for_lifetimes = other.for_lifetimes;
+ function_qualifiers = other.function_qualifiers;
+ params = other.params;
+ is_variadic = other.is_variadic;
+ return_type = other.return_type->clone_type ();
+ locus = other.locus;
+
+ return *this;
+}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
index e4a9754..cbc20ff 100644
--- a/gcc/rust/hir/tree/rust-hir-type.h
+++ b/gcc/rust/hir/tree/rust-hir-type.h
@@ -19,73 +19,13 @@
#ifndef RUST_HIR_TYPE_H
#define RUST_HIR_TYPE_H
+#include "rust-hir-type-abstract.h"
#include "rust-common.h"
-#include "rust-hir.h"
-#include "rust-hir-path.h"
+#include "rust-hir-trait-bound.h"
+#include "rust-hir-item.h"
namespace Rust {
namespace HIR {
-// definitions moved to rust-ast.h
-class TypeParamBound;
-class Lifetime;
-
-// A trait bound
-class TraitBound : public TypeParamBound
-{
- bool in_parens;
- BoundPolarity polarity;
- std::vector<LifetimeParam> for_lifetimes;
- TypePath type_path;
- location_t locus;
-
- Analysis::NodeMapping mappings;
-
-public:
- // Returns whether trait bound has "for" lifetimes
- bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
-
- TraitBound (Analysis::NodeMapping mapping, TypePath type_path,
- location_t locus, bool in_parens = false,
- BoundPolarity polarity = BoundPolarity::RegularBound,
- std::vector<LifetimeParam> for_lifetimes
- = std::vector<LifetimeParam> ())
- : in_parens (in_parens), polarity (polarity),
- for_lifetimes (std::move (for_lifetimes)),
- type_path (std::move (type_path)), locus (locus), mappings (mapping)
- {}
-
- std::string as_string () const override;
-
- location_t get_locus () const override final { return locus; }
-
- void accept_vis (HIRFullVisitor &vis) override;
-
- Analysis::NodeMapping get_mappings () const override final
- {
- return mappings;
- }
-
- std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
- bool get_in_parens () { return in_parens; }
- BoundPolarity get_polarity () { return polarity; }
-
- BoundType get_bound_type () const final override { return TRAITBOUND; }
-
- TypePath &get_path () { return type_path; }
-
- const TypePath &get_path () const { return type_path; }
-
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- TraitBound *clone_type_param_bound_impl () const override
- {
- return new TraitBound (*this);
- }
-};
-
-// definition moved to rust-ast.h
-class TypeNoBounds;
// An impl trait? Poor reference material here.
class ImplTraitType : public Type
@@ -105,31 +45,13 @@ protected:
public:
ImplTraitType (Analysis::NodeMapping mappings,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
- location_t locus)
- : Type (mappings, locus), type_param_bounds (std::move (type_param_bounds))
- {}
+ location_t locus);
// copy constructor with vector clone
- ImplTraitType (ImplTraitType const &other)
- : Type (other.mappings, other.locus)
- {
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
- }
+ ImplTraitType (ImplTraitType const &other);
// overloaded assignment operator to clone
- ImplTraitType &operator= (ImplTraitType const &other)
- {
- locus = other.locus;
- mappings = other.mappings;
-
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
-
- return *this;
- }
+ ImplTraitType &operator= (ImplTraitType const &other);
// move constructors
ImplTraitType (ImplTraitType &&other) = default;
@@ -162,32 +84,13 @@ public:
TraitObjectType (
Analysis::NodeMapping mappings,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
- location_t locus, bool is_dyn_dispatch)
- : Type (mappings, locus), has_dyn (is_dyn_dispatch),
- type_param_bounds (std::move (type_param_bounds))
- {}
+ location_t locus, bool is_dyn_dispatch);
// copy constructor with vector clone
- TraitObjectType (TraitObjectType const &other)
- : Type (other.mappings, other.locus), has_dyn (other.has_dyn)
- {
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
- }
+ TraitObjectType (TraitObjectType const &other);
// overloaded assignment operator to clone
- TraitObjectType &operator= (TraitObjectType const &other)
- {
- mappings = other.mappings;
- has_dyn = other.has_dyn;
- locus = other.locus;
- type_param_bounds.reserve (other.type_param_bounds.size ());
- for (const auto &e : other.type_param_bounds)
- type_param_bounds.push_back (e->clone_type_param_bound ());
-
- return *this;
- }
+ TraitObjectType &operator= (TraitObjectType const &other);
// move constructors
TraitObjectType (TraitObjectType &&other) = default;
@@ -233,26 +136,15 @@ protected:
public:
// Constructor uses Type pointer for polymorphism
ParenthesisedType (Analysis::NodeMapping mappings,
- std::unique_ptr<Type> type_inside_parens, location_t locus)
- : TypeNoBounds (mappings, locus),
- type_in_parens (std::move (type_inside_parens))
- {}
+ std::unique_ptr<Type> type_inside_parens,
+ location_t locus);
/* Copy constructor uses custom deep copy method for type to preserve
* polymorphism */
- ParenthesisedType (ParenthesisedType const &other)
- : TypeNoBounds (other.mappings, other.locus),
- type_in_parens (other.type_in_parens->clone_type ())
- {}
+ ParenthesisedType (ParenthesisedType const &other);
// overload assignment operator to use custom clone method
- ParenthesisedType &operator= (ParenthesisedType const &other)
- {
- mappings = other.mappings;
- type_in_parens = other.type_in_parens->clone_type ();
- locus = other.locus;
- return *this;
- }
+ ParenthesisedType &operator= (ParenthesisedType const &other);
// default move semantics
ParenthesisedType (ParenthesisedType &&other) = default;
@@ -264,52 +156,14 @@ public:
}
// Creates a trait bound (clone of this one's trait bound) - HACK
- TraitBound *to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const override
- {
- /* NOTE: obviously it is unknown whether the internal type is a trait bound
- * due to polymorphism, so just let the internal type handle it. As
- * parenthesised type, it must be in parentheses. */
- return type_in_parens->to_trait_bound (true);
- }
- std::unique_ptr<Type> &get_type_in_parens () { return type_in_parens; }
- void accept_vis (HIRFullVisitor &vis) override;
- void accept_vis (HIRTypeVisitor &vis) override;
-};
-
-// Impl trait with a single bound? Poor reference material here.
-class ImplTraitTypeOneBound : public TypeNoBounds
-{
- TraitBound trait_bound;
-
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- ImplTraitTypeOneBound *clone_type_impl () const override
- {
- return new ImplTraitTypeOneBound (*this);
- }
+ std::unique_ptr<TraitBound>
+ to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const override;
- /* 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 (Analysis::NodeMapping mappings, TraitBound trait_bound,
- location_t locus)
- : TypeNoBounds (mappings, locus), trait_bound (std::move (trait_bound))
- {}
-
- std::string as_string () const override;
- TraitBound &get_trait_bound () { return trait_bound; }
+ Type &get_type_in_parens () { return *type_in_parens; }
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRTypeVisitor &vis) override;
};
-class TypePath; // definition moved to "rust-path.h"
-
/* A type consisting of the "product" of others (the tuple's elements) in a
* specific order */
class TupleType : public TypeNoBounds
@@ -321,31 +175,13 @@ public:
bool is_unit_type () const { return elems.empty (); }
TupleType (Analysis::NodeMapping mappings,
- std::vector<std::unique_ptr<Type>> elems, location_t locus)
- : TypeNoBounds (mappings, locus), elems (std::move (elems))
- {}
+ std::vector<std::unique_ptr<Type>> elems, location_t locus);
// copy constructor with vector clone
- TupleType (TupleType const &other)
- : TypeNoBounds (other.mappings, other.locus)
- {
- mappings = other.mappings;
- elems.reserve (other.elems.size ());
- for (const auto &e : other.elems)
- elems.push_back (e->clone_type ());
- }
+ TupleType (TupleType const &other);
// overloaded assignment operator to clone
- TupleType &operator= (TupleType const &other)
- {
- locus = other.locus;
-
- elems.reserve (other.elems.size ());
- for (const auto &e : other.elems)
- elems.push_back (e->clone_type ());
-
- return *this;
- }
+ TupleType &operator= (TupleType const &other);
// move constructors
TupleType (TupleType &&other) = default;
@@ -390,9 +226,7 @@ protected:
}
public:
- NeverType (Analysis::NodeMapping mappings, location_t locus)
- : TypeNoBounds (mappings, locus)
- {}
+ NeverType (Analysis::NodeMapping mappings, location_t locus);
std::string as_string () const override { return "! (never type)"; }
@@ -410,25 +244,13 @@ private:
public:
// Constructor requires pointer for polymorphism reasons
RawPointerType (Analysis::NodeMapping mappings, Mutability mut,
- std::unique_ptr<Type> type, location_t locus)
- : TypeNoBounds (mappings, locus), mut (mut), type (std::move (type))
- {}
+ std::unique_ptr<Type> type, location_t locus);
// Copy constructor calls custom polymorphic clone function
- RawPointerType (RawPointerType const &other)
- : TypeNoBounds (other.mappings, other.locus), mut (other.mut),
- type (other.type->clone_type ())
- {}
+ RawPointerType (RawPointerType const &other);
// overload assignment operator to use custom clone method
- RawPointerType &operator= (RawPointerType const &other)
- {
- mappings = other.mappings;
- mut = other.mut;
- type = other.type->clone_type ();
- locus = other.locus;
- return *this;
- }
+ RawPointerType &operator= (RawPointerType const &other);
// default move semantics
RawPointerType (RawPointerType &&other) = default;
@@ -439,7 +261,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRTypeVisitor &vis) override;
- std::unique_ptr<Type> &get_type () { return type; }
+ Type &get_type () { return *type; }
Mutability get_mut () const { return mut; }
@@ -447,7 +269,7 @@ public:
bool is_const () const { return mut == Mutability::Imm; }
- std::unique_ptr<Type> &get_base_type () { return type; }
+ Type &get_base_type () { return *type; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -469,7 +291,7 @@ protected:
class ReferenceType : public TypeNoBounds
{
// bool has_lifetime; // TODO: handle in lifetime or something?
- Lifetime lifetime;
+ tl::optional<Lifetime> lifetime;
Mutability mut;
std::unique_ptr<Type> type;
@@ -479,33 +301,18 @@ public:
bool is_mut () const { return mut == Mutability::Mut; }
// Returns whether the reference has a lifetime.
- bool has_lifetime () const { return !lifetime.is_error (); }
+ bool has_lifetime () const { return lifetime.has_value (); }
// Constructor
ReferenceType (Analysis::NodeMapping mappings, Mutability mut,
std::unique_ptr<Type> type_no_bounds, location_t locus,
- Lifetime lifetime)
- : TypeNoBounds (mappings, locus), lifetime (std::move (lifetime)),
- mut (mut), type (std::move (type_no_bounds))
- {}
+ tl::optional<Lifetime> lifetime);
// Copy constructor with custom clone method
- ReferenceType (ReferenceType const &other)
- : TypeNoBounds (other.mappings, other.locus), lifetime (other.lifetime),
- mut (other.mut), type (other.type->clone_type ())
- {}
+ ReferenceType (ReferenceType const &other);
// Operator overload assignment operator to custom clone the unique pointer
- ReferenceType &operator= (ReferenceType const &other)
- {
- mappings = other.mappings;
- lifetime = other.lifetime;
- mut = other.mut;
- type = other.type->clone_type ();
- locus = other.locus;
-
- return *this;
- }
+ ReferenceType &operator= (ReferenceType const &other);
// move constructors
ReferenceType (ReferenceType &&other) = default;
@@ -516,11 +323,12 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRTypeVisitor &vis) override;
- Lifetime &get_lifetime () { return lifetime; }
+ Lifetime &get_lifetime () { return lifetime.value (); }
+ const Lifetime &get_lifetime () const { return lifetime.value (); }
Mutability get_mut () const { return mut; }
- std::unique_ptr<Type> &get_base_type () { return type; }
+ Type &get_base_type () { return *type; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -547,27 +355,13 @@ class ArrayType : public TypeNoBounds
public:
// Constructor requires pointers for polymorphism
ArrayType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
- std::unique_ptr<Expr> array_size, location_t locus)
- : TypeNoBounds (mappings, locus), elem_type (std::move (type)),
- size (std::move (array_size))
- {}
+ std::unique_ptr<Expr> array_size, location_t locus);
// Copy constructor requires deep copies of both unique pointers
- ArrayType (ArrayType const &other)
- : TypeNoBounds (other.mappings, other.locus),
- elem_type (other.elem_type->clone_type ()),
- size (other.size->clone_expr ())
- {}
+ ArrayType (ArrayType const &other);
// Overload assignment operator to deep copy pointers
- ArrayType &operator= (ArrayType const &other)
- {
- mappings = other.mappings;
- elem_type = other.elem_type->clone_type ();
- size = other.size->clone_expr ();
- locus = other.locus;
- return *this;
- }
+ ArrayType &operator= (ArrayType const &other);
// move constructors
ArrayType (ArrayType &&other) = default;
@@ -578,9 +372,9 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRTypeVisitor &vis) override;
- std::unique_ptr<Type> &get_element_type () { return elem_type; }
+ Type &get_element_type () { return *elem_type; }
- std::unique_ptr<Expr> &get_size_expr () { return size; }
+ Expr &get_size_expr () { return *size; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -604,25 +398,13 @@ class SliceType : public TypeNoBounds
public:
// Constructor requires pointer for polymorphism
SliceType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
- location_t locus)
- : TypeNoBounds (mappings, locus), elem_type (std::move (type))
- {}
+ location_t locus);
// Copy constructor requires deep copy of Type smart pointer
- SliceType (SliceType const &other)
- : TypeNoBounds (other.mappings, other.locus),
- elem_type (other.elem_type->clone_type ())
- {}
+ SliceType (SliceType const &other);
// Overload assignment operator to deep copy
- SliceType &operator= (SliceType const &other)
- {
- mappings = other.mappings;
- elem_type = other.elem_type->clone_type ();
- locus = other.locus;
-
- return *this;
- }
+ SliceType &operator= (SliceType const &other);
// move constructors
SliceType (SliceType &&other) = default;
@@ -633,7 +415,7 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRTypeVisitor &vis) override;
- std::unique_ptr<Type> &get_element_type () { return elem_type; }
+ Type &get_element_type () { return *elem_type; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -669,9 +451,7 @@ protected:
}
public:
- InferredType (Analysis::NodeMapping mappings, location_t locus)
- : TypeNoBounds (mappings, locus)
- {}
+ InferredType (Analysis::NodeMapping mappings, location_t locus);
std::string as_string () const override;
@@ -679,8 +459,6 @@ public:
void accept_vis (HIRTypeVisitor &vis) override;
};
-class QualifiedPathInType; // definition moved to "rust-path.h"
-
// A possibly named param used in a BaseFunctionType
struct MaybeNamedParam
{
@@ -702,29 +480,15 @@ private:
public:
MaybeNamedParam (Identifier name, ParamKind param_kind,
- std::unique_ptr<Type> param_type, location_t locus)
- : param_type (std::move (param_type)), param_kind (param_kind),
- name (std::move (name)), locus (locus)
- {}
+ std::unique_ptr<Type> param_type, location_t locus);
// Copy constructor with clone
- MaybeNamedParam (MaybeNamedParam const &other)
- : param_type (other.param_type->clone_type ()),
- param_kind (other.param_kind), name (other.name), locus (other.locus)
- {}
+ MaybeNamedParam (MaybeNamedParam const &other);
~MaybeNamedParam () = default;
// Overloaded assignment operator with clone
- MaybeNamedParam &operator= (MaybeNamedParam const &other)
- {
- name = other.name;
- param_kind = other.param_kind;
- param_type = other.param_type->clone_type ();
- locus = other.locus;
-
- return *this;
- }
+ MaybeNamedParam &operator= (MaybeNamedParam const &other);
// move constructors
MaybeNamedParam (MaybeNamedParam &&other) = default;
@@ -743,7 +507,7 @@ public:
location_t get_locus () const { return locus; }
- std::unique_ptr<Type> &get_type () { return param_type; }
+ Type &get_type () { return *param_type; }
ParamKind get_param_kind () const { return param_kind; }
@@ -777,36 +541,13 @@ public:
std::vector<LifetimeParam> lifetime_params,
FunctionQualifiers qualifiers,
std::vector<MaybeNamedParam> named_params, bool is_variadic,
- std::unique_ptr<Type> type, location_t locus)
- : TypeNoBounds (mappings, locus),
- for_lifetimes (std::move (lifetime_params)),
- function_qualifiers (std::move (qualifiers)),
- params (std::move (named_params)), is_variadic (is_variadic),
- return_type (std::move (type))
- {}
+ std::unique_ptr<Type> type, location_t locus);
// Copy constructor with clone
- BareFunctionType (BareFunctionType const &other)
- : TypeNoBounds (other.mappings, other.locus),
- for_lifetimes (other.for_lifetimes),
- function_qualifiers (other.function_qualifiers), params (other.params),
- is_variadic (other.is_variadic),
- return_type (other.return_type->clone_type ())
- {}
+ BareFunctionType (BareFunctionType const &other);
// Overload assignment operator to deep copy
- BareFunctionType &operator= (BareFunctionType const &other)
- {
- mappings = other.mappings;
- for_lifetimes = other.for_lifetimes;
- function_qualifiers = other.function_qualifiers;
- params = other.params;
- is_variadic = other.is_variadic;
- return_type = other.return_type->clone_type ();
- locus = other.locus;
-
- return *this;
- }
+ BareFunctionType &operator= (BareFunctionType const &other);
// move constructors
BareFunctionType (BareFunctionType &&other) = default;
@@ -828,7 +569,7 @@ public:
}
// TODO: would a "vis_type" be better?
- std::unique_ptr<Type> &get_return_type () { return return_type; }
+ Type &get_return_type () { return *return_type; }
protected:
/* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/hir/tree/rust-hir-visibility.h b/gcc/rust/hir/tree/rust-hir-visibility.h
new file mode 100644
index 0000000..a750d88
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-visibility.h
@@ -0,0 +1,80 @@
+// Copyright (C) 2020-2024 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_HIR_VISIBILITY_H
+#define RUST_HIR_VISIBILITY_H
+
+#include "rust-hir-simple-path.h"
+
+namespace Rust {
+namespace HIR {
+// Visibility of an item
+struct Visibility
+{
+public:
+ enum VisType
+ {
+ PRIVATE,
+ PUBLIC,
+ RESTRICTED,
+ ERROR,
+ };
+
+private:
+ VisType vis_type;
+ HIR::SimplePath path;
+ location_t locus;
+
+ // should this store location info?
+
+public:
+ Visibility (VisType vis_type,
+ HIR::SimplePath path = HIR::SimplePath::create_empty (),
+ location_t locus = UNDEF_LOCATION)
+ : vis_type (vis_type), path (std::move (path)), locus (locus)
+ {}
+
+ // Returns whether visibility is in an error state.
+ bool is_error () const { return vis_type == ERROR; }
+
+ // Does the current visibility refer to a simple `pub <item>` entirely public
+ bool is_public () const { return vis_type == PUBLIC; }
+
+ // Is the current visibility public restricted to a certain path
+ bool is_restricted () const { return vis_type == RESTRICTED; }
+
+ // Creates an error visibility.
+ static Visibility create_error ()
+ {
+ return Visibility (ERROR, HIR::SimplePath::create_empty ());
+ }
+
+ VisType get_vis_type () const { return vis_type; }
+
+ const HIR::SimplePath &get_path () const
+ {
+ rust_assert (!is_error ());
+ return path;
+ }
+
+ std::string as_string () const;
+};
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-visitable.h b/gcc/rust/hir/tree/rust-hir-visitable.h
new file mode 100644
index 0000000..9c05cbf
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-visitable.h
@@ -0,0 +1,41 @@
+// Copyright (C) 2020-2024 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_HIR_VISITABLE_H
+#define RUST_HIR_VISITABLE_H
+
+namespace Rust {
+namespace HIR {
+
+class HIRFullVisitor;
+class HIRTraitItemVisitor;
+class HIRImplVisitor;
+class HIRStmtVisitor;
+class HIRExpressionVisitor;
+class HIRTypeVisitor;
+class HIRPatternVisitor;
+
+class FullVisitable
+{
+public:
+ virtual void accept_vis (HIRFullVisitor &vis) = 0;
+};
+} // namespace HIR
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index e69e951..283cc34 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -19,7 +19,6 @@
#ifndef RUST_HIR_VISITOR_H
#define RUST_HIR_VISITOR_H
-#include "rust-hir-expr.h"
#include "rust-hir-full-decls.h"
namespace Rust {
@@ -81,12 +80,11 @@ public:
virtual void visit (WhileLetLoopExpr &expr) = 0;
virtual void visit (IfExpr &expr) = 0;
virtual void visit (IfExprConseqElse &expr) = 0;
- virtual void visit (IfLetExpr &expr) = 0;
- virtual void visit (IfLetExprConseqElse &expr) = 0;
virtual void visit (MatchExpr &expr) = 0;
virtual void visit (AwaitExpr &expr) = 0;
virtual void visit (AsyncBlockExpr &expr) = 0;
virtual void visit (InlineAsm &expr) = 0;
+ virtual void visit (LlvmInlineAsm &expr) = 0;
virtual void visit (TypeParam &param) = 0;
virtual void visit (ConstGenericParam &param) = 0;
virtual void visit (LifetimeWhereClauseItem &item) = 0;
@@ -145,7 +143,6 @@ public:
virtual void visit (ImplTraitType &type) = 0;
virtual void visit (TraitObjectType &type) = 0;
virtual void visit (ParenthesisedType &type) = 0;
- virtual void visit (ImplTraitTypeOneBound &type) = 0;
virtual void visit (TupleType &type) = 0;
virtual void visit (NeverType &type) = 0;
virtual void visit (RawPointerType &type) = 0;
@@ -219,13 +216,12 @@ public:
virtual void visit (WhileLetLoopExpr &) override {}
virtual void visit (IfExpr &) override {}
virtual void visit (IfExprConseqElse &) override {}
- virtual void visit (IfLetExpr &) override {}
- virtual void visit (IfLetExprConseqElse &) override {}
virtual void visit (MatchExpr &) override {}
virtual void visit (AwaitExpr &) override {}
virtual void visit (AsyncBlockExpr &) override {}
virtual void visit (InlineAsm &) override {}
+ virtual void visit (LlvmInlineAsm &) override {}
virtual void visit (TypeParam &) override {}
virtual void visit (ConstGenericParam &) override {}
@@ -295,7 +291,6 @@ public:
virtual void visit (ImplTraitType &) override {}
virtual void visit (TraitObjectType &) override {}
virtual void visit (ParenthesisedType &) override {}
- virtual void visit (ImplTraitTypeOneBound &) override {}
virtual void visit (TupleType &) override {}
virtual void visit (NeverType &) override {}
virtual void visit (RawPointerType &) override {}
@@ -359,7 +354,6 @@ public:
virtual void visit (ImplTraitType &type) = 0;
virtual void visit (TraitObjectType &type) = 0;
virtual void visit (ParenthesisedType &type) = 0;
- virtual void visit (ImplTraitTypeOneBound &type) = 0;
virtual void visit (TupleType &type) = 0;
virtual void visit (NeverType &type) = 0;
virtual void visit (RawPointerType &type) = 0;
@@ -448,9 +442,8 @@ public:
virtual void visit (WhileLetLoopExpr &expr) = 0;
virtual void visit (IfExpr &expr) = 0;
virtual void visit (IfExprConseqElse &expr) = 0;
- virtual void visit (IfLetExpr &expr) = 0;
- virtual void visit (IfLetExprConseqElse &expr) = 0;
virtual void visit (InlineAsm &expr) = 0;
+ virtual void visit (LlvmInlineAsm &expr) = 0;
virtual void visit (MatchExpr &expr) = 0;
virtual void visit (AwaitExpr &expr) = 0;
virtual void visit (AsyncBlockExpr &expr) = 0;
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index f05e506..093d8d5 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -19,6 +19,7 @@
#include "rust-ast-full.h"
#include "rust-hir-expr.h"
#include "rust-hir-full.h"
+#include "rust-hir-path.h"
#include "rust-hir-visitor.h"
#include "rust-diagnostics.h"
@@ -70,6 +71,33 @@ get_string_in_delims (std::string str_input, AST::DelimType delim_type)
rust_unreachable ();
}
+Crate::Crate (std::vector<std::unique_ptr<Item>> items,
+ AST::AttrVec inner_attrs, Analysis::NodeMapping mappings)
+ : WithInnerAttrs (std::move (inner_attrs)), items (std::move (items)),
+ mappings (mappings)
+{}
+
+Crate::Crate (Crate const &other)
+ : WithInnerAttrs (other.inner_attrs), mappings (other.mappings)
+{
+ items.reserve (other.items.size ());
+ for (const auto &e : other.items)
+ items.push_back (e->clone_item ());
+}
+
+Crate &
+Crate::operator= (Crate const &other)
+{
+ inner_attrs = other.inner_attrs;
+ mappings = other.mappings;
+
+ items.reserve (other.items.size ());
+ for (const auto &e : other.items)
+ items.push_back (e->clone_item ());
+
+ return *this;
+}
+
std::string
Crate::as_string () const
{
@@ -1183,6 +1211,9 @@ ClosureExpr::as_string () const
std::string
PathPattern::as_string () const
{
+ if (is_lang_item ())
+ return LangItem::PrettyString (*lang_item);
+
std::string str;
for (const auto &segment : segments)
@@ -1283,7 +1314,7 @@ ContinueExpr::as_string () const
if (has_label ())
{
- str += label.as_string ();
+ str += get_label ().as_string ();
}
return str;
@@ -1572,41 +1603,6 @@ IfExprConseqElse::as_string () const
}
std::string
-IfLetExpr::as_string () const
-{
- std::string str ("IfLetExpr: ");
-
- str += "\n Condition match arm patterns: ";
- if (match_arm_patterns.empty ())
- {
- str += "none";
- }
- else
- {
- for (const auto &pattern : match_arm_patterns)
- {
- str += "\n " + pattern->as_string ();
- }
- }
-
- str += "\n Scrutinee expr: " + value->as_string ();
-
- str += "\n If let block expr: " + if_block->as_string ();
-
- return str;
-}
-
-std::string
-IfLetExprConseqElse::as_string () const
-{
- std::string str = IfLetExpr::as_string ();
-
- str += "\n Else expr: " + else_block->as_string ();
-
- return str;
-}
-
-std::string
RangeFromToInclExpr::as_string () const
{
return from->as_string () + "..=" + to->as_string ();
@@ -1708,7 +1704,7 @@ WhileLoopExpr::as_string () const
}
else
{
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
}
str += "\n Conditional expr: " + condition->as_string ();
@@ -1730,7 +1726,7 @@ WhileLetLoopExpr::as_string () const
}
else
{
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
}
str += "\n Match arm patterns: ";
@@ -1765,7 +1761,7 @@ LoopExpr::as_string () const
}
else
{
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
}
str += "\n Loop block: " + loop_block->as_string ();
@@ -1820,7 +1816,7 @@ BreakExpr::as_string () const
if (has_label ())
{
- str += label.as_string () + " ";
+ str += get_label ().as_string () + " ";
}
if (has_break_expr ())
@@ -2105,11 +2101,6 @@ QualifiedPathInType::as_string () const
std::string
Lifetime::as_string () const
{
- if (is_error ())
- {
- return "error lifetime";
- }
-
switch (lifetime_type)
{
case AST::Lifetime::LifetimeType::NAMED:
@@ -2186,7 +2177,7 @@ TypeParam::as_string () const
}
else
{
- str += type->as_string ();
+ str += type.value ()->as_string ();
}
return str;
@@ -2195,6 +2186,8 @@ TypeParam::as_string () const
AST::SimplePath
PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const
{
+ rust_assert (kind == Kind::Segmented);
+
if (!has_segments ())
{
return AST::SimplePath::create_empty ();
@@ -2677,12 +2670,12 @@ LetStmt::as_string () const
if (has_type ())
{
- str += " : " + type->as_string ();
+ str += " : " + get_type ().as_string ();
}
if (has_init_expr ())
{
- str += " = " + init_expr->as_string ();
+ str += " = " + get_init_expr ().as_string ();
}
return str;
@@ -2712,14 +2705,14 @@ Expr::as_string () const
}
// hopefully definition here will prevent circular dependency issue
-TraitBound *
+std::unique_ptr<TraitBound>
TypePath::to_trait_bound (bool in_parens) const
{
// create clone FIXME is this required? or is copy constructor automatically
// called?
TypePath copy (*this);
- return new TraitBound (mappings, std::move (copy), copy.get_locus (),
- in_parens);
+ return std::make_unique<TraitBound> (mappings, std::move (copy),
+ copy.get_locus (), in_parens);
}
std::string
@@ -2762,7 +2755,7 @@ ReferenceType::as_string () const
if (has_lifetime ())
{
- str += lifetime.as_string () + " ";
+ str += get_lifetime ().as_string () + " ";
}
if (is_mut ())
@@ -2868,14 +2861,6 @@ BareFunctionType::as_string () const
}
std::string
-ImplTraitTypeOneBound::as_string () const
-{
- std::string str ("ImplTraitTypeOneBound: \n TraitBound: ");
-
- return str + trait_bound.as_string ();
-}
-
-std::string
TypePathSegmentGeneric::as_string () const
{
return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">";
@@ -3047,7 +3032,7 @@ StructExprStructFields::as_string () const
}
else
{
- str += struct_base->as_string ();
+ str += (*struct_base)->as_string ();
}
return str;
@@ -3421,7 +3406,7 @@ TraitFunctionDecl::as_string () const
str += "\n Function params: ";
if (is_method ())
{
- str += self.as_string () + (has_params () ? ", " : "");
+ str += get_self_unchecked ().as_string () + (has_params () ? ", " : "");
}
if (has_params ())
@@ -3535,70 +3520,63 @@ TraitItemType::as_string () const
std::string
SelfParam::as_string () const
{
- if (is_error ())
- {
- return "error";
- }
- else
+ if (has_type ())
{
- if (has_type ())
+ // type (i.e. not ref, no lifetime)
+ std::string str;
+
+ if (is_mut ())
{
- // type (i.e. not ref, no lifetime)
- std::string str;
+ str += "mut ";
+ }
- if (is_mut ())
- {
- str += "mut ";
- }
+ str += "self : ";
- str += "self : ";
+ str += type->as_string ();
- str += type->as_string ();
+ return str;
+ }
+ else if (has_lifetime ())
+ {
+ // ref and lifetime
+ std::string str = "&" + get_lifetime ().as_string () + " ";
- return str;
- }
- else if (has_lifetime ())
+ if (is_mut ())
{
- // ref and lifetime
- std::string str = "&" + lifetime.as_string () + " ";
+ str += "mut ";
+ }
- if (is_mut ())
- {
- str += "mut ";
- }
+ str += "self";
- str += "self";
+ return str;
+ }
+ else if (is_ref ())
+ {
+ // ref with no lifetime
+ std::string str = "&";
- return str;
- }
- else if (is_ref ())
+ if (is_mut ())
{
- // ref with no lifetime
- std::string str = "&";
+ str += " mut ";
+ }
- if (is_mut ())
- {
- str += " mut ";
- }
+ str += "self";
- str += "self";
+ return str;
+ }
+ else
+ {
+ // no ref, no type
+ std::string str;
- return str;
- }
- else
+ if (is_mut ())
{
- // no ref, no type
- std::string str;
-
- if (is_mut ())
- {
- str += "mut ";
- }
+ str += "mut ";
+ }
- str += "self";
+ str += "self";
- return str;
- }
+ return str;
}
}
@@ -3844,6 +3822,17 @@ InlineAsm::accept_vis (HIRFullVisitor &vis)
}
void
+LlvmInlineAsm::accept_vis (HIRFullVisitor &vis)
+{
+ vis.visit (*this);
+}
+void
+LlvmInlineAsm::accept_vis (HIRExpressionVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
BorrowExpr::accept_vis (HIRExpressionVisitor &vis)
{
vis.visit (*this);
@@ -4030,6 +4019,12 @@ StructExprStructBase::accept_vis (HIRFullVisitor &vis)
}
void
+StructExprStructBase::accept_vis (HIRExpressionVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
CallExpr::accept_vis (HIRFullVisitor &vis)
{
vis.visit (*this);
@@ -4150,18 +4145,6 @@ IfExprConseqElse::accept_vis (HIRFullVisitor &vis)
}
void
-IfLetExpr::accept_vis (HIRFullVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
-IfLetExprConseqElse::accept_vis (HIRFullVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
MatchExpr::accept_vis (HIRFullVisitor &vis)
{
vis.visit (*this);
@@ -4534,12 +4517,6 @@ ParenthesisedType::accept_vis (HIRFullVisitor &vis)
}
void
-ImplTraitTypeOneBound::accept_vis (HIRFullVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
TupleType::accept_vis (HIRFullVisitor &vis)
{
vis.visit (*this);
@@ -4732,12 +4709,6 @@ ArrayType::accept_vis (HIRTypeVisitor &vis)
}
void
-ImplTraitTypeOneBound::accept_vis (HIRTypeVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
BareFunctionType::accept_vis (HIRTypeVisitor &vis)
{
vis.visit (*this);
@@ -4912,18 +4883,6 @@ RangeFromToInclExpr::accept_vis (HIRExpressionVisitor &vis)
}
void
-IfLetExprConseqElse::accept_vis (HIRExpressionVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
-IfLetExpr::accept_vis (HIRExpressionVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
IfExprConseqElse::accept_vis (HIRExpressionVisitor &vis)
{
vis.visit (*this);
@@ -5211,20 +5170,5 @@ StaticItem::accept_vis (HIRVisItemVisitor &vis)
vis.visit (*this);
}
-std::string
-ConstGenericParam::as_string () const
-{
- auto result = "ConstGenericParam: " + name + " : " + type->as_string ();
-
- if (default_expression)
- result += " = " + default_expression->as_string ();
-
- return result;
-}
-
-void
-ConstGenericParam::accept_vis (HIRFullVisitor &)
-{}
-
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index f8eb22d..ffab5ff 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -19,779 +19,24 @@
#ifndef RUST_HIR_BASE_H
#define RUST_HIR_BASE_H
-#include "rust-ast.h"
#include "rust-system.h"
+#include "rust-ast.h"
+#include "rust-hir-visitable.h"
+#include "rust-hir-attrs.h"
+
#include "rust-token.h"
+
#include "rust-location.h"
+
#include "rust-hir-map.h"
#include "rust-diagnostics.h"
+#include "rust-hir-bound.h"
namespace Rust {
+
typedef int TupleIndex;
namespace HIR {
-// foward decl: ast visitor
-class HIRFullVisitor;
-class HIRStmtVisitor;
-class HIRTraitItemVisitor;
-class HIRExternalItemVisitor;
-class HIRVisItemVisitor;
-class HIRExpressionVisitor;
-class HIRPatternVisitor;
-class HIRImplVisitor;
-class HIRTypeVisitor;
-
-class WithOuterAttrs
-{
-protected:
- AST::AttrVec outer_attrs;
-
-public:
- AST::AttrVec &get_outer_attrs () { return outer_attrs; }
- const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
-
- WithOuterAttrs (AST::AttrVec outer_attrs)
- : outer_attrs (std::move (outer_attrs)){};
-};
-
-class WithInnerAttrs
-{
-protected:
- AST::AttrVec inner_attrs;
-
-public:
- AST::AttrVec get_inner_attrs () const { return inner_attrs; }
- WithInnerAttrs (AST::AttrVec inner_attrs)
- : inner_attrs (std::move (inner_attrs)){};
-};
-
-class FullVisitable
-{
-public:
- virtual void accept_vis (HIRFullVisitor &vis) = 0;
-};
-
-// forward decl for use in token tree method
-class Token;
-
-class Node
-{
-public:
- // Kind for downcasting various HIR nodes to other base classes when visiting
- // them
- enum BaseKind
- {
- /* class ExternalItem */
- EXTERNAL,
- /* class TraitItem */
- TRAIT_ITEM,
- /* class VisItem */
- VIS_ITEM,
- /* class Item */
- ITEM,
- /* class ImplItem */
- IMPL,
- /* class Type */
- TYPE,
- /* class Stmt */
- STMT,
- /* class Expr */
- EXPR,
- /* class Pattern */
- PATTERN,
- };
-
- /**
- * Get the kind of HIR node we are dealing with. This is useful for
- * downcasting to more precise types when necessary, i.e going from an `Item*`
- * to a `VisItem*`
- */
- virtual BaseKind get_hir_kind () = 0;
-};
-
-// A literal - value with a type. Used in LiteralExpr and LiteralPattern.
-struct Literal
-{
-public:
- enum LitType
- {
- CHAR,
- STRING,
- BYTE,
- BYTE_STRING,
- INT,
- FLOAT,
- BOOL
- };
-
-private:
- std::string value_as_string;
- LitType type;
- PrimitiveCoreType type_hint;
-
-public:
- std::string as_string () const { return value_as_string; }
-
- LitType get_lit_type () const { return type; }
-
- PrimitiveCoreType get_type_hint () const { return type_hint; }
-
- Literal (std::string value_as_string, LitType type,
- PrimitiveCoreType type_hint)
- : value_as_string (std::move (value_as_string)), type (type),
- type_hint (type_hint)
- {}
-
- static Literal create_error ()
- {
- return Literal ("", CHAR, PrimitiveCoreType::CORETYPE_UNKNOWN);
- }
-
- void set_lit_type (LitType lt) { type = lt; }
-
- // Returns whether literal is in an invalid state.
- bool is_error () const { return value_as_string == ""; }
-
- bool is_equal (Literal &other)
- {
- return value_as_string == other.value_as_string && type == other.type
- && type_hint == other.type_hint;
- }
-};
-
-/* Base statement abstract class. Note that most "statements" are not allowed in
- * top-level module scope - only a subclass of statements called "items" are. */
-class Stmt : public Node, public FullVisitable
-{
-public:
- using FullVisitable::accept_vis;
-
- // Unique pointer custom clone function
- std::unique_ptr<Stmt> clone_stmt () const
- {
- return std::unique_ptr<Stmt> (clone_stmt_impl ());
- }
-
- BaseKind get_hir_kind () override { return STMT; }
-
- virtual ~Stmt () {}
-
- virtual std::string as_string () const = 0;
-
- virtual void accept_vis (HIRStmtVisitor &vis) = 0;
-
- virtual location_t get_locus () const = 0;
-
- virtual bool is_unit_check_needed () const { return false; }
-
- const Analysis::NodeMapping &get_mappings () const { return mappings; }
-
- virtual bool is_item () const = 0;
-
-protected:
- Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {}
-
- // Clone function implementation as pure virtual method
- virtual Stmt *clone_stmt_impl () const = 0;
-
- Analysis::NodeMapping mappings;
-};
-
-// Rust "item" HIR node (declaration of top-level/module-level allowed stuff)
-class Item : public Stmt, public WithOuterAttrs
-{
- // TODO: should outer attrs be defined here or in each derived class?
-public:
- enum class ItemKind
- {
- Static,
- Constant,
- TypeAlias,
- Function,
- UseDeclaration,
- ExternBlock,
- ExternCrate,
- Struct,
- Union,
- Enum,
- EnumItem, // FIXME: ARTHUR: Do we need that?
- Trait,
- Impl,
- Module,
- };
-
- static std::string item_kind_string (ItemKind kind);
-
- virtual ItemKind get_item_kind () const = 0;
-
- // Unique pointer custom clone function
- std::unique_ptr<Item> clone_item () const
- {
- return std::unique_ptr<Item> (clone_item_impl ());
- }
-
- BaseKind get_hir_kind () override { return ITEM; }
-
- std::string as_string () const override;
-
- /* Adds crate names to the vector passed by reference, if it can
- * (polymorphism). */
- virtual void
- add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
- {}
-
- bool is_item () const override final { return true; }
-
-protected:
- // Constructor
- Item (Analysis::NodeMapping mappings,
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : Stmt (std::move (mappings)), WithOuterAttrs (std::move (outer_attribs))
- {}
-
- // Clone function implementation as pure virtual method
- virtual Item *clone_item_impl () const = 0;
-
- /* Save having to specify two clone methods in derived classes by making
- * statement clone return item clone. Hopefully won't affect performance too
- * much. */
- Item *clone_stmt_impl () const override { return clone_item_impl (); }
-};
-
-// forward decl of ExprWithoutBlock
-class ExprWithoutBlock;
-
-// Base expression HIR node - abstract
-class Expr : public Node, virtual public FullVisitable
-{
-public:
- using FullVisitable::accept_vis;
-
-protected:
- AST::AttrVec outer_attrs;
- Analysis::NodeMapping mappings;
-
-public:
- enum BlockType
- {
- WITH_BLOCK,
- WITHOUT_BLOCK,
- };
-
- enum ExprType
- {
- Lit,
- Operator,
- Grouped,
- Array,
- ArrayIndex,
- Tuple,
- TupleIdx,
- Struct,
- Call,
- MethodCall,
- FieldAccess,
- Closure,
- Block,
- Continue,
- Break,
- Range,
- Return,
- UnsafeBlock,
- BaseLoop,
- If,
- IfLet,
- Match,
- Await,
- AsyncBlock,
- Path,
- InlineAsm,
- };
-
- BaseKind get_hir_kind () override final { return EXPR; }
-
- const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
-
- // Unique pointer custom clone function
- std::unique_ptr<Expr> clone_expr () const
- {
- return std::unique_ptr<Expr> (clone_expr_impl ());
- }
-
- // TODO: make pure virtual if move out outer attributes to derived classes
- virtual std::string as_string () const;
-
- virtual ~Expr () {}
-
- virtual location_t get_locus () const = 0;
-
- const Analysis::NodeMapping &get_mappings () const { return mappings; }
-
- // Clone function implementation as pure virtual method
- virtual Expr *clone_expr_impl () const = 0;
-
- virtual BlockType get_block_expr_type () const = 0;
-
- virtual ExprType get_expression_type () const = 0;
-
- virtual void accept_vis (HIRExpressionVisitor &vis) = 0;
-
-protected:
- // Constructor
- Expr (Analysis::NodeMapping mappings,
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : outer_attrs (std::move (outer_attribs)), mappings (std::move (mappings))
- {}
-
- // TODO: think of less hacky way to implement this kind of thing
- // Sets outer attributes.
- void set_outer_attrs (AST::AttrVec outer_attrs_to_set)
- {
- outer_attrs = std::move (outer_attrs_to_set);
- }
-};
-
-// HIR node for an expression without an accompanying block - abstract
-class ExprWithoutBlock : public Expr
-{
-protected:
- // Constructor
- ExprWithoutBlock (Analysis::NodeMapping mappings,
- AST::AttrVec outer_attribs = AST::AttrVec ())
- : Expr (std::move (mappings), std::move (outer_attribs))
- {}
-
- // pure virtual clone implementation
- virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0;
-
- /* Save having to specify two clone methods in derived classes by making expr
- * clone return exprwithoutblock clone. Hopefully won't affect performance too
- * much. */
- ExprWithoutBlock *clone_expr_impl () const override
- {
- return clone_expr_without_block_impl ();
- }
-
-public:
- // Unique pointer custom clone function
- std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const
- {
- return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ());
- }
-
- BlockType get_block_expr_type () const final override
- {
- return BlockType::WITHOUT_BLOCK;
- };
-};
-
-// Pattern base HIR node
-class Pattern : public Node, virtual public FullVisitable
-{
-public:
- using FullVisitable::accept_vis;
-
- enum PatternType
- {
- PATH,
- LITERAL,
- IDENTIFIER,
- WILDCARD,
- RANGE,
- REFERENCE,
- STRUCT,
- TUPLE_STRUCT,
- TUPLE,
- GROUPED,
- SLICE,
- ALT
- };
-
- BaseKind get_hir_kind () override final { return PATTERN; }
-
- // Unique pointer custom clone function
- std::unique_ptr<Pattern> clone_pattern () const
- {
- return std::unique_ptr<Pattern> (clone_pattern_impl ());
- }
-
- // possible virtual methods: is_refutable()
-
- virtual ~Pattern () {}
-
- virtual std::string as_string () const = 0;
-
- virtual void accept_vis (HIRPatternVisitor &vis) = 0;
-
- virtual const Analysis::NodeMapping &get_mappings () const = 0;
-
- virtual location_t get_locus () const = 0;
-
- virtual PatternType get_pattern_type () const = 0;
-
-protected:
- // Clone pattern implementation as pure virtual method
- virtual Pattern *clone_pattern_impl () const = 0;
-};
-
-// forward decl for Type
-class TraitBound;
-
-// Base class for types as represented in HIR - abstract
-class Type : public Node, public FullVisitable
-{
-public:
- using FullVisitable::accept_vis;
- // Unique pointer custom clone function
- std::unique_ptr<Type> clone_type () const
- {
- return std::unique_ptr<Type> (clone_type_impl ());
- }
-
- // virtual destructor
- virtual ~Type () {}
-
- BaseKind get_hir_kind () override final { return TYPE; }
-
- virtual std::string as_string () const = 0;
-
- /* HACK: convert to trait bound. Virtual method overriden by classes that
- * enable this. */
- virtual TraitBound *to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const
- {
- return nullptr;
- }
- /* as pointer, shouldn't require definition beforehand, only forward
- * declaration. */
-
- virtual void accept_vis (HIRTypeVisitor &vis) = 0;
-
- virtual Analysis::NodeMapping get_mappings () const { return mappings; }
- virtual location_t get_locus () const { return locus; }
-
-protected:
- Type (Analysis::NodeMapping mappings, location_t locus)
- : mappings (mappings), locus (locus)
- {}
-
- // Clone function implementation as pure virtual method
- virtual Type *clone_type_impl () const = 0;
-
- Analysis::NodeMapping mappings;
- location_t locus;
-};
-
-// A type without parentheses? - abstract
-class TypeNoBounds : public Type
-{
-public:
- // Unique pointer custom clone function
- std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const
- {
- return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
- }
-
-protected:
- TypeNoBounds (Analysis::NodeMapping mappings, location_t locus)
- : Type (mappings, locus)
- {}
-
- // Clone function implementation as pure virtual method
- virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
-
- /* Save having to specify two clone methods in derived classes by making type
- * clone return typenobounds clone. Hopefully won't affect performance too
- * much. */
- TypeNoBounds *clone_type_impl () const override
- {
- return clone_type_no_bounds_impl ();
- }
-};
-
-/* Abstract base class representing a type param bound - Lifetime and TraitBound
- * extends it */
-class TypeParamBound : public FullVisitable
-{
-public:
- using FullVisitable::accept_vis;
- enum BoundType
- {
- LIFETIME,
- TRAITBOUND
- };
-
- virtual ~TypeParamBound () {}
-
- // Unique pointer custom clone function
- std::unique_ptr<TypeParamBound> clone_type_param_bound () const
- {
- return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
- }
-
- virtual std::string as_string () const = 0;
-
- virtual Analysis::NodeMapping get_mappings () const = 0;
-
- virtual location_t get_locus () const = 0;
-
- virtual BoundType get_bound_type () const = 0;
-
-protected:
- // Clone function implementation as pure virtual method
- virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
-};
-
-// Represents a lifetime (and is also a kind of type param bound)
-class Lifetime : public TypeParamBound
-{
-private:
- AST::Lifetime::LifetimeType lifetime_type;
- std::string lifetime_name;
- location_t locus;
- Analysis::NodeMapping mappings;
-
-public:
- // Constructor
- Lifetime (Analysis::NodeMapping mapping, AST::Lifetime::LifetimeType type,
- std::string name, location_t locus)
- : lifetime_type (type), lifetime_name (std::move (name)), locus (locus),
- mappings (mapping)
- {}
-
- // Returns true if the lifetime is in an error state.
- bool is_error () const
- {
- return lifetime_type == AST::Lifetime::LifetimeType::NAMED
- && lifetime_name.empty ();
- }
-
- static Lifetime error ()
- {
- return Lifetime (Analysis::NodeMapping::get_error (),
- AST::Lifetime::LifetimeType::NAMED, "", UNDEF_LOCATION);
- }
-
- std::string as_string () const override;
-
- void accept_vis (HIRFullVisitor &vis) override;
-
- WARN_UNUSED_RESULT const std::string &get_name () const
- {
- return lifetime_name;
- }
-
- AST::Lifetime::LifetimeType get_lifetime_type () const
- {
- return lifetime_type;
- }
-
- location_t get_locus () const override final { return locus; }
-
- Analysis::NodeMapping get_mappings () const override final
- {
- return mappings;
- }
-
- BoundType get_bound_type () const final override { return LIFETIME; }
-
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- Lifetime *clone_type_param_bound_impl () const override
- {
- return new Lifetime (*this);
- }
-};
-
-/* Base generic parameter in HIR. Abstract - can be represented by a Lifetime or
- * Type param */
-class GenericParam : public FullVisitable
-{
-public:
- using FullVisitable::accept_vis;
-
- virtual ~GenericParam () {}
-
- enum class GenericKind
- {
- TYPE,
- LIFETIME,
- CONST,
- };
-
- virtual AST::AttrVec &get_outer_attrs () = 0;
- virtual bool has_outer_attribute () const = 0;
-
- // Unique pointer custom clone function
- std::unique_ptr<GenericParam> clone_generic_param () const
- {
- return std::unique_ptr<GenericParam> (clone_generic_param_impl ());
- }
-
- virtual std::string as_string () const = 0;
-
- virtual location_t get_locus () const = 0;
-
- Analysis::NodeMapping get_mappings () const { return mappings; }
-
- enum GenericKind get_kind () const { return kind; }
-
-protected:
- // Clone function implementation as pure virtual method
- virtual GenericParam *clone_generic_param_impl () const = 0;
-
- Analysis::NodeMapping mappings;
-
- enum GenericKind kind;
-
- GenericParam (Analysis::NodeMapping mapping,
- enum GenericKind kind = GenericKind::TYPE)
- : mappings (mapping), kind (kind)
- {}
-};
-
-// A lifetime generic parameter (as opposed to a type generic parameter)
-class LifetimeParam : public GenericParam
-{
- Lifetime lifetime;
-
- // bool has_lifetime_bounds;
- // LifetimeBounds lifetime_bounds;
- std::vector<Lifetime> lifetime_bounds; // inlined LifetimeBounds
-
- AST::AttrVec outer_attrs;
-
- location_t locus;
-
-public:
- Lifetime get_lifetime () { return lifetime; }
-
- // Returns whether the lifetime param has any lifetime bounds.
- bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
-
- std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
-
- // Returns whether the lifetime param has an outer attribute.
- bool has_outer_attribute () const override { return outer_attrs.size () > 1; }
-
- AST::AttrVec &get_outer_attrs () { return outer_attrs; }
-
- // Returns whether the lifetime param is in an error state.
- bool is_error () const { return lifetime.is_error (); }
-
- // Constructor
- LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime,
- location_t locus = UNDEF_LOCATION,
- std::vector<Lifetime> lifetime_bounds
- = std::vector<Lifetime> (),
- AST::AttrVec outer_attrs = std::vector<AST::Attribute> ())
- : GenericParam (mappings, GenericKind::LIFETIME),
- lifetime (std::move (lifetime)),
- lifetime_bounds (std::move (lifetime_bounds)),
- outer_attrs (std::move (outer_attrs)), locus (locus)
- {}
-
- // TODO: remove copy and assignment operator definitions - not required
-
- // Copy constructor with clone
- LifetimeParam (LifetimeParam const &other)
- : GenericParam (other.mappings, GenericKind::LIFETIME),
- lifetime (other.lifetime), lifetime_bounds (other.lifetime_bounds),
- outer_attrs (other.outer_attrs), locus (other.locus)
- {}
-
- // Overloaded assignment operator to clone attribute
- LifetimeParam &operator= (LifetimeParam const &other)
- {
- lifetime = other.lifetime;
- lifetime_bounds = other.lifetime_bounds;
- outer_attrs = other.outer_attrs;
- locus = other.locus;
- mappings = other.mappings;
-
- return *this;
- }
-
- // move constructors
- LifetimeParam (LifetimeParam &&other) = default;
- LifetimeParam &operator= (LifetimeParam &&other) = default;
-
- std::string as_string () const override;
-
- void accept_vis (HIRFullVisitor &vis) override;
-
- location_t get_locus () const override final { return locus; }
-
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- LifetimeParam *clone_generic_param_impl () const override
- {
- return new LifetimeParam (*this);
- }
-};
-
-class ConstGenericParam : public GenericParam
-{
-public:
- ConstGenericParam (std::string name, std::unique_ptr<Type> type,
- std::unique_ptr<Expr> default_expression,
- Analysis::NodeMapping mapping, location_t locus)
- : GenericParam (mapping, GenericKind::CONST), name (std::move (name)),
- type (std::move (type)),
- default_expression (std::move (default_expression)), locus (locus)
- {}
-
- ConstGenericParam (const ConstGenericParam &other) : GenericParam (other)
- {
- name = other.name;
- locus = other.locus;
-
- if (other.type)
- type = other.type->clone_type ();
- if (other.default_expression)
- default_expression = other.default_expression->clone_expr ();
- }
-
- bool has_outer_attribute () const override { return false; }
-
- AST::AttrVec &get_outer_attrs () override { return outer_attrs; }
-
- std::string as_string () const override final;
-
- void accept_vis (HIRFullVisitor &vis) override final;
-
- location_t get_locus () const override final { return locus; };
-
- bool has_default_expression () { return default_expression != nullptr; }
-
- std::string get_name () { return name; }
- std::unique_ptr<Type> &get_type () { return type; }
- std::unique_ptr<Expr> &get_default_expression ()
- {
- return default_expression;
- }
-
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- ConstGenericParam *clone_generic_param_impl () const override
- {
- return new ConstGenericParam (*this);
- }
-
-private:
- std::string name;
- std::unique_ptr<Type> type;
-
- /* const params have no outer attrs, should be empty */
- AST::AttrVec outer_attrs = std::vector<AST::Attribute> ();
-
- /* Optional - can be a null pointer if there is no default expression */
- std::unique_ptr<Expr> default_expression;
-
- location_t locus;
-};
// Item used in trait declarations - abstract base class
class TraitItem : public Node, public FullVisitable
@@ -892,34 +137,15 @@ class Crate : public WithInnerAttrs
public:
// Constructor
Crate (std::vector<std::unique_ptr<Item>> items, AST::AttrVec inner_attrs,
- Analysis::NodeMapping mappings)
- : WithInnerAttrs (std::move (inner_attrs)), items (std::move (items)),
- mappings (mappings)
- {}
+ Analysis::NodeMapping mappings);
// Copy constructor with vector clone
- Crate (Crate const &other)
- : WithInnerAttrs (other.inner_attrs), mappings (other.mappings)
- {
- items.reserve (other.items.size ());
- for (const auto &e : other.items)
- items.push_back (e->clone_item ());
- }
+ Crate (Crate const &other);
~Crate () = default;
// Overloaded assignment operator with vector clone
- Crate &operator= (Crate const &other)
- {
- inner_attrs = other.inner_attrs;
- mappings = other.mappings;
-
- items.reserve (other.items.size ());
- for (const auto &e : other.items)
- items.push_back (e->clone_item ());
-
- return *this;
- }
+ Crate &operator= (Crate const &other);
// Move constructors
Crate (Crate &&other) = default;
@@ -932,27 +158,6 @@ public:
std::vector<std::unique_ptr<Item>> &get_items () { return items; }
};
-// Base path expression HIR node - abstract
-class PathExpr : public ExprWithoutBlock
-{
-protected:
- PathExpr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs))
- {}
-
-public:
- /* Replaces the outer attributes of this path expression with the given outer
- * attributes. */
- void replace_outer_attrs (AST::AttrVec outer_attrs)
- {
- set_outer_attrs (std::move (outer_attrs));
- }
-
- ExprType get_expression_type () const final override
- {
- return ExprType::Path;
- }
-};
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
index ae601eb..9cdbce2 100644
--- a/gcc/rust/lang.opt
+++ b/gcc/rust/lang.opt
@@ -212,4 +212,21 @@ frust-borrowcheck
Rust Var(flag_borrowcheck)
Use the WIP borrow checker.
+frust-panic=
+Rust Joined RejectNegative Enum(frust_panic) Var(flag_rust_panic)
+-frust-edition=[unwind|abort] Panic strategy to compile crate with
+
+Enum
+Name(frust_panic) Type(int) UnknownError(unknown panic strategy %qs)
+
+EnumValue
+Enum(frust_panic) String(unwind) Value(0)
+
+EnumValue
+Enum(frust_panic) String(abort) Value(1)
+
+frust-overflow-checks
+Rust Var(flag_overflow_checks) Init(1)
+Enable the overflow checks in code generation
+
; This comment is to ensure we retain the blank line above.
diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index 8490638..b143e70 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -21,7 +21,7 @@
#include "rust-lex.h"
#include "rust-diagnostics.h"
#include "rust-linemap.h"
-#include "rust-session-manager.h"
+#include "rust-edition.h"
#include "safe-ctype.h"
#include "cpplib.h"
#include "rust-keyword-values.h"
@@ -277,9 +277,7 @@ Lexer::classify_keyword (const std::string &str)
// https://doc.rust-lang.org/reference/keywords.html#reserved-keywords
// `try` is not a reserved keyword before 2018
- if (Session::get_instance ().options.get_edition ()
- == CompileOptions::Edition::E2015
- && id == TRY)
+ if (get_rust_edition () == Edition::E2015 && id == TRY)
return IDENTIFIER;
return id;
diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h
index aa2f308..c683ecd 100644
--- a/gcc/rust/lex/rust-token.h
+++ b/gcc/rust/lex/rust-token.h
@@ -21,7 +21,6 @@
#include "rust-system.h"
#include "rust-linemap.h"
-#include "rust-make-unique.h"
#include "rust-unicode.h"
namespace Rust {
@@ -268,7 +267,7 @@ private:
: token_id (token_id), locus (location), type_hint (CORETYPE_UNKNOWN)
{
// Normalize identifier tokens
- str = Rust::make_unique<std::string> (
+ str = std::make_unique<std::string> (
nfc_normalize_token_string (location, token_id, paramStr));
}
@@ -285,7 +284,7 @@ private:
: token_id (token_id), locus (location), type_hint (CORETYPE_UNKNOWN)
{
// Normalize identifier tokens
- str = Rust::make_unique<std::string> (
+ str = std::make_unique<std::string> (
nfc_normalize_token_string (location, token_id,
paramCodepoint.as_string ()));
}
@@ -296,7 +295,7 @@ private:
: token_id (token_id), locus (location), type_hint (parType)
{
// Normalize identifier tokens
- str = Rust::make_unique<std::string> (
+ str = std::make_unique<std::string> (
nfc_normalize_token_string (location, token_id, paramStr));
}
diff --git a/gcc/rust/metadata/rust-export-metadata.cc b/gcc/rust/metadata/rust-export-metadata.cc
index 79c5f30..771bec6 100644
--- a/gcc/rust/metadata/rust-export-metadata.cc
+++ b/gcc/rust/metadata/rust-export-metadata.cc
@@ -234,7 +234,7 @@ PublicInterface::write_to_path (const std::string &path) const
{
// validate path contains correct extension
const std::string expected_file_name = expected_metadata_filename ();
- const char *path_base_name = basename (path.c_str ());
+ const char *path_base_name = lbasename (path.c_str ());
if (strcmp (path_base_name, expected_file_name.c_str ()) != 0)
{
rust_error_at (UNDEF_LOCATION,
diff --git a/gcc/rust/metadata/rust-import-archive.cc b/gcc/rust/metadata/rust-import-archive.cc
index 6c392b0..cf24607 100644
--- a/gcc/rust/metadata/rust-import-archive.cc
+++ b/gcc/rust/metadata/rust-import-archive.cc
@@ -7,7 +7,6 @@
#include "rust-system.h"
#include "rust-diagnostics.h"
#include "rust-imports.h"
-#include "rust-make-unique.h"
#ifndef O_BINARY
#define O_BINARY 0
@@ -844,7 +843,7 @@ Import::find_archive_export_data (const std::string &filename, int fd,
if (!afile.initialize ())
return nullptr;
- auto ret = Rust::make_unique<Stream_concatenate> ();
+ auto ret = std::make_unique<Stream_concatenate> ();
bool any_data = false;
bool any_members = false;
@@ -872,7 +871,7 @@ Import::find_archive_export_data (const std::string &filename, int fd,
if (!any_members)
{
// It's normal to have an empty archive file when using gobuild.
- return Rust::make_unique<Stream_from_string> ("");
+ return std::make_unique<Stream_from_string> ("");
}
if (!any_data)
diff --git a/gcc/rust/metadata/rust-imports.cc b/gcc/rust/metadata/rust-imports.cc
index f2ab105..8d5c381 100644
--- a/gcc/rust/metadata/rust-imports.cc
+++ b/gcc/rust/metadata/rust-imports.cc
@@ -21,7 +21,6 @@
#include "rust-imports.h"
#include "rust-object-export.h"
#include "rust-export-metadata.h"
-#include "rust-make-unique.h"
#ifndef O_BINARY
#define O_BINARY 0
@@ -259,7 +258,7 @@ Import::find_export_data (const std::string &filename, int fd,
//
if (memcmp (buf, Metadata::kMagicHeader, sizeof (Metadata::kMagicHeader))
== 0)
- return Rust::make_unique<Stream_from_file> (fd);
+ return std::make_unique<Stream_from_file> (fd);
// See if we can read this as an archive.
if (Import::is_archive_magic (buf))
@@ -291,7 +290,7 @@ Import::find_object_export_data (const std::string &filename, int fd,
if (buf == nullptr)
return nullptr;
- return Rust::make_unique<Stream_from_buffer> (buf, len);
+ return std::make_unique<Stream_from_buffer> (buf, len);
}
// Class Import.
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index d5383ad..9dda231 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -29,11 +29,10 @@
#include "rust-token.h"
#define INCLUDE_ALGORITHM
#include "rust-diagnostics.h"
-#include "rust-make-unique.h"
#include "rust-dir-owner.h"
#include "rust-attribute-values.h"
#include "rust-keyword-values.h"
-#include "rust-session-manager.h"
+#include "rust-edition.h"
#include "optional.h"
@@ -1454,8 +1453,7 @@ Parser<ManagedTokenSource>::parse_async_item (AST::Visibility vis,
auto offset = (lexer.peek_token ()->get_id () == CONST) ? 1 : 0;
const_TokenPtr t = lexer.peek_token (offset);
- if (Session::get_instance ().options.get_edition ()
- == CompileOptions::Edition::E2015)
+ if (get_rust_edition () == Edition::E2015)
{
add_error (Error (t->get_locus (), ErrorCode::E0670,
"%<async fn%> is not permitted in Rust 2015"));
@@ -3104,7 +3102,7 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token)
{
case LIFETIME: {
auto lifetime = parse_lifetime (false);
- if (lifetime.is_error ())
+ if (!lifetime)
{
rust_error_at (
token->get_locus (),
@@ -3124,7 +3122,7 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token)
}
param = std::unique_ptr<AST::LifetimeParam> (new AST::LifetimeParam (
- std::move (lifetime), std::move (lifetime_bounds),
+ std::move (lifetime.value ()), std::move (lifetime_bounds),
std::move (outer_attrs), token->get_locus ()));
break;
}
@@ -3176,24 +3174,28 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token)
return nullptr;
// optional default value
- auto default_expr = AST::GenericArg::create_error ();
+ tl::optional<AST::GenericArg> default_expr = tl::nullopt;
if (lexer.peek_token ()->get_id () == EQUAL)
{
lexer.skip_token ();
auto tok = lexer.peek_token ();
default_expr = parse_generic_arg ();
- if (default_expr.is_error ())
- rust_error_at (tok->get_locus (),
- "invalid token for start of default value for "
- "const generic parameter: expected %<block%>, "
- "%<identifier%> or %<literal%>, got %qs",
- token_id_to_str (tok->get_id ()));
+ if (!default_expr)
+ {
+ rust_error_at (tok->get_locus (),
+ "invalid token for start of default value for "
+ "const generic parameter: expected %<block%>, "
+ "%<identifier%> or %<literal%>, got %qs",
+ token_id_to_str (tok->get_id ()));
+ return nullptr;
+ }
// At this point, we *know* that we are parsing a const
// expression
- if (default_expr.get_kind () == AST::GenericArg::Kind::Either)
- default_expr = default_expr.disambiguate_to_const ();
+ if (default_expr.value ().get_kind ()
+ == AST::GenericArg::Kind::Either)
+ default_expr = default_expr.value ().disambiguate_to_const ();
}
param = std::unique_ptr<AST::ConstGenericParam> (
@@ -3278,16 +3280,16 @@ Parser<ManagedTokenSource>::parse_lifetime_params ()
while (lexer.peek_token ()->get_id () != END_OF_FILE)
{
- AST::LifetimeParam lifetime_param = parse_lifetime_param ();
+ auto lifetime_param = parse_lifetime_param ();
- if (lifetime_param.is_error ())
+ if (!lifetime_param)
{
// can't treat as error as only way to get out with trailing comma
break;
}
lifetime_params.push_back (std::unique_ptr<AST::LifetimeParam> (
- new AST::LifetimeParam (std::move (lifetime_param))));
+ new AST::LifetimeParam (std::move (lifetime_param.value ()))));
if (lexer.peek_token ()->get_id () != COMMA)
break;
@@ -3313,9 +3315,9 @@ Parser<ManagedTokenSource>::parse_lifetime_params (EndTokenPred is_end_token)
// if end_token is not specified, it defaults to EOF, so should work fine
while (!is_end_token (lexer.peek_token ()->get_id ()))
{
- AST::LifetimeParam lifetime_param = parse_lifetime_param ();
+ auto lifetime_param = parse_lifetime_param ();
- if (lifetime_param.is_error ())
+ if (!lifetime_param)
{
/* TODO: is it worth throwing away all lifetime params just because
* one failed? */
@@ -3353,9 +3355,9 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs ()
// bad control structure as end token cannot be guaranteed
while (true)
{
- AST::LifetimeParam lifetime_param = parse_lifetime_param ();
+ auto lifetime_param = parse_lifetime_param ();
- if (lifetime_param.is_error ())
+ if (!lifetime_param)
{
// not an error as only way to exit if trailing comma
break;
@@ -3388,9 +3390,9 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs (
while (!is_end_token (lexer.peek_token ()->get_id ()))
{
- AST::LifetimeParam lifetime_param = parse_lifetime_param ();
+ auto lifetime_param = parse_lifetime_param ();
- if (lifetime_param.is_error ())
+ if (!lifetime_param)
{
/* TODO: is it worth throwing away all lifetime params just because
* one failed? */
@@ -3401,7 +3403,7 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs (
return {};
}
- lifetime_params.push_back (std::move (lifetime_param));
+ lifetime_params.push_back (std::move (lifetime_param.value ()));
if (lexer.peek_token ()->get_id () != COMMA)
break;
@@ -3460,7 +3462,7 @@ Parser<ManagedTokenSource>::parse_non_ptr_sequence (
/* Parses a single lifetime generic parameter (not including comma). */
template <typename ManagedTokenSource>
-AST::LifetimeParam
+tl::expected<AST::LifetimeParam, ParseLifetimeParamError>
Parser<ManagedTokenSource>::parse_lifetime_param ()
{
// parse outer attributes, which are optional and may not exist
@@ -3470,8 +3472,8 @@ Parser<ManagedTokenSource>::parse_lifetime_param ()
const_TokenPtr lifetime_tok = lexer.peek_token ();
if (lifetime_tok->get_id () != LIFETIME)
{
- // if lifetime is missing, must not be a lifetime param, so return null
- return AST::LifetimeParam::create_error ();
+ // if lifetime is missing, must not be a lifetime param, so return error
+ return tl::make_unexpected<ParseLifetimeParamError> ({});
}
lexer.skip_token ();
AST::Lifetime lifetime (AST::Lifetime::NAMED, lifetime_tok->get_str (),
@@ -3683,7 +3685,7 @@ Parser<ManagedTokenSource>::parse_function_param ()
if (lexer.peek_token ()->get_id () == ELLIPSIS) // Unnamed variadic
{
lexer.skip_token (); // Skip ellipsis
- return Rust::make_unique<AST::VariadicParam> (
+ return std::make_unique<AST::VariadicParam> (
AST::VariadicParam (std::move (outer_attrs), locus));
}
@@ -3705,7 +3707,7 @@ Parser<ManagedTokenSource>::parse_function_param ()
if (lexer.peek_token ()->get_id () == ELLIPSIS) // Named variadic
{
lexer.skip_token (); // Skip ellipsis
- return Rust::make_unique<AST::VariadicParam> (
+ return std::make_unique<AST::VariadicParam> (
AST::VariadicParam (std::move (param_pattern), std::move (outer_attrs),
locus));
}
@@ -3716,7 +3718,7 @@ Parser<ManagedTokenSource>::parse_function_param ()
{
return nullptr;
}
- return Rust::make_unique<AST::FunctionParam> (
+ return std::make_unique<AST::FunctionParam> (
AST::FunctionParam (std::move (param_pattern), std::move (param_type),
std::move (outer_attrs), locus));
}
@@ -3817,12 +3819,13 @@ template <typename ManagedTokenSource>
std::unique_ptr<AST::LifetimeWhereClauseItem>
Parser<ManagedTokenSource>::parse_lifetime_where_clause_item ()
{
- AST::Lifetime lifetime = parse_lifetime (false);
- if (lifetime.is_error ())
+ auto parsed_lifetime = parse_lifetime (false);
+ if (!parsed_lifetime)
{
// TODO: error here?
return nullptr;
}
+ auto lifetime = parsed_lifetime.value ();
if (!skip_token (COLON))
{
@@ -4015,7 +4018,7 @@ Parser<ManagedTokenSource>::parse_type_param_bound ()
{
case LIFETIME:
return std::unique_ptr<AST::Lifetime> (
- new AST::Lifetime (parse_lifetime (false)));
+ new AST::Lifetime (parse_lifetime (false).value ()));
case LEFT_PAREN:
case QUESTION_MARK:
case FOR:
@@ -4088,13 +4091,13 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds ()
while (true)
{
- AST::Lifetime lifetime = parse_lifetime (false);
+ auto lifetime = parse_lifetime (false);
// quick exit for parsing failure
- if (lifetime.is_error ())
+ if (!lifetime)
break;
- lifetime_bounds.push_back (std::move (lifetime));
+ lifetime_bounds.push_back (std::move (lifetime.value ()));
/* plus is maybe not allowed at end - spec defines it weirdly, so
* assuming allowed at end */
@@ -4118,9 +4121,9 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token)
while (!is_end_token (lexer.peek_token ()->get_id ()))
{
- AST::Lifetime lifetime = parse_lifetime (false);
+ auto lifetime = parse_lifetime (false);
- if (lifetime.is_error ())
+ if (!lifetime)
{
/* TODO: is it worth throwing away all lifetime bound info just
* because one failed? */
@@ -4131,7 +4134,7 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token)
return {};
}
- lifetime_bounds.push_back (std::move (lifetime));
+ lifetime_bounds.push_back (std::move (lifetime.value ()));
/* plus is maybe not allowed at end - spec defines it weirdly, so
* assuming allowed at end */
@@ -4148,14 +4151,20 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token)
/* Parses a lifetime token (named, 'static, or '_). Also handles lifetime not
* existing. */
template <typename ManagedTokenSource>
-AST::Lifetime
+tl::expected<AST::Lifetime, ParseLifetimeError>
Parser<ManagedTokenSource>::parse_lifetime (bool allow_elided)
{
const_TokenPtr lifetime_tok = lexer.peek_token ();
if (lifetime_tok->get_id () != LIFETIME)
{
- return (allow_elided) ? AST::Lifetime::elided ()
- : AST::Lifetime::error ();
+ if (allow_elided)
+ {
+ return AST::Lifetime::elided ();
+ }
+ else
+ {
+ return tl::make_unexpected<ParseLifetimeError> ({});
+ }
}
lexer.skip_token ();
@@ -5937,106 +5946,6 @@ Parser<ManagedTokenSource>::parse_extern_block (AST::Visibility vis,
std::move (outer_attrs), locus));
}
-template <typename ManagedTokenSource>
-AST::NamedFunctionParam
-Parser<ManagedTokenSource>::parse_named_function_param ()
-{
- AST::AttrVec outer_attrs = parse_outer_attributes ();
- location_t locus = lexer.peek_token ()->get_locus ();
-
- if (lexer.peek_token ()->get_id () == ELLIPSIS) // Unnamed variadic
- {
- lexer.skip_token (); // Skip ellipsis
- return AST::NamedFunctionParam (std::move (outer_attrs), locus);
- }
-
- // parse identifier/_
- std::string name;
-
- const_TokenPtr t = lexer.peek_token ();
- location_t name_location = t->get_locus ();
- switch (t->get_id ())
- {
- case IDENTIFIER:
- name = t->get_str ();
- lexer.skip_token ();
- break;
- case UNDERSCORE:
- name = "_";
- lexer.skip_token ();
- break;
- default:
- // this is not a function param, but not necessarily an error
- return AST::NamedFunctionParam::create_error ();
- }
-
- if (!skip_token (COLON))
- {
- // skip after somewhere?
- return AST::NamedFunctionParam::create_error ();
- }
-
- if (lexer.peek_token ()->get_id () == ELLIPSIS) // Named variadic
- {
- lexer.skip_token (); // Skip ellipsis
- return AST::NamedFunctionParam (std::move (name), std::move (outer_attrs),
- locus);
- }
-
- // parse (required) type
- std::unique_ptr<AST::Type> param_type = parse_type ();
- if (param_type == nullptr)
- {
- Error error (
- lexer.peek_token ()->get_locus (),
- "could not parse param type in extern block function declaration");
- add_error (std::move (error));
-
- skip_after_semicolon ();
- return AST::NamedFunctionParam::create_error ();
- }
-
- return AST::NamedFunctionParam (std::move (name), std::move (param_type),
- std::move (outer_attrs), name_location);
-}
-
-template <typename ManagedTokenSource>
-template <typename EndTokenPred>
-std::vector<AST::NamedFunctionParam>
-Parser<ManagedTokenSource>::parse_named_function_params (
- EndTokenPred is_end_token)
-{
- std::vector<AST::NamedFunctionParam> params;
- if (is_end_token (lexer.peek_token ()->get_id ()))
- return params;
-
- auto initial_param = parse_named_function_param ();
- if (initial_param.is_error ())
- return params;
-
- params.push_back (std::move (initial_param));
- auto t = lexer.peek_token ();
- while (t->get_id () == COMMA)
- {
- lexer.skip_token ();
- if (is_end_token (lexer.peek_token ()->get_id ()))
- break;
-
- auto param = parse_named_function_param ();
- if (param.is_error ())
- {
- Error error (lexer.peek_token ()->get_locus (),
- "failed to parse param in c function params");
- add_error (error);
- return std::vector<AST::NamedFunctionParam> ();
- }
- params.push_back (std::move (param));
- t = lexer.peek_token ();
- }
- params.shrink_to_fit ();
- return params;
-}
-
// Parses a single extern block item (static or function declaration).
template <typename ManagedTokenSource>
std::unique_ptr<AST::ExternalItem>
@@ -6265,6 +6174,10 @@ Parser<ManagedTokenSource>::parse_let_stmt (AST::AttrVec outer_attrs,
}
}
+ tl::optional<std::unique_ptr<AST::Expr>> else_expr = tl::nullopt;
+ if (maybe_skip_token (ELSE))
+ else_expr = parse_block_expr ();
+
if (restrictions.consume_semi)
{
// `stmt` macro variables are parsed without a semicolon, but should be
@@ -6279,7 +6192,7 @@ Parser<ManagedTokenSource>::parse_let_stmt (AST::AttrVec outer_attrs,
return std::unique_ptr<AST::LetStmt> (
new AST::LetStmt (std::move (pattern), std::move (expr), std::move (type),
- std::move (outer_attrs), locus));
+ std::move (else_expr), std::move (outer_attrs), locus));
}
// Parses a type path.
@@ -6340,7 +6253,7 @@ Parser<ManagedTokenSource>::parse_type_path ()
}
template <typename ManagedTokenSource>
-AST::GenericArg
+tl::optional<AST::GenericArg>
Parser<ManagedTokenSource>::parse_generic_arg ()
{
auto tok = lexer.peek_token ();
@@ -6361,7 +6274,7 @@ Parser<ManagedTokenSource>::parse_generic_arg ()
if (type)
return AST::GenericArg::create_type (std::move (type));
else
- return AST::GenericArg::create_error ();
+ return tl::nullopt;
}
else if (next_tok->get_id () == COLON)
{
@@ -6378,7 +6291,7 @@ Parser<ManagedTokenSource>::parse_generic_arg ()
if (type)
return AST::GenericArg::create_type (std::move (type));
else
- return AST::GenericArg::create_error ();
+ return tl::nullopt;
}
lexer.skip_token ();
return AST::GenericArg::create_ambiguous (tok->get_str (),
@@ -6404,12 +6317,12 @@ Parser<ManagedTokenSource>::parse_generic_arg ()
if (type)
return AST::GenericArg::create_type (std::move (type));
else
- return AST::GenericArg::create_error ();
+ return tl::nullopt;
}
}
if (!expr)
- return AST::GenericArg::create_error ();
+ return tl::nullopt;
return AST::GenericArg::create_const (std::move (expr));
}
@@ -6438,14 +6351,14 @@ Parser<ManagedTokenSource>::parse_path_generic_args ()
location_t locus = t->get_locus ();
while (!is_right_angle_tok (t->get_id ()))
{
- AST::Lifetime lifetime = parse_lifetime (false);
- if (lifetime.is_error ())
+ auto lifetime = parse_lifetime (false);
+ if (!lifetime)
{
// not necessarily an error
break;
}
- lifetime_args.push_back (std::move (lifetime));
+ lifetime_args.push_back (std::move (lifetime.value ()));
// if next token isn't comma, then it must be end of list
if (lexer.peek_token ()->get_id () != COMMA)
@@ -6474,9 +6387,9 @@ Parser<ManagedTokenSource>::parse_path_generic_args ()
break;
auto arg = parse_generic_arg ();
- if (!arg.is_error ())
+ if (arg)
{
- generic_args.emplace_back (std::move (arg));
+ generic_args.emplace_back (std::move (arg.value ()));
}
// FIXME: Do we need to break if we encounter an error?
@@ -7059,10 +6972,12 @@ Parser<ManagedTokenSource>::parse_self_param ()
// now test whether it has a lifetime
if (lexer.peek_token ()->get_id () == LIFETIME)
{
- lifetime = parse_lifetime (true);
-
// something went wrong somehow
- if (lifetime.is_error ())
+ if (auto parsed_lifetime = parse_lifetime (true))
+ {
+ lifetime = parsed_lifetime.value ();
+ }
+ else
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse lifetime in self param");
@@ -7124,14 +7039,14 @@ Parser<ManagedTokenSource>::parse_self_param ()
if (has_reference)
{
- return Rust::make_unique<AST::SelfParam> (std::move (lifetime), has_mut,
- locus);
+ return std::make_unique<AST::SelfParam> (std::move (lifetime), has_mut,
+ locus);
}
else
{
// note that type may be nullptr here and that's fine
- return Rust::make_unique<AST::SelfParam> (std::move (type), has_mut,
- locus);
+ return std::make_unique<AST::SelfParam> (std::move (type), has_mut,
+ locus);
}
}
@@ -7251,9 +7166,9 @@ Parser<ManagedTokenSource>::parse_expr_stmt (AST::AttrVec outer_attrs,
// Parses a block expression, including the curly braces at start and end.
template <typename ManagedTokenSource>
std::unique_ptr<AST::BlockExpr>
-Parser<ManagedTokenSource>::parse_block_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label,
- location_t pratt_parsed_loc)
+Parser<ManagedTokenSource>::parse_block_expr (
+ AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label,
+ location_t pratt_parsed_loc)
{
location_t locus = pratt_parsed_loc;
if (locus == UNKNOWN_LOCATION)
@@ -7617,12 +7532,10 @@ Parser<ManagedTokenSource>::parse_break_expr (AST::AttrVec outer_attrs,
skip_token (BREAK);
}
- // parse label (lifetime) if it exists - create dummy first
- AST::Lifetime label = AST::Lifetime::error ();
- if (lexer.peek_token ()->get_id () == LIFETIME)
- {
- label = parse_lifetime (false);
- }
+ auto parsed_label = parse_lifetime (false);
+ auto label = (parsed_label)
+ ? tl::optional<AST::Lifetime> (parsed_label.value ())
+ : tl::nullopt;
// parse break return expression if it exists
ParseRestrictions restrictions;
@@ -7648,12 +7561,10 @@ Parser<ManagedTokenSource>::parse_continue_expr (AST::AttrVec outer_attrs,
skip_token (CONTINUE);
}
- // parse label (lifetime) if it exists - create dummy first
- AST::Lifetime label = AST::Lifetime::error ();
- if (lexer.peek_token ()->get_id () == LIFETIME)
- {
- label = parse_lifetime (false);
- }
+ auto parsed_label = parse_lifetime (false);
+ auto label = (parsed_label)
+ ? tl::optional<AST::Lifetime> (parsed_label.value ())
+ : tl::nullopt;
return std::unique_ptr<AST::ContinueExpr> (
new AST::ContinueExpr (std::move (label), std::move (outer_attrs), locus));
@@ -7661,14 +7572,15 @@ Parser<ManagedTokenSource>::parse_continue_expr (AST::AttrVec outer_attrs,
// Parses a loop label used in loop expressions.
template <typename ManagedTokenSource>
-AST::LoopLabel
+tl::expected<AST::LoopLabel, ParseLoopLabelError>
Parser<ManagedTokenSource>::parse_loop_label (const_TokenPtr tok)
{
// parse lifetime - if doesn't exist, assume no label
if (tok->get_id () != LIFETIME)
{
// not necessarily an error
- return AST::LoopLabel::error ();
+ return tl::unexpected<ParseLoopLabelError> (
+ ParseLoopLabelError::NOT_LOOP_LABEL);
}
/* FIXME: check for named lifetime requirement here? or check in semantic
* analysis phase? */
@@ -7677,10 +7589,12 @@ Parser<ManagedTokenSource>::parse_loop_label (const_TokenPtr tok)
if (!skip_token (COLON))
{
// skip somewhere?
- return AST::LoopLabel::error ();
+ return tl::unexpected<ParseLoopLabelError> (
+ ParseLoopLabelError::MISSING_COLON);
}
- return AST::LoopLabel (std::move (label), tok->get_locus ());
+ return tl::expected<AST::LoopLabel, ParseLoopLabelError> (
+ AST::LoopLabel (std::move (label), tok->get_locus ()));
}
/* Parses an if expression of any kind, including with else, else if, else if
@@ -8033,16 +7947,16 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec outer_attrs,
template <typename ManagedTokenSource>
std::unique_ptr<AST::LoopExpr>
Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label,
+ tl::optional<AST::LoopLabel> label,
location_t pratt_parsed_loc)
{
location_t locus = pratt_parsed_loc;
if (locus == UNKNOWN_LOCATION)
{
- if (label.is_error ())
- locus = lexer.peek_token ()->get_locus ();
+ if (label)
+ locus = label->get_locus ();
else
- locus = label.get_locus ();
+ locus = lexer.peek_token ()->get_locus ();
if (!skip_token (LOOP))
{
@@ -8052,8 +7966,8 @@ Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs,
}
else
{
- if (!label.is_error ())
- locus = label.get_locus ();
+ if (label)
+ locus = label->get_locus ();
}
// parse loop body, which is required
@@ -8076,17 +7990,17 @@ Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs,
* via parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
std::unique_ptr<AST::WhileLoopExpr>
-Parser<ManagedTokenSource>::parse_while_loop_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label,
- location_t pratt_parsed_loc)
+Parser<ManagedTokenSource>::parse_while_loop_expr (
+ AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label,
+ location_t pratt_parsed_loc)
{
location_t locus = pratt_parsed_loc;
if (locus == UNKNOWN_LOCATION)
{
- if (label.is_error ())
- locus = lexer.peek_token ()->get_locus ();
+ if (label)
+ locus = label->get_locus ();
else
- locus = label.get_locus ();
+ locus = lexer.peek_token ()->get_locus ();
if (!skip_token (WHILE))
{
@@ -8096,8 +8010,8 @@ Parser<ManagedTokenSource>::parse_while_loop_expr (AST::AttrVec outer_attrs,
}
else
{
- if (!label.is_error ())
- locus = label.get_locus ();
+ if (label)
+ locus = label->get_locus ();
}
// ensure it isn't a while let loop
@@ -8149,14 +8063,14 @@ Parser<ManagedTokenSource>::parse_while_loop_expr (AST::AttrVec outer_attrs,
* parsed via parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
std::unique_ptr<AST::WhileLetLoopExpr>
-Parser<ManagedTokenSource>::parse_while_let_loop_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label)
+Parser<ManagedTokenSource>::parse_while_let_loop_expr (
+ AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label)
{
location_t locus = UNKNOWN_LOCATION;
- if (label.is_error ())
- locus = lexer.peek_token ()->get_locus ();
+ if (label)
+ locus = label->get_locus ();
else
- locus = label.get_locus ();
+ locus = lexer.peek_token ()->get_locus ();
maybe_skip_token (WHILE);
/* check for possible accidental recognition of a while loop as a while let
@@ -8223,14 +8137,14 @@ Parser<ManagedTokenSource>::parse_while_let_loop_expr (AST::AttrVec outer_attrs,
* parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
std::unique_ptr<AST::ForLoopExpr>
-Parser<ManagedTokenSource>::parse_for_loop_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label)
+Parser<ManagedTokenSource>::parse_for_loop_expr (
+ AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label)
{
location_t locus = UNKNOWN_LOCATION;
- if (label.is_error ())
- locus = lexer.peek_token ()->get_locus ();
+ if (label)
+ locus = label->get_locus ();
else
- locus = label.get_locus ();
+ locus = lexer.peek_token ()->get_locus ();
maybe_skip_token (FOR);
// parse pattern, which is required
@@ -8308,8 +8222,9 @@ Parser<ManagedTokenSource>::parse_labelled_loop_expr (const_TokenPtr tok,
}
// parse loop label (required)
- AST::LoopLabel label = parse_loop_label (tok);
- if (label.is_error ())
+ // TODO: Convert this return type to tl::expected instead of tl::optional
+ auto parsed_label = parse_loop_label (tok);
+ if (!parsed_label)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse loop label in labelled loop expr");
@@ -8319,6 +8234,10 @@ Parser<ManagedTokenSource>::parse_labelled_loop_expr (const_TokenPtr tok,
return nullptr;
}
+ auto label = parsed_label
+ ? tl::optional<AST::LoopLabel> (parsed_label.value ())
+ : tl::nullopt;
+
// branch on next token
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
@@ -8693,10 +8612,10 @@ Parser<ManagedTokenSource>::parse_array_expr (AST::AttrVec outer_attrs,
std::vector<std::unique_ptr<AST::Expr>> exprs;
auto array_elems
- = Rust::make_unique<AST::ArrayElemsValues> (std::move (exprs), locus);
- return Rust::make_unique<AST::ArrayExpr> (std::move (array_elems),
- std::move (inner_attrs),
- std::move (outer_attrs), locus);
+ = std::make_unique<AST::ArrayElemsValues> (std::move (exprs), locus);
+ return std::make_unique<AST::ArrayExpr> (std::move (array_elems),
+ std::move (inner_attrs),
+ std::move (outer_attrs), locus);
}
else
{
@@ -9696,8 +9615,12 @@ Parser<ManagedTokenSource>::parse_reference_type_inner (location_t locus)
AST::Lifetime lifetime = AST::Lifetime::elided ();
if (lexer.peek_token ()->get_id () == LIFETIME)
{
- lifetime = parse_lifetime (true);
- if (lifetime.is_error ())
+ auto parsed_lifetime = parse_lifetime (true);
+ if (parsed_lifetime)
+ {
+ lifetime = parsed_lifetime.value ();
+ }
+ else
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse lifetime in reference type");
@@ -12498,8 +12421,8 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
return parse_continue_expr (std::move (outer_attrs), tok->get_locus ());
case LEFT_CURLY:
// ok - this is an expression with block for once.
- return parse_block_expr (std::move (outer_attrs),
- AST::LoopLabel::error (), tok->get_locus ());
+ return parse_block_expr (std::move (outer_attrs), tl::nullopt,
+ tok->get_locus ());
case IF:
// if or if let, so more lookahead to find out
if (lexer.peek_token ()->get_id () == LET)
@@ -12515,7 +12438,7 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
case LIFETIME:
return parse_labelled_loop_expr (tok, std::move (outer_attrs));
case LOOP:
- return parse_loop_expr (std::move (outer_attrs), AST::LoopLabel::error (),
+ return parse_loop_expr (std::move (outer_attrs), tl::nullopt,
tok->get_locus ());
case WHILE:
if (lexer.peek_token ()->get_id () == LET)
@@ -12524,13 +12447,11 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
}
else
{
- return parse_while_loop_expr (std::move (outer_attrs),
- AST::LoopLabel::error (),
+ return parse_while_loop_expr (std::move (outer_attrs), tl::nullopt,
tok->get_locus ());
}
case FOR:
- return parse_for_loop_expr (std::move (outer_attrs),
- AST::LoopLabel::error ());
+ return parse_for_loop_expr (std::move (outer_attrs), tl::nullopt);
case MATCH_KW:
// also an expression with block
return parse_match_expr (std::move (outer_attrs), tok->get_locus ());
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 95c0a0b..827d91d 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -25,6 +25,26 @@ along with GCC; see the file COPYING3. If not see
#include "expected.h"
namespace Rust {
+
+class ParseLifetimeParamError
+{
+};
+
+class ParseLifetimeError
+{
+};
+enum class ParseLoopLabelError
+{
+ NOT_LOOP_LABEL,
+ MISSING_COLON,
+};
+enum ParseSelfError
+{
+ SELF_PTR,
+ PARSING,
+ NOT_SELF,
+};
+
/* HACK: used to resolve the expression-or-statement problem at the end of a
* block by allowing either to be returned (technically). Tagged union would
* probably take up the same amount of space. */
@@ -95,12 +115,6 @@ struct ParseRestrictions
bool allow_close_after_expr_stmt = false;
};
-enum ParseSelfError
-{
- SELF_PTR,
- PARSING,
- NOT_SELF,
-};
// Parser implementation for gccrs.
// TODO: if updated to C++20, ManagedTokenSource would be useful as a concept
template <typename ManagedTokenSource> class Parser
@@ -148,7 +162,7 @@ public:
std::unique_ptr<AST::BlockExpr>
parse_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error (),
+ tl::optional<AST::LoopLabel> = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
bool is_macro_rules_def (const_TokenPtr t);
@@ -212,7 +226,7 @@ private:
AST::TypePath parse_type_path ();
std::unique_ptr<AST::TypePathSegment> parse_type_path_segment ();
AST::PathIdentSegment parse_path_ident_segment ();
- AST::GenericArg parse_generic_arg ();
+ tl::optional<AST::GenericArg> parse_generic_arg ();
AST::GenericArgs parse_path_generic_args ();
AST::GenericArgsBinding parse_generic_args_binding ();
AST::TypePathFunction parse_type_path_function (location_t locus);
@@ -277,7 +291,8 @@ private:
ParseFunction parsing_function, EndTokenPred is_end_token,
std::string error_msg = "failed to parse generic param in generic params")
-> std::vector<decltype (parsing_function ())>;
- AST::LifetimeParam parse_lifetime_param ();
+ tl::expected<AST::LifetimeParam, ParseLifetimeParamError>
+ parse_lifetime_param ();
std::vector<std::unique_ptr<AST::TypeParam>> parse_type_params ();
template <typename EndTokenPred>
std::vector<std::unique_ptr<AST::TypeParam>>
@@ -306,14 +321,11 @@ private:
std::vector<AST::Lifetime> parse_lifetime_bounds ();
template <typename EndTokenPred>
std::vector<AST::Lifetime> parse_lifetime_bounds (EndTokenPred is_end_token);
- AST::Lifetime parse_lifetime (bool allow_elided);
+ tl::expected<AST::Lifetime, ParseLifetimeError>
+ parse_lifetime (bool allow_elided);
AST::Lifetime lifetime_from_token (const_TokenPtr tok);
std::unique_ptr<AST::ExternalTypeItem>
parse_external_type_item (AST::Visibility vis, AST::AttrVec outer_attrs);
- AST::NamedFunctionParam parse_named_function_param ();
- template <typename EndTokenPred>
- std::vector<AST::NamedFunctionParam>
- parse_named_function_params (EndTokenPred is_end_token);
std::unique_ptr<AST::TypeAlias> parse_type_alias (AST::Visibility vis,
AST::AttrVec outer_attrs);
@@ -592,18 +604,18 @@ private:
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::LoopExpr>
parse_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error (),
+ tl::optional<AST::LoopLabel> label = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::WhileLoopExpr>
parse_while_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error (),
+ tl::optional<AST::LoopLabel> label = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::WhileLetLoopExpr>
parse_while_let_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error ());
+ tl::optional<AST::LoopLabel> label = tl::nullopt);
std::unique_ptr<AST::ForLoopExpr>
parse_for_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error ());
+ tl::optional<AST::LoopLabel> label = tl::nullopt);
std::unique_ptr<AST::MatchExpr>
parse_match_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
@@ -613,7 +625,8 @@ private:
std::unique_ptr<AST::Expr> parse_labelled_loop_expr (const_TokenPtr tok,
AST::AttrVec outer_attrs
= AST::AttrVec ());
- AST::LoopLabel parse_loop_label (const_TokenPtr tok);
+ tl::expected<AST::LoopLabel, ParseLoopLabelError>
+ parse_loop_label (const_TokenPtr tok);
std::unique_ptr<AST::AsyncBlockExpr>
parse_async_block_expr (AST::AttrVec outer_attrs = AST::AttrVec ());
std::unique_ptr<AST::GroupedExpr> parse_grouped_expr (AST::AttrVec outer_attrs
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc
index b23c1eb..b781ce33 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -72,14 +72,6 @@ ResolverBase::visit (AST::ConstGenericParam &)
{}
void
-ResolverBase::visit (AST::RegularPath &)
-{}
-
-void
-ResolverBase::visit (AST::LangItemPath &)
-{}
-
-void
ResolverBase::visit (AST::PathInExpression &)
{}
@@ -336,6 +328,10 @@ ResolverBase::visit (AST::InlineAsm &)
{}
void
+ResolverBase::visit (AST::LlvmInlineAsm &)
+{}
+
+void
ResolverBase::visit (AST::TypeParam &)
{}
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
index 703460a..5bb9e4f 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -27,6 +27,11 @@
namespace Rust {
namespace Resolver {
+inline void
+redefined_error (const rich_location &loc)
+{
+ rust_error_at (loc, "redefined multiple times");
+}
class ResolverBase : public AST::ASTVisitor
{
@@ -40,8 +45,6 @@ public:
void visit (AST::Lifetime &);
void visit (AST::LifetimeParam &);
void visit (AST::ConstGenericParam &);
- void visit (AST::RegularPath &);
- void visit (AST::LangItemPath &);
void visit (AST::PathInExpression &);
void visit (AST::TypePathSegment &);
void visit (AST::TypePathSegmentGeneric &);
@@ -107,6 +110,7 @@ public:
void visit (AST::AwaitExpr &);
void visit (AST::AsyncBlockExpr &);
void visit (AST::InlineAsm &);
+ void visit (AST::LlvmInlineAsm &);
void visit (AST::TypeParam &);
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 7ddf4a9..6242235 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -22,8 +22,8 @@
#include "rust-ast-resolve-type.h"
#include "rust-ast-resolve-pattern.h"
#include "rust-ast-resolve-path.h"
-#include "diagnostic.h"
#include "rust-expr.h"
+#include "rust-ice-finalizer.h"
namespace Rust {
namespace Resolver {
@@ -108,46 +108,6 @@ ResolveExpr::visit (AST::AssignmentExpr &expr)
ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix);
}
-/* The "break rust" Easter egg.
-
- Backstory: once upon a time, there used to be a bug in rustc: it would ICE
- during typechecking on a 'break' with an expression outside of a loop. The
- issue has been reported [0] and fixed [1], but in recognition of this, as a
- special Easter egg, "break rust" was made to intentionally cause an ICE.
-
- [0]: https://github.com/rust-lang/rust/issues/43162
- [1]: https://github.com/rust-lang/rust/pull/43745
-
- This was made in a way that does not break valid programs: namely, it only
- happens when the 'break' is outside of a loop (so invalid anyway).
-
- GCC Rust supports this essential feature as well, but in a slightly
- different way. Instead of delaying the error until type checking, we emit
- it here in the resolution phase. We, too, only do this to programs that
- are already invalid: we only emit our funny ICE if the name "rust" (which
- must be immediately inside a break-with-a-value expression) fails to
- resolve. Note that "break (rust)" does not trigger our ICE, only using
- "break rust" directly does, and only if there's no "rust" in scope. We do
- this in the same way regardless of whether the "break" is outside of a loop
- or inside one.
-
- As a GNU extension, we also support "break gcc", much to the same effect,
- subject to the same rules. */
-
-/* The finalizer for our funny ICE. This prints a custom message instead of
- the default bug reporting instructions, as there is no bug to report. */
-
-static void ATTRIBUTE_NORETURN
-funny_ice_text_finalizer (diagnostic_text_output_format &text_output,
- const diagnostic_info *diagnostic,
- diagnostic_t diag_kind)
-{
- gcc_assert (diag_kind == DK_ICE_NOBT);
- default_diagnostic_text_finalizer (text_output, diagnostic, diag_kind);
- fnotice (stderr, "You have broken GCC Rust. This is a feature.\n");
- exit (ICE_EXIT_CODE);
-}
-
void
ResolveExpr::visit (AST::IdentifierExpr &expr)
{
@@ -249,7 +209,7 @@ ResolveExpr::visit (AST::IfLetExpr &expr)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
// We know expr.get_patterns () has one pattern at most
// so there's no reason to handle it like an AltPattern.
@@ -279,7 +239,7 @@ ResolveExpr::visit (AST::IfLetExprConseqElse &expr)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
// We know expr.get_patterns () has one pattern at most
// so there's no reason to handle it like an AltPattern.
@@ -308,7 +268,7 @@ ResolveExpr::visit (AST::BlockExpr &expr)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
if (expr.has_label ())
{
@@ -327,7 +287,7 @@ ResolveExpr::visit (AST::BlockExpr &expr)
CanonicalPath::new_seg (label.get_node_id (), label_name),
label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (label.get_locus (), "label redefined multiple times");
+ rust_error_at (label.get_locus (), "label defined multiple times");
rust_error_at (locus, "was defined here");
});
}
@@ -408,6 +368,17 @@ ResolveExpr::visit (AST::InlineAsm &expr)
{
translate_operand (expr, prefix, canonical_prefix);
}
+
+void
+ResolveExpr::visit (AST::LlvmInlineAsm &expr)
+{
+ for (auto &output : expr.get_outputs ())
+ ResolveExpr::go (*output.expr, prefix, canonical_prefix);
+
+ for (auto &input : expr.get_inputs ())
+ ResolveExpr::go (*input.expr, prefix, canonical_prefix);
+}
+
void
ResolveExpr::visit (AST::UnsafeBlockExpr &expr)
{
@@ -499,7 +470,7 @@ ResolveExpr::visit (AST::LoopExpr &expr)
CanonicalPath::new_seg (expr.get_node_id (), label_name),
label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (label.get_locus (), "label redefined multiple times");
+ rust_error_at (label.get_locus (), "label defined multiple times");
rust_error_at (locus, "was defined here");
});
}
@@ -511,7 +482,7 @@ ResolveExpr::visit (AST::BreakExpr &expr)
{
if (expr.has_label ())
{
- auto label = expr.get_label ().get_lifetime ();
+ auto label = expr.get_label_unchecked ().get_lifetime ();
if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED)
{
rust_error_at (label.get_locus (),
@@ -526,8 +497,8 @@ ResolveExpr::visit (AST::BreakExpr &expr)
&resolved_node))
{
rust_error_at (label.get_locus (), ErrorCode::E0426,
- "use of undeclared label %qs in %<break%>",
- label.get_lifetime_name ().c_str ());
+ "use of undeclared label %qs",
+ label.as_string ().c_str ());
return;
}
resolver->insert_resolved_label (label.get_node_id (), resolved_node);
@@ -537,7 +508,7 @@ ResolveExpr::visit (AST::BreakExpr &expr)
{
bool funny_error = false;
auto &break_expr = expr.get_break_expr ();
- if (break_expr.get_ast_kind () == AST::Kind::IDENTIFIER)
+ if (break_expr.get_expr_kind () == AST::Expr::Kind::Identifier)
{
/* This is a break with an expression, and the expression is
just a single identifier. See if the identifier is either
@@ -575,7 +546,7 @@ ResolveExpr::visit (AST::WhileLoopExpr &expr)
CanonicalPath::new_seg (label.get_node_id (), label_name),
label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (label.get_locus (), "label redefined multiple times");
+ rust_error_at (label.get_locus (), "label defined multiple times");
rust_error_at (locus, "was defined here");
});
}
@@ -604,7 +575,7 @@ ResolveExpr::visit (AST::ForLoopExpr &expr)
CanonicalPath::new_seg (label.get_node_id (), label_name),
label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (label.get_locus (), "label redefined multiple times");
+ rust_error_at (label.get_locus (), "label defined multiple times");
rust_error_at (locus, "was defined here");
});
}
@@ -616,7 +587,7 @@ ResolveExpr::visit (AST::ForLoopExpr &expr)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
// resolve the expression
PatternDeclaration::go (expr.get_pattern (), Rib::ItemType::Var);
@@ -634,7 +605,7 @@ ResolveExpr::visit (AST::ContinueExpr &expr)
{
if (expr.has_label ())
{
- auto label = expr.get_label ();
+ auto label = expr.get_label_unchecked ();
if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED)
{
rust_error_at (label.get_locus (),
@@ -648,9 +619,9 @@ ResolveExpr::visit (AST::ContinueExpr &expr)
label.get_lifetime_name ()),
&resolved_node))
{
- rust_error_at (expr.get_label ().get_locus (), ErrorCode::E0426,
- "use of undeclared label %qs in %<continue%>",
- label.get_lifetime_name ().c_str ());
+ rust_error_at (expr.get_label_unchecked ().get_locus (),
+ ErrorCode::E0426, "use of undeclared label %qs",
+ label.as_string ().c_str ());
return;
}
resolver->insert_resolved_label (label.get_node_id (), resolved_node);
@@ -682,7 +653,7 @@ ResolveExpr::visit (AST::MatchExpr &expr)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
// resolve
AST::MatchArm &arm = match_case.get_arm ();
@@ -751,7 +722,7 @@ ResolveExpr::visit (AST::ClosureExprInner &expr)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
std::vector<PatternBinding> bindings
= {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
@@ -781,7 +752,7 @@ ResolveExpr::visit (AST::ClosureExprInnerTyped &expr)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
std::vector<PatternBinding> bindings
= {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 562a3bd..b296d66 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -57,6 +57,7 @@ public:
void visit (AST::IfLetExprConseqElse &expr) override;
void visit (AST::BlockExpr &expr) override;
void visit (AST::InlineAsm &expr) override;
+ void visit (AST::LlvmInlineAsm &expr) override;
void visit (AST::UnsafeBlockExpr &expr) override;
void visit (AST::ArrayElemsValues &elems) override;
void visit (AST::ArrayExpr &expr) override;
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index 2ca1296..2081697 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -51,7 +51,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, type.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
}
@@ -67,7 +67,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, constant.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
}
@@ -84,7 +84,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
}
@@ -124,7 +124,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (function.get_node_id (), cpath);
@@ -144,7 +144,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, constant.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (constant.get_node_id (), cpath);
@@ -162,7 +162,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, type.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (type.get_node_id (), cpath);
@@ -202,7 +202,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -221,7 +221,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -239,8 +239,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, type.get_locus ());
r.add_range (locus);
-
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 34098bc..30f6d43 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -61,11 +61,11 @@ ResolveTraitItems::visit (AST::Function &function)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
if (function.has_generics ())
- for (auto &generic : function.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
if (function.has_return_type ())
ResolveType::go (function.get_return_type ());
@@ -188,8 +188,8 @@ ResolveItem::visit (AST::TypeAlias &alias)
resolver->get_type_scope ().push (scope_node_id);
if (alias.has_generics ())
- for (auto &generic : alias.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (alias.get_generic_params (), prefix,
+ canonical_prefix);
if (alias.has_where_clause ())
ResolveWhereClause::Resolve (alias.get_where_clause ());
@@ -216,7 +216,7 @@ ResolveItem::visit (AST::Module &module)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
// FIXME: Should we reinsert a child here? Any reason we ResolveTopLevel::go
// in ResolveTopLevel::visit (AST::Module) as well as here?
@@ -250,8 +250,8 @@ ResolveItem::visit (AST::TupleStruct &struct_decl)
resolver->get_type_scope ().push (scope_node_id);
if (struct_decl.has_generics ())
- for (auto &generic : struct_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
if (struct_decl.has_where_clause ())
ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
@@ -284,8 +284,8 @@ ResolveItem::visit (AST::Enum &enum_decl)
resolver->get_type_scope ().push (scope_node_id);
if (enum_decl.has_generics ())
- for (auto &generic : enum_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, cpath);
+ ResolveGenericParams::go (enum_decl.get_generic_params (), prefix,
+ canonical_prefix);
if (enum_decl.has_where_clause ())
ResolveWhereClause::Resolve (enum_decl.get_where_clause ());
@@ -356,6 +356,8 @@ ResolveItem::visit (AST::EnumItemDiscriminant &item)
auto cpath = canonical_prefix.append (decl);
mappings.insert_canonical_path (item.get_node_id (), cpath);
+
+ ResolveExpr::go (item.get_expr (), path, cpath);
}
void
@@ -374,8 +376,8 @@ ResolveItem::visit (AST::StructStruct &struct_decl)
resolver->get_type_scope ().push (scope_node_id);
if (struct_decl.has_generics ())
- for (auto &generic : struct_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
if (struct_decl.has_where_clause ())
ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
@@ -409,8 +411,8 @@ ResolveItem::visit (AST::Union &union_decl)
resolver->get_type_scope ().push (scope_node_id);
if (union_decl.has_generics ())
- for (auto &generic : union_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (union_decl.get_generic_params (), prefix,
+ canonical_prefix);
if (union_decl.has_where_clause ())
ResolveWhereClause::Resolve (union_decl.get_where_clause ());
@@ -473,11 +475,11 @@ ResolveItem::visit (AST::Function &function)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
if (function.has_generics ())
- for (auto &generic : function.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
// resolve any where clause items
if (function.has_where_clause ())
@@ -567,8 +569,8 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
resolve_visibility (impl_block.get_visibility ());
if (impl_block.has_generics ())
- for (auto &generic : impl_block.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (impl_block.get_generic_params (), prefix,
+ canonical_prefix);
// resolve any where clause items
if (impl_block.has_where_clause ())
@@ -582,7 +584,14 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
// Setup paths
CanonicalPath self_cpath = CanonicalPath::create_empty ();
bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_type (), self_cpath);
- rust_assert (ok);
+ if (!ok)
+ {
+ resolver->get_name_scope ().pop ();
+ resolver->get_type_scope ().pop ();
+ resolver->get_label_scope ().pop ();
+ return;
+ }
+
rust_debug ("AST::InherentImpl resolve Self: {%s}",
self_cpath.get ().c_str ());
@@ -641,11 +650,11 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
if (impl_block.has_generics ())
- for (auto &generic : impl_block.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (impl_block.get_generic_params (), prefix,
+ canonical_prefix);
// resolve any where clause items
if (impl_block.has_where_clause ())
@@ -671,12 +680,20 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
return;
}
- bool ok;
+ bool ok = true;
+
// setup paths
CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
+
ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path (),
canonical_trait_type);
- rust_assert (ok);
+ if (!ok)
+ {
+ resolver->get_name_scope ().pop ();
+ resolver->get_type_scope ().pop ();
+ resolver->get_label_scope ().pop ();
+ return;
+ }
rust_debug ("AST::TraitImpl resolve trait type: {%s}",
canonical_trait_type.get ().c_str ());
@@ -684,7 +701,13 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
ok = ResolveTypeToCanonicalPath::go (impl_block.get_type (),
canonical_impl_type);
- rust_assert (ok);
+ if (!ok)
+ {
+ resolver->get_name_scope ().pop ();
+ resolver->get_type_scope ().pop ();
+ resolver->get_label_scope ().pop ();
+ return;
+ }
rust_debug ("AST::TraitImpl resolve self: {%s}",
canonical_impl_type.get ().c_str ());
@@ -755,20 +778,14 @@ ResolveItem::visit (AST::Trait &trait)
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- // we need to inject an implicit self TypeParam here
- // FIXME: which location should be used for Rust::Identifier `Self`?
- AST::TypeParam *implicit_self
- = new AST::TypeParam ({"Self"}, trait.get_locus ());
- trait.insert_implict_self (
- std::unique_ptr<AST::GenericParam> (implicit_self));
- CanonicalPath Self = CanonicalPath::get_big_self (trait.get_node_id ());
-
- for (auto &generic : trait.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go_single (trait.get_implicit_self (), prefix,
+ canonical_prefix);
+ ResolveGenericParams::go (trait.get_generic_params (), prefix,
+ canonical_prefix);
// Self is an implicit TypeParam so lets mark it as such
resolver->get_type_scope ().append_reference_for_def (
- Self.get_node_id (), implicit_self->get_node_id ());
+ trait.get_node_id (), trait.get_implicit_self ().get_node_id ());
if (trait.has_type_param_bounds ())
{
@@ -888,7 +905,18 @@ flatten_list (const AST::UseTreeList &list, std::vector<Import> &imports)
for (auto import = imports.begin () + start_idx; import != imports.end ();
import++)
- import->add_prefix (prefix);
+ {
+ // avoid duplicate node ids
+ auto prefix_copy
+ = AST::SimplePath ({}, prefix.has_opening_scope_resolution (),
+ prefix.get_locus ());
+ for (auto &seg : prefix.get_segments ())
+ prefix_copy.get_segments ().push_back (
+ AST::SimplePathSegment (seg.get_segment_name (),
+ seg.get_locus ()));
+
+ import->add_prefix (std::move (prefix_copy));
+ }
}
}
@@ -1025,12 +1053,12 @@ ResolveExternItem::visit (AST::Function &function)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
// resolve the generics
if (function.has_generics ())
- for (auto &generic : function.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
if (function.has_return_type ())
ResolveType::go (function.get_return_type ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc
index ea39fd4..fb6715d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-path.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2025 Free Software Foundation, Inc.
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
// This file is part of GCC.
@@ -18,6 +18,7 @@
#include "rust-ast-resolve-path.h"
#include "rust-ast-resolve-type.h"
+#include "rust-hir-map.h"
#include "rust-path.h"
namespace Rust {
@@ -49,6 +50,10 @@ ResolvePath::go (AST::SimplePath &expr)
NodeId
ResolvePath::resolve_path (AST::PathInExpression &expr)
{
+ if (expr.is_lang_item ())
+ return Analysis::Mappings::get ().get_lang_item_node (
+ expr.get_lang_item ());
+
NodeId resolved_node_id = UNKNOWN_NODEID;
NodeId module_scope_id = resolver->peek_current_module_scope ();
NodeId previous_resolved_node_id = module_scope_id;
@@ -63,8 +68,7 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
if (in_middle_of_path && segment.is_lower_self_seg ())
{
rust_error_at (segment.get_locus (), ErrorCode::E0433,
- "failed to resolve: %qs in paths can only be used "
- "in start position",
+ "%qs in paths can only be used in start position",
segment.as_string ().c_str ());
return UNKNOWN_NODEID;
}
@@ -75,8 +79,16 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
// what is the current crate scope node id?
module_scope_id = crate_scope_id;
previous_resolved_node_id = module_scope_id;
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == module_scope_id);
+ else
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
continue;
}
else if (segment.is_super_path_seg ())
@@ -90,8 +102,16 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
module_scope_id = resolver->peek_parent_module_scope ();
previous_resolved_node_id = module_scope_id;
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == module_scope_id);
+ else
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
continue;
}
@@ -135,23 +155,45 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
ident_seg.as_string ());
if (resolver->get_name_scope ().lookup (path, &resolved_node))
{
- resolver->insert_resolved_name (segment.get_node_id (),
- resolved_node);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_name (segment.get_node_id (),
+ resolved_node);
resolved_node_id = resolved_node;
}
// check the type scope
else if (resolver->get_type_scope ().lookup (path, &resolved_node))
{
- resolver->insert_resolved_type (segment.get_node_id (),
- resolved_node);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_type (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_type (segment.get_node_id (),
+ resolved_node);
resolved_node_id = resolved_node;
}
else if (segment.is_lower_self_seg ())
{
module_scope_id = crate_scope_id;
previous_resolved_node_id = module_scope_id;
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == module_scope_id);
+ else
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
continue;
}
else
@@ -174,20 +216,38 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
resolved_node))
{
resolved_node_id = resolved_node;
- resolver->insert_resolved_name (segment.get_node_id (),
- resolved_node);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_name (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_name (segment.get_node_id (),
+ resolved_node);
}
else if (resolver->get_type_scope ().decl_was_declared_here (
resolved_node))
{
resolved_node_id = resolved_node;
- resolver->insert_resolved_type (segment.get_node_id (),
- resolved_node);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_type (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_type (segment.get_node_id (),
+ resolved_node);
}
else
{
rust_error_at (segment.get_locus (),
- "Cannot find path %qs in this scope",
+ "Cannot find path %<%s%> in this scope",
segment.as_string ().c_str ());
return UNKNOWN_NODEID;
}
@@ -207,7 +267,7 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
else if (is_first_segment)
{
rust_error_at (segment.get_locus (), ErrorCode::E0433,
- "Cannot find path %qs in this scope",
+ "Cannot find path %<%s%> in this scope",
segment.as_string ().c_str ());
return UNKNOWN_NODEID;
}
@@ -219,15 +279,29 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
// name scope first
if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
{
- resolver->insert_resolved_name (expr.get_node_id (),
- resolved_node_id);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_name (expr.get_node_id (), &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node_id);
+ else
+ resolver->insert_resolved_name (expr.get_node_id (),
+ resolved_node_id);
}
// check the type scope
else if (resolver->get_type_scope ().decl_was_declared_here (
resolved_node_id))
{
- resolver->insert_resolved_type (expr.get_node_id (),
- resolved_node_id);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_type (expr.get_node_id (), &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node_id);
+ else
+ resolver->insert_resolved_type (expr.get_node_id (),
+ resolved_node_id);
}
else
{
@@ -279,14 +353,29 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
// what is the current crate scope node id?
module_scope_id = crate_scope_id;
previous_resolved_node_id = module_scope_id;
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == module_scope_id);
+ else
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
resolved_node_id = module_scope_id;
continue;
}
else if (segment.is_super_path_seg ())
{
+ if (!is_first_segment)
+ {
+ rust_error_at (
+ segment.get_locus (), ErrorCode::E0433,
+ "%<super%> in paths can only be used in start position");
+ return UNKNOWN_NODEID;
+ }
if (module_scope_id == crate_scope_id)
{
rust_error_at (segment.get_locus (),
@@ -296,8 +385,16 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
module_scope_id = resolver->peek_parent_module_scope ();
previous_resolved_node_id = module_scope_id;
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == module_scope_id);
+ else
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
resolved_node_id = module_scope_id;
continue;
@@ -313,20 +410,36 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
resolved_node))
{
resolved_node_id = resolved_node;
- resolver->insert_resolved_name (segment.get_node_id (),
- resolved_node);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_name (segment.get_node_id (),
+ resolved_node);
}
else if (resolver->get_type_scope ().decl_was_declared_here (
resolved_node))
{
resolved_node_id = resolved_node;
- resolver->insert_resolved_type (segment.get_node_id (),
- resolved_node);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_type (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_type (segment.get_node_id (),
+ resolved_node);
}
else
{
rust_error_at (segment.get_locus (),
- "Cannot find path %qs in this scope",
+ "Cannot find path %<%s%> in this scope",
segment.as_string ().c_str ());
return UNKNOWN_NODEID;
}
@@ -342,15 +455,31 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
if (resolver->get_name_scope ().lookup (path, &resolved_node))
{
resolved_node_id = resolved_node;
- resolver->insert_resolved_name (segment.get_node_id (),
- resolved_node);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_name (segment.get_node_id (),
+ resolved_node);
}
// check the type scope
else if (resolver->get_type_scope ().lookup (path, &resolved_node))
{
resolved_node_id = resolved_node;
- resolver->insert_resolved_type (segment.get_node_id (),
- resolved_node);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_type (segment.get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_type (segment.get_node_id (),
+ resolved_node);
}
}
@@ -374,7 +503,7 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
if (resolved_node_id == UNKNOWN_NODEID)
{
rust_error_at (segment.get_locus (),
- "cannot find simple path segment %qs in this scope",
+ "cannot find simple path segment %<%s%> in this scope",
segment.as_string ().c_str ());
return UNKNOWN_NODEID;
}
@@ -393,15 +522,29 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
// name scope first
if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
{
- resolver->insert_resolved_name (expr.get_node_id (),
- resolved_node_id);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_name (expr.get_node_id (), &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node_id);
+ else
+ resolver->insert_resolved_name (expr.get_node_id (),
+ resolved_node_id);
}
// check the type scope
else if (resolver->get_type_scope ().decl_was_declared_here (
resolved_node_id))
{
- resolver->insert_resolved_type (expr.get_node_id (),
- resolved_node_id);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_type (expr.get_node_id (), &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node_id);
+ else
+ resolver->insert_resolved_type (expr.get_node_id (),
+ resolved_node_id);
}
else
{
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.cc b/gcc/rust/resolve/rust-ast-resolve-stmt.cc
index 2885291..bfba302 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.cc
@@ -56,5 +56,26 @@ ResolveStmt::visit (AST::TraitImpl &impl_block)
ResolveItem::go (impl_block, prefix, canonical_prefix);
}
+void
+ResolveStmt::visit (AST::StaticItem &var)
+{
+ auto decl = CanonicalPath::new_seg (var.get_node_id (),
+ var.get_identifier ().as_string ());
+ auto path = decl;
+ auto cpath = canonical_prefix.append (decl);
+ mappings.insert_canonical_path (var.get_node_id (), cpath);
+
+ resolver->get_name_scope ().insert (
+ path, var.get_node_id (), var.get_locus (), false, Rib::ItemType::Static,
+ [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+ rich_location r (line_table, var.get_locus ());
+ r.add_range (locus);
+ redefined_error (r);
+ });
+
+ ResolveType::go (var.get_type ());
+ ResolveExpr::go (var.get_expr (), path, cpath);
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index 8e64a76..d413a7c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -63,7 +63,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, constant.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
ResolveType::go (constant.get_type ());
@@ -73,9 +73,10 @@ public:
void visit (AST::LetStmt &stmt) override
{
if (stmt.has_init_expr ())
- {
- ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix);
- }
+ ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix);
+
+ if (stmt.has_else_expr ())
+ ResolveExpr::go (stmt.get_else_expr (), prefix, canonical_prefix);
PatternDeclaration::go (stmt.get_pattern (), Rib::ItemType::Var);
if (stmt.has_type ())
@@ -97,17 +98,15 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, struct_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = struct_decl.get_node_id ();
resolver->get_type_scope ().push (scope_node_id);
if (struct_decl.has_generics ())
- {
- for (auto &generic : struct_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
- }
+ ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
for (AST::TupleField &field : struct_decl.get_fields ())
ResolveType::go (field.get_field_type ());
@@ -130,17 +129,15 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, enum_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = enum_decl.get_node_id ();
resolver->get_type_scope ().push (scope_node_id);
if (enum_decl.has_generics ())
- {
- for (auto &generic : enum_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
- }
+ ResolveGenericParams::go (enum_decl.get_generic_params (), prefix,
+ canonical_prefix);
for (auto &variant : enum_decl.get_variants ())
ResolveStmt::go (*variant, path, canonical_prefix, path);
@@ -162,7 +159,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
// Done, no fields.
@@ -182,7 +179,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
for (auto &field : item.get_tuple_fields ())
@@ -208,7 +205,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
for (auto &field : item.get_struct_fields ())
@@ -234,7 +231,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
// Done, no fields.
@@ -255,17 +252,15 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, struct_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = struct_decl.get_node_id ();
resolver->get_type_scope ().push (scope_node_id);
if (struct_decl.has_generics ())
- {
- for (auto &generic : struct_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
- }
+ ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
for (AST::StructField &field : struct_decl.get_fields ())
{
@@ -293,15 +288,15 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, union_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = union_decl.get_node_id ();
resolver->get_type_scope ().push (scope_node_id);
if (union_decl.has_generics ())
- for (auto &generic : union_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (union_decl.get_generic_params (), prefix,
+ canonical_prefix);
for (AST::StructField &field : union_decl.get_variants ())
{
@@ -329,7 +324,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = function.get_node_id ();
@@ -338,11 +333,11 @@ public:
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
if (function.has_generics ())
- for (auto &generic : function.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
if (function.has_return_type ())
ResolveType::go (function.get_return_type ());
@@ -388,6 +383,7 @@ public:
void visit (AST::Trait &trait) override;
void visit (AST::InherentImpl &impl_block) override;
void visit (AST::TraitImpl &impl_block) override;
+ void visit (AST::StaticItem &var) override;
private:
ResolveStmt (const CanonicalPath &prefix,
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 565ca92..f52fb8a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -58,7 +58,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, module.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -88,7 +88,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, alias.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -110,7 +110,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, struct_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -132,7 +132,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, enum_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
resolver->push_new_module_scope (enum_decl.get_node_id ());
@@ -158,7 +158,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (item.get_node_id (), cpath);
@@ -180,7 +180,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (item.get_node_id (), cpath);
@@ -202,7 +202,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (item.get_node_id (), cpath);
@@ -224,7 +224,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (item.get_node_id (), cpath);
@@ -242,14 +242,21 @@ public:
auto path = prefix.append (decl);
auto cpath = canonical_prefix.append (decl);
- resolver->get_type_scope ().insert (
- path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
- Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, struct_decl.get_locus ());
- r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
- });
+ auto duplicate_item
+ = [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+ rich_location r (line_table, struct_decl.get_locus ());
+ r.add_range (locus);
+ redefined_error (r);
+ };
+
+ resolver->get_type_scope ().insert (path, struct_decl.get_node_id (),
+ struct_decl.get_locus (), false,
+ Rib::ItemType::Type, duplicate_item);
+
+ if (struct_decl.is_unit_struct ())
+ resolver->get_name_scope ().insert (path, struct_decl.get_node_id (),
+ struct_decl.get_locus (), false,
+ Rib::ItemType::Type, duplicate_item);
NodeId current_module = resolver->peek_current_module_scope ();
mappings.insert_module_child_item (current_module, decl);
@@ -270,7 +277,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, union_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -290,7 +297,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, var.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -311,7 +318,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, constant.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -333,7 +340,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -381,7 +388,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, impl_block.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
for (auto &impl_item : impl_block.get_impl_items ())
@@ -401,7 +408,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, trait.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
for (auto &item : trait.get_trait_items ())
@@ -473,7 +480,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, extern_crate.get_locus ());
r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
+ redefined_error (r);
});
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index ec5e8a7..8fd69c3 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -18,12 +18,58 @@
#include "rust-ast-resolve-type.h"
#include "rust-ast-resolve-expr.h"
+#include "rust-canonical-path.h"
+#include "rust-type.h"
+#include "rust-hir-map.h"
namespace Rust {
namespace Resolver {
// rust-ast-resolve-type.h
+NodeId
+ResolveType::go (AST::Type &type)
+{
+ ResolveType resolver;
+ type.accept_vis (resolver);
+ return resolver.resolved_node;
+}
+
+void
+ResolveType::visit (AST::BareFunctionType &fntype)
+{
+ for (auto &param : fntype.get_function_params ())
+ ResolveType::go (param.get_type ());
+
+ if (fntype.has_return_type ())
+ ResolveType::go (fntype.get_return_type ());
+}
+
+void
+ResolveType::visit (AST::TupleType &tuple)
+{
+ if (tuple.is_unit_type ())
+ {
+ resolved_node = resolver->get_unit_type_node_id ();
+ return;
+ }
+
+ for (auto &elem : tuple.get_elems ())
+ ResolveType::go (*elem);
+}
+
+void
+ResolveType::visit (AST::TypePath &path)
+{
+ ResolveRelativeTypePath::go (path, resolved_node);
+}
+
+void
+ResolveType::visit (AST::QualifiedPathInType &path)
+{
+ ResolveRelativeQualTypePath::go (path);
+}
+
void
ResolveType::visit (AST::ArrayType &type)
{
@@ -49,6 +95,12 @@ ResolveType::visit (AST::TraitObjectType &type)
}
void
+ResolveType::visit (AST::ParenthesisedType &type)
+{
+ resolved_node = ResolveType::go (*type.get_type_in_parens ());
+}
+
+void
ResolveType::visit (AST::ReferenceType &type)
{
resolved_node = ResolveType::go (type.get_type_referenced ());
@@ -63,7 +115,7 @@ ResolveType::visit (AST::RawPointerType &type)
void
ResolveType::visit (AST::InferredType &)
{
- // FIXME
+ // nothing to do
}
void
@@ -78,6 +130,19 @@ ResolveType::visit (AST::SliceType &type)
resolved_node = ResolveType::go (type.get_elem_type ());
}
+void
+ResolveType::visit (AST::ImplTraitType &type)
+{
+ for (auto &bound : type.get_type_param_bounds ())
+ ResolveTypeBound::go (*bound);
+}
+
+void
+ResolveType::visit (AST::ImplTraitTypeOneBound &type)
+{
+ ResolveTypeBound::go (type.get_trait_bound ());
+}
+
// resolve relative type-paths
bool
@@ -91,45 +156,56 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
for (size_t i = 0; i < path.get_segments ().size (); i++)
{
auto &segment = path.get_segments ().at (i);
- const AST::PathIdentSegment &ident_seg = segment->get_ident_segment ();
bool is_first_segment = i == 0;
- resolved_node_id = UNKNOWN_NODEID;
+ NodeId crate_scope_id = resolver->peek_crate_module_scope ();
+ auto ident_string = segment->is_lang_item ()
+ ? LangItem::PrettyString (segment->get_lang_item ())
+ : segment->get_ident_segment ().as_string ();
- bool in_middle_of_path = i > 0;
- if (in_middle_of_path && segment->is_lower_self_seg ())
- {
- rust_error_at (segment->get_locus (), ErrorCode::E0433,
- "failed to resolve: %qs in paths can only be used "
- "in start position",
- segment->as_string ().c_str ());
- return false;
- }
+ resolved_node_id = UNKNOWN_NODEID;
- NodeId crate_scope_id = resolver->peek_crate_module_scope ();
- if (segment->is_crate_path_seg ())
+ if (segment->is_lang_item ())
{
- // what is the current crate scope node id?
- module_scope_id = crate_scope_id;
- previous_resolved_node_id = module_scope_id;
- resolver->insert_resolved_name (segment->get_node_id (),
- module_scope_id);
-
- continue;
+ resolved_node_id = Analysis::Mappings::get ().get_lang_item_node (
+ segment->get_lang_item ());
+ previous_resolved_node_id = resolved_node_id;
}
- else if (segment->is_super_path_seg ())
+ else
{
- if (module_scope_id == crate_scope_id)
+ bool in_middle_of_path = i > 0;
+ if (in_middle_of_path && segment->is_lower_self_seg ())
{
- rust_error_at (segment->get_locus (),
- "cannot use super at the crate scope");
+ rust_error_at (segment->get_locus (), ErrorCode::E0433,
+ "%qs in paths can only be used in start position",
+ segment->as_string ().c_str ());
return false;
}
- module_scope_id = resolver->peek_parent_module_scope ();
- previous_resolved_node_id = module_scope_id;
- resolver->insert_resolved_name (segment->get_node_id (),
- module_scope_id);
- continue;
+ if (segment->is_crate_path_seg ())
+ {
+ // what is the current crate scope node id?
+ module_scope_id = crate_scope_id;
+ previous_resolved_node_id = module_scope_id;
+ resolver->insert_resolved_name (segment->get_node_id (),
+ module_scope_id);
+
+ continue;
+ }
+ else if (segment->is_super_path_seg ())
+ {
+ if (module_scope_id == crate_scope_id)
+ {
+ rust_error_at (segment->get_locus (),
+ "cannot use super at the crate scope");
+ return false;
+ }
+
+ module_scope_id = resolver->peek_parent_module_scope ();
+ previous_resolved_node_id = module_scope_id;
+ resolver->insert_resolved_name (segment->get_node_id (),
+ module_scope_id);
+ continue;
+ }
}
switch (segment->get_type ())
@@ -169,27 +245,48 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
// name scope first
NodeId resolved_node = UNKNOWN_NODEID;
const CanonicalPath path
- = CanonicalPath::new_seg (segment->get_node_id (),
- ident_seg.as_string ());
+ = CanonicalPath::new_seg (segment->get_node_id (), ident_string);
if (resolver->get_type_scope ().lookup (path, &resolved_node))
{
- resolver->insert_resolved_type (segment->get_node_id (),
- resolved_node);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_type (segment->get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_type (segment->get_node_id (),
+ resolved_node);
resolved_node_id = resolved_node;
}
else if (resolver->get_name_scope ().lookup (path, &resolved_node))
{
- resolver->insert_resolved_name (segment->get_node_id (),
- resolved_node);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment->get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_name (segment->get_node_id (),
+ resolved_node);
resolved_node_id = resolved_node;
}
- else if (segment->is_lower_self_seg ())
+ else if (!segment->is_lang_item () && segment->is_lower_self_seg ())
{
// what is the current crate scope node id?
module_scope_id = crate_scope_id;
previous_resolved_node_id = module_scope_id;
- resolver->insert_resolved_name (segment->get_node_id (),
- module_scope_id);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok = resolver->lookup_resolved_name (segment->get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == module_scope_id);
+ else
+ resolver->insert_resolved_name (segment->get_node_id (),
+ module_scope_id);
continue;
}
@@ -199,8 +296,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
&& previous_resolved_node_id == module_scope_id)
{
tl::optional<CanonicalPath &> resolved_child
- = mappings.lookup_module_child (module_scope_id,
- ident_seg.as_string ());
+ = mappings.lookup_module_child (module_scope_id, ident_string);
if (resolved_child.has_value ())
{
NodeId resolved_node = resolved_child->get_node_id ();
@@ -208,15 +304,33 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
resolved_node))
{
resolved_node_id = resolved_node;
- resolver->insert_resolved_name (segment->get_node_id (),
- resolved_node);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_name (segment->get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_name (segment->get_node_id (),
+ resolved_node);
}
else if (resolver->get_type_scope ().decl_was_declared_here (
resolved_node))
{
resolved_node_id = resolved_node;
- resolver->insert_resolved_type (segment->get_node_id (),
- resolved_node);
+
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_type (segment->get_node_id (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node);
+ else
+ resolver->insert_resolved_type (segment->get_node_id (),
+ resolved_node);
}
else
{
@@ -241,8 +355,8 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
else if (is_first_segment)
{
rust_error_at (segment->get_locus (), ErrorCode::E0412,
- "failed to resolve TypePath: %s in this scope",
- segment->as_string ().c_str ());
+ "could not resolve type path %qs",
+ segment->get_ident_segment ().as_string ().c_str ());
return false;
}
}
@@ -252,15 +366,29 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
// name scope first
if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
{
- resolver->insert_resolved_name (path.get_node_id (),
- resolved_node_id);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_name (path.get_node_id (), &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node_id);
+ else
+ resolver->insert_resolved_name (path.get_node_id (),
+ resolved_node_id);
}
// check the type scope
else if (resolver->get_type_scope ().decl_was_declared_here (
resolved_node_id))
{
- resolver->insert_resolved_type (path.get_node_id (),
- resolved_node_id);
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_type (path.get_node_id (), &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node_id);
+ else
+ resolver->insert_resolved_type (path.get_node_id (),
+ resolved_node_id);
}
else
{
@@ -495,10 +623,59 @@ ResolveTypeToCanonicalPath::visit (AST::TraitObjectTypeOneBound &type)
}
void
-ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &)
+ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type)
{
- // FIXME is this actually allowed? dyn A+B
- rust_unreachable ();
+ rust_assert (!type.get_type_param_bounds ().empty ());
+
+ auto &first_bound = type.get_type_param_bounds ().front ();
+
+ // Is it allowed or even possible to have a lifetime bound as a first bound?
+ if (first_bound->get_bound_type () == AST::TraitBound::LIFETIME)
+ rust_unreachable ();
+
+ auto &trait = static_cast<AST::TraitBound &> (*first_bound);
+
+ CanonicalPath path = CanonicalPath::create_empty ();
+ bool ok = ResolveTypeToCanonicalPath::go (trait.get_type_path (), path);
+
+ // right?
+ rust_assert (ok);
+
+ auto slice_path = "<dyn " + path.get ();
+
+ for (size_t idx = 1; idx < type.get_type_param_bounds ().size (); idx++)
+ {
+ auto &additional_bound = type.get_type_param_bounds ()[idx];
+
+ std::string str;
+
+ switch (additional_bound->get_bound_type ())
+ {
+ case AST::TypeParamBound::TRAIT: {
+ auto bound_path = CanonicalPath::create_empty ();
+
+ auto &bound_type_path
+ = static_cast<AST::TraitBound &> (*additional_bound)
+ .get_type_path ();
+ bool ok
+ = ResolveTypeToCanonicalPath::go (bound_type_path, bound_path);
+
+ if (!ok)
+ continue;
+
+ str = bound_path.get ();
+ break;
+ }
+ case AST::TypeParamBound::LIFETIME:
+ rust_unreachable ();
+ break;
+ }
+ slice_path += " + " + str;
+ }
+
+ slice_path += ">";
+
+ result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
}
void
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 561948e..f1481fc 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -21,6 +21,11 @@
#include "rust-ast-resolve-base.h"
#include "rust-ast-resolve-expr.h"
+#include "rust-diagnostics.h"
+#include "rust-hir-map.h"
+#include "rust-path.h"
+#include "rust-type.h"
+#include "util/rust-hir-map.h"
namespace Rust {
namespace Resolver {
@@ -56,59 +61,23 @@ class ResolveType : public ResolverBase
using Rust::Resolver::ResolverBase::visit;
public:
- static NodeId go (AST::Type &type)
- {
- ResolveType resolver;
- type.accept_vis (resolver);
- return resolver.resolved_node;
- }
-
- void visit (AST::BareFunctionType &fntype) override
- {
- for (auto &param : fntype.get_function_params ())
- ResolveType::go (param.get_type ());
-
- if (fntype.has_return_type ())
- ResolveType::go (fntype.get_return_type ());
- }
-
- void visit (AST::TupleType &tuple) override
- {
- if (tuple.is_unit_type ())
- {
- resolved_node = resolver->get_unit_type_node_id ();
- return;
- }
-
- for (auto &elem : tuple.get_elems ())
- ResolveType::go (*elem);
- }
-
- void visit (AST::TypePath &path) override
- {
- ResolveRelativeTypePath::go (path, resolved_node);
- }
-
- void visit (AST::QualifiedPathInType &path) override
- {
- ResolveRelativeQualTypePath::go (path);
- }
+ static NodeId go (AST::Type &type);
+ void visit (AST::BareFunctionType &fntype) override;
+ void visit (AST::TupleType &tuple) override;
+ void visit (AST::TypePath &path) override;
+ void visit (AST::QualifiedPathInType &path) override;
void visit (AST::ArrayType &type) override;
-
void visit (AST::ReferenceType &type) override;
-
void visit (AST::InferredType &type) override;
-
void visit (AST::NeverType &type) override;
-
void visit (AST::RawPointerType &type) override;
-
void visit (AST::TraitObjectTypeOneBound &type) override;
-
void visit (AST::TraitObjectType &type) override;
-
+ void visit (AST::ParenthesisedType &type) override;
void visit (AST::SliceType &type) override;
+ void visit (AST::ImplTraitType &type) override;
+ void visit (AST::ImplTraitTypeOneBound &type) override;
private:
ResolveType () : ResolverBase () {}
@@ -135,66 +104,83 @@ private:
ResolveTypeBound () : ResolverBase () {}
};
-class ResolveGenericParam : public ResolverBase
+class ResolveGenericParams : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
- static NodeId go (AST::GenericParam &param, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
+ static void go (std::vector<std::unique_ptr<AST::GenericParam>> &params,
+ const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveGenericParam resolver (prefix, canonical_prefix);
- param.accept_vis (resolver);
- return resolver.resolved_node;
+ ResolveGenericParams resolver (prefix, canonical_prefix);
+
+ // this needs to be done in two phases as they can be used and defined later
+ // in bounds
+ for (auto &param : params)
+ param->accept_vis (resolver);
+
+ resolver.first_pass = false;
+
+ for (auto &param : params)
+ param->accept_vis (resolver);
}
- void visit (AST::ConstGenericParam &param) override
+ static void go_single (AST::GenericParam &param, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveType::go (param.get_type ());
-
- if (param.has_default_value ())
- ResolveExpr::go (param.get_default_value ().get_expression (), prefix,
- canonical_prefix);
+ ResolveGenericParams resolver (prefix, canonical_prefix);
- ok = true;
+ param.accept_vis (resolver);
+ resolver.first_pass = false;
+ param.accept_vis (resolver);
}
- void visit (AST::TypeParam &param) override
+ void visit (AST::ConstGenericParam &param) override
{
- // if it has a type lets resolve it
- if (param.has_type ())
+ if (first_pass)
ResolveType::go (param.get_type ());
+ else if (param.has_default_value ())
+ ResolveExpr::go (param.get_default_value_unchecked ().get_expression (),
+ prefix, canonical_prefix);
+ }
- if (param.has_type_param_bounds ())
+ void visit (AST::TypeParam &param) override
+ {
+ if (first_pass)
+ {
+ // if it has a type lets resolve it
+ if (param.has_type ())
+ ResolveType::go (param.get_type ());
+
+ auto seg = CanonicalPath::new_seg (
+ param.get_node_id (), param.get_type_representation ().as_string ());
+ resolver->get_type_scope ().insert (
+ seg, param.get_node_id (), param.get_locus (), false,
+ Rib::ItemType::Type,
+ [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+ rust_error_at (param.get_locus (),
+ "generic param defined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
+
+ mappings.insert_canonical_path (param.get_node_id (), seg);
+ }
+ else if (param.has_type_param_bounds ())
{
for (auto &bound : param.get_type_param_bounds ())
- {
- ResolveTypeBound::go (*bound);
- }
+ ResolveTypeBound::go (*bound);
}
-
- auto seg
- = CanonicalPath::new_seg (param.get_node_id (),
- param.get_type_representation ().as_string ());
- resolver->get_type_scope ().insert (
- seg, param.get_node_id (), param.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (param.get_locus (),
- "generic param redefined multiple times");
- rust_error_at (locus, "was defined here");
- });
-
- mappings.insert_canonical_path (param.get_node_id (), seg);
}
private:
- ResolveGenericParam (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), ok (false), prefix (prefix),
+ ResolveGenericParams (const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ : ResolverBase (), first_pass (true), prefix (prefix),
canonical_prefix (canonical_prefix)
{}
- bool ok;
+ bool first_pass;
const CanonicalPath &prefix;
const CanonicalPath &canonical_prefix;
};
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index a093ef7..3e3c992 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -75,7 +75,7 @@ NameResolution::go (AST::Crate &crate)
resolver->get_label_scope ().push (scope_node_id);
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
// get the root segment
CanonicalPath crate_prefix
diff --git a/gcc/rust/resolve/rust-default-resolver.cc b/gcc/rust/resolve/rust-default-resolver.cc
index 57b1cc4..480034c 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -88,21 +88,24 @@ DefaultResolver::visit (AST::TraitImpl &impl)
void
DefaultResolver::visit (AST::StructStruct &type)
{
- // do we need to scope anything here? no, right?
+ auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
- // we also can't visit `StructField`s by default, so there's nothing to do -
- // correct? or should we do something like
+ ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_struct_name ());
+}
- AST::DefaultASTVisitor::visit (type);
+void
+DefaultResolver::visit (AST::TupleStruct &type)
+{
+ auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
- // FIXME: ???
+ ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_struct_name ());
}
void
DefaultResolver::visit (AST::Enum &type)
{
- // FIXME: Do we need to scope anything by default?
-
auto variant_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
@@ -110,6 +113,24 @@ DefaultResolver::visit (AST::Enum &type)
}
void
+DefaultResolver::visit (AST::Union &type)
+{
+ auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+ ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_identifier ());
+}
+
+void
+DefaultResolver::visit (AST::TypeAlias &type)
+{
+ auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+ ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_new_type_name ());
+}
+
+void
DefaultResolver::visit (AST::ClosureExprInner &expr)
{
if (expr.is_marked_for_strip ())
@@ -158,5 +179,13 @@ DefaultResolver::visit (AST::StaticItem &item)
ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis);
}
+void
+DefaultResolver::visit (AST::TypeParam &param)
+{
+ auto expr_vis = [this, &param] () { AST::DefaultASTVisitor::visit (param); };
+
+ ctx.scoped (Rib::Kind::ForwardTypeParamBan, param.get_node_id (), expr_vis);
+}
+
} // namespace Resolver2_0
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-default-resolver.h b/gcc/rust/resolve/rust-default-resolver.h
index 9fcddd1..2a987ef 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -50,9 +50,14 @@ public:
void visit (AST::InherentImpl &) override;
void visit (AST::TraitImpl &) override;
+ void visit (AST::TypeParam &) override;
+
// type dec nodes, which visit their fields or variants by default
void visit (AST::StructStruct &) override;
+ void visit (AST::TupleStruct &) override;
void visit (AST::Enum &) override;
+ void visit (AST::Union &) override;
+ void visit (AST::TypeAlias &) override;
// Visitors that visit their expression node(s)
void visit (AST::ClosureExprInner &) 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 5533048..3390f09 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -22,11 +22,13 @@
#include "rust-toplevel-name-resolver-2.0.h"
#include "rust-attributes.h"
#include "rust-finalize-imports-2.0.h"
+#include "rust-attribute-values.h"
namespace Rust {
namespace Resolver2_0 {
-Early::Early (NameResolutionContext &ctx) : DefaultResolver (ctx), dirty (false)
+Early::Early (NameResolutionContext &ctx)
+ : DefaultResolver (ctx), toplevel (TopLevel (ctx)), dirty (false)
{}
void
@@ -51,16 +53,10 @@ void
Early::go (AST::Crate &crate)
{
// First we go through TopLevel resolution to get all our declared items
- auto toplevel = TopLevel (ctx);
toplevel.go (crate);
// We start with resolving the list of imports that `TopLevel` has built for
// us
- for (auto &&import : toplevel.get_imports_to_resolve ())
- build_import_mapping (std::move (import));
-
- // Once this is done, we finalize their resolution
- FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
dirty = toplevel.is_dirty ();
// We now proceed with resolving macros, which can be nested in almost any
@@ -74,7 +70,7 @@ Early::go (AST::Crate &crate)
bool
Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
{
- auto resolved = ctx.types.resolve_path (glob.to_resolve.get_segments ());
+ auto resolved = ctx.resolve_path (glob.to_resolve, Namespace::Types);
if (!resolved.has_value ())
return false;
@@ -144,6 +140,10 @@ Early::build_import_mapping (
// be moved into the newly created import mappings
auto path = import.to_resolve;
+ // used to skip the "unresolved import" error
+ // if we output other errors during resolution
+ size_t old_error_count = macro_resolve_errors.size ();
+
switch (import.kind)
{
case TopLevel::ImportKind::Kind::Glob:
@@ -157,7 +157,7 @@ Early::build_import_mapping (
break;
}
- if (!found)
+ if (!found && old_error_count == macro_resolve_errors.size ())
collect_error (Error (path.get_final_segment ().get_locus (),
ErrorCode::E0433, "unresolved import %qs",
path.as_string ().c_str ()));
@@ -226,11 +226,24 @@ Early::visit (AST::BlockExpr &block)
void
Early::visit (AST::Module &module)
{
- textual_scope.push ();
+ bool is_macro_use = false;
+
+ for (const auto &attr : module.get_outer_attrs ())
+ {
+ if (attr.get_path ().as_string () == Values::Attributes::MACRO_USE)
+ {
+ is_macro_use = true;
+ break;
+ }
+ }
+
+ if (!is_macro_use)
+ textual_scope.push ();
DefaultResolver::visit (module);
- textual_scope.pop ();
+ if (!is_macro_use)
+ textual_scope.pop ();
}
void
@@ -238,6 +251,10 @@ Early::visit (AST::MacroInvocation &invoc)
{
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 ())
+ pending_invoc->accept_vis (*this);
+
// When a macro is invoked by an unqualified identifier (not part of a
// multi-part path), it is first looked up in textual scoping. If this does
// not yield any results, then it is looked up in path-based scoping. If the
@@ -255,13 +272,14 @@ 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.macros.resolve_path (path.get_segments ());
+ definition = ctx.resolve_path (path.get_segments (), Namespace::Macros);
// if the definition still does not have a value, then it's an error
if (!definition.has_value ())
{
collect_error (Error (invoc.get_locus (), ErrorCode::E0433,
- "could not resolve macro invocation"));
+ "could not resolve macro invocation %qs",
+ path.as_string ().c_str ()));
return;
}
@@ -296,8 +314,8 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
auto traits = attr.get_traits_to_derive ();
for (auto &trait : traits)
{
- auto definition
- = ctx.macros.resolve_path (trait.get ().get_segments ());
+ auto definition = ctx.resolve_path (trait.get ().get_segments (),
+ Namespace::Macros);
if (!definition.has_value ())
{
// FIXME: Change to proper error message
@@ -310,18 +328,17 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
auto pm_def = mappings.lookup_derive_proc_macro_def (
definition->get_node_id ());
- rust_assert (pm_def.has_value ());
-
- mappings.insert_derive_proc_macro_invocation (trait,
- pm_def.value ());
+ if (pm_def.has_value ())
+ mappings.insert_derive_proc_macro_invocation (trait,
+ pm_def.value ());
}
}
else if (Analysis::BuiltinAttributeMappings::get ()
->lookup_builtin (name)
.is_error ()) // Do not resolve builtins
{
- auto definition
- = ctx.macros.resolve_path (attr.get_path ().get_segments ());
+ auto definition = ctx.resolve_path (attr.get_path ().get_segments (),
+ Namespace::Macros);
if (!definition.has_value ())
{
// FIXME: Change to proper error message
@@ -355,5 +372,103 @@ Early::visit (AST::StructStruct &s)
DefaultResolver::visit (s);
}
+void
+Early::finalize_simple_import (const Early::ImportPair &mapping)
+{
+ // FIXME: We probably need to store namespace information
+
+ auto locus = mapping.import_kind.to_resolve.get_locus ();
+ auto data = mapping.data;
+ auto identifier
+ = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
+
+ for (auto &&definition : data.definitions ())
+ toplevel
+ .insert_or_error_out (
+ identifier, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
+}
+
+void
+Early::finalize_glob_import (NameResolutionContext &ctx,
+ const Early::ImportPair &mapping)
+{
+ auto module = Analysis::Mappings::get ().lookup_ast_module (
+ mapping.data.module ().get_node_id ());
+ rust_assert (module);
+
+ GlobbingVisitor glob_visitor (ctx);
+ glob_visitor.go (module.value ());
+}
+
+void
+Early::finalize_rebind_import (const Early::ImportPair &mapping)
+{
+ // We can fetch the value here as `resolve_rebind` will only be called on
+ // imports of the right kind
+ auto &path = mapping.import_kind.to_resolve;
+ auto &rebind = mapping.import_kind.rebind.value ();
+ auto data = mapping.data;
+
+ location_t locus = UNKNOWN_LOCATION;
+ std::string declared_name;
+
+ // FIXME: This needs to be done in `FinalizeImports`
+ switch (rebind.get_new_bind_type ())
+ {
+ case AST::UseTreeRebind::NewBindType::IDENTIFIER:
+ declared_name = rebind.get_identifier ().as_string ();
+ locus = rebind.get_identifier ().get_locus ();
+ break;
+ 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 ())
+ {
+ rust_assert (segments.size () > 1);
+ declared_name = segments[segments.size () - 2].as_string ();
+ }
+ else
+ declared_name = path.get_final_segment ().as_string ();
+ locus = path.get_final_segment ().get_locus ();
+ break;
+ }
+ case AST::UseTreeRebind::NewBindType::WILDCARD:
+ rust_unreachable ();
+ break;
+ }
+
+ for (auto &&definition : data.definitions ())
+ toplevel.insert_or_error_out (
+ declared_name, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
+}
+
+void
+Early::visit (AST::UseDeclaration &decl)
+{
+ auto &imports = toplevel.get_imports_to_resolve ();
+ auto current_import = imports.find (decl.get_node_id ());
+ if (current_import != imports.end ())
+ {
+ build_import_mapping (*current_import);
+ }
+
+ // Once this is done, we finalize their resolution
+ for (const auto &mapping : import_mappings.get (decl.get_node_id ()))
+ switch (mapping.import_kind.kind)
+ {
+ case TopLevel::ImportKind::Kind::Glob:
+ finalize_glob_import (ctx, mapping);
+ break;
+ case TopLevel::ImportKind::Kind::Simple:
+ finalize_simple_import (mapping);
+ break;
+ case TopLevel::ImportKind::Kind::Rebind:
+ finalize_rebind_import (mapping);
+ break;
+ }
+
+ DefaultResolver::visit (decl);
+}
+
} // namespace Resolver2_0
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.h b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
index a7ad0f7..e78bec0 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -34,6 +34,7 @@ class Early : public DefaultResolver
{
using DefaultResolver::visit;
+ TopLevel toplevel;
bool dirty;
public:
@@ -59,6 +60,7 @@ public:
void visit (AST::Function &) override;
void visit (AST::StructStruct &) override;
+ void visit (AST::UseDeclaration &) override;
struct ImportData
{
@@ -216,7 +218,6 @@ private:
std::vector<std::pair<Rib::Definition, Namespace>>
resolve_path_in_all_ns (const P &path)
{
- const auto &segments = path.get_segments ();
std::vector<std::pair<Rib::Definition, Namespace>> resolved;
// Pair a definition with the namespace it was found in
@@ -227,9 +228,21 @@ private:
};
};
- ctx.values.resolve_path (segments).map (pair_with_ns (Namespace::Values));
- ctx.types.resolve_path (segments).map (pair_with_ns (Namespace::Types));
- ctx.macros.resolve_path (segments).map (pair_with_ns (Namespace::Macros));
+ std::vector<Error> value_errors;
+ std::vector<Error> type_errors;
+ std::vector<Error> macro_errors;
+
+ ctx.resolve_path (path, value_errors, Namespace::Values)
+ .map (pair_with_ns (Namespace::Values));
+ ctx.resolve_path (path, type_errors, Namespace::Types)
+ .map (pair_with_ns (Namespace::Types));
+ ctx.resolve_path (path, macro_errors, Namespace::Macros)
+ .map (pair_with_ns (Namespace::Macros));
+
+ if (!value_errors.empty () && !type_errors.empty ()
+ && !macro_errors.empty ())
+ for (auto &ent : value_errors)
+ collect_error (std::move (ent));
return resolved;
}
@@ -243,6 +256,13 @@ private:
std::vector<Error> macro_resolve_errors;
void collect_error (Error e) { macro_resolve_errors.push_back (e); }
+
+ void finalize_simple_import (const Early::ImportPair &mapping);
+
+ void finalize_glob_import (NameResolutionContext &ctx,
+ const Early::ImportPair &mapping);
+
+ void finalize_rebind_import (const Early::ImportPair &mapping);
};
} // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc b/gcc/rust/resolve/rust-early-name-resolver.cc
index ce427dd..fc9a26c 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -17,7 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-early-name-resolver.h"
-#include "rust-ast-full.h"
+#include "rust-pattern.h"
#include "rust-name-resolver.h"
#include "rust-macro-builtins.h"
#include "rust-attribute-values.h"
@@ -53,7 +53,7 @@ EarlyNameResolver::accumulate_escaped_macros (AST::Module &module)
scoped (module.get_node_id (), [&module, &escaped_macros, this] {
for (auto &item : module.get_items ())
{
- if (item->get_ast_kind () == AST::Kind::MODULE)
+ if (item->get_item_kind () == AST::Item::Kind::Module)
{
auto &module = *static_cast<AST::Module *> (item.get ());
auto new_macros = accumulate_escaped_macros (module);
@@ -64,7 +64,7 @@ EarlyNameResolver::accumulate_escaped_macros (AST::Module &module)
continue;
}
- if (item->get_ast_kind () == AST::Kind::MACRO_RULES_DEFINITION)
+ if (item->get_item_kind () == AST::Item::Kind::MacroRulesDefinition)
escaped_macros.emplace_back (item->clone_item ());
}
});
@@ -113,7 +113,7 @@ EarlyNameResolver::visit (AST::Crate &crate)
{
auto new_macros = std::vector<std::unique_ptr<AST::Item>> ();
- if (item->get_ast_kind () == AST::Kind::MODULE)
+ if (item->get_item_kind () == AST::Item::Kind::Module)
new_macros = accumulate_escaped_macros (
*static_cast<AST::Module *> (item.get ()));
@@ -156,9 +156,10 @@ EarlyNameResolver::visit (AST::ConstGenericParam &)
void
EarlyNameResolver::visit (AST::PathInExpression &path)
{
- for (auto &segment : path.get_segments ())
- if (segment.has_generic_args ())
- resolve_generic_args (segment.get_generic_args ());
+ if (!path.is_lang_item ())
+ for (auto &segment : path.get_segments ())
+ if (segment.has_generic_args ())
+ resolve_generic_args (segment.get_generic_args ());
}
void
@@ -300,7 +301,7 @@ EarlyNameResolver::visit (AST::Module &module)
{
auto new_macros = std::vector<std::unique_ptr<AST::Item>> ();
- if (item->get_ast_kind () == AST::Kind::MODULE)
+ if (item->get_item_kind () == AST::Item::Kind::Module)
new_macros = accumulate_escaped_macros (
*static_cast<AST::Module *> (item.get ()));
@@ -353,6 +354,8 @@ EarlyNameResolver::visit (AST::TraitItemType &)
void
EarlyNameResolver::visit (AST::Trait &trait)
{
+ // shouldn't need to visit trait.get_implicit_self ()
+
for (auto &generic : trait.get_generic_params ())
generic->accept_vis (*this);
@@ -474,7 +477,8 @@ EarlyNameResolver::visit (AST::MacroInvocation &invoc)
bool found = resolver.get_macro_scope ().lookup (seg, &resolved_node);
if (!found)
{
- rust_error_at (invoc.get_locus (), "unknown macro: [%s]",
+ rust_error_at (invoc.get_locus (), ErrorCode::E0433,
+ "could not resolve macro invocation %qs",
seg.get ().c_str ());
return;
}
@@ -558,30 +562,6 @@ EarlyNameResolver::visit (AST::TupleStructPattern &pattern)
}
void
-EarlyNameResolver::visit (AST::TraitBound &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ImplTraitType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::TraitObjectType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ParenthesisedType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ImplTraitTypeOneBound &)
-{}
-
-void
-EarlyNameResolver::visit (AST::TraitObjectTypeOneBound &)
-{}
-
-void
EarlyNameResolver::visit (AST::TupleType &)
{}
diff --git a/gcc/rust/resolve/rust-early-name-resolver.h b/gcc/rust/resolve/rust-early-name-resolver.h
index 48562df..26fc84d 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.h
+++ b/gcc/rust/resolve/rust-early-name-resolver.h
@@ -36,6 +36,7 @@ public:
private:
using AST::DefaultASTVisitor::visit;
+
/**
* Execute a lambda within a scope. This is equivalent to calling
* `enter_scope` before your code and `exit_scope` after. This ensures
@@ -181,12 +182,6 @@ private:
virtual void visit (AST::StructPatternFieldIdent &field);
virtual void visit (AST::StructPattern &pattern);
virtual void visit (AST::TupleStructPattern &pattern);
- virtual void visit (AST::TraitBound &bound);
- virtual void visit (AST::ImplTraitType &type);
- virtual void visit (AST::TraitObjectType &type);
- virtual void visit (AST::ParenthesisedType &type);
- virtual void visit (AST::ImplTraitTypeOneBound &type);
- virtual void visit (AST::TraitObjectTypeOneBound &type);
virtual void visit (AST::TupleType &type);
virtual void visit (AST::RawPointerType &type);
virtual void visit (AST::ReferenceType &type);
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index 71916ae..b0e8651 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -125,100 +125,5 @@ GlobbingVisitor::visit (AST::UseDeclaration &use)
// Handle cycles ?
}
-void
-finalize_simple_import (TopLevel &toplevel, const Early::ImportPair &mapping)
-{
- // FIXME: We probably need to store namespace information
-
- auto locus = mapping.import_kind.to_resolve.get_locus ();
- auto data = mapping.data;
- auto identifier
- = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
-
- for (auto &&definition : data.definitions ())
- toplevel
- .insert_or_error_out (
- identifier, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
-}
-
-void
-finalize_glob_import (NameResolutionContext &ctx,
- const Early::ImportPair &mapping)
-{
- auto module = Analysis::Mappings::get ().lookup_ast_module (
- mapping.data.module ().get_node_id ());
- rust_assert (module);
-
- GlobbingVisitor glob_visitor (ctx);
- glob_visitor.go (module.value ());
-}
-
-void
-finalize_rebind_import (TopLevel &toplevel, const Early::ImportPair &mapping)
-{
- // We can fetch the value here as `resolve_rebind` will only be called on
- // imports of the right kind
- auto &path = mapping.import_kind.to_resolve;
- auto &rebind = mapping.import_kind.rebind.value ();
- auto data = mapping.data;
-
- location_t locus = UNKNOWN_LOCATION;
- std::string declared_name;
-
- // FIXME: This needs to be done in `FinalizeImports`
- switch (rebind.get_new_bind_type ())
- {
- case AST::UseTreeRebind::NewBindType::IDENTIFIER:
- declared_name = rebind.get_identifier ().as_string ();
- locus = rebind.get_identifier ().get_locus ();
- break;
- case AST::UseTreeRebind::NewBindType::NONE:
- declared_name = path.get_final_segment ().as_string ();
- locus = path.get_final_segment ().get_locus ();
- break;
- case AST::UseTreeRebind::NewBindType::WILDCARD:
- rust_unreachable ();
- break;
- }
-
- for (auto &&definition : data.definitions ())
- toplevel.insert_or_error_out (
- declared_name, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
-}
-
-FinalizeImports::FinalizeImports (Early::ImportMappings &&data,
- TopLevel &toplevel,
- NameResolutionContext &ctx)
- : DefaultResolver (ctx), data (std::move (data)), toplevel (toplevel),
- ctx (ctx)
-{}
-
-void
-FinalizeImports::go (AST::Crate &crate)
-{
- for (auto &item : crate.items)
- item->accept_vis (*this);
-}
-
-void
-FinalizeImports::visit (AST::UseDeclaration &use)
-{
- auto import_mappings = data.get (use.get_node_id ());
-
- for (const auto &mapping : import_mappings)
- switch (mapping.import_kind.kind)
- {
- case TopLevel::ImportKind::Kind::Glob:
- finalize_glob_import (ctx, mapping);
- break;
- case TopLevel::ImportKind::Kind::Simple:
- finalize_simple_import (toplevel, mapping);
- break;
- case TopLevel::ImportKind::Kind::Rebind:
- finalize_rebind_import (toplevel, mapping);
- break;
- }
-}
-
} // namespace Resolver2_0
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h b/gcc/rust/resolve/rust-finalize-imports-2.0.h
index 0fba5a5..d587a5e 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -49,62 +49,5 @@ private:
NameResolutionContext &ctx;
};
-// TODO: Fix documentation
-// How do we do that?
-//
-// We want to resolve in the EarlyNameResolver, but we want to declare in the
-// TopLevel Should the TopLevel declare stubs? How does rustc do it? How to do
-// that for globbing? Should we do globbing afterwards once we've declared all
-// the Uses*?
-//
-// Basically, for each use declare it in a separate map - in the
-// EarlyNameResolver resolve and fix the ForeverStack? Emptying the maps each
-// time?
-//
-// e.g. TopLevel builds a std::vector<NodeId, SimplePath> use_trees_to_resolve;
-// Early goes through and resolves the SimplePath, then replaces the NodeId with
-// the resolved one? Do we even need to do that?
-//
-// rustc just creates an empty definition for the use tree.
-//
-// What about globbing? std::vector<GlobbulesPath> globules;
-// Early goes through and visits the module's path and calls the
-// GlobbingVisitor?
-//
-// the file `imports.rs` goes through and *finalizes* imports. So we can
-// probably add a FinalizeImport pass after the TopLevel and the Early.
-// - TopLevel takes care of declaring these use trees
-// - Early takes care of resolving them to definition points
-// - Finalize takes care of mapping the use's definition point to the actual
-// definition point
-// - We need to work more on that last bit to know exactly what is being
-// inserted, but probably it's going to mutate the ForeverStack - is that okay?
-// - Oh actually maybe no!
-// - TopLevel creates a map of UseTrees with paths to resolve. This should
-// probably be an ImportKind enum or whatever
-// - Early resolves them, creates a map of SimplePath with the associated
-// definition: Map<ImportKind, ImportData>
-// - Finalizes visits all UseTrees and inserts the Definitions found for
-// each ImportKind - easy!
-// - yay!
-
-class FinalizeImports : DefaultResolver
-{
-public:
- FinalizeImports (Early::ImportMappings &&data, TopLevel &toplevel,
- NameResolutionContext &ctx);
-
- void go (AST::Crate &crate);
-
-private:
- using AST::DefaultASTVisitor::visit;
-
- void visit (AST::UseDeclaration &) override;
-
- Early::ImportMappings data;
- TopLevel &toplevel;
- NameResolutionContext &ctx;
-};
-
} // namespace Resolver2_0
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-forever-stack.cc b/gcc/rust/resolve/rust-forever-stack.cc
new file mode 100644
index 0000000..725ae0e
--- /dev/null
+++ b/gcc/rust/resolve/rust-forever-stack.cc
@@ -0,0 +1,318 @@
+// Copyright (C) 2024 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 "expected.h"
+#include "rust-ast.h"
+#include "rust-diagnostics.h"
+#include "rust-forever-stack.h"
+#include "rust-rib.h"
+#include "optional.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+bool
+ForeverStackStore::Node::is_root () const
+{
+ return !parent.has_value ();
+}
+
+bool
+ForeverStackStore::Node::is_leaf () const
+{
+ return children.empty ();
+}
+
+NodeId
+ForeverStackStore::Node::get_id () const
+{
+ return id;
+}
+
+ForeverStackStore::Node &
+ForeverStackStore::Node::insert_child (NodeId id, tl::optional<Identifier> path,
+ Rib::Kind kind)
+{
+ auto res = children.insert ({Link (id, path), Node (kind, id, *this)});
+
+ rust_debug ("inserting link: Link(%d [%s]): existed? %s", id,
+ path.has_value () ? path.value ().as_string ().c_str ()
+ : "<anon>",
+ !res.second ? "yes" : "no");
+
+ // sanity check on rib kind
+ // pick the value rib, since all ribs should have the same kind anyways
+ rust_assert (res.second || res.first->second.value_rib.kind == kind);
+
+ // verify, if we're using an existing node, our paths don't contradict
+ if (!res.second && path.has_value ())
+ {
+ auto other_path = res.first->first.path;
+ rust_assert (!other_path.has_value ()
+ || other_path.value ().as_string ()
+ == path.value ().as_string ());
+ }
+
+ return res.first->second;
+}
+
+tl::optional<ForeverStackStore::Node &>
+ForeverStackStore::Node::get_child (const Identifier &path)
+{
+ for (auto &ent : children)
+ {
+ if (ent.first.path.has_value ()
+ && ent.first.path->as_string () == path.as_string ())
+ return ent.second;
+ }
+ return tl::nullopt;
+}
+
+tl::optional<const ForeverStackStore::Node &>
+ForeverStackStore::Node::get_child (const Identifier &path) const
+{
+ for (auto &ent : children)
+ {
+ if (ent.first.path.has_value ()
+ && ent.first.path->as_string () == path.as_string ())
+ return ent.second;
+ }
+ return tl::nullopt;
+}
+
+tl::optional<ForeverStackStore::Node &>
+ForeverStackStore::Node::get_parent ()
+{
+ return parent;
+}
+
+tl::optional<const ForeverStackStore::Node &>
+ForeverStackStore::Node::get_parent () const
+{
+ if (parent)
+ return *parent;
+ return tl::nullopt;
+}
+
+tl::optional<const Identifier &>
+ForeverStackStore::Node::get_parent_path () const
+{
+ if (parent.has_value ())
+ for (auto &ent : parent->children)
+ if (ent.first.id == id && ent.first.path.has_value ())
+ return ent.first.path.value ();
+ return tl::nullopt;
+}
+
+Rib &
+ForeverStackStore::Node::get_rib (Namespace ns)
+{
+ switch (ns)
+ {
+ case Namespace::Values:
+ return value_rib;
+ case Namespace::Types:
+ return type_rib;
+ case Namespace::Labels:
+ return label_rib;
+ case Namespace::Macros:
+ return macro_rib;
+ default:
+ rust_unreachable ();
+ }
+}
+
+const Rib &
+ForeverStackStore::Node::get_rib (Namespace ns) const
+{
+ switch (ns)
+ {
+ case Namespace::Values:
+ return value_rib;
+ case Namespace::Types:
+ return type_rib;
+ case Namespace::Labels:
+ return label_rib;
+ case Namespace::Macros:
+ return macro_rib;
+ default:
+ rust_unreachable ();
+ }
+}
+
+tl::expected<NodeId, DuplicateNameError>
+ForeverStackStore::Node::insert (const Identifier &name, NodeId node,
+ Namespace ns)
+{
+ // So what do we do here - if the Rib has already been pushed in an earlier
+ // pass, we might end up in a situation where it is okay to re-add new names.
+ // Do we just ignore that here? Do we keep track of if the Rib is new or not?
+ // should our cursor have info on the current node like "is it newly pushed"?
+ return get_rib (ns).insert (name.as_string (),
+ Rib::Definition::NonShadowable (node));
+}
+
+tl::expected<NodeId, DuplicateNameError>
+ForeverStackStore::Node::insert_shadowable (const Identifier &name, NodeId node,
+ Namespace ns)
+{
+ return get_rib (ns).insert (name.as_string (),
+ Rib::Definition::Shadowable (node));
+}
+
+tl::expected<NodeId, DuplicateNameError>
+ForeverStackStore::Node::insert_globbed (const Identifier &name, NodeId node,
+ Namespace ns)
+{
+ return get_rib (ns).insert (name.as_string (),
+ Rib::Definition::Globbed (node));
+}
+
+void
+ForeverStackStore::Node::reverse_iter (std::function<KeepGoing (Node &)> lambda)
+{
+ for (Node *tmp = this; lambda (*tmp) == KeepGoing::Yes && !tmp->is_root ();
+ tmp = &tmp->parent.value ())
+ ;
+}
+
+void
+ForeverStackStore::Node::reverse_iter (
+ std::function<KeepGoing (const Node &)> lambda) const
+{
+ for (const Node *tmp = this;
+ lambda (*tmp) == KeepGoing::Yes && !tmp->is_root ();
+ tmp = &tmp->parent.value ())
+ ;
+}
+
+void
+ForeverStackStore::Node::child_iter (
+ std::function<KeepGoing (NodeId, tl::optional<const Identifier &>, Node &)>
+ lambda)
+{
+ for (auto &ent : children)
+ {
+ tl::optional<const Identifier &> path;
+ if (ent.first.path.has_value ())
+ path = ent.first.path.value ();
+ auto keep_going = lambda (ent.first.id, path, ent.second);
+ if (keep_going == KeepGoing::No)
+ return;
+ }
+}
+
+void
+ForeverStackStore::Node::child_iter (
+ std::function<KeepGoing (NodeId, tl::optional<const Identifier &>,
+ const Node &)>
+ lambda) const
+{
+ for (auto &ent : children)
+ {
+ tl::optional<const Identifier &> path;
+ if (ent.first.path.has_value ())
+ path = ent.first.path.value ();
+ auto keep_going = lambda (ent.first.id, path, ent.second);
+ if (keep_going == KeepGoing::No)
+ return;
+ }
+}
+
+ForeverStackStore::Node &
+ForeverStackStore::Node::find_closest_module ()
+{
+ // get kind of value_rib
+ // but all ribs should share the same kind anyways
+ if (value_rib.kind == Rib::Kind::Module || !parent.has_value ())
+ return *this;
+ else
+ return parent->find_closest_module ();
+}
+
+const ForeverStackStore::Node &
+ForeverStackStore::Node::find_closest_module () const
+{
+ // get kind of value_rib
+ // but all ribs should share the same kind anyways
+ if (value_rib.kind != Rib::Kind::Module || !parent.has_value ())
+ return *this;
+ else
+ return parent->find_closest_module ();
+}
+
+tl::optional<ForeverStackStore::Node &>
+ForeverStackStore::Node::dfs_node (NodeId to_find)
+{
+ if (id == to_find)
+ return *this;
+
+ for (auto &child : children)
+ {
+ auto candidate = child.second.dfs_node (to_find);
+
+ if (candidate.has_value ())
+ return candidate;
+ }
+
+ return tl::nullopt;
+}
+
+tl::optional<const ForeverStackStore::Node &>
+ForeverStackStore::Node::dfs_node (NodeId to_find) const
+{
+ if (id == to_find)
+ return *this;
+
+ for (auto &child : children)
+ {
+ auto candidate = child.second.dfs_node (to_find);
+
+ if (candidate.has_value ())
+ return candidate;
+ }
+
+ return tl::nullopt;
+}
+
+ForeverStackStore::Node &
+ForeverStackStore::get_root ()
+{
+ return root;
+}
+
+const ForeverStackStore::Node &
+ForeverStackStore::get_root () const
+{
+ return root;
+}
+
+tl::optional<ForeverStackStore::Node &>
+ForeverStackStore::get_node (NodeId node_id)
+{
+ return root.dfs_node (node_id);
+}
+
+tl::optional<const ForeverStackStore::Node &>
+ForeverStackStore::get_node (NodeId node_id) const
+{
+ return root.dfs_node (node_id);
+}
+
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h
index 8c5e207..81468e5 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -392,17 +392,173 @@ not contain any imports, macro definitions or macro invocations. You can look at
this pass's documentation for more details on this resolution process.
**/
+
+/**
+ * Intended for use by ForeverStack to store Nodes
+ * Unlike ForeverStack, does not store a cursor reference
+ * Intended to make path resolution in multiple namespaces simpler
+ **/
+class ForeverStackStore
+{
+public:
+ ForeverStackStore (NodeId crate_id) : root (Rib::Kind::Normal, crate_id)
+ {
+ rust_assert (root.is_root ());
+ rust_assert (root.is_leaf ());
+ }
+
+private:
+ /**
+ * A link between two Nodes in our trie data structure. This class represents
+ * the edges of the graph
+ */
+ class Link
+ {
+ public:
+ Link (NodeId id, tl::optional<Identifier> path) : id (id), path (path) {}
+
+ bool compare (const Link &other) const { return id < other.id; }
+
+ NodeId id;
+ tl::optional<Identifier> path;
+ };
+
+ /* Link comparison class, which we use in a Node's `children` map */
+ class LinkCmp
+ {
+ public:
+ bool operator() (const Link &lhs, const Link &rhs) const
+ {
+ return lhs.compare (rhs);
+ }
+ };
+
+public:
+ class Node;
+
+ struct DfsResult
+ {
+ Node &first;
+ std::string second;
+ };
+
+ struct ConstDfsResult
+ {
+ const Node &first;
+ std::string second;
+ };
+
+ /* Should we keep going upon seeing a Rib? */
+ enum class KeepGoing
+ {
+ Yes,
+ No,
+ };
+
+ class Node
+ {
+ private:
+ friend class ForeverStackStore::ForeverStackStore;
+
+ Node (Rib::Kind rib_kind, NodeId id, tl::optional<Node &> parent)
+ : value_rib (rib_kind), type_rib (rib_kind), label_rib (rib_kind),
+ macro_rib (rib_kind), id (id), parent (parent)
+ {}
+ Node (Rib::Kind rib_kind, NodeId id) : Node (rib_kind, id, tl::nullopt) {}
+ Node (Rib::Kind rib_kind, NodeId id, Node &parent)
+ : Node (rib_kind, id, tl::optional<Node &> (parent))
+ {}
+
+ public:
+ Node (const Node &) = default;
+ Node (Node &&) = default;
+ Node &operator= (const Node &) = delete;
+ Node &operator= (Node &&) = default;
+
+ bool is_root () const;
+ bool is_leaf () const;
+
+ NodeId get_id () const;
+
+ Node &insert_child (NodeId id, tl::optional<Identifier> path,
+ Rib::Kind kind);
+
+ tl::optional<Node &> get_child (const Identifier &path);
+ tl::optional<const Node &> get_child (const Identifier &path) const;
+
+ tl::optional<Node &> get_parent ();
+ tl::optional<const Node &> get_parent () const;
+
+ // finds the identifier, if any, used to link
+ // this node's parent to this node
+ tl::optional<const Identifier &> get_parent_path () const;
+
+ Rib &get_rib (Namespace ns);
+ const Rib &get_rib (Namespace ns) const;
+
+ tl::expected<NodeId, DuplicateNameError> insert (const Identifier &name,
+ NodeId node, Namespace ns);
+ tl::expected<NodeId, DuplicateNameError>
+ insert_shadowable (const Identifier &name, NodeId node, Namespace ns);
+ tl::expected<NodeId, DuplicateNameError>
+ insert_globbed (const Identifier &name, NodeId node, Namespace ns);
+
+ void reverse_iter (std::function<KeepGoing (Node &)> lambda);
+ void reverse_iter (std::function<KeepGoing (const Node &)> lambda) const;
+
+ void child_iter (std::function<KeepGoing (
+ NodeId, tl::optional<const Identifier &>, Node &)>
+ lambda);
+ void child_iter (std::function<KeepGoing (
+ NodeId, tl::optional<const Identifier &>, const Node &)>
+ lambda) const;
+
+ Node &find_closest_module ();
+ const Node &find_closest_module () const;
+
+ tl::optional<Node &> dfs_node (NodeId to_find);
+ tl::optional<const Node &> dfs_node (NodeId to_find) const;
+
+ private:
+ // per-namespace ribs
+ Rib value_rib;
+ Rib type_rib;
+ Rib label_rib;
+ Rib macro_rib;
+ // all linked nodes
+ std::map<Link, Node, LinkCmp> children;
+
+ NodeId id; // The node id of the Node's scope
+
+ tl::optional<Node &> parent; // `None` only if the node is a root
+ };
+
+ Node &get_root ();
+ const Node &get_root () const;
+
+ tl::optional<Node &> get_node (NodeId node_id);
+ tl::optional<const Node &> get_node (NodeId node_id) const;
+
+private:
+ Node root;
+};
+
template <Namespace N> class ForeverStack
{
public:
ForeverStack ()
- // FIXME: Is that valid? Do we use the root? If yes, we should give the
- // crate's node id to ForeverStack's constructor
: root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)),
+ lang_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)),
+ extern_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID)),
cursor_reference (root)
{
rust_assert (root.is_root ());
rust_assert (root.is_leaf ());
+
+ // TODO: Should we be using the forever stack root as the crate scope?
+ // TODO: Is this how we should be getting the crate node id?
+ auto &mappings = Analysis::Mappings::get ();
+ root.id = *mappings.crate_num_to_nodeid (mappings.get_current_crate ());
}
/**
@@ -416,7 +572,7 @@ public:
* @param path An optional path if the Rib was created due to a "named"
* lexical scope, like a module's.
*/
- void push (Rib rib, NodeId id, tl::optional<Identifier> path = {});
+ void push (Rib::Kind rib_kind, NodeId id, tl::optional<Identifier> path = {});
/**
* Pop the innermost Rib from the stack
@@ -437,6 +593,9 @@ public:
*/
tl::expected<NodeId, DuplicateNameError> insert (Identifier name, NodeId id);
+ tl::expected<NodeId, DuplicateNameError> insert_variant (Identifier name,
+ NodeId id);
+
/**
* Insert a new shadowable definition in the innermost `Rib` in this stack
*
@@ -500,6 +659,8 @@ public:
* the current map, an empty one otherwise.
*/
tl::optional<Rib::Definition> get (const Identifier &name);
+ tl::optional<Rib::Definition> get_lang_prelude (const Identifier &name);
+ tl::optional<Rib::Definition> get_lang_prelude (const std::string &name);
/**
* Resolve a path to its definition in the current `ForeverStack`
@@ -510,7 +671,10 @@ public:
* current map, an empty one otherwise.
*/
template <typename S>
- tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments);
+ tl::optional<Rib::Definition> resolve_path (
+ const std::vector<S> &segments, bool has_opening_scope_resolution,
+ 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;
@@ -519,7 +683,13 @@ public:
tl::optional<Rib &> to_rib (NodeId rib_id);
tl::optional<const Rib &> to_rib (NodeId rib_id) const;
- std::string as_debug_string ();
+ std::string as_debug_string () const;
+
+ /**
+ * Used to check if a module is a descendant of another module
+ * Intended for use in the privacy checker
+ */
+ bool is_module_descendant (NodeId parent, NodeId child) const;
private:
/**
@@ -556,6 +726,7 @@ private:
{}
bool is_root () const;
+ bool is_prelude () const;
bool is_leaf () const;
void insert_child (Link link, Node child);
@@ -591,13 +762,25 @@ private:
const Node &cursor () const;
void update_cursor (Node &new_cursor);
+ /* The forever stack's actual nodes */
Node root;
+ /*
+ * A special prelude node used currently for resolving language builtins
+ * It has the root node as a parent, and acts as a "special case" for name
+ * resolution
+ */
+ Node lang_prelude;
+ /*
+ * The extern prelude, used for resolving external crates
+ */
+ Node extern_prelude;
+
std::reference_wrapper<Node> cursor_reference;
void stream_rib (std::stringstream &stream, const Rib &rib,
- const std::string &next, const std::string &next_next);
+ const std::string &next, const std::string &next_next) const;
void stream_node (std::stringstream &stream, unsigned indentation,
- const Node &node);
+ const Node &node) const;
/* Helper types and functions for `resolve_path` */
@@ -607,13 +790,22 @@ private:
Node &find_closest_module (Node &starting_point);
template <typename S>
- tl::optional<SegIterator<S>>
- find_starting_point (const std::vector<S> &segments, Node &starting_point);
+ tl::optional<SegIterator<S>> find_starting_point (
+ const std::vector<S> &segments,
+ std::reference_wrapper<Node> &starting_point,
+ std::function<void (const S &, NodeId)> insert_segment_resolution,
+ std::vector<Error> &collect_errors);
template <typename S>
- tl::optional<Node &> resolve_segments (Node &starting_point,
- const std::vector<S> &segments,
- SegIterator<S> iterator);
+ tl::optional<Node &> resolve_segments (
+ Node &starting_point, const std::vector<S> &segments,
+ SegIterator<S> iterator,
+ std::function<void (const S &, NodeId)> insert_segment_resolution,
+ std::vector<Error> &collect_errors);
+
+ tl::optional<Rib::Definition> resolve_final_segment (Node &final_node,
+ std::string &seg_name,
+ bool is_lower_self);
/* Helper functions for forward resolution (to_canonical_path, to_rib...) */
struct DfsResult
@@ -635,6 +827,25 @@ private:
tl::optional<Rib &> dfs_rib (Node &starting_point, NodeId to_find);
tl::optional<const Rib &> dfs_rib (const Node &starting_point,
NodeId to_find) const;
+ // FIXME: Documentation
+ tl::optional<Node &> dfs_node (Node &starting_point, NodeId to_find);
+ tl::optional<const Node &> dfs_node (const Node &starting_point,
+ NodeId to_find) const;
+
+public:
+ bool forward_declared (NodeId definition, NodeId usage)
+ {
+ if (peek ().kind != Rib::Kind::ForwardTypeParamBan)
+ return false;
+
+ const auto &definition_rib = dfs_rib (cursor (), definition);
+
+ if (!definition_rib)
+ return false;
+
+ return (definition_rib
+ && definition_rib.value ().kind == Rib::Kind::ForwardTypeParamBan);
+ }
};
} // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index 5a5a7c7..069111ee 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -20,7 +20,9 @@
#include "rust-ast.h"
#include "rust-diagnostics.h"
#include "rust-forever-stack.h"
+#include "rust-edition.h"
#include "rust-rib.h"
+#include "rust-unwrap-segment.h"
#include "optional.h"
namespace Rust {
@@ -35,6 +37,13 @@ ForeverStack<N>::Node::is_root () const
template <Namespace N>
bool
+ForeverStack<N>::Node::is_prelude () const
+{
+ return rib.kind == Rib::Kind::Prelude;
+}
+
+template <Namespace N>
+bool
ForeverStack<N>::Node::is_leaf () const
{
return children.empty ();
@@ -52,15 +61,26 @@ ForeverStack<N>::Node::insert_child (Link link, Node child)
template <Namespace N>
void
-ForeverStack<N>::push (Rib rib, NodeId id, tl::optional<Identifier> path)
+ForeverStack<N>::push (Rib::Kind rib_kind, NodeId id,
+ tl::optional<Identifier> path)
{
- push_inner (rib, Link (id, path));
+ push_inner (rib_kind, Link (id, path));
}
template <Namespace N>
void
ForeverStack<N>::push_inner (Rib rib, Link link)
{
+ if (rib.kind == Rib::Kind::Prelude)
+ {
+ // If you push_inner into the prelude from outside the root, you will pop
+ // back into the root, which could screw up a traversal.
+ rust_assert (&cursor_reference.get () == &root);
+ // Prelude doesn't have an access path
+ rust_assert (!link.path);
+ update_cursor (this->lang_prelude);
+ return;
+ }
// If the link does not exist, we create it and emplace a new `Node` with the
// current node as its parent. `unordered_map::emplace` returns a pair with
// the iterator and a boolean. If the value already exists, the iterator
@@ -171,6 +191,14 @@ ForeverStack<Namespace::Labels>::insert (Identifier name, NodeId node)
Rib::Definition::Shadowable (node));
}
+template <>
+inline tl::expected<NodeId, DuplicateNameError>
+ForeverStack<Namespace::Types>::insert_variant (Identifier name, NodeId node)
+{
+ return insert_inner (peek (), name.as_string (),
+ Rib::Definition::NonShadowable (node, true));
+}
+
template <Namespace N>
Rib &
ForeverStack<N>::peek ()
@@ -273,10 +301,12 @@ ForeverStack<N>::get (const Identifier &name)
return candidate.map_or (
[&resolved_definition] (Rib::Definition found) {
- // for most namespaces, we do not need to care about various ribs - they
- // are available from all contexts if defined in the current scope, or
- // an outermore one. so if we do have a candidate, we can return it
- // directly and stop iterating
+ if (found.is_variant ())
+ return KeepGoing::Yes;
+ // for most namespaces, we do not need to care about various ribs -
+ // they are available from all contexts if defined in the current
+ // scope, or an outermore one. so if we do have a candidate, we can
+ // return it directly and stop iterating
resolved_definition = found;
return KeepGoing::No;
@@ -288,6 +318,20 @@ ForeverStack<N>::get (const Identifier &name)
return resolved_definition;
}
+template <Namespace N>
+tl::optional<Rib::Definition>
+ForeverStack<N>::get_lang_prelude (const Identifier &name)
+{
+ return lang_prelude.rib.get (name.as_string ());
+}
+
+template <Namespace N>
+tl::optional<Rib::Definition>
+ForeverStack<N>::get_lang_prelude (const std::string &name)
+{
+ return lang_prelude.rib.get (name);
+}
+
template <>
tl::optional<Rib::Definition> inline ForeverStack<Namespace::Labels>::get (
const Identifier &name)
@@ -354,12 +398,13 @@ ForeverStack<N>::find_closest_module (Node &starting_point)
* segments */
template <typename S>
static inline bool
-check_leading_kw_at_start (const S &segment, bool condition)
+check_leading_kw_at_start (std::vector<Error> &collect_errors, const S &segment,
+ bool condition)
{
if (condition)
- rust_error_at (
+ collect_errors.emplace_back (
segment.get_locus (), ErrorCode::E0433,
- "leading path segment %qs can only be used at the beginning of a path",
+ "%qs in paths can only be used in start position",
segment.as_string ().c_str ());
return condition;
@@ -373,52 +418,61 @@ check_leading_kw_at_start (const S &segment, bool condition)
template <Namespace N>
template <typename S>
tl::optional<typename std::vector<S>::const_iterator>
-ForeverStack<N>::find_starting_point (const std::vector<S> &segments,
- Node &starting_point)
+ForeverStack<N>::find_starting_point (
+ const std::vector<S> &segments, std::reference_wrapper<Node> &starting_point,
+ std::function<void (const S &, NodeId)> insert_segment_resolution,
+ std::vector<Error> &collect_errors)
{
auto iterator = segments.begin ();
- // If we need to do path segment resolution, then we start
- // at the closest module. In order to resolve something like `foo::bar!()`, we
- // need to get back to the surrounding module, and look for a child module
- // named `foo`.
- if (segments.size () > 1)
- starting_point = find_closest_module (starting_point);
-
for (; !is_last (iterator, segments); iterator++)
{
- auto &seg = *iterator;
- auto is_self_or_crate
+ auto &outer_seg = *iterator;
+
+ if (unwrap_segment_get_lang_item (outer_seg).has_value ())
+ break;
+
+ auto &seg = unwrap_type_segment (outer_seg);
+ bool is_self_or_crate
= seg.is_crate_path_seg () || seg.is_lower_self_seg ();
// if we're after the first path segment and meet `self` or `crate`, it's
// an error - we should only be seeing `super` keywords at this point
- if (check_leading_kw_at_start (seg, !is_start (iterator, segments)
- && is_self_or_crate))
+ if (check_leading_kw_at_start (collect_errors, seg,
+ !is_start (iterator, segments)
+ && is_self_or_crate))
return tl::nullopt;
if (seg.is_crate_path_seg ())
{
starting_point = root;
+ insert_segment_resolution (outer_seg, starting_point.get ().id);
iterator++;
break;
}
if (seg.is_lower_self_seg ())
{
- // do nothing and exit
+ // insert segment resolution and exit
+ starting_point = find_closest_module (starting_point);
+ insert_segment_resolution (outer_seg, starting_point.get ().id);
iterator++;
break;
}
if (seg.is_super_path_seg ())
{
- if (starting_point.is_root ())
+ starting_point = find_closest_module (starting_point);
+ if (starting_point.get ().is_root ())
{
- rust_error_at (seg.get_locus (), ErrorCode::E0433,
- "too many leading %<super%> keywords");
+ collect_errors.emplace_back (
+ seg.get_locus (), ErrorCode::E0433,
+ "too many leading %<super%> keywords");
return tl::nullopt;
}
- starting_point = find_closest_module (starting_point.parent.value ());
+ starting_point
+ = find_closest_module (starting_point.get ().parent.value ());
+
+ insert_segment_resolution (outer_seg, starting_point.get ().id);
continue;
}
@@ -436,73 +490,223 @@ template <typename S>
tl::optional<typename ForeverStack<N>::Node &>
ForeverStack<N>::resolve_segments (
Node &starting_point, const std::vector<S> &segments,
- typename std::vector<S>::const_iterator iterator)
+ typename std::vector<S>::const_iterator iterator,
+ std::function<void (const S &, NodeId)> insert_segment_resolution,
+ std::vector<Error> &collect_errors)
{
- auto *current_node = &starting_point;
+ Node *current_node = &starting_point;
for (; !is_last (iterator, segments); iterator++)
{
- auto &seg = *iterator;
- auto str = seg.as_string ();
+ auto &outer_seg = *iterator;
+
+ if (auto lang_item = unwrap_segment_get_lang_item (outer_seg))
+ {
+ NodeId seg_id = Analysis::Mappings::get ().get_lang_item_node (
+ lang_item.value ());
+ current_node = &dfs_node (root, seg_id).value ();
+
+ insert_segment_resolution (outer_seg, seg_id);
+ continue;
+ }
+
+ auto &seg = unwrap_type_segment (outer_seg);
+ std::string str = seg.as_string ();
rust_debug ("[ARTHUR]: resolving segment part: %s", str.c_str ());
// check that we don't encounter *any* leading keywords afterwards
- if (check_leading_kw_at_start (seg, seg.is_crate_path_seg ()
- || seg.is_super_path_seg ()
- || seg.is_lower_self_seg ()))
+ if (check_leading_kw_at_start (collect_errors, seg,
+ seg.is_crate_path_seg ()
+ || seg.is_super_path_seg ()
+ || seg.is_lower_self_seg ()))
return tl::nullopt;
tl::optional<typename ForeverStack<N>::Node &> child = tl::nullopt;
- for (auto &kv : current_node->children)
+ /*
+ * On every iteration this loop either
+ *
+ * 1. terminates
+ *
+ * 2. decreases the depth of the node pointed to by current_node until
+ * current_node reaches the root
+ *
+ * 3. If the root node is reached, and we were not able to resolve the
+ * segment, we search the prelude rib for the segment, by setting
+ * current_node to point to the prelude, and toggling the
+ * searched_prelude boolean to true. If current_node is the prelude
+ * rib, and searched_prelude is true, we will exit.
+ *
+ * This ensures termination.
+ *
+ */
+ bool searched_prelude = false;
+ while (true)
{
- auto &link = kv.first;
+ // may set the value of child
+ for (auto &kv : current_node->children)
+ {
+ auto &link = kv.first;
+
+ if (link.path.map_or (
+ [&str] (Identifier path) {
+ auto &path_str = path.as_string ();
+ return str == path_str;
+ },
+ false))
+ {
+ child = kv.second;
+ break;
+ }
+ }
- if (link.path.map_or (
- [&str] (Identifier path) {
- auto &path_str = path.as_string ();
- return str == path_str;
- },
- false))
+ if (child.has_value ())
{
- child = kv.second;
break;
}
- }
- if (!child.has_value ())
- {
- rust_error_at (seg.get_locus (), ErrorCode::E0433,
- "failed to resolve path segment %qs", str.c_str ());
- return tl::nullopt;
+ if (N == Namespace::Types)
+ {
+ auto rib_lookup = current_node->rib.get (seg.as_string ());
+ if (rib_lookup && !rib_lookup->is_ambiguous ())
+ {
+ insert_segment_resolution (outer_seg,
+ rib_lookup->get_node_id ());
+ return tl::nullopt;
+ }
+ }
+
+ if (current_node->is_root () && !searched_prelude)
+ {
+ searched_prelude = true;
+ current_node = &lang_prelude;
+ continue;
+ }
+
+ if (!is_start (iterator, segments)
+ || current_node->rib.kind == Rib::Kind::Module
+ || current_node->is_prelude ())
+ {
+ return tl::nullopt;
+ }
+
+ current_node = &current_node->parent.value ();
}
+ // if child didn't contain a value
+ // the while loop above should have return'd or kept looping
current_node = &child.value ();
+ insert_segment_resolution (outer_seg, current_node->id);
}
return *current_node;
}
+template <>
+inline tl::optional<Rib::Definition>
+ForeverStack<Namespace::Types>::resolve_final_segment (Node &final_node,
+ std::string &seg_name,
+ bool is_lower_self)
+{
+ if (is_lower_self)
+ return Rib::Definition::NonShadowable (final_node.id);
+ else
+ return final_node.rib.get (seg_name);
+}
+
+template <Namespace N>
+tl::optional<Rib::Definition>
+ForeverStack<N>::resolve_final_segment (Node &final_node, std::string &seg_name,
+ bool is_lower_self)
+{
+ return final_node.rib.get (seg_name);
+}
+
template <Namespace N>
template <typename S>
tl::optional<Rib::Definition>
-ForeverStack<N>::resolve_path (const std::vector<S> &segments)
+ForeverStack<N>::resolve_path (
+ const std::vector<S> &segments, bool has_opening_scope_resolution,
+ std::function<void (const S &, NodeId)> insert_segment_resolution,
+ std::vector<Error> &collect_errors)
{
// TODO: What to do if segments.empty() ?
+ // handle paths with opening scopes
+ std::function<void (void)> cleanup_current = [] () {};
+ if (has_opening_scope_resolution)
+ {
+ 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; };
+ }
+
// if there's only one segment, we just use `get`
if (segments.size () == 1)
- return get (segments.back ().as_string ());
+ {
+ auto &seg = segments.front ();
+ if (auto lang_item = unwrap_segment_get_lang_item (seg))
+ {
+ NodeId seg_id = Analysis::Mappings::get ().get_lang_item_node (
+ lang_item.value ());
- auto starting_point = cursor ();
+ insert_segment_resolution (seg, seg_id);
+ cleanup_current ();
+ // TODO: does NonShadowable matter?
+ return Rib::Definition::NonShadowable (seg_id);
+ }
- return find_starting_point (segments, starting_point)
- .and_then ([this, &segments, &starting_point] (
- typename std::vector<S>::const_iterator iterator) {
- return resolve_segments (starting_point, segments, iterator);
- })
- .and_then ([&segments] (Node final_node) {
- return final_node.rib.get (segments.back ().as_string ());
- });
+ tl::optional<Rib::Definition> res
+ = get (unwrap_type_segment (segments.back ()).as_string ());
+
+ if (!res)
+ res = get_lang_prelude (
+ unwrap_type_segment (segments.back ()).as_string ());
+
+ if (res && !res->is_ambiguous ())
+ insert_segment_resolution (segments.back (), res->get_node_id ());
+ cleanup_current ();
+ return res;
+ }
+
+ std::reference_wrapper<Node> starting_point = cursor ();
+
+ 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;
}
template <Namespace N>
@@ -593,7 +797,7 @@ ForeverStack<N>::to_canonical_path (NodeId id) const
auto &link = kv.first;
auto &child = kv.second;
- if (link.id == child.id)
+ if (current.id == child.id)
{
outer_link = &link;
break;
@@ -611,7 +815,12 @@ ForeverStack<N>::to_canonical_path (NodeId id) const
return KeepGoing::Yes;
});
- auto path = Resolver::CanonicalPath::create_empty ();
+ 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);
@@ -626,12 +835,31 @@ template <Namespace N>
tl::optional<Rib &>
ForeverStack<N>::dfs_rib (ForeverStack<N>::Node &starting_point, NodeId to_find)
{
+ return dfs_node (starting_point, to_find).map ([] (Node &x) -> Rib & {
+ return x.rib;
+ });
+}
+
+template <Namespace N>
+tl::optional<const Rib &>
+ForeverStack<N>::dfs_rib (const ForeverStack<N>::Node &starting_point,
+ NodeId to_find) const
+{
+ return dfs_node (starting_point, to_find)
+ .map ([] (const Node &x) -> const Rib & { return x.rib; });
+}
+
+template <Namespace N>
+tl::optional<typename ForeverStack<N>::Node &>
+ForeverStack<N>::dfs_node (ForeverStack<N>::Node &starting_point,
+ NodeId to_find)
+{
if (starting_point.id == to_find)
- return starting_point.rib;
+ return starting_point;
for (auto &child : starting_point.children)
{
- auto candidate = dfs_rib (child.second, to_find);
+ auto candidate = dfs_node (child.second, to_find);
if (candidate.has_value ())
return candidate;
@@ -641,16 +869,16 @@ ForeverStack<N>::dfs_rib (ForeverStack<N>::Node &starting_point, NodeId to_find)
}
template <Namespace N>
-tl::optional<const Rib &>
-ForeverStack<N>::dfs_rib (const ForeverStack<N>::Node &starting_point,
- NodeId to_find) const
+tl::optional<const typename ForeverStack<N>::Node &>
+ForeverStack<N>::dfs_node (const ForeverStack<N>::Node &starting_point,
+ NodeId to_find) const
{
if (starting_point.id == to_find)
- return starting_point.rib;
+ return starting_point;
for (auto &child : starting_point.children)
{
- auto candidate = dfs_rib (child.second, to_find);
+ auto candidate = dfs_node (child.second, to_find);
if (candidate.has_value ())
return candidate;
@@ -677,15 +905,19 @@ template <Namespace N>
void
ForeverStack<N>::stream_rib (std::stringstream &stream, const Rib &rib,
const std::string &next,
- const std::string &next_next)
+ const std::string &next_next) const
{
+ std::string rib_kind = Rib::kind_to_string (rib.kind);
+ stream << next << "rib [" << rib_kind << "]: {";
if (rib.get_values ().empty ())
{
- stream << next << "rib: {},\n";
+ stream << "}\n";
return;
}
-
- stream << next << "rib: {\n";
+ else
+ {
+ stream << "\n";
+ }
for (const auto &kv : rib.get_values ())
stream << next_next << kv.first << ": " << kv.second.to_string () << "\n";
@@ -696,7 +928,7 @@ ForeverStack<N>::stream_rib (std::stringstream &stream, const Rib &rib,
template <Namespace N>
void
ForeverStack<N>::stream_node (std::stringstream &stream, unsigned indentation,
- const ForeverStack<N>::Node &node)
+ const ForeverStack<N>::Node &node) const
{
auto indent = std::string (indentation, ' ');
auto next = std::string (indentation + 4, ' ');
@@ -728,7 +960,7 @@ ForeverStack<N>::stream_node (std::stringstream &stream, unsigned indentation,
template <Namespace N>
std::string
-ForeverStack<N>::as_debug_string ()
+ForeverStack<N>::as_debug_string () const
{
std::stringstream stream;
@@ -737,6 +969,13 @@ ForeverStack<N>::as_debug_string ()
return stream.str ();
}
+template <Namespace N>
+bool
+ForeverStack<N>::is_module_descendant (NodeId parent, NodeId child) const
+{
+ return dfs_node (dfs_node (root, parent).value (), child).has_value ();
+}
+
// FIXME: Can we add selftests?
} // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-ice-finalizer.cc b/gcc/rust/resolve/rust-ice-finalizer.cc
new file mode 100644
index 0000000..bd4763f
--- /dev/null
+++ b/gcc/rust/resolve/rust-ice-finalizer.cc
@@ -0,0 +1,36 @@
+// Copyright (C) 2020-2024 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-ice-finalizer.h"
+
+namespace Rust {
+namespace Resolver {
+
+void ATTRIBUTE_NORETURN
+funny_ice_text_finalizer (diagnostic_text_output_format &text_output,
+ const diagnostic_info *diagnostic,
+ diagnostic_t diag_kind)
+{
+ gcc_assert (diag_kind == DK_ICE_NOBT);
+ default_diagnostic_text_finalizer (text_output, diagnostic, diag_kind);
+ fnotice (stderr, "You have broken GCC Rust. This is a feature.\n");
+ exit (ICE_EXIT_CODE);
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ice-finalizer.h b/gcc/rust/resolve/rust-ice-finalizer.h
new file mode 100644
index 0000000..85ab88f
--- /dev/null
+++ b/gcc/rust/resolve/rust-ice-finalizer.h
@@ -0,0 +1,65 @@
+// Copyright (C) 2020-2024 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_ICE_FINALIZER_H
+#define RUST_ICE_FINALIZER_H
+
+#include "rust-linemap.h"
+#include "diagnostic.h"
+
+namespace Rust {
+namespace Resolver {
+
+/* The "break rust" Easter egg.
+
+ Backstory: once upon a time, there used to be a bug in rustc: it would ICE
+ during typechecking on a 'break' with an expression outside of a loop. The
+ issue has been reported [0] and fixed [1], but in recognition of this, as a
+ special Easter egg, "break rust" was made to intentionally cause an ICE.
+
+ [0]: https://github.com/rust-lang/rust/issues/43162
+ [1]: https://github.com/rust-lang/rust/pull/43745
+
+ This was made in a way that does not break valid programs: namely, it only
+ happens when the 'break' is outside of a loop (so invalid anyway).
+
+ GCC Rust supports this essential feature as well, but in a slightly
+ different way. Instead of delaying the error until type checking, we emit
+ it here in the resolution phase. We, too, only do this to programs that
+ are already invalid: we only emit our funny ICE if the name "rust" (which
+ must be immediately inside a break-with-a-value expression) fails to
+ resolve. Note that "break (rust)" does not trigger our ICE, only using
+ "break rust" directly does, and only if there's no "rust" in scope. We do
+ this in the same way regardless of whether the "break" is outside of a loop
+ or inside one.
+
+ As a GNU extension, we also support "break gcc", much to the same effect,
+ subject to the same rules. */
+
+/* The finalizer for our funny ICE. This prints a custom message instead of
+ the default bug reporting instructions, as there is no bug to report. */
+
+void ATTRIBUTE_NORETURN
+funny_ice_text_finalizer (diagnostic_text_output_format &text_output,
+ const diagnostic_info *diagnostic,
+ diagnostic_t diag_kind);
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif /* ! RUST_ICE_FINALIZER_H */
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 43f33df..6ec0422 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -18,6 +18,7 @@
#include "optional.h"
#include "rust-ast-full.h"
+#include "rust-diagnostics.h"
#include "rust-hir-map.h"
#include "rust-late-name-resolver-2.0.h"
#include "rust-default-resolver.h"
@@ -26,6 +27,8 @@
#include "rust-system.h"
#include "rust-tyty.h"
#include "rust-hir-type-check.h"
+#include "rust-ice-finalizer.h"
+#include "rust-ast.h"
namespace Rust {
namespace Resolver2_0 {
@@ -88,19 +91,21 @@ Late::setup_builtin_types ()
// insert it in the type context...
};
- for (const auto &builtin : builtins)
- {
- // we should be able to use `insert_at_root` or `insert` here, since we're
- // at the root :) hopefully!
- auto ok = ctx.types.insert (builtin.name, builtin.node_id);
- rust_assert (ok);
+ // There's a special Rib for putting prelude items, since prelude items need
+ // to satisfy certain special rules.
+ ctx.scoped (Rib::Kind::Prelude, 0, [this, &ty_ctx] (void) -> void {
+ for (const auto &builtin : builtins)
+ {
+ auto ok = ctx.types.insert (builtin.name, builtin.node_id);
+ rust_assert (ok);
- ctx.mappings.insert_node_to_hir (builtin.node_id, builtin.hir_id);
- ty_ctx.insert_builtin (builtin.hir_id, builtin.node_id, builtin.type);
- }
+ ctx.mappings.insert_node_to_hir (builtin.node_id, builtin.hir_id);
+ ty_ctx.insert_builtin (builtin.hir_id, builtin.node_id, builtin.type);
+ }
+ });
// ...here!
- auto *unit_type = TyTy::TupleType::get_unit_type (next_hir_id ());
+ auto *unit_type = TyTy::TupleType::get_unit_type ();
ty_ctx.insert_builtin (unit_type->get_ref (), next_node_id (), unit_type);
}
@@ -124,10 +129,72 @@ Late::new_label (Identifier name, NodeId id)
}
void
+Late::visit (AST::ForLoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+
+ ctx.bindings.enter (BindingSource::For);
+
+ visit (expr.get_pattern ());
+
+ ctx.bindings.exit ();
+
+ visit (expr.get_iterator_expr ());
+ visit (expr.get_loop_label ());
+ visit (expr.get_loop_block ());
+}
+
+void
+Late::visit (AST::IfLetExpr &expr)
+{
+ visit_outer_attrs (expr);
+
+ ctx.bindings.enter (BindingSource::Let);
+
+ for (auto &pattern : expr.get_patterns ())
+ visit (pattern);
+
+ ctx.bindings.exit ();
+
+ visit (expr.get_value_expr ());
+ visit (expr.get_if_block ());
+}
+
+void
+Late::visit (AST::MatchArm &arm)
+{
+ visit_outer_attrs (arm);
+
+ ctx.bindings.enter (BindingSource::Match);
+
+ for (auto &pattern : arm.get_patterns ())
+ visit (pattern);
+
+ ctx.bindings.exit ();
+
+ if (arm.has_match_arm_guard ())
+ visit (arm.get_guard_expr ());
+}
+
+void
Late::visit (AST::LetStmt &let)
{
- // so we don't need that method
- DefaultResolver::visit (let);
+ DefaultASTVisitor::visit_outer_attrs (let);
+ if (let.has_type ())
+ visit (let.get_type ());
+ // visit expression before pattern
+ // this makes variable shadowing work properly
+ if (let.has_init_expr ())
+ visit (let.get_init_expr ());
+
+ ctx.bindings.enter (BindingSource::Let);
+
+ visit (let.get_pattern ());
+
+ ctx.bindings.exit ();
+
+ if (let.has_else_expr ())
+ visit (let.get_init_expr ());
// how do we deal with the fact that `let a = blipbloup` should look for a
// label and cannot go through function ribs, but `let a = blipbloup()` can?
@@ -153,9 +220,143 @@ Late::visit (AST::IdentifierPattern &identifier)
// 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 ().get_source () == BindingSource::Param)
+ rust_error_at (
+ identifier.get_locus (), ErrorCode::E0415,
+ "identifier %qs is bound more than once in the same parameter list",
+ identifier.as_string ().c_str ());
+ else
+ rust_error_at (
+ identifier.get_locus (), ErrorCode::E0416,
+ "identifier %qs is bound more than once in the same pattern",
+ identifier.as_string ().c_str ());
+ return;
+ }
+
+ ctx.bindings.peek ().insert_ident (identifier.get_ident ());
+
+ if (ctx.bindings.peek ().is_or_bound (identifier.get_ident ()))
+ {
+ // FIXME: map usage instead
+ std::ignore = ctx.values.insert_shadowable (identifier.get_ident (),
+ identifier.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 ());
+ }
+}
+
+void
+Late::visit (AST::AltPattern &pattern)
+{
+ ctx.bindings.peek ().push (Binding::Kind::Or);
+ for (auto &alt : pattern.get_alts ())
+ {
+ ctx.bindings.peek ().push (Binding::Kind::Product);
+ visit (alt);
+ ctx.bindings.peek ().merge ();
+ }
+ ctx.bindings.peek ().merge ();
+}
+
+void
+Late::visit_function_params (AST::Function &function)
+{
+ ctx.bindings.enter (BindingSource::Param);
+
+ for (auto &param : function.get_function_params ())
+ visit (param);
+
+ ctx.bindings.exit ();
+}
+
+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 (identifier.get_ident (),
- identifier.get_node_id ());
+ std::ignore = ctx.values.insert_shadowable (field.get_identifier (),
+ field.get_node_id ());
+}
+
+void
+Late::visit (AST::SelfParam &param)
+{
+ // handle similar to AST::IdentifierPattern
+
+ DefaultResolver::visit (param);
+ // FIXME: this location should be a bit off
+ // ex: would point to the begining of "mut self" instead of the "self"
+ std::ignore = ctx.values.insert (Identifier ("self", param.get_locus ()),
+ param.get_node_id ());
+}
+
+void
+Late::visit (AST::BreakExpr &expr)
+{
+ if (expr.has_label ())
+ resolve_label (expr.get_label_unchecked ().get_lifetime ());
+
+ if (expr.has_break_expr ())
+ {
+ auto &break_expr = expr.get_break_expr ();
+ if (break_expr.get_expr_kind () == AST::Expr::Kind::Identifier)
+ {
+ /* This is a break with an expression, and the expression is
+ just a single identifier. See if the identifier is either
+ "rust" or "gcc", in which case we have "break rust" or "break
+ gcc", and so may need to emit our funny error. We cannot yet
+ emit the error here though, because the identifier may still
+ be in scope, and ICE'ing on valid programs would not be very
+ funny. */
+ std::string ident
+ = static_cast<AST::IdentifierExpr &> (expr.get_break_expr ())
+ .as_string ();
+ if (ident == "rust" || ident == "gcc")
+ funny_error = true;
+ }
+ }
+
+ DefaultResolver::visit (expr);
+
+ funny_error = false;
+}
+
+void
+Late::visit (AST::LoopLabel &label)
+{
+ auto &lifetime = label.get_lifetime ();
+ ctx.labels.insert (Identifier (lifetime.as_string (), lifetime.get_locus ()),
+ lifetime.get_node_id ());
+}
+
+void
+Late::resolve_label (AST::Lifetime &lifetime)
+{
+ if (auto resolved = ctx.labels.get (lifetime.as_string ()))
+ {
+ if (resolved->get_node_id () != lifetime.get_node_id ())
+ ctx.map_usage (Usage (lifetime.get_node_id ()),
+ Definition (resolved->get_node_id ()));
+ }
+ else
+ rust_error_at (lifetime.get_locus (), ErrorCode::E0426,
+ "use of undeclared label %qs",
+ lifetime.as_string ().c_str ());
+}
+
+void
+Late::visit (AST::ContinueExpr &expr)
+{
+ if (expr.has_label ())
+ resolve_label (expr.get_label_unchecked ());
+
+ DefaultResolver::visit (expr);
}
void
@@ -164,7 +365,6 @@ Late::visit (AST::IdentifierExpr &expr)
// TODO: same thing as visit(PathInExpression) here?
tl::optional<Rib::Definition> resolved = tl::nullopt;
-
if (auto value = ctx.values.get (expr.get_ident ()))
{
resolved = value;
@@ -173,49 +373,95 @@ Late::visit (AST::IdentifierExpr &expr)
{
resolved = type;
}
+ else if (funny_error)
+ {
+ diagnostic_text_finalizer (global_dc) = Resolver::funny_ice_text_finalizer;
+ emit_diagnostic (DK_ICE_NOBT, expr.get_locus (), -1,
+ "are you trying to break %s? how dare you?",
+ expr.as_string ().c_str ());
+ }
else
{
- rust_error_at (expr.get_locus (),
- "could not resolve identifier expression: %qs",
- expr.get_ident ().as_string ().c_str ());
+ if (auto type = ctx.types.get_lang_prelude (expr.get_ident ()))
+ {
+ resolved = type;
+ }
+ else
+ {
+ rust_error_at (expr.get_locus (), ErrorCode::E0425,
+ "cannot find value %qs in this scope",
+ expr.get_ident ().as_string ().c_str ());
+ return;
+ }
+ }
+
+ if (resolved->is_ambiguous ())
+ {
+ rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
+ expr.as_string ().c_str ());
return;
}
ctx.map_usage (Usage (expr.get_node_id ()),
Definition (resolved->get_node_id ()));
- // in the old resolver, resolutions are kept in the resolver, not the mappings
- // :/ how do we deal with that?
- // ctx.mappings.insert_resolved_name(expr, resolved);
-
// For empty types, do we perform a lookup in ctx.types or should the
// toplevel instead insert a name in ctx.values? (like it currently does)
}
void
+Late::visit (AST::StructExprFieldIdentifier &expr)
+{
+ tl::optional<Rib::Definition> resolved = tl::nullopt;
+
+ if (auto value = ctx.values.get (expr.get_field_name ()))
+ {
+ resolved = value;
+ }
+ // seems like we don't need a type namespace lookup
+ else
+ {
+ rust_error_at (expr.get_locus (), "could not resolve struct field: %qs",
+ expr.get_field_name ().as_string ().c_str ());
+ return;
+ }
+
+ if (resolved->is_ambiguous ())
+ {
+ rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
+ expr.as_string ().c_str ());
+ return;
+ }
+
+ ctx.map_usage (Usage (expr.get_node_id ()),
+ Definition (resolved->get_node_id ()));
+}
+
+void
Late::visit (AST::PathInExpression &expr)
{
// TODO: How do we have a nice error with `can't capture dynamic environment
// in a function item` error here?
// do we emit it in `get<Namespace::Labels>`?
- rust_debug ("[ARTHUR]: %s", expr.as_simple_path ().as_string ().c_str ());
-
- tl::optional<Rib::Definition> resolved = tl::nullopt;
+ DefaultResolver::visit (expr);
- if (auto value = ctx.values.resolve_path (expr.get_segments ()))
- {
- resolved = value;
- }
- else if (auto type = ctx.types.resolve_path (expr.get_segments ()))
+ if (expr.is_lang_item ())
{
- resolved = type;
+ ctx.map_usage (Usage (expr.get_node_id ()),
+ Definition (Analysis::Mappings::get ().get_lang_item_node (
+ expr.get_lang_item ())));
+ return;
}
- else
+
+ auto resolved = ctx.resolve_path (expr, Namespace::Values, Namespace::Types);
+
+ if (!resolved)
{
- rust_error_at (expr.get_locus (),
- "could not resolve path expression: %qs",
- expr.as_simple_path ().as_string ().c_str ());
+ if (!ctx.lookup (expr.get_segments ().front ().get_node_id ()))
+ rust_error_at (expr.get_locus (), ErrorCode::E0433,
+ "Cannot find path %qs in this scope",
+ expr.as_simple_path ().as_string ().c_str ());
return;
}
@@ -225,6 +471,7 @@ Late::visit (AST::PathInExpression &expr)
expr.as_string ().c_str ());
return;
}
+
ctx.map_usage (Usage (expr.get_node_id ()),
Definition (resolved->get_node_id ()));
}
@@ -237,14 +484,50 @@ Late::visit (AST::TypePath &type)
// maybe we can overload `resolve_path<Namespace::Types>` to only do
// typepath-like path resolution? that sounds good
- auto str = type.get_segments ().back ()->get_ident_segment ().as_string ();
- auto values = ctx.types.peek ().get_values ();
+ DefaultResolver::visit (type);
- if (auto resolved = ctx.types.get (str))
- ctx.map_usage (Usage (type.get_node_id ()),
- Definition (resolved->get_node_id ()));
- else
- rust_unreachable ();
+ // this *should* mostly work
+ // TODO: make sure typepath-like path resolution (?) is working
+ auto resolved = ctx.resolve_path (type, Namespace::Types);
+
+ 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 ());
+ return;
+ }
+
+ if (resolved->is_ambiguous ())
+ {
+ rust_error_at (type.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
+ type.as_string ().c_str ());
+ return;
+ }
+
+ if (ctx.types.forward_declared (resolved->get_node_id (),
+ type.get_node_id ()))
+ {
+ rust_error_at (type.get_locus (), ErrorCode::E0128,
+ "type parameters with a default cannot use forward "
+ "declared identifiers");
+ }
+
+ ctx.map_usage (Usage (type.get_node_id ()),
+ Definition (resolved->get_node_id ()));
+}
+
+void
+Late::visit (AST::Trait &trait)
+{
+ // kind of weird how this is done
+ // names are resolved to the node id of trait.get_implicit_self ()
+ // which is then resolved to the node id of trait
+ // we set up the latter mapping here
+ ctx.map_usage (Usage (trait.get_implicit_self ().get_node_id ()),
+ Definition (trait.get_node_id ()));
+
+ DefaultResolver::visit (trait);
}
void
@@ -255,24 +538,47 @@ Late::visit (AST::StructStruct &s)
}
void
+Late::visit (AST::StructExprStruct &s)
+{
+ visit_outer_attrs (s);
+ visit_inner_attrs (s);
+ DefaultResolver::visit (s.get_struct_name ());
+
+ auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
+
+ ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
+ Definition (resolved->get_node_id ()));
+}
+
+void
Late::visit (AST::StructExprStructBase &s)
{
- auto resolved = ctx.types.get (s.get_struct_name ().as_string ());
+ visit_outer_attrs (s);
+ visit_inner_attrs (s);
+ DefaultResolver::visit (s.get_struct_name ());
+ visit (s.get_struct_base ());
+
+ auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
Definition (resolved->get_node_id ()));
- DefaultResolver::visit (s);
}
void
Late::visit (AST::StructExprStructFields &s)
{
- auto resolved = ctx.types.get (s.get_struct_name ().as_string ());
+ visit_outer_attrs (s);
+ visit_inner_attrs (s);
+ DefaultResolver::visit (s.get_struct_name ());
+ if (s.has_struct_base ())
+ visit (s.get_struct_base ());
+ for (auto &field : s.get_fields ())
+ visit (field);
+
+ auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
Definition (resolved->get_node_id ()));
-
- DefaultResolver::visit (s);
}
// needed because Late::visit (AST::GenericArg &) is non-virtual
@@ -307,5 +613,52 @@ 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)
+{
+ add_captures (closure, ctx);
+
+ visit_outer_attrs (closure);
+
+ ctx.bindings.enter (BindingSource::Param);
+
+ for (auto &param : closure.get_params ())
+ visit (param);
+
+ ctx.bindings.exit ();
+
+ visit (closure.get_definition_expr ());
+}
+
+void
+Late::visit (AST::ClosureExprInnerTyped &closure)
+{
+ add_captures (closure, ctx);
+
+ visit_outer_attrs (closure);
+
+ ctx.bindings.enter (BindingSource::Param);
+
+ for (auto &param : closure.get_params ())
+ visit (param);
+
+ ctx.bindings.exit ();
+
+ visit (closure.get_return_type ());
+ visit (closure.get_definition_block ());
+}
+
} // namespace Resolver2_0
} // namespace Rust
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 7e33c96..171d9bf 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -21,6 +21,7 @@
#include "rust-ast-full.h"
#include "rust-default-resolver.h"
+#include "rust-expr.h"
namespace Rust {
namespace Resolver2_0 {
@@ -36,25 +37,46 @@ public:
void new_label (Identifier name, NodeId id);
+ // Specialized visit bits
+ void visit_function_params (AST::Function &function) override;
+
// some more label declarations
void visit (AST::LetStmt &) override;
// TODO: Do we need this?
// void visit (AST::Method &) override;
void visit (AST::IdentifierPattern &) override;
+ void visit (AST::StructPatternFieldIdent &) override;
+ void visit (AST::AltPattern &) override;
+ void visit (AST::SelfParam &) override;
+ void visit (AST::MatchArm &) override;
+ void visit (AST::ForLoopExpr &) override;
+ void visit (AST::IfLetExpr &) override;
// resolutions
void visit (AST::IdentifierExpr &) override;
+ void visit (AST::StructExprFieldIdentifier &) override;
+ void visit (AST::BreakExpr &) override;
+ void visit (AST::ContinueExpr &) override;
+ void visit (AST::LoopLabel &) override;
void visit (AST::PathInExpression &) override;
void visit (AST::TypePath &) override;
+ void visit (AST::Trait &) override;
+ void visit (AST::StructExprStruct &) override;
void visit (AST::StructExprStructBase &) override;
void visit (AST::StructExprStructFields &) override;
void visit (AST::StructStruct &) override;
void visit (AST::GenericArgs &) override;
void visit (AST::GenericArg &);
+ void visit (AST::ClosureExprInner &) override;
+ void visit (AST::ClosureExprInnerTyped &) override;
private:
+ void resolve_label (AST::Lifetime &lifetime);
+
/* Setup Rust's builtin types (u8, i32, !...) in the resolver */
void setup_builtin_types ();
+
+ bool funny_error;
};
// 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 9bfaa09..f098e48 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -23,6 +23,65 @@
namespace Rust {
namespace Resolver2_0 {
+BindingLayer::BindingLayer (BindingSource source) : source (source)
+{
+ push (Binding::Kind::Product);
+}
+
+bool
+BindingLayer::bind_test (Identifier ident, Binding::Kind kind)
+{
+ for (auto &bind : bindings)
+ {
+ if (bind.set.find (ident) != bind.set.cend () && bind.kind == kind)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+BindingLayer::push (Binding::Kind kind)
+{
+ bindings.push_back (Binding (kind));
+}
+
+bool
+BindingLayer::is_and_bound (Identifier ident)
+{
+ return bind_test (ident, Binding::Kind::Product);
+}
+
+bool
+BindingLayer::is_or_bound (Identifier ident)
+{
+ return bind_test (ident, Binding::Kind::Or);
+}
+
+void
+BindingLayer::insert_ident (Identifier ident)
+{
+ bindings.back ().set.insert (ident);
+}
+
+void
+BindingLayer::merge ()
+{
+ auto last_binding = bindings.back ();
+ bindings.pop_back ();
+ for (auto &value : last_binding.set)
+ {
+ bindings.back ().set.insert (value);
+ }
+}
+
+BindingSource
+BindingLayer::get_source () const
+{
+ return source;
+}
+
NameResolutionContext::NameResolutionContext ()
: mappings (Analysis::Mappings::get ())
{}
@@ -46,6 +105,12 @@ NameResolutionContext::insert (Identifier name, NodeId id, Namespace ns)
}
tl::expected<NodeId, DuplicateNameError>
+NameResolutionContext::insert_variant (Identifier name, NodeId id)
+{
+ return types.insert_variant (name, id);
+}
+
+tl::expected<NodeId, DuplicateNameError>
NameResolutionContext::insert_shadowable (Identifier name, NodeId id,
Namespace ns)
{
@@ -103,13 +168,14 @@ NameResolutionContext::lookup (NodeId usage) const
}
void
-NameResolutionContext::scoped (Rib rib, NodeId id,
+NameResolutionContext::scoped (Rib::Kind rib_kind, NodeId id,
std::function<void (void)> lambda,
tl::optional<Identifier> path)
{
- values.push (rib, id, path);
- types.push (rib, id, path);
- macros.push (rib, id, path);
+ // NOTE: You must be at the root node when pushing the prelude rib.
+ values.push (rib_kind, id, path);
+ types.push (rib_kind, id, path);
+ macros.push (rib_kind, id, path);
// labels.push (rib, id);
lambda ();
@@ -121,17 +187,21 @@ NameResolutionContext::scoped (Rib rib, NodeId id,
}
void
-NameResolutionContext::scoped (Rib rib, Namespace ns, NodeId scope_id,
+NameResolutionContext::scoped (Rib::Kind rib_kind, Namespace ns,
+ NodeId scope_id,
std::function<void (void)> lambda,
tl::optional<Identifier> path)
{
+ // This could work... I'm not sure why you would want to do this though.
+ rust_assert (rib_kind != Rib::Kind::Prelude);
+
switch (ns)
{
case Namespace::Values:
- values.push (rib, scope_id, path);
+ values.push (rib_kind, scope_id, path);
break;
case Namespace::Types:
- types.push (rib, scope_id, path);
+ types.push (rib_kind, scope_id, path);
break;
case Namespace::Labels:
case Namespace::Macros:
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h
index cd6fa93..19ba750 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -23,6 +23,7 @@
#include "rust-forever-stack.h"
#include "rust-hir-map.h"
#include "rust-rib.h"
+#include "rust-stacked-contexts.h"
namespace Rust {
namespace Resolver2_0 {
@@ -156,6 +157,62 @@ public:
NodeId id;
};
+struct Binding
+{
+ enum class Kind
+ {
+ Product,
+ Or,
+ } kind;
+
+ std::unordered_set<Identifier> set;
+
+ Binding (Binding::Kind kind) : kind (kind) {}
+};
+
+/**
+ * Used to identify the source of a binding, and emit the correct error message.
+ */
+enum class BindingSource
+{
+ Match,
+ Let,
+ For,
+ /* Closure param or function param */
+ Param
+};
+
+class BindingLayer
+{
+ BindingSource source;
+ std::vector<Binding> bindings;
+
+ bool bind_test (Identifier ident, Binding::Kind kind);
+
+public:
+ void push (Binding::Kind kind);
+
+ BindingLayer (BindingSource source);
+
+ /**
+ * Identifies if the identifier has been used in a product binding context.
+ * eg. `let (a, a) = test();`
+ */
+ bool is_and_bound (Identifier ident);
+
+ /**
+ * Identifies if the identifier has been used in a or context.
+ * eg. `let (a, 1) | (a, 2) = test()`
+ */
+ bool is_or_bound (Identifier ident);
+
+ void insert_ident (Identifier ident);
+
+ void merge ();
+
+ BindingSource get_source () const;
+};
+
// Now our resolver, which keeps track of all the `ForeverStack`s we could want
class NameResolutionContext
{
@@ -172,6 +229,9 @@ public:
tl::expected<NodeId, DuplicateNameError> insert (Identifier name, NodeId id,
Namespace ns);
+ tl::expected<NodeId, DuplicateNameError> insert_variant (Identifier name,
+ NodeId id);
+
tl::expected<NodeId, DuplicateNameError>
insert_shadowable (Identifier name, NodeId id, Namespace ns);
@@ -185,8 +245,8 @@ public:
* function. This variant of the function enters a new scope in *all*
* namespaces, while the second variant enters a scope in *one* namespace.
*
- * @param rib New `Rib` to create when entering this scope. A function `Rib`,
- * or an item `Rib`... etc
+ * @param rib_kind New `Rib` to create when entering this scope. A function
+ * `Rib`, or an item `Rib`... etc
* @param scope_id node ID of the scope we are entering, e.g the block's
* `NodeId`.
* @param lambda Function to run within that scope
@@ -196,9 +256,10 @@ public:
*/
// FIXME: Do we want to handle something in particular for expected within the
// scoped lambda?
- void scoped (Rib rib, NodeId scope_id, std::function<void (void)> lambda,
+ void scoped (Rib::Kind rib_kind, NodeId scope_id,
+ std::function<void (void)> lambda,
tl::optional<Identifier> path = {});
- void scoped (Rib rib, Namespace ns, NodeId scope_id,
+ void scoped (Rib::Kind rib_kind, Namespace ns, NodeId scope_id,
std::function<void (void)> lambda,
tl::optional<Identifier> path = {});
@@ -208,6 +269,7 @@ public:
ForeverStack<Namespace::Labels> labels;
Analysis::Mappings &mappings;
+ StackedContexts<BindingLayer> bindings;
// TODO: Rename
// TODO: Use newtype pattern for Usage and Definition
@@ -215,6 +277,120 @@ public:
tl::optional<NodeId> lookup (NodeId usage) const;
+ template <typename S>
+ tl::optional<Rib::Definition>
+ resolve_path (const std::vector<S> &segments,
+ bool has_opening_scope_resolution,
+ std::vector<Error> &collect_errors, Namespace ns)
+ {
+ std::function<void (const S &, NodeId)> insert_segment_resolution
+ = [this] (const S &seg, NodeId id) {
+ auto seg_id = unwrap_segment_node_id (seg);
+ if (resolved_nodes.find (Usage (seg_id)) == resolved_nodes.end ())
+ map_usage (Usage (seg_id), Definition (id));
+ };
+ switch (ns)
+ {
+ case Namespace::Values:
+ return values.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution, collect_errors);
+ case Namespace::Types:
+ return types.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution, collect_errors);
+ case Namespace::Macros:
+ return macros.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution, collect_errors);
+ case Namespace::Labels:
+ return labels.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution, collect_errors);
+ default:
+ rust_unreachable ();
+ }
+ }
+
+ template <typename S, typename... Args>
+ tl::optional<Rib::Definition>
+ resolve_path (const std::vector<S> &segments,
+ bool has_opening_scope_resolution,
+ tl::optional<std::vector<Error> &> collect_errors,
+ Namespace ns_first, Args... ns_args)
+ {
+ std::initializer_list<Namespace> namespaces = {ns_first, ns_args...};
+
+ for (auto ns : namespaces)
+ {
+ std::vector<Error> collect_errors_inner;
+ if (auto ret = resolve_path (segments, has_opening_scope_resolution,
+ collect_errors_inner, ns))
+ return ret;
+ if (!collect_errors_inner.empty ())
+ {
+ if (collect_errors.has_value ())
+ {
+ std::move (collect_errors_inner.begin (),
+ collect_errors_inner.end (),
+ std::back_inserter (collect_errors.value ()));
+ }
+ else
+ {
+ for (auto &e : collect_errors_inner)
+ e.emit ();
+ }
+ return tl::nullopt;
+ }
+ }
+
+ return tl::nullopt;
+ }
+
+ template <typename... Args>
+ tl::optional<Rib::Definition>
+ resolve_path (const AST::SimplePath &path,
+ 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...);
+ }
+
+ template <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)
+ {
+ return resolve_path (path.get_segments (), path.opening_scope_resolution (),
+ collect_errors, ns_first, ns_args...);
+ }
+
+ template <typename... Args>
+ tl::optional<Rib::Definition>
+ resolve_path (const AST::TypePath &path,
+ tl::optional<std::vector<Error> &> collect_errors,
+ Namespace ns_first, Args... ns_args)
+ {
+ return resolve_path (path.get_segments (),
+ path.has_opening_scope_resolution_op (),
+ collect_errors, ns_first, ns_args...);
+ }
+
+ template <typename P, typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const P &path, Namespace ns_first,
+ Args... ns_args)
+ {
+ return resolve_path (path, tl::nullopt, ns_first, ns_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)
+ {
+ return resolve_path (path_segments, has_opening_scope_resolution,
+ tl::nullopt, ns_first, ns_args...);
+ }
+
private:
/* Map of "usage" nodes which have been resolved to a "definition" node */
std::map<Usage, Definition> resolved_nodes;
diff --git a/gcc/rust/resolve/rust-name-resolver.cc b/gcc/rust/resolve/rust-name-resolver.cc
index 21147bd8..dddaa07 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -19,6 +19,9 @@
#include "rust-name-resolver.h"
#include "rust-ast-full.h"
+// for flag_name_resolution_2_0
+#include "options.h"
+
namespace Rust {
namespace Resolver {
@@ -435,8 +438,7 @@ Resolver::generate_builtins ()
set_never_type_node_id (never_node_id);
// unit type ()
- TyTy::TupleType *unit_tyty
- = TyTy::TupleType::get_unit_type (mappings.get_next_hir_id ());
+ TyTy::TupleType *unit_tyty = TyTy::TupleType::get_unit_type ();
std::vector<std::unique_ptr<AST::Type> > elems;
AST::TupleType *unit_type
= new AST::TupleType (std::move (elems), BUILTINS_LOCATION);
@@ -469,6 +471,9 @@ Resolver::setup_builtin (const std::string &name, TyTy::BaseType *tyty)
void
Resolver::insert_resolved_name (NodeId refId, NodeId defId)
{
+ rust_assert (!flag_name_resolution_2_0);
+ rust_assert (resolved_names.find (refId) == resolved_names.end ());
+
resolved_names[refId] = defId;
get_name_scope ().append_reference_for_def (refId, defId);
insert_captured_item (defId);
@@ -477,6 +482,7 @@ Resolver::insert_resolved_name (NodeId refId, NodeId defId)
bool
Resolver::lookup_resolved_name (NodeId refId, NodeId *defId)
{
+ rust_assert (!flag_name_resolution_2_0);
auto it = resolved_names.find (refId);
if (it == resolved_names.end ())
return false;
@@ -488,8 +494,8 @@ Resolver::lookup_resolved_name (NodeId refId, NodeId *defId)
void
Resolver::insert_resolved_type (NodeId refId, NodeId defId)
{
- // auto it = resolved_types.find (refId);
- // rust_assert (it == resolved_types.end ());
+ rust_assert (!flag_name_resolution_2_0);
+ rust_assert (resolved_types.find (refId) == resolved_types.end ());
resolved_types[refId] = defId;
get_type_scope ().append_reference_for_def (refId, defId);
@@ -498,6 +504,7 @@ Resolver::insert_resolved_type (NodeId refId, NodeId defId)
bool
Resolver::lookup_resolved_type (NodeId refId, NodeId *defId)
{
+ rust_assert (!flag_name_resolution_2_0);
auto it = resolved_types.find (refId);
if (it == resolved_types.end ())
return false;
@@ -509,6 +516,7 @@ Resolver::lookup_resolved_type (NodeId refId, NodeId *defId)
void
Resolver::insert_resolved_label (NodeId refId, NodeId defId)
{
+ rust_assert (!flag_name_resolution_2_0);
auto it = resolved_labels.find (refId);
rust_assert (it == resolved_labels.end ());
@@ -519,6 +527,7 @@ Resolver::insert_resolved_label (NodeId refId, NodeId defId)
bool
Resolver::lookup_resolved_label (NodeId refId, NodeId *defId)
{
+ rust_assert (!flag_name_resolution_2_0);
auto it = resolved_labels.find (refId);
if (it == resolved_labels.end ())
return false;
@@ -530,6 +539,7 @@ Resolver::lookup_resolved_label (NodeId refId, NodeId *defId)
void
Resolver::insert_resolved_macro (NodeId refId, NodeId defId)
{
+ rust_assert (!flag_name_resolution_2_0);
auto it = resolved_macros.find (refId);
rust_assert (it == resolved_macros.end ());
@@ -540,6 +550,7 @@ Resolver::insert_resolved_macro (NodeId refId, NodeId defId)
bool
Resolver::lookup_resolved_macro (NodeId refId, NodeId *defId)
{
+ rust_assert (!flag_name_resolution_2_0);
auto it = resolved_macros.find (refId);
if (it == resolved_macros.end ())
return false;
@@ -551,6 +562,7 @@ Resolver::lookup_resolved_macro (NodeId refId, NodeId *defId)
void
Resolver::insert_resolved_misc (NodeId refId, NodeId defId)
{
+ rust_assert (!flag_name_resolution_2_0);
auto it = misc_resolved_items.find (refId);
rust_assert (it == misc_resolved_items.end ());
@@ -560,6 +572,7 @@ Resolver::insert_resolved_misc (NodeId refId, NodeId defId)
bool
Resolver::lookup_resolved_misc (NodeId refId, NodeId *defId)
{
+ rust_assert (!flag_name_resolution_2_0);
auto it = misc_resolved_items.find (refId);
if (it == misc_resolved_items.end ())
return false;
@@ -662,6 +675,8 @@ Resolver::decl_needs_capture (NodeId decl_rib_node_id,
const std::set<NodeId> &
Resolver::get_captures (NodeId id) const
{
+ rust_assert (!flag_name_resolution_2_0);
+
auto it = closures_capture_mappings.find (id);
rust_assert (it != closures_capture_mappings.end ());
return it->second;
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 43b79e5..a3b34a9 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -204,6 +204,41 @@ public:
void insert_captured_item (NodeId id);
const std::set<NodeId> &get_captures (NodeId id) const;
+ std::string as_debug_string () const
+ {
+ std::stringstream ss;
+
+ ss << "Names:\n";
+ for (auto &n : name_ribs)
+ {
+ ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
+ << "\n";
+ }
+ ss << "Types:\n";
+ for (auto &n : type_ribs)
+ {
+ ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
+ << "\n";
+ }
+ ss << "Macros:\n";
+
+ for (auto &n : macro_ribs)
+ {
+ ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
+ << "\n";
+ }
+
+ ss << "Labels:\n";
+
+ for (auto &n : label_ribs)
+ {
+ ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
+ << "\n";
+ }
+
+ return ss.str ();
+ }
+
protected:
bool decl_needs_capture (NodeId decl_rib_node_id, NodeId closure_rib_node_id,
const Scope &scope);
diff --git a/gcc/rust/resolve/rust-rib.cc b/gcc/rust/resolve/rust-rib.cc
index b0380bb..690bde9 100644
--- a/gcc/rust/resolve/rust-rib.cc
+++ b/gcc/rust/resolve/rust-rib.cc
@@ -22,7 +22,8 @@
namespace Rust {
namespace Resolver2_0 {
-Rib::Definition::Definition (NodeId id, Mode mode)
+Rib::Definition::Definition (NodeId id, Mode mode, bool enum_variant)
+ : enum_variant (enum_variant)
{
switch (mode)
{
@@ -51,6 +52,12 @@ Rib::Definition::is_ambiguous () const
return ids_globbed.size () > 1;
}
+bool
+Rib::Definition::is_variant () const
+{
+ return enum_variant;
+}
+
std::string
Rib::Definition::to_string () const
{
@@ -69,25 +76,27 @@ Rib::Definition::to_string () const
}
}
out << "]";
+ if (enum_variant)
+ out << "(enum variant)";
return out.str ();
}
Rib::Definition
Rib::Definition::Shadowable (NodeId id)
{
- return Definition (id, Mode::SHADOWABLE);
+ return Definition (id, Mode::SHADOWABLE, false);
}
Rib::Definition
-Rib::Definition::NonShadowable (NodeId id)
+Rib::Definition::NonShadowable (NodeId id, bool enum_variant)
{
- return Definition (id, Mode::NON_SHADOWABLE);
+ return Definition (id, Mode::NON_SHADOWABLE, enum_variant);
}
Rib::Definition
Rib::Definition::Globbed (NodeId id)
{
- return Definition (id, Mode::GLOBBED);
+ return Definition (id, Mode::GLOBBED, false);
}
DuplicateNameError::DuplicateNameError (std::string name, NodeId existing)
diff --git a/gcc/rust/resolve/rust-rib.h b/gcc/rust/resolve/rust-rib.h
index 2eb8de8..c498328 100644
--- a/gcc/rust/resolve/rust-rib.h
+++ b/gcc/rust/resolve/rust-rib.h
@@ -111,7 +111,7 @@ public:
class Definition
{
public:
- static Definition NonShadowable (NodeId id);
+ static Definition NonShadowable (NodeId id, bool enum_variant = false);
static Definition Shadowable (NodeId id);
static Definition Globbed (NodeId id);
@@ -124,11 +124,21 @@ public:
std::vector<NodeId> ids_non_shadowable;
std::vector<NodeId> ids_globbed;
+ // Enum variant should be skipped when dealing with inner definition.
+ // struct E2;
+ //
+ // enum MyEnum<T> /* <-- Should be kept */{
+ // E2 /* <-- Should be skipped */ (E2);
+ // }
+ bool enum_variant;
+
Definition () = default;
Definition &operator= (const Definition &) = default;
Definition (Definition const &) = default;
+ bool is_variant () const;
+
bool is_ambiguous () const;
NodeId get_node_id () const
@@ -155,7 +165,7 @@ public:
GLOBBED
};
- Definition (NodeId id, Mode mode);
+ Definition (NodeId id, Mode mode, bool enum_variant);
};
enum class Kind
@@ -173,8 +183,42 @@ public:
ForwardTypeParamBan,
/* Const generic, as in the following example: fn foo<T, const X: T>() {} */
ConstParamType,
+ /* Prelude rib, used for both the language prelude (i32,usize,etc) and the
+ * (future) {std,core}::prelude::* import. A regular rib with the
+ * restriction that you cannot `use` items from the Prelude
+ */
+ Prelude,
} kind;
+ static std::string kind_to_string (Rib::Kind kind)
+ {
+ switch (kind)
+ {
+ case Rib::Kind::Normal:
+ return "Normal";
+ case Rib::Kind::Module:
+ return "Module";
+ case Rib::Kind::Function:
+ return "Function";
+ case Rib::Kind::ConstantItem:
+ return "ConstantItem";
+ case Rib::Kind::TraitOrImpl:
+ return "TraitOrImpl";
+ case Rib::Kind::Item:
+ return "Item";
+ case Rib::Kind::Closure:
+ return "Closure";
+ case Rib::Kind::MacroDefinition:
+ return "Macro definition";
+ case Rib::Kind::ForwardTypeParamBan:
+ return "Forward type param ban";
+ case Rib::Kind::ConstParamType:
+ return "Const Param Type";
+ default:
+ rust_unreachable ();
+ }
+ }
+
Rib (Kind kind);
Rib (Kind kind, std::string identifier, NodeId id);
Rib (Kind kind, std::unordered_map<std::string, NodeId> values);
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 a0d8492..2f036fe 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -32,21 +32,18 @@ TopLevel::TopLevel (NameResolutionContext &resolver)
template <typename T>
void
-TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
- Namespace ns)
+TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
+ const T &node)
{
- insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns);
+ insert_enum_variant_or_error_out (identifier, node.get_locus (),
+ node.get_node_id ());
}
void
-TopLevel::insert_or_error_out (const Identifier &identifier,
- const location_t &locus, const NodeId &node_id,
- Namespace ns)
+TopLevel::check_multiple_insertion_error (
+ tl::expected<NodeId, DuplicateNameError> result, const Identifier &identifier,
+ const location_t &locus, const NodeId node_id)
{
- // keep track of each node's location to provide useful errors
- node_locations.emplace (node_id, locus);
-
- auto result = ctx.insert (identifier, node_id, ns);
if (result)
dirty = true;
else if (result.error ().existing != node_id)
@@ -58,6 +55,37 @@ TopLevel::insert_or_error_out (const Identifier &identifier,
identifier.as_string ().c_str ());
}
}
+void
+TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
+ const location_t &locus,
+ const NodeId node_id)
+{
+ // keep track of each node's location to provide useful errors
+ node_locations.emplace (node_id, locus);
+
+ auto result = ctx.insert_variant (identifier, node_id);
+ check_multiple_insertion_error (result, identifier, locus, node_id);
+}
+
+template <typename T>
+void
+TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
+ Namespace ns)
+{
+ insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns);
+}
+
+void
+TopLevel::insert_or_error_out (const Identifier &identifier,
+ const location_t &locus, const NodeId &node_id,
+ Namespace ns)
+{
+ // keep track of each node's location to provide useful errors
+ node_locations.emplace (node_id, locus);
+
+ auto result = ctx.insert (identifier, node_id, ns);
+ check_multiple_insertion_error (result, identifier, locus, node_id);
+}
void
TopLevel::go (AST::Crate &crate)
@@ -85,15 +113,19 @@ TopLevel::visit (AST::Module &module)
// This was copied from the old early resolver method
// 'accumulate_escaped_macros'
if (module.get_kind () == AST::Module::UNLOADED)
- module.load_items ();
+ {
+ module.load_items ();
- auto sub_visitor = [this, &module] () {
- for (auto &item : module.get_items ())
- item->accept_vis (*this);
- };
+ // If the module was previously unloaded, then we don't want to visit it
+ // this time around as the CfgStrip hasn't run on its inner items yet.
+ // Skip it for now, mark the visitor as dirty and try again
+
+ dirty = true;
- ctx.scoped (Rib::Kind::Module, module.get_node_id (), sub_visitor,
- module.get_name ());
+ return;
+ }
+
+ DefaultResolver::visit (module);
if (Analysis::Mappings::get ().lookup_ast_module (module.get_node_id ())
== tl::nullopt)
@@ -103,26 +135,50 @@ TopLevel::visit (AST::Module &module)
void
TopLevel::visit (AST::Trait &trait)
{
- // FIXME: This Self injection is dodgy. It even lead to issues with metadata
- // export in the past (#2349). We cannot tell appart injected parameters from
- // regular ones. Dumping generic parameters highlights this Self in metadata,
- // during debug or proc macro collection. This is clearly a hack.
- //
- // For now I'll keep it here in the new name resolver even if it should
- // probably not be there. We need to find another way to solve this.
- // Maybe an additional attribute to Trait ?
- //
- // From old resolver:
- //// we need to inject an implicit self TypeParam here
- //// FIXME: which location should be used for Rust::Identifier `Self`?
- AST::TypeParam *implicit_self
- = new AST::TypeParam ({"Self"}, trait.get_locus ());
- trait.insert_implict_self (
- std::unique_ptr<AST::GenericParam> (implicit_self));
+ insert_or_error_out (trait.get_identifier (), trait, Namespace::Types);
DefaultResolver::visit (trait);
}
+void
+TopLevel::visit (AST::InherentImpl &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);
+}
+
+void
+TopLevel::visit (AST::TraitItemType &trait_item)
+{
+ insert_or_error_out (trait_item.get_identifier ().as_string (), trait_item,
+ Namespace::Types);
+
+ DefaultResolver::visit (trait_item);
+}
+
template <typename PROC_MACRO>
static void
insert_macros (std::vector<PROC_MACRO> &macros, NameResolutionContext &ctx)
@@ -144,7 +200,16 @@ void
TopLevel::visit (AST::ExternCrate &crate)
{
auto &mappings = Analysis::Mappings::get ();
- CrateNum num = *mappings.lookup_crate_name (crate.get_referenced_crate ());
+ auto num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
+
+ if (!num_opt)
+ {
+ rust_error_at (crate.get_locus (), "unknown crate %qs",
+ crate.get_referenced_crate ().c_str ());
+ return;
+ }
+
+ CrateNum num = *num_opt;
auto attribute_macros = mappings.lookup_attribute_proc_macros (num);
@@ -236,32 +301,12 @@ TopLevel::visit (AST::Function &function)
}
void
-TopLevel::visit (AST::BlockExpr &expr)
-{
- // extracting the lambda from the `scoped` call otherwise the code looks like
- // a hot turd thanks to our .clang-format
-
- auto sub_vis = [this, &expr] () {
- for (auto &stmt : expr.get_statements ())
- stmt->accept_vis (*this);
-
- if (expr.has_tail_expr ())
- expr.get_tail_expr ().accept_vis (*this);
- };
-
- ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), sub_vis);
-}
-
-void
TopLevel::visit (AST::StaticItem &static_item)
{
- auto sub_vis
- = [this, &static_item] () { static_item.get_expr ().accept_vis (*this); };
-
- ctx.scoped (Rib::Kind::Item, static_item.get_node_id (), sub_vis);
-
- insert_or_error_out (static_item.get_identifier ().as_string (), static_item,
+ insert_or_error_out (static_item.get_identifier (), static_item,
Namespace::Values);
+
+ DefaultResolver::visit (static_item);
}
void
@@ -269,6 +314,8 @@ TopLevel::visit (AST::ExternalStaticItem &static_item)
{
insert_or_error_out (static_item.get_identifier ().as_string (), static_item,
Namespace::Values);
+
+ DefaultResolver::visit (static_item);
}
void
@@ -297,11 +344,10 @@ TopLevel::visit (AST::StructStruct &struct_item)
void
TopLevel::visit (AST::TypeParam &type_param)
{
- // Hacky and weird, find a better solution
- // We should probably not even insert self in the first place ?
- if (type_param.get_type_representation ().as_string () != "Self")
- insert_or_error_out (type_param.get_type_representation (), type_param,
- Namespace::Types);
+ insert_or_error_out (type_param.get_type_representation (), type_param,
+ Namespace::Types);
+
+ DefaultResolver::visit (type_param);
}
void
@@ -320,24 +366,26 @@ TopLevel::visit (AST::TupleStruct &tuple_struct)
insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
Namespace::Values);
+
+ DefaultResolver::visit (tuple_struct);
}
void
TopLevel::visit (AST::EnumItem &variant)
{
- insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+ insert_enum_variant_or_error_out (variant.get_identifier (), variant);
}
void
TopLevel::visit (AST::EnumItemTuple &variant)
{
- insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+ insert_enum_variant_or_error_out (variant.get_identifier (), variant);
}
void
TopLevel::visit (AST::EnumItemStruct &variant)
{
- insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+ insert_enum_variant_or_error_out (variant.get_identifier (), variant);
}
void
@@ -352,13 +400,7 @@ TopLevel::visit (AST::Enum &enum_item)
insert_or_error_out (enum_item.get_identifier (), enum_item,
Namespace::Types);
- auto field_vis = [this, &enum_item] () {
- for (auto &variant : enum_item.get_variants ())
- variant->accept_vis (*this);
- };
-
- ctx.scoped (Rib::Kind::Item /* FIXME: Is that correct? */,
- enum_item.get_node_id (), field_vis, enum_item.get_identifier ());
+ DefaultResolver::visit (enum_item);
}
void
@@ -366,6 +408,8 @@ TopLevel::visit (AST::Union &union_item)
{
insert_or_error_out (union_item.get_identifier (), union_item,
Namespace::Types);
+
+ DefaultResolver::visit (union_item);
}
void
@@ -503,6 +547,8 @@ flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths,
{
if (glob.has_path ())
paths.emplace_back (glob.get_path ());
+ else
+ paths.emplace_back (AST::SimplePath ({}, false, glob.get_locus ()));
}
void
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 7f4e295..3ff37ed 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -108,15 +108,19 @@ public:
{}
};
- std::unordered_map<NodeId, std::vector<ImportKind>> &&
- get_imports_to_resolve ()
+ std::unordered_map<NodeId, std::vector<ImportKind>> &get_imports_to_resolve ()
{
- return std::move (imports_to_resolve);
+ return imports_to_resolve;
}
+ void check_multiple_insertion_error (
+ tl::expected<NodeId, DuplicateNameError> result,
+ const Identifier &identifier, const location_t &locus,
+ const NodeId node_id);
+
/**
- * Insert a new definition or error out if a definition with the same name was
- * already present in the same namespace in the same scope.
+ * Insert a new definition or error out if a definition with the same name
+ * was already present in the same namespace in the same scope.
*
* @param identifier The identifier of the definition to add.
* @param node A reference to the node, so we can get its `NodeId` and
@@ -130,6 +134,14 @@ public:
const location_t &locus, const NodeId &id,
Namespace ns);
+ template <typename T>
+ void insert_enum_variant_or_error_out (const Identifier &identifier,
+ const T &node);
+
+ void insert_enum_variant_or_error_out (const Identifier &identifier,
+ const location_t &locus,
+ const NodeId node_id);
+
private:
// If a new export has been defined whilst visiting the visitor is considered
// dirty
@@ -148,9 +160,11 @@ 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 visit (AST::TraitItemType &trait_item) override;
void visit (AST::MacroRulesDefinition &macro) override;
void visit (AST::Function &function) override;
- void visit (AST::BlockExpr &expr) override;
void visit (AST::StaticItem &static_item) override;
void visit (AST::ExternalStaticItem &static_item) override;
void visit (AST::StructStruct &struct_item) override;
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 9d28cf6..414799e 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -133,11 +133,11 @@ function_ptr_type (tree result, const std::vector<tree> &praameters,
// Get a struct type.
tree
-struct_type (const std::vector<typed_identifier> &fields);
+struct_type (const std::vector<typed_identifier> &fields, bool layout = true);
// Get a union type.
tree
-union_type (const std::vector<typed_identifier> &fields);
+union_type (const std::vector<typed_identifier> &fields, bool layout = true);
// Get an array type.
tree
@@ -496,7 +496,7 @@ write_global_definitions (const std::vector<tree> &type_decls,
// TODO: make static
tree
-fill_in_fields (tree, const std::vector<typed_identifier> &);
+fill_in_fields (tree, const std::vector<typed_identifier> &, bool);
tree fill_in_array (tree, tree, tree);
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 273ab78..e5319d3 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -61,7 +61,7 @@
tree
Bvariable::get_tree (location_t location) const
{
- if (this->t_ == error_mark_node)
+ if (error_operand_p (this->t_))
return error_mark_node;
TREE_USED (this->t_) = 1;
@@ -431,7 +431,7 @@ float_type (int bits)
tree
pointer_type (tree to_type)
{
- if (to_type == error_mark_node)
+ if (error_operand_p (to_type))
return error_mark_node;
tree type = build_pointer_type (to_type);
return type;
@@ -442,7 +442,7 @@ pointer_type (tree to_type)
tree
reference_type (tree to_type)
{
- if (to_type == error_mark_node)
+ if (error_operand_p (to_type))
return error_mark_node;
tree type = build_reference_type (to_type);
return type;
@@ -453,7 +453,7 @@ reference_type (tree to_type)
tree
immutable_type (tree base)
{
- if (base == error_mark_node)
+ if (error_operand_p (base))
return error_mark_node;
tree constified = build_qualified_type (base, TYPE_QUAL_CONST);
return constified;
@@ -472,17 +472,16 @@ function_type (const typed_identifier &receiver,
if (receiver.type != NULL_TREE)
{
tree t = receiver.type;
- if (t == error_mark_node)
+ if (error_operand_p (t))
return error_mark_node;
*pp = tree_cons (NULL_TREE, t, NULL_TREE);
pp = &TREE_CHAIN (*pp);
}
- for (std::vector<typed_identifier>::const_iterator p = parameters.begin ();
- p != parameters.end (); ++p)
+ for (const auto &p : parameters)
{
- tree t = p->type;
- if (t == error_mark_node)
+ tree t = p.type;
+ if (error_operand_p (t))
return error_mark_node;
*pp = tree_cons (NULL_TREE, t, NULL_TREE);
pp = &TREE_CHAIN (*pp);
@@ -502,11 +501,11 @@ function_type (const typed_identifier &receiver,
gcc_assert (result_struct != NULL);
result = result_struct;
}
- if (result == error_mark_node)
+ if (error_operand_p (result))
return error_mark_node;
tree fntype = build_function_type (result, args);
- if (fntype == error_mark_node)
+ if (error_operand_p (fntype))
return error_mark_node;
return build_pointer_type (fntype);
@@ -521,21 +520,16 @@ function_type_variadic (const typed_identifier &receiver,
size_t n = parameters.size () + (receiver.type != NULL_TREE ? 1 : 0);
tree *args = XALLOCAVEC (tree, n);
size_t offs = 0;
+ if (error_operand_p (receiver.type))
+ return error_mark_node;
if (receiver.type != NULL_TREE)
- {
- tree t = receiver.type;
- if (t == error_mark_node)
- return error_mark_node;
-
- args[offs++] = t;
- }
+ args[offs++] = receiver.type;
- for (std::vector<typed_identifier>::const_iterator p = parameters.begin ();
- p != parameters.end (); ++p)
+ for (const auto &p : parameters)
{
- tree t = p->type;
- if (t == error_mark_node)
+ tree t = p.type;
+ if (error_operand_p (t))
return error_mark_node;
args[offs++] = t;
}
@@ -550,11 +544,11 @@ function_type_variadic (const typed_identifier &receiver,
gcc_assert (result_struct != NULL_TREE);
result = result_struct;
}
- if (result == error_mark_node)
+ if (error_operand_p (result))
return error_mark_node;
tree fntype = build_varargs_function_type_array (result, n, args);
- if (fntype == error_mark_node)
+ if (error_operand_p (fntype))
return error_mark_node;
return build_pointer_type (fntype);
@@ -569,7 +563,7 @@ function_ptr_type (tree result_type, const std::vector<tree> &parameters,
for (auto &param : parameters)
{
- if (param == error_mark_node)
+ if (error_operand_p (param))
return error_mark_node;
*pp = tree_cons (NULL_TREE, param, NULL_TREE);
@@ -583,7 +577,7 @@ function_ptr_type (tree result_type, const std::vector<tree> &parameters,
result = void_type_node;
tree fntype = build_function_type (result, args);
- if (fntype == error_mark_node)
+ if (error_operand_p (fntype))
return error_mark_node;
return build_pointer_type (fntype);
@@ -592,40 +586,42 @@ function_ptr_type (tree result_type, const std::vector<tree> &parameters,
// Make a struct type.
tree
-struct_type (const std::vector<typed_identifier> &fields)
+struct_type (const std::vector<typed_identifier> &fields, bool layout)
{
- return fill_in_fields (make_node (RECORD_TYPE), fields);
+ return fill_in_fields (make_node (RECORD_TYPE), fields, layout);
}
// Make a union type.
tree
-union_type (const std::vector<typed_identifier> &fields)
+union_type (const std::vector<typed_identifier> &fields, bool layout)
{
- return fill_in_fields (make_node (UNION_TYPE), fields);
+ return fill_in_fields (make_node (UNION_TYPE), fields, layout);
}
// Fill in the fields of a struct or union type.
tree
-fill_in_fields (tree fill, const std::vector<typed_identifier> &fields)
+fill_in_fields (tree fill, const std::vector<typed_identifier> &fields,
+ bool layout)
{
tree field_trees = NULL_TREE;
tree *pp = &field_trees;
- for (std::vector<typed_identifier>::const_iterator p = fields.begin ();
- p != fields.end (); ++p)
+ for (const auto &p : fields)
{
- tree name_tree = get_identifier_from_string (p->name);
- tree type_tree = p->type;
- if (type_tree == error_mark_node)
+ tree name_tree = get_identifier_from_string (p.name);
+ tree type_tree = p.type;
+ if (error_operand_p (type_tree))
return error_mark_node;
- tree field = build_decl (p->location, FIELD_DECL, name_tree, type_tree);
+ tree field = build_decl (p.location, FIELD_DECL, name_tree, type_tree);
DECL_CONTEXT (field) = fill;
*pp = field;
pp = &DECL_CHAIN (field);
}
TYPE_FIELDS (fill) = field_trees;
- layout_type (fill);
+
+ if (layout)
+ layout_type (fill);
// Because Rust permits converting between named struct types and
// equivalent struct types, for which we use VIEW_CONVERT_EXPR, and
@@ -649,7 +645,7 @@ array_type (tree element_type, tree length)
tree
fill_in_array (tree fill, tree element_type, tree length_tree)
{
- if (element_type == error_mark_node || length_tree == error_mark_node)
+ if (error_operand_p (element_type) || error_operand_p (length_tree))
return error_mark_node;
gcc_assert (TYPE_SIZE (element_type) != NULL_TREE);
@@ -681,7 +677,7 @@ fill_in_array (tree fill, tree element_type, tree length_tree)
tree
named_type (const std::string &name, tree type, location_t location)
{
- if (type == error_mark_node)
+ if (error_operand_p (type))
return error_mark_node;
// The middle-end expects a basic type to have a name. In Rust every
@@ -711,7 +707,7 @@ named_type (const std::string &name, tree type, location_t location)
int64_t
type_size (tree t)
{
- if (t == error_mark_node)
+ if (error_operand_p (t))
return 1;
if (t == void_type_node)
return 0;
@@ -729,7 +725,7 @@ type_size (tree t)
int64_t
type_alignment (tree t)
{
- if (t == error_mark_node)
+ if (error_operand_p (t))
return 1;
return TYPE_ALIGN_UNIT (t);
}
@@ -739,7 +735,7 @@ type_alignment (tree t)
int64_t
type_field_alignment (tree t)
{
- if (t == error_mark_node)
+ if (error_operand_p (t))
return 1;
return rust_field_alignment (t);
}
@@ -749,7 +745,7 @@ type_field_alignment (tree t)
int64_t
type_field_offset (tree struct_tree, size_t index)
{
- if (struct_tree == error_mark_node)
+ if (error_operand_p (struct_tree))
return 0;
gcc_assert (TREE_CODE (struct_tree) == RECORD_TYPE);
tree field = TYPE_FIELDS (struct_tree);
@@ -770,7 +766,7 @@ tree
zero_expression (tree t)
{
tree ret;
- if (t == error_mark_node)
+ if (error_operand_p (t))
ret = error_mark_node;
else
ret = build_zero_cst (t);
@@ -791,7 +787,7 @@ tree
float_constant_expression (tree t, mpfr_t val)
{
tree ret;
- if (t == error_mark_node)
+ if (error_operand_p (t))
return error_mark_node;
REAL_VALUE_TYPE r1;
@@ -842,8 +838,7 @@ boolean_constant_expression (bool val)
tree
convert_expression (tree type_tree, tree expr_tree, location_t location)
{
- if (type_tree == error_mark_node || expr_tree == error_mark_node
- || TREE_TYPE (expr_tree) == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (expr_tree))
return error_mark_node;
tree ret;
@@ -875,8 +870,7 @@ convert_expression (tree type_tree, tree expr_tree, location_t location)
tree
struct_field_expression (tree struct_tree, size_t index, location_t location)
{
- if (struct_tree == error_mark_node
- || TREE_TYPE (struct_tree) == error_mark_node)
+ if (error_operand_p (struct_tree))
return error_mark_node;
gcc_assert (TREE_CODE (TREE_TYPE (struct_tree)) == RECORD_TYPE
|| TREE_CODE (TREE_TYPE (struct_tree)) == UNION_TYPE);
@@ -892,7 +886,7 @@ struct_field_expression (tree struct_tree, size_t index, location_t location)
field = DECL_CHAIN (field);
gcc_assert (field != NULL_TREE);
}
- if (TREE_TYPE (field) == error_mark_node)
+ if (error_operand_p (TREE_TYPE (field)))
return error_mark_node;
tree ret = fold_build3_loc (location, COMPONENT_REF, TREE_TYPE (field),
struct_tree, field, NULL_TREE);
@@ -906,7 +900,7 @@ struct_field_expression (tree struct_tree, size_t index, location_t location)
tree
compound_expression (tree stat, tree expr, location_t location)
{
- if (stat == error_mark_node || expr == error_mark_node)
+ if (error_operand_p (stat) || error_operand_p (expr))
return error_mark_node;
tree ret
= fold_build2_loc (location, COMPOUND_EXPR, TREE_TYPE (expr), stat, expr);
@@ -920,8 +914,8 @@ tree
conditional_expression (tree, tree type_tree, tree cond_expr, tree then_expr,
tree else_expr, location_t location)
{
- if (type_tree == error_mark_node || cond_expr == error_mark_node
- || then_expr == error_mark_node || else_expr == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (cond_expr)
+ || error_operand_p (then_expr) || error_operand_p (else_expr))
return error_mark_node;
tree ret = build3_loc (location, COND_EXPR, type_tree, cond_expr, then_expr,
else_expr);
@@ -939,7 +933,7 @@ operator_to_tree_code (NegationOperator op)
case NegationOperator::NEGATE:
return NEGATE_EXPR;
case NegationOperator::NOT:
- return TRUTH_NOT_EXPR;
+ return BIT_NOT_EXPR;
default:
rust_unreachable ();
}
@@ -1018,12 +1012,12 @@ operator_to_tree_code (LazyBooleanOperator op)
}
}
-/* Helper function for deciding if a tree is a floating point node. */
+/* Returns true if the type of EXP is a floating point type.
+ False otherwise. */
bool
-is_floating_point (tree t)
+is_floating_point (tree exp)
{
- auto tree_type = TREE_CODE (TREE_TYPE (t));
- return tree_type == REAL_TYPE || tree_type == COMPLEX_TYPE;
+ return FLOAT_TYPE_P (TREE_TYPE (exp));
}
// Return an expression for the negation operation OP EXPR.
@@ -1032,7 +1026,7 @@ negation_expression (NegationOperator op, tree expr_tree, location_t location)
{
/* Check if the expression is an error, in which case we return an error
expression. */
- if (expr_tree == error_mark_node || TREE_TYPE (expr_tree) == error_mark_node)
+ if (error_operand_p (expr_tree))
return error_mark_node;
/* For negation operators, the resulting type should be the same as its
@@ -1068,9 +1062,15 @@ arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op, tree left,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left == error_mark_node || right == error_mark_node)
+ if (error_operand_p (left) || error_operand_p (right))
return error_mark_node;
+ // unwrap the const decls if set
+ if (TREE_CODE (left) == CONST_DECL)
+ left = DECL_INITIAL (left);
+ if (TREE_CODE (right) == CONST_DECL)
+ right = DECL_INITIAL (right);
+
/* We need to determine if we're doing floating point arithmetics of integer
arithmetics. */
bool floating_point = is_floating_point (left);
@@ -1103,6 +1103,18 @@ arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op, tree left,
if (floating_point && extended_type != NULL_TREE)
ret = convert (original_type, ret);
+ if (op == ArithmeticOrLogicalOperator::DIVIDE
+ && (integer_zerop (right) || fixed_zerop (right)))
+ {
+ rust_error_at (location, "division by zero");
+ }
+ else if (op == ArithmeticOrLogicalOperator::LEFT_SHIFT
+ && TREE_CODE (right) == INTEGER_CST
+ && (compare_tree_int (right, TYPE_PRECISION (TREE_TYPE (ret))) >= 0))
+ {
+ rust_error_at (location, "left shift count >= width of type");
+ }
+
return ret;
}
@@ -1162,7 +1174,7 @@ arithmetic_or_logical_expression_checked (ArithmeticOrLogicalOperator op,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left == error_mark_node || right == error_mark_node)
+ if (error_operand_p (left) || error_operand_p (right))
return error_mark_node;
// FIXME: Add `if (!debug_mode)`
@@ -1202,7 +1214,7 @@ comparison_expression (ComparisonOperator op, tree left_tree, tree right_tree,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left_tree == error_mark_node || right_tree == error_mark_node)
+ if (error_operand_p (left_tree) || error_operand_p (right_tree))
return error_mark_node;
/* For comparison operators, the resulting type should be boolean. */
@@ -1222,7 +1234,7 @@ lazy_boolean_expression (LazyBooleanOperator op, tree left_tree,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left_tree == error_mark_node || right_tree == error_mark_node)
+ if (error_operand_p (left_tree) || error_operand_p (right_tree))
return error_mark_node;
/* For lazy boolean operators, the resulting type should be the same as the
@@ -1243,7 +1255,7 @@ constructor_expression (tree type_tree, bool is_variant,
const std::vector<tree> &vals, int union_index,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return error_mark_node;
vec<constructor_elt, va_gc> *init;
@@ -1285,8 +1297,8 @@ constructor_expression (tree type_tree, bool is_variant,
gcc_assert (field != NULL_TREE);
field = DECL_CHAIN (field);
}
- if (TREE_TYPE (field) == error_mark_node || val == error_mark_node
- || TREE_TYPE (val) == error_mark_node)
+
+ if (TREE_TYPE (field) == error_mark_node || error_operand_p (val))
return error_mark_node;
if (int_size_in_bytes (TREE_TYPE (field)) == 0)
@@ -1316,8 +1328,7 @@ constructor_expression (tree type_tree, bool is_variant,
{
gcc_assert (field != NULL_TREE);
tree val = (*p);
- if (TREE_TYPE (field) == error_mark_node || val == error_mark_node
- || TREE_TYPE (val) == error_mark_node)
+ if (TREE_TYPE (field) == error_mark_node || error_operand_p (val))
return error_mark_node;
if (int_size_in_bytes (TREE_TYPE (field)) == 0)
@@ -1338,7 +1349,7 @@ constructor_expression (tree type_tree, bool is_variant,
if (!TREE_CONSTANT (elt->value))
is_constant = false;
}
- gcc_assert (field == NULL_TREE);
+ // gcc_assert (field == NULL_TREE);
}
}
@@ -1356,7 +1367,7 @@ array_constructor_expression (tree type_tree,
const std::vector<tree> &vals,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return error_mark_node;
gcc_assert (indexes.size () == vals.size ());
@@ -1373,7 +1384,7 @@ array_constructor_expression (tree type_tree,
tree index = size_int (indexes[i]);
tree val = vals[i];
- if (index == error_mark_node || val == error_mark_node)
+ if (error_operand_p (index) || error_operand_p (val))
return error_mark_node;
if (element_size == 0)
@@ -1477,8 +1488,7 @@ array_initializer (tree fndecl, tree block, tree array_type, tree length,
tree
array_index_expression (tree array_tree, tree index_tree, location_t location)
{
- if (array_tree == error_mark_node || TREE_TYPE (array_tree) == error_mark_node
- || index_tree == error_mark_node)
+ if (error_operand_p (array_tree) || error_operand_p (index_tree))
return error_mark_node;
// A function call that returns a zero sized object will have been
@@ -1500,7 +1510,7 @@ tree
call_expression (tree fn, const std::vector<tree> &fn_args, tree chain_expr,
location_t location)
{
- if (fn == error_mark_node || TREE_TYPE (fn) == error_mark_node)
+ if (error_operand_p (fn))
return error_mark_node;
gcc_assert (FUNCTION_POINTER_TYPE_P (TREE_TYPE (fn)));
@@ -1580,7 +1590,7 @@ tree
init_statement (tree, Bvariable *var, tree init_tree)
{
tree var_tree = var->get_decl ();
- if (var_tree == error_mark_node || init_tree == error_mark_node)
+ if (error_operand_p (var_tree) || error_operand_p (init_tree))
return error_mark_node;
gcc_assert (TREE_CODE (var_tree) == VAR_DECL);
@@ -1611,7 +1621,7 @@ init_statement (tree, Bvariable *var, tree init_tree)
tree
assignment_statement (tree lhs, tree rhs, location_t location)
{
- if (lhs == error_mark_node || rhs == error_mark_node)
+ if (error_operand_p (lhs) || error_operand_p (rhs))
return error_mark_node;
// To avoid problems with GNU ld, we don't make zero-sized
@@ -1636,14 +1646,14 @@ assignment_statement (tree lhs, tree rhs, location_t location)
tree
return_statement (tree fntree, tree val, location_t location)
{
- if (fntree == error_mark_node)
+ if (error_operand_p (fntree))
return error_mark_node;
tree result = DECL_RESULT (fntree);
- if (result == error_mark_node)
+ if (error_operand_p (result))
return error_mark_node;
- if (val == error_mark_node)
+ if (error_operand_p (val))
return error_mark_node;
tree set
@@ -1661,8 +1671,8 @@ tree
exception_handler_statement (tree try_stmt, tree except_stmt, tree finally_stmt,
location_t location)
{
- if (try_stmt == error_mark_node || except_stmt == error_mark_node
- || finally_stmt == error_mark_node)
+ if (error_operand_p (try_stmt) || error_operand_p (except_stmt)
+ || error_operand_p (finally_stmt))
return error_mark_node;
if (except_stmt != NULL_TREE)
@@ -1681,8 +1691,8 @@ tree
if_statement (tree, tree cond_tree, tree then_tree, tree else_tree,
location_t location)
{
- if (cond_tree == error_mark_node || then_tree == error_mark_node
- || else_tree == error_mark_node)
+ if (error_operand_p (cond_tree) || error_operand_p (then_tree)
+ || error_operand_p (else_tree))
return error_mark_node;
tree ret = build3_loc (location, COND_EXPR, void_type_node, cond_tree,
then_tree, else_tree);
@@ -1708,15 +1718,12 @@ exit_expression (tree cond_tree, location_t locus)
tree
compound_statement (tree s1, tree s2)
{
- tree stmt_list = NULL_TREE;
- tree t = s1;
- if (t == error_mark_node)
- return error_mark_node;
- append_to_statement_list (t, &stmt_list);
- t = s2;
- if (t == error_mark_node)
+ if (error_operand_p (s1) || error_operand_p (s2))
return error_mark_node;
- append_to_statement_list (t, &stmt_list);
+
+ tree stmt_list = NULL_TREE;
+ append_to_statement_list (s1, &stmt_list);
+ append_to_statement_list (s2, &stmt_list);
// If neither statement has any side effects, stmt_list can be NULL
// at this point.
@@ -1732,11 +1739,9 @@ tree
statement_list (const std::vector<tree> &statements)
{
tree stmt_list = NULL_TREE;
- for (std::vector<tree>::const_iterator p = statements.begin ();
- p != statements.end (); ++p)
+ for (tree t : statements)
{
- tree t = (*p);
- if (t == error_mark_node)
+ if (error_operand_p (t))
return error_mark_node;
append_to_statement_list (t, &stmt_list);
}
@@ -1788,12 +1793,13 @@ block (tree fndecl, tree enclosing, const std::vector<Bvariable *> &vars,
*pp = block_tree;
}
+ // Chain the variables of the scope together so they are all connected
+ // to the block.
tree *pp = &BLOCK_VARS (block_tree);
- for (std::vector<Bvariable *>::const_iterator pv = vars.begin ();
- pv != vars.end (); ++pv)
+ for (Bvariable *bv : vars)
{
- *pp = (*pv)->get_decl ();
- if (*pp != error_mark_node)
+ *pp = bv->get_decl ();
+ if (!error_operand_p (*pp))
pp = &DECL_CHAIN (*pp);
}
*pp = NULL_TREE;
@@ -1812,11 +1818,9 @@ void
block_add_statements (tree bind_tree, const std::vector<tree> &statements)
{
tree stmt_list = NULL_TREE;
- for (std::vector<tree>::const_iterator p = statements.begin ();
- p != statements.end (); ++p)
+ for (tree s : statements)
{
- tree s = (*p);
- if (s != error_mark_node)
+ if (!error_operand_p (s))
append_to_statement_list (s, &stmt_list);
}
@@ -1894,8 +1898,7 @@ convert_tree (tree type_tree, tree expr_tree, location_t location)
if (type_tree == TREE_TYPE (expr_tree))
return expr_tree;
- if (type_tree == error_mark_node || expr_tree == error_mark_node
- || TREE_TYPE (expr_tree) == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (expr_tree))
return error_mark_node;
if (POINTER_TYPE_P (type_tree) || INTEGRAL_TYPE_P (type_tree)
@@ -1924,7 +1927,7 @@ global_variable (const std::string &var_name, const std::string &asm_name,
tree type_tree, bool is_external, bool is_hidden,
bool in_unique_section, location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
// The GNU linker does not like dynamic variables with zero size.
@@ -1963,11 +1966,11 @@ global_variable (const std::string &var_name, const std::string &asm_name,
void
global_variable_set_init (Bvariable *var, tree expr_tree)
{
- if (expr_tree == error_mark_node)
+ if (error_operand_p (expr_tree))
return;
gcc_assert (TREE_CONSTANT (expr_tree));
tree var_decl = var->get_decl ();
- if (var_decl == error_mark_node)
+ if (error_operand_p (var_decl))
return;
DECL_INITIAL (var_decl) = expr_tree;
@@ -1988,7 +1991,7 @@ Bvariable *
local_variable (tree function, const std::string &name, tree type_tree,
Bvariable *decl_var, location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
tree decl = build_decl (location, VAR_DECL, get_identifier_from_string (name),
type_tree);
@@ -2009,7 +2012,7 @@ Bvariable *
parameter_variable (tree function, const std::string &name, tree type_tree,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
tree decl = build_decl (location, PARM_DECL,
get_identifier_from_string (name), type_tree);
@@ -2026,7 +2029,7 @@ Bvariable *
static_chain_variable (tree fndecl, const std::string &name, tree type_tree,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
tree decl = build_decl (location, PARM_DECL,
get_identifier_from_string (name), type_tree);
@@ -2060,8 +2063,8 @@ temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree init_tree,
tree *pstatement)
{
gcc_assert (fndecl != NULL_TREE);
- if (type_tree == error_mark_node || init_tree == error_mark_node
- || fndecl == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (init_tree)
+ || error_operand_p (fndecl))
{
*pstatement = error_mark_node;
return Bvariable::error_variable ();
@@ -2178,13 +2181,13 @@ tree
function (tree functype, const std::string &name, const std::string &asm_name,
unsigned int flags, location_t location)
{
- if (functype != error_mark_node)
- {
- gcc_assert (FUNCTION_POINTER_TYPE_P (functype));
- functype = TREE_TYPE (functype);
- }
+ if (error_operand_p (functype))
+ return error_mark_node;
+
+ gcc_assert (FUNCTION_POINTER_TYPE_P (functype));
+ functype = TREE_TYPE (functype);
tree id = get_identifier_from_string (name);
- if (functype == error_mark_node || id == error_mark_node)
+ if (error_operand_p (id))
return error_mark_node;
tree decl = build_decl (location, FUNCTION_DECL, id, functype);
@@ -2222,8 +2225,8 @@ tree
function_defer_statement (tree function, tree undefer_tree, tree defer_tree,
location_t location)
{
- if (undefer_tree == error_mark_node || defer_tree == error_mark_node
- || function == error_mark_node)
+ if (error_operand_p (undefer_tree) || error_operand_p (defer_tree)
+ || error_operand_p (function))
return error_mark_node;
if (DECL_STRUCT_FUNCTION (function) == NULL)
@@ -2255,16 +2258,15 @@ bool
function_set_parameters (tree function,
const std::vector<Bvariable *> &param_vars)
{
- if (function == error_mark_node)
+ if (error_operand_p (function))
return false;
tree params = NULL_TREE;
tree *pp = &params;
- for (std::vector<Bvariable *>::const_iterator pv = param_vars.begin ();
- pv != param_vars.end (); ++pv)
+ for (Bvariable *bv : param_vars)
{
- *pp = (*pv)->get_decl ();
- gcc_assert (*pp != error_mark_node);
+ *pp = bv->get_decl ();
+ gcc_assert (!error_operand_p (*pp));
pp = &DECL_CHAIN (*pp);
}
*pp = NULL_TREE;
@@ -2289,23 +2291,19 @@ write_global_definitions (const std::vector<tree> &type_decls,
// Convert all non-erroneous declarations into Gimple form.
size_t i = 0;
- for (std::vector<Bvariable *>::const_iterator p = variable_decls.begin ();
- p != variable_decls.end (); ++p)
+ for (Bvariable *bv : variable_decls)
{
- tree v = (*p)->get_decl ();
- if (v != error_mark_node)
- {
- defs[i] = v;
- rust_preserve_from_gc (defs[i]);
- ++i;
- }
+ tree v = bv->get_decl ();
+ if (error_operand_p (v))
+ continue;
+ defs[i] = v;
+ rust_preserve_from_gc (defs[i]);
+ ++i;
}
- for (std::vector<tree>::const_iterator p = type_decls.begin ();
- p != type_decls.end (); ++p)
+ for (tree type_tree : type_decls)
{
- tree type_tree = (*p);
- if (type_tree != error_mark_node && IS_TYPE_OR_DECL_P (type_tree))
+ if (!error_operand_p (type_tree) && IS_TYPE_OR_DECL_P (type_tree))
{
defs[i] = TYPE_NAME (type_tree);
gcc_assert (defs[i] != NULL);
@@ -2313,21 +2311,18 @@ write_global_definitions (const std::vector<tree> &type_decls,
++i;
}
}
- for (std::vector<tree>::const_iterator p = constant_decls.begin ();
- p != constant_decls.end (); ++p)
+ for (tree t : constant_decls)
{
- if ((*p) != error_mark_node)
+ if (!error_operand_p (t))
{
- defs[i] = (*p);
+ defs[i] = t;
rust_preserve_from_gc (defs[i]);
++i;
}
}
- for (std::vector<tree>::const_iterator p = function_decls.begin ();
- p != function_decls.end (); ++p)
+ for (tree decl : function_decls)
{
- tree decl = (*p);
- if (decl != error_mark_node)
+ if (!error_operand_p (decl))
{
rust_preserve_from_gc (decl);
if (DECL_STRUCT_FUNCTION (decl) == NULL)
diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index b84e114..f3a155d 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -143,6 +143,8 @@ grs_langhook_init_options_struct (struct gcc_options *opts)
opts->x_warn_unused_result = 1;
/* lets warn for infinite recursion*/
opts->x_warn_infinite_recursion = 1;
+ /* Enable exception handling (aka `panic!` in Rust) */
+ opts->x_flag_exceptions = 1;
// nothing yet - used by frontends to change specific options for the language
Rust::Session::get_instance ().init_options ();
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 11ff250..48acbf34 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -17,6 +17,9 @@
// <http://www.gnu.org/licenses/>.
#include "rust-session-manager.h"
+#include "rust-collect-lang-items.h"
+#include "rust-desugar-for-loops.h"
+#include "rust-desugar-question-mark.h"
#include "rust-diagnostics.h"
#include "rust-hir-pattern-analysis.h"
#include "rust-immutable-name-resolution-context.h"
@@ -265,6 +268,9 @@ Session::handle_option (
case OPT_frust_metadata_output_:
options.set_metadata_output (arg);
break;
+ case OPT_frust_panic_:
+ options.set_panic_strategy (flag_rust_panic);
+ break;
default:
break;
@@ -397,31 +403,16 @@ Session::handle_input_files (int num_files, const char **files)
const auto &file = files[0];
- if (options.crate_name.empty ())
- {
- auto filename = "-";
- if (num_files > 0)
- filename = files[0];
-
- auto crate_name = infer_crate_name (filename);
- rust_debug ("inferred crate name: %s", crate_name.c_str ());
- // set the preliminary crate name here
- // we will figure out the real crate name in `handle_crate_name`
- options.set_crate_name (crate_name);
- }
-
- CrateNum crate_num = mappings.get_next_crate_num (options.get_crate_name ());
- mappings.set_current_crate (crate_num);
-
rust_debug ("Attempting to parse file: %s", file);
compile_crate (file);
}
void
-Session::handle_crate_name (const AST::Crate &parsed_crate)
+Session::handle_crate_name (const char *filename,
+ const AST::Crate &parsed_crate)
{
auto &mappings = Analysis::Mappings::get ();
- auto crate_name_changed = false;
+ auto crate_name_found = false;
auto error = Error (UNDEF_LOCATION, std::string ());
for (const auto &attr : parsed_crate.inner_attrs)
@@ -445,7 +436,6 @@ Session::handle_crate_name (const AST::Crate &parsed_crate)
continue;
}
- auto options = Session::get_instance ().options;
if (options.crate_name_set_manually && (options.crate_name != msg_str))
{
rust_error_at (attr.get_locus (),
@@ -453,19 +443,39 @@ Session::handle_crate_name (const AST::Crate &parsed_crate)
"required to match, but %qs does not match %qs",
options.crate_name.c_str (), msg_str.c_str ());
}
- crate_name_changed = true;
+ crate_name_found = true;
options.set_crate_name (msg_str);
- mappings.set_crate_name (mappings.get_current_crate (), msg_str);
}
- options.crate_name_set_manually |= crate_name_changed;
- if (!options.crate_name_set_manually
- && !validate_crate_name (options.crate_name, error))
+ options.crate_name_set_manually |= crate_name_found;
+ if (!options.crate_name_set_manually)
{
- error.emit ();
- rust_inform (linemap_position_for_column (line_table, 0),
- "crate name inferred from this file");
+ auto crate_name = infer_crate_name (filename);
+ if (crate_name.empty ())
+ {
+ rust_error_at (UNDEF_LOCATION, "crate name is empty");
+ rust_inform (linemap_position_for_column (line_table, 0),
+ "crate name inferred from this file");
+ return;
+ }
+
+ rust_debug ("inferred crate name: %s", crate_name.c_str ());
+ options.set_crate_name (crate_name);
+
+ if (!validate_crate_name (options.get_crate_name (), error))
+ {
+ error.emit ();
+ rust_inform (linemap_position_for_column (line_table, 0),
+ "crate name inferred from this file");
+ return;
+ }
}
+
+ if (saw_errors ())
+ return;
+
+ CrateNum crate_num = mappings.get_next_crate_num (options.get_crate_name ());
+ mappings.set_current_crate (crate_num);
}
// Parses a single file with filename filename.
@@ -535,7 +545,7 @@ Session::compile_crate (const char *filename)
std::unique_ptr<AST::Crate> ast_crate = parser.parse_crate ();
// handle crate name
- handle_crate_name (*ast_crate.get ());
+ handle_crate_name (filename, *ast_crate.get ());
// dump options except lexer dump
if (options.dump_option_enabled (CompileOptions::AST_DUMP_PRETTY))
@@ -600,10 +610,16 @@ Session::compile_crate (const char *filename)
if (last_step == CompileOptions::CompileStep::Expansion)
return;
+ AST::CollectLangItems ().go (parsed_crate);
+
auto name_resolution_ctx = Resolver2_0::NameResolutionContext ();
// expansion pipeline stage
expansion (parsed_crate, name_resolution_ctx);
+
+ AST::DesugarForLoops ().go (parsed_crate);
+ AST::DesugarQuestionMark ().go (parsed_crate);
+
rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))
{
@@ -1394,6 +1410,7 @@ rust_crate_name_validation_test (void)
ASSERT_FALSE (Rust::validate_crate_name ("∀", error));
/* Tests for crate name inference */
+ ASSERT_EQ (Rust::infer_crate_name (".rs"), "");
ASSERT_EQ (Rust::infer_crate_name ("c.rs"), "c");
// NOTE: ... but - is allowed when in the filename
ASSERT_EQ (Rust::infer_crate_name ("a-b.rs"), "a_b");
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index b5a715c..83ba121 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -264,6 +264,13 @@ struct CompileOptions
} compile_until
= CompileStep::End;
+ enum class PanicStrategy
+ {
+ Unwind,
+ Abort,
+ } panic_strategy
+ = PanicStrategy::Unwind;
+
bool dump_option_enabled (DumpOption option) const
{
return dump_options.find (option) != dump_options.end ();
@@ -320,6 +327,13 @@ struct CompileOptions
const CompileStep &get_compile_until () const { return compile_until; }
+ void set_panic_strategy (int strategy)
+ {
+ panic_strategy = static_cast<PanicStrategy> (strategy);
+ }
+
+ const PanicStrategy &get_panic_strategy () const { return panic_strategy; }
+
void set_metadata_output (const std::string &path)
{
metadata_output_path = path;
@@ -376,7 +390,7 @@ public:
const struct cl_option_handlers *handlers);
void handle_input_files (int num_files, const char **files);
void init_options ();
- void handle_crate_name (const AST::Crate &parsed_crate);
+ void handle_crate_name (const char *filename, const AST::Crate &parsed_crate);
/* This function saves the filename data into the session manager using the
* `move` semantics, and returns a C-style string referencing the input
diff --git a/gcc/rust/typecheck/rust-autoderef.cc b/gcc/rust/typecheck/rust-autoderef.cc
index 7e80b8e..6aa20a8 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -113,7 +113,7 @@ Adjuster::try_unsize_type (TyTy::BaseType *ty)
auto slice
= new TyTy::SliceType (mappings.get_next_hir_id (), ty->get_ident ().locus,
TyTy::TyVar (slice_elem->get_ref ()));
- context->insert_implicit_type (slice);
+ context->insert_implicit_type (slice->get_ref (), slice);
return Adjustment (Adjustment::AdjustmentType::UNSIZE, ty, slice);
}
@@ -209,7 +209,7 @@ resolve_operator_overload_fn (
== 0)
{
TraitReference *trait_reference
- = TraitResolver::Lookup (*parent->get_trait_ref ().get ());
+ = TraitResolver::Lookup (parent->get_trait_ref ());
if (!trait_reference->is_error ())
{
TyTy::BaseType *lookup = nullptr;
diff --git a/gcc/rust/typecheck/rust-casts.cc b/gcc/rust/typecheck/rust-casts.cc
index 5235069f..90bdef1 100644
--- a/gcc/rust/typecheck/rust-casts.cc
+++ b/gcc/rust/typecheck/rust-casts.cc
@@ -200,6 +200,26 @@ TypeCastRules::cast_rules ()
}
break;
+ case TyTy::TypeKind::FLOAT: {
+ // can only do this for number types not char
+ bool from_char
+ = from.get_ty ()->get_kind () == TyTy::TypeKind::CHAR;
+ if (!from_char)
+ return TypeCoercionRules::CoercionResult{{},
+ to.get_ty ()->clone ()};
+ }
+ break;
+
+ case TyTy::TypeKind::POINTER: {
+ // char can't be casted as a ptr
+ bool from_char
+ = from.get_ty ()->get_kind () == TyTy::TypeKind::CHAR;
+ if (!from_char)
+ return TypeCoercionRules::CoercionResult{{},
+ to.get_ty ()->clone ()};
+ }
+ break;
+
case TyTy::TypeKind::INFER:
case TyTy::TypeKind::USIZE:
case TyTy::TypeKind::ISIZE:
@@ -215,6 +235,12 @@ TypeCastRules::cast_rules ()
case TyTy::TypeKind::FLOAT:
switch (to.get_ty ()->get_kind ())
{
+ case TyTy::TypeKind::USIZE:
+ case TyTy::TypeKind::ISIZE:
+ case TyTy::TypeKind::UINT:
+ case TyTy::TypeKind::INT:
+ return TypeCoercionRules::CoercionResult{{}, to.get_ty ()->clone ()};
+
case TyTy::TypeKind::FLOAT:
return TypeCoercionRules::CoercionResult{{}, to.get_ty ()->clone ()};
@@ -244,12 +270,25 @@ TypeCastRules::cast_rules ()
case TyTy::TypeKind::POINTER:
switch (to.get_ty ()->get_kind ())
{
+ case TyTy::TypeKind::USIZE:
+ case TyTy::TypeKind::ISIZE:
+ case TyTy::TypeKind::UINT:
+ case TyTy::TypeKind::INT: {
+ // refs should not cast to numeric type
+ bool from_ptr
+ = from.get_ty ()->get_kind () == TyTy::TypeKind::POINTER;
+ if (from_ptr)
+ {
+ return TypeCoercionRules::CoercionResult{
+ {}, to.get_ty ()->clone ()};
+ }
+ }
+ break;
+
case TyTy::TypeKind::REF:
case TyTy::TypeKind::POINTER:
return check_ptr_ptr_cast ();
- // FIXME can you cast a pointer to a integral type?
-
default:
return TypeCoercionRules::CoercionResult::get_error ();
}
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc
index 8e5473f..c1165e9 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.cc
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc
@@ -62,7 +62,7 @@ MethodResolver::Select (std::set<MethodCandidate> &candidates,
for (size_t i = 0; i < arguments.size (); i++)
{
TyTy::BaseType *arg = arguments.at (i);
- TyTy::BaseType *param = fn.get_params ().at (i + 1).second;
+ TyTy::BaseType *param = fn.get_params ().at (i + 1).get_type ();
TyTy::BaseType *coerced
= try_coercion (0, TyTy::TyWithLocation (param),
TyTy::TyWithLocation (arg), UNDEF_LOCATION);
@@ -200,104 +200,103 @@ MethodResolver::select (TyTy::BaseType &receiver)
};
std::vector<trait_item_candidate> trait_fns;
- mappings.iterate_impl_blocks (
- [&] (HirId id, HIR::ImplBlock *impl) mutable -> bool {
- bool is_trait_impl = impl->has_trait_ref ();
- if (!is_trait_impl)
- return true;
-
- // look for impl implementation else lookup the associated trait item
- for (auto &impl_item : impl->get_impl_items ())
- {
- bool is_fn = impl_item->get_impl_item_type ()
- == HIR::ImplItem::ImplItemType::FUNCTION;
- if (!is_fn)
- continue;
-
- HIR::Function *func = static_cast<HIR::Function *> (impl_item.get ());
- if (!func->is_method ())
- continue;
-
- bool name_matches = func->get_function_name ().as_string ().compare (
- segment_name.as_string ())
- == 0;
- if (!name_matches)
- continue;
-
- TyTy::BaseType *ty = nullptr;
- if (!query_type (func->get_mappings ().get_hirid (), &ty))
- continue;
- if (ty->get_kind () == TyTy::TypeKind::ERROR)
- continue;
-
- rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
- TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
- const TyTy::BaseType *impl_self
- = TypeCheckItem::ResolveImplBlockSelf (*impl);
-
- // see:
- // https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/Method.20Resolution/near/338646280
- // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/method/probe.rs#L650-L660
- bool impl_self_is_ptr
- = impl_self->get_kind () == TyTy::TypeKind::POINTER;
- bool impl_self_is_ref = impl_self->get_kind () == TyTy::TypeKind::REF;
- if (receiver_is_raw_ptr && impl_self_is_ptr)
- {
- const TyTy::PointerType &sptr
- = *static_cast<const TyTy::PointerType *> (impl_self);
- const TyTy::PointerType &ptr
- = *static_cast<const TyTy::PointerType *> (raw);
-
- // we could do this via lang-item assemblies if we refactor this
- bool mut_match = sptr.mutability () == ptr.mutability ();
- if (!mut_match)
- continue;
- }
- else if (receiver_is_ref && impl_self_is_ref)
- {
- const TyTy::ReferenceType &sptr
- = *static_cast<const TyTy::ReferenceType *> (impl_self);
- const TyTy::ReferenceType &ptr
- = *static_cast<const TyTy::ReferenceType *> (raw);
-
- // we could do this via lang-item assemblies if we refactor this
- bool mut_match = sptr.mutability () == ptr.mutability ();
- if (!mut_match)
- continue;
- }
+ mappings.iterate_impl_blocks ([&] (HirId id,
+ HIR::ImplBlock *impl) mutable -> bool {
+ bool is_trait_impl = impl->has_trait_ref ();
+ if (!is_trait_impl)
+ return true;
- inherent_impl_fns.push_back ({func, impl, fnty});
- return true;
- }
+ // look for impl implementation else lookup the associated trait item
+ for (auto &impl_item : impl->get_impl_items ())
+ {
+ bool is_fn = impl_item->get_impl_item_type ()
+ == HIR::ImplItem::ImplItemType::FUNCTION;
+ if (!is_fn)
+ continue;
+
+ HIR::Function *func = static_cast<HIR::Function *> (impl_item.get ());
+ if (!func->is_method ())
+ continue;
+
+ bool name_matches = func->get_function_name ().as_string ().compare (
+ segment_name.as_string ())
+ == 0;
+ if (!name_matches)
+ continue;
+
+ TyTy::BaseType *ty = nullptr;
+ if (!query_type (func->get_mappings ().get_hirid (), &ty))
+ continue;
+ if (ty->get_kind () == TyTy::TypeKind::ERROR)
+ continue;
+
+ rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
+ const TyTy::BaseType *impl_self
+ = TypeCheckItem::ResolveImplBlockSelf (*impl);
+
+ // see:
+ // https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/Method.20Resolution/near/338646280
+ // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/method/probe.rs#L650-L660
+ bool impl_self_is_ptr
+ = impl_self->get_kind () == TyTy::TypeKind::POINTER;
+ bool impl_self_is_ref = impl_self->get_kind () == TyTy::TypeKind::REF;
+ if (receiver_is_raw_ptr && impl_self_is_ptr)
+ {
+ const TyTy::PointerType &sptr
+ = *static_cast<const TyTy::PointerType *> (impl_self);
+ const TyTy::PointerType &ptr
+ = *static_cast<const TyTy::PointerType *> (raw);
+
+ // we could do this via lang-item assemblies if we refactor this
+ bool mut_match = sptr.mutability () == ptr.mutability ();
+ if (!mut_match)
+ continue;
+ }
+ else if (receiver_is_ref && impl_self_is_ref)
+ {
+ const TyTy::ReferenceType &sptr
+ = *static_cast<const TyTy::ReferenceType *> (impl_self);
+ const TyTy::ReferenceType &ptr
+ = *static_cast<const TyTy::ReferenceType *> (raw);
+
+ // we could do this via lang-item assemblies if we refactor this
+ bool mut_match = sptr.mutability () == ptr.mutability ();
+ if (!mut_match)
+ continue;
+ }
+
+ inherent_impl_fns.push_back ({func, impl, fnty});
+ return true;
+ }
- TraitReference *trait_ref
- = TraitResolver::Resolve (*impl->get_trait_ref ().get ());
- rust_assert (!trait_ref->is_error ());
+ TraitReference *trait_ref = TraitResolver::Resolve (impl->get_trait_ref ());
+ rust_assert (!trait_ref->is_error ());
- auto item_ref
- = trait_ref->lookup_trait_item (segment_name.as_string (),
- TraitItemReference::TraitItemType::FN);
- if (item_ref->is_error ())
- return true;
+ auto item_ref
+ = trait_ref->lookup_trait_item (segment_name.as_string (),
+ TraitItemReference::TraitItemType::FN);
+ if (item_ref->is_error ())
+ return true;
- const HIR::Trait *trait = trait_ref->get_hir_trait_ref ();
- HIR::TraitItem *item = item_ref->get_hir_trait_item ();
- if (item->get_item_kind () != HIR::TraitItem::TraitItemKind::FUNC)
- return true;
+ const HIR::Trait *trait = trait_ref->get_hir_trait_ref ();
+ HIR::TraitItem *item = item_ref->get_hir_trait_item ();
+ if (item->get_item_kind () != HIR::TraitItem::TraitItemKind::FUNC)
+ return true;
- HIR::TraitItemFunc *func = static_cast<HIR::TraitItemFunc *> (item);
- if (!func->get_decl ().is_method ())
- return true;
+ HIR::TraitItemFunc *func = static_cast<HIR::TraitItemFunc *> (item);
+ if (!func->get_decl ().is_method ())
+ return true;
- TyTy::BaseType *ty = item_ref->get_tyty ();
- rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
- TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
+ TyTy::BaseType *ty = item_ref->get_tyty ();
+ rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
- trait_item_candidate candidate{func, trait, fnty, trait_ref, item_ref};
- trait_fns.push_back (candidate);
+ trait_item_candidate candidate{func, trait, fnty, trait_ref, item_ref};
+ trait_fns.push_back (candidate);
- return true;
- });
+ return true;
+ });
// lookup specified bounds for an associated item
struct precdicate_candidate
@@ -473,8 +472,11 @@ MethodResolver::get_predicate_items (
if (ty->get_kind () == TyTy::TypeKind::FNDEF)
{
TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
- predicate_candidate candidate{lookup, fnty};
- predicate_items.push_back (candidate);
+ if (fnty->is_method ())
+ {
+ predicate_candidate candidate{lookup, fnty};
+ predicate_items.push_back (candidate);
+ }
}
}
diff --git a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
index 5cef1c2..5537b14 100644
--- a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
+++ b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
@@ -54,7 +54,7 @@ public:
// impl-type -> [ (item, name), ... ]
// }
- HirId impl_type_id = impl->get_type ()->get_mappings ().get_hirid ();
+ HirId impl_type_id = impl->get_type ().get_mappings ().get_hirid ();
TyTy::BaseType *impl_type = nullptr;
bool ok = query_type (impl_type_id, &impl_type);
if (!ok)
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.cc b/gcc/rust/typecheck/rust-hir-path-probe.cc
index 196cc82..32e2399 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.cc
+++ b/gcc/rust/typecheck/rust-hir-path-probe.cc
@@ -168,7 +168,7 @@ PathProbeType::Probe (const TyTy::BaseType *receiver,
if (!probe_bounds)
return probe.candidates;
- if (!probe.is_reciever_generic ())
+ if (!probe.is_receiver_generic ())
{
std::vector<std::pair<TraitReference *, HIR::ImplBlock *>> probed_bounds
= TypeBoundsProbe::Probe (receiver);
@@ -212,8 +212,8 @@ PathProbeType::visit (HIR::TypeAlias &alias)
{
HirId tyid = alias.get_mappings ().get_hirid ();
TyTy::BaseType *ty = nullptr;
- bool ok = query_type (tyid, &ty);
- rust_assert (ok);
+ if (!query_type (tyid, &ty))
+ return;
PathProbeCandidate::ImplItemCandidate impl_item_candidate{&alias,
current_impl};
@@ -232,8 +232,8 @@ PathProbeType::visit (HIR::ConstantItem &constant)
{
HirId tyid = constant.get_mappings ().get_hirid ();
TyTy::BaseType *ty = nullptr;
- bool ok = query_type (tyid, &ty);
- rust_assert (ok);
+ if (!query_type (tyid, &ty))
+ return;
PathProbeCandidate::ImplItemCandidate impl_item_candidate{&constant,
current_impl};
@@ -252,8 +252,8 @@ PathProbeType::visit (HIR::Function &function)
{
HirId tyid = function.get_mappings ().get_hirid ();
TyTy::BaseType *ty = nullptr;
- bool ok = query_type (tyid, &ty);
- rust_assert (ok);
+ if (!query_type (tyid, &ty))
+ return;
PathProbeCandidate::ImplItemCandidate impl_item_candidate{&function,
current_impl};
@@ -297,7 +297,7 @@ PathProbeType::process_impl_item_candidate (HirId id, HIR::ImplItem *item,
HIR::ImplBlock *impl)
{
current_impl = impl;
- HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
+ HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid ();
TyTy::BaseType *impl_block_ty = nullptr;
if (!query_type (impl_ty_id, &impl_block_ty))
return;
@@ -346,7 +346,7 @@ PathProbeType::process_associated_trait_for_candidates (
const TyTy::TypeBoundPredicate p (*trait_ref, BoundPolarity::RegularBound,
UNDEF_LOCATION);
- TyTy::TypeBoundPredicateItem item (&p, trait_item_ref);
+ TyTy::TypeBoundPredicateItem item (p, trait_item_ref);
TyTy::BaseType *trait_item_tyty = item.get_raw_item ()->get_tyty ();
if (receiver->get_kind () != TyTy::DYNAMIC)
@@ -433,7 +433,7 @@ PathProbeType::union_bounds (
}
bool
-PathProbeType::is_reciever_generic () const
+PathProbeType::is_receiver_generic () const
{
const TyTy::BaseType *root = receiver->get_root ();
bool receiver_is_type_param = root->get_kind () == TyTy::TypeKind::PARAM;
@@ -472,8 +472,7 @@ PathProbeImplTrait::process_trait_impl_items_for_candidates ()
if (!impl->has_trait_ref ())
return true;
- TraitReference *resolved
- = TraitResolver::Lookup (*(impl->get_trait_ref ().get ()));
+ TraitReference *resolved = TraitResolver::Lookup (impl->get_trait_ref ());
if (!trait_reference->is_equal (*resolved))
return true;
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h
index 09a6492..59ffeb1 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.h
+++ b/gcc/rust/typecheck/rust-hir-path-probe.h
@@ -145,7 +145,7 @@ protected:
const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> b)
const;
- bool is_reciever_generic () const;
+ bool is_receiver_generic () const;
const TyTy::BaseType *receiver;
const HIR::PathIdentSegment &search;
diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.cc b/gcc/rust/typecheck/rust-hir-trait-reference.cc
index 2ac086c..83985f0 100644
--- a/gcc/rust/typecheck/rust-hir-trait-reference.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-reference.cc
@@ -106,7 +106,7 @@ TraitItemReference::get_error () const
TraitReference::TraitReference (
const HIR::Trait *hir_trait_ref, std::vector<TraitItemReference> item_refs,
- std::vector<const TraitReference *> super_traits,
+ std::vector<TyTy::TypeBoundPredicate> super_traits,
std::vector<TyTy::SubstitutionParamMapping> substs)
: hir_trait_ref (hir_trait_ref), item_refs (item_refs),
super_traits (super_traits)
@@ -263,7 +263,8 @@ TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
bool
TraitReference::lookup_trait_item (const std::string &ident,
- const TraitItemReference **ref) const
+ const TraitItemReference **ref,
+ bool lookup_supers) const
{
for (auto &item : item_refs)
{
@@ -274,10 +275,13 @@ TraitReference::lookup_trait_item (const std::string &ident,
}
}
+ if (!lookup_supers)
+ return false;
+
// lookup super traits
for (const auto &super_trait : super_traits)
{
- bool found = super_trait->lookup_trait_item (ident, ref);
+ bool found = super_trait.get ()->lookup_trait_item (ident, ref);
if (found)
return true;
}
@@ -302,7 +306,7 @@ TraitReference::lookup_trait_item (const std::string &ident,
for (const auto &super_trait : super_traits)
{
const TraitItemReference *res
- = super_trait->lookup_trait_item (ident, type);
+ = super_trait.get ()->lookup_trait_item (ident, type);
if (!res->is_error ())
return res;
}
@@ -330,7 +334,7 @@ TraitReference::get_trait_items_and_supers (
result.push_back (&item);
for (const auto &super_trait : super_traits)
- super_trait->get_trait_items_and_supers (result);
+ super_trait.get ()->get_trait_items_and_supers (result);
}
void
@@ -374,7 +378,7 @@ TraitReference::is_equal (const TraitReference &other) const
return this_id == other_id;
}
-const std::vector<const TraitReference *>
+std::vector<TyTy::TypeBoundPredicate>
TraitReference::get_super_traits () const
{
return super_traits;
@@ -385,10 +389,10 @@ TraitReference::is_object_safe (bool emit_error, location_t locus) const
{
// https: // doc.rust-lang.org/reference/items/traits.html#object-safety
std::vector<const TraitReference *> non_object_super_traits;
- for (auto &item : super_traits)
+ for (auto &super_trait : super_traits)
{
- if (!item->is_object_safe (false, UNDEF_LOCATION))
- non_object_super_traits.push_back (item);
+ if (!super_trait.get ()->is_object_safe (false, UNDEF_LOCATION))
+ non_object_super_traits.push_back (super_trait.get ());
}
std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
@@ -434,7 +438,7 @@ TraitReference::satisfies_bound (const TraitReference &reference) const
for (const auto &super_trait : super_traits)
{
- if (super_trait->satisfies_bound (reference))
+ if (super_trait.get ()->satisfies_bound (reference))
return true;
}
diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h b/gcc/rust/typecheck/rust-hir-trait-reference.h
index bdfd987..8b1ac7d 100644
--- a/gcc/rust/typecheck/rust-hir-trait-reference.h
+++ b/gcc/rust/typecheck/rust-hir-trait-reference.h
@@ -144,7 +144,7 @@ class TraitReference
public:
TraitReference (const HIR::Trait *hir_trait_ref,
std::vector<TraitItemReference> item_refs,
- std::vector<const TraitReference *> super_traits,
+ std::vector<TyTy::TypeBoundPredicate> super_traits,
std::vector<TyTy::SubstitutionParamMapping> substs);
TraitReference (TraitReference const &other);
@@ -196,7 +196,8 @@ public:
const TraitItemReference **ref) const;
bool lookup_trait_item (const std::string &ident,
- const TraitItemReference **ref) const;
+ const TraitItemReference **ref,
+ bool lookup_supers = true) const;
const TraitItemReference *
lookup_trait_item (const std::string &ident,
@@ -217,7 +218,7 @@ public:
bool is_equal (const TraitReference &other) const;
- const std::vector<const TraitReference *> get_super_traits () const;
+ std::vector<TyTy::TypeBoundPredicate> get_super_traits () const;
bool is_object_safe (bool emit_error, location_t locus) const;
@@ -230,7 +231,7 @@ public:
private:
const HIR::Trait *hir_trait_ref;
std::vector<TraitItemReference> item_refs;
- std::vector<const TraitReference *> super_traits;
+ std::vector<TyTy::TypeBoundPredicate> super_traits;
std::vector<TyTy::SubstitutionParamMapping> trait_substs;
};
@@ -246,15 +247,16 @@ public:
HIR::ImplBlock *get_impl_block ();
+ location_t get_locus () const;
+
TyTy::BaseType *get_self ();
const TyTy::BaseType *get_self () const;
void setup_raw_associated_types ();
- TyTy::BaseType *
- setup_associated_types (const TyTy::BaseType *self,
- const TyTy::TypeBoundPredicate &bound,
- TyTy::SubstitutionArgumentMappings *args = nullptr);
+ TyTy::BaseType *setup_associated_types (
+ const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound,
+ TyTy::SubstitutionArgumentMappings *args = nullptr, bool infer = true);
void reset_associated_types ();
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index ec331cf..032bb58 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -20,6 +20,10 @@
#include "rust-hir-type-check-expr.h"
#include "rust-substitution-mapper.h"
#include "rust-type-util.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// used for flag_name_resolution_2_0
+#include "options.h"
namespace Rust {
namespace Resolver {
@@ -65,7 +69,7 @@ ResolveTraitItemToRef::visit (HIR::TraitItemFunc &fn)
{
// create trait-item-ref
location_t locus = fn.get_locus ();
- bool is_optional = fn.has_block_defined ();
+ bool is_optional = fn.has_definition ();
std::string identifier = fn.get_decl ().get_function_name ().as_string ();
resolved = TraitItemReference (identifier, is_optional,
@@ -103,6 +107,16 @@ TraitResolver::Lookup (HIR::TypePath &path)
return resolver.lookup_path (path);
}
+HIR::Trait *
+TraitResolver::ResolveHirItem (const HIR::TypePath &path)
+{
+ TraitResolver resolver;
+
+ HIR::Trait *lookup = nullptr;
+ bool ok = resolver.resolve_path_to_trait (path, &lookup);
+ return ok ? lookup : nullptr;
+}
+
TraitResolver::TraitResolver () : TypeCheckBase () {}
bool
@@ -110,8 +124,26 @@ TraitResolver::resolve_path_to_trait (const HIR::TypePath &path,
HIR::Trait **resolved) const
{
NodeId ref;
- if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
- &ref))
+ bool ok;
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ auto ref_opt = nr_ctx.lookup (path.get_mappings ().get_nodeid ());
+
+ if ((ok = ref_opt.has_value ()))
+ ref = *ref_opt;
+ }
+ else
+ {
+ auto path_nodeid = path.get_mappings ().get_nodeid ();
+ ok = resolver->lookup_resolved_type (path_nodeid, &ref)
+ || resolver->lookup_resolved_name (path_nodeid, &ref)
+ || resolver->lookup_resolved_macro (path_nodeid, &ref);
+ }
+
+ if (!ok)
{
rust_error_at (path.get_locus (), "Failed to resolve path to node-id");
return false;
@@ -125,7 +157,13 @@ TraitResolver::resolve_path_to_trait (const HIR::TypePath &path,
}
auto resolved_item = mappings.lookup_hir_item (hid.value ());
- rust_assert (resolved_item.has_value ());
+ if (!resolved_item.has_value ())
+ {
+ rust_error_at (path.get_locus (),
+ "Failed to resolve trait by looking up hir node");
+ return false;
+ }
+
if (resolved_item.value ()->get_item_kind () != HIR::Item::ItemKind::Trait)
{
rich_location r (line_table, path.get_locus ());
@@ -196,8 +234,9 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
// The one exception is the implicit Self type of a trait
bool apply_sized = !is_self;
auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get (),
+ = TypeResolveGenericParam::Resolve (*generic_param, true,
apply_sized);
+
context->insert_type (generic_param->get_mappings (), param_type);
substitutions.push_back (
TyTy::SubstitutionParamMapping (typaram, param_type));
@@ -235,7 +274,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
specified_bounds.push_back (self_hrtb);
// look for any
- std::vector<const TraitReference *> super_traits;
+ std::vector<TyTy::TypeBoundPredicate> super_traits;
if (trait_reference->has_type_param_bounds ())
{
for (auto &bound : trait_reference->get_type_param_bounds ())
@@ -248,17 +287,18 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
auto predicate = get_predicate_from_bound (
b->get_path (),
- nullptr /*this will setup a PLACEHOLDER for self*/);
+ tl::nullopt /*this will setup a PLACEHOLDER for self*/);
if (predicate.is_error ())
return &TraitReference::error_node ();
specified_bounds.push_back (predicate);
- super_traits.push_back (predicate.get ());
+ super_traits.push_back (predicate);
}
}
}
self->inherit_bounds (specified_bounds);
+ context->block_context ().enter (TypeCheckBlockContextItem (trait_reference));
std::vector<TraitItemReference> item_refs;
for (auto &item : trait_reference->get_trait_items ())
{
@@ -273,8 +313,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
item_refs.push_back (std::move (trait_item_ref));
}
- TraitReference trait_object (trait_reference, item_refs,
- std::move (super_traits),
+ TraitReference trait_object (trait_reference, item_refs, super_traits,
std::move (substitutions));
context->insert_trait_reference (
trait_reference->get_mappings ().get_defid (), std::move (trait_object));
@@ -288,6 +327,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
// resolve the blocks of functions etc because it can end up in a recursive
// loop of trying to resolve traits as required by the types
tref->on_resolved ();
+ context->block_context ().exit ();
return tref;
}
@@ -336,6 +376,7 @@ TraitItemReference::resolve_item (HIR::TraitItemType &type)
{
TyTy::BaseType *ty
= new TyTy::PlaceholderType (type.get_name ().as_string (),
+ type.get_mappings ().get_defid (),
type.get_mappings ().get_hirid ());
context->insert_type (type.get_mappings (), ty);
}
@@ -343,7 +384,26 @@ TraitItemReference::resolve_item (HIR::TraitItemType &type)
void
TraitItemReference::resolve_item (HIR::TraitItemConst &constant)
{
- // TODO
+ TyTy::BaseType *ty = nullptr;
+ if (constant.has_type ())
+ ty = TypeCheckType::Resolve (constant.get_type ());
+
+ TyTy::BaseType *expr = nullptr;
+ if (constant.has_expr ())
+ expr = TypeCheckExpr::Resolve (constant.get_expr ());
+
+ bool have_specified_ty = ty != nullptr && !ty->is<TyTy::ErrorType> ();
+ bool have_expr_ty = expr != nullptr && !expr->is<TyTy::ErrorType> ();
+
+ if (have_specified_ty && have_expr_ty)
+ {
+ coercion_site (constant.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (ty,
+ constant.get_type ().get_locus ()),
+ TyTy::TyWithLocation (expr,
+ constant.get_expr ().get_locus ()),
+ constant.get_locus ());
+ }
}
void
@@ -364,11 +424,11 @@ TraitItemReference::resolve_item (HIR::TraitItemFunc &func)
auto expected_ret_tyty = resolved_fn_type->get_return_type ();
context->push_return_type (TypeCheckContextItem (&func), expected_ret_tyty);
- auto block_expr_ty = TypeCheckExpr::Resolve (func.get_block_expr ().get ());
+ auto block_expr_ty = TypeCheckExpr::Resolve (func.get_block_expr ());
location_t fn_return_locus
= func.get_decl ().has_return_type ()
- ? func.get_decl ().get_return_type ()->get_locus ()
+ ? func.get_decl ().get_return_type ().get_locus ()
: func.get_locus ();
coercion_site (func.get_mappings ().get_hirid (),
@@ -452,7 +512,7 @@ AssociatedImplTrait::setup_raw_associated_types ()
TyTy::BaseType *
AssociatedImplTrait::setup_associated_types (
const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound,
- TyTy::SubstitutionArgumentMappings *args)
+ TyTy::SubstitutionArgumentMappings *args, bool infer)
{
// compute the constrained impl block generic arguments based on self and the
// higher ranked trait bound
@@ -512,7 +572,7 @@ AssociatedImplTrait::setup_associated_types (
std::vector<TyTy::SubstitutionArg> subst_args;
for (auto &p : substitutions)
{
- if (p.needs_substitution ())
+ if (p.needs_substitution () && infer)
{
TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
subst_args.push_back (
@@ -586,7 +646,7 @@ AssociatedImplTrait::setup_associated_types (
= unify_site_and (a->get_ref (), TyTy::TyWithLocation (a),
TyTy::TyWithLocation (b), impl_predicate.get_locus (),
true /*emit-errors*/, true /*commit-if-ok*/,
- false /*infer*/, true /*cleanup-on-fail*/);
+ true /*infer*/, true /*cleanup-on-fail*/);
rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
}
@@ -599,7 +659,7 @@ AssociatedImplTrait::setup_associated_types (
TyTy::TyWithLocation (impl_self_infer),
impl_predicate.get_locus (),
true /*emit-errors*/, true /*commit-if-ok*/,
- false /*infer*/, true /*cleanup-on-fail*/);
+ true /*infer*/, true /*cleanup-on-fail*/);
rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
TyTy::BaseType *self_result = result;
@@ -669,6 +729,12 @@ AssociatedImplTrait::reset_associated_types ()
trait->clear_associated_types ();
}
+location_t
+AssociatedImplTrait::get_locus () const
+{
+ return impl->get_locus ();
+}
+
Analysis::NodeMapping
TraitItemReference::get_parent_trait_mappings () const
{
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h b/gcc/rust/typecheck/rust-hir-trait-resolve.h
index 916abe6..b79fe17 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.h
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h
@@ -58,6 +58,8 @@ public:
static TraitReference *Lookup (HIR::TypePath &path);
+ static HIR::Trait *ResolveHirItem (const HIR::TypePath &path);
+
private:
TraitResolver ();
diff --git a/gcc/rust/typecheck/rust-hir-type-bounds.h b/gcc/rust/typecheck/rust-hir-type-bounds.h
index 7fdba1c..82333f1 100644
--- a/gcc/rust/typecheck/rust-hir-type-bounds.h
+++ b/gcc/rust/typecheck/rust-hir-type-bounds.h
@@ -38,6 +38,7 @@ public:
private:
void scan ();
void assemble_sized_builtin ();
+ void add_trait_bound (HIR::Trait *trait);
void assemble_builtin_candidate (LangItem::Kind item);
private:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 7e34cef..14b8ab8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -31,6 +31,36 @@ TypeCheckBase::TypeCheckBase ()
context (TypeCheckContext::get ())
{}
+void
+TypeCheckBase::ResolveGenericParams (
+ const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+ ABI abi)
+{
+ TypeCheckBase ctx;
+ ctx.resolve_generic_params (generic_params, substitutions, is_foreign, abi);
+}
+
+static void
+walk_types_to_constrain (std::set<HirId> &constrained_symbols,
+ const TyTy::SubstitutionArgumentMappings &constraints)
+{
+ for (const auto &c : constraints.get_mappings ())
+ {
+ const TyTy::BaseType *arg = c.get_tyty ();
+ if (arg != nullptr)
+ {
+ const TyTy::BaseType *p = arg->get_root ();
+ constrained_symbols.insert (p->get_ty_ref ());
+ if (p->has_substitutions_defined ())
+ {
+ walk_types_to_constrain (constrained_symbols,
+ p->get_subst_argument_mappings ());
+ }
+ }
+ }
+}
+
bool
TypeCheckBase::check_for_unconstrained (
const std::vector<TyTy::SubstitutionParamMapping> &params_to_constrain,
@@ -52,28 +82,14 @@ TypeCheckBase::check_for_unconstrained (
HirId ref = p.get_param_ty ()->get_ref ();
symbols_to_constrain.insert (ref);
symbol_to_location.insert ({ref, p.get_param_locus ()});
+
+ rust_debug_loc (p.get_param_locus (), "XX constrain THIS");
}
// set up the set of constrained symbols
std::set<HirId> constrained_symbols;
- for (const auto &c : constraint_a.get_mappings ())
- {
- const TyTy::BaseType *arg = c.get_tyty ();
- if (arg != nullptr)
- {
- const TyTy::BaseType *p = arg->get_root ();
- constrained_symbols.insert (p->get_ty_ref ());
- }
- }
- for (const auto &c : constraint_b.get_mappings ())
- {
- const TyTy::BaseType *arg = c.get_tyty ();
- if (arg != nullptr)
- {
- const TyTy::BaseType *p = arg->get_root ();
- constrained_symbols.insert (p->get_ty_ref ());
- }
- }
+ walk_types_to_constrain (constrained_symbols, constraint_a);
+ walk_types_to_constrain (constrained_symbols, constraint_b);
const auto root = reference->get_root ();
if (root->get_kind () == TyTy::TypeKind::PARAM)
@@ -292,9 +308,20 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
repr.pack = 0;
repr.align = 0;
+ // Default repr for enums is isize, but we now check for other repr in the
+ // attributes.
+ bool ok = context->lookup_builtin ("isize", &repr.repr);
+ rust_assert (ok);
+
for (const auto &attr : attrs)
{
bool is_repr = attr.get_path ().as_string () == Values::Attributes::REPR;
+ if (is_repr && !attr.has_attr_input ())
+ {
+ rust_error_at (attr.get_locus (), "malformed %qs attribute", "repr");
+ continue;
+ }
+
if (is_repr)
{
const AST::AttrInput &input = attr.get_attr_input ();
@@ -305,21 +332,51 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
AST::AttrInputMetaItemContainer *meta_items
= option.parse_to_meta_item ();
- const std::string inline_option
- = meta_items->get_items ().at (0)->as_string ();
+ if (meta_items == nullptr)
+ {
+ rust_error_at (attr.get_locus (), "malformed %qs attribute",
+ "repr");
+ continue;
+ }
+
+ auto &items = meta_items->get_items ();
+ if (items.size () == 0)
+ {
+ // nothing to do with this its empty
+ delete meta_items;
+ continue;
+ }
+
+ const std::string inline_option = items.at (0)->as_string ();
// TODO: it would probably be better to make the MetaItems more aware
// of constructs with nesting like #[repr(packed(2))] rather than
// manually parsing the string "packed(2)" here.
size_t oparen = inline_option.find ('(', 0);
- bool is_pack = false, is_align = false;
+ bool is_pack = false;
+ bool is_align = false;
+ bool is_c = false;
+ bool is_integer = false;
unsigned char value = 1;
if (oparen == std::string::npos)
{
is_pack = inline_option.compare ("packed") == 0;
is_align = inline_option.compare ("align") == 0;
+ is_c = inline_option.compare ("C") == 0;
+ is_integer = (inline_option.compare ("isize") == 0
+ || inline_option.compare ("i8") == 0
+ || inline_option.compare ("i16") == 0
+ || inline_option.compare ("i32") == 0
+ || inline_option.compare ("i64") == 0
+ || inline_option.compare ("i128") == 0
+ || inline_option.compare ("usize") == 0
+ || inline_option.compare ("u8") == 0
+ || inline_option.compare ("u16") == 0
+ || inline_option.compare ("u32") == 0
+ || inline_option.compare ("u64") == 0
+ || inline_option.compare ("u128") == 0);
}
else
@@ -339,9 +396,30 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
}
if (is_pack)
- repr.pack = value;
+ {
+ repr.repr_kind = TyTy::ADTType::ReprKind::PACKED;
+ repr.pack = value;
+ }
else if (is_align)
- repr.align = value;
+ {
+ repr.repr_kind = TyTy::ADTType::ReprKind::ALIGN;
+ repr.align = value;
+ }
+ else if (is_c)
+ {
+ repr.repr_kind = TyTy::ADTType::ReprKind::C;
+ }
+ else if (is_integer)
+ {
+ repr.repr_kind = TyTy::ADTType::ReprKind::INT;
+ bool ok = context->lookup_builtin (inline_option, &repr.repr);
+ if (!ok)
+ {
+ rust_error_at (attr.get_locus (), "Invalid repr type");
+ }
+ }
+
+ delete meta_items;
// Multiple repr options must be specified with e.g. #[repr(C,
// packed(2))].
@@ -355,7 +433,8 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
void
TypeCheckBase::resolve_generic_params (
const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
- std::vector<TyTy::SubstitutionParamMapping> &substitutions)
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+ ABI abi)
{
for (auto &generic_param : generic_params)
{
@@ -365,31 +444,33 @@ TypeCheckBase::resolve_generic_params (
auto lifetime_param
= static_cast<HIR::LifetimeParam &> (*generic_param);
auto lifetime = lifetime_param.get_lifetime ();
- rust_assert (lifetime.get_lifetime_type ()
- == AST::Lifetime::LifetimeType::NAMED);
context->get_lifetime_resolver ().insert_mapping (
context->intern_lifetime (lifetime));
}
-
break;
case HIR::GenericParam::GenericKind::CONST: {
- auto param
- = static_cast<HIR::ConstGenericParam *> (generic_param.get ());
- auto specified_type
- = TypeCheckType::Resolve (param->get_type ().get ());
+ if (is_foreign && abi != Rust::ABI::INTRINSIC)
+ {
+ rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
+ "foreign items may not have const parameters");
+ }
+
+ auto &param
+ = static_cast<HIR::ConstGenericParam &> (*generic_param);
+ auto specified_type = TypeCheckType::Resolve (param.get_type ());
- if (param->has_default_expression ())
+ if (param.has_default_expression ())
{
- auto expr_type = TypeCheckExpr::Resolve (
- param->get_default_expression ().get ());
-
- coercion_site (
- param->get_mappings ().get_hirid (),
- TyTy::TyWithLocation (specified_type),
- TyTy::TyWithLocation (
- expr_type, param->get_default_expression ()->get_locus ()),
- param->get_locus ());
+ auto expr_type
+ = TypeCheckExpr::Resolve (param.get_default_expression ());
+
+ coercion_site (param.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (specified_type),
+ TyTy::TyWithLocation (
+ expr_type,
+ param.get_default_expression ().get_locus ()),
+ param.get_locus ());
}
context->insert_type (generic_param->get_mappings (),
@@ -398,16 +479,31 @@ TypeCheckBase::resolve_generic_params (
break;
case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get ());
+ if (is_foreign && abi != Rust::ABI::INTRINSIC)
+ {
+ rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
+ "foreign items may not have type parameters");
+ }
+
+ auto param_type = TypeResolveGenericParam::Resolve (
+ *generic_param, false /*resolve_trait_bounds*/);
context->insert_type (generic_param->get_mappings (), param_type);
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
+ auto &param = static_cast<HIR::TypeParam &> (*generic_param);
+ TyTy::SubstitutionParamMapping p (param, param_type);
+ substitutions.push_back (p);
}
break;
}
}
+
+ // now walk them to setup any specified type param bounds
+ for (auto &subst : substitutions)
+ {
+ auto pty = subst.get_param_ty ();
+ TypeResolveGenericParam::ApplyAnyTraitBounds (subst.get_generic_param (),
+ pty);
+ }
}
TyTy::TypeBoundPredicate
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index 0bc2905..580082a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -32,15 +32,21 @@ class TypeCheckBase
public:
virtual ~TypeCheckBase () {}
+ static void ResolveGenericParams (
+ const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+ ABI abi);
+
protected:
TypeCheckBase ();
TraitReference *resolve_trait_path (HIR::TypePath &);
- TyTy::TypeBoundPredicate
- get_predicate_from_bound (HIR::TypePath &path, HIR::Type *associated_self,
- BoundPolarity polarity
- = BoundPolarity::RegularBound);
+ TyTy::TypeBoundPredicate get_predicate_from_bound (
+ HIR::TypePath &path,
+ tl::optional<std::reference_wrapper<HIR::Type>> associated_self,
+ BoundPolarity polarity = BoundPolarity::RegularBound,
+ bool is_qualified_type = false);
bool check_for_unconstrained (
const std::vector<TyTy::SubstitutionParamMapping> &params_to_constrain,
@@ -55,8 +61,9 @@ protected:
location_t locus);
void resolve_generic_params (
- const std::vector<std::unique_ptr<HIR::GenericParam> > &generic_params,
- std::vector<TyTy::SubstitutionParamMapping> &substitutions);
+ const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions,
+ bool is_foreign = false, ABI abi = ABI::RUST);
TyTy::TypeBoundPredicate get_marker_predicate (LangItem::Kind item_type,
location_t locus);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
index a9154c6..c80a12f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
@@ -16,6 +16,7 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "rust-hir-expr.h"
#include "rust-hir-type-check-type.h"
#include "rust-hir-type-check-expr.h"
#include "rust-hir-type-check-enumitem.h"
@@ -29,25 +30,25 @@ namespace Rust {
namespace Resolver {
TyTy::VariantDef *
-TypeCheckEnumItem::Resolve (HIR::EnumItem *item, int64_t last_discriminant)
+TypeCheckEnumItem::Resolve (HIR::EnumItem &item, int64_t last_discriminant)
{
TypeCheckEnumItem resolver (last_discriminant);
- switch (item->get_enum_item_kind ())
+ switch (item.get_enum_item_kind ())
{
case HIR::EnumItem::EnumItemKind::Named:
- resolver.visit (static_cast<HIR::EnumItem &> (*item));
+ resolver.visit (static_cast<HIR::EnumItem &> (item));
break;
case HIR::EnumItem::EnumItemKind::Tuple:
- resolver.visit (static_cast<HIR::EnumItemTuple &> (*item));
+ resolver.visit (static_cast<HIR::EnumItemTuple &> (item));
break;
case HIR::EnumItem::EnumItemKind::Struct:
- resolver.visit (static_cast<HIR::EnumItemStruct &> (*item));
+ resolver.visit (static_cast<HIR::EnumItemStruct &> (item));
break;
case HIR::EnumItem::EnumItemKind::Discriminant:
- resolver.visit (static_cast<HIR::EnumItemDiscriminant &> (*item));
+ resolver.visit (static_cast<HIR::EnumItemDiscriminant &> (item));
break;
}
return resolver.variant;
@@ -68,11 +69,10 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
mappings.get_next_hir_id (
item.get_mappings ().get_crate_num ()),
item.get_mappings ().get_local_defid ());
- HIR::LiteralExpr *discim_expr
- = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
- HIR::Literal::LitType::INT,
- PrimitiveCoreType::CORETYPE_I64, item.get_locus (),
- {});
+ auto discim_expr = std::make_unique<HIR::LiteralExpr> (
+ HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
+ HIR::Literal::LitType::INT,
+ PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
TyTy::BaseType *isize = nullptr;
bool ok = context->lookup_builtin ("isize", &isize);
@@ -83,7 +83,7 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
@@ -101,7 +101,7 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
item.get_mappings ().get_defid (),
item.get_identifier ().as_string (), ident,
- discim_expr);
+ std::move (discim_expr));
}
void
@@ -111,13 +111,13 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
rust_error_at (item.get_locus (), "discriminant too big");
auto &discriminant = item.get_discriminant_expression ();
- auto capacity_type = TypeCheckExpr::Resolve (discriminant.get ());
+ auto capacity_type = TypeCheckExpr::Resolve (discriminant);
if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
return;
TyTy::ISizeType *expected_ty
- = new TyTy::ISizeType (discriminant->get_mappings ().get_hirid ());
- context->insert_type (discriminant->get_mappings (), expected_ty);
+ = new TyTy::ISizeType (discriminant.get_mappings ().get_hirid ());
+ context->insert_type (discriminant.get_mappings (), expected_ty);
unify_site (item.get_mappings ().get_hirid (),
TyTy::TyWithLocation (expected_ty),
@@ -127,7 +127,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
@@ -142,10 +142,11 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
rust_assert (canonical_path.has_value ());
RustIdent ident{*canonical_path, item.get_locus ()};
- variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
- item.get_mappings ().get_defid (),
- item.get_identifier ().as_string (), ident,
- item.get_discriminant_expression ().get ());
+ variant
+ = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+ item.get_mappings ().get_defid (),
+ item.get_identifier ().as_string (), ident,
+ item.get_discriminant_expression ().clone_expr ());
}
void
@@ -159,7 +160,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
for (auto &field : item.get_tuple_fields ())
{
TyTy::BaseType *field_type
- = TypeCheckType::Resolve (field.get_field_type ().get ());
+ = TypeCheckType::Resolve (field.get_field_type ());
TyTy::StructFieldType *ty_field
= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
std::to_string (idx), field_type,
@@ -174,11 +175,10 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
mappings.get_next_hir_id (
item.get_mappings ().get_crate_num ()),
item.get_mappings ().get_local_defid ());
- HIR::LiteralExpr *discim_expr
- = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
- HIR::Literal::LitType::INT,
- PrimitiveCoreType::CORETYPE_I64, item.get_locus (),
- {});
+ auto discim_expr = std::make_unique<HIR::LiteralExpr> (
+ HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
+ HIR::Literal::LitType::INT,
+ PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
TyTy::BaseType *isize = nullptr;
bool ok = context->lookup_builtin ("isize", &isize);
@@ -189,7 +189,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
@@ -208,7 +208,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
item.get_mappings ().get_defid (),
item.get_identifier ().as_string (), ident,
TyTy::VariantDef::VariantType::TUPLE,
- discim_expr, fields);
+ std::move (discim_expr), fields);
}
void
@@ -221,7 +221,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
for (auto &field : item.get_struct_fields ())
{
TyTy::BaseType *field_type
- = TypeCheckType::Resolve (field.get_field_type ().get ());
+ = TypeCheckType::Resolve (field.get_field_type ());
TyTy::StructFieldType *ty_field
= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
field.get_field_name ().as_string (),
@@ -235,11 +235,10 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
mappings.get_next_hir_id (
item.get_mappings ().get_crate_num ()),
item.get_mappings ().get_local_defid ());
- HIR::LiteralExpr *discrim_expr
- = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
- HIR::Literal::LitType::INT,
- PrimitiveCoreType::CORETYPE_I64, item.get_locus (),
- {});
+ auto discrim_expr = std::make_unique<HIR::LiteralExpr> (
+ HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
+ HIR::Literal::LitType::INT,
+ PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
TyTy::BaseType *isize = nullptr;
bool ok = context->lookup_builtin ("isize", &isize);
@@ -250,7 +249,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
@@ -269,7 +268,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
item.get_mappings ().get_defid (),
item.get_identifier ().as_string (), ident,
TyTy::VariantDef::VariantType::STRUCT,
- discrim_expr, fields);
+ std::move (discrim_expr), fields);
}
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
index bccffe7..6b01a49 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
@@ -28,7 +28,7 @@ namespace Resolver {
class TypeCheckEnumItem : public TypeCheckBase
{
public:
- static TyTy::VariantDef *Resolve (HIR::EnumItem *item,
+ static TyTy::VariantDef *Resolve (HIR::EnumItem &item,
int64_t last_discriminant);
protected:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index ba22eaf..cbf529a7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -16,6 +16,9 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "optional.h"
+#include "rust-hir-expr.h"
+#include "rust-system.h"
#include "rust-tyty-call.h"
#include "rust-hir-type-check-struct-field.h"
#include "rust-hir-path-probe.h"
@@ -27,6 +30,10 @@
#include "rust-hir-type-check-stmt.h"
#include "rust-hir-type-check-item.h"
#include "rust-type-util.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
namespace Rust {
namespace Resolver {
@@ -36,17 +43,17 @@ TypeCheckExpr::TypeCheckExpr () : TypeCheckBase (), infered (nullptr) {}
// Perform type checking on expr. Also runs type unification algorithm.
// Returns the unified type of expr
TyTy::BaseType *
-TypeCheckExpr::Resolve (HIR::Expr *expr)
+TypeCheckExpr::Resolve (HIR::Expr &expr)
{
TypeCheckExpr resolver;
- expr->accept_vis (resolver);
+ expr.accept_vis (resolver);
if (resolver.infered == nullptr)
- return new TyTy::ErrorType (expr->get_mappings ().get_hirid ());
+ return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
- auto ref = expr->get_mappings ().get_hirid ();
+ auto ref = expr.get_mappings ().get_hirid ();
resolver.infered->set_ref (ref);
- resolver.context->insert_type (expr->get_mappings (), resolver.infered);
+ resolver.context->insert_type (expr.get_mappings (), resolver.infered);
return resolver.infered;
}
@@ -54,10 +61,10 @@ TypeCheckExpr::Resolve (HIR::Expr *expr)
void
TypeCheckExpr::visit (HIR::TupleIndexExpr &expr)
{
- auto resolved = TypeCheckExpr::Resolve (expr.get_tuple_expr ().get ());
+ auto resolved = TypeCheckExpr::Resolve (expr.get_tuple_expr ());
if (resolved->get_kind () == TyTy::TypeKind::ERROR)
{
- rust_error_at (expr.get_tuple_expr ()->get_locus (),
+ rust_error_at (expr.get_tuple_expr ().get_locus (),
"failed to resolve TupleIndexExpr receiver");
return;
}
@@ -73,7 +80,7 @@ TypeCheckExpr::visit (HIR::TupleIndexExpr &expr)
|| resolved->get_kind () == TyTy::TypeKind::TUPLE;
if (!is_valid_type)
{
- rust_error_at (expr.get_tuple_expr ()->get_locus (),
+ rust_error_at (expr.get_tuple_expr ().get_locus (),
"Expected Tuple or ADT got: %s",
resolved->as_string ().c_str ());
return;
@@ -131,19 +138,14 @@ TypeCheckExpr::visit (HIR::TupleExpr &expr)
{
if (expr.is_unit ())
{
- auto unit_node_id = resolver->get_unit_type_node_id ();
- if (!context->lookup_builtin (unit_node_id, &infered))
- {
- rust_error_at (expr.get_locus (),
- "failed to lookup builtin unit type");
- }
+ infered = TyTy::TupleType::get_unit_type ();
return;
}
std::vector<TyTy::TyVar> fields;
for (auto &elem : expr.get_tuple_elems ())
{
- auto field_ty = TypeCheckExpr::Resolve (elem.get ());
+ auto field_ty = TypeCheckExpr::Resolve (*elem);
fields.push_back (TyTy::TyVar (field_ty->get_ref ()));
}
infered = new TyTy::TupleType (expr.get_mappings ().get_hirid (),
@@ -163,12 +165,12 @@ TypeCheckExpr::visit (HIR::ReturnExpr &expr)
auto fn_return_tyty = context->peek_return_type ();
location_t expr_locus = expr.has_return_expr ()
- ? expr.get_expr ()->get_locus ()
+ ? expr.get_expr ().get_locus ()
: expr.get_locus ();
- TyTy::BaseType *expr_ty
- = expr.has_return_expr ()
- ? TypeCheckExpr::Resolve (expr.get_expr ().get ())
- : TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+
+ TyTy::BaseType *expr_ty = expr.has_return_expr ()
+ ? TypeCheckExpr::Resolve (expr.get_expr ())
+ : TyTy::TupleType::get_unit_type ();
coercion_site (expr.get_mappings ().get_hirid (),
TyTy::TyWithLocation (fn_return_tyty),
@@ -180,8 +182,7 @@ TypeCheckExpr::visit (HIR::ReturnExpr &expr)
void
TypeCheckExpr::visit (HIR::CallExpr &expr)
{
- TyTy::BaseType *function_tyty
- = TypeCheckExpr::Resolve (expr.get_fnexpr ().get ());
+ TyTy::BaseType *function_tyty = TypeCheckExpr::Resolve (expr.get_fnexpr ());
rust_debug_loc (expr.get_locus (), "resolved_call_expr to: {%s}",
function_tyty->get_name ().c_str ());
@@ -195,7 +196,7 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
// lookup variant id
HirId variant_id;
bool ok = context->lookup_variant_definition (
- expr.get_fnexpr ()->get_mappings ().get_hirid (), &variant_id);
+ expr.get_fnexpr ().get_mappings ().get_hirid (), &variant_id);
if (!ok)
{
@@ -209,14 +210,13 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
ok = adt->lookup_variant_by_id (variant_id, &lookup_variant);
rust_assert (ok);
- variant = *lookup_variant;
+ variant = std::move (*lookup_variant->clone ());
}
else
{
rust_assert (adt->number_of_variants () == 1);
- variant = *adt->get_variants ().at (0);
+ variant = std::move (*adt->get_variants ().at (0)->clone ());
}
-
infered
= TyTy::TypeCheckCallExpr::go (function_tyty, expr, variant, context);
return;
@@ -227,45 +227,96 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
if (resolved_fn_trait_call)
return;
- bool valid_tyty = function_tyty->get_kind () == TyTy::TypeKind::FNDEF
- || function_tyty->get_kind () == TyTy::TypeKind::FNPTR;
+ bool valid_tyty
+ = function_tyty->is<TyTy::FnType> () || function_tyty->is<TyTy::FnPtr> ();
if (!valid_tyty)
{
- rust_error_at (expr.get_locus (),
- "Failed to resolve expression of function call");
+ bool emit_error = !function_tyty->is<TyTy::ErrorType> ();
+ if (emit_error)
+ {
+ rich_location r (line_table, expr.get_locus ());
+ rust_error_at (r, ErrorCode::E0618, "expected function, found %<%s%>",
+ function_tyty->get_name ().c_str ());
+ }
return;
}
infered = TyTy::TypeCheckCallExpr::go (function_tyty, expr, variant, context);
+
+ auto discriminant_type_lookup
+ = mappings.lookup_lang_item (LangItem::Kind::DISCRIMINANT_TYPE);
+ if (infered->is<TyTy::PlaceholderType> () && discriminant_type_lookup)
+ {
+ const auto &p = *static_cast<const TyTy::PlaceholderType *> (infered);
+ if (p.get_def_id () == discriminant_type_lookup.value ())
+ {
+ // this is a special case where this will actually return the repr of
+ // the enum. We dont currently support repr on enum yet to change the
+ // discriminant type but the default is always isize. We need to
+ // assert this is a generic function with one param
+ //
+ // fn<BookFormat> (v & T=BookFormat{Paperback) -> <placeholder:>
+ //
+ // note the default is isize
+
+ bool ok = context->lookup_builtin ("isize", &infered);
+ rust_assert (ok);
+
+ rust_assert (function_tyty->is<TyTy::FnType> ());
+ auto &fn = *static_cast<TyTy::FnType *> (function_tyty);
+ rust_assert (fn.has_substitutions ());
+ rust_assert (fn.get_num_type_params () == 1);
+ auto &mapping = fn.get_substs ().at (0);
+ auto param_ty = mapping.get_param_ty ();
+
+ if (!param_ty->can_resolve ())
+ {
+ // this could be a valid error need to test more weird cases and
+ // look at rustc
+ rust_internal_error_at (expr.get_locus (),
+ "something wrong computing return type");
+ return;
+ }
+
+ auto resolved = param_ty->resolve ();
+ bool is_adt = resolved->is<TyTy::ADTType> ();
+ if (is_adt)
+ {
+ const auto &adt = *static_cast<TyTy::ADTType *> (resolved);
+ infered = adt.get_repr_options ().repr;
+ rust_assert (infered != nullptr);
+ }
+ }
+ }
}
void
TypeCheckExpr::visit (HIR::AssignmentExpr &expr)
{
- infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+ infered = TyTy::TupleType::get_unit_type ();
- auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
- auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+ auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+ auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
coercion_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
- TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+ TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+ TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
expr.get_locus ());
}
void
TypeCheckExpr::visit (HIR::CompoundAssignmentExpr &expr)
{
- infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+ infered = TyTy::TupleType::get_unit_type ();
- auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
- auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+ auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+ auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
// we dont care about the result of the unify from a compound assignment
// since this is a unit-type expr
coercion_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
- TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+ TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+ TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
expr.get_locus ());
auto lang_item_type
@@ -298,8 +349,8 @@ TypeCheckExpr::visit (HIR::LiteralExpr &expr)
void
TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
{
- auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
- auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+ auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+ auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
auto lang_item_type = LangItem::OperatorToLangItem (expr.get_expr_type ());
bool operator_overloaded
@@ -323,8 +374,8 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
{
case ArithmeticOrLogicalOperator::LEFT_SHIFT:
case ArithmeticOrLogicalOperator::RIGHT_SHIFT: {
- TyTy::TyWithLocation from (rhs, expr.get_rhs ()->get_locus ());
- TyTy::TyWithLocation to (lhs, expr.get_lhs ()->get_locus ());
+ 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,
expr.get_locus ());
}
@@ -333,8 +384,8 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
default: {
infered = unify_site (
expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
- TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+ TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+ TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
expr.get_locus ());
}
break;
@@ -344,12 +395,27 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
void
TypeCheckExpr::visit (HIR::ComparisonExpr &expr)
{
- auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
- auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+ auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+ auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
+
+ auto borrowed_rhs
+ = new TyTy::ReferenceType (mappings.get_next_hir_id (),
+ TyTy::TyVar (rhs->get_ref ()), Mutability::Imm);
+ context->insert_implicit_type (borrowed_rhs->get_ref (), borrowed_rhs);
+
+ auto seg_name = LangItem::ComparisonToSegment (expr.get_expr_type ());
+ auto segment = HIR::PathIdentSegment (seg_name);
+ auto lang_item_type = LangItem::ComparisonToLangItem (expr.get_expr_type ());
+
+ bool operator_overloaded
+ = resolve_operator_overload (lang_item_type, expr, lhs, borrowed_rhs,
+ segment);
+ if (operator_overloaded)
+ return;
unify_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
- TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+ TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+ TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
expr.get_locus ());
bool ok = context->lookup_builtin ("bool", &infered);
@@ -359,8 +425,8 @@ TypeCheckExpr::visit (HIR::ComparisonExpr &expr)
void
TypeCheckExpr::visit (HIR::LazyBooleanExpr &expr)
{
- auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
- auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
+ auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+ auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
// we expect the lhs and rhs must be bools at this point
TyTy::BaseType *boolean_node = nullptr;
@@ -370,27 +436,27 @@ TypeCheckExpr::visit (HIR::LazyBooleanExpr &expr)
// verify the lhs and rhs before unifying together
lhs = unify_site (expr.get_mappings ().get_hirid (),
TyTy::TyWithLocation (boolean_node,
- expr.get_lhs ()->get_locus ()),
- TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
+ expr.get_lhs ().get_locus ()),
+ TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
expr.get_locus ());
rhs = unify_site (expr.get_mappings ().get_hirid (),
TyTy::TyWithLocation (boolean_node,
- expr.get_rhs ()->get_locus ()),
- TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+ expr.get_rhs ().get_locus ()),
+ TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
expr.get_locus ());
infered
= unify_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
- TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
+ TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+ TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
expr.get_locus ());
}
void
TypeCheckExpr::visit (HIR::NegationExpr &expr)
{
- auto negated_expr_ty = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+ auto negated_expr_ty = TypeCheckExpr::Resolve (expr.get_expr ());
// check for operator overload
auto lang_item_type
@@ -455,17 +521,25 @@ TypeCheckExpr::visit (HIR::IfExpr &expr)
bool ok = context->lookup_builtin ("bool", &bool_ty);
rust_assert (ok);
- TyTy::BaseType *cond_type
- = TypeCheckExpr::Resolve (expr.get_if_condition ().get ());
+ TyTy::BaseType *cond_type = TypeCheckExpr::Resolve (expr.get_if_condition ());
unify_site (expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (bool_ty),
TyTy::TyWithLocation (cond_type,
- expr.get_if_condition ()->get_locus ()),
+ expr.get_if_condition ().get_locus ()),
expr.get_locus ());
- TypeCheckExpr::Resolve (expr.get_if_block ().get ());
+ TyTy::BaseType *block_type = TypeCheckExpr::Resolve (expr.get_if_block ());
- infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+ TyTy::BaseType *unit_ty = nullptr;
+ ok = context->lookup_builtin ("()", &unit_ty);
+ rust_assert (ok);
+
+ infered
+ = coercion_site (expr.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (unit_ty),
+ TyTy::TyWithLocation (block_type,
+ expr.get_if_block ().get_locus ()),
+ expr.get_locus ());
}
void
@@ -475,17 +549,15 @@ TypeCheckExpr::visit (HIR::IfExprConseqElse &expr)
bool ok = context->lookup_builtin ("bool", &bool_ty);
rust_assert (ok);
- TyTy::BaseType *cond_type
- = TypeCheckExpr::Resolve (expr.get_if_condition ().get ());
+ TyTy::BaseType *cond_type = TypeCheckExpr::Resolve (expr.get_if_condition ());
unify_site (expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (bool_ty),
TyTy::TyWithLocation (cond_type,
- expr.get_if_condition ()->get_locus ()),
+ expr.get_if_condition ().get_locus ()),
expr.get_locus ());
- auto if_blk_resolved = TypeCheckExpr::Resolve (expr.get_if_block ().get ());
- auto else_blk_resolved
- = TypeCheckExpr::Resolve (expr.get_else_block ().get ());
+ auto if_blk_resolved = TypeCheckExpr::Resolve (expr.get_if_block ());
+ auto else_blk_resolved = TypeCheckExpr::Resolve (expr.get_else_block ());
if (if_blk_resolved->get_kind () == TyTy::NEVER)
infered = else_blk_resolved;
@@ -493,81 +565,20 @@ TypeCheckExpr::visit (HIR::IfExprConseqElse &expr)
infered = if_blk_resolved;
else
{
- infered = unify_site (
- expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (if_blk_resolved,
- expr.get_if_block ()->get_locus ()),
- TyTy::TyWithLocation (else_blk_resolved,
- expr.get_else_block ()->get_locus ()),
- expr.get_locus ());
- }
-}
-
-void
-TypeCheckExpr::visit (HIR::IfLetExpr &expr)
-{
- // this needs to perform a least upper bound coercion on the blocks and then
- // unify the scruintee and arms
- TyTy::BaseType *scrutinee_tyty
- = TypeCheckExpr::Resolve (expr.get_scrutinee_expr ().get ());
-
- for (auto &pattern : expr.get_patterns ())
- {
- TyTy::BaseType *kase_arm_ty
- = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty);
-
- unify_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (scrutinee_tyty),
- TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()),
- expr.get_locus ());
- }
-
- TypeCheckExpr::Resolve (expr.get_if_block ().get ());
-
- infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
-}
-
-void
-TypeCheckExpr::visit (HIR::IfLetExprConseqElse &expr)
-{
- TyTy::BaseType *scrutinee_tyty
- = TypeCheckExpr::Resolve (expr.get_scrutinee_expr ().get ());
-
- for (auto &pattern : expr.get_patterns ())
- {
- TyTy::BaseType *kase_arm_ty
- = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty);
-
- unify_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (scrutinee_tyty),
- TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()),
- expr.get_locus ());
- }
-
- auto if_blk_resolved = TypeCheckExpr::Resolve (expr.get_if_block ().get ());
- auto else_blk_resolved
- = TypeCheckExpr::Resolve (expr.get_else_block ().get ());
-
- if (if_blk_resolved->get_kind () == TyTy::NEVER)
- infered = else_blk_resolved;
- else if (else_blk_resolved->get_kind () == TyTy::NEVER)
- infered = if_blk_resolved;
- else
- {
- infered = unify_site (
- expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (if_blk_resolved,
- expr.get_if_block ()->get_locus ()),
- TyTy::TyWithLocation (else_blk_resolved,
- expr.get_else_block ()->get_locus ()),
- expr.get_locus ());
+ infered
+ = unify_site (expr.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (if_blk_resolved,
+ expr.get_if_block ().get_locus ()),
+ TyTy::TyWithLocation (
+ else_blk_resolved, expr.get_else_block ().get_locus ()),
+ expr.get_locus ());
}
}
void
TypeCheckExpr::visit (HIR::UnsafeBlockExpr &expr)
{
- infered = TypeCheckExpr::Resolve (expr.get_block_expr ().get ());
+ infered = TypeCheckExpr::Resolve (expr.get_block_expr ());
}
void
@@ -582,7 +593,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
if (!s->is_item ())
continue;
- TypeCheckStmt::Resolve (s.get ());
+ TypeCheckStmt::Resolve (*s);
}
for (auto &s : expr.get_statements ())
@@ -590,7 +601,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
if (s->is_item ())
continue;
- auto resolved = TypeCheckStmt::Resolve (s.get ());
+ auto resolved = TypeCheckStmt::Resolve (*s);
if (resolved == nullptr)
{
rust_error_at (s->get_locus (), "failure to resolve type");
@@ -599,8 +610,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
if (s->is_unit_check_needed () && !resolved->is_unit ())
{
- auto unit
- = TyTy::TupleType::get_unit_type (s->get_mappings ().get_hirid ());
+ auto unit = TyTy::TupleType::get_unit_type ();
resolved
= unify_site (s->get_mappings ().get_hirid (),
TyTy::TyWithLocation (unit),
@@ -609,10 +619,9 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
}
if (expr.has_expr ())
- infered = TypeCheckExpr::Resolve (expr.get_final_expr ().get ())->clone ();
+ infered = TypeCheckExpr::Resolve (expr.get_final_expr ())->clone ();
else if (expr.is_tail_reachable ())
- infered
- = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+ infered = TyTy::TupleType::get_unit_type ();
else if (expr.has_label ())
{
TyTy::BaseType *loop_context_type = context->pop_loop_context ();
@@ -624,8 +633,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
!= TyTy::InferType::GENERAL));
infered = loop_context_type_infered ? loop_context_type
- : TyTy::TupleType::get_unit_type (
- expr.get_mappings ().get_hirid ());
+ : TyTy::TupleType::get_unit_type ();
}
else
{
@@ -665,14 +673,13 @@ TypeCheckExpr::visit (HIR::RangeFromToExpr &expr)
// resolve the range expressions and these types must unify then we use that
// type to substitute into the ADT
- TyTy::BaseType *from_ty
- = TypeCheckExpr::Resolve (expr.get_from_expr ().get ());
- TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ());
+ TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_from_expr ());
+ TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ());
TyTy::BaseType *unified = unify_site (
expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (from_ty, expr.get_from_expr ()->get_locus ()),
- TyTy::TyWithLocation (to_ty, expr.get_to_expr ()->get_locus ()),
+ TyTy::TyWithLocation (from_ty, expr.get_from_expr ().get_locus ()),
+ TyTy::TyWithLocation (to_ty, expr.get_to_expr ().get_locus ()),
expr.get_locus ());
// substitute it in
@@ -717,8 +724,7 @@ TypeCheckExpr::visit (HIR::RangeFromExpr &expr)
// resolve the range expressions and these types must unify then we use that
// type to substitute into the ADT
- TyTy::BaseType *from_ty
- = TypeCheckExpr::Resolve (expr.get_from_expr ().get ());
+ TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_from_expr ());
// substitute it in
std::vector<TyTy::SubstitutionArg> subst_mappings;
@@ -762,7 +768,7 @@ TypeCheckExpr::visit (HIR::RangeToExpr &expr)
// resolve the range expressions and these types must unify then we use that
// type to substitute into the ADT
- TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ());
+ TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_to_expr ());
// substitute it in
std::vector<TyTy::SubstitutionArg> subst_mappings;
@@ -786,38 +792,38 @@ typecheck_inline_asm_operand (HIR::InlineAsm &expr)
{
case RegisterType::In: {
auto in = operand.get_in ();
- TypeCheckExpr::Resolve (in.expr.get ());
+ TypeCheckExpr::Resolve (*in.expr);
break;
}
case RegisterType::Out: {
auto out = operand.get_out ();
- TypeCheckExpr::Resolve (out.expr.get ());
+ TypeCheckExpr::Resolve (*out.expr);
break;
}
case RegisterType::InOut: {
auto in_out = operand.get_in_out ();
- TypeCheckExpr::Resolve (in_out.expr.get ());
+ TypeCheckExpr::Resolve (*in_out.expr);
break;
}
case RegisterType::SplitInOut: {
auto split_in_out = operand.get_split_in_out ();
- TypeCheckExpr::Resolve (split_in_out.in_expr.get ());
- TypeCheckExpr::Resolve (split_in_out.out_expr.get ());
+ TypeCheckExpr::Resolve (*split_in_out.in_expr);
+ TypeCheckExpr::Resolve (*split_in_out.out_expr);
break;
}
case RegisterType::Const: {
auto anon_const = operand.get_const ().anon_const;
- TypeCheckExpr::Resolve (anon_const.expr.get ());
+ TypeCheckExpr::Resolve (*anon_const.expr);
break;
}
case RegisterType::Sym: {
auto sym = operand.get_sym ();
- TypeCheckExpr::Resolve (sym.expr.get ());
+ TypeCheckExpr::Resolve (*sym.expr);
break;
}
case RegisterType::Label: {
auto label = operand.get_label ();
- TypeCheckExpr::Resolve (label.expr.get ());
+ TypeCheckExpr::Resolve (*label.expr);
break;
}
}
@@ -834,8 +840,20 @@ TypeCheckExpr::visit (HIR::InlineAsm &expr)
if (expr.options.count (AST::InlineAsmOption::NORETURN) == 1)
infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ());
else
- infered
- = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+ infered = TyTy::TupleType::get_unit_type ();
+}
+
+void
+TypeCheckExpr::visit (HIR::LlvmInlineAsm &expr)
+{
+ for (auto &i : expr.inputs)
+ TypeCheckExpr::Resolve (*i.expr);
+
+ for (auto &o : expr.outputs)
+ TypeCheckExpr::Resolve (*o.expr);
+
+ // Black box hint is unit type
+ infered = TyTy::TupleType::get_unit_type ();
}
void
@@ -897,13 +915,12 @@ TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr)
// resolve the range expressions and these types must unify then we use that
// type to substitute into the ADT
- TyTy::BaseType *from_ty
- = TypeCheckExpr::Resolve (expr.get_from_expr ().get ());
- TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ());
+ TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_from_expr ());
+ TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ());
TyTy::BaseType *unified = unify_site (
expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (from_ty, expr.get_from_expr ()->get_locus ()),
- TyTy::TyWithLocation (to_ty, expr.get_to_expr ()->get_locus ()),
+ TyTy::TyWithLocation (from_ty, expr.get_from_expr ().get_locus ()),
+ TyTy::TyWithLocation (to_ty, expr.get_to_expr ().get_locus ()),
expr.get_locus ());
// substitute it in
@@ -920,11 +937,11 @@ TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr)
void
TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
{
- auto array_expr_ty = TypeCheckExpr::Resolve (expr.get_array_expr ().get ());
+ auto array_expr_ty = TypeCheckExpr::Resolve (expr.get_array_expr ());
if (array_expr_ty->get_kind () == TyTy::TypeKind::ERROR)
return;
- auto index_expr_ty = TypeCheckExpr::Resolve (expr.get_index_expr ().get ());
+ auto index_expr_ty = TypeCheckExpr::Resolve (expr.get_index_expr ());
if (index_expr_ty->get_kind () == TyTy::TypeKind::ERROR)
return;
@@ -947,10 +964,10 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
if (maybe_simple_array_access
&& direct_array_expr_ty->get_kind () == TyTy::TypeKind::ARRAY)
{
- unify_site (expr.get_index_expr ()->get_mappings ().get_hirid (),
+ unify_site (expr.get_index_expr ().get_mappings ().get_hirid (),
TyTy::TyWithLocation (size_ty),
TyTy::TyWithLocation (index_expr_ty,
- expr.get_index_expr ()->get_locus ()),
+ expr.get_index_expr ().get_locus ()),
expr.get_locus ());
TyTy::ArrayType *array_type
@@ -977,8 +994,8 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
// error[E0277]: the type `[{integer}]` cannot be indexed by `u32`
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 ());
+ 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",
array_expr_ty->get_name ().c_str (),
@@ -988,7 +1005,7 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
void
TypeCheckExpr::visit (HIR::ArrayExpr &expr)
{
- HIR::ArrayElems &elements = *expr.get_internal_elements ();
+ auto &elements = expr.get_internal_elements ();
HIR::Expr *capacity_expr = nullptr;
TyTy::BaseType *element_type = nullptr;
@@ -997,25 +1014,24 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
case HIR::ArrayElems::ArrayExprType::COPIED: {
HIR::ArrayElemsCopied &elems
= static_cast<HIR::ArrayElemsCopied &> (elements);
- element_type
- = TypeCheckExpr::Resolve (elems.get_elem_to_copy ().get ());
+ element_type = TypeCheckExpr::Resolve (elems.get_elem_to_copy ());
auto capacity_type
- = TypeCheckExpr::Resolve (elems.get_num_copies_expr ().get ());
+ = TypeCheckExpr::Resolve (elems.get_num_copies_expr ());
TyTy::BaseType *expected_ty = nullptr;
bool ok = context->lookup_builtin ("usize", &expected_ty);
rust_assert (ok);
- context->insert_type (elems.get_num_copies_expr ()->get_mappings (),
+ context->insert_type (elems.get_num_copies_expr ().get_mappings (),
expected_ty);
- unify_site (
- expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (expected_ty),
- TyTy::TyWithLocation (capacity_type,
- elems.get_num_copies_expr ()->get_locus ()),
- expr.get_locus ());
+ unify_site (expr.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (expected_ty),
+ TyTy::TyWithLocation (
+ capacity_type, elems.get_num_copies_expr ().get_locus ()),
+ expr.get_locus ());
- capacity_expr = elems.get_num_copies_expr ().get ();
+ capacity_expr = &elems.get_num_copies_expr ();
}
break;
@@ -1026,7 +1042,7 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
std::vector<TyTy::BaseType *> types;
for (auto &elem : elems.get_values ())
{
- types.push_back (TypeCheckExpr::Resolve (elem.get ()));
+ types.push_back (TypeCheckExpr::Resolve (*elem));
}
// this is a LUB
@@ -1070,7 +1086,7 @@ void
TypeCheckExpr::visit (HIR::StructExprStruct &struct_expr)
{
TyTy::BaseType *struct_path_ty
- = TypeCheckExpr::Resolve (&struct_expr.get_struct_name ());
+ = TypeCheckExpr::Resolve (struct_expr.get_struct_name ());
if (struct_path_ty->get_kind () != TyTy::TypeKind::ADT)
{
rust_error_at (struct_expr.get_struct_name ().get_locus (),
@@ -1102,19 +1118,19 @@ TypeCheckExpr::visit (HIR::StructExprStruct &struct_expr)
void
TypeCheckExpr::visit (HIR::StructExprStructFields &struct_expr)
{
- infered = TypeCheckStructExpr::Resolve (&struct_expr);
+ infered = TypeCheckStructExpr::Resolve (struct_expr);
}
void
TypeCheckExpr::visit (HIR::GroupedExpr &expr)
{
- infered = TypeCheckExpr::Resolve (expr.get_expr_in_parens ().get ());
+ infered = TypeCheckExpr::Resolve (expr.get_expr_in_parens ());
}
void
TypeCheckExpr::visit (HIR::FieldAccessExpr &expr)
{
- auto struct_base = TypeCheckExpr::Resolve (expr.get_receiver_expr ().get ());
+ auto struct_base = TypeCheckExpr::Resolve (expr.get_receiver_expr ());
// FIXME does this require autoderef here?
if (struct_base->get_kind () == TyTy::TypeKind::REF)
@@ -1126,46 +1142,130 @@ TypeCheckExpr::visit (HIR::FieldAccessExpr &expr)
bool is_valid_type = struct_base->get_kind () == TyTy::TypeKind::ADT;
if (!is_valid_type)
{
- rust_error_at (expr.get_locus (),
- "expected algebraic data type got: [%s]",
- struct_base->as_string ().c_str ());
+ rust_error_at (expr.get_locus (), "expected algebraic data type got %qs",
+ struct_base->get_name ().c_str ());
return;
}
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (struct_base);
- rust_assert (!adt->is_enum ());
- rust_assert (adt->number_of_variants () == 1);
-
+ rust_assert (adt->number_of_variants () > 0);
TyTy::VariantDef *vaiant = adt->get_variants ().at (0);
TyTy::StructFieldType *lookup = nullptr;
bool found = vaiant->lookup_field (expr.get_field_name ().as_string (),
&lookup, nullptr);
- if (!found)
+ if (!found || adt->is_enum ())
{
- rust_error_at (expr.get_locus (), ErrorCode::E0609,
- "no field %qs on type %qs",
+ rich_location r (line_table, expr.get_locus ());
+ r.add_range (expr.get_field_name ().get_locus ());
+ rust_error_at (r, ErrorCode::E0609, "no field %qs on type %qs",
expr.get_field_name ().as_string ().c_str (),
- adt->as_string ().c_str ());
+ adt->get_name ().c_str ());
return;
}
infered = lookup->get_field_type ();
}
+bool
+is_default_fn (const MethodCandidate &candidate)
+{
+ if (candidate.candidate.is_impl_candidate ())
+ {
+ auto *item = candidate.candidate.item.impl.impl_item;
+
+ if (item->get_impl_item_type () == HIR::ImplItem::FUNCTION)
+ {
+ auto &fn = static_cast<HIR::Function &> (*item);
+
+ return fn.is_default ();
+ }
+ }
+
+ return false;
+}
+
+void
+emit_ambiguous_resolution_error (HIR::MethodCallExpr &expr,
+ std::set<MethodCandidate> &candidates)
+{
+ rich_location r (line_table, expr.get_method_name ().get_locus ());
+ std::string rich_msg = "multiple "
+ + expr.get_method_name ().get_segment ().as_string ()
+ + " found";
+
+ // We have to filter out default candidates
+ for (auto &c : candidates)
+ if (!is_default_fn (c))
+ r.add_range (c.candidate.locus);
+
+ r.add_fixit_replace (rich_msg.c_str ());
+
+ rust_error_at (r, ErrorCode::E0592, "duplicate definitions with name %qs",
+ expr.get_method_name ().get_segment ().as_string ().c_str ());
+}
+
+// We are allowed to have multiple candidates if they are all specializable
+// functions or if all of them except one are specializable functions.
+// In the later case, we just return a valid candidate without erroring out
+// about ambiguity. If there are two or more specialized functions, then we
+// error out.
+//
+// FIXME: The first case is not handled at the moment, so we error out
+tl::optional<const MethodCandidate &>
+handle_multiple_candidates (HIR::MethodCallExpr &expr,
+ std::set<MethodCandidate> &candidates)
+{
+ auto all_default = true;
+ tl::optional<const MethodCandidate &> found = tl::nullopt;
+
+ for (auto &c : candidates)
+ {
+ if (!is_default_fn (c))
+ {
+ all_default = false;
+
+ // We haven't found a final candidate yet, so we can select
+ // this one. However, if we already have a candidate, then
+ // that means there are multiple non-default candidates - we
+ // must error out
+ if (!found)
+ {
+ found = c;
+ }
+ else
+ {
+ emit_ambiguous_resolution_error (expr, candidates);
+ return tl::nullopt;
+ }
+ }
+ }
+
+ // None of the candidates were a non-default (specialized) function, so we
+ // error out
+ if (all_default)
+ {
+ rust_sorry_at (expr.get_locus (),
+ "cannot resolve method calls to non-specialized methods "
+ "(all function candidates are %qs)",
+ "default");
+ return tl::nullopt;
+ }
+
+ return found;
+}
+
void
TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
{
- auto receiver_tyty = TypeCheckExpr::Resolve (expr.get_receiver ().get ());
+ auto receiver_tyty = TypeCheckExpr::Resolve (expr.get_receiver ());
if (receiver_tyty->get_kind () == TyTy::TypeKind::ERROR)
{
- rust_error_at (expr.get_receiver ()->get_locus (),
+ rust_error_at (expr.get_receiver ().get_locus (),
"failed to resolve receiver in MethodCallExpr");
return;
}
- context->insert_receiver (expr.get_mappings ().get_hirid (), receiver_tyty);
-
rust_debug_loc (expr.get_locus (), "attempting to resolve method for %s",
receiver_tyty->debug_str ().c_str ());
auto candidates
@@ -1182,34 +1282,25 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
return;
}
- if (candidates.size () > 1)
- {
- rich_location r (line_table, expr.get_method_name ().get_locus ());
- std::string rich_msg
- = "multiple " + expr.get_method_name ().get_segment ().as_string ()
- + " found";
+ tl::optional<const MethodCandidate &> candidate = *candidates.begin ();
- for (auto &c : candidates)
- r.add_range (c.candidate.locus);
+ if (candidates.size () > 1)
+ candidate = handle_multiple_candidates (expr, candidates);
- r.add_fixit_replace (rich_msg.c_str ());
+ if (!candidate)
+ return;
- rust_error_at (
- r, ErrorCode::E0592, "duplicate definitions with name %qs",
- expr.get_method_name ().get_segment ().as_string ().c_str ());
- return;
- }
+ auto found_candidate = *candidate;
- auto candidate = *candidates.begin ();
rust_debug_loc (expr.get_method_name ().get_locus (),
"resolved method to: {%u} {%s} with [%lu] adjustments",
- candidate.candidate.ty->get_ref (),
- candidate.candidate.ty->debug_str ().c_str (),
- (unsigned long) candidate.adjustments.size ());
+ found_candidate.candidate.ty->get_ref (),
+ found_candidate.candidate.ty->debug_str ().c_str (),
+ (unsigned long) found_candidate.adjustments.size ());
// Get the adjusted self
Adjuster adj (receiver_tyty);
- TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments);
+ TyTy::BaseType *adjusted_self = adj.adjust_type (found_candidate.adjustments);
rust_debug ("receiver: %s adjusted self %s",
receiver_tyty->debug_str ().c_str (),
adjusted_self->debug_str ().c_str ());
@@ -1218,12 +1309,12 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
// stored onto the receiver to so as we don't trigger duplicate deref mappings
// ICE when an argument is a method call
HirId autoderef_mappings_id
- = expr.get_receiver ()->get_mappings ().get_hirid ();
+ = expr.get_receiver ().get_mappings ().get_hirid ();
context->insert_autoderef_mappings (autoderef_mappings_id,
- std::move (candidate.adjustments));
+ std::move (found_candidate.adjustments));
- PathProbeCandidate &resolved_candidate = candidate.candidate;
- TyTy::BaseType *lookup_tyty = candidate.candidate.ty;
+ PathProbeCandidate &resolved_candidate = found_candidate.candidate;
+ TyTy::BaseType *lookup_tyty = found_candidate.candidate.ty;
NodeId resolved_node_id
= resolved_candidate.is_impl_candidate ()
? resolved_candidate.item.impl.impl_item->get_impl_mappings ()
@@ -1250,8 +1341,8 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
fn->prepare_higher_ranked_bounds ();
rust_debug_loc (expr.get_locus (), "resolved method call to: {%u} {%s}",
- candidate.candidate.ty->get_ref (),
- candidate.candidate.ty->debug_str ().c_str ());
+ found_candidate.candidate.ty->get_ref (),
+ found_candidate.candidate.ty->debug_str ().c_str ());
if (resolved_candidate.is_impl_candidate ())
{
@@ -1266,7 +1357,7 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
if (impl_self_infer->get_kind () == TyTy::TypeKind::ERROR)
{
rich_location r (line_table, expr.get_locus ());
- r.add_range (impl.get_type ()->get_locus ());
+ r.add_range (impl.get_type ().get_locus ());
rust_error_at (
r, "failed to resolve impl type for method call resolution");
return;
@@ -1317,8 +1408,17 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
// store the expected fntype
context->insert_type (expr.get_method_name ().get_mappings (), lookup);
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
+ Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+ nr_ctx.map_usage (Resolver2_0::Usage (expr.get_mappings ().get_nodeid ()),
+ Resolver2_0::Definition (resolved_node_id));
+ }
// set up the resolved name on the path
- if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
+ else if (resolver->get_name_scope ().decl_was_declared_here (
+ resolved_node_id))
{
resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
resolved_node_id);
@@ -1338,11 +1438,10 @@ TypeCheckExpr::visit (HIR::LoopExpr &expr)
{
context->push_new_loop_context (expr.get_mappings ().get_hirid (),
expr.get_locus ());
- TyTy::BaseType *block_expr
- = TypeCheckExpr::Resolve (expr.get_loop_block ().get ());
+ TyTy::BaseType *block_expr = TypeCheckExpr::Resolve (expr.get_loop_block ());
if (!block_expr->is_unit ())
{
- rust_error_at (expr.get_loop_block ()->get_locus (),
+ rust_error_at (expr.get_loop_block ().get_locus (),
"expected %<()%> got %s",
block_expr->as_string ().c_str ());
return;
@@ -1356,10 +1455,8 @@ TypeCheckExpr::visit (HIR::LoopExpr &expr)
&& (((TyTy::InferType *) loop_context_type)->get_infer_kind ()
!= TyTy::InferType::GENERAL));
- infered
- = loop_context_type_infered
- ? loop_context_type
- : TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+ infered = loop_context_type_infered ? loop_context_type
+ : TyTy::TupleType::get_unit_type ();
}
void
@@ -1367,20 +1464,19 @@ TypeCheckExpr::visit (HIR::WhileLoopExpr &expr)
{
context->push_new_while_loop_context (expr.get_mappings ().get_hirid ());
- TypeCheckExpr::Resolve (expr.get_predicate_expr ().get ());
- TyTy::BaseType *block_expr
- = TypeCheckExpr::Resolve (expr.get_loop_block ().get ());
+ TypeCheckExpr::Resolve (expr.get_predicate_expr ());
+ TyTy::BaseType *block_expr = TypeCheckExpr::Resolve (expr.get_loop_block ());
if (!block_expr->is_unit ())
{
- rust_error_at (expr.get_loop_block ()->get_locus (),
+ rust_error_at (expr.get_loop_block ().get_locus (),
"expected %<()%> got %s",
block_expr->as_string ().c_str ());
return;
}
context->pop_loop_context ();
- infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+ infered = TyTy::TupleType::get_unit_type ();
}
void
@@ -1396,7 +1492,7 @@ TypeCheckExpr::visit (HIR::BreakExpr &expr)
if (expr.has_break_expr ())
{
TyTy::BaseType *break_expr_tyty
- = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+ = TypeCheckExpr::Resolve (expr.get_expr ());
TyTy::BaseType *loop_context = context->peek_loop_context ();
if (loop_context->get_kind () == TyTy::TypeKind::ERROR)
@@ -1411,7 +1507,7 @@ TypeCheckExpr::visit (HIR::BreakExpr &expr)
= unify_site (expr.get_mappings ().get_hirid (),
TyTy::TyWithLocation (loop_context),
TyTy::TyWithLocation (break_expr_tyty,
- expr.get_expr ()->get_locus ()),
+ expr.get_expr ().get_locus ()),
expr.get_locus ());
context->swap_head_loop_context (unified_ty);
}
@@ -1435,8 +1531,9 @@ TypeCheckExpr::visit (HIR::ContinueExpr &expr)
void
TypeCheckExpr::visit (HIR::BorrowExpr &expr)
{
- TyTy::BaseType *resolved_base
- = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+ TyTy::BaseType *resolved_base = TypeCheckExpr::Resolve (expr.get_expr ());
+ if (resolved_base->is<TyTy::ErrorType> ())
+ return;
// In Rust this is valid because of DST's
//
@@ -1458,6 +1555,15 @@ TypeCheckExpr::visit (HIR::BorrowExpr &expr)
}
}
+ if (expr.is_raw_borrow ())
+ {
+ infered = new TyTy::PointerType (expr.get_mappings ().get_hirid (),
+ TyTy::TyVar (resolved_base->get_ref ()),
+ expr.get_mut ());
+
+ return;
+ }
+
infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
TyTy::TyVar (resolved_base->get_ref ()),
expr.get_mut ());
@@ -1466,8 +1572,7 @@ TypeCheckExpr::visit (HIR::BorrowExpr &expr)
void
TypeCheckExpr::visit (HIR::DereferenceExpr &expr)
{
- TyTy::BaseType *resolved_base
- = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+ TyTy::BaseType *resolved_base = TypeCheckExpr::Resolve (expr.get_expr ());
rust_debug_loc (expr.get_locus (), "attempting deref operator overload");
auto lang_item_type = LangItem::Kind::DEREF;
@@ -1508,14 +1613,14 @@ void
TypeCheckExpr::visit (HIR::TypeCastExpr &expr)
{
TyTy::BaseType *expr_to_convert
- = TypeCheckExpr::Resolve (expr.get_casted_expr ().get ());
+ = TypeCheckExpr::Resolve (expr.get_casted_expr ());
TyTy::BaseType *tyty_to_convert_to
- = TypeCheckType::Resolve (expr.get_type_to_convert_to ().get ());
+ = TypeCheckType::Resolve (expr.get_type_to_convert_to ());
TyTy::TyWithLocation from (expr_to_convert,
- expr.get_casted_expr ()->get_locus ());
+ expr.get_casted_expr ().get_locus ());
TyTy::TyWithLocation to (tyty_to_convert_to,
- expr.get_type_to_convert_to ()->get_locus ());
+ expr.get_type_to_convert_to ().get_locus ());
infered = cast_site (expr.get_mappings ().get_hirid (), from, to,
expr.get_locus ());
}
@@ -1526,7 +1631,19 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
// this needs to perform a least upper bound coercion on the blocks and then
// unify the scruintee and arms
TyTy::BaseType *scrutinee_tyty
- = TypeCheckExpr::Resolve (expr.get_scrutinee_expr ().get ());
+ = TypeCheckExpr::Resolve (expr.get_scrutinee_expr ());
+
+ // https://github.com/Rust-GCC/gccrs/issues/3231#issuecomment-2462660048
+ // https://github.com/rust-lang/rust/blob/3d1dba830a564d1118361345d7ada47a05241f45/compiler/rustc_hir_typeck/src/_match.rs#L32-L36
+ if (!expr.has_match_arms ())
+ {
+ // this is a special case where rustc returns !
+ TyTy::BaseType *lookup = nullptr;
+ bool ok = context->lookup_builtin ("!", &lookup);
+ rust_assert (ok);
+ infered = lookup->clone ();
+ return;
+ }
bool saw_error = false;
std::vector<TyTy::BaseType *> kase_block_tys;
@@ -1537,7 +1654,7 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
for (auto &pattern : kase_arm.get_patterns ())
{
TyTy::BaseType *kase_arm_ty
- = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty);
+ = TypeCheckPattern::Resolve (*pattern, scrutinee_tyty);
if (kase_arm_ty->get_kind () == TyTy ::TypeKind::ERROR)
{
saw_error = true;
@@ -1547,7 +1664,7 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
TyTy::BaseType *checked_kase = unify_site (
expr.get_mappings ().get_hirid (),
TyTy::TyWithLocation (scrutinee_tyty,
- expr.get_scrutinee_expr ()->get_locus ()),
+ expr.get_scrutinee_expr ().get_locus ()),
TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()),
expr.get_locus ());
if (checked_kase->get_kind () == TyTy::TypeKind::ERROR)
@@ -1558,8 +1675,7 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
}
// check the kase type
- TyTy::BaseType *kase_block_ty
- = TypeCheckExpr::Resolve (kase.get_expr ().get ());
+ TyTy::BaseType *kase_block_ty = TypeCheckExpr::Resolve (kase.get_expr ());
kase_block_tys.push_back (kase_block_ty);
}
if (saw_error)
@@ -1567,8 +1683,7 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
if (kase_block_tys.size () == 0)
{
- infered
- = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+ infered = TyTy::TupleType::get_unit_type ();
return;
}
@@ -1577,9 +1692,10 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
for (size_t i = 1; i < kase_block_tys.size (); i++)
{
TyTy::BaseType *kase_ty = kase_block_tys.at (i);
- infered = unify_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (infered),
- TyTy::TyWithLocation (kase_ty), expr.get_locus ());
+ infered
+ = coercion_site (expr.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (infered),
+ TyTy::TyWithLocation (kase_ty), expr.get_locus ());
}
}
@@ -1603,17 +1719,17 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
TyTy::BaseType *param_tyty = nullptr;
if (p.has_type_given ())
{
- param_tyty = TypeCheckType::Resolve (p.get_type ().get ());
+ param_tyty = TypeCheckType::Resolve (p.get_type ());
}
else
{
- param_tyty = ClosureParamInfer::Resolve (p.get_pattern ().get ());
+ param_tyty = ClosureParamInfer::Resolve (p.get_pattern ());
}
TyTy::TyVar param_ty (param_tyty->get_ref ());
parameter_types.push_back (param_ty);
- TypeCheckPattern::Resolve (p.get_pattern ().get (), param_ty.get_tyty ());
+ TypeCheckPattern::Resolve (p.get_pattern (), param_ty.get_tyty ());
}
// we generate an implicit hirid for the closure args
@@ -1621,21 +1737,20 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
TyTy::TupleType *closure_args
= new TyTy::TupleType (implicit_args_id, expr.get_locus (),
parameter_types);
- context->insert_implicit_type (closure_args);
+ context->insert_implicit_type (closure_args->get_ref (), closure_args);
location_t result_type_locus = expr.has_return_type ()
- ? expr.get_return_type ()->get_locus ()
+ ? expr.get_return_type ().get_locus ()
: expr.get_locus ();
TyTy::TyVar result_type
= expr.has_return_type ()
? TyTy::TyVar (
- TypeCheckType::Resolve (expr.get_return_type ().get ())->get_ref ())
+ TypeCheckType::Resolve (expr.get_return_type ())->get_ref ())
: TyTy::TyVar::get_implicit_infer_var (expr.get_locus ());
// resolve the block
- location_t closure_expr_locus = expr.get_expr ()->get_locus ();
- TyTy::BaseType *closure_expr_ty
- = TypeCheckExpr::Resolve (expr.get_expr ().get ());
+ location_t closure_expr_locus = expr.get_expr ().get_locus ();
+ TyTy::BaseType *closure_expr_ty = TypeCheckExpr::Resolve (expr.get_expr ());
coercion_site (expr.get_mappings ().get_hirid (),
TyTy::TyWithLocation (result_type.get_tyty (),
result_type_locus),
@@ -1644,7 +1759,24 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
// generate the closure type
NodeId closure_node_id = expr.get_mappings ().get_nodeid ();
- const std::set<NodeId> &captures = resolver->get_captures (closure_node_id);
+
+ // Resolve closure captures
+
+ std::set<NodeId> captures;
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
+ Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+ if (auto opt_cap = nr_ctx.mappings.lookup_captures (closure_node_id))
+ for (auto cap : opt_cap.value ())
+ captures.insert (cap);
+ }
+ else
+ {
+ captures = resolver->get_captures (closure_node_id);
+ }
+
infered = new TyTy::ClosureType (ref, id, ident, closure_args, result_type,
subst_refs, captures);
@@ -1701,10 +1833,10 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
}
bool
-TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
- HIR::OperatorExprMeta expr,
- TyTy::BaseType *lhs,
- TyTy::BaseType *rhs)
+TypeCheckExpr::resolve_operator_overload (
+ LangItem::Kind lang_item_type, HIR::OperatorExprMeta expr,
+ TyTy::BaseType *lhs, TyTy::BaseType *rhs,
+ HIR::PathIdentSegment specified_segment)
{
// look up lang item for arithmetic type
std::string associated_item_name = LangItem::ToString (lang_item_type);
@@ -1722,7 +1854,9 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
current_context = context->peek_context ();
}
- auto segment = HIR::PathIdentSegment (associated_item_name);
+ auto segment = specified_segment.is_error ()
+ ? HIR::PathIdentSegment (associated_item_name)
+ : specified_segment;
auto candidates = MethodResolver::Probe (lhs, segment);
// remove any recursive candidates
@@ -1775,9 +1909,6 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
context->insert_autoderef_mappings (expr.get_lvalue_mappings ().get_hirid (),
std::move (candidate.adjustments));
- // now its just like a method-call-expr
- context->insert_receiver (expr.get_mappings ().get_hirid (), lhs);
-
PathProbeCandidate &resolved_candidate = candidate.candidate;
TyTy::BaseType *lookup_tyty = candidate.candidate.ty;
NodeId resolved_node_id
@@ -1822,13 +1953,23 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
HIR::ImplBlock *parent = impl_item.first;
HIR::Function *fn = impl_item.second;
- if (parent->has_trait_ref ()
- && fn->get_function_name ().as_string ().compare (
- associated_item_name)
- == 0)
+ bool is_deref = lang_item_type == LangItem::Kind::DEREF
+ || lang_item_type == LangItem::Kind::DEREF_MUT;
+ bool is_deref_match = fn->get_function_name ().as_string ().compare (
+ LangItem::ToString (LangItem::Kind::DEREF))
+ == 0
+ || fn->get_function_name ().as_string ().compare (
+ LangItem::ToString (LangItem::Kind::DEREF_MUT))
+ == 0;
+
+ bool is_recursive_op
+ = fn->get_function_name ().as_string ().compare (associated_item_name)
+ == 0
+ || (is_deref && is_deref_match);
+ if (parent->has_trait_ref () && is_recursive_op)
{
TraitReference *trait_reference
- = TraitResolver::Lookup (*parent->get_trait_ref ().get ());
+ = TraitResolver::Lookup (parent->get_trait_ref ());
if (!trait_reference->is_error ())
{
TyTy::BaseType *lookup = nullptr;
@@ -1842,7 +1983,8 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
bool is_lang_item_impl
= trait_reference->get_mappings ().get_defid ()
- == respective_lang_item_id;
+ == respective_lang_item_id
+ || (is_deref && is_deref_match);
bool self_is_lang_item_self
= fntype->get_self_type ()->is_equal (*adjusted_self);
bool recursive_operator_overload
@@ -1867,11 +2009,11 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
// type check the arguments if required
TyTy::FnType *type = static_cast<TyTy::FnType *> (lookup);
rust_assert (type->num_params () > 0);
- auto fnparam = type->param_at (0);
+ auto &fnparam = type->param_at (0);
// typecheck the self
unify_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (fnparam.second),
+ TyTy::TyWithLocation (fnparam.get_type ()),
TyTy::TyWithLocation (adjusted_self), expr.get_locus ());
if (rhs == nullptr)
{
@@ -1880,9 +2022,9 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
else
{
rust_assert (type->num_params () == 2);
- auto fnparam = type->param_at (1);
+ auto &fnparam = type->param_at (1);
unify_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (fnparam.second),
+ TyTy::TyWithLocation (fnparam.get_type ()),
TyTy::TyWithLocation (rhs), expr.get_locus ());
}
@@ -1898,8 +2040,19 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
context->insert_operator_overload (expr.get_mappings ().get_hirid (), type);
// set up the resolved name on the path
- resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
- resolved_node_id);
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
+ Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+ nr_ctx.map_usage (Resolver2_0::Usage (expr.get_mappings ().get_nodeid ()),
+ Resolver2_0::Definition (resolved_node_id));
+ }
+ else
+ {
+ resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
+ resolved_node_id);
+ }
// return the result of the function back
infered = function_ret_tyty;
@@ -1996,11 +2149,10 @@ TypeCheckExpr::resolve_fn_trait_call (HIR::CallExpr &expr,
// store the adjustments for code-generation to know what to do which must be
// stored onto the receiver to so as we don't trigger duplicate deref mappings
// ICE when an argument is a method call
- HIR::Expr *fnexpr = expr.get_fnexpr ().get ();
- HirId autoderef_mappings_id = fnexpr->get_mappings ().get_hirid ();
+ HIR::Expr &fnexpr = expr.get_fnexpr ();
+ HirId autoderef_mappings_id = fnexpr.get_mappings ().get_hirid ();
context->insert_autoderef_mappings (autoderef_mappings_id,
std::move (candidate.adjustments));
- context->insert_receiver (expr.get_mappings ().get_hirid (), receiver_tyty);
PathProbeCandidate &resolved_candidate = candidate.candidate;
TyTy::BaseType *lookup_tyty = candidate.candidate.ty;
@@ -2034,7 +2186,7 @@ TypeCheckExpr::resolve_fn_trait_call (HIR::CallExpr &expr,
std::vector<TyTy::TyVar> call_args;
for (auto &arg : expr.get_arguments ())
{
- TyTy::BaseType *a = TypeCheckExpr::Resolve (arg.get ());
+ TyTy::BaseType *a = TypeCheckExpr::Resolve (*arg);
call_args.push_back (TyTy::TyVar (a->get_ref ()));
}
@@ -2068,8 +2220,32 @@ TypeCheckExpr::resolve_fn_trait_call (HIR::CallExpr &expr,
context->insert_operator_overload (expr.get_mappings ().get_hirid (), fn);
// set up the resolved name on the path
- resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
- resolved_node_id);
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
+ Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+ auto existing = nr_ctx.lookup (expr.get_mappings ().get_nodeid ());
+ if (existing)
+ rust_assert (*existing == resolved_node_id);
+ else
+ nr_ctx.map_usage (Resolver2_0::Usage (
+ expr.get_mappings ().get_nodeid ()),
+ Resolver2_0::Definition (resolved_node_id));
+ }
+ else
+ {
+ NodeId existing = UNKNOWN_NODEID;
+ bool ok
+ = resolver->lookup_resolved_name (expr.get_mappings ().get_nodeid (),
+ &existing);
+
+ if (ok)
+ rust_assert (existing == resolved_node_id);
+ else
+ resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
+ resolved_node_id);
+ }
// return the result of the function back
*result = function_ret_tyty;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 7192cf4..79121b3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -29,7 +29,7 @@ namespace Resolver {
class TypeCheckExpr : private TypeCheckBase, private HIR::HIRExpressionVisitor
{
public:
- static TyTy::BaseType *Resolve (HIR::Expr *expr);
+ static TyTy::BaseType *Resolve (HIR::Expr &expr);
void visit (HIR::TupleIndexExpr &expr) override;
void visit (HIR::TupleExpr &expr) override;
@@ -45,8 +45,6 @@ public:
void visit (HIR::NegationExpr &expr) override;
void visit (HIR::IfExpr &expr) override;
void visit (HIR::IfExprConseqElse &expr) override;
- void visit (HIR::IfLetExpr &expr) override;
- void visit (HIR::IfLetExprConseqElse &) override;
void visit (HIR::BlockExpr &expr) override;
void visit (HIR::UnsafeBlockExpr &expr) override;
void visit (HIR::ArrayIndexExpr &expr) override;
@@ -72,6 +70,7 @@ public:
void visit (HIR::WhileLoopExpr &expr) override;
void visit (HIR::ClosureExpr &expr) override;
void visit (HIR::InlineAsm &expr) override;
+ void visit (HIR::LlvmInlineAsm &expr) override;
// TODO
void visit (HIR::ErrorPropagationExpr &) override {}
@@ -99,7 +98,9 @@ public:
protected:
bool resolve_operator_overload (LangItem::Kind lang_item_type,
HIR::OperatorExprMeta expr,
- TyTy::BaseType *lhs, TyTy::BaseType *rhs);
+ TyTy::BaseType *lhs, TyTy::BaseType *rhs,
+ HIR::PathIdentSegment specified_segment
+ = HIR::PathIdentSegment::create_error ());
bool resolve_fn_trait_call (HIR::CallExpr &expr,
TyTy::BaseType *function_tyty,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 0036e9a..bc7f6dc 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -18,6 +18,8 @@
#include "rust-hir-type-check-implitem.h"
#include "rust-diagnostics.h"
+#include "rust-hir-full-decls.h"
+#include "rust-hir-pattern.h"
#include "rust-hir-type-check-base.h"
#include "rust-hir-type-check-type.h"
#include "rust-hir-type-check-expr.h"
@@ -38,27 +40,26 @@ TypeCheckTopLevelExternItem::TypeCheckTopLevelExternItem (
{}
TyTy::BaseType *
-TypeCheckTopLevelExternItem::Resolve (HIR::ExternalItem *item,
+TypeCheckTopLevelExternItem::Resolve (HIR::ExternalItem &item,
const HIR::ExternBlock &parent)
{
// is it already resolved?
auto context = TypeCheckContext::get ();
TyTy::BaseType *resolved = nullptr;
bool already_resolved
- = context->lookup_type (item->get_mappings ().get_hirid (), &resolved);
+ = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
if (already_resolved)
return resolved;
TypeCheckTopLevelExternItem resolver (parent);
- item->accept_vis (resolver);
+ item.accept_vis (resolver);
return resolver.resolved;
}
void
TypeCheckTopLevelExternItem::visit (HIR::ExternalStaticItem &item)
{
- TyTy::BaseType *actual_type
- = TypeCheckType::Resolve (item.get_item_type ().get ());
+ TyTy::BaseType *actual_type = TypeCheckType::Resolve (item.get_item_type ());
context->insert_type (item.get_mappings (), actual_type);
resolved = actual_type;
@@ -72,33 +73,8 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
std::vector<TyTy::SubstitutionParamMapping> substitutions;
if (function.has_generics ())
{
- for (auto &generic_param : function.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME:
- context->intern_and_insert_lifetime (
- static_cast<HIR::LifetimeParam &> (*generic_param)
- .get_lifetime ());
- // TODO: handle bounds
- break;
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get ());
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
+ resolve_generic_params (function.get_generic_params (), substitutions,
+ true /*is_foreign*/, parent.get_abi ());
}
TyTy::RegionConstraints region_constraints;
@@ -106,19 +82,17 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
{
for (auto &where_clause_item : function.get_where_clause ().get_items ())
{
- ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
+ ResolveWhereClauseItem::Resolve (*where_clause_item,
region_constraints);
}
}
TyTy::BaseType *ret_type = nullptr;
if (!function.has_return_type ())
- ret_type
- = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid ());
+ ret_type = TyTy::TupleType::get_unit_type ();
else
{
- auto resolved
- = TypeCheckType::Resolve (function.get_return_type ().get ());
+ auto resolved = TypeCheckType::Resolve (function.get_return_type ());
if (resolved == nullptr)
{
rust_error_at (function.get_locus (),
@@ -128,14 +102,14 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
ret_type = resolved->clone ();
ret_type->set_ref (
- function.get_return_type ()->get_mappings ().get_hirid ());
+ function.get_return_type ().get_mappings ().get_hirid ());
}
- std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
+ std::vector<TyTy::FnParam> params;
for (auto &param : function.get_function_params ())
{
// get the name as well required for later on
- auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
+ auto param_tyty = TypeCheckType::Resolve (param.get_type ());
// these are implicit mappings and not used
auto crate_num = mappings.get_current_crate ();
@@ -143,14 +117,12 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- HIR::IdentifierPattern *param_pattern
- = new HIR::IdentifierPattern (mapping, param.get_param_name (),
- UNDEF_LOCATION, false, Mutability::Imm,
- std::unique_ptr<HIR::Pattern> (nullptr));
+ auto param_pattern = std::make_unique<HIR::IdentifierPattern> (
+ HIR::IdentifierPattern (mapping, param.get_param_name (),
+ UNDEF_LOCATION, false, Mutability::Imm,
+ std::unique_ptr<HIR::Pattern> (nullptr)));
- params.push_back (
- std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern,
- param_tyty));
+ params.push_back (TyTy::FnParam (std::move (param_pattern), param_tyty));
context->insert_type (param.get_mappings (), param_tyty);
@@ -192,132 +164,11 @@ void
TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem &type)
{
rust_sorry_at (type.get_locus (), "extern types are not supported yet");
- // auto binder_pin = context->push_clean_lifetime_resolver ();
-
- // std::vector<TyTy::SubstitutionParamMapping> substitutions;
- // if (function.has_generics ())
- // {
- // for (auto &generic_param : function.get_generic_params ())
- // {
- // switch (generic_param.get ()->get_kind ())
- // {
- // case HIR::GenericParam::GenericKind::LIFETIME:
- // context->intern_and_insert_lifetime (
- // static_cast<HIR::LifetimeParam &> (*generic_param)
- // .get_lifetime ());
- // // TODO: handle bounds
- // break;
- // case HIR::GenericParam::GenericKind::CONST:
- // // FIXME: Skipping Lifetime and Const completely until better
- // // handling.
- // break;
-
- // case HIR::GenericParam::GenericKind::TYPE: {
- // auto param_type
- // = TypeResolveGenericParam::Resolve (generic_param.get ());
- // context->insert_type (generic_param->get_mappings (),
- // param_type);
-
- // substitutions.push_back (TyTy::SubstitutionParamMapping (
- // static_cast<HIR::TypeParam &> (*generic_param), param_type));
- // }
- // break;
- // }
- // }
- // }
-
- // TyTy::RegionConstraints region_constraints;
- // if (function.has_where_clause ())
- // {
- // for (auto &where_clause_item : function.get_where_clause ().get_items
- // ())
- // {
- // ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
- // region_constraints);
- // }
- // }
-
- // TyTy::BaseType *ret_type = nullptr;
- // if (!function.has_return_type ())
- // ret_type
- // = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid
- // ());
- // else
- // {
- // auto resolved
- // = TypeCheckType::Resolve (function.get_return_type ().get ());
- // if (resolved == nullptr)
- // {
- // rust_error_at (function.get_locus (),
- // "failed to resolve return type");
- // return;
- // }
-
- // ret_type = resolved->clone ();
- // ret_type->set_ref (
- // function.get_return_type ()->get_mappings ().get_hirid ());
- // }
-
- // std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
- // for (auto &param : function.get_function_params ())
- // {
- // // get the name as well required for later on
- // auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
-
- // // these are implicit mappings and not used
- // auto crate_num = mappings->get_current_crate ();
- // Analysis::NodeMapping mapping (crate_num, mappings->get_next_node_id
- // (),
- // mappings->get_next_hir_id (crate_num),
- // UNKNOWN_LOCAL_DEFID);
-
- // HIR::IdentifierPattern *param_pattern
- // = new HIR::IdentifierPattern (mapping, param.get_param_name (),
- // UNDEF_LOCATION, false, Mutability::Imm,
- // std::unique_ptr<HIR::Pattern> (nullptr));
-
- // params.push_back (
- // std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern,
- // param_tyty));
-
- // context->insert_type (param.get_mappings (), param_tyty);
-
- // // FIXME do we need error checking for patterns here?
- // // see https://github.com/Rust-GCC/gccrs/issues/995
- // }
-
- // uint8_t flags = TyTy::FnType::FNTYPE_IS_EXTERN_FLAG;
- // if (function.is_variadic ())
- // {
- // flags |= TyTy::FnType::FNTYPE_IS_VARADIC_FLAG;
- // if (parent.get_abi () != Rust::ABI::C)
- // {
- // rust_error_at (
- // function.get_locus (), ErrorCode::E0045,
- // "C-variadic function must have C or cdecl calling convention");
- // }
- // }
-
- // RustIdent ident{
- // CanonicalPath::new_seg (function.get_mappings ().get_nodeid (),
- // function.get_item_name ().as_string ()),
- // function.get_locus ()};
-
- // auto fnType = new TyTy::FnType (
- // function.get_mappings ().get_hirid (),
- // function.get_mappings ().get_defid (),
- // function.get_item_name ().as_string (), ident, flags, parent.get_abi (),
- // std::move (params), ret_type, std::move (substitutions),
- // TyTy::SubstitutionArgumentMappings::empty (
- // context->get_lifetime_resolver ().get_num_bound_regions ()),
- // region_constraints);
-
- // context->insert_type (function.get_mappings (), fnType);
- // resolved = fnType;
+ // TODO
}
TypeCheckImplItem::TypeCheckImplItem (
- HIR::ImplBlock *parent, TyTy::BaseType *self,
+ HIR::ImplBlock &parent, TyTy::BaseType *self,
std::vector<TyTy::SubstitutionParamMapping> substitutions)
: TypeCheckBase (), parent (parent), self (self),
substitutions (substitutions)
@@ -325,20 +176,24 @@ TypeCheckImplItem::TypeCheckImplItem (
TyTy::BaseType *
TypeCheckImplItem::Resolve (
- HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
+ HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
std::vector<TyTy::SubstitutionParamMapping> substitutions)
{
// is it already resolved?
auto context = TypeCheckContext::get ();
TyTy::BaseType *resolved = nullptr;
bool already_resolved
- = context->lookup_type (item->get_impl_mappings ().get_hirid (), &resolved);
+ = context->lookup_type (item.get_impl_mappings ().get_hirid (), &resolved);
if (already_resolved)
return resolved;
// resolve
TypeCheckImplItem resolver (parent, self, substitutions);
- item->accept_vis (resolver);
+ resolver.context->block_context ().enter (
+ TypeCheckBlockContextItem (&parent));
+ item.accept_vis (resolver);
+ resolver.context->block_context ().exit ();
+
return resolver.result;
}
@@ -359,12 +214,10 @@ TypeCheckImplItem::visit (HIR::Function &function)
TyTy::BaseType *ret_type = nullptr;
if (!function.has_function_return_type ())
- ret_type
- = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid ());
+ ret_type = TyTy::TupleType::get_unit_type ();
else
{
- auto resolved
- = TypeCheckType::Resolve (function.get_return_type ().get ());
+ auto resolved = TypeCheckType::Resolve (function.get_return_type ());
if (resolved == nullptr)
{
rust_error_at (function.get_locus (),
@@ -374,10 +227,10 @@ TypeCheckImplItem::visit (HIR::Function &function)
ret_type = resolved->clone ();
ret_type->set_ref (
- function.get_return_type ()->get_mappings ().get_hirid ());
+ function.get_return_type ().get_mappings ().get_hirid ());
}
- std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
+ std::vector<TyTy::FnParam> params;
if (function.is_method ())
{
// these are implicit mappings and not used
@@ -389,18 +242,20 @@ TypeCheckImplItem::visit (HIR::Function &function)
// add the synthetic self param at the front, this is a placeholder for
// compilation to know parameter names. The types are ignored but we
// reuse the HIR identifier pattern which requires it
- HIR::SelfParam &self_param = function.get_self_param ();
+ HIR::SelfParam &self_param = function.get_self_param_unchecked ();
// FIXME: which location should be used for Rust::Identifier for `self`?
- HIR::IdentifierPattern *self_pattern = new HIR::IdentifierPattern (
- mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
- self_param.get_mut (), std::unique_ptr<HIR::Pattern> (nullptr));
+ std::unique_ptr<HIR::Pattern> self_pattern
+ = std::make_unique<HIR::IdentifierPattern> (
+ HIR::IdentifierPattern (mapping, {"self"}, self_param.get_locus (),
+ self_param.is_ref (), self_param.get_mut (),
+ std::unique_ptr<HIR::Pattern> (nullptr)));
// might have a specified type
TyTy::BaseType *self_type = nullptr;
if (self_param.has_type ())
{
- std::unique_ptr<HIR::Type> &specified_type = self_param.get_type ();
- self_type = TypeCheckType::Resolve (specified_type.get ());
+ auto &specified_type = self_param.get_type ();
+ self_type = TypeCheckType::Resolve (specified_type);
}
else
{
@@ -412,13 +267,21 @@ TypeCheckImplItem::visit (HIR::Function &function)
break;
case HIR::SelfParam::IMM_REF: {
- auto region = context->lookup_and_resolve_lifetime (
- self_param.get_lifetime ());
- if (!region.has_value ())
+ tl::optional<TyTy::Region> region;
+ if (self_param.has_lifetime ())
+ {
+ region = context->lookup_and_resolve_lifetime (
+ self_param.get_lifetime ());
+ if (!region.has_value ())
+ {
+ rust_inform (self_param.get_locus (),
+ "failed to resolve lifetime");
+ return;
+ }
+ }
+ else
{
- rust_inform (self_param.get_locus (),
- "failed to resolve lifetime");
- region = TyTy::Region::make_anonymous (); // FIXME
+ region = TyTy::Region::make_anonymous ();
}
self_type = new TyTy::ReferenceType (
self_param.get_mappings ().get_hirid (),
@@ -428,13 +291,21 @@ TypeCheckImplItem::visit (HIR::Function &function)
break;
case HIR::SelfParam::MUT_REF: {
- auto region = context->lookup_and_resolve_lifetime (
- self_param.get_lifetime ());
- if (!region.has_value ())
+ tl::optional<TyTy::Region> region;
+ if (self_param.has_lifetime ())
{
- rust_error_at (self_param.get_locus (),
- "failed to resolve lifetime");
- return;
+ region = context->lookup_and_resolve_lifetime (
+ self_param.get_lifetime ());
+ if (!region.has_value ())
+ {
+ rust_error_at (self_param.get_locus (),
+ "failed to resolve lifetime");
+ return;
+ }
+ }
+ else
+ {
+ region = TyTy::Region::make_anonymous ();
}
self_type = new TyTy::ReferenceType (
self_param.get_mappings ().get_hirid (),
@@ -450,26 +321,26 @@ TypeCheckImplItem::visit (HIR::Function &function)
}
context->insert_type (self_param.get_mappings (), self_type);
- params.push_back (
- std::pair<HIR::Pattern *, TyTy::BaseType *> (self_pattern, self_type));
+ params.push_back (TyTy::FnParam (std::move (self_pattern), self_type));
}
for (auto &param : function.get_function_params ())
{
// get the name as well required for later on
- auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
- params.push_back (std::pair<HIR::Pattern *, TyTy::BaseType *> (
- param.get_param_name ().get (), param_tyty));
+ auto param_tyty = TypeCheckType::Resolve (param.get_type ());
context->insert_type (param.get_mappings (), param_tyty);
- TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
+ TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
+
+ params.push_back (
+ TyTy::FnParam (param.get_param_name ().clone_pattern (), param_tyty));
}
tl::optional<CanonicalPath> canonical_path;
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path = nr_ctx.values.to_canonical_path (
@@ -504,17 +375,16 @@ TypeCheckImplItem::visit (HIR::Function &function)
context->push_return_type (TypeCheckContextItem (parent, &function),
expected_ret_tyty);
- auto block_expr_ty
- = TypeCheckExpr::Resolve (function.get_definition ().get ());
+ auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
location_t fn_return_locus = function.has_function_return_type ()
- ? function.get_return_type ()->get_locus ()
+ ? function.get_return_type ().get_locus ()
: function.get_locus ();
- coercion_site (function.get_definition ()->get_mappings ().get_hirid (),
+ coercion_site (function.get_definition ().get_mappings ().get_hirid (),
TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
TyTy::TyWithLocation (block_expr_ty),
- function.get_definition ()->get_locus ());
+ function.get_definition ().get_locus ());
context->pop_return_type ();
}
@@ -522,14 +392,13 @@ TypeCheckImplItem::visit (HIR::Function &function)
void
TypeCheckImplItem::visit (HIR::ConstantItem &constant)
{
- TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
- TyTy::BaseType *expr_type
- = TypeCheckExpr::Resolve (constant.get_expr ().get ());
+ TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
+ TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
TyTy::BaseType *unified = unify_site (
constant.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
- TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
+ TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
+ TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
constant.get_locus ());
context->insert_type (constant.get_mappings (), unified);
result = unified;
@@ -544,7 +413,7 @@ TypeCheckImplItem::visit (HIR::TypeAlias &alias)
resolve_generic_params (alias.get_generic_params (), substitutions);
TyTy::BaseType *actual_type
- = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
+ = TypeCheckType::Resolve (alias.get_type_aliased ());
context->insert_type (alias.get_mappings (), actual_type);
result = actual_type;
@@ -557,7 +426,7 @@ TypeCheckImplItem::visit (HIR::TypeAlias &alias)
}
TypeCheckImplItemWithTrait::TypeCheckImplItemWithTrait (
- HIR::ImplBlock *parent, TyTy::BaseType *self,
+ HIR::ImplBlock &parent, TyTy::BaseType *self,
TyTy::TypeBoundPredicate &trait_reference,
std::vector<TyTy::SubstitutionParamMapping> substitutions)
: TypeCheckBase (), trait_reference (trait_reference),
@@ -569,13 +438,13 @@ TypeCheckImplItemWithTrait::TypeCheckImplItemWithTrait (
TyTy::TypeBoundPredicateItem
TypeCheckImplItemWithTrait::Resolve (
- HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
+ HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
TyTy::TypeBoundPredicate &trait_reference,
std::vector<TyTy::SubstitutionParamMapping> substitutions)
{
TypeCheckImplItemWithTrait resolver (parent, self, trait_reference,
substitutions);
- item->accept_vis (resolver);
+ item.accept_vis (resolver);
return resolver.resolved_trait_item;
}
@@ -584,7 +453,7 @@ TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
{
// normal resolution of the item
TyTy::BaseType *lookup
- = TypeCheckImplItem::Resolve (parent, &constant, self, substitutions);
+ = TypeCheckImplItem::Resolve (parent, constant, self, substitutions);
// map the impl item to the associated trait item
const auto tref = trait_reference.get ();
@@ -637,7 +506,7 @@ TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
{
// normal resolution of the item
TyTy::BaseType *lookup
- = TypeCheckImplItem::Resolve (parent, &type, self, substitutions);
+ = TypeCheckImplItem::Resolve (parent, type, self, substitutions);
// map the impl item to the associated trait item
const auto tref = trait_reference.get ();
@@ -698,7 +567,7 @@ TypeCheckImplItemWithTrait::visit (HIR::Function &function)
{
// normal resolution of the item
TyTy::BaseType *lookup
- = TypeCheckImplItem::Resolve (parent, &function, self, substitutions);
+ = TypeCheckImplItem::Resolve (parent, function, self, substitutions);
// map the impl item to the associated trait item
const auto tref = trait_reference.get ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 4fb2256..14f6a05 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -29,7 +29,7 @@ class TypeCheckTopLevelExternItem : public TypeCheckBase,
public HIR::HIRExternalItemVisitor
{
public:
- static TyTy::BaseType *Resolve (HIR::ExternalItem *item,
+ static TyTy::BaseType *Resolve (HIR::ExternalItem &item,
const HIR::ExternBlock &parent);
void visit (HIR::ExternalStaticItem &item) override;
@@ -47,7 +47,7 @@ class TypeCheckImplItem : public TypeCheckBase, public HIR::HIRImplVisitor
{
public:
static TyTy::BaseType *
- Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
+ Resolve (HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
std::vector<TyTy::SubstitutionParamMapping> substitutions);
void visit (HIR::Function &function) override;
@@ -55,10 +55,10 @@ public:
void visit (HIR::TypeAlias &type_alias) override;
protected:
- TypeCheckImplItem (HIR::ImplBlock *parent, TyTy::BaseType *self,
+ TypeCheckImplItem (HIR::ImplBlock &parent, TyTy::BaseType *self,
std::vector<TyTy::SubstitutionParamMapping> substitutions);
- HIR::ImplBlock *parent;
+ HIR::ImplBlock &parent;
TyTy::BaseType *self;
std::vector<TyTy::SubstitutionParamMapping> substitutions;
@@ -70,7 +70,7 @@ class TypeCheckImplItemWithTrait : public TypeCheckBase,
{
public:
static TyTy::TypeBoundPredicateItem
- Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
+ Resolve (HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
TyTy::TypeBoundPredicate &trait_reference,
std::vector<TyTy::SubstitutionParamMapping> substitutions);
@@ -86,7 +86,7 @@ protected:
private:
TypeCheckImplItemWithTrait (
- HIR::ImplBlock *parent, TyTy::BaseType *self,
+ HIR::ImplBlock &parent, TyTy::BaseType *self,
TyTy::TypeBoundPredicate &trait_reference,
std::vector<TyTy::SubstitutionParamMapping> substitutions);
@@ -95,7 +95,7 @@ private:
TyTy::TypeBoundPredicate &trait_reference;
TyTy::TypeBoundPredicateItem resolved_trait_item;
- HIR::ImplBlock *parent;
+ HIR::ImplBlock &parent;
TyTy::BaseType *self;
std::vector<TyTy::SubstitutionParamMapping> substitutions;
TyTy::RegionConstraints region_constraints;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 4ea6852..aaa04af 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-hir-type-check-item.h"
+#include "optional.h"
#include "rust-canonical-path.h"
#include "rust-diagnostics.h"
#include "rust-hir-type-check-enumitem.h"
@@ -150,7 +151,7 @@ void
TypeCheckItem::visit (HIR::TypeAlias &alias)
{
TyTy::BaseType *actual_type
- = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
+ = TypeCheckType::Resolve (alias.get_type_aliased ());
context->insert_type (alias.get_mappings (), actual_type);
@@ -182,7 +183,7 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
for (auto &field : struct_decl.get_fields ())
{
TyTy::BaseType *field_type
- = TypeCheckType::Resolve (field.get_field_type ().get ());
+ = TypeCheckType::Resolve (field.get_field_type ());
auto *ty_field
= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
std::to_string (idx), field_type,
@@ -199,7 +200,7 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
// FIXME: HACK: ARTHUR: Disgusting
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
path = nr_ctx.values
@@ -222,7 +223,7 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
struct_decl.get_mappings ().get_defid (),
struct_decl.get_identifier ().as_string (), ident,
- TyTy::VariantDef::VariantType::TUPLE, nullptr,
+ TyTy::VariantDef::VariantType::TUPLE, tl::nullopt,
std::move (fields)));
// Process #[repr(X)] attribute, if any
@@ -231,7 +232,9 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
= parse_repr_options (attrs, struct_decl.get_locus ());
auto *type = new TyTy::ADTType (
- struct_decl.get_mappings ().get_hirid (), mappings.get_next_hir_id (),
+ struct_decl.get_mappings ().get_defid (),
+ struct_decl.get_mappings ().get_hirid (),
+ struct_decl.get_mappings ().get_hirid (),
struct_decl.get_identifier ().as_string (), ident,
TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
std::move (substitutions), repr,
@@ -264,7 +267,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
for (auto &field : struct_decl.get_fields ())
{
TyTy::BaseType *field_type
- = TypeCheckType::Resolve (field.get_field_type ().get ());
+ = TypeCheckType::Resolve (field.get_field_type ());
auto *ty_field
= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
field.get_field_name ().as_string (),
@@ -278,7 +281,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
// FIXME: HACK: ARTHUR: Disgusting
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
auto canonical_path = nr_ctx.types.to_canonical_path (
struct_decl.get_mappings ().get_nodeid ());
@@ -303,7 +306,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
struct_decl.get_mappings ().get_defid (),
struct_decl.get_identifier ().as_string (), ident,
- TyTy::VariantDef::VariantType::STRUCT, nullptr,
+ TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
std::move (fields)));
// Process #[repr(X)] attribute, if any
@@ -312,7 +315,9 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
= parse_repr_options (attrs, struct_decl.get_locus ());
auto *type = new TyTy::ADTType (
- struct_decl.get_mappings ().get_hirid (), mappings.get_next_hir_id (),
+ struct_decl.get_mappings ().get_defid (),
+ struct_decl.get_mappings ().get_hirid (),
+ struct_decl.get_mappings ().get_hirid (),
struct_decl.get_identifier ().as_string (), ident,
TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
std::move (substitutions), repr,
@@ -334,23 +339,40 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
if (enum_decl.has_generics ())
resolve_generic_params (enum_decl.get_generic_params (), substitutions);
+ // Process #[repr(X)] attribute, if any
+ const AST::AttrVec &attrs = enum_decl.get_outer_attrs ();
+ TyTy::ADTType::ReprOptions repr
+ = parse_repr_options (attrs, enum_decl.get_locus ());
+
std::vector<TyTy::VariantDef *> variants;
int64_t discriminant_value = 0;
for (auto &variant : enum_decl.get_variants ())
{
TyTy::VariantDef *field_type
- = TypeCheckEnumItem::Resolve (variant.get (), discriminant_value);
+ = TypeCheckEnumItem::Resolve (*variant, discriminant_value);
discriminant_value++;
variants.push_back (field_type);
}
+ // Check for zero-variant enum compatibility
+ if (enum_decl.is_zero_variant ())
+ {
+ if (repr.repr_kind == TyTy::ADTType::ReprKind::INT
+ || repr.repr_kind == TyTy::ADTType::ReprKind::C)
+ {
+ rust_error_at (enum_decl.get_locus (),
+ "unsupported representation for zero-variant enum");
+ return;
+ }
+ }
+
// get the path
tl::optional<CanonicalPath> canonical_path;
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path = nr_ctx.types.to_canonical_path (
@@ -368,11 +390,12 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
// multi variant ADT
auto *type
- = new TyTy::ADTType (enum_decl.get_mappings ().get_hirid (),
- mappings.get_next_hir_id (),
+ = new TyTy::ADTType (enum_decl.get_mappings ().get_defid (),
+ enum_decl.get_mappings ().get_hirid (),
+ enum_decl.get_mappings ().get_hirid (),
enum_decl.get_identifier ().as_string (), ident,
TyTy::ADTType::ADTKind::ENUM, std::move (variants),
- std::move (substitutions));
+ std::move (substitutions), repr);
context->insert_type (enum_decl.get_mappings (), type);
infered = type;
@@ -398,7 +421,7 @@ TypeCheckItem::visit (HIR::Union &union_decl)
for (auto &variant : union_decl.get_variants ())
{
TyTy::BaseType *variant_type
- = TypeCheckType::Resolve (variant.get_field_type ().get ());
+ = TypeCheckType::Resolve (variant.get_field_type ());
auto *ty_variant
= new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
variant.get_field_name ().as_string (),
@@ -413,7 +436,7 @@ TypeCheckItem::visit (HIR::Union &union_decl)
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path = nr_ctx.types.to_canonical_path (
@@ -435,12 +458,13 @@ TypeCheckItem::visit (HIR::Union &union_decl)
new TyTy::VariantDef (union_decl.get_mappings ().get_hirid (),
union_decl.get_mappings ().get_defid (),
union_decl.get_identifier ().as_string (), ident,
- TyTy::VariantDef::VariantType::STRUCT, nullptr,
+ TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
std::move (fields)));
auto *type
- = new TyTy::ADTType (union_decl.get_mappings ().get_hirid (),
- mappings.get_next_hir_id (),
+ = new TyTy::ADTType (union_decl.get_mappings ().get_defid (),
+ union_decl.get_mappings ().get_hirid (),
+ union_decl.get_mappings ().get_hirid (),
union_decl.get_identifier ().as_string (), ident,
TyTy::ADTType::ADTKind::UNION, std::move (variants),
std::move (substitutions));
@@ -454,14 +478,14 @@ TypeCheckItem::visit (HIR::Union &union_decl)
void
TypeCheckItem::visit (HIR::StaticItem &var)
{
- TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ().get ());
- TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ().get ());
+ TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
+ TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
TyTy::BaseType *unified
= coercion_site (var.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (type, var.get_type ()->get_locus ()),
+ TyTy::TyWithLocation (type, var.get_type ().get_locus ()),
TyTy::TyWithLocation (expr_type,
- var.get_expr ()->get_locus ()),
+ var.get_expr ().get_locus ()),
var.get_locus ());
context->insert_type (var.get_mappings (), unified);
infered = unified;
@@ -470,14 +494,13 @@ TypeCheckItem::visit (HIR::StaticItem &var)
void
TypeCheckItem::visit (HIR::ConstantItem &constant)
{
- TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
- TyTy::BaseType *expr_type
- = TypeCheckExpr::Resolve (constant.get_expr ().get ());
+ TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
+ TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
TyTy::BaseType *unified = unify_site (
constant.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
- TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
+ TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
+ TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
constant.get_locus ());
context->insert_type (constant.get_mappings (), unified);
infered = unified;
@@ -491,8 +514,8 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
TraitReference *trait_reference = &TraitReference::error_node ();
if (impl_block.has_trait_ref ())
{
- std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
- trait_reference = TraitResolver::Resolve (*ref);
+ HIR::TypePath &ref = impl_block.get_trait_ref ();
+ trait_reference = TraitResolver::Resolve (ref);
if (trait_reference->is_error ())
return;
}
@@ -513,8 +536,7 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
// resolve each impl_item
for (auto &impl_item : impl_block.get_impl_items ())
{
- TypeCheckImplItem::Resolve (&impl_block, impl_item.get (), self,
- substitutions);
+ TypeCheckImplItem::Resolve (impl_block, *impl_item, self, substitutions);
}
// validate the impl items
@@ -538,7 +560,7 @@ TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
TyTy::BaseType *self = resolve_impl_block_self (impl_block);
- return TypeCheckImplItem::Resolve (&impl_block, &item, self, substitutions);
+ return TypeCheckImplItem::Resolve (impl_block, item, self, substitutions);
}
void
@@ -558,12 +580,10 @@ TypeCheckItem::visit (HIR::Function &function)
TyTy::BaseType *ret_type = nullptr;
if (!function.has_function_return_type ())
- ret_type
- = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid ());
+ ret_type = TyTy::TupleType::get_unit_type ();
else
{
- auto resolved
- = TypeCheckType::Resolve (function.get_return_type ().get ());
+ auto resolved = TypeCheckType::Resolve (function.get_return_type ());
if (resolved->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (function.get_locus (),
@@ -573,18 +593,18 @@ TypeCheckItem::visit (HIR::Function &function)
ret_type = resolved->clone ();
ret_type->set_ref (
- function.get_return_type ()->get_mappings ().get_hirid ());
+ function.get_return_type ().get_mappings ().get_hirid ());
}
- std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *>> params;
+ std::vector<TyTy::FnParam> params;
for (auto &param : function.get_function_params ())
{
// get the name as well required for later on
- auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
- params.emplace_back (param.get_param_name ().get (), param_tyty);
-
+ auto param_tyty = TypeCheckType::Resolve (param.get_type ());
context->insert_type (param.get_mappings (), param_tyty);
- TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
+ TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
+ params.push_back (
+ TyTy::FnParam (param.get_param_name ().clone_pattern (), param_tyty));
}
auto path = CanonicalPath::create_empty ();
@@ -592,7 +612,7 @@ TypeCheckItem::visit (HIR::Function &function)
// FIXME: HACK: ARTHUR: Disgusting
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
auto canonical_path = nr_ctx.values.to_canonical_path (
function.get_mappings ().get_nodeid ());
@@ -627,16 +647,47 @@ TypeCheckItem::visit (HIR::Function &function)
expected_ret_tyty);
context->switch_to_fn_body ();
- auto block_expr_ty
- = TypeCheckExpr::Resolve (function.get_definition ().get ());
+ auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
+
+ // emit check for
+ // error[E0121]: the type placeholder `_` is not allowed within types on item
+ const auto placeholder = ret_type->contains_infer ();
+ if (placeholder != nullptr && function.has_return_type ())
+ {
+ // FIXME
+ // this will be a great place for the Default Hir Visitor we want to
+ // grab the locations of the placeholders (HIR::InferredType) their
+ // location, for now maybe we can use their hirid to lookup the location
+ location_t placeholder_locus
+ = mappings.lookup_location (placeholder->get_ref ());
+ location_t type_locus = function.get_return_type ().get_locus ();
+ rich_location r (line_table, placeholder_locus);
+
+ bool have_expected_type
+ = block_expr_ty != nullptr && !block_expr_ty->is<TyTy::ErrorType> ();
+ if (!have_expected_type)
+ {
+ r.add_range (type_locus);
+ }
+ else
+ {
+ std::string fixit
+ = "replace with the correct type " + block_expr_ty->get_name ();
+ r.add_fixit_replace (type_locus, fixit.c_str ());
+ }
+
+ rust_error_at (r, ErrorCode::E0121,
+ "the type placeholder %<_%> is not allowed within types "
+ "on item signatures");
+ }
location_t fn_return_locus = function.has_function_return_type ()
- ? function.get_return_type ()->get_locus ()
+ ? function.get_return_type ().get_locus ()
: function.get_locus ();
- coercion_site (function.get_definition ()->get_mappings ().get_hirid (),
+ coercion_site (function.get_definition ().get_mappings ().get_hirid (),
TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
TyTy::TyWithLocation (block_expr_ty),
- function.get_definition ()->get_locus ());
+ function.get_definition ().get_locus ());
context->pop_return_type ();
@@ -690,7 +741,7 @@ TypeCheckItem::visit (HIR::ExternBlock &extern_block)
{
for (auto &item : extern_block.get_extern_items ())
{
- TypeCheckTopLevelExternItem::Resolve (item.get (), extern_block);
+ TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
}
}
@@ -712,17 +763,25 @@ TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
TraitReference *trait_reference = &TraitReference::error_node ();
if (impl_block.has_trait_ref ())
{
- std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
- trait_reference = TraitResolver::Resolve (*ref);
+ auto &ref = impl_block.get_trait_ref ();
+ trait_reference = TraitResolver::Resolve (ref);
rust_assert (!trait_reference->is_error ());
// we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
// for example
- specified_bound
- = get_predicate_from_bound (*ref, impl_block.get_type ().get ());
+ specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
+ impl_block.get_polarity ());
}
- TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ().get ());
+ TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
+ if (self->is<TyTy::ErrorType> ())
+ {
+ // we cannot check for unconstrained type arguments when the Self type is
+ // not resolved it will just add extra errors that dont help as well as
+ // the case where this could just be a recursive type query that should
+ // fail and will work later on anyway
+ return {substitutions, region_constraints};
+ }
// inherit the bounds
if (!specified_bound.is_error ())
@@ -749,14 +808,21 @@ TypeCheckItem::validate_trait_impl_block (
auto specified_bound = TyTy::TypeBoundPredicate::error ();
if (impl_block.has_trait_ref ())
{
- std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
+ auto &ref = impl_block.get_trait_ref ();
+ trait_reference = TraitResolver::Resolve (ref);
if (trait_reference->is_error ())
return;
// we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
// for example
- specified_bound
- = get_predicate_from_bound (*ref, impl_block.get_type ().get ());
+ specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
+ impl_block.get_polarity ());
+
+ // need to check that if this specified bound has super traits does this
+ // Self
+ // implement them?
+ specified_bound.validate_type_implements_super_traits (
+ *self, impl_block.get_type (), impl_block.get_trait_ref ());
}
bool is_trait_impl_block = !trait_reference->is_error ();
@@ -766,8 +832,7 @@ TypeCheckItem::validate_trait_impl_block (
if (!specified_bound.is_error ())
{
auto trait_item_ref
- = TypeCheckImplItemWithTrait::Resolve (&impl_block,
- impl_item.get (), self,
+ = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
specified_bound,
substitutions);
if (!trait_item_ref.is_error ())
@@ -840,7 +905,7 @@ TypeCheckItem::validate_trait_impl_block (
TyTy::BaseType *
TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
{
- return TypeCheckType::Resolve (impl_block.get_type ().get ());
+ return TypeCheckType::Resolve (impl_block.get_type ());
}
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index c655209..5662da5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -16,6 +16,9 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "rust-diagnostics.h"
+#include "rust-hir-map.h"
+#include "rust-hir-path.h"
#include "rust-hir-type-check-expr.h"
#include "rust-hir-type-check-type.h"
#include "rust-hir-type-check-item.h"
@@ -24,6 +27,7 @@
#include "rust-hir-path-probe.h"
#include "rust-type-util.h"
#include "rust-hir-type-bounds.h"
+#include "rust-hir-item.h"
#include "rust-session-manager.h"
#include "rust-immutable-name-resolution-context.h"
@@ -34,8 +38,7 @@ void
TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
{
HIR::QualifiedPathType qual_path_type = expr.get_path_type ();
- TyTy::BaseType *root
- = TypeCheckType::Resolve (qual_path_type.get_type ().get ());
+ TyTy::BaseType *root = TypeCheckType::Resolve (qual_path_type.get_type ());
if (root->get_kind () == TyTy::TypeKind::ERROR)
return;
@@ -48,8 +51,8 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
}
// Resolve the trait now
- std::unique_ptr<HIR::TypePath> &trait_path_ref = qual_path_type.get_trait ();
- TraitReference *trait_ref = TraitResolver::Resolve (*trait_path_ref.get ());
+ HIR::TypePath &trait_path_ref = qual_path_type.get_trait ();
+ TraitReference *trait_ref = TraitResolver::Resolve (trait_path_ref);
if (trait_ref->is_error ())
return;
@@ -64,8 +67,7 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
// get the predicate for the bound
auto specified_bound
- = get_predicate_from_bound (*trait_path_ref.get (),
- qual_path_type.get_type ().get ());
+ = get_predicate_from_bound (trait_path_ref, qual_path_type.get_type ());
if (specified_bound.is_error ())
return;
@@ -155,9 +157,20 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
bool fully_resolved = expr.get_segments ().size () <= 1;
if (fully_resolved)
{
- resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
- root_resolved_node_id);
- context->insert_receiver (expr.get_mappings ().get_hirid (), root);
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
+ Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+ nr_ctx.map_usage (Resolver2_0::Usage (
+ expr.get_mappings ().get_nodeid ()),
+ Resolver2_0::Definition (root_resolved_node_id));
+ }
+ else
+ {
+ resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
+ root_resolved_node_id);
+ }
return;
}
@@ -169,20 +182,72 @@ void
TypeCheckExpr::visit (HIR::PathInExpression &expr)
{
NodeId resolved_node_id = UNKNOWN_NODEID;
- size_t offset = -1;
- TyTy::BaseType *tyseg = resolve_root_path (expr, &offset, &resolved_node_id);
- if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
- return;
-
- bool fully_resolved = offset == expr.get_segments ().size ();
- if (fully_resolved)
+ if (expr.is_lang_item ())
{
- infered = tyseg;
- return;
+ auto lookup
+ = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
+ auto hir_id = mappings.lookup_node_to_hir (lookup);
+
+ // We can type resolve the path in expression easily as it is a lang
+ // item path, but we still need to setup the various generics and
+ // substitutions
+
+ // FIXME: We probably need to check *if* the type needs substitutions
+ // or not
+ if (LangItem::IsEnumVariant (expr.get_lang_item ()))
+ {
+ std::pair<HIR::Enum *, HIR::EnumItem *> enum_item_lookup
+ = mappings.lookup_hir_enumitem (*hir_id);
+ bool enum_item_ok = enum_item_lookup.first != nullptr
+ && enum_item_lookup.second != nullptr;
+ rust_assert (enum_item_ok);
+
+ HirId variant_id
+ = enum_item_lookup.second->get_mappings ().get_hirid ();
+
+ HIR::EnumItem *enum_item = enum_item_lookup.second;
+ resolved_node_id = enum_item->get_mappings ().get_nodeid ();
+
+ // insert the id of the variant we are resolved to
+ context->insert_variant_definition (expr.get_mappings ().get_hirid (),
+ variant_id);
+
+ query_type (variant_id, &infered);
+ infered = SubstMapper::InferSubst (infered, expr.get_locus ());
+ }
+ else
+ {
+ TyTy::BaseType *resolved = nullptr;
+ context->lookup_type (*hir_id, &resolved);
+
+ rust_assert (resolved);
+
+ query_type (*hir_id, &infered);
+
+ infered = SubstMapper::InferSubst (resolved, expr.get_locus ());
+ }
+
+ // FIXME: also we probably need to insert resolved types in the name
+ // resolver here
}
+ else
+ {
+ size_t offset = -1;
+ TyTy::BaseType *tyseg
+ = resolve_root_path (expr, &offset, &resolved_node_id);
+ if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
+ return;
- resolve_segments (resolved_node_id, expr.get_segments (), offset, tyseg,
- expr.get_mappings (), expr.get_locus ());
+ bool fully_resolved = offset == expr.get_segments ().size ();
+ if (fully_resolved)
+ {
+ infered = tyseg;
+ return;
+ }
+
+ resolve_segments (resolved_node_id, expr.get_segments (), offset, tyseg,
+ expr.get_mappings (), expr.get_locus ());
+ }
}
TyTy::BaseType *
@@ -204,12 +269,13 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
// assign the ref_node_id if we've found something
- nr_ctx.lookup (expr.get_mappings ().get_nodeid ())
- .map ([&ref_node_id] (NodeId resolved) { ref_node_id = resolved; });
+ nr_ctx.lookup (ast_node_id).map ([&ref_node_id] (NodeId resolved) {
+ ref_node_id = resolved;
+ });
}
else if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
@@ -245,6 +311,9 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
auto seg_is_module = mappings.lookup_module (ref).has_value ();
auto seg_is_crate = mappings.is_local_hirid_crate (ref);
+ auto seg_is_pattern = mappings.lookup_hir_pattern (ref).has_value ();
+ auto seg_is_self = is_root && !have_more_segments
+ && seg.get_segment ().as_string () == "self";
if (seg_is_module || seg_is_crate)
{
// A::B::C::this_is_a_module::D::E::F
@@ -267,7 +336,7 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
TyTy::BaseType *lookup = nullptr;
if (!query_type (ref, &lookup))
{
- if (is_root)
+ if (is_root || root_tyty == nullptr)
{
rust_error_at (expr.get_locus (), ErrorCode::E0425,
"cannot find value %qs in this scope",
@@ -321,7 +390,8 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
if (lookup->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
- else if (lookup->needs_generic_substitutions ())
+ else if (lookup->needs_generic_substitutions () && !seg_is_pattern
+ && !seg_is_self)
{
lookup = SubstMapper::InferSubst (lookup, expr.get_locus ());
}
@@ -343,12 +413,13 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
{
NodeId resolved_node_id = root_resolved_node_id;
TyTy::BaseType *prev_segment = tyseg;
- bool reciever_is_generic = prev_segment->get_kind () == TyTy::TypeKind::PARAM;
+ bool receiver_is_generic = prev_segment->get_kind () == TyTy::TypeKind::PARAM;
+ bool receiver_is_dyn = prev_segment->get_kind () == TyTy::TypeKind::DYNAMIC;
for (size_t i = offset; i < segments.size (); i++)
{
HIR::PathExprSegment &seg = segments.at (i);
- bool probe_impls = !reciever_is_generic;
+ bool probe_impls = !receiver_is_generic;
// probe the path is done in two parts one where we search impls if no
// candidate is found then we search extensions from traits
@@ -423,7 +494,7 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
}
}
- if (associated_impl_block != nullptr)
+ if (associated_impl_block != nullptr && !receiver_is_dyn)
{
// associated types
HirId impl_block_id
@@ -456,7 +527,7 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
{
// we need to setup with apropriate bounds
HIR::TypePath &bound_path
- = *associated->get_impl_block ()->get_trait_ref ().get ();
+ = associated->get_impl_block ()->get_trait_ref ();
const auto &trait_ref = *TraitResolver::Resolve (bound_path);
rust_assert (!trait_ref.is_error ());
@@ -464,8 +535,8 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
= impl_block_ty->lookup_predicate (trait_ref.get_defid ());
if (!predicate.is_error ())
impl_block_ty
- = associated->setup_associated_types (prev_segment,
- predicate);
+ = associated->setup_associated_types (prev_segment, predicate,
+ nullptr, false);
}
}
@@ -480,7 +551,7 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
return;
}
- else if (tyseg->needs_generic_substitutions () && !reciever_is_generic)
+ else if (tyseg->needs_generic_substitutions () && !receiver_is_generic)
{
location_t locus = seg.get_locus ();
tyseg = SubstMapper::InferSubst (tyseg, locus);
@@ -490,18 +561,17 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
}
rust_assert (resolved_node_id != UNKNOWN_NODEID);
- if (tyseg->needs_generic_substitutions () && !reciever_is_generic)
+ if (flag_name_resolution_2_0)
{
- location_t locus = segments.back ().get_locus ();
- tyseg = SubstMapper::InferSubst (tyseg, locus);
- if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
- return;
- }
-
- context->insert_receiver (expr_mappings.get_hirid (), prev_segment);
+ auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
+ Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+ nr_ctx.map_usage (Resolver2_0::Usage (expr_mappings.get_nodeid ()),
+ Resolver2_0::Definition (resolved_node_id));
+ }
// name scope first
- if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
+ else if (resolver->get_name_scope ().decl_was_declared_here (
+ resolved_node_id))
{
resolver->insert_resolved_name (expr_mappings.get_nodeid (),
resolved_node_id);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 88e4d32f..bd13f7a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -33,15 +33,15 @@ TypeCheckPattern::TypeCheckPattern (TyTy::BaseType *parent)
{}
TyTy::BaseType *
-TypeCheckPattern::Resolve (HIR::Pattern *pattern, TyTy::BaseType *parent)
+TypeCheckPattern::Resolve (HIR::Pattern &pattern, TyTy::BaseType *parent)
{
TypeCheckPattern resolver (parent);
- pattern->accept_vis (resolver);
+ pattern.accept_vis (resolver);
if (resolver.infered == nullptr)
- return new TyTy::ErrorType (pattern->get_mappings ().get_hirid ());
+ return new TyTy::ErrorType (pattern.get_mappings ().get_hirid ());
- resolver.context->insert_type (pattern->get_mappings (), resolver.infered);
+ resolver.context->insert_type (pattern.get_mappings (), resolver.infered);
return resolver.infered;
}
@@ -49,7 +49,7 @@ void
TypeCheckPattern::visit (HIR::PathInExpression &pattern)
{
// Pattern must be enum variants, sturcts, constants, or associated constansts
- TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (&pattern);
+ TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (pattern);
NodeId ref_node_id = UNKNOWN_NODEID;
bool maybe_item = false;
@@ -109,7 +109,7 @@ TypeCheckPattern::visit (HIR::PathInExpression &pattern)
rich_location rich_locus (
line_table, pattern.get_final_segment ().get_locus ());
rich_locus.add_fixit_replace (
- "not a unit struct, unit variant or constatnt");
+ "not a unit struct, unit variant or constant");
rust_error_at (rich_locus, ErrorCode::E0532,
"expected unit struct, unit variant or constant, "
"found %s %<%s%>",
@@ -161,7 +161,7 @@ TypeCheckPattern::visit (HIR::PathInExpression &pattern)
void
TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
{
- TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (&pattern.get_path ());
+ TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (pattern.get_path ());
if (pattern_ty->get_kind () != TyTy::TypeKind::ADT)
{
rust_error_at (
@@ -210,8 +210,8 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
// error[E0023]: this pattern has 0 fields, but the corresponding tuple
// variant has 1 field
- std::unique_ptr<HIR::TupleStructItems> &items = pattern.get_items ();
- switch (items->get_item_type ())
+ auto &items = pattern.get_items ();
+ switch (items.get_item_type ())
{
case HIR::TupleStructItems::RANGED: {
// TODO
@@ -221,7 +221,7 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
case HIR::TupleStructItems::MULTIPLE: {
HIR::TupleStructItemsNoRange &items_no_range
- = static_cast<HIR::TupleStructItemsNoRange &> (*items.get ());
+ = static_cast<HIR::TupleStructItemsNoRange &> (items);
if (items_no_range.get_patterns ().size () != variant->num_fields ())
{
@@ -247,7 +247,7 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
// setup the type on this pattern type
context->insert_type (pattern->get_mappings (), fty);
- TypeCheckPattern::Resolve (pattern.get (), fty);
+ TypeCheckPattern::Resolve (*pattern, fty);
}
}
break;
@@ -266,7 +266,7 @@ emit_invalid_field_error (location_t loc, Rust::TyTy::VariantDef *variant,
void
TypeCheckPattern::visit (HIR::StructPattern &pattern)
{
- TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (&pattern.get_path ());
+ TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (pattern.get_path ());
if (pattern_ty->get_kind () != TyTy::TypeKind::ADT)
{
rust_error_at (pattern.get_locus (),
@@ -277,7 +277,15 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
infered = pattern_ty;
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
- rust_assert (adt->number_of_variants () > 0);
+ if (adt->number_of_variants () == 0)
+ {
+ HIR::PathInExpression &path = pattern.get_path ();
+ const AST::SimplePath &sp = path.as_simple_path ();
+ rust_error_at (pattern.get_locus (), ErrorCode::E0574,
+ "expected struct, variant or union type, found enum %qs",
+ sp.as_string ().c_str ());
+ return;
+ }
TyTy::VariantDef *variant = adt->get_variants ().at (0);
if (adt->is_enum ())
@@ -285,7 +293,16 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
HirId variant_id = UNKNOWN_HIRID;
bool ok = context->lookup_variant_definition (
pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
- rust_assert (ok);
+ if (!ok)
+ {
+ HIR::PathInExpression &path = pattern.get_path ();
+ const AST::SimplePath &sp = path.as_simple_path ();
+ rust_error_at (
+ pattern.get_locus (), ErrorCode::E0574,
+ "expected struct, variant or union type, found enum %qs",
+ sp.as_string ().c_str ());
+ return;
+ }
ok = adt->lookup_variant_by_id (variant_id, &variant);
rust_assert (ok);
@@ -324,7 +341,7 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
case HIR::StructPatternField::ItemType::IDENT_PAT: {
HIR::StructPatternFieldIdentPat &ident
- = static_cast<HIR::StructPatternFieldIdentPat &> (*field.get ());
+ = static_cast<HIR::StructPatternFieldIdentPat &> (*field);
TyTy::StructFieldType *field = nullptr;
if (!variant->lookup_field (ident.get_identifier ().as_string (),
@@ -337,13 +354,13 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
named_fields.push_back (ident.get_identifier ().as_string ());
TyTy::BaseType *fty = field->get_field_type ();
- TypeCheckPattern::Resolve (ident.get_pattern ().get (), fty);
+ TypeCheckPattern::Resolve (ident.get_pattern (), fty);
}
break;
case HIR::StructPatternField::ItemType::IDENT: {
HIR::StructPatternFieldIdent &ident
- = static_cast<HIR::StructPatternFieldIdent &> (*field.get ());
+ = static_cast<HIR::StructPatternFieldIdent &> (*field);
TyTy::StructFieldType *field = nullptr;
if (!variant->lookup_field (ident.get_identifier ().as_string (),
@@ -440,12 +457,11 @@ void
TypeCheckPattern::visit (HIR::TuplePattern &pattern)
{
std::unique_ptr<HIR::TuplePatternItems> items;
- switch (pattern.get_items ()->get_item_type ())
+ switch (pattern.get_items ().get_item_type ())
{
case HIR::TuplePatternItems::ItemType::MULTIPLE: {
- HIR::TuplePatternItemsMultiple &ref
- = *static_cast<HIR::TuplePatternItemsMultiple *> (
- pattern.get_items ().get ());
+ auto &ref = static_cast<HIR::TuplePatternItemsMultiple &> (
+ pattern.get_items ());
auto resolved_parent = parent->destructure ();
if (resolved_parent->get_kind () != TyTy::TUPLE)
@@ -474,8 +490,7 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
auto &p = patterns[i];
TyTy::BaseType *par_type = par.get_field (i);
- TyTy::BaseType *elem
- = TypeCheckPattern::Resolve (p.get (), par_type);
+ TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
}
infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (),
@@ -521,9 +536,18 @@ TypeCheckPattern::visit (HIR::RangePattern &pattern)
}
void
-TypeCheckPattern::visit (HIR::IdentifierPattern &)
+TypeCheckPattern::visit (HIR::IdentifierPattern &pattern)
{
- infered = parent;
+ if (!pattern.get_is_ref ())
+ {
+ infered = parent;
+ return;
+ }
+
+ infered = new TyTy::ReferenceType (pattern.get_mappings ().get_hirid (),
+ TyTy::TyVar (parent->get_ref ()),
+ pattern.is_mut () ? Mutability::Mut
+ : Mutability::Imm);
}
void
@@ -543,10 +567,10 @@ TypeCheckPattern::visit (HIR::ReferencePattern &pattern)
return;
}
- TyTy::ReferenceType *ref_ty_ty = static_cast<TyTy::ReferenceType *> (parent);
+ auto &ref_ty_ty = static_cast<TyTy::ReferenceType &> (*parent);
TyTy::BaseType *infered_base
- = TypeCheckPattern::Resolve (pattern.get_referenced_pattern ().get (),
- ref_ty_ty->get_base ());
+ = TypeCheckPattern::Resolve (pattern.get_referenced_pattern (),
+ ref_ty_ty.get_base ());
infered = new TyTy::ReferenceType (pattern.get_mappings ().get_hirid (),
TyTy::TyVar (infered_base->get_ref ()),
pattern.is_mut () ? Mutability::Mut
@@ -578,15 +602,14 @@ TypeCheckPattern::emit_pattern_size_error (const HIR::Pattern &pattern,
TyTy::BaseType *
TypeCheckPattern::typecheck_range_pattern_bound (
- std::unique_ptr<Rust::HIR::RangePatternBound> &bound,
- Analysis::NodeMapping mappings, location_t locus)
+ Rust::HIR::RangePatternBound &bound, Analysis::NodeMapping mappings,
+ location_t locus)
{
TyTy::BaseType *resolved_bound = nullptr;
- switch (bound->get_bound_type ())
+ switch (bound.get_bound_type ())
{
case HIR::RangePatternBound::RangePatternBoundType::LITERAL: {
- HIR::RangePatternBoundLiteral &ref
- = *static_cast<HIR::RangePatternBoundLiteral *> (bound.get ());
+ auto &ref = static_cast<HIR::RangePatternBoundLiteral &> (bound);
HIR::Literal lit = ref.get_literal ();
@@ -595,18 +618,16 @@ TypeCheckPattern::typecheck_range_pattern_bound (
break;
case HIR::RangePatternBound::RangePatternBoundType::PATH: {
- HIR::RangePatternBoundPath &ref
- = *static_cast<HIR::RangePatternBoundPath *> (bound.get ());
+ auto &ref = static_cast<HIR::RangePatternBoundPath &> (bound);
- resolved_bound = TypeCheckExpr::Resolve (&ref.get_path ());
+ resolved_bound = TypeCheckExpr::Resolve (ref.get_path ());
}
break;
case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: {
- HIR::RangePatternBoundQualPath &ref
- = *static_cast<HIR::RangePatternBoundQualPath *> (bound.get ());
+ auto &ref = static_cast<HIR::RangePatternBoundQualPath &> (bound);
- resolved_bound = TypeCheckExpr::Resolve (&ref.get_qualified_path ());
+ resolved_bound = TypeCheckExpr::Resolve (ref.get_qualified_path ());
}
break;
}
@@ -623,7 +644,7 @@ TypeCheckPattern::visit (HIR::AltPattern &pattern)
std::vector<TyTy::BaseType *> types;
for (auto &alt_pattern : alts)
{
- types.push_back (TypeCheckPattern::Resolve (alt_pattern.get (), parent));
+ types.push_back (TypeCheckPattern::Resolve (*alt_pattern, parent));
}
TyTy::BaseType *alt_pattern_type
@@ -642,16 +663,17 @@ TypeCheckPattern::visit (HIR::AltPattern &pattern)
}
TyTy::BaseType *
-ClosureParamInfer::Resolve (HIR::Pattern *pattern)
+ClosureParamInfer::Resolve (HIR::Pattern &pattern)
{
ClosureParamInfer resolver;
- pattern->accept_vis (resolver);
+ pattern.accept_vis (resolver);
if (resolver.infered->get_kind () != TyTy::TypeKind::ERROR)
{
- resolver.context->insert_implicit_type (resolver.infered);
+ resolver.context->insert_implicit_type (resolver.infered->get_ref (),
+ resolver.infered);
resolver.mappings.insert_location (resolver.infered->get_ref (),
- pattern->get_locus ());
+ pattern.get_locus ());
}
return resolver.infered;
}
@@ -682,7 +704,7 @@ void
ClosureParamInfer::visit (HIR::ReferencePattern &pattern)
{
TyTy::BaseType *element
- = ClosureParamInfer::Resolve (pattern.get_referenced_pattern ().get ());
+ = ClosureParamInfer::Resolve (pattern.get_referenced_pattern ());
HirId id = pattern.get_mappings ().get_hirid ();
infered = new TyTy::ReferenceType (id, TyTy::TyVar (element->get_ref ()),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.h b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
index ba45b65..d477181 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
@@ -28,7 +28,7 @@ namespace Resolver {
class TypeCheckPattern : public TypeCheckBase, public HIR::HIRPatternVisitor
{
public:
- static TyTy::BaseType *Resolve (HIR::Pattern *pattern,
+ static TyTy::BaseType *Resolve (HIR::Pattern &pattern,
TyTy::BaseType *parent);
void visit (HIR::PathInExpression &pattern) override;
@@ -47,9 +47,10 @@ public:
private:
TypeCheckPattern (TyTy::BaseType *parent);
- TyTy::BaseType *typecheck_range_pattern_bound (
- std::unique_ptr<Rust::HIR::RangePatternBound> &bound,
- Analysis::NodeMapping mappings, location_t locus);
+ TyTy::BaseType *
+ typecheck_range_pattern_bound (Rust::HIR::RangePatternBound &bound,
+ Analysis::NodeMapping mappings,
+ location_t locus);
void emit_pattern_size_error (const HIR::Pattern &pattern,
size_t expected_field_count,
@@ -62,7 +63,7 @@ private:
class ClosureParamInfer : private TypeCheckBase, private HIR::HIRPatternVisitor
{
public:
- static TyTy::BaseType *Resolve (HIR::Pattern *pattern);
+ static TyTy::BaseType *Resolve (HIR::Pattern &pattern);
void visit (HIR::PathInExpression &pattern) override;
void visit (HIR::StructPattern &pattern) override;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc
index 6d27d3d..4e53856 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc
@@ -28,23 +28,23 @@ namespace Rust {
namespace Resolver {
TyTy::BaseType *
-TypeCheckStmt::Resolve (HIR::Stmt *stmt)
+TypeCheckStmt::Resolve (HIR::Stmt &stmt)
{
TypeCheckStmt resolver;
- stmt->accept_vis (resolver);
+ stmt.accept_vis (resolver);
return resolver.infered;
}
void
TypeCheckStmt::visit (HIR::ExprStmt &stmt)
{
- infered = TypeCheckExpr::Resolve (stmt.get_expr ().get ());
+ infered = TypeCheckExpr::Resolve (stmt.get_expr ());
}
void
TypeCheckStmt::visit (HIR::EmptyStmt &stmt)
{
- infered = TyTy::TupleType::get_unit_type (stmt.get_mappings ().get_hirid ());
+ infered = TyTy::TupleType::get_unit_type ();
}
void
@@ -52,21 +52,20 @@ TypeCheckStmt::visit (HIR::ExternBlock &extern_block)
{
for (auto &item : extern_block.get_extern_items ())
{
- TypeCheckTopLevelExternItem::Resolve (item.get (), extern_block);
+ TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
}
}
void
TypeCheckStmt::visit (HIR::ConstantItem &constant)
{
- TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
- TyTy::BaseType *expr_type
- = TypeCheckExpr::Resolve (constant.get_expr ().get ());
+ TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
+ TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
infered = coercion_site (
constant.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
- TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
+ TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
+ TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
constant.get_locus ());
context->insert_type (constant.get_mappings (), infered);
}
@@ -74,15 +73,15 @@ TypeCheckStmt::visit (HIR::ConstantItem &constant)
void
TypeCheckStmt::visit (HIR::LetStmt &stmt)
{
- infered = TyTy::TupleType::get_unit_type (stmt.get_mappings ().get_hirid ());
+ infered = TyTy::TupleType::get_unit_type ();
- HIR::Pattern &stmt_pattern = *stmt.get_pattern ();
+ auto &stmt_pattern = stmt.get_pattern ();
TyTy::BaseType *init_expr_ty = nullptr;
location_t init_expr_locus = UNKNOWN_LOCATION;
if (stmt.has_init_expr ())
{
- init_expr_locus = stmt.get_init_expr ()->get_locus ();
- init_expr_ty = TypeCheckExpr::Resolve (stmt.get_init_expr ().get ());
+ init_expr_locus = stmt.get_init_expr ().get_locus ();
+ init_expr_ty = TypeCheckExpr::Resolve (stmt.get_init_expr ());
if (init_expr_ty->get_kind () == TyTy::TypeKind::ERROR)
return;
@@ -94,8 +93,8 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
location_t specified_ty_locus;
if (stmt.has_type ())
{
- specified_ty = TypeCheckType::Resolve (stmt.get_type ().get ());
- specified_ty_locus = stmt.get_type ()->get_locus ();
+ specified_ty = TypeCheckType::Resolve (stmt.get_type ());
+ specified_ty_locus = stmt.get_type ().get_locus ();
}
// let x:i32 = 123;
@@ -105,19 +104,19 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
TyTy::TyWithLocation (specified_ty, specified_ty_locus),
TyTy::TyWithLocation (init_expr_ty, init_expr_locus),
stmt.get_locus ());
- TypeCheckPattern::Resolve (&stmt_pattern, specified_ty);
+ TypeCheckPattern::Resolve (stmt_pattern, specified_ty);
}
else
{
// let x:i32;
if (specified_ty != nullptr)
{
- TypeCheckPattern::Resolve (&stmt_pattern, specified_ty);
+ TypeCheckPattern::Resolve (stmt_pattern, specified_ty);
}
// let x = 123;
else if (init_expr_ty != nullptr)
{
- TypeCheckPattern::Resolve (&stmt_pattern, init_expr_ty);
+ TypeCheckPattern::Resolve (stmt_pattern, init_expr_ty);
}
// let x;
else
@@ -127,7 +126,7 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
TyTy::InferType::InferTypeKind::GENERAL,
TyTy::InferType::TypeHint::Default (),
stmt.get_locus ());
- TypeCheckPattern::Resolve (&stmt_pattern, infer);
+ TypeCheckPattern::Resolve (stmt_pattern, infer);
}
}
}
@@ -135,12 +134,12 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
void
TypeCheckStmt::visit (HIR::TypePath &path)
{
- infered = TypeCheckType::Resolve (&path);
+ infered = TypeCheckType::Resolve (path);
}
void
TypeCheckStmt::visit (HIR::QualifiedPathInType &path)
{
- infered = TypeCheckType::Resolve (&path);
+ infered = TypeCheckType::Resolve (path);
}
void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index 6d91372..d679805 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -28,7 +28,7 @@ namespace Resolver {
class TypeCheckStmt : private TypeCheckBase, private HIR::HIRStmtVisitor
{
public:
- static TyTy::BaseType *Resolve (HIR::Stmt *stmt);
+ static TyTy::BaseType *Resolve (HIR::Stmt &stmt);
void visit (HIR::ExprStmt &stmt) override;
void visit (HIR::EmptyStmt &stmt) override;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
index cfa17ac..7e3a57a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
@@ -33,7 +33,7 @@ namespace Resolver {
class TypeCheckStructExpr : public TypeCheckBase
{
public:
- static TyTy::BaseType *Resolve (HIR::StructExprStructFields *expr);
+ static TyTy::BaseType *Resolve (HIR::StructExprStructFields &expr);
// Helper for making any errors
static Error
@@ -49,7 +49,7 @@ protected:
bool visit (HIR::StructExprFieldIdentifier &field);
private:
- TypeCheckStructExpr (HIR::Expr *e);
+ TypeCheckStructExpr (HIR::Expr &e);
// result
TyTy::BaseType *resolved;
@@ -60,6 +60,9 @@ private:
TyTy::BaseType *resolved_field_value_expr;
std::set<std::string> fields_assigned;
std::map<size_t, HIR::StructExprField *> adtFieldIndexToField;
+
+ // parent
+ HIR::Expr &parent;
};
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index 5018829..df1636a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -24,18 +24,18 @@
namespace Rust {
namespace Resolver {
-TypeCheckStructExpr::TypeCheckStructExpr (HIR::Expr *e)
+TypeCheckStructExpr::TypeCheckStructExpr (HIR::Expr &e)
: TypeCheckBase (),
- resolved (new TyTy::ErrorType (e->get_mappings ().get_hirid ())),
+ resolved (new TyTy::ErrorType (e.get_mappings ().get_hirid ())),
struct_path_resolved (nullptr),
- variant (&TyTy::VariantDef::get_error_node ())
+ variant (&TyTy::VariantDef::get_error_node ()), parent (e)
{}
TyTy::BaseType *
-TypeCheckStructExpr::Resolve (HIR::StructExprStructFields *expr)
+TypeCheckStructExpr::Resolve (HIR::StructExprStructFields &expr)
{
TypeCheckStructExpr resolver (expr);
- resolver.resolve (*expr);
+ resolver.resolve (expr);
return resolver.resolved;
}
@@ -43,7 +43,7 @@ void
TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
{
TyTy::BaseType *struct_path_ty
- = TypeCheckExpr::Resolve (&struct_expr.get_struct_name ());
+ = TypeCheckExpr::Resolve (struct_expr.get_struct_name ());
if (struct_path_ty->get_kind () != TyTy::TypeKind::ADT)
{
rust_error_at (struct_expr.get_struct_name ().get_locus (),
@@ -56,17 +56,18 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
if (struct_expr.has_struct_base ())
{
TyTy::BaseType *base_resolved
- = TypeCheckExpr::Resolve (struct_expr.struct_base->base_struct.get ());
+ = TypeCheckExpr::Resolve (struct_expr.get_struct_base ().get_base ());
TyTy::BaseType *base_unify = unify_site (
- struct_expr.struct_base->base_struct->get_mappings ().get_hirid (),
+ struct_expr.get_struct_base ().get_base ().get_mappings ().get_hirid (),
TyTy::TyWithLocation (struct_path_resolved),
TyTy::TyWithLocation (base_resolved),
- struct_expr.struct_base->base_struct->get_locus ());
+ struct_expr.get_struct_base ().get_base ().get_locus ());
if (base_unify->get_kind () != struct_path_ty->get_kind ())
{
- rust_fatal_error (struct_expr.struct_base->base_struct->get_locus (),
- "incompatible types for base struct reference");
+ rust_error_at (
+ struct_expr.get_struct_base ().get_base ().get_locus (),
+ "incompatible types for base struct reference");
return;
}
@@ -81,7 +82,16 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
bool ok = context->lookup_variant_definition (
struct_expr.get_struct_name ().get_mappings ().get_hirid (),
&variant_id);
- rust_assert (ok);
+ if (!ok)
+ {
+ rich_location r (line_table, struct_expr.get_locus ());
+ r.add_range (struct_expr.get_struct_name ().get_locus ());
+ rust_error_at (
+ struct_expr.get_struct_name ().get_locus (), ErrorCode::E0574,
+ "expected a struct, variant or union type, found enum %qs",
+ struct_path_resolved->get_name ().c_str ());
+ return;
+ }
ok = struct_path_resolved->lookup_variant_by_id (variant_id, &variant);
rust_assert (ok);
@@ -117,29 +127,14 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
break;
}
- if (!ok)
- {
- return;
- }
-
- if (resolved_field_value_expr == nullptr)
- {
- rust_fatal_error (field->get_locus (),
- "failed to resolve type for field");
- ok = false;
- break;
- }
-
- context->insert_type (field->get_mappings (), resolved_field_value_expr);
+ if (ok)
+ context->insert_type (field->get_mappings (),
+ resolved_field_value_expr);
}
- // something failed setting up the fields
+ // something failed setting up the fields and error's emitted
if (!ok)
- {
- rust_error_at (struct_expr.get_locus (),
- "constructor type resolution failure");
- return;
- }
+ return;
// check the arguments are all assigned and fix up the ordering
std::vector<std::string> missing_field_names;
@@ -190,26 +185,29 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
for (auto &missing : missing_fields)
{
HIR::Expr *receiver
- = struct_expr.struct_base->base_struct->clone_expr_impl ();
+ = struct_expr.get_struct_base ().get_base ().clone_expr_impl ();
HIR::StructExprField *implicit_field = nullptr;
AST::AttrVec outer_attribs;
auto crate_num = mappings.get_current_crate ();
- Analysis::NodeMapping mapping (
- crate_num,
- struct_expr.struct_base->base_struct->get_mappings ()
- .get_nodeid (),
- mappings.get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID);
+ Analysis::NodeMapping mapping (crate_num,
+ struct_expr.get_struct_base ()
+ .get_base ()
+ .get_mappings ()
+ .get_nodeid (),
+ mappings.get_next_hir_id (
+ crate_num),
+ UNKNOWN_LOCAL_DEFID);
HIR::Expr *field_value = new HIR::FieldAccessExpr (
mapping, std::unique_ptr<HIR::Expr> (receiver), missing,
std::move (outer_attribs),
- struct_expr.struct_base->base_struct->get_locus ());
+ struct_expr.get_struct_base ().get_base ().get_locus ());
implicit_field = new HIR::StructExprFieldIdentifierValue (
mapping, missing, std::unique_ptr<HIR::Expr> (field_value),
- struct_expr.struct_base->base_struct->get_locus ());
+ struct_expr.get_struct_base ().get_base ().get_locus ());
size_t field_index;
bool ok = variant->lookup_field (missing, nullptr, &field_index);
@@ -267,8 +265,11 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifierValue &field)
&field_index);
if (!ok)
{
- rust_error_at (field.get_locus (), "unknown field");
- return true;
+ rich_location r (line_table, parent.get_locus ());
+ r.add_range (field.get_locus ());
+ rust_error_at (r, ErrorCode::E0560, "unknown field %qs",
+ field.field_name.as_string ().c_str ());
+ return false;
}
auto it = adtFieldIndexToField.find (field_index);
@@ -284,8 +285,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifierValue &field)
return false;
}
- TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ().get ());
- location_t value_locus = field.get_value ()->get_locus ();
+ TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ());
+ location_t value_locus = field.get_value ().get_locus ();
HirId coercion_site_id = field.get_mappings ().get_hirid ();
resolved_field_value_expr
@@ -313,8 +314,11 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue &field)
bool ok = variant->lookup_field (field_name, &field_type, &field_index);
if (!ok)
{
- rust_error_at (field.get_locus (), "unknown field");
- return true;
+ rich_location r (line_table, parent.get_locus ());
+ r.add_range (field.get_locus ());
+ rust_error_at (r, ErrorCode::E0560, "unknown field %qs",
+ field_name.c_str ());
+ return false;
}
auto it = adtFieldIndexToField.find (field_index);
@@ -330,8 +334,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue &field)
return false;
}
- TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ().get ());
- location_t value_locus = field.get_value ()->get_locus ();
+ TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ());
+ location_t value_locus = field.get_value ().get_locus ();
HirId coercion_site_id = field.get_mappings ().get_hirid ();
resolved_field_value_expr
@@ -385,7 +389,7 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifier &field)
HIR::GenericArgs::create_empty ());
HIR::PathInExpression expr (mappings_copy2, {seg}, field.get_locus (), false,
{});
- TyTy::BaseType *value = TypeCheckExpr::Resolve (&expr);
+ TyTy::BaseType *value = TypeCheckExpr::Resolve (expr);
location_t value_locus = expr.get_locus ();
HirId coercion_site_id = field.get_mappings ().get_hirid ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index f7ae8cc..6919093 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -18,6 +18,8 @@
#include "rust-hir-type-check-type.h"
#include "options.h"
+#include "optional.h"
+#include "rust-hir-map.h"
#include "rust-hir-trait-resolve.h"
#include "rust-hir-type-check-expr.h"
#include "rust-hir-path-probe.h"
@@ -26,18 +28,19 @@
#include "rust-mapping-common.h"
#include "rust-substitution-mapper.h"
#include "rust-type-util.h"
+#include "rust-system.h"
namespace Rust {
namespace Resolver {
HIR::GenericArgs
-TypeCheckResolveGenericArguments::resolve (HIR::TypePathSegment *segment)
+TypeCheckResolveGenericArguments::resolve (HIR::TypePathSegment &segment)
{
- TypeCheckResolveGenericArguments resolver (segment->get_locus ());
- switch (segment->get_type ())
+ TypeCheckResolveGenericArguments resolver (segment.get_locus ());
+ switch (segment.get_type ())
{
case HIR::TypePathSegment::SegmentType::GENERIC:
- resolver.visit (static_cast<HIR::TypePathSegmentGeneric &> (*segment));
+ resolver.visit (static_cast<HIR::TypePathSegmentGeneric &> (segment));
break;
default:
@@ -53,20 +56,20 @@ TypeCheckResolveGenericArguments::visit (HIR::TypePathSegmentGeneric &generic)
}
TyTy::BaseType *
-TypeCheckType::Resolve (HIR::Type *type)
+TypeCheckType::Resolve (HIR::Type &type)
{
// is it already resolved?
auto context = TypeCheckContext::get ();
TyTy::BaseType *resolved = nullptr;
bool already_resolved
- = context->lookup_type (type->get_mappings ().get_hirid (), &resolved);
+ = context->lookup_type (type.get_mappings ().get_hirid (), &resolved);
if (already_resolved)
return resolved;
- TypeCheckType resolver (type->get_mappings ().get_hirid ());
- type->accept_vis (resolver);
+ TypeCheckType resolver (type.get_mappings ().get_hirid ());
+ type.accept_vis (resolver);
rust_assert (resolver.translated != nullptr);
- resolver.context->insert_type (type->get_mappings (), resolver.translated);
+ resolver.context->insert_type (type.get_mappings (), resolver.translated);
return resolver.translated;
}
@@ -82,20 +85,20 @@ TypeCheckType::visit (HIR::BareFunctionType &fntype)
TyTy::BaseType *return_type;
if (fntype.has_return_type ())
{
- return_type = TypeCheckType::Resolve (fntype.get_return_type ().get ());
+ return_type = TypeCheckType::Resolve (fntype.get_return_type ());
}
else
{
// needs a new implicit ID
HirId ref = mappings.get_next_hir_id ();
- return_type = TyTy::TupleType::get_unit_type (ref);
+ return_type = TyTy::TupleType::get_unit_type ();
context->insert_implicit_type (ref, return_type);
}
std::vector<TyTy::TyVar> params;
for (auto &param : fntype.get_function_params ())
{
- TyTy::BaseType *ptype = TypeCheckType::Resolve (param.get_type ().get ());
+ TyTy::BaseType *ptype = TypeCheckType::Resolve (param.get_type ());
params.push_back (TyTy::TyVar (ptype->get_ref ()));
}
@@ -109,19 +112,14 @@ TypeCheckType::visit (HIR::TupleType &tuple)
{
if (tuple.is_unit_type ())
{
- auto unit_node_id = resolver->get_unit_type_node_id ();
- if (!context->lookup_builtin (unit_node_id, &translated))
- {
- rust_error_at (tuple.get_locus (),
- "failed to lookup builtin unit type");
- }
+ translated = TyTy::TupleType::get_unit_type ();
return;
}
std::vector<TyTy::TyVar> fields;
for (auto &elem : tuple.get_elems ())
{
- auto field_ty = TypeCheckType::Resolve (elem.get ());
+ auto field_ty = TypeCheckType::Resolve (*elem);
fields.push_back (TyTy::TyVar (field_ty->get_ref ()));
}
@@ -136,11 +134,14 @@ TypeCheckType::visit (HIR::TypePath &path)
// this can happen so we need to look up the root then resolve the
// remaining segments if possible
+ bool wasBigSelf = false;
size_t offset = 0;
- NodeId resolved_node_id = UNKNOWN_NODEID;
- TyTy::BaseType *root = resolve_root_path (path, &offset, &resolved_node_id);
+ TyTy::BaseType *root = resolve_root_path (path, &offset, &wasBigSelf);
if (root->get_kind () == TyTy::TypeKind::ERROR)
- return;
+ {
+ rust_debug_loc (path.get_locus (), "failed to resolve type-path type");
+ return;
+ }
TyTy::BaseType *path_type = root->clone ();
path_type->set_ref (path.get_mappings ().get_hirid ());
@@ -150,21 +151,25 @@ TypeCheckType::visit (HIR::TypePath &path)
if (fully_resolved)
{
translated = path_type;
+ rust_debug_loc (path.get_locus (), "root resolved type-path to: [%s]",
+ translated->debug_str ().c_str ());
return;
}
translated
- = resolve_segments (resolved_node_id, path.get_mappings ().get_hirid (),
- path.get_segments (), offset, path_type,
- path.get_mappings (), path.get_locus ());
+ = resolve_segments (path.get_mappings ().get_hirid (), path.get_segments (),
+ offset, path_type, path.get_mappings (),
+ path.get_locus (), wasBigSelf);
+
+ rust_debug_loc (path.get_locus (), "resolved type-path to: [%s]",
+ translated->debug_str ().c_str ());
}
void
TypeCheckType::visit (HIR::QualifiedPathInType &path)
{
HIR::QualifiedPathType qual_path_type = path.get_path_type ();
- TyTy::BaseType *root
- = TypeCheckType::Resolve (qual_path_type.get_type ().get ());
+ TyTy::BaseType *root = TypeCheckType::Resolve (qual_path_type.get_type ());
if (root->get_kind () == TyTy::TypeKind::ERROR)
{
rust_debug_loc (path.get_locus (), "failed to resolve the root");
@@ -173,39 +178,25 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
if (!qual_path_type.has_as_clause ())
{
- // then this is just a normal path-in-expression
- NodeId root_resolved_node_id = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_type (
- qual_path_type.get_type ()->get_mappings ().get_nodeid (),
- &root_resolved_node_id);
- rust_assert (ok);
-
- translated = resolve_segments (root_resolved_node_id,
- path.get_mappings ().get_hirid (),
- path.get_segments (), 0, translated,
- path.get_mappings (), path.get_locus ());
+ translated
+ = resolve_segments (path.get_mappings ().get_hirid (),
+ path.get_segments (), 0, translated,
+ path.get_mappings (), path.get_locus (), false);
return;
}
// Resolve the trait now
- std::unique_ptr<HIR::TypePath> &trait_path_ref = qual_path_type.get_trait ();
- TraitReference *trait_ref = TraitResolver::Resolve (*trait_path_ref.get ());
+ auto &trait_path_ref = qual_path_type.get_trait ();
+ TraitReference *trait_ref = TraitResolver::Resolve (trait_path_ref);
if (trait_ref->is_error ())
return;
- // does this type actually implement this type-bound?
- if (!TypeBoundsProbe::is_bound_satisfied_for_type (root, trait_ref))
- {
- rust_error_at (qual_path_type.get_locus (),
- "root does not satisfy specified trait-bound");
- return;
- }
-
// get the predicate for the bound
auto specified_bound
- = get_predicate_from_bound (*qual_path_type.get_trait ().get (),
- qual_path_type.get_type ().get ());
+ = get_predicate_from_bound (qual_path_type.get_trait (),
+ qual_path_type.get_type (),
+ BoundPolarity::RegularBound, true);
if (specified_bound.is_error ())
return;
@@ -213,18 +204,17 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
root->inherit_bounds ({specified_bound});
// lookup the associated item from the specified bound
- std::unique_ptr<HIR::TypePathSegment> &item_seg
- = path.get_associated_segment ();
- HIR::PathIdentSegment item_seg_identifier = item_seg->get_ident_segment ();
+ HIR::TypePathSegment &item_seg = path.get_associated_segment ();
+ HIR::PathIdentSegment item_seg_identifier = item_seg.get_ident_segment ();
TyTy::TypeBoundPredicateItem item
= specified_bound.lookup_associated_item (item_seg_identifier.as_string ());
if (item.is_error ())
{
std::string item_seg_ident_name, rich_msg;
- item_seg_ident_name = qual_path_type.get_trait ()->as_string ();
+ item_seg_ident_name = qual_path_type.get_trait ().as_string ();
rich_msg = "not found in `" + item_seg_ident_name + "`";
- rich_location richloc (line_table, item_seg->get_locus ());
+ rich_location richloc (line_table, item_seg.get_locus ());
richloc.add_fixit_replace (rich_msg.c_str ());
rust_error_at (richloc, ErrorCode::E0576,
@@ -264,7 +254,6 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
}
}
- NodeId root_resolved_node_id = UNKNOWN_NODEID;
if (impl_item == nullptr)
{
// this may be valid as there could be a default trait implementation here
@@ -272,41 +261,32 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
// not because this will have already been validated as part of the trait
// impl block
translated = item.get_tyty_for_receiver (root);
- root_resolved_node_id
- = item.get_raw_item ()->get_mappings ().get_nodeid ();
}
else
{
HirId impl_item_id = impl_item->get_impl_mappings ().get_hirid ();
bool ok = query_type (impl_item_id, &translated);
if (!ok)
- {
- // FIXME
- // I think query_type should error if required here anyway
- return;
- }
+ return;
if (!args.is_error ())
{
// apply the args
translated = SubstMapperInternal::Resolve (translated, args);
}
-
- root_resolved_node_id = impl_item->get_impl_mappings ().get_nodeid ();
}
// turbo-fish segment path::<ty>
- if (item_seg->get_type () == HIR::TypePathSegment::SegmentType::GENERIC)
+ if (item_seg.get_type () == HIR::TypePathSegment::SegmentType::GENERIC)
{
- HIR::TypePathSegmentGeneric &generic_seg
- = static_cast<HIR::TypePathSegmentGeneric &> (*item_seg.get ());
+ auto &generic_seg = static_cast<HIR::TypePathSegmentGeneric &> (item_seg);
// turbo-fish segment path::<ty>
if (generic_seg.has_generic_args ())
{
if (!translated->has_substitutions_defined ())
{
- rust_error_at (item_seg->get_locus (),
+ rust_error_at (item_seg.get_locus (),
"substitutions not supported for %s",
translated->as_string ().c_str ());
translated
@@ -324,25 +304,21 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
// continue on as a path-in-expression
bool fully_resolved = path.get_segments ().empty ();
if (fully_resolved)
- {
- resolver->insert_resolved_type (path.get_mappings ().get_nodeid (),
- root_resolved_node_id);
- context->insert_receiver (path.get_mappings ().get_hirid (), root);
- return;
- }
+ return;
translated
- = resolve_segments (root_resolved_node_id,
- path.get_mappings ().get_hirid (), path.get_segments (),
- 0, translated, path.get_mappings (), path.get_locus ());
+ = resolve_segments (path.get_mappings ().get_hirid (), path.get_segments (),
+ 0, translated, path.get_mappings (), path.get_locus (),
+ false);
}
TyTy::BaseType *
TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
- NodeId *root_resolved_node_id)
+ bool *wasBigSelf)
{
TyTy::BaseType *root_tyty = nullptr;
*offset = 0;
+
for (size_t i = 0; i < path.get_num_segments (); i++)
{
std::unique_ptr<HIR::TypePathSegment> &seg = path.get_segments ().at (i);
@@ -354,19 +330,25 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
// then lookup the reference_node_id
NodeId ref_node_id = UNKNOWN_NODEID;
- // FIXME: HACK: ARTHUR: Remove this
- if (flag_name_resolution_2_0)
+ if (seg->is_lang_item ())
+ ref_node_id = Analysis::Mappings::get ().get_lang_item_node (
+ seg->get_lang_item ());
+ else
{
- auto nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- // assign the ref_node_id if we've found something
- nr_ctx.lookup (path.get_mappings ().get_nodeid ())
- .map ([&ref_node_id, &path] (NodeId resolved) {
- ref_node_id = resolved;
- });
+ // FIXME: HACK: ARTHUR: Remove this
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx = Resolver2_0::ImmutableNameResolutionContext::get ()
+ .resolver ();
+
+ // assign the ref_node_id if we've found something
+ nr_ctx.lookup (ast_node_id)
+ .map (
+ [&ref_node_id] (NodeId resolved) { ref_node_id = resolved; });
+ }
+ else if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
+ resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
}
- else if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
// ref_node_id is the NodeId that the segments refers to.
if (ref_node_id == UNKNOWN_NODEID)
@@ -375,12 +357,22 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
{
rust_error_at (seg->get_locus (),
"unknown reference for resolved name: %qs",
- seg->get_ident_segment ().as_string ().c_str ());
+ seg->as_string ().c_str ());
+ return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+ }
+ else if (root_tyty == nullptr)
+ {
+ rust_error_at (seg->get_locus (),
+ "unknown reference for resolved name: %qs",
+ seg->as_string ().c_str ());
return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
}
return root_tyty;
}
+ if (seg->is_ident_only () && seg->as_string () == "Self")
+ *wasBigSelf = true;
+
// node back to HIR
tl::optional<HirId> hid = mappings.lookup_node_to_hir (ref_node_id);
if (!hid.has_value ())
@@ -425,12 +417,14 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
TyTy::BaseType *lookup = nullptr;
if (!query_type (ref, &lookup))
{
- if (is_root)
+ if (is_root || root_tyty == nullptr)
{
rust_error_at (seg->get_locus (),
- "failed to resolve root segment");
+ "failed to resolve type path segment: %qs",
+ seg->as_string ().c_str ());
return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
}
+
return root_tyty;
}
@@ -457,13 +451,13 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
// turbo-fish segment path::<ty>
if (seg->is_generic_segment ())
{
- HIR::TypePathSegmentGeneric *generic_segment
- = static_cast<HIR::TypePathSegmentGeneric *> (seg.get ());
+ auto &generic_segment
+ = static_cast<HIR::TypePathSegmentGeneric &> (*seg);
auto regions = context->regions_from_generic_args (
- generic_segment->get_generic_args ());
+ generic_segment.get_generic_args ());
lookup = SubstMapper::Resolve (lookup, path.get_locus (),
- &generic_segment->get_generic_args (),
+ &generic_segment.get_generic_args (),
regions);
if (lookup->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (seg->get_mappings ().get_hirid ());
@@ -477,7 +471,6 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
context->regions_from_generic_args (empty));
}
- *root_resolved_node_id = ref_node_id;
*offset = *offset + 1;
root_tyty = lookup;
@@ -490,14 +483,58 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
return root_tyty;
}
+bool
+TypeCheckType::resolve_associated_type (const std::string &search,
+ TypeCheckBlockContextItem &ctx,
+ TyTy::BaseType **result)
+{
+ if (ctx.is_trait_block ())
+ {
+ HIR::Trait &trait = ctx.get_trait ();
+ for (auto &item : trait.get_trait_items ())
+ {
+ if (item->get_item_kind () != HIR::TraitItem::TraitItemKind::TYPE)
+ continue;
+
+ if (item->trait_identifier () == search)
+ {
+ HirId item_id = item->get_mappings ().get_hirid ();
+ if (query_type (item_id, result))
+ return true;
+ }
+ }
+
+ // FIXME
+ // query any parent trait?
+
+ return false;
+ }
+
+ // look for any segment in here which matches
+ HIR::ImplBlock &block = ctx.get_impl_block ();
+ for (auto &item : block.get_impl_items ())
+ {
+ if (item->get_impl_item_type () != HIR::ImplItem::TYPE_ALIAS)
+ continue;
+
+ if (item->get_impl_item_name () == search)
+ {
+ HirId item_id = item->get_impl_mappings ().get_hirid ();
+ if (query_type (item_id, result))
+ return true;
+ }
+ }
+
+ return false;
+}
+
TyTy::BaseType *
TypeCheckType::resolve_segments (
- NodeId root_resolved_node_id, HirId expr_id,
- std::vector<std::unique_ptr<HIR::TypePathSegment>> &segments, size_t offset,
- TyTy::BaseType *tyseg, const Analysis::NodeMapping &expr_mappings,
- location_t expr_locus)
+ HirId expr_id, std::vector<std::unique_ptr<HIR::TypePathSegment>> &segments,
+ size_t offset, TyTy::BaseType *tyseg,
+ const Analysis::NodeMapping &expr_mappings, location_t expr_locus,
+ bool tySegIsBigSelf)
{
- NodeId resolved_node_id = root_resolved_node_id;
TyTy::BaseType *prev_segment = tyseg;
for (size_t i = offset; i < segments.size (); i++)
{
@@ -508,76 +545,84 @@ TypeCheckType::resolve_segments (
bool probe_bounds = true;
bool probe_impls = !reciever_is_generic;
bool ignore_mandatory_trait_items = !reciever_is_generic;
+ bool first_segment = i == offset;
+ bool selfResolveOk = false;
- // probe the path is done in two parts one where we search impls if no
- // candidate is found then we search extensions from traits
- auto candidates
- = PathProbeType::Probe (prev_segment, seg->get_ident_segment (),
- probe_impls, false,
- ignore_mandatory_trait_items);
- if (candidates.size () == 0)
+ if (first_segment && tySegIsBigSelf
+ && context->block_context ().is_in_context ()
+ && context->block_context ().peek ().is_impl_block ())
{
- candidates
+ TypeCheckBlockContextItem ctx = context->block_context ().peek ();
+ TyTy::BaseType *lookup = nullptr;
+ selfResolveOk
+ = resolve_associated_type (seg->as_string (), ctx, &lookup);
+ if (selfResolveOk)
+ {
+ prev_segment = tyseg;
+ tyseg = lookup;
+ }
+ }
+ if (!selfResolveOk)
+ {
+ // probe the path is done in two parts one where we search impls if no
+ // candidate is found then we search extensions from traits
+ auto candidates
= PathProbeType::Probe (prev_segment, seg->get_ident_segment (),
- false, probe_bounds,
+ probe_impls, false,
ignore_mandatory_trait_items);
-
if (candidates.size () == 0)
{
- rust_error_at (
- seg->get_locus (),
- "failed to resolve path segment using an impl Probe");
+ candidates
+ = PathProbeType::Probe (prev_segment, seg->get_ident_segment (),
+ false, probe_bounds,
+ ignore_mandatory_trait_items);
+ if (candidates.size () == 0)
+ {
+ prev_segment->debug ();
+ rust_error_at (
+ seg->get_locus (),
+ "failed to resolve path segment using an impl Probe");
+ return new TyTy::ErrorType (expr_id);
+ }
+ }
+
+ if (candidates.size () > 1)
+ {
+ ReportMultipleCandidateError::Report (candidates,
+ seg->get_ident_segment (),
+ seg->get_locus ());
return new TyTy::ErrorType (expr_id);
}
- }
- if (candidates.size () > 1)
- {
- ReportMultipleCandidateError::Report (candidates,
- seg->get_ident_segment (),
- seg->get_locus ());
- return new TyTy::ErrorType (expr_id);
- }
+ auto &candidate = *candidates.begin ();
+ prev_segment = tyseg;
+ tyseg = candidate.ty;
- auto &candidate = *candidates.begin ();
- prev_segment = tyseg;
- tyseg = candidate.ty;
+ if (candidate.is_enum_candidate ())
+ {
+ TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyseg);
+ auto last_variant = adt->get_variants ();
+ TyTy::VariantDef *variant = last_variant.back ();
- if (candidate.is_enum_candidate ())
- {
- TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyseg);
- auto last_variant = adt->get_variants ();
- TyTy::VariantDef *variant = last_variant.back ();
-
- rich_location richloc (line_table, seg->get_locus ());
- richloc.add_fixit_replace ("not a type");
-
- rust_error_at (richloc, ErrorCode::E0573,
- "expected type, found variant of %<%s::%s%>",
- adt->get_name ().c_str (),
- variant->get_identifier ().c_str ());
- return new TyTy::ErrorType (expr_id);
- }
+ rich_location richloc (line_table, seg->get_locus ());
+ richloc.add_fixit_replace ("not a type");
- if (candidate.is_impl_candidate ())
- {
- resolved_node_id
- = candidate.item.impl.impl_item->get_impl_mappings ().get_nodeid ();
- }
- else
- {
- resolved_node_id
- = candidate.item.trait.item_ref->get_mappings ().get_nodeid ();
+ rust_error_at (richloc, ErrorCode::E0573,
+ "expected type, found variant of %<%s::%s%>",
+ adt->get_name ().c_str (),
+ variant->get_identifier ().c_str ());
+ return new TyTy::ErrorType (expr_id);
+ }
}
if (seg->is_generic_segment ())
{
- auto *generic_segment
- = static_cast<HIR::TypePathSegmentGeneric *> (seg.get ());
+ auto &generic_segment
+ = static_cast<HIR::TypePathSegmentGeneric &> (*seg);
std::vector<TyTy::Region> regions;
for (auto &lifetime :
- generic_segment->get_generic_args ().get_lifetime_args ())
+ generic_segment.get_generic_args ().get_lifetime_args ())
{
auto region = context->lookup_and_resolve_lifetime (lifetime);
if (!region.has_value ())
@@ -590,46 +635,13 @@ TypeCheckType::resolve_segments (
}
tyseg = SubstMapper::Resolve (tyseg, expr_locus,
- &generic_segment->get_generic_args (),
+ &generic_segment.get_generic_args (),
regions);
if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (expr_id);
}
}
- context->insert_receiver (expr_mappings.get_hirid (), prev_segment);
- rust_assert (resolved_node_id != UNKNOWN_NODEID);
-
- // lookup if the name resolver was able to canonically resolve this or not
- NodeId path_resolved_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (expr_mappings.get_nodeid (),
- &path_resolved_id))
- {
- rust_assert (path_resolved_id == resolved_node_id);
- }
- // check the type scope
- else if (resolver->lookup_resolved_type (expr_mappings.get_nodeid (),
- &path_resolved_id))
- {
- rust_assert (path_resolved_id == resolved_node_id);
- }
- else
- {
- // name scope first
- if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
- {
- resolver->insert_resolved_name (expr_mappings.get_nodeid (),
- resolved_node_id);
- }
- // check the type scope
- else if (resolver->get_type_scope ().decl_was_declared_here (
- resolved_node_id))
- {
- resolver->insert_resolved_type (expr_mappings.get_nodeid (),
- resolved_node_id);
- }
- }
-
return tyseg;
}
@@ -639,6 +651,11 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
std::vector<TyTy::TypeBoundPredicate> specified_bounds;
for (auto &bound : type.get_type_param_bounds ())
{
+ // TODO: here we need to check if there are additional bounds that aren't
+ // auto traits. this is an error. for example, `dyn A + Sized + Sync` is
+ // okay, because Sized and Sync are both auto traits but `dyn A + Copy +
+ // Clone` is not okay and should error out.
+
if (bound->get_bound_type ()
!= HIR::TypeParamBound::BoundType::TRAITBOUND)
continue;
@@ -654,7 +671,7 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
TyTy::TypeBoundPredicate predicate = get_predicate_from_bound (
trait_bound.get_path (),
- nullptr /*this will setup a PLACEHOLDER for self*/);
+ tl::nullopt /*this will setup a PLACEHOLDER for self*/);
if (!predicate.is_error ()
&& predicate.is_object_safe (true, type.get_locus ()))
@@ -668,35 +685,41 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
}
void
+TypeCheckType::visit (HIR::ParenthesisedType &type)
+{
+ // I think this really needs to be a tuple.. but will sort that out when we
+ // fix the parser issue
+ translated = TypeCheckType::Resolve (type.get_type_in_parens ());
+}
+
+void
TypeCheckType::visit (HIR::ArrayType &type)
{
- auto capacity_type = TypeCheckExpr::Resolve (type.get_size_expr ().get ());
+ auto capacity_type = TypeCheckExpr::Resolve (type.get_size_expr ());
if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
return;
TyTy::BaseType *expected_ty = nullptr;
bool ok = context->lookup_builtin ("usize", &expected_ty);
rust_assert (ok);
- context->insert_type (type.get_size_expr ()->get_mappings (), expected_ty);
+ context->insert_type (type.get_size_expr ().get_mappings (), expected_ty);
- unify_site (type.get_size_expr ()->get_mappings ().get_hirid (),
+ unify_site (type.get_size_expr ().get_mappings ().get_hirid (),
TyTy::TyWithLocation (expected_ty),
TyTy::TyWithLocation (capacity_type,
- type.get_size_expr ()->get_locus ()),
- type.get_size_expr ()->get_locus ());
+ type.get_size_expr ().get_locus ()),
+ type.get_size_expr ().get_locus ());
- TyTy::BaseType *base
- = TypeCheckType::Resolve (type.get_element_type ().get ());
+ TyTy::BaseType *base = TypeCheckType::Resolve (type.get_element_type ());
translated = new TyTy::ArrayType (type.get_mappings ().get_hirid (),
- type.get_locus (), *type.get_size_expr (),
+ type.get_locus (), type.get_size_expr (),
TyTy::TyVar (base->get_ref ()));
}
void
TypeCheckType::visit (HIR::SliceType &type)
{
- TyTy::BaseType *base
- = TypeCheckType::Resolve (type.get_element_type ().get ());
+ TyTy::BaseType *base = TypeCheckType::Resolve (type.get_element_type ());
translated
= new TyTy::SliceType (type.get_mappings ().get_hirid (), type.get_locus (),
TyTy::TyVar (base->get_ref ()));
@@ -704,7 +727,7 @@ TypeCheckType::visit (HIR::SliceType &type)
void
TypeCheckType::visit (HIR::ReferenceType &type)
{
- TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ().get ());
+ TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ());
rust_assert (type.has_lifetime ());
auto region = context->lookup_and_resolve_lifetime (type.get_lifetime ());
if (!region.has_value ())
@@ -716,12 +739,12 @@ TypeCheckType::visit (HIR::ReferenceType &type)
translated = new TyTy::ReferenceType (type.get_mappings ().get_hirid (),
TyTy::TyVar (base->get_ref ()),
type.get_mut (), region.value ());
-} // namespace Resolver
+}
void
TypeCheckType::visit (HIR::RawPointerType &type)
{
- TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ().get ());
+ TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ());
translated
= new TyTy::PointerType (type.get_mappings ().get_hirid (),
TyTy::TyVar (base->get_ref ()), type.get_mut ());
@@ -746,28 +769,70 @@ TypeCheckType::visit (HIR::NeverType &type)
translated = lookup->clone ();
}
+void
+TypeCheckType::visit (HIR::ImplTraitType &type)
+{
+ std::vector<TyTy::TypeBoundPredicate> specified_bounds;
+ for (auto &bound : type.get_type_param_bounds ())
+ {
+ if (bound->get_bound_type ()
+ != HIR::TypeParamBound::BoundType::TRAITBOUND)
+ continue;
+
+ HIR::TypeParamBound &b = *bound.get ();
+ HIR::TraitBound &trait_bound = static_cast<HIR::TraitBound &> (b);
+
+ auto binder_pin = context->push_lifetime_binder ();
+ for (auto &lifetime_param : trait_bound.get_for_lifetimes ())
+ {
+ context->intern_and_insert_lifetime (lifetime_param.get_lifetime ());
+ }
+
+ TyTy::TypeBoundPredicate predicate = get_predicate_from_bound (
+ trait_bound.get_path (),
+ tl::nullopt /*this will setup a PLACEHOLDER for self*/);
+
+ if (!predicate.is_error ()
+ && predicate.is_object_safe (true, type.get_locus ()))
+ specified_bounds.push_back (std::move (predicate));
+ }
+
+ translated = new TyTy::OpaqueType (type.get_locus (),
+ type.get_mappings ().get_hirid (),
+ specified_bounds);
+}
+
TyTy::ParamType *
-TypeResolveGenericParam::Resolve (HIR::GenericParam *param, bool apply_sized)
+TypeResolveGenericParam::Resolve (HIR::GenericParam &param,
+ bool resolve_trait_bounds, bool apply_sized)
{
- TypeResolveGenericParam resolver (apply_sized);
- switch (param->get_kind ())
+ TypeResolveGenericParam resolver (apply_sized, resolve_trait_bounds);
+ switch (param.get_kind ())
{
case HIR::GenericParam::GenericKind::TYPE:
- resolver.visit (static_cast<HIR::TypeParam &> (*param));
+ resolver.visit (static_cast<HIR::TypeParam &> (param));
break;
case HIR::GenericParam::GenericKind::CONST:
- resolver.visit (static_cast<HIR::ConstGenericParam &> (*param));
+ resolver.visit (static_cast<HIR::ConstGenericParam &> (param));
break;
case HIR::GenericParam::GenericKind::LIFETIME:
- resolver.visit (static_cast<HIR::LifetimeParam &> (*param));
+ resolver.visit (static_cast<HIR::LifetimeParam &> (param));
break;
}
return resolver.resolved;
}
void
+TypeResolveGenericParam::ApplyAnyTraitBounds (HIR::TypeParam &param,
+ TyTy::ParamType *pty)
+{
+ TypeResolveGenericParam resolver (true, true);
+ resolver.apply_trait_bounds (param, pty);
+}
+
+void
TypeResolveGenericParam::visit (HIR::LifetimeParam &param)
{
// nothing to do
@@ -783,9 +848,22 @@ void
TypeResolveGenericParam::visit (HIR::TypeParam &param)
{
if (param.has_type ())
- TypeCheckType::Resolve (param.get_type ().get ());
+ TypeCheckType::Resolve (param.get_type ());
+
+ resolved
+ = new TyTy::ParamType (param.get_type_representation ().as_string (),
+ param.get_locus (),
+ param.get_mappings ().get_hirid (), param, {});
- HIR::Type *implicit_self_bound = nullptr;
+ if (resolve_trait_bounds)
+ apply_trait_bounds (param, resolved);
+}
+
+void
+TypeResolveGenericParam::apply_trait_bounds (HIR::TypeParam &param,
+ TyTy::ParamType *pty)
+{
+ std::unique_ptr<HIR::Type> implicit_self_bound = nullptr;
if (param.has_type_param_bounds ())
{
// We need two possible parameter types. One with no Bounds and one with
@@ -803,8 +881,8 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
param.get_mappings ().get_nodeid (),
implicit_id,
param.get_mappings ().get_local_defid ());
- implicit_self_bound
- = new HIR::TypePath (mappings, {}, BUILTINS_LOCATION, false);
+ implicit_self_bound = std::make_unique<HIR::TypePath> (
+ HIR::TypePath (mappings, {}, BUILTINS_LOCATION, false));
}
std::map<DefId, std::vector<TyTy::TypeBoundPredicate>> predicates;
@@ -815,8 +893,6 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
//
// We can only do this when we are not resolving the implicit Self for Sized
// itself
- rust_debug_loc (param.get_locus (), "apply_sized: %s",
- apply_sized ? "true" : "false");
if (apply_sized)
{
TyTy::TypeBoundPredicate sized_predicate
@@ -833,13 +909,13 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
switch (bound->get_bound_type ())
{
case HIR::TypeParamBound::BoundType::TRAITBOUND: {
- HIR::TraitBound *b
- = static_cast<HIR::TraitBound *> (bound.get ());
+ HIR::TraitBound &b = static_cast<HIR::TraitBound &> (*bound);
- TyTy::TypeBoundPredicate predicate
- = get_predicate_from_bound (b->get_path (),
- implicit_self_bound,
- b->get_polarity ());
+ TyTy::TypeBoundPredicate predicate = get_predicate_from_bound (
+ b.get_path (),
+ tl::optional<std::reference_wrapper<HIR::Type>> (
+ std::ref (*implicit_self_bound)),
+ b.get_polarity ());
if (!predicate.is_error ())
{
switch (predicate.get_polarity ())
@@ -852,7 +928,7 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
else
{
// emit error message
- rich_location r (line_table, b->get_locus ());
+ rich_location r (line_table, b.get_locus ());
r.add_range (predicate.get ()->get_locus ());
rust_error_at (
r, "antibound for %s is not applied here",
@@ -891,10 +967,8 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
}
}
- resolved = new TyTy::ParamType (param.get_type_representation ().as_string (),
- param.get_locus (),
- param.get_mappings ().get_hirid (), param,
- specified_bounds);
+ // inherit them
+ pty->inherit_bounds (specified_bounds);
}
void
@@ -950,7 +1024,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
}
auto &binding_type_path = item.get_bound_type ();
- TyTy::BaseType *binding = TypeCheckType::Resolve (binding_type_path.get ());
+ TyTy::BaseType *binding = TypeCheckType::Resolve (binding_type_path);
// FIXME double check there might be a trait cycle here see TypeParam handling
@@ -963,8 +1037,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
auto *b = static_cast<HIR::TraitBound *> (bound.get ());
TyTy::TypeBoundPredicate predicate
- = get_predicate_from_bound (b->get_path (),
- binding_type_path.get ());
+ = get_predicate_from_bound (b->get_path (), binding_type_path);
if (!predicate.is_error ())
specified_bounds.push_back (std::move (predicate));
}
@@ -994,16 +1067,32 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
// When we apply these bounds we must lookup which type this binding
// resolves to, as this is the type which will be used during resolution
// of the block.
- NodeId ast_node_id = binding_type_path->get_mappings ().get_nodeid ();
+ NodeId ast_node_id = binding_type_path.get_mappings ().get_nodeid ();
// then lookup the reference_node_id
NodeId ref_node_id = UNKNOWN_NODEID;
- if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ if (auto id = nr_ctx.lookup (ast_node_id))
+ ref_node_id = *id;
+ }
+ else
+ {
+ NodeId id = UNKNOWN_NODEID;
+
+ if (resolver->lookup_resolved_type (ast_node_id, &id))
+ ref_node_id = id;
+ }
+
+ if (ref_node_id == UNKNOWN_NODEID)
{
// FIXME
rust_error_at (UNDEF_LOCATION,
"Failed to lookup type reference for node: %s",
- binding_type_path->as_string ().c_str ());
+ binding_type_path.as_string ().c_str ());
return;
}
@@ -1016,7 +1105,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
{
rust_error_at (mappings.lookup_location (*hid),
"Failed to resolve where-clause binding type: %s",
- binding_type_path->as_string ().c_str ());
+ binding_type_path.as_string ().c_str ());
return;
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index a440250..cc991b6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -31,7 +31,7 @@ namespace Resolver {
class TypeCheckResolveGenericArguments : public TypeCheckBase
{
public:
- static HIR::GenericArgs resolve (HIR::TypePathSegment *segment);
+ static HIR::GenericArgs resolve (HIR::TypePathSegment &segment);
void visit (HIR::TypePathSegmentGeneric &generic);
@@ -46,7 +46,7 @@ private:
class TypeCheckType : public TypeCheckBase, public HIR::HIRTypeVisitor
{
public:
- static TyTy::BaseType *Resolve (HIR::Type *type);
+ static TyTy::BaseType *Resolve (HIR::Type &type);
void visit (HIR::BareFunctionType &fntype) override;
void visit (HIR::TupleType &tuple) override;
@@ -59,22 +59,12 @@ public:
void visit (HIR::InferredType &type) override;
void visit (HIR::NeverType &type) override;
void visit (HIR::TraitObjectType &type) override;
+ void visit (HIR::ParenthesisedType &type) override;
+ void visit (HIR::ImplTraitType &type) override;
- void visit (HIR::TypePathSegmentFunction &segment) override
- { /* TODO */
- }
- void visit (HIR::TraitBound &bound) override
- { /* TODO */
- }
- void visit (HIR::ImplTraitType &type) override
- { /* TODO */
- }
- void visit (HIR::ParenthesisedType &type) override
- { /* TODO */
- }
- void visit (HIR::ImplTraitTypeOneBound &type) override
- { /* TODO */
- }
+ // These dont need to be implemented as they are segments or part of types
+ void visit (HIR::TypePathSegmentFunction &segment) override {}
+ void visit (HIR::TraitBound &bound) override {}
private:
TypeCheckType (HirId id)
@@ -82,13 +72,17 @@ private:
{}
TyTy::BaseType *resolve_root_path (HIR::TypePath &path, size_t *offset,
- NodeId *root_resolved_node_id);
+ bool *wasBigSelf);
TyTy::BaseType *resolve_segments (
- NodeId root_resolved_node_id, HirId expr_id,
- std::vector<std::unique_ptr<HIR::TypePathSegment>> &segments, size_t offset,
- TyTy::BaseType *tyseg, const Analysis::NodeMapping &expr_mappings,
- location_t expr_locus);
+ HirId expr_id, std::vector<std::unique_ptr<HIR::TypePathSegment>> &segments,
+ size_t offset, TyTy::BaseType *tyseg,
+ const Analysis::NodeMapping &expr_mappings, location_t expr_locus,
+ bool tySegIsBigSelf);
+
+ bool resolve_associated_type (const std::string &search,
+ TypeCheckBlockContextItem &ctx,
+ TyTy::BaseType **result);
TyTy::BaseType *translated;
};
@@ -96,21 +90,28 @@ private:
class TypeResolveGenericParam : public TypeCheckBase
{
public:
- static TyTy::ParamType *Resolve (HIR::GenericParam *param,
+ static TyTy::ParamType *Resolve (HIR::GenericParam &param,
+ bool resolve_trait_bounds = true,
bool apply_sized = true);
+ static void ApplyAnyTraitBounds (HIR::TypeParam &param, TyTy::ParamType *pty);
+
protected:
void visit (HIR::TypeParam &param);
void visit (HIR::LifetimeParam &param);
void visit (HIR::ConstGenericParam &param);
+ void apply_trait_bounds (HIR::TypeParam &param, TyTy::ParamType *pty);
+
private:
- TypeResolveGenericParam (bool apply_sized)
- : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized)
+ TypeResolveGenericParam (bool apply_sized, bool resolve_trait_bounds)
+ : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized),
+ resolve_trait_bounds (resolve_trait_bounds)
{}
TyTy::ParamType *resolved;
bool apply_sized;
+ bool resolve_trait_bounds;
};
class ResolveWhereClauseItem : public TypeCheckBase
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 45cb75d..fbaf323 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -19,10 +19,15 @@
#include "rust-hir-type-check.h"
#include "rust-hir-full.h"
#include "rust-hir-inherent-impl-overlap.h"
+#include "rust-hir-pattern.h"
#include "rust-hir-type-check-expr.h"
#include "rust-hir-type-check-item.h"
#include "rust-hir-type-check-pattern.h"
#include "rust-hir-type-check-struct-field.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
extern bool
saw_errors (void);
@@ -136,11 +141,10 @@ TyTy::BaseType *
TraitItemReference::get_type_from_constant (
/*const*/ HIR::TraitItemConst &constant) const
{
- TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
+ TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
if (constant.has_expr ())
{
- TyTy::BaseType *expr
- = TypeCheckExpr::Resolve (constant.get_expr ().get ());
+ TyTy::BaseType *expr = TypeCheckExpr::Resolve (constant.get_expr ());
return unify_site (constant.get_mappings ().get_hirid (),
TyTy::TyWithLocation (type),
@@ -161,36 +165,9 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
HIR::TraitFunctionDecl &function = fn.get_decl ();
if (function.has_generics ())
{
- for (auto &generic_param : function.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME: {
- auto lifetime_param
- = static_cast<HIR::LifetimeParam &> (*generic_param);
-
- context->intern_and_insert_lifetime (
- lifetime_param.get_lifetime ());
- // TODO: Handle lifetime bounds
- }
- break;
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get ());
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
+ TypeCheckBase::ResolveGenericParams (function.get_generic_params (),
+ substitutions, false /*is_foreign*/,
+ ABI::RUST);
}
if (function.has_where_clause ())
@@ -202,11 +179,10 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
TyTy::BaseType *ret_type = nullptr;
if (!function.has_return_type ())
- ret_type = TyTy::TupleType::get_unit_type (fn.get_mappings ().get_hirid ());
+ ret_type = TyTy::TupleType::get_unit_type ();
else
{
- auto resolved
- = TypeCheckType::Resolve (function.get_return_type ().get ());
+ auto resolved = TypeCheckType::Resolve (function.get_return_type ());
if (resolved->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (fn.get_locus (), "failed to resolve return type");
@@ -215,10 +191,11 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
ret_type = resolved->clone ();
ret_type->set_ref (
- function.get_return_type ()->get_mappings ().get_hirid ());
+ function.get_return_type ().get_mappings ().get_hirid ());
}
- std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
+ std::vector<TyTy::FnParam> params;
+
if (function.is_method ())
{
// these are implicit mappings and not used
@@ -231,17 +208,18 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
// add the synthetic self param at the front, this is a placeholder
// for compilation to know parameter names. The types are ignored
// but we reuse the HIR identifier pattern which requires it
- HIR::SelfParam &self_param = function.get_self ();
- HIR::IdentifierPattern *self_pattern = new HIR::IdentifierPattern (
- mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
- self_param.is_mut () ? Mutability::Mut : Mutability::Imm,
- std::unique_ptr<HIR::Pattern> (nullptr));
+ HIR::SelfParam &self_param = function.get_self_unchecked ();
+ std::unique_ptr<HIR::Pattern> self_pattern
+ = std::make_unique<HIR::IdentifierPattern> (HIR::IdentifierPattern (
+ mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
+ self_param.is_mut () ? Mutability::Mut : Mutability::Imm,
+ std::unique_ptr<HIR::Pattern> (nullptr)));
// might have a specified type
TyTy::BaseType *self_type = nullptr;
if (self_param.has_type ())
{
- std::unique_ptr<HIR::Type> &specified_type = self_param.get_type ();
- self_type = TypeCheckType::Resolve (specified_type.get ());
+ HIR::Type &specified_type = self_param.get_type ();
+ self_type = TypeCheckType::Resolve (specified_type);
}
else
{
@@ -283,24 +261,38 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
}
context->insert_type (self_param.get_mappings (), self_type);
- params.push_back (
- std::pair<HIR::Pattern *, TyTy::BaseType *> (self_pattern, self_type));
+ params.push_back (TyTy::FnParam (std::move (self_pattern), self_type));
}
for (auto &param : function.get_function_params ())
{
// get the name as well required for later on
- auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
- params.push_back (std::pair<HIR::Pattern *, TyTy::BaseType *> (
- param.get_param_name ().get (), param_tyty));
-
+ auto param_tyty = TypeCheckType::Resolve (param.get_type ());
context->insert_type (param.get_mappings (), param_tyty);
- TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
+ TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
+ // FIXME: Should we take the name ? Use a shared pointer instead ?
+ params.push_back (
+ TyTy::FnParam (param.get_param_name ().clone_pattern (), param_tyty));
}
auto &mappings = Analysis::Mappings::get ();
- auto canonical_path
- = mappings.lookup_canonical_path (fn.get_mappings ().get_nodeid ());
+
+ tl::optional<CanonicalPath> canonical_path;
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ canonical_path
+ = nr_ctx.values.to_canonical_path (fn.get_mappings ().get_nodeid ());
+ }
+ else
+ {
+ canonical_path
+ = mappings.lookup_canonical_path (fn.get_mappings ().get_nodeid ());
+ }
+
+ rust_assert (canonical_path);
RustIdent ident{*canonical_path, fn.get_locus ()};
auto resolved = new TyTy::FnType (
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index fa49e06..18a65fe 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -22,6 +22,7 @@
#include "rust-hir-map.h"
#include "rust-tyty.h"
#include "rust-hir-trait-reference.h"
+#include "rust-stacked-contexts.h"
#include "rust-autoderef.h"
#include "rust-tyty-region.h"
#include "rust-tyty-variance-analysis.h"
@@ -42,7 +43,7 @@ public:
};
TypeCheckContextItem (HIR::Function *item);
- TypeCheckContextItem (HIR::ImplBlock *impl_block, HIR::Function *item);
+ TypeCheckContextItem (HIR::ImplBlock &impl_block, HIR::Function *item);
TypeCheckContextItem (HIR::TraitItemFunc *trait_item);
TypeCheckContextItem (const TypeCheckContextItem &other);
@@ -82,6 +83,37 @@ private:
Item item;
};
+class TypeCheckBlockContextItem
+{
+public:
+ enum ItemType
+ {
+ IMPL_BLOCK,
+ TRAIT
+ };
+
+ TypeCheckBlockContextItem (HIR::ImplBlock *block);
+ TypeCheckBlockContextItem (HIR::Trait *trait);
+
+ bool is_impl_block () const;
+ bool is_trait_block () const;
+
+ HIR::ImplBlock &get_impl_block ();
+ HIR::Trait &get_trait ();
+
+private:
+ union Item
+ {
+ HIR::ImplBlock *block;
+ HIR::Trait *trait;
+
+ Item (HIR::ImplBlock *block);
+ Item (HIR::Trait *trait);
+ };
+ ItemType type;
+ Item item;
+};
+
/**
* Interned lifetime representation in TyTy
*
@@ -135,10 +167,10 @@ public:
bool lookup_builtin (NodeId id, TyTy::BaseType **type);
bool lookup_builtin (std::string name, TyTy::BaseType **type);
void insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type);
+ const std::vector<std::unique_ptr<TyTy::BaseType>> &get_builtins () const;
void insert_type (const Analysis::NodeMapping &mappings,
TyTy::BaseType *type);
- void insert_implicit_type (TyTy::BaseType *type);
bool lookup_type (HirId id, TyTy::BaseType **type) const;
void clear_type (TyTy::BaseType *ty);
@@ -153,6 +185,9 @@ public:
void push_return_type (TypeCheckContextItem item,
TyTy::BaseType *return_type);
void pop_return_type ();
+
+ StackedContexts<TypeCheckBlockContextItem> &block_context ();
+
void iterate (std::function<bool (HirId, TyTy::BaseType *)> cb);
bool have_loop_context () const;
@@ -166,9 +201,6 @@ public:
void insert_trait_reference (DefId id, TraitReference &&ref);
bool lookup_trait_reference (DefId id, TraitReference **ref);
- void insert_receiver (HirId id, TyTy::BaseType *t);
- bool lookup_receiver (HirId id, TyTy::BaseType **ref);
-
void insert_associated_trait_impl (HirId id,
AssociatedImplTrait &&associated);
bool lookup_associated_trait_impl (HirId id,
@@ -244,8 +276,8 @@ private:
std::vector<std::pair<TypeCheckContextItem, TyTy::BaseType *>>
return_type_stack;
std::vector<TyTy::BaseType *> loop_type_stack;
+ StackedContexts<TypeCheckBlockContextItem> block_stack;
std::map<DefId, TraitReference> trait_context;
- std::map<HirId, TyTy::BaseType *> receiver_context;
std::map<HirId, AssociatedImplTrait> associated_impl_traits;
// trait-id -> list of < self-tyty:impl-id>
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
index dbf49be..f0bd1f8 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.cc
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -34,6 +34,15 @@ SubstMapper::Resolve (TyTy::BaseType *base, location_t locus,
HIR::GenericArgs *generics,
const std::vector<TyTy::Region> &regions)
{
+ if (!valid_type (base))
+ {
+ rich_location r (line_table, locus);
+ r.add_fixit_remove (generics->get_locus ());
+ rust_error_at (r, ErrorCode::E0109,
+ "generic arguments are not allowed for this type");
+ return base;
+ }
+
SubstMapper mapper (base->get_ref (), generics, regions, locus);
base->accept_vis (mapper);
rust_assert (mapper.resolved != nullptr);
@@ -47,6 +56,17 @@ SubstMapper::InferSubst (TyTy::BaseType *base, location_t locus)
}
bool
+SubstMapper::valid_type (TyTy::BaseType *base)
+{
+ bool is_fn = base->is<TyTy::FnType> ();
+ bool is_adt = base->is<TyTy::ADTType> ();
+ bool is_placeholder = base->is<TyTy::PlaceholderType> ();
+ bool is_projection = base->is<TyTy::ProjectionType> ();
+
+ return is_fn || is_adt || is_placeholder || is_projection;
+}
+
+bool
SubstMapper::have_generic_args () const
{
return generics != nullptr;
@@ -103,7 +123,12 @@ SubstMapper::visit (TyTy::ADTType &type)
void
SubstMapper::visit (TyTy::PlaceholderType &type)
{
- rust_assert (type.can_resolve ());
+ if (!type.can_resolve ())
+ {
+ resolved = &type;
+ return;
+ }
+
resolved = SubstMapper::Resolve (type.resolve (), locus, generics, regions);
}
@@ -192,8 +217,10 @@ SubstMapperInternal::visit (TyTy::FnType &type)
{
TyTy::SubstitutionArgumentMappings adjusted
= type.adjust_mappings_for_this (mappings);
- if (adjusted.is_error ())
+ if (adjusted.is_error () && !mappings.trait_item_mode ())
return;
+ if (adjusted.is_error () && mappings.trait_item_mode ())
+ adjusted = mappings;
TyTy::BaseType *concrete = type.handle_substitions (adjusted);
if (concrete != nullptr)
@@ -205,8 +232,10 @@ SubstMapperInternal::visit (TyTy::ADTType &type)
{
TyTy::SubstitutionArgumentMappings adjusted
= type.adjust_mappings_for_this (mappings);
- if (adjusted.is_error ())
+ if (adjusted.is_error () && !mappings.trait_item_mode ())
return;
+ if (adjusted.is_error () && mappings.trait_item_mode ())
+ adjusted = mappings;
TyTy::BaseType *concrete = type.handle_substitions (adjusted);
if (concrete != nullptr)
@@ -342,6 +371,11 @@ SubstMapperInternal::visit (TyTy::DynamicObjectType &type)
{
resolved = type.clone ();
}
+void
+SubstMapperInternal::visit (TyTy::OpaqueType &type)
+{
+ resolved = type.handle_substitions (mappings);
+}
// SubstMapperFromExisting
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index bcd93fd..32ab71c 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -37,6 +37,8 @@ public:
bool have_generic_args () const;
+ static bool valid_type (TyTy::BaseType *base);
+
void visit (TyTy::FnType &type) override;
void visit (TyTy::ADTType &type) override;
void visit (TyTy::PlaceholderType &type) override;
@@ -63,6 +65,7 @@ public:
void visit (TyTy::NeverType &) override { rust_unreachable (); }
void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); }
void visit (TyTy::ClosureType &) override { rust_unreachable (); }
+ void visit (TyTy::OpaqueType &) override { rust_unreachable (); }
private:
SubstMapper (HirId ref, HIR::GenericArgs *generics,
@@ -107,6 +110,7 @@ public:
void visit (TyTy::StrType &type) override;
void visit (TyTy::NeverType &type) override;
void visit (TyTy::DynamicObjectType &type) override;
+ void visit (TyTy::OpaqueType &type) override;
private:
SubstMapperInternal (HirId ref, TyTy::SubstitutionArgumentMappings &mappings);
@@ -146,6 +150,7 @@ public:
void visit (TyTy::PlaceholderType &) override { rust_unreachable (); }
void visit (TyTy::ProjectionType &) override { rust_unreachable (); }
void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); }
+ void visit (TyTy::OpaqueType &type) override { rust_unreachable (); }
private:
SubstMapperFromExisting (TyTy::BaseType *concrete, TyTy::BaseType *receiver);
@@ -185,6 +190,7 @@ public:
void visit (const TyTy::PlaceholderType &) override {}
void visit (const TyTy::ProjectionType &) override {}
void visit (const TyTy::DynamicObjectType &) override {}
+ void visit (const TyTy::OpaqueType &type) override {}
private:
GetUsedSubstArgs ();
diff --git a/gcc/rust/typecheck/rust-type-util.cc b/gcc/rust/typecheck/rust-type-util.cc
index 0ed7124..c6c5b4b 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -22,10 +22,13 @@
#include "rust-hir-type-check-implitem.h"
#include "rust-hir-type-check-item.h"
#include "rust-hir-type-check.h"
+#include "rust-hir-type-check-type.h"
#include "rust-casts.h"
#include "rust-unify.h"
#include "rust-coercion.h"
#include "rust-hir-type-bounds.h"
+#include "rust-immutable-name-resolution-context.h"
+#include "options.h"
namespace Rust {
namespace Resolver {
@@ -34,6 +37,7 @@ bool
query_type (HirId reference, TyTy::BaseType **result)
{
auto &mappings = Analysis::Mappings::get ();
+ auto &resolver = *Resolver::get ();
TypeCheckContext *context = TypeCheckContext::get ();
if (context->query_in_progress (reference))
@@ -87,8 +91,44 @@ query_type (HirId reference, TyTy::BaseType **result)
// is it an impl_type?
if (auto impl_block_by_type = mappings.lookup_impl_block_type (reference))
{
- *result
- = TypeCheckItem::ResolveImplBlockSelf (*impl_block_by_type.value ());
+ // found an impl item
+ HIR::ImplBlock *impl = impl_block_by_type.value ();
+ rust_debug_loc (impl->get_locus (), "resolved impl block type {%u} to",
+ reference);
+
+ // this could be recursive to the root type
+ if (impl->has_type ())
+ {
+ HIR::Type &ty = impl->get_type ();
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ NodeId ast_node_id = ty.get_mappings ().get_nodeid ();
+
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx = Resolver2_0::ImmutableNameResolutionContext::get ()
+ .resolver ();
+
+ // assign the ref_node_id if we've found something
+ nr_ctx.lookup (ast_node_id)
+ .map (
+ [&ref_node_id] (NodeId resolved) { ref_node_id = resolved; });
+ }
+ else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ resolver.lookup_resolved_type (ast_node_id, &ref_node_id);
+
+ if (ref_node_id != UNKNOWN_NODEID)
+ {
+ tl::optional<HirId> hid
+ = mappings.lookup_node_to_hir (ref_node_id);
+ if (hid.has_value () && context->query_in_progress (hid.value ()))
+ {
+ context->query_completed (reference);
+ return false;
+ }
+ }
+ }
+
+ *result = TypeCheckItem::ResolveImplBlockSelf (*impl);
context->query_completed (reference);
return true;
}
@@ -99,8 +139,9 @@ query_type (HirId reference, TyTy::BaseType **result)
auto block = mappings.lookup_hir_extern_block (extern_item->second);
rust_assert (block.has_value ());
- *result = TypeCheckTopLevelExternItem::Resolve (extern_item->first,
- *block.value ());
+ *result
+ = TypeCheckTopLevelExternItem::Resolve (*extern_item.value ().first,
+ *block.value ());
context->query_completed (reference);
return true;
}
@@ -216,8 +257,10 @@ coercion_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
rust_debug ("coerce_default_unify(a={%s}, b={%s})",
receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
TyTy::BaseType *coerced
- = unify_site (id, lhs, TyTy::TyWithLocation (receiver, rhs.get_locus ()),
- locus);
+ = unify_site_and (id, lhs,
+ TyTy::TyWithLocation (receiver, rhs.get_locus ()), locus,
+ true /*emit_error*/, true /*commit*/, true /*infer*/,
+ true /*cleanup*/);
context->insert_autoderef_mappings (id, std::move (result.adjustments));
return coerced;
}
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc
index 8f7a8a4..9112b99 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -73,6 +73,12 @@ TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
}
+const std::vector<std::unique_ptr<TyTy::BaseType>> &
+TypeCheckContext::get_builtins () const
+{
+ return builtins;
+}
+
void
TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
TyTy::BaseType *type)
@@ -85,13 +91,6 @@ TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
}
void
-TypeCheckContext::insert_implicit_type (TyTy::BaseType *type)
-{
- rust_assert (type != nullptr);
- resolved[type->get_ref ()] = type;
-}
-
-void
TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
{
rust_assert (type != nullptr);
@@ -171,6 +170,12 @@ TypeCheckContext::peek_context ()
return return_type_stack.back ().first;
}
+StackedContexts<TypeCheckBlockContextItem> &
+TypeCheckContext::block_context ()
+{
+ return block_stack;
+}
+
void
TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
{
@@ -243,23 +248,6 @@ TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
}
void
-TypeCheckContext::insert_receiver (HirId id, TyTy::BaseType *t)
-{
- receiver_context[id] = t;
-}
-
-bool
-TypeCheckContext::lookup_receiver (HirId id, TyTy::BaseType **ref)
-{
- auto it = receiver_context.find (id);
- if (it == receiver_context.end ())
- return false;
-
- *ref = it->second;
- return true;
-}
-
-void
TypeCheckContext::insert_associated_trait_impl (
HirId id, AssociatedImplTrait &&associated)
{
@@ -526,7 +514,16 @@ TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
{
if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
{
- rust_assert (lifetime.get_name () != "static");
+ if (lifetime.get_name () == "static")
+ {
+ rich_location r (line_table, lifetime.get_locus ());
+ r.add_fixit_insert_after (lifetime.get_locus (),
+ "static is a reserved lifetime name");
+ rust_error_at (r, ErrorCode::E0262,
+ "invalid lifetime parameter name: %qs",
+ lifetime.get_name ().c_str ());
+ return tl::nullopt;
+ }
const auto name = lifetime.get_name ();
auto it = lifetime_name_interner.find (name);
if (it == lifetime_name_interner.end ())
@@ -640,9 +637,9 @@ TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
: type (ItemType::ITEM), item (item)
{}
-TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock *impl_block,
+TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
HIR::Function *item)
- : type (ItemType::IMPL_ITEM), item (impl_block, item)
+ : type (ItemType::IMPL_ITEM), item (&impl_block, item)
{}
TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
@@ -796,5 +793,43 @@ TypeCheckContextItem::get_defid () const
return UNKNOWN_DEFID;
}
+// TypeCheckBlockContextItem
+
+TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
+
+TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
+
+TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
+ : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
+{}
+
+TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
+ : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
+{}
+
+bool
+TypeCheckBlockContextItem::is_impl_block () const
+{
+ return type == IMPL_BLOCK;
+}
+
+bool
+TypeCheckBlockContextItem::is_trait_block () const
+{
+ return type == TRAIT;
+}
+
+HIR::ImplBlock &
+TypeCheckBlockContextItem::get_impl_block ()
+{
+ return *(item.block);
+}
+
+HIR::Trait &
+TypeCheckBlockContextItem::get_trait ()
+{
+ return *(item.trait);
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index b73e592..e028a0a 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -16,9 +16,11 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "rust-hir-full-decls.h"
#include "rust-hir-type-bounds.h"
#include "rust-hir-trait-resolve.h"
#include "rust-substitution-mapper.h"
+#include "rust-hir-trait-resolve.h"
#include "rust-type-util.h"
namespace Rust {
@@ -70,7 +72,15 @@ TypeBoundsProbe::scan ()
if (!impl->has_trait_ref ())
return true;
- HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
+ // can be recursive trait resolution
+ HIR::Trait *t = TraitResolver::ResolveHirItem (impl->get_trait_ref ());
+ if (t == nullptr)
+ return true;
+ DefId trait_id = t->get_mappings ().get_defid ();
+ if (context->trait_query_in_progress (trait_id))
+ return true;
+
+ HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid ();
TyTy::BaseType *impl_type = nullptr;
if (!query_type (impl_ty_id, &impl_type))
return true;
@@ -81,7 +91,7 @@ TypeBoundsProbe::scan ()
return true;
}
- possible_trait_paths.push_back ({impl->get_trait_ref ().get (), impl});
+ possible_trait_paths.push_back ({&impl->get_trait_ref (), impl});
return true;
});
@@ -96,6 +106,10 @@ TypeBoundsProbe::scan ()
// marker traits...
assemble_sized_builtin ();
+
+ // add auto trait bounds
+ for (auto *auto_trait : mappings.get_auto_traits ())
+ add_trait_bound (auto_trait);
}
void
@@ -131,6 +145,7 @@ TypeBoundsProbe::assemble_sized_builtin ()
case TyTy::NEVER:
case TyTy::PLACEHOLDER:
case TyTy::PROJECTION:
+ case TyTy::OPAQUE:
assemble_builtin_candidate (LangItem::Kind::SIZED);
break;
@@ -150,6 +165,14 @@ TypeBoundsProbe::assemble_sized_builtin ()
}
void
+TypeBoundsProbe::add_trait_bound (HIR::Trait *trait)
+{
+ auto trait_ref = TraitResolver::Resolve (*trait);
+
+ trait_references.push_back ({trait_ref, mappings.lookup_builtin_marker ()});
+}
+
+void
TypeBoundsProbe::assemble_builtin_candidate (LangItem::Kind lang_item)
{
auto lang_item_defined = mappings.lookup_lang_item (lang_item);
@@ -166,9 +189,7 @@ TypeBoundsProbe::assemble_builtin_candidate (LangItem::Kind lang_item)
HIR::Trait *trait = static_cast<HIR::Trait *> (item);
const TyTy::BaseType *raw = receiver->destructure ();
- // assemble the reference
- TraitReference *trait_ref = TraitResolver::Resolve (*trait);
- trait_references.push_back ({trait_ref, mappings.lookup_builtin_marker ()});
+ add_trait_bound (trait);
rust_debug ("Added builtin lang_item: %s for %s",
LangItem::ToString (lang_item).c_str (),
@@ -182,9 +203,10 @@ TypeCheckBase::resolve_trait_path (HIR::TypePath &path)
}
TyTy::TypeBoundPredicate
-TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
- HIR::Type *associated_self,
- BoundPolarity polarity)
+TypeCheckBase::get_predicate_from_bound (
+ HIR::TypePath &type_path,
+ tl::optional<std::reference_wrapper<HIR::Type>> associated_self,
+ BoundPolarity polarity, bool is_qualified_type_path)
{
TyTy::TypeBoundPredicate lookup = TyTy::TypeBoundPredicate::error ();
bool already_resolved
@@ -202,29 +224,44 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
= HIR::GenericArgs::create_empty (type_path.get_locus ());
auto &final_seg = type_path.get_final_segment ();
- switch (final_seg->get_type ())
+ switch (final_seg.get_type ())
{
case HIR::TypePathSegment::SegmentType::GENERIC: {
- auto final_generic_seg
- = static_cast<HIR::TypePathSegmentGeneric *> (final_seg.get ());
- if (final_generic_seg->has_generic_args ())
+ auto &final_generic_seg
+ = static_cast<HIR::TypePathSegmentGeneric &> (final_seg);
+ if (final_generic_seg.has_generic_args ())
{
- args = final_generic_seg->get_generic_args ();
+ args = final_generic_seg.get_generic_args ();
+ if (args.get_binding_args ().size () > 0
+ && associated_self.has_value () && is_qualified_type_path)
+ {
+ auto &binding_args = args.get_binding_args ();
+
+ rich_location r (line_table, args.get_locus ());
+ for (auto it = binding_args.begin (); it != binding_args.end ();
+ it++)
+ {
+ auto &arg = *it;
+ r.add_fixit_remove (arg.get_locus ());
+ }
+ rust_error_at (r, ErrorCode::E0229,
+ "associated type bindings are not allowed here");
+ }
}
}
break;
case HIR::TypePathSegment::SegmentType::FUNCTION: {
- auto final_function_seg
- = static_cast<HIR::TypePathSegmentFunction *> (final_seg.get ());
- auto &fn = final_function_seg->get_function_path ();
+ auto &final_function_seg
+ = static_cast<HIR::TypePathSegmentFunction &> (final_seg);
+ auto &fn = final_function_seg.get_function_path ();
// we need to make implicit generic args which must be an implicit
// Tuple
auto crate_num = mappings.get_current_crate ();
HirId implicit_args_id = mappings.get_next_hir_id ();
Analysis::NodeMapping mapping (crate_num,
- final_seg->get_mappings ().get_nodeid (),
+ final_seg.get_mappings ().get_nodeid (),
implicit_args_id, UNKNOWN_LOCAL_DEFID);
std::vector<std::unique_ptr<HIR::Type>> params_copy;
@@ -233,36 +270,34 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
params_copy.push_back (p->clone_type ());
}
- HIR::TupleType *implicit_tuple
- = new HIR::TupleType (mapping, std::move (params_copy),
- final_seg->get_locus ());
-
std::vector<std::unique_ptr<HIR::Type>> inputs;
- inputs.push_back (std::unique_ptr<HIR::Type> (implicit_tuple));
+ inputs.push_back (
+ std::make_unique<HIR::TupleType> (mapping, std::move (params_copy),
+ final_seg.get_locus ()));
// resolve the fn_once_output type which assumes there must be an output
// set
rust_assert (fn.has_return_type ());
- TypeCheckType::Resolve (fn.get_return_type ().get ());
+ TypeCheckType::Resolve (fn.get_return_type ());
HIR::TraitItem *trait_item
= mappings
.lookup_trait_item_lang_item (LangItem::Kind::FN_ONCE_OUTPUT,
- final_seg->get_locus ())
+ final_seg.get_locus ())
.value ();
std::vector<HIR::GenericArgsBinding> bindings;
- location_t output_locus = fn.get_return_type ()->get_locus ();
+ location_t output_locus = fn.get_return_type ().get_locus ();
HIR::GenericArgsBinding binding (Identifier (
trait_item->trait_identifier ()),
- fn.get_return_type ()->clone_type (),
+ fn.get_return_type ().clone_type (),
output_locus);
bindings.push_back (std::move (binding));
args = HIR::GenericArgs ({} /* lifetimes */,
std::move (inputs) /* type_args*/,
std::move (bindings) /* binding_args*/,
- {} /* const_args */, final_seg->get_locus ());
+ {} /* const_args */, final_seg.get_locus ());
}
break;
@@ -271,11 +306,11 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
break;
}
- if (associated_self != nullptr)
+ if (associated_self.has_value ())
{
std::vector<std::unique_ptr<HIR::Type>> type_args;
- type_args.push_back (
- std::unique_ptr<HIR::Type> (associated_self->clone_type ()));
+ type_args.push_back (std::unique_ptr<HIR::Type> (
+ associated_self.value ().get ().clone_type ()));
for (auto &arg : args.get_type_args ())
{
type_args.push_back (std::unique_ptr<HIR::Type> (arg->clone_type ()));
@@ -292,7 +327,7 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
if (!args.is_empty () || predicate.requires_generic_args ())
{
// this is applying generic arguments to a trait reference
- predicate.apply_generic_arguments (&args, associated_self != nullptr);
+ predicate.apply_generic_arguments (&args, associated_self.has_value ());
}
context->insert_resolved_predicate (type_path.get_mappings ().get_hirid (),
@@ -310,7 +345,8 @@ TypeBoundPredicate::TypeBoundPredicate (
location_t locus)
: SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
reference (trait_reference.get_mappings ().get_defid ()), locus (locus),
- error_flag (false), polarity (polarity)
+ error_flag (false), polarity (polarity),
+ super_traits (trait_reference.get_super_traits ())
{
rust_assert (!trait_reference.get_trait_substs ().empty ());
@@ -350,7 +386,8 @@ TypeBoundPredicate::TypeBoundPredicate (mark_is_error)
TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other)
: SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
reference (other.reference), locus (other.locus),
- error_flag (other.error_flag), polarity (other.polarity)
+ error_flag (other.error_flag), polarity (other.polarity),
+ super_traits (other.super_traits)
{
substitutions.clear ();
for (const auto &p : other.get_substs ())
@@ -420,6 +457,7 @@ TypeBoundPredicate::operator= (const TypeBoundPredicate &other)
= SubstitutionArgumentMappings (copied_arg_mappings, {},
other.used_arguments.get_regions (),
other.used_arguments.get_locus ());
+ super_traits = other.super_traits;
return *this;
}
@@ -486,11 +524,19 @@ TypeBoundPredicate::apply_generic_arguments (HIR::GenericArgs *generic_args,
}
// now actually perform a substitution
- used_arguments = get_mappings_from_generic_args (
+ auto args = get_mappings_from_generic_args (
*generic_args,
Resolver::TypeCheckContext::get ()->regions_from_generic_args (
*generic_args));
+ apply_argument_mappings (args);
+}
+
+void
+TypeBoundPredicate::apply_argument_mappings (
+ SubstitutionArgumentMappings &arguments)
+{
+ used_arguments = arguments;
error_flag |= used_arguments.is_error ();
auto &subst_mappings = used_arguments;
for (auto &sub : get_substs ())
@@ -514,6 +560,14 @@ TypeBoundPredicate::apply_generic_arguments (HIR::GenericArgs *generic_args,
const auto item_ref = item.get_raw_item ();
item_ref->associated_type_set (type);
}
+
+ for (auto &super_trait : super_traits)
+ {
+ auto adjusted
+ = super_trait.adjust_mappings_for_this (used_arguments,
+ true /*trait mode*/);
+ super_trait.apply_argument_mappings (adjusted);
+ }
}
bool
@@ -529,34 +583,56 @@ TypeBoundPredicate::lookup_associated_item (const std::string &search) const
{
auto trait_ref = get ();
const Resolver::TraitItemReference *trait_item_ref = nullptr;
- if (!trait_ref->lookup_trait_item (search, &trait_item_ref))
- return TypeBoundPredicateItem::error ();
+ if (trait_ref->lookup_trait_item (search, &trait_item_ref,
+ false /*lookup supers*/))
+ return TypeBoundPredicateItem (*this, trait_item_ref);
- return TypeBoundPredicateItem (this, trait_item_ref);
+ for (auto &super_trait : super_traits)
+ {
+ auto lookup = super_trait.lookup_associated_item (search);
+ if (!lookup.is_error ())
+ return lookup;
+ }
+
+ return TypeBoundPredicateItem::error ();
}
TypeBoundPredicateItem::TypeBoundPredicateItem (
- const TypeBoundPredicate *parent,
+ const TypeBoundPredicate parent,
const Resolver::TraitItemReference *trait_item_ref)
: parent (parent), trait_item_ref (trait_item_ref)
{}
+TypeBoundPredicateItem::TypeBoundPredicateItem (
+ const TypeBoundPredicateItem &other)
+ : parent (other.parent), trait_item_ref (other.trait_item_ref)
+{}
+
+TypeBoundPredicateItem &
+TypeBoundPredicateItem::operator= (const TypeBoundPredicateItem &other)
+{
+ parent = other.parent;
+ trait_item_ref = other.trait_item_ref;
+
+ return *this;
+}
+
TypeBoundPredicateItem
TypeBoundPredicateItem::error ()
{
- return TypeBoundPredicateItem (nullptr, nullptr);
+ return TypeBoundPredicateItem (TypeBoundPredicate::error (), nullptr);
}
bool
TypeBoundPredicateItem::is_error () const
{
- return parent == nullptr || trait_item_ref == nullptr;
+ return parent.is_error () || trait_item_ref == nullptr;
}
const TypeBoundPredicate *
TypeBoundPredicateItem::get_parent () const
{
- return parent;
+ return &parent;
}
TypeBoundPredicateItem
@@ -570,7 +646,7 @@ BaseType *
TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver)
{
TyTy::BaseType *trait_item_tyty = get_raw_item ()->get_tyty ();
- if (parent->get_substitution_arguments ().is_empty ())
+ if (parent.get_substitution_arguments ().is_empty ())
return trait_item_tyty;
const Resolver::TraitItemReference *tref = get_raw_item ();
@@ -579,7 +655,7 @@ TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver)
return trait_item_tyty;
// set up the self mapping
- SubstitutionArgumentMappings gargs = parent->get_substitution_arguments ();
+ SubstitutionArgumentMappings gargs = parent.get_substitution_arguments ();
rust_assert (!gargs.is_empty ());
// setup the adjusted mappings
@@ -711,7 +787,7 @@ TypeBoundPredicate::get_associated_type_items ()
== Resolver::TraitItemReference::TraitItemType::TYPE;
if (is_associated_type)
{
- TypeBoundPredicateItem item (this, &trait_item);
+ TypeBoundPredicateItem item (*this, &trait_item);
items.push_back (std::move (item));
}
}
@@ -752,6 +828,65 @@ TypeBoundPredicate::is_equal (const TypeBoundPredicate &other) const
return true;
}
+bool
+TypeBoundPredicate::validate_type_implements_super_traits (
+ TyTy::BaseType &self, HIR::Type &impl_type, HIR::Type &trait) const
+{
+ if (get_polarity () != BoundPolarity::RegularBound)
+ return true;
+
+ auto &ptref = *get ();
+ for (auto &super : super_traits)
+ {
+ if (super.get_polarity () != BoundPolarity::RegularBound)
+ continue;
+
+ if (!super.validate_type_implements_this (self, impl_type, trait))
+ {
+ auto &sptref = *super.get ();
+
+ // emit error
+ std::string fixit1
+ = "required by this bound in: " + ptref.get_name ();
+ std::string fixit2 = "the trait " + sptref.get_name ()
+ + " is not implemented for "
+ + impl_type.as_string ();
+
+ rich_location r (line_table, trait.get_locus ());
+ r.add_fixit_insert_after (super.get_locus (), fixit1.c_str ());
+ r.add_fixit_insert_after (trait.get_locus (), fixit2.c_str ());
+ rust_error_at (r, ErrorCode::E0277,
+ "the trait bound %<%s: %s%> is not satisfied",
+ impl_type.as_string ().c_str (),
+ sptref.get_name ().c_str ());
+
+ return false;
+ }
+
+ if (!super.validate_type_implements_super_traits (self, impl_type, trait))
+ return false;
+ }
+
+ return true;
+}
+
+bool
+TypeBoundPredicate::validate_type_implements_this (TyTy::BaseType &self,
+ HIR::Type &impl_type,
+ HIR::Type &trait) const
+{
+ const auto &ptref = *get ();
+ auto probed_bounds = Resolver::TypeBoundsProbe::Probe (&self);
+ for (auto &elem : probed_bounds)
+ {
+ auto &tref = *(elem.first);
+ if (ptref.is_equal (tref))
+ return true;
+ }
+
+ return false;
+}
+
// trait item reference
const Resolver::TraitItemReference *
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.h b/gcc/rust/typecheck/rust-tyty-bounds.h
index be309b2..6392af1 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.h
+++ b/gcc/rust/typecheck/rust-tyty-bounds.h
@@ -34,31 +34,6 @@ namespace TyTy {
class BaseType;
class TypeBoundPredicate;
-class TypeBoundPredicateItem
-{
-public:
- TypeBoundPredicateItem (const TypeBoundPredicate *parent,
- const Resolver::TraitItemReference *trait_item_ref);
-
- static TypeBoundPredicateItem error ();
-
- bool is_error () const;
-
- BaseType *get_tyty_for_receiver (const TyTy::BaseType *receiver);
-
- const Resolver::TraitItemReference *get_raw_item () const;
-
- bool needs_implementation () const;
-
- const TypeBoundPredicate *get_parent () const;
-
- location_t get_locus () const;
-
-private:
- const TypeBoundPredicate *parent;
- const Resolver::TraitItemReference *trait_item_ref;
-};
-
class TypeBoundsMappings
{
protected:
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index ad3b2c3..2e0830e 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -80,7 +80,7 @@ TypeCheckCallExpr::visit (ADTType &type)
BaseType *field_tyty = field->get_field_type ();
location_t arg_locus = argument->get_locus ();
- BaseType *arg = Resolver::TypeCheckExpr::Resolve (argument.get ());
+ BaseType *arg = Resolver::TypeCheckExpr::Resolve (*argument);
if (arg->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (argument->get_locus (),
@@ -139,26 +139,19 @@ TypeCheckCallExpr::visit (FnType &type)
for (auto &argument : call.get_arguments ())
{
location_t arg_locus = argument->get_locus ();
- auto argument_expr_tyty
- = Resolver::TypeCheckExpr::Resolve (argument.get ());
- if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (
- argument->get_locus (),
- "failed to resolve type for argument expr in CallExpr");
- return;
- }
+ auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (*argument);
+ if (argument_expr_tyty->is<TyTy::ErrorType> ())
+ return;
// it might be a variadic function
if (i < type.num_params ())
{
- auto fnparam = type.param_at (i);
- HIR::Pattern *fn_param_pattern = fnparam.first;
- BaseType *param_ty = fnparam.second;
+ auto &fnparam = type.param_at (i);
+ BaseType *param_ty = fnparam.get_type ();
location_t param_locus
- = fn_param_pattern == nullptr
- ? mappings.lookup_location (param_ty->get_ref ())
- : fn_param_pattern->get_locus ();
+ = fnparam.has_pattern ()
+ ? fnparam.get_pattern ().get_locus ()
+ : mappings.lookup_location (param_ty->get_ref ());
HirId coercion_side_id = argument->get_mappings ().get_hirid ();
auto resolved_argument_type
@@ -272,8 +265,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
{
location_t arg_locus = argument->get_locus ();
BaseType *fnparam = type.get_param_type_at (i);
- auto argument_expr_tyty
- = Resolver::TypeCheckExpr::Resolve (argument.get ());
+ auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (*argument);
if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (
@@ -322,8 +314,7 @@ TypeCheckMethodCallExpr::go (FnType *ref, HIR::MethodCallExpr &call,
std::vector<Argument> args;
for (auto &arg : call.get_arguments ())
{
- BaseType *argument_expr_tyty
- = Resolver::TypeCheckExpr::Resolve (arg.get ());
+ BaseType *argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (*arg);
if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (arg->get_locus (),
@@ -337,7 +328,7 @@ TypeCheckMethodCallExpr::go (FnType *ref, HIR::MethodCallExpr &call,
TypeCheckMethodCallExpr checker (call.get_mappings (), args,
call.get_locus (),
- call.get_receiver ()->get_locus (),
+ call.get_receiver ().get_locus (),
adjusted_self, context);
return checker.check (*ref);
}
@@ -377,13 +368,12 @@ TypeCheckMethodCallExpr::check (FnType &type)
{
location_t arg_locus = argument.get_locus ();
- auto fnparam = type.param_at (i);
- HIR::Pattern *fn_param_pattern = fnparam.first;
- BaseType *param_ty = fnparam.second;
+ auto &fnparam = type.param_at (i);
+ BaseType *param_ty = fnparam.get_type ();
location_t param_locus
- = fn_param_pattern == nullptr
- ? mappings.lookup_location (param_ty->get_ref ())
- : fn_param_pattern->get_locus ();
+ = fnparam.has_pattern ()
+ ? fnparam.get_pattern ().get_locus ()
+ : mappings.lookup_location (param_ty->get_ref ());
auto argument_expr_tyty = argument.get_argument_type ();
HirId coercion_side_id = argument.get_mappings ().get_hirid ();
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index 67cfe30..c42fdcd 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -61,6 +61,7 @@ public:
void visit (ProjectionType &) override { rust_unreachable (); }
void visit (DynamicObjectType &) override { rust_unreachable (); }
void visit (ClosureType &type) override { rust_unreachable (); }
+ void visit (OpaqueType &type) override { rust_unreachable (); }
// tuple-structs
void visit (ADTType &type) override;
@@ -73,14 +74,12 @@ private:
TypeCheckCallExpr (HIR::CallExpr &c, TyTy::VariantDef &variant,
Resolver::TypeCheckContext *context)
: resolved (new TyTy::ErrorType (c.get_mappings ().get_hirid ())), call (c),
- variant (variant), context (context),
- mappings (Analysis::Mappings::get ())
+ variant (variant), mappings (Analysis::Mappings::get ())
{}
BaseType *resolved;
HIR::CallExpr &call;
TyTy::VariantDef &variant;
- Resolver::TypeCheckContext *context;
Analysis::Mappings &mappings;
};
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h
index c384287..c897c13 100644
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ b/gcc/rust/typecheck/rust-tyty-cmp.h
@@ -431,6 +431,22 @@ public:
}
}
+ virtual void visit (const OpaqueType &type) override
+ {
+ ok = false;
+ if (emit_error_flag)
+ {
+ location_t ref_locus = mappings.lookup_location (type.get_ref ());
+ location_t base_locus
+ = mappings.lookup_location (get_base ()->get_ref ());
+ rich_location r (line_table, ref_locus);
+ r.add_range (base_locus);
+ rust_error_at (r, "expected [%s] got [%s]",
+ get_base ()->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+ }
+
protected:
BaseCmp (const BaseType *base, bool emit_errors)
: mappings (Analysis::Mappings::get ()),
@@ -735,8 +751,8 @@ public:
for (size_t i = 0; i < base->num_params (); i++)
{
- auto a = base->param_at (i).second;
- auto b = type.param_at (i).second;
+ auto a = base->param_at (i).get_type ();
+ auto b = type.param_at (i).get_type ();
if (!a->can_eq (b, emit_error_flag))
{
@@ -831,7 +847,7 @@ public:
for (size_t i = 0; i < base->num_params (); i++)
{
auto this_param = base->get_param_type_at (i);
- auto other_param = type.param_at (i).second;
+ auto other_param = type.param_at (i).get_type ();
if (!this_param->can_eq (other_param, emit_error_flag))
{
BaseCmp::visit (type);
@@ -1571,6 +1587,23 @@ private:
const DynamicObjectType *base;
};
+class OpaqueCmp : public BaseCmp
+{
+ using Rust::TyTy::BaseCmp::visit;
+
+public:
+ OpaqueCmp (const OpaqueType *base, bool emit_errors)
+ : BaseCmp (base, emit_errors), base (base)
+ {}
+
+ // TODO
+
+private:
+ const BaseType *get_base () const override { return base; }
+
+ const OpaqueType *base;
+};
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index a3ebf0a..bdb6474 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -28,8 +28,8 @@
namespace Rust {
namespace TyTy {
-SubstitutionParamMapping::SubstitutionParamMapping (
- const HIR::TypeParam &generic, ParamType *param)
+SubstitutionParamMapping::SubstitutionParamMapping (HIR::TypeParam &generic,
+ ParamType *param)
: generic (generic), param (param)
{}
@@ -66,8 +66,8 @@ SubstitutionParamMapping::get_param_ty () const
return param;
}
-const HIR::TypeParam &
-SubstitutionParamMapping::get_generic_param () const
+HIR::TypeParam &
+SubstitutionParamMapping::get_generic_param ()
{
return generic;
}
@@ -630,12 +630,10 @@ SubstitutionRef::get_mappings_from_generic_args (
for (auto &binding : args.get_binding_args ())
{
BaseType *resolved
- = Resolver::TypeCheckType::Resolve (binding.get_type ().get ());
+ = Resolver::TypeCheckType::Resolve (binding.get_type ());
if (resolved == nullptr
|| resolved->get_kind () == TyTy::TypeKind::ERROR)
{
- rust_error_at (binding.get_locus (),
- "failed to resolve type arguments");
return SubstitutionArgumentMappings::error ();
}
@@ -698,10 +696,9 @@ SubstitutionRef::get_mappings_from_generic_args (
std::vector<SubstitutionArg> mappings = used_arguments.get_mappings ();
for (auto &arg : args.get_type_args ())
{
- BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ());
+ BaseType *resolved = Resolver::TypeCheckType::Resolve (*arg);
if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR)
{
- rust_error_at (args.get_locus (), "failed to resolve type arguments");
return SubstitutionArgumentMappings::error ();
}
@@ -791,7 +788,7 @@ SubstitutionRef::infer_substitions (location_t locus)
SubstitutionArgumentMappings
SubstitutionRef::adjust_mappings_for_this (
- SubstitutionArgumentMappings &mappings)
+ SubstitutionArgumentMappings &mappings, bool trait_mode)
{
std::vector<SubstitutionArg> resolved_mappings;
for (size_t i = 0; i < substitutions.size (); i++)
@@ -819,7 +816,7 @@ SubstitutionRef::adjust_mappings_for_this (
}
bool ok = !arg.is_error ();
- if (ok)
+ if (ok || (trait_mode && i == 0))
{
SubstitutionArg adjusted (&subst, arg.get_tyty ());
resolved_mappings.push_back (std::move (adjusted));
@@ -937,27 +934,8 @@ SubstitutionRef::monomorphize ()
auto associated
= Resolver::lookup_associated_impl_block (bound, binding,
&ambigious);
- if (associated == nullptr && ambigious)
- {
- // go for the first one? or error out?
- auto &mappings = Analysis::Mappings::get ();
- const auto &type_param = subst.get_generic_param ();
- const auto *trait_ref = bound.get ();
-
- rich_location r (line_table, type_param.get_locus ());
- r.add_range (bound.get_locus ());
- r.add_range (mappings.lookup_location (binding->get_ref ()));
-
- rust_error_at (r, "ambiguous type bound for trait %s and type %s",
- trait_ref->get_name ().c_str (),
- binding->get_name ().c_str ());
- return false;
- }
-
if (associated != nullptr)
- {
- associated->setup_associated_types (binding, bound);
- }
+ associated->setup_associated_types (binding, bound);
}
}
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
index ab53502..e6ed1fc 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -44,7 +44,7 @@ class SubstitutionArgumentMappings;
class SubstitutionParamMapping
{
public:
- SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param);
+ SubstitutionParamMapping (HIR::TypeParam &generic, ParamType *param);
SubstitutionParamMapping (const SubstitutionParamMapping &other);
@@ -59,7 +59,7 @@ public:
const ParamType *get_param_ty () const;
- const HIR::TypeParam &get_generic_param () const;
+ HIR::TypeParam &get_generic_param ();
// 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
@@ -76,7 +76,7 @@ public:
bool need_substitution () const;
private:
- const HIR::TypeParam &generic;
+ HIR::TypeParam &generic;
ParamType *param;
};
@@ -125,7 +125,7 @@ public:
std::vector<Region> subst)
{
RegionParamList list (num_regions);
- for (size_t i = 0; i < subst.size (); i++)
+ for (size_t i = 0; i < MIN (num_regions, subst.size ()); i++)
list.regions.at (i) = subst.at (i);
for (size_t i = subst.size (); i < num_regions; i++)
{
@@ -253,6 +253,7 @@ private:
bool error_flag;
};
+class TypeBoundPredicateItem;
class SubstitutionRef
{
public:
@@ -319,7 +320,8 @@ public:
// we have bindings for X Y Z and need to propagate the binding Y,Z into Foo
// Which binds to A,B
SubstitutionArgumentMappings
- adjust_mappings_for_this (SubstitutionArgumentMappings &mappings);
+ adjust_mappings_for_this (SubstitutionArgumentMappings &mappings,
+ bool trait_mode = false);
// Are the mappings here actually bound to this type. For example imagine the
// case:
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
index 450e53e..d36afc8 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
@@ -168,6 +168,8 @@ public:
{
// TODO
}
+
+ void visit (OpaqueType &type) override {}
};
/** Per crate context for generic type variance analysis. */
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
index 1aba576..38f9d52 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
@@ -238,7 +238,7 @@ GenericTyVisitorCtx::process_type (ADTType &ty)
first_lifetime = lookup_or_add_type (ty.get_orig_ref ());
first_type = first_lifetime + ty.get_used_arguments ().get_regions ().size ();
- for (const auto &param : ty.get_substs ())
+ for (auto &param : ty.get_substs ())
param_names.push_back (
param.get_generic_param ().get_type_representation ().as_string ());
diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h
index 85726ff..4f8e785 100644
--- a/gcc/rust/typecheck/rust-tyty-visitor.h
+++ b/gcc/rust/typecheck/rust-tyty-visitor.h
@@ -51,6 +51,7 @@ public:
virtual void visit (ProjectionType &type) = 0;
virtual void visit (DynamicObjectType &type) = 0;
virtual void visit (ClosureType &type) = 0;
+ virtual void visit (OpaqueType &type) = 0;
};
class TyConstVisitor
@@ -80,6 +81,7 @@ public:
virtual void visit (const ProjectionType &type) = 0;
virtual void visit (const DynamicObjectType &type) = 0;
virtual void visit (const ClosureType &type) = 0;
+ virtual void visit (const OpaqueType &type) = 0;
};
} // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index e0a8745..f0f4a07 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -18,6 +18,7 @@
#include "rust-tyty.h"
+#include "optional.h"
#include "rust-tyty-visitor.h"
#include "rust-hir-map.h"
#include "rust-location.h"
@@ -31,6 +32,7 @@
#include "rust-hir-type-bounds.h"
#include "options.h"
+#include "rust-system.h"
namespace Rust {
namespace TyTy {
@@ -109,6 +111,9 @@ TypeKindFormat::to_string (TypeKind kind)
case TypeKind::CLOSURE:
return "Closure";
+ case TypeKind::OPAQUE:
+ return "Opaque";
+
case TypeKind::ERROR:
return "ERROR";
}
@@ -215,7 +220,7 @@ BaseType::is_unit () const
case FLOAT:
case USIZE:
case ISIZE:
-
+ case OPAQUE:
case STR:
case DYNAMIC:
case ERROR:
@@ -541,6 +546,17 @@ 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;
+
+ // x = pr;
+ // }
else
{
return x;
@@ -593,9 +609,9 @@ BaseType::monomorphized_clone () const
}
else if (auto fn = x->try_as<const FnType> ())
{
- std::vector<std::pair<HIR::Pattern *, BaseType *>> cloned_params;
+ std::vector<TyTy::FnParam> cloned_params;
for (auto &p : fn->get_params ())
- cloned_params.push_back ({p.first, p.second->monomorphized_clone ()});
+ cloned_params.push_back (p.monomorphized_clone ());
BaseType *retty = fn->get_return_type ()->monomorphized_clone ();
return new FnType (fn->get_ref (), fn->get_ty_ref (), fn->get_id (),
@@ -622,7 +638,7 @@ BaseType::monomorphized_clone () const
for (auto &variant : adt->get_variants ())
cloned_variants.push_back (variant->monomorphized_clone ());
- return new ADTType (adt->get_ref (), adt->get_ty_ref (),
+ return new ADTType (adt->get_id (), adt->get_ref (), adt->get_ty_ref (),
adt->get_identifier (), adt->ident,
adt->get_adt_kind (), cloned_variants,
adt->clone_substs (), adt->get_repr_options (),
@@ -666,6 +682,91 @@ BaseType::debug () const
debug_str ().c_str ());
}
+const TyTy::BaseType *
+BaseType::contains_infer () const
+{
+ const TyTy::BaseType *x = destructure ();
+
+ if (auto fn = x->try_as<const FnType> ())
+ {
+ for (const auto &param : fn->get_params ())
+ {
+ auto infer = param.get_type ()->contains_infer ();
+ if (infer)
+ return infer;
+ }
+ return fn->get_return_type ()->contains_infer ();
+ }
+ else if (auto fn = x->try_as<const FnPtr> ())
+ {
+ for (const auto &param : fn->get_params ())
+ {
+ auto infer = param.get_tyty ()->contains_infer ();
+ if (infer)
+ return infer;
+ }
+ return fn->get_return_type ()->contains_infer ();
+ }
+ else if (auto adt = x->try_as<const ADTType> ())
+ {
+ for (auto &variant : adt->get_variants ())
+ {
+ bool is_num_variant
+ = variant->get_variant_type () == VariantDef::VariantType::NUM;
+ if (is_num_variant)
+ continue;
+
+ for (auto &field : variant->get_fields ())
+ {
+ const BaseType *field_type = field->get_field_type ();
+ auto infer = (field_type->contains_infer ());
+ if (infer)
+ return infer;
+ }
+ }
+ return nullptr;
+ }
+ else if (auto arr = x->try_as<const ArrayType> ())
+ {
+ return arr->get_element_type ()->contains_infer ();
+ }
+ else if (auto slice = x->try_as<const SliceType> ())
+ {
+ return slice->get_element_type ()->contains_infer ();
+ }
+ else if (auto ptr = x->try_as<const PointerType> ())
+ {
+ return ptr->get_base ()->contains_infer ();
+ }
+ else if (auto ref = x->try_as<const ReferenceType> ())
+ {
+ return ref->get_base ()->contains_infer ();
+ }
+ else if (auto tuple = x->try_as<const TupleType> ())
+ {
+ for (size_t i = 0; i < tuple->num_fields (); i++)
+ {
+ auto infer = (tuple->get_field (i)->contains_infer ());
+ if (infer)
+ return infer;
+ }
+ return nullptr;
+ }
+ else if (auto closure = x->try_as<const ClosureType> ())
+ {
+ auto infer = (closure->get_parameters ().contains_infer ());
+ if (infer)
+ return infer;
+ return closure->get_result_type ().contains_infer ();
+ }
+ else if (x->is<InferType> ())
+ {
+ return x;
+ }
+
+ return nullptr;
+}
+
bool
BaseType::is_concrete () const
{
@@ -686,7 +787,7 @@ BaseType::is_concrete () const
{
for (const auto &param : fn->get_params ())
{
- if (!param.second->is_concrete ())
+ if (!param.get_type ()->is_concrete ())
return false;
}
return fn->get_return_type ()->is_concrete ();
@@ -790,6 +891,7 @@ BaseType::has_substitutions_defined () const
case TUPLE:
case PARAM:
case PLACEHOLDER:
+ case OPAQUE:
return false;
case PROJECTION: {
@@ -851,6 +953,7 @@ BaseType::needs_generic_substitutions () const
case TUPLE:
case PARAM:
case PLACEHOLDER:
+ case OPAQUE:
return false;
case PROJECTION: {
@@ -886,6 +989,48 @@ BaseType::needs_generic_substitutions () const
return false;
}
+const SubstitutionArgumentMappings &
+BaseType::get_subst_argument_mappings () const
+{
+ static auto empty = SubstitutionArgumentMappings::empty ();
+ const TyTy::BaseType *x = destructure ();
+ switch (x->get_kind ())
+ {
+ 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: {
+ const auto &fn = *static_cast<const FnType *> (x);
+ const auto &ref = static_cast<const SubstitutionRef &> (fn);
+ return ref.get_substitution_arguments ();
+ }
+ break;
+
+ 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: {
+ const auto &closure = *static_cast<const ClosureType *> (x);
+ const auto &ref = static_cast<const SubstitutionRef &> (closure);
+ return ref.get_substitution_arguments ();
+ }
+ break;
+
+ default:
+ return empty;
+ }
+
+ return empty;
+}
+
// InferType
InferType::InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint,
@@ -1341,9 +1486,10 @@ VariantDef::variant_type_string (VariantType type)
}
VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
- RustIdent ident, HIR::Expr *discriminant)
+ RustIdent ident,
+ tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant)
: id (id), defid (defid), identifier (identifier), ident (ident),
- discriminant (discriminant)
+ discriminant (std::move (discriminant))
{
type = VariantType::NUM;
@@ -1352,41 +1498,22 @@ VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
RustIdent ident, VariantType type,
- HIR::Expr *discriminant,
+ tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant,
std::vector<StructFieldType *> fields)
: id (id), defid (defid), identifier (identifier), ident (ident), type (type),
- discriminant (discriminant), fields (fields)
+ discriminant (std::move (discriminant)), fields (fields)
{
rust_assert ((type == VariantType::NUM && fields.empty ())
|| (type == VariantType::TUPLE || type == VariantType::STRUCT));
}
-VariantDef::VariantDef (const VariantDef &other)
- : id (other.id), defid (other.defid), identifier (other.identifier),
- ident (other.ident), type (other.type), discriminant (other.discriminant),
- fields (other.fields)
-{}
-
-VariantDef &
-VariantDef::operator= (const VariantDef &other)
-{
- id = other.id;
- identifier = other.identifier;
- type = other.type;
- discriminant = other.discriminant;
- fields = other.fields;
- ident = other.ident;
-
- return *this;
-}
-
VariantDef &
VariantDef::get_error_node ()
{
static VariantDef node
= VariantDef (UNKNOWN_HIRID, UNKNOWN_DEFID, "",
{Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
- nullptr);
+ tl::nullopt);
return node;
}
@@ -1475,18 +1602,31 @@ VariantDef::lookup_field (const std::string &lookup,
return false;
}
-HIR::Expr *
+HIR::Expr &
+VariantDef::get_discriminant ()
+{
+ return *discriminant.value ();
+}
+
+const HIR::Expr &
VariantDef::get_discriminant () const
{
- rust_assert (discriminant != nullptr);
- return discriminant;
+ return *discriminant.value ();
+}
+
+bool
+VariantDef::has_discriminant () const
+{
+ return discriminant.has_value ();
}
std::string
VariantDef::as_string () const
{
if (type == VariantType::NUM)
- return identifier + " = " + discriminant->as_string ();
+ return identifier
+ + (has_discriminant () ? " = " + get_discriminant ().as_string ()
+ : "");
std::string buffer;
for (size_t i = 0; i < fields.size (); ++i)
@@ -1511,9 +1651,6 @@ VariantDef::is_equal (const VariantDef &other) const
if (identifier.compare (other.identifier) != 0)
return false;
- if (discriminant != other.discriminant)
- return false;
-
if (fields.size () != other.fields.size ())
return false;
@@ -1533,8 +1670,13 @@ VariantDef::clone () const
for (auto &f : fields)
cloned_fields.push_back ((StructFieldType *) f->clone ());
- return new VariantDef (id, defid, identifier, ident, type, discriminant,
- cloned_fields);
+ auto &&discriminant_opt = has_discriminant ()
+ ? tl::optional<std::unique_ptr<HIR::Expr>> (
+ get_discriminant ().clone_expr ())
+ : tl::nullopt;
+
+ return new VariantDef (id, defid, identifier, ident, type,
+ std::move (discriminant_opt), cloned_fields);
}
VariantDef *
@@ -1544,8 +1686,13 @@ VariantDef::monomorphized_clone () const
for (auto &f : fields)
cloned_fields.push_back ((StructFieldType *) f->monomorphized_clone ());
- return new VariantDef (id, defid, identifier, ident, type, discriminant,
- cloned_fields);
+ auto discriminant_opt = has_discriminant ()
+ ? tl::optional<std::unique_ptr<HIR::Expr>> (
+ get_discriminant ().clone_expr ())
+ : tl::nullopt;
+
+ return new VariantDef (id, defid, identifier, ident, type,
+ std::move (discriminant_opt), cloned_fields);
}
const RustIdent &
@@ -1556,6 +1703,43 @@ VariantDef::get_ident () const
// ADTType
+ADTType::ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
+ ADTKind adt_kind, std::vector<VariantDef *> variants,
+ std::vector<SubstitutionParamMapping> subst_refs,
+ SubstitutionArgumentMappings generic_arguments,
+ RegionConstraints region_constraints, std::set<HirId> refs)
+ : BaseType (ref, ref, TypeKind::ADT, ident, refs),
+ SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+ region_constraints),
+ id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
+{}
+
+ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
+ RustIdent ident, ADTKind adt_kind,
+ std::vector<VariantDef *> variants,
+ std::vector<SubstitutionParamMapping> subst_refs,
+ SubstitutionArgumentMappings generic_arguments,
+ RegionConstraints region_constraints, std::set<HirId> refs)
+ : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
+ SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+ region_constraints),
+ id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
+{}
+
+ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
+ RustIdent ident, ADTKind adt_kind,
+ std::vector<VariantDef *> variants,
+ std::vector<SubstitutionParamMapping> subst_refs,
+ ReprOptions repr,
+ SubstitutionArgumentMappings generic_arguments,
+ RegionConstraints region_constraints, std::set<HirId> refs)
+ : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
+ SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+ region_constraints),
+ id (id), identifier (identifier), variants (variants), adt_kind (adt_kind),
+ repr (repr)
+{}
+
void
ADTType::accept_vis (TyVisitor &vis)
{
@@ -1637,6 +1821,12 @@ ADTType::is_equal (const BaseType &other) const
return true;
}
+DefId
+ADTType::get_id () const
+{
+ return id;
+}
+
BaseType *
ADTType::clone () const
{
@@ -1644,7 +1834,7 @@ ADTType::clone () const
for (auto &variant : variants)
cloned_variants.push_back (variant->clone ());
- return new ADTType (get_ref (), get_ty_ref (), identifier, ident,
+ return new ADTType (get_id (), get_ref (), get_ty_ref (), identifier, ident,
get_adt_kind (), cloned_variants, clone_substs (),
get_repr_options (), used_arguments,
get_region_constraints (), get_combined_refs ());
@@ -1747,9 +1937,13 @@ TupleType::TupleType (HirId ref, HirId ty_ref, location_t locus,
{}
TupleType *
-TupleType::get_unit_type (HirId ref)
+TupleType::get_unit_type ()
{
- return new TupleType (ref, BUILTINS_LOCATION);
+ static TupleType *ret = nullptr;
+ if (ret == nullptr)
+ ret = new TupleType (Analysis::Mappings::get ().get_next_hir_id (),
+ BUILTINS_LOCATION);
+ return ret;
}
size_t
@@ -1891,9 +2085,9 @@ FnType::as_string () const
std::string params_str = "";
for (auto &param : params)
{
- auto pattern = param.first;
- auto ty = param.second;
- params_str += pattern->as_string () + " " + ty->as_string ();
+ auto &pattern = param.get_pattern ();
+ auto ty = param.get_type ();
+ params_str += pattern.as_string () + " " + ty->as_string ();
params_str += ",";
}
@@ -1914,7 +2108,7 @@ FnType::is_equal (const BaseType &other) const
if (get_kind () != other.get_kind ())
return false;
- auto other2 = static_cast<const FnType &> (other);
+ auto &other2 = static_cast<const FnType &> (other);
if (get_identifier ().compare (other2.get_identifier ()) != 0)
return false;
@@ -1948,8 +2142,8 @@ FnType::is_equal (const BaseType &other) const
for (size_t i = 0; i < num_params (); i++)
{
- auto lhs = param_at (i).second;
- auto rhs = other2.param_at (i).second;
+ auto lhs = param_at (i).get_type ();
+ auto rhs = other2.param_at (i).get_type ();
if (!lhs->is_equal (*rhs))
return false;
}
@@ -1959,9 +2153,9 @@ FnType::is_equal (const BaseType &other) const
BaseType *
FnType::clone () const
{
- std::vector<std::pair<HIR::Pattern *, BaseType *>> cloned_params;
+ std::vector<TyTy::FnParam> cloned_params;
for (auto &p : params)
- cloned_params.push_back ({p.first, p.second->clone ()});
+ cloned_params.push_back (p.clone ());
return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
ident, flags, abi, std::move (cloned_params),
@@ -2035,7 +2229,7 @@ FnType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
for (auto &param : fn->get_params ())
{
- auto fty = param.second;
+ auto fty = param.get_type ();
bool is_param_ty = fty->get_kind () == TypeKind::PARAM;
if (is_param_ty)
@@ -2054,7 +2248,7 @@ FnType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
{
auto new_field = argt->clone ();
new_field->set_ref (fty->get_ref ());
- param.second = new_field;
+ param.set_type (new_field);
}
else
{
@@ -2078,7 +2272,7 @@ FnType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
auto new_field = concrete->clone ();
new_field->set_ref (fty->get_ref ());
- param.second = new_field;
+ param.set_type (new_field);
}
}
@@ -2215,12 +2409,24 @@ void
ClosureType::setup_fn_once_output () const
{
// lookup the lang items
- auto fn_once_lang_item = LangItem::Kind::FN_ONCE;
- auto fn_once_output_lang_item = LangItem::Kind::FN_ONCE_OUTPUT;
+ auto fn_once_lookup = mappings.lookup_lang_item (LangItem::Kind::FN_ONCE);
+ auto fn_once_output_lookup
+ = mappings.lookup_lang_item (LangItem::Kind::FN_ONCE_OUTPUT);
+ if (!fn_once_lookup)
+ {
+ rust_fatal_error (UNKNOWN_LOCATION,
+ "Missing required %<fn_once%> lang item");
+ return;
+ }
+ if (!fn_once_output_lookup)
+ {
+ rust_fatal_error (UNKNOWN_LOCATION,
+ "Missing required %<fn_once_ouput%> lang item");
+ return;
+ }
- DefId &trait_id = mappings.lookup_lang_item (fn_once_lang_item).value ();
- DefId &trait_item_id
- = mappings.lookup_lang_item (fn_once_output_lang_item).value ();
+ DefId &trait_id = fn_once_lookup.value ();
+ DefId &trait_item_id = fn_once_output_lookup.value ();
// resolve to the trait
HIR::Item *item = mappings.lookup_defid (trait_id).value ();
@@ -3350,6 +3556,140 @@ ParamType::is_implicit_self_trait () const
return is_trait_self;
}
+// OpaqueType
+
+OpaqueType::OpaqueType (location_t locus, HirId ref,
+ std::vector<TypeBoundPredicate> specified_bounds,
+ std::set<HirId> refs)
+ : BaseType (ref, ref, KIND,
+ {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
+ locus},
+ specified_bounds, refs)
+{}
+
+OpaqueType::OpaqueType (location_t locus, HirId ref, HirId ty_ref,
+ std::vector<TypeBoundPredicate> specified_bounds,
+ std::set<HirId> refs)
+ : BaseType (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
+ locus},
+ specified_bounds, refs)
+{}
+
+bool
+OpaqueType::can_resolve () const
+{
+ return get_ref () != get_ty_ref ();
+}
+
+void
+OpaqueType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+OpaqueType::accept_vis (TyConstVisitor &vis) const
+{
+ vis.visit (*this);
+}
+
+std::string
+OpaqueType::as_string () const
+{
+ return get_name ();
+}
+
+std::string
+OpaqueType::get_name () const
+{
+ return "impl " + raw_bounds_as_name ();
+}
+
+bool
+OpaqueType::can_eq (const BaseType *other, bool emit_errors) const
+{
+ OpaqueCmp r (this, emit_errors);
+ return r.can_eq (other);
+}
+
+BaseType *
+OpaqueType::clone () const
+{
+ return new OpaqueType (ident.locus, get_ref (), get_ty_ref (),
+ get_specified_bounds (), get_combined_refs ());
+}
+
+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;
+}
+
+bool
+OpaqueType::is_equal (const BaseType &other) const
+{
+ auto other2 = static_cast<const OpaqueType &> (other);
+ 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)
@@ -3460,20 +3800,20 @@ NeverType::clone () const
// placeholder type
-PlaceholderType::PlaceholderType (std::string symbol, HirId ref,
+PlaceholderType::PlaceholderType (std::string symbol, DefId id, HirId ref,
std::set<HirId> refs)
: BaseType (ref, ref, KIND,
{Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
refs),
- symbol (symbol)
+ symbol (symbol), defId (id)
{}
-PlaceholderType::PlaceholderType (std::string symbol, HirId ref, HirId ty_ref,
- std::set<HirId> refs)
+PlaceholderType::PlaceholderType (std::string symbol, DefId id, HirId ref,
+ HirId ty_ref, std::set<HirId> refs)
: BaseType (ref, ty_ref, KIND,
{Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
refs),
- symbol (symbol)
+ symbol (symbol), defId (id)
{}
std::string
@@ -3517,8 +3857,8 @@ PlaceholderType::can_eq (const BaseType *other, bool emit_errors) const
BaseType *
PlaceholderType::clone () const
{
- return new PlaceholderType (get_symbol (), get_ref (), get_ty_ref (),
- get_combined_refs ());
+ return new PlaceholderType (get_symbol (), get_def_id (), get_ref (),
+ get_ty_ref (), get_combined_refs ());
}
void
@@ -3539,7 +3879,17 @@ bool
PlaceholderType::can_resolve () const
{
auto context = Resolver::TypeCheckContext::get ();
- return context->lookup_associated_type_mapping (get_ty_ref (), nullptr);
+
+ BaseType *lookup = nullptr;
+ HirId mapping;
+
+ if (!context->lookup_associated_type_mapping (get_ty_ref (), &mapping))
+ return false;
+
+ if (!context->lookup_type (mapping, &lookup))
+ return false;
+
+ return lookup != nullptr;
}
BaseType *
@@ -3569,6 +3919,12 @@ PlaceholderType::is_equal (const BaseType &other) const
return get_symbol ().compare (other2.get_symbol ()) == 0;
}
+DefId
+PlaceholderType::get_def_id () const
+{
+ return defId;
+}
+
// Projection type
ProjectionType::ProjectionType (
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 3975029..1cada9a 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -28,6 +28,7 @@
#include "rust-tyty-subst.h"
#include "rust-tyty-region.h"
#include "rust-system.h"
+#include "rust-hir.h"
namespace Rust {
@@ -72,6 +73,7 @@ enum TypeKind
PROJECTION,
DYNAMIC,
CLOSURE,
+ OPAQUE,
// there are more to add...
ERROR
};
@@ -135,6 +137,9 @@ public:
void inherit_bounds (
const std::vector<TyTy::TypeBoundPredicate> &specified_bounds);
+ // contains_infer checks if there is an inference variable inside the type
+ const TyTy::BaseType *contains_infer () const;
+
// is_unit returns whether this is just a unit-struct
bool is_unit () const;
@@ -173,6 +178,7 @@ public:
bool has_substitutions_defined () const;
bool needs_generic_substitutions () const;
+ const SubstitutionArgumentMappings &get_subst_argument_mappings () const;
std::string mangle_string () const
{
@@ -406,6 +412,39 @@ private:
HIR::GenericParam &param;
};
+class OpaqueType : public BaseType
+{
+public:
+ static constexpr auto KIND = TypeKind::OPAQUE;
+
+ OpaqueType (location_t locus, HirId ref,
+ std::vector<TypeBoundPredicate> specified_bounds,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ OpaqueType (location_t locus, HirId ref, HirId ty_ref,
+ std::vector<TypeBoundPredicate> specified_bounds,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ bool can_eq (const BaseType *other, bool emit_errors) const override final;
+
+ BaseType *clone () const final override;
+
+ bool can_resolve () const;
+
+ BaseType *resolve () const;
+
+ std::string get_name () const override final;
+
+ bool is_equal (const BaseType &other) const override;
+
+ OpaqueType *handle_substitions (SubstitutionArgumentMappings &mappings);
+};
+
class StructFieldType
{
public:
@@ -447,7 +486,7 @@ public:
std::vector<TyVar> fields = std::vector<TyVar> (),
std::set<HirId> refs = std::set<HirId> ());
- static TupleType *get_unit_type (HirId ref);
+ static TupleType *get_unit_type ();
void accept_vis (TyVisitor &vis) override;
void accept_vis (TyConstVisitor &vis) const override;
@@ -509,6 +548,8 @@ public:
void apply_generic_arguments (HIR::GenericArgs *generic_args,
bool has_associated_self);
+ void apply_argument_mappings (SubstitutionArgumentMappings &arguments);
+
bool contains_item (const std::string &search) const;
TypeBoundPredicateItem
@@ -540,6 +581,14 @@ public:
bool is_equal (const TypeBoundPredicate &other) const;
+ bool validate_type_implements_super_traits (TyTy::BaseType &self,
+ HIR::Type &impl_type,
+ HIR::Type &trait) const;
+
+ bool validate_type_implements_this (TyTy::BaseType &self,
+ HIR::Type &impl_type,
+ HIR::Type &trait) const;
+
private:
struct mark_is_error
{
@@ -551,6 +600,36 @@ private:
location_t locus;
bool error_flag;
BoundPolarity polarity;
+ std::vector<TyTy::TypeBoundPredicate> super_traits;
+};
+
+class TypeBoundPredicateItem
+{
+public:
+ TypeBoundPredicateItem (const TypeBoundPredicate parent,
+ const Resolver::TraitItemReference *trait_item_ref);
+
+ TypeBoundPredicateItem (const TypeBoundPredicateItem &other);
+
+ TypeBoundPredicateItem &operator= (const TypeBoundPredicateItem &other);
+
+ static TypeBoundPredicateItem error ();
+
+ bool is_error () const;
+
+ BaseType *get_tyty_for_receiver (const TyTy::BaseType *receiver);
+
+ const Resolver::TraitItemReference *get_raw_item () const;
+
+ bool needs_implementation () const;
+
+ const TypeBoundPredicate *get_parent () const;
+
+ location_t get_locus () const;
+
+private:
+ TypeBoundPredicate parent;
+ const Resolver::TraitItemReference *trait_item_ref;
};
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.VariantDef.html
@@ -567,16 +646,13 @@ public:
static std::string variant_type_string (VariantType type);
VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
- HIR::Expr *discriminant);
+ tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant);
VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
- VariantType type, HIR::Expr *discriminant,
+ VariantType type,
+ tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant,
std::vector<StructFieldType *> fields);
- VariantDef (const VariantDef &other);
-
- VariantDef &operator= (const VariantDef &other);
-
static VariantDef &get_error_node ();
bool is_error () const;
@@ -597,7 +673,10 @@ public:
bool lookup_field (const std::string &lookup, StructFieldType **field_lookup,
size_t *index) const;
- HIR::Expr *get_discriminant () const;
+ bool has_discriminant () const;
+
+ HIR::Expr &get_discriminant ();
+ const HIR::Expr &get_discriminant () const;
std::string as_string () const;
@@ -615,8 +694,10 @@ private:
std::string identifier;
RustIdent ident;
VariantType type;
+
// can either be a structure or a discriminant value
- HIR::Expr *discriminant;
+ tl::optional<std::unique_ptr<HIR::Expr>> discriminant;
+
std::vector<StructFieldType *> fields;
};
@@ -633,59 +714,56 @@ public:
ENUM
};
+ enum ReprKind
+ {
+ RUST,
+ C,
+ INT,
+ ALIGN,
+ PACKED,
+ // TRANSPARENT,
+ // SIMD,
+ // ...
+ };
+
// Representation options, specified via attributes e.g. #[repr(packed)]
struct ReprOptions
{
- // bool is_c;
- // bool is_transparent;
- //...
+ ReprKind repr_kind = ReprKind::RUST;
// For align and pack: 0 = unspecified. Nonzero = byte alignment.
// It is an error for both to be nonzero, this should be caught when
// parsing the #[repr] attribute.
unsigned char align = 0;
unsigned char pack = 0;
+ BaseType *repr = nullptr;
};
- ADTType (HirId ref, std::string identifier, RustIdent ident, ADTKind adt_kind,
- std::vector<VariantDef *> variants,
+ ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
+ ADTKind adt_kind, std::vector<VariantDef *> variants,
std::vector<SubstitutionParamMapping> subst_refs,
SubstitutionArgumentMappings generic_arguments
= SubstitutionArgumentMappings::error (),
- RegionConstraints region_constraints = {},
- std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ref, TypeKind::ADT, ident, refs),
- SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
- region_constraints),
- identifier (identifier), variants (variants), adt_kind (adt_kind)
- {}
+ RegionConstraints region_constraints = RegionConstraints{},
+ std::set<HirId> refs = std::set<HirId> ());
- ADTType (HirId ref, HirId ty_ref, std::string identifier, RustIdent ident,
- ADTKind adt_kind, std::vector<VariantDef *> variants,
+ ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
+ RustIdent ident, ADTKind adt_kind,
+ std::vector<VariantDef *> variants,
std::vector<SubstitutionParamMapping> subst_refs,
SubstitutionArgumentMappings generic_arguments
= SubstitutionArgumentMappings::error (),
- RegionConstraints region_constraints = {},
- std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
- SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
- region_constraints),
- identifier (identifier), variants (variants), adt_kind (adt_kind)
- {}
+ RegionConstraints region_constraints = RegionConstraints{},
+ std::set<HirId> refs = std::set<HirId> ());
- ADTType (HirId ref, HirId ty_ref, std::string identifier, RustIdent ident,
- ADTKind adt_kind, std::vector<VariantDef *> variants,
+ ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
+ RustIdent ident, ADTKind adt_kind,
+ std::vector<VariantDef *> variants,
std::vector<SubstitutionParamMapping> subst_refs, ReprOptions repr,
SubstitutionArgumentMappings generic_arguments
= SubstitutionArgumentMappings::error (),
- RegionConstraints region_constraints = {},
- std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
- SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
- region_constraints),
- identifier (identifier), variants (variants), adt_kind (adt_kind),
- repr (repr)
- {}
+ RegionConstraints region_constraints = RegionConstraints{},
+ std::set<HirId> refs = std::set<HirId> ());
ADTKind get_adt_kind () const { return adt_kind; }
@@ -716,6 +794,8 @@ public:
return identifier + subst_as_string ();
}
+ DefId get_id () const;
+
BaseType *clone () const final override;
size_t number_of_variants () const { return variants.size (); }
@@ -761,12 +841,46 @@ public:
handle_substitions (SubstitutionArgumentMappings &mappings) override final;
private:
+ DefId id;
std::string identifier;
std::vector<VariantDef *> variants;
ADTType::ADTKind adt_kind;
ReprOptions repr;
};
+class FnParam
+{
+public:
+ FnParam (std::unique_ptr<HIR::Pattern> pattern, BaseType *type)
+ : pattern (std::move (pattern)), type (type)
+ {}
+
+ FnParam (const FnParam &) = delete;
+ FnParam (FnParam &&) = default;
+ FnParam &operator= (FnParam &&) = default;
+
+ HIR::Pattern &get_pattern () { return *pattern; }
+ const HIR::Pattern &get_pattern () const { return *pattern; }
+
+ bool has_pattern () { return pattern != nullptr; }
+ BaseType *get_type () const { return type; }
+ void set_type (BaseType *new_type) { type = new_type; }
+
+ FnParam clone () const
+ {
+ return FnParam (pattern->clone_pattern (), type->clone ());
+ }
+
+ FnParam monomorphized_clone () const
+ {
+ return FnParam (pattern->clone_pattern (), type->monomorphized_clone ());
+ }
+
+private:
+ std::unique_ptr<HIR::Pattern> pattern;
+ BaseType *type;
+};
+
class FnType : public CallableTypeInterface, public SubstitutionRef
{
public:
@@ -778,9 +892,8 @@ public:
static const uint8_t FNTYPE_IS_VARADIC_FLAG = 0X04;
FnType (HirId ref, DefId id, std::string identifier, RustIdent ident,
- uint8_t flags, ABI abi,
- std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
- BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
+ uint8_t flags, ABI abi, std::vector<FnParam> params, BaseType *type,
+ std::vector<SubstitutionParamMapping> subst_refs,
SubstitutionArgumentMappings substitution_argument_mappings,
RegionConstraints region_constraints,
std::set<HirId> refs = std::set<HirId> ())
@@ -795,8 +908,7 @@ public:
}
FnType (HirId ref, HirId ty_ref, DefId id, std::string identifier,
- RustIdent ident, uint8_t flags, ABI abi,
- std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
+ RustIdent ident, uint8_t flags, ABI abi, std::vector<FnParam> params,
BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
SubstitutionArgumentMappings substitution_argument_mappings,
RegionConstraints region_constraints,
@@ -804,13 +916,16 @@ public:
: CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
region_constraints),
- params (params), type (type), flags (flags), identifier (identifier),
- id (id), abi (abi)
+ params (std::move (params)), type (type), flags (flags),
+ identifier (identifier), id (id), abi (abi)
{
LocalDefId local_def_id = id.localDefId;
rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
}
+ FnType (const FnType &) = delete;
+ FnType (FnType &&) = default;
+
void accept_vis (TyVisitor &vis) override;
void accept_vis (TyConstVisitor &vis) const override;
@@ -844,28 +959,16 @@ public:
BaseType *get_self_type () const
{
rust_assert (is_method ());
- return param_at (0).second;
+ return param_at (0).get_type ();
}
- std::vector<std::pair<HIR::Pattern *, BaseType *>> &get_params ()
- {
- return params;
- }
+ std::vector<FnParam> &get_params () { return params; }
- const std::vector<std::pair<HIR::Pattern *, BaseType *>> &get_params () const
- {
- return params;
- }
+ const std::vector<FnParam> &get_params () const { return params; }
- std::pair<HIR::Pattern *, BaseType *> &param_at (size_t idx)
- {
- return params.at (idx);
- }
+ FnParam &param_at (size_t idx) { return params.at (idx); }
- const std::pair<HIR::Pattern *, BaseType *> &param_at (size_t idx) const
- {
- return params.at (idx);
- }
+ const FnParam &param_at (size_t idx) const { return params.at (idx); }
BaseType *clone () const final override;
@@ -882,7 +985,7 @@ public:
WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
{
- return param_at (index).second;
+ return param_at (index).get_type ();
}
WARN_UNUSED_RESULT BaseType *get_return_type () const override
@@ -891,7 +994,7 @@ public:
}
private:
- std::vector<std::pair<HIR::Pattern *, BaseType *>> params;
+ std::vector<FnParam> params;
BaseType *type;
uint8_t flags;
std::string identifier;
@@ -1505,9 +1608,9 @@ class PlaceholderType : public BaseType
public:
static constexpr auto KIND = TypeKind::PLACEHOLDER;
- PlaceholderType (std::string symbol, HirId ref,
+ PlaceholderType (std::string symbol, DefId id, HirId ref,
std::set<HirId> refs = std::set<HirId> ());
- PlaceholderType (std::string symbol, HirId ref, HirId ty_ref,
+ PlaceholderType (std::string symbol, DefId id, HirId ref, HirId ty_ref,
std::set<HirId> refs = std::set<HirId> ());
void accept_vis (TyVisitor &vis) override;
@@ -1533,8 +1636,11 @@ public:
bool is_equal (const BaseType &other) const override;
+ DefId get_def_id () const;
+
private:
std::string symbol;
+ DefId defId;
};
class ProjectionType : public BaseType, public SubstitutionRef
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index fa2308f..294b677 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -17,7 +17,6 @@
// <http://www.gnu.org/licenses/>.
#include "rust-unify.h"
-#include "rust-tyty.h"
namespace Rust {
namespace Resolver {
@@ -190,7 +189,7 @@ UnifyRules::go ()
== TyTy::InferType::GENERAL;
bool expected_is_concrete
= ltype->is_concrete () && !lhs_is_general_infer_var;
- bool rneeds_infer = expected_is_concrete && rgot_param;
+ bool rneeds_infer = expected_is_concrete && (rgot_param);
bool lgot_param = ltype->get_kind () == TyTy::TypeKind::PARAM;
bool rhs_is_infer_var = rtype->get_kind () == TyTy::TypeKind::INFER;
@@ -200,7 +199,7 @@ UnifyRules::go ()
== TyTy::InferType::GENERAL;
bool receiver_is_concrete
= rtype->is_concrete () && !rhs_is_general_infer_var;
- bool lneeds_infer = receiver_is_concrete && lgot_param;
+ bool lneeds_infer = receiver_is_concrete && (lgot_param);
if (rneeds_infer)
{
@@ -238,15 +237,6 @@ UnifyRules::go ()
}
}
- // The never type should always get coerced to the type it's being matched
- // against, so in that case, ltype. This avoids doing the same check in all
- // the `expect_*` functions.
- // However, this does not work if we have an annoying ltype - like INFER.
- // TODO: Is ltype == Infer the only special case here? What about projections?
- // references?
- if (rtype->get_kind () == TyTy::NEVER && ltype->get_kind () != TyTy::INFER)
- return ltype->clone ();
-
switch (ltype->get_kind ())
{
case TyTy::INFER:
@@ -322,6 +312,9 @@ UnifyRules::go ()
case TyTy::CLOSURE:
return expect_closure (static_cast<TyTy::ClosureType *> (ltype), rtype);
+ case TyTy::OPAQUE:
+ return expect_opaque (static_cast<TyTy::OpaqueType *> (ltype), rtype);
+
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -410,7 +403,8 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
case TyTy::PLACEHOLDER:
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
- case TyTy::CLOSURE: {
+ case TyTy::CLOSURE:
+ case TyTy::OPAQUE: {
bool is_valid = (ltype->get_infer_kind ()
== TyTy::InferType::InferTypeKind::GENERAL);
if (is_valid)
@@ -538,6 +532,7 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -582,6 +577,7 @@ UnifyRules::expect_str (TyTy::StrType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -652,6 +648,7 @@ UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -722,6 +719,7 @@ UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -783,6 +781,7 @@ UnifyRules::expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -842,6 +841,7 @@ UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -900,6 +900,7 @@ UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -929,8 +930,8 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
for (size_t i = 0; i < ltype->num_params (); i++)
{
- auto a = ltype->param_at (i).second;
- auto b = type.param_at (i).second;
+ auto a = ltype->param_at (i).get_type ();
+ auto b = type.param_at (i).get_type ();
auto unified_param
= UnifyRules::Resolve (TyTy::TyWithLocation (a),
@@ -990,6 +991,7 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1069,7 +1071,7 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
for (size_t i = 0; i < ltype->num_params (); i++)
{
auto this_param = ltype->get_param_type_at (i);
- auto other_param = type.param_at (i).second;
+ auto other_param = type.param_at (i).get_type ();
auto unified_param
= UnifyRules::Resolve (TyTy::TyWithLocation (this_param),
@@ -1106,6 +1108,7 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1176,6 +1179,7 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1223,6 +1227,7 @@ UnifyRules::expect_bool (TyTy::BoolType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1270,6 +1275,7 @@ UnifyRules::expect_char (TyTy::CharType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1324,6 +1330,7 @@ UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1378,6 +1385,7 @@ UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1432,6 +1440,7 @@ UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1479,6 +1488,7 @@ UnifyRules::expect_isize (TyTy::ISizeType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1526,6 +1536,7 @@ UnifyRules::expect_usize (TyTy::USizeType *ltype, TyTy::BaseType *rtype)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1591,6 +1602,7 @@ UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype,
case TyTy::USIZE:
case TyTy::ISIZE:
case TyTy::NEVER:
+ case TyTy::OPAQUE:
if (infer_flag)
return rtype->clone ();
gcc_fallthrough ();
@@ -1642,6 +1654,7 @@ UnifyRules::expect_projection (TyTy::ProjectionType *ltype,
case TyTy::ISIZE:
case TyTy::NEVER:
case TyTy::PLACEHOLDER:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1700,6 +1713,7 @@ UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype)
case TyTy::NEVER:
case TyTy::PLACEHOLDER:
case TyTy::PROJECTION:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
@@ -1770,6 +1784,65 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
case TyTy::PLACEHOLDER:
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
+ case TyTy::OPAQUE:
+ case TyTy::ERROR:
+ return new TyTy::ErrorType (0);
+ }
+ return new TyTy::ErrorType (0);
+}
+
+TyTy::BaseType *
+UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype)
+{
+ switch (rtype->get_kind ())
+ {
+ 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;
+
+ 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->bounds_compatible (type, locus, true))
+ {
+ 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);
}
diff --git a/gcc/rust/typecheck/rust-unify.h b/gcc/rust/typecheck/rust-unify.h
index 20f7b4e..5ff3b7c 100644
--- a/gcc/rust/typecheck/rust-unify.h
+++ b/gcc/rust/typecheck/rust-unify.h
@@ -82,6 +82,8 @@ protected:
TyTy::BaseType *rtype);
TyTy::BaseType *expect_closure (TyTy::ClosureType *ltype,
TyTy::BaseType *rtype);
+ TyTy::BaseType *expect_opaque (TyTy::OpaqueType *ltype,
+ TyTy::BaseType *rtype);
private:
UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
diff --git a/gcc/rust/util/expected.h b/gcc/rust/util/expected.h
index a9e3bc2..07ba877 100644
--- a/gcc/rust/util/expected.h
+++ b/gcc/rust/util/expected.h
@@ -212,10 +212,8 @@ template <typename E>
throw std::forward<E>(e);
#else
(void)e;
-#ifdef _MSC_VER
gcc_unreachable();
#endif
-#endif
}
#ifndef TL_TRAITS_MUTEX
@@ -2437,4 +2435,4 @@ void swap(expected<T, E> &lhs,
}
} // namespace tl
-#endif \ No newline at end of file
+#endif
diff --git a/gcc/rust/util/rust-attribute-values.h b/gcc/rust/util/rust-attribute-values.h
index ef01e67..47e6a17 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -29,6 +29,7 @@ public:
static constexpr auto &COLD = "cold";
static constexpr auto &CFG = "cfg";
static constexpr auto &CFG_ATTR = "cfg_attr";
+ static constexpr auto &DERIVE_ATTR = "derive";
static constexpr auto &DEPRECATED = "deprecated";
static constexpr auto &ALLOW = "allow";
static constexpr auto &ALLOW_INTERNAL_UNSTABLE = "allow_internal_unstable";
@@ -39,12 +40,14 @@ public:
static constexpr auto &NO_MANGLE = "no_mangle";
static constexpr auto &REPR = "repr";
static constexpr auto &RUSTC_BUILTIN_MACRO = "rustc_builtin_macro";
+ static constexpr auto &RUSTC_MACRO_TRANSPARENCY = "rustc_macro_transparency";
static constexpr auto &PATH = "path";
static constexpr auto &MACRO_USE = "macro_use";
static constexpr auto &MACRO_EXPORT = "macro_export";
static constexpr auto &PROC_MACRO = "proc_macro";
static constexpr auto &PROC_MACRO_DERIVE = "proc_macro_derive";
static constexpr auto &PROC_MACRO_ATTRIBUTE = "proc_macro_attribute";
+
static constexpr auto &TARGET_FEATURE = "target_feature";
// From now on, these are reserved by the compiler and gated through
// #![feature(rustc_attrs)]
@@ -53,10 +56,35 @@ public:
= "rustc_inherit_overflow_checks";
static constexpr auto &STABLE = "stable";
static constexpr auto &UNSTABLE = "unstable";
+
+ static constexpr auto &RUSTC_PROMOTABLE = "rustc_promotable";
static constexpr auto &RUSTC_CONST_STABLE = "rustc_const_stable";
static constexpr auto &RUSTC_CONST_UNSTABLE = "rustc_const_unstable";
+
+ static constexpr auto &RUSTC_SPECIALIZATION_TRAIT
+ = "rustc_specialization_trait";
+ static constexpr auto &RUSTC_UNSAFE_SPECIALIZATION_MARKER
+ = "rustc_unsafe_specialization_marker";
+ static constexpr auto &RUSTC_RESERVATION_IMPL = "rustc_reservation_impl";
+ static constexpr auto &RUSTC_PAREN_SUGAR = "rustc_paren_sugar";
+ static constexpr auto &RUSTC_NONNULL_OPTIMIZATION_GUARANTEED
+ = "rustc_nonnull_optimization_guaranteed";
+
+ static constexpr auto &RUSTC_LAYOUT_SCALAR_VALID_RANGE_START
+ = "rustc_layout_scalar_valid_range_start";
+
static constexpr auto &MAY_DANGLE = "may_dangle";
static constexpr auto &PRELUDE_IMPORT = "prelude_import";
+ static constexpr auto &TRACK_CALLER = "track_caller";
+
+ static constexpr auto &RUSTC_DIAGNOSTIC_ITEM = "rustc_diagnostic_item";
+ static constexpr auto &RUSTC_ON_UNIMPLEMENTED = "rustc_on_unimplemented";
+
+ static constexpr auto &FUNDAMENTAL = "fundamental";
+
+ static constexpr auto &NON_EXHAUSTIVE = "non_exhaustive";
+
+ static constexpr auto &RUSTFMT = "rustfmt";
};
} // namespace Values
} // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 958f7c3..c77e99c 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -29,6 +29,15 @@
namespace Rust {
namespace Analysis {
+bool
+Attributes::is_known (const std::string &attribute_path)
+{
+ const auto &lookup
+ = BuiltinAttributeMappings::get ()->lookup_builtin (attribute_path);
+
+ return !lookup.is_error ();
+}
+
using Attrs = Values::Attributes;
// https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
@@ -37,6 +46,7 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::COLD, CODE_GENERATION},
{Attrs::CFG, EXPANSION},
{Attrs::CFG_ATTR, EXPANSION},
+ {Attrs::DERIVE_ATTR, EXPANSION},
{Attrs::DEPRECATED, STATIC_ANALYSIS},
{Attrs::ALLOW, STATIC_ANALYSIS},
{Attrs::ALLOW_INTERNAL_UNSTABLE, STATIC_ANALYSIS},
@@ -47,6 +57,7 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::NO_MANGLE, CODE_GENERATION},
{Attrs::REPR, CODE_GENERATION},
{Attrs::RUSTC_BUILTIN_MACRO, EXPANSION},
+ {Attrs::RUSTC_MACRO_TRANSPARENCY, EXPANSION},
{Attrs::PATH, EXPANSION},
{Attrs::MACRO_USE, NAME_RESOLUTION},
{Attrs::MACRO_EXPORT, NAME_RESOLUTION},
@@ -62,10 +73,29 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION},
{Attrs::STABLE, STATIC_ANALYSIS},
{Attrs::UNSTABLE, STATIC_ANALYSIS},
+
// assuming we keep these for static analysis
+ {Attrs::RUSTC_PROMOTABLE, CODE_GENERATION},
{Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
{Attrs::RUSTC_CONST_UNSTABLE, STATIC_ANALYSIS},
- {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION}};
+ {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
+ {Attrs::TRACK_CALLER, CODE_GENERATION},
+ {Attrs::RUSTC_SPECIALIZATION_TRAIT, TYPE_CHECK},
+ {Attrs::RUSTC_UNSAFE_SPECIALIZATION_MARKER, TYPE_CHECK},
+ {Attrs::RUSTC_RESERVATION_IMPL, TYPE_CHECK},
+ {Attrs::RUSTC_PAREN_SUGAR, TYPE_CHECK},
+ {Attrs::RUSTC_NONNULL_OPTIMIZATION_GUARANTEED, TYPE_CHECK},
+
+ {Attrs::RUSTC_LAYOUT_SCALAR_VALID_RANGE_START, CODE_GENERATION},
+
+ {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
+
+ {Attrs::RUSTC_DIAGNOSTIC_ITEM, STATIC_ANALYSIS},
+ {Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS},
+
+ {Attrs::FUNDAMENTAL, TYPE_CHECK},
+ {Attrs::NON_EXHAUSTIVE, TYPE_CHECK},
+ {Attrs::RUSTFMT, EXTERNAL}};
BuiltinAttributeMappings *
BuiltinAttributeMappings::get ()
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index 1345168..7c7a1fc 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -25,6 +25,12 @@
namespace Rust {
namespace Analysis {
+class Attributes
+{
+public:
+ static bool is_known (const std::string &attribute_path);
+};
+
enum CompilerPass
{
UNKNOWN,
@@ -34,7 +40,12 @@ enum CompilerPass
HIR_LOWERING,
TYPE_CHECK,
STATIC_ANALYSIS,
- CODE_GENERATION
+ CODE_GENERATION,
+
+ // External Rust tooling attributes, like #[rustfmt::skip]
+ EXTERNAL,
+
+ // Do we need to add something here for const fns?
};
struct BuiltinAttrDefinition
diff --git a/gcc/rust/util/rust-common.h b/gcc/rust/util/rust-common.h
index 2033694..71637ce 100644
--- a/gcc/rust/util/rust-common.h
+++ b/gcc/rust/util/rust-common.h
@@ -21,7 +21,6 @@
#ifndef RUST_COMMON
#define RUST_COMMON
#include "rust-system.h"
-#include <string>
namespace Rust {
diff --git a/gcc/rust/util/rust-edition.cc b/gcc/rust/util/rust-edition.cc
new file mode 100644
index 0000000..4e44a91
--- /dev/null
+++ b/gcc/rust/util/rust-edition.cc
@@ -0,0 +1,40 @@
+// 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-edition.h"
+#include "rust-session-manager.h"
+
+namespace Rust {
+
+Edition
+get_rust_edition ()
+{
+ switch (Session::get_instance ().options.get_edition ())
+ {
+ case CompileOptions::Edition::E2015:
+ return Edition::E2015;
+ case CompileOptions::Edition::E2018:
+ return Edition::E2018;
+ case CompileOptions::Edition::E2021:
+ return Edition::E2021;
+ default:
+ rust_unreachable ();
+ }
+}
+
+} // namespace Rust
diff --git a/gcc/rust/util/rust-edition.h b/gcc/rust/util/rust-edition.h
new file mode 100644
index 0000000..d034ea0
--- /dev/null
+++ b/gcc/rust/util/rust-edition.h
@@ -0,0 +1,41 @@
+// 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_EDITION_H
+#define RUST_EDITION_H
+
+/*
+ * This header exists to avoid including rust-session-manager.h
+ * when we only need information on the selected rust edition
+ */
+
+namespace Rust {
+
+enum class Edition
+{
+ E2015,
+ E2018,
+ E2021
+};
+
+Edition
+get_rust_edition ();
+
+} // namespace Rust
+
+#endif // !RUST_EDITION_H
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 03b3343..eaa640c 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -148,6 +148,16 @@ Mappings::get_crate_name (CrateNum crate_num) const
return it->second;
}
+tl::optional<CrateNum>
+Mappings::lookup_crate_num (NodeId node_id) const
+{
+ auto it = crate_node_to_crate_num.find (node_id);
+ if (it == crate_node_to_crate_num.end ())
+ return tl::nullopt;
+
+ return it->second;
+}
+
void
Mappings::set_crate_name (CrateNum crate_num, const std::string &name)
{
@@ -184,13 +194,7 @@ Mappings::crate_num_to_nodeid (const CrateNum &crate_num) const
bool
Mappings::node_is_crate (NodeId node_id) const
{
- for (const auto &it : ast_crate_mappings)
- {
- NodeId crate_node_id = it.second->get_node_id ();
- if (crate_node_id == node_id)
- return true;
- }
- return false;
+ return lookup_crate_num (node_id).has_value ();
}
NodeId
@@ -262,6 +266,7 @@ Mappings::insert_ast_crate (std::unique_ptr<AST::Crate> &&crate,
rust_assert (it == ast_crate_mappings.end ());
// store it
+ crate_node_to_crate_num.insert ({crate->get_node_id (), crate_num});
ast_crate_mappings.insert ({crate_num, crate.release ()});
// return the reference to it
@@ -459,7 +464,7 @@ Mappings::insert_hir_impl_block (HIR::ImplBlock *item)
auto id = item->get_mappings ().get_hirid ();
rust_assert (!lookup_hir_impl_block (id));
- HirId impl_type_id = item->get_type ()->get_mappings ().get_hirid ();
+ HirId impl_type_id = item->get_type ().get_mappings ().get_hirid ();
hirImplBlockMappings[id] = item;
hirImplBlockTypeMappings[impl_type_id] = item;
insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
@@ -874,7 +879,7 @@ Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
auto it = macroMappings.find (macro->get_node_id ());
rust_assert (it == macroMappings.end ());
- macroMappings[macro->get_node_id ()] = macro;
+ macroMappings[macro->get_node_id ()] = {macro, currentCrateNum};
}
tl::optional<AST::MacroRulesDefinition *>
@@ -884,7 +889,17 @@ Mappings::lookup_macro_def (NodeId id)
if (it == macroMappings.end ())
return tl::nullopt;
- return it->second;
+ return it->second.first;
+}
+
+tl::optional<CrateNum>
+Mappings::lookup_macro_def_crate (NodeId id)
+{
+ auto it = macroMappings.find (id);
+ if (it == macroMappings.end ())
+ return tl::nullopt;
+
+ return it->second.second;
}
void
@@ -1241,6 +1256,9 @@ Mappings::lookup_builtin_marker ()
return builtinMarker;
}
+// FIXME: Before merging: Should we remove the `locus` parameter here? since
+// lang items are looked up mostly for code generation, it doesn't make sense to
+// error out on the locus of the node trying to access an inexistant lang item
DefId
Mappings::get_lang_item (LangItem::Kind item_type, location_t locus)
{
@@ -1258,5 +1276,85 @@ Mappings::lookup_trait_item_lang_item (LangItem::Kind item, location_t locus)
return lookup_trait_item_defid (trait_item_id);
}
+void
+Mappings::insert_lang_item (LangItem::Kind item_type, DefId id)
+{
+ auto it = lang_item_mappings.find (item_type);
+ rust_assert (it == lang_item_mappings.end ());
+
+ lang_item_mappings[item_type] = id;
+}
+
+tl::optional<DefId &>
+Mappings::lookup_lang_item (LangItem::Kind item_type)
+{
+ auto it = lang_item_mappings.find (item_type);
+ if (it == lang_item_mappings.end ())
+ return tl::nullopt;
+
+ return it->second;
+}
+
+void
+Mappings::insert_lang_item_node (LangItem::Kind item_type, NodeId node_id)
+{
+ auto it = lang_item_nodes.find (item_type);
+ rust_assert (it == lang_item_nodes.end ());
+
+ lang_item_nodes.insert ({item_type, node_id});
+}
+
+tl::optional<NodeId &>
+Mappings::lookup_lang_item_node (LangItem::Kind item_type)
+{
+ auto it = lang_item_nodes.find (item_type);
+ if (it == lang_item_nodes.end ())
+ return tl::nullopt;
+
+ return it->second;
+}
+
+NodeId
+Mappings::get_lang_item_node (LangItem::Kind item_type)
+{
+ if (auto lookup = lookup_lang_item_node (item_type))
+ return *lookup;
+
+ rust_fatal_error (UNKNOWN_LOCATION, "undeclared lang item: %qs",
+ LangItem::PrettyString (item_type).c_str ());
+}
+
+void
+Mappings::insert_auto_trait (HIR::Trait *trait)
+{
+ auto_traits.emplace_back (trait);
+}
+
+std::vector<HIR::Trait *> &
+Mappings::get_auto_traits ()
+{
+ return auto_traits;
+}
+
+void
+Mappings::add_capture (NodeId closure, NodeId definition)
+{
+ auto cap = captures.find (closure);
+ if (cap == captures.end ())
+ captures[closure] = {definition};
+ else
+ cap->second.push_back (definition);
+}
+
+tl::optional<std::vector<NodeId>>
+Mappings::lookup_captures (NodeId closure)
+{
+ auto cap = captures.find (closure);
+ if (cap == captures.end ())
+ return tl::nullopt;
+ else
+ return cap->second;
+}
+
} // namespace Analysis
} // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index bb7318e..b523a36 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -81,6 +81,8 @@ public:
void set_current_crate (CrateNum crateNum);
CrateNum get_current_crate () const;
tl::optional<const std::string &> get_crate_name (CrateNum crate_num) const;
+
+ tl::optional<CrateNum> lookup_crate_num (NodeId node_id) const;
void set_crate_name (CrateNum crate_num, const std::string &name);
const std::string &get_current_crate_name () const;
tl::optional<CrateNum>
@@ -256,22 +258,12 @@ public:
return it->second;
}
- void insert_lang_item (LangItem::Kind item_type, DefId id)
- {
- auto it = lang_item_mappings.find (item_type);
- rust_assert (it == lang_item_mappings.end ());
-
- lang_item_mappings[item_type] = id;
- }
-
- tl::optional<DefId &> lookup_lang_item (LangItem::Kind item_type)
- {
- auto it = lang_item_mappings.find (item_type);
- if (it == lang_item_mappings.end ())
- return tl::nullopt;
+ void insert_lang_item (LangItem::Kind item_type, DefId id);
+ tl::optional<DefId &> lookup_lang_item (LangItem::Kind item_type);
- return it->second;
- }
+ void insert_lang_item_node (LangItem::Kind item_type, NodeId node_id);
+ tl::optional<NodeId &> lookup_lang_item_node (LangItem::Kind item_type);
+ NodeId get_lang_item_node (LangItem::Kind item_type);
// This will fatal_error when this lang item does not exist
DefId get_lang_item (LangItem::Kind item_type, location_t locus);
@@ -279,6 +271,7 @@ public:
void insert_macro_def (AST::MacroRulesDefinition *macro);
tl::optional<AST::MacroRulesDefinition *> lookup_macro_def (NodeId id);
+ tl::optional<CrateNum> lookup_macro_def_crate (NodeId id);
void insert_macro_invocation (AST::MacroInvocation &invoc,
AST::MacroRulesDefinition *def);
@@ -352,6 +345,11 @@ public:
tl::optional<HIR::TraitItem *>
lookup_trait_item_lang_item (LangItem::Kind item, location_t locus);
+ void insert_auto_trait (HIR::Trait *trait);
+ std::vector<HIR::Trait *> &get_auto_traits ();
+ void add_capture (NodeId closure, NodeId definition);
+ tl::optional<std::vector<NodeId>> lookup_captures (NodeId closure);
+
private:
Mappings ();
@@ -389,7 +387,15 @@ private:
std::map<HirId, HIR::GenericParam *> hirGenericParamMappings;
std::map<HirId, HIR::Trait *> hirTraitItemsToTraitMappings;
std::map<HirId, HIR::Pattern *> hirPatternMappings;
+
+ // FIXME: Add documentation
+ std::vector<HIR::Trait *> auto_traits;
+
+ // We need to have two maps here, as lang-items need to be used for both AST
+ // passes and HIR passes. Thus those two maps are created at different times.
std::map<LangItem::Kind, DefId> lang_item_mappings;
+ std::map<LangItem::Kind, NodeId> lang_item_nodes;
+
std::map<NodeId, Resolver::CanonicalPath> paths;
std::map<NodeId, location_t> locations;
std::map<NodeId, HirId> nodeIdToHirMappings;
@@ -399,7 +405,8 @@ private:
std::map<CrateNum, std::set<HirId>> hirNodesWithinCrate;
// MBE macros
- std::map<NodeId, AST::MacroRulesDefinition *> macroMappings;
+ std::map<NodeId, std::pair<AST::MacroRulesDefinition *, CrateNum>>
+ macroMappings;
std::map<NodeId, AST::MacroRulesDefinition *> macroInvocations;
std::vector<NodeId> exportedMacros;
@@ -433,6 +440,9 @@ private:
// AST mappings
std::map<NodeId, AST::Item *> ast_item_mappings;
+
+ // Closure AST NodeId -> vector of Definition node ids
+ std::unordered_map<NodeId, std::vector<NodeId>> captures;
};
} // namespace Analysis
diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index 5ddffaa..9aff31b 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -46,6 +46,7 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{
{"shr_assign", Kind::SHR_ASSIGN},
{"deref", Kind::DEREF},
{"deref_mut", Kind::DEREF_MUT},
+ {"receiver", Kind::RECEIVER},
{"index", Kind::INDEX},
{"index_mut", Kind::INDEX_MUT},
{"RangeFull", Kind::RANGE_FULL},
@@ -62,6 +63,7 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{
{"copy", Kind::COPY},
{"clone", Kind::CLONE},
{"sized", Kind::SIZED},
+ {"sync", Kind::SYNC},
{"slice_alloc", Kind::SLICE_ALLOC},
{"slice_u8_alloc", Kind::SLICE_U8_ALLOC},
{"str_alloc", Kind::STR_ALLOC},
@@ -91,6 +93,32 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{
{"str", Kind::STR},
{"f32_runtime", Kind::F32_RUNTIME},
{"f64_runtime", Kind::F64_RUNTIME},
+
+ {"Some", Kind::OPTION_SOME},
+ {"None", Kind::OPTION_NONE},
+
+ {"Ok", Kind::RESULT_OK},
+ {"Err", Kind::RESULT_ERR},
+
+ {"into_iter", Kind::INTOITER_INTOITER},
+ {"next", Kind::ITERATOR_NEXT},
+
+ {"eq", Kind::EQ},
+ {"partial_ord", Kind::PARTIAL_ORD},
+
+ {"try", Kind::TRY},
+ {"into_result", Kind::TRY_INTO_RESULT},
+ {"from_error", Kind::TRY_FROM_ERROR},
+ {"from_ok", Kind::TRY_FROM_OK},
+
+ {"from", Kind::FROM_FROM},
+
+ {"structural_peq", Kind::STRUCTURAL_PEQ},
+ {"structural_teq", Kind::STRUCTURAL_TEQ},
+
+ {"discriminant_kind", Kind::DISCRIMINANT_KIND},
+ {"discriminant_type", Kind::DISCRIMINANT_TYPE},
+ {"manually_drop", Kind::MANUALLY_DROP},
}};
tl::optional<LangItem::Kind>
@@ -108,6 +136,12 @@ LangItem::ToString (LangItem::Kind type)
return str.value ();
}
+std::string
+LangItem::PrettyString (LangItem::Kind type)
+{
+ return "#[lang = \"" + LangItem::ToString (type) + "\"]";
+}
+
LangItem::Kind
LangItem::OperatorToLangItem (ArithmeticOrLogicalOperator op)
{
@@ -139,6 +173,47 @@ LangItem::OperatorToLangItem (ArithmeticOrLogicalOperator op)
}
LangItem::Kind
+LangItem::ComparisonToLangItem (ComparisonOperator op)
+{
+ switch (op)
+ {
+ case ComparisonOperator::NOT_EQUAL:
+ case ComparisonOperator::EQUAL:
+ return LangItem::Kind::EQ;
+
+ case ComparisonOperator::GREATER_THAN:
+ case ComparisonOperator::LESS_THAN:
+ case ComparisonOperator::GREATER_OR_EQUAL:
+ case ComparisonOperator::LESS_OR_EQUAL:
+ return LangItem::Kind::PARTIAL_ORD;
+ }
+
+ rust_unreachable ();
+}
+
+std::string
+LangItem::ComparisonToSegment (ComparisonOperator op)
+{
+ switch (op)
+ {
+ case ComparisonOperator::NOT_EQUAL:
+ return "ne";
+ case ComparisonOperator::EQUAL:
+ return "eq";
+ case ComparisonOperator::GREATER_THAN:
+ return "gt";
+ case ComparisonOperator::LESS_THAN:
+ return "lt";
+ case ComparisonOperator::GREATER_OR_EQUAL:
+ return "ge";
+ case ComparisonOperator::LESS_OR_EQUAL:
+ return "le";
+ }
+
+ rust_unreachable ();
+}
+
+LangItem::Kind
LangItem::CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op)
{
switch (op)
@@ -182,4 +257,13 @@ LangItem::NegationOperatorToLangItem (NegationOperator op)
rust_unreachable ();
}
+bool
+LangItem::IsEnumVariant (LangItem::Kind type)
+{
+ const static std::set<LangItem::Kind> enum_variants
+ = {Kind::OPTION_NONE, Kind::OPTION_SOME, Kind::RESULT_OK, Kind::RESULT_ERR};
+
+ return enum_variants.find (type) != enum_variants.end ();
+}
+
} // namespace Rust
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 951e4a3..67a5d9c 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -23,12 +23,15 @@
namespace Rust {
-// https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs
class LangItem
{
public:
+ // FIXME: We should clean up that enum to make it more inline with the list of
+ // lang-items in Rust 1.49
+ // https://github.com/rust-lang/rust/blob/1.49.0/compiler/rustc_hir/src/lang_items.rs
enum class Kind
{
+ // https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs
ADD,
SUBTRACT,
MULTIPLY,
@@ -42,6 +45,8 @@ public:
NEGATION,
NOT,
+ EQ,
+ PARTIAL_ORD,
ADD_ASSIGN,
SUB_ASSIGN,
@@ -56,6 +61,7 @@ public:
DEREF,
DEREF_MUT,
+ RECEIVER,
// https://github.com/rust-lang/rust/blob/master/library/core/src/ops/index.rs
INDEX,
@@ -82,6 +88,7 @@ public:
COPY,
CLONE,
SIZED,
+ SYNC,
// https://github.com/Rust-GCC/gccrs/issues/1896
// https://github.com/rust-lang/rust/commit/afbecc0f68c4dcfc4878ba5bcb1ac942544a1bdc
@@ -116,16 +123,52 @@ public:
STR,
F32_RUNTIME,
F64_RUNTIME,
+
+ OPTION_SOME,
+ OPTION_NONE,
+
+ RESULT_OK,
+ RESULT_ERR,
+
+ INTOITER_INTOITER,
+ ITERATOR_NEXT,
+
+ // NOTE: These lang items are *not* necessarily present in later versions of
+ // Rust (I am unsure at which point they have been removed as the `Try`
+ // trait is unstable). They will need to be changed when updating the
+ // targeted Rust version of gccrs
+ TRY,
+ TRY_INTO_RESULT,
+ TRY_FROM_ERROR,
+ TRY_FROM_OK,
+
+ // NOTE: This is not a lang item in later versions of Rust
+ FROM_FROM,
+
+ STRUCTURAL_PEQ,
+ STRUCTURAL_TEQ,
+
+ DISCRIMINANT_TYPE,
+ DISCRIMINANT_KIND,
+
+ MANUALLY_DROP,
};
static const BiMap<std::string, Kind> lang_items;
static tl::optional<Kind> Parse (const std::string &item);
+
static std::string ToString (Kind type);
+ static std::string PrettyString (Kind type);
+
static Kind OperatorToLangItem (ArithmeticOrLogicalOperator op);
static Kind
CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op);
static Kind NegationOperatorToLangItem (NegationOperator op);
+ static Kind ComparisonToLangItem (ComparisonOperator op);
+ static std::string ComparisonToSegment (ComparisonOperator op);
+
+ static bool IsEnumVariant (Kind type);
};
} // namespace Rust
diff --git a/gcc/rust/util/rust-operators.h b/gcc/rust/util/rust-operators.h
index 608e771..02b1820 100644
--- a/gcc/rust/util/rust-operators.h
+++ b/gcc/rust/util/rust-operators.h
@@ -43,10 +43,10 @@ enum class ComparisonOperator
{
EQUAL, // std::cmp::PartialEq::eq
NOT_EQUAL, // std::cmp::PartialEq::ne
- GREATER_THAN, // std::cmp::PartialEq::gt
- LESS_THAN, // std::cmp::PartialEq::lt
- GREATER_OR_EQUAL, // std::cmp::PartialEq::ge
- LESS_OR_EQUAL // std::cmp::PartialEq::le
+ GREATER_THAN, // std::cmp::PartialOrd::gt
+ LESS_THAN, // std::cmp::PartialOrd::lt
+ GREATER_OR_EQUAL, // std::cmp::PartialOrd::ge
+ LESS_OR_EQUAL // std::cmp::PartialOrd::le
};
enum class LazyBooleanOperator
diff --git a/gcc/rust/util/rust-stacked-contexts.h b/gcc/rust/util/rust-stacked-contexts.h
index 39a0c08..b263d75 100644
--- a/gcc/rust/util/rust-stacked-contexts.h
+++ b/gcc/rust/util/rust-stacked-contexts.h
@@ -71,6 +71,20 @@ public:
return last;
}
+ const T &peek () const
+ {
+ rust_assert (!stack.empty ());
+
+ return stack.back ();
+ }
+
+ T &peek ()
+ {
+ rust_assert (!stack.empty ());
+
+ return stack.back ();
+ }
+
/**
* Are we currently inside of a special context?
*/
diff --git a/gcc/rust/util/rust-token-converter.cc b/gcc/rust/util/rust-token-converter.cc
index 220e891..fc34adb 100644
--- a/gcc/rust/util/rust-token-converter.cc
+++ b/gcc/rust/util/rust-token-converter.cc
@@ -18,8 +18,7 @@
#include "rust-token-converter.h"
#include "bi-map.h"
#include "line-map.h"
-
-#include <string>
+#include "rust-system.h"
namespace Rust {
diff --git a/gcc/rust/util/rust-token-converter.h b/gcc/rust/util/rust-token-converter.h
index 0498041..5405d6e 100644
--- a/gcc/rust/util/rust-token-converter.h
+++ b/gcc/rust/util/rust-token-converter.h
@@ -17,7 +17,7 @@
#ifndef RUST_TOKEN_CONVERTER_H
#define RUST_TOKEN_CONVERTER_H
-#include <vector>
+#include "rust-system.h"
#include "rust-token.h"
#include "libproc_macro_internal/proc_macro.h"
diff --git a/gcc/rust/util/rust-unwrap-segment.cc b/gcc/rust/util/rust-unwrap-segment.cc
new file mode 100644
index 0000000..083a0e5
--- /dev/null
+++ b/gcc/rust/util/rust-unwrap-segment.cc
@@ -0,0 +1,61 @@
+// 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 "ast/rust-path.h"
+
+namespace Rust {
+
+NodeId
+unwrap_segment_node_id (const AST::TypePathSegment &seg)
+{
+ return seg.get_node_id ();
+}
+
+NodeId
+unwrap_segment_node_id (const AST::SimplePathSegment &seg)
+{
+ return seg.get_node_id ();
+}
+
+NodeId
+unwrap_segment_node_id (const AST::PathExprSegment &seg)
+{
+ return seg.get_node_id ();
+}
+
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::TypePathSegment &seg)
+{
+ if (seg.is_lang_item ())
+ return seg.get_lang_item ();
+ return tl::nullopt;
+}
+
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::SimplePathSegment &seg)
+{
+ return tl::nullopt;
+}
+
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::PathExprSegment &seg)
+{
+ return tl::nullopt;
+}
+
+} // namespace Rust
diff --git a/gcc/rust/util/rust-unwrap-segment.h b/gcc/rust/util/rust-unwrap-segment.h
new file mode 100644
index 0000000..bebdc3a
--- /dev/null
+++ b/gcc/rust/util/rust-unwrap-segment.h
@@ -0,0 +1,121 @@
+// 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 <ast/rust-ast-full-decls.h>
+
+namespace Rust {
+
+/*
+ * Used to convert different path segment object references
+ * into SimplePathSegment/PathIdentSegment references
+ *
+ * unwrap_type_segment:
+ * expands to a call to unwrap_type_segment_inner::unwrap,
+ * used for type inference
+ */
+#define unwrap_type_segment(x) \
+ (unwrap_type_segment_inner<typename std::remove_const< \
+ typename std::remove_reference<decltype (x)>::type>::type>::unwrap (x))
+
+template <class T> class unwrap_type_segment_inner;
+
+/* base case */
+template <> class unwrap_type_segment_inner<AST::SimplePathSegment>
+{
+public:
+ /* The return type of unwrap */
+ using ret = AST::SimplePathSegment;
+
+ /* non-const qualified unwrap */
+ static AST::SimplePathSegment &unwrap (AST::SimplePathSegment &x)
+ {
+ return x;
+ }
+
+ /* const qualified unwrap */
+ static const AST::SimplePathSegment &unwrap (const AST::SimplePathSegment &x)
+ {
+ return x;
+ }
+};
+
+/* case which dereferences unique_ptr */
+template <class T> class unwrap_type_segment_inner<std::unique_ptr<T>>
+{
+public:
+ using ret = typename unwrap_type_segment_inner<T>::ret;
+
+ static ret &unwrap (std::unique_ptr<T> &x)
+ {
+ return unwrap_type_segment (*x);
+ }
+ static const ret &unwrap (const std::unique_ptr<T> &x)
+ {
+ return unwrap_type_segment (*x);
+ }
+};
+
+/* case which handles objects with a get_ident_segment member function */
+template <class T> class unwrap_type_segment_inner
+{
+public:
+ using ret = AST::PathIdentSegment;
+
+ static ret &unwrap (T &x) { return x.get_ident_segment (); }
+ static const ret &unwrap (const T &x) { return x.get_ident_segment (); }
+};
+
+/*
+ * 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::SimplePathSegment &seg);
+
+NodeId
+unwrap_segment_node_id (const AST::PathExprSegment &seg);
+
+template <class T>
+NodeId
+unwrap_segment_node_id (const std::unique_ptr<T> &ptr)
+{
+ return unwrap_segment_node_id (*ptr);
+}
+
+/**
+ * Used to check if a path segment is associated with a lang item
+ */
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::TypePathSegment &seg);
+
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::SimplePathSegment &seg);
+
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::PathExprSegment &seg);
+
+template <class T>
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const std::unique_ptr<T> &ptr)
+{
+ return unwrap_segment_get_lang_item (*ptr);
+}
+
+} // namespace Rust