aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/ChangeLog1445
-rw-r--r--gcc/rust/Make-lang.in19
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc56
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc244
-rw-r--r--gcc/rust/ast/rust-ast-collector.h9
-rw-r--r--gcc/rust/ast/rust-ast-formatting.h3
-rw-r--r--gcc/rust/ast/rust-ast-fragment.cc42
-rw-r--r--gcc/rust/ast/rust-ast-fragment.h6
-rw-r--r--gcc/rust/ast/rust-ast-full-decls.h9
-rw-r--r--gcc/rust/ast/rust-ast-pointer-visitor.cc1475
-rw-r--r--gcc/rust/ast/rust-ast-pointer-visitor.h234
-rw-r--r--gcc/rust/ast/rust-ast-visitor.cc18
-rw-r--r--gcc/rust/ast/rust-ast-visitor.h18
-rw-r--r--gcc/rust/ast/rust-ast.cc136
-rw-r--r--gcc/rust/ast/rust-ast.h120
-rw-r--r--gcc/rust/ast/rust-builtin-ast-nodes.h8
-rw-r--r--gcc/rust/ast/rust-collect-lang-items.cc14
-rw-r--r--gcc/rust/ast/rust-cond-compilation.h32
-rw-r--r--gcc/rust/ast/rust-desugar-apit.cc26
-rw-r--r--gcc/rust/ast/rust-desugar-for-loops.cc2
-rw-r--r--gcc/rust/ast/rust-desugar-question-mark.cc4
-rw-r--r--gcc/rust/ast/rust-expr.h257
-rw-r--r--gcc/rust/ast/rust-expression-yeast.cc47
-rw-r--r--gcc/rust/ast/rust-expression-yeast.h15
-rw-r--r--gcc/rust/ast/rust-fmt.cc38
-rw-r--r--gcc/rust/ast/rust-fmt.h228
-rw-r--r--gcc/rust/ast/rust-item.h145
-rw-r--r--gcc/rust/ast/rust-path.cc11
-rw-r--r--gcc/rust/ast/rust-path.h17
-rw-r--r--gcc/rust/ast/rust-pattern.cc20
-rw-r--r--gcc/rust/ast/rust-pattern.h229
-rw-r--r--gcc/rust/ast/rust-stmt.h6
-rw-r--r--gcc/rust/ast/rust-type.h32
-rw-r--r--gcc/rust/backend/rust-compile-base.cc24
-rw-r--r--gcc/rust/backend/rust-compile-base.h2
-rw-r--r--gcc/rust/backend/rust-compile-context.h24
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc73
-rw-r--r--gcc/rust/backend/rust-compile-extern.h46
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc510
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc7
-rw-r--r--gcc/rust/backend/rust-compile-type.cc98
-rw-r--r--gcc/rust/backend/rust-compile-type.h5
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h70
-rw-r--r--gcc/rust/backend/rust-compile.cc14
-rw-r--r--gcc/rust/backend/rust-constexpr.cc698
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h65
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc47
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h16
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-function-collector.h10
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature-gate.cc (renamed from gcc/rust/checks/errors/rust-feature-gate.cc)0
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature-gate.h (renamed from gcc/rust/checks/errors/rust-feature-gate.h)0
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature.cc (renamed from gcc/rust/checks/errors/rust-feature.cc)0
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature.h (renamed from gcc/rust/checks/errors/rust-feature.h)0
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-check.cc9
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc56
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-reporter.h7
-rw-r--r--gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc29
-rw-r--r--gcc/rust/checks/errors/privacy/rust-visibility-resolver.h6
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.cc16
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.h10
-rw-r--r--gcc/rust/checks/errors/rust-hir-pattern-analysis.cc86
-rw-r--r--gcc/rust/checks/errors/rust-hir-pattern-analysis.h14
-rw-r--r--gcc/rust/checks/errors/rust-readonly-check.cc340
-rw-r--r--gcc/rust/checks/errors/rust-readonly-check.h59
-rw-r--r--gcc/rust/checks/errors/rust-readonly-check2.cc253
-rw-r--r--gcc/rust/checks/errors/rust-readonly-check2.h67
-rw-r--r--gcc/rust/checks/errors/rust-unsafe-checker.cc16
-rw-r--r--gcc/rust/checks/errors/rust-unsafe-checker.h10
-rw-r--r--gcc/rust/checks/lints/rust-lint-marklive-base.h3
-rw-r--r--gcc/rust/expand/rust-cfg-strip.cc53
-rw-r--r--gcc/rust/expand/rust-cfg-strip.h23
-rw-r--r--gcc/rust/expand/rust-derive-clone.cc9
-rw-r--r--gcc/rust/expand/rust-derive-cmp-common.cc8
-rw-r--r--gcc/rust/expand/rust-derive-eq.cc6
-rw-r--r--gcc/rust/expand/rust-derive-hash.cc2
-rw-r--r--gcc/rust/expand/rust-derive-ord.cc2
-rw-r--r--gcc/rust/expand/rust-derive-partial-eq.cc10
-rw-r--r--gcc/rust/expand/rust-derive.h11
-rw-r--r--gcc/rust/expand/rust-expand-visitor.cc184
-rw-r--r--gcc/rust/expand/rust-expand-visitor.h67
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.cc30
-rw-r--r--gcc/rust/expand/rust-macro-builtins-format-args.cc78
-rw-r--r--gcc/rust/expand/rust-macro-builtins-helpers.h1
-rw-r--r--gcc/rust/expand/rust-macro-builtins-offset-of.cc2
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc1
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc49
-rw-r--r--gcc/rust/expand/rust-macro-expand.h2
-rw-r--r--gcc/rust/expand/rust-macro-substitute-ctx.cc19
-rw-r--r--gcc/rust/expand/rust-macro-substitute-ctx.h6
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc119
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.h19
-rw-r--r--gcc/rust/hir/rust-ast-lower-enumitem.h9
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.cc88
-rw-r--r--gcc/rust/hir/rust-ast-lower-extern.h5
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.cc20
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.cc175
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.cc102
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc52
-rw-r--r--gcc/rust/hir/rust-hir-dump.cc43
-rw-r--r--gcc/rust/hir/rust-hir-dump.h12
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-decls.h10
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-pattern.h324
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.cc27
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h41
-rw-r--r--gcc/rust/hir/tree/rust-hir.cc104
-rw-r--r--gcc/rust/lex/rust-lex.cc9
-rw-r--r--gcc/rust/lex/rust-token.cc23
-rw-r--r--gcc/rust/lex/rust-token.h72
-rw-r--r--gcc/rust/metadata/rust-export-metadata.cc4
-rw-r--r--gcc/rust/parse/rust-parse-impl.h274
-rw-r--r--gcc/rust/parse/rust-parse.h13
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.cc691
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h238
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.cc816
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h105
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h260
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc1247
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h161
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.cc558
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.h52
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc419
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.h146
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.cc81
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h408
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-struct-expr-field.cc61
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h54
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h500
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc785
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h280
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc114
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc47
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.h1
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.cc589
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.h196
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx21
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc120
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.h3
-rw-r--r--gcc/rust/resolve/rust-resolve-builtins.cc125
-rw-r--r--gcc/rust/resolve/rust-resolve-builtins.h37
-rw-r--r--gcc/rust/rust-gcc.cc2
-rw-r--r--gcc/rust/rust-lang.cc2
-rw-r--r--gcc/rust/rust-session-manager.cc73
-rw-r--r--gcc/rust/typecheck/rust-autoderef.cc6
-rw-r--r--gcc/rust/typecheck/rust-casts.cc6
-rw-r--r--gcc/rust/typecheck/rust-coercion.cc136
-rw-r--r--gcc/rust/typecheck/rust-coercion.h12
-rw-r--r--gcc/rust/typecheck/rust-hir-dot-operator.cc44
-rw-r--r--gcc/rust/typecheck/rust-hir-dot-operator.h16
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.cc27
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc28
-rw-r--r--gcc/rust/typecheck/rust-hir-type-bounds.h6
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc142
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc97
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.cc20
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.cc8
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc13
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.cc327
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-struct.cc11
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc66
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc6
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.cc30
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h22
-rw-r--r--gcc/rust/typecheck/rust-type-util.cc32
-rw-r--r--gcc/rust/typecheck/rust-type-util.h7
-rw-r--r--gcc/rust/typecheck/rust-typecheck-context.cc4
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc74
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.cc6
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h9
-rw-r--r--gcc/rust/typecheck/rust-tyty-cmp.h1645
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.cc138
-rw-r--r--gcc/rust/typecheck/rust-tyty-util.cc24
-rw-r--r--gcc/rust/typecheck/rust-tyty-util.h3
-rw-r--r--gcc/rust/typecheck/rust-tyty-variance-analysis-private.h9
-rw-r--r--gcc/rust/typecheck/rust-tyty-variance-analysis.cc4
-rw-r--r--gcc/rust/typecheck/rust-tyty-visitor.h10
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc777
-rw-r--r--gcc/rust/typecheck/rust-tyty.h256
-rw-r--r--gcc/rust/typecheck/rust-unify.cc675
-rw-r--r--gcc/rust/typecheck/rust-unify.h17
-rw-r--r--gcc/rust/util/bi-map.h1
-rw-r--r--gcc/rust/util/fnv-hash.h1
-rw-r--r--gcc/rust/util/rust-attribute-values.h7
-rw-r--r--gcc/rust/util/rust-attributes.cc94
-rw-r--r--gcc/rust/util/rust-attributes.h15
-rw-r--r--gcc/rust/util/rust-canonical-path.h2
-rw-r--r--gcc/rust/util/rust-dump.h2
-rw-r--r--gcc/rust/util/rust-ggc.cc3
-rw-r--r--gcc/rust/util/rust-ggc.h4
-rw-r--r--gcc/rust/util/rust-inline-visitor.h1
-rw-r--r--gcc/rust/util/rust-lang-item.h5
-rw-r--r--gcc/rust/util/rust-token-converter.cc4
-rw-r--r--gcc/rust/util/rust-unwrap-segment.h20
194 files changed, 9486 insertions, 13344 deletions
diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog
index f960ef2..556ce28 100644
--- a/gcc/rust/ChangeLog
+++ b/gcc/rust/ChangeLog
@@ -1,3 +1,1446 @@
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-pointer-visitor.cc (PointerVisitor::visit):
+ Handle the expression contained in an ErrorPropagationExpr.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * typecheck/rust-hir-type-check-pattern.cc (visit(TuplePattern)): Update HAS_REST
+ case to continue to attempt to resolve pattern items after emitting size error.
+
+2025-10-30 Ryo Yoshida <low.ryoshida@gmail.com>
+
+ * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): Emit
+ an error when the path refers to an enum itself rather than its variant.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * typecheck/rust-hir-type-check-base.cc (parse_repr_options): Changed TOKEN_TREE
+ assert into error, update malformed repr attribute error message to be inline
+ with other attribute error messages.
+
+2025-10-30 Lucas Ly Ba <lucas.ly-ba@outlook.fr>
+
+ * ast/rust-ast.cc (Attribute::is_derive):
+ Change string derive to its definition.
+ * util/rust-attribute-values.h:
+ Add attribute definition derive.
+ * util/rust-attributes.cc (AttributeChecker::visit):
+ Add method check_inner_attributes.
+ (AttributeChecker::check_inner_attributes):
+ Check if there is a bad inner attribute.
+ * util/rust-attributes.h:
+ Add method check_inner_attributes in .h.
+
+2025-10-30 lishin <lishin1008@gmail.com>
+
+ * typecheck/rust-tyty-util.cc (TyVar::TyVar): Add null check to avoid ICE.
+ (TyVar::get_tyty): Return nullptr when lookup fails.
+ (TyVar::clone): Handle null base type safely.
+ (TyVar::monomorphized_clone): Add fallback for error types.
+
+2025-10-30 Ryo Yoshida <low.ryoshida@gmail.com>
+
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): check
+ and properly emit an error when the tuple index is on a non-tuple-struct.
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::array_copied_expr): refactor to new classes
+ * backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit): likewise
+ (CompilePatternBindings::visit): likewise
+ * backend/rust-compile-type.cc (TyTyResolveCompile::visit): likewise
+ * backend/rust-compile-type.h: likewise
+ * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::resolve_literal): likewise
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): likewise
+ * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): likewise
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise
+ * typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit): likewise
+ * typecheck/rust-substitution-mapper.h: likewise
+ * typecheck/rust-type-util.cc (unify_site_and): remove bad delete (alpine32)
+ * typecheck/rust-tyty-call.h: refactor to new classes
+ * typecheck/rust-tyty-subst.cc (SubstitutionParamMapping::clone): likewise
+ (SubstitutionRef::infer_substitions): likewise
+ * typecheck/rust-tyty-util.cc (TyVar::get_implicit_const_infer_var): likewise
+ * typecheck/rust-tyty-util.h: likewise
+ * typecheck/rust-tyty-variance-analysis-private.h: likewise
+ * typecheck/rust-tyty-visitor.h: likewise
+ * typecheck/rust-tyty.cc (BaseType::destructure): likewise
+ (BaseType::monomorphized_clone): likewise
+ (BaseType::is_concrete): likewise
+ (VariantDef::clone): likewise
+ (VariantDef::monomorphized_clone): likewise
+ (ArrayType::as_string): likewise
+ (ArrayType::get_capacity): likewise
+ (ArrayType::handle_substitions): likewise
+ (generate_tree_str): likewise
+ (ConstType::ConstType): likewise
+ (ConstParamType::ConstParamType): likewise
+ (ConstType::accept_vis): likewise
+ (ConstParamType::const_kind): likewise
+ (ConstParamType::get_symbol): likewise
+ (ConstParamType::can_resolve): likewise
+ (ConstParamType::resolve): likewise
+ (ConstParamType::accept_vis): likewise
+ (ConstType::set_value): likewise
+ (ConstType::as_string): likewise
+ (ConstParamType::as_string): likewise
+ (ConstType::clone): likewise
+ (ConstParamType::clone): likewise
+ (ConstType::get_symbol): likewise
+ (ConstParamType::get_name): likewise
+ (ConstType::can_resolve): likewise
+ (ConstParamType::is_equal): likewise
+ (ConstType::resolve): likewise
+ (ConstValueType::ConstValueType): likewise
+ (ConstValueType::const_kind): likewise
+ (ConstValueType::accept_vis): likewise
+ (ConstValueType::as_string): likewise
+ (ConstValueType::clone): likewise
+ (ConstValueType::get_name): likewise
+ (ConstValueType::is_equal): likewise
+ (ConstValueType::get_value): likewise
+ (ConstInferType::ConstInferType): likewise
+ (ConstInferType::const_kind): likewise
+ (ConstInferType::accept_vis): likewise
+ (ConstType::get_name): likewise
+ (ConstInferType::as_string): likewise
+ (ConstInferType::clone): likewise
+ (ConstInferType::get_name): likewise
+ (ConstType::is_equal): likewise
+ (ConstInferType::is_equal): likewise
+ (ConstErrorType::ConstErrorType): likewise
+ (ConstErrorType::const_kind): likewise
+ (ConstType::handle_substitions): likewise
+ (ConstErrorType::accept_vis): likewise
+ (ConstErrorType::as_string): likewise
+ (ConstErrorType::clone): likewise
+ (ConstErrorType::get_name): likewise
+ (ConstErrorType::is_equal): likewise
+ * typecheck/rust-tyty.h (class BaseConstType): likewise
+ (class ConstType): likewise
+ (class ConstParamType): likewise
+ (class ConstValueType): likewise
+ (class ConstInferType): likewise
+ (class ConstErrorType): likewise
+ * typecheck/rust-unify.cc (UnifyRules::commit): likewise
+ (UnifyRules::go): likewise
+ (UnifyRules::expect_array): likewise
+ (UnifyRules::expect_const): likewise
+ * typecheck/rust-unify.h: likewise
+
+2025-10-30 0xllx0 <github+elle@weathered-steel.dev>
+
+ * ast/rust-ast.cc (Module::process_file_path): empty module early return
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * util/rust-attributes.cc (check_doc_attribute): Change message.
+ (AttributeChecker::visit): Add doc attribute checking on traits.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast.cc (AttrInputMetaItemContainer::separate_cfg_attrs):
+ Avoid malformed attributes.
+ * util/rust-attributes.cc (AttributeChecker::visit): Change location.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-expr.h: Force crash when retrieving locus.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast.h: Add missing override modifier.
+ * ast/rust-path.h: Likewise.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * util/rust-attributes.cc (AttributeChecker::check_attribute): Recurse
+ within attr input for additional attribute checking.
+ (AttributeChecker::visit): Remove empty definition in favor of default
+ ast visitor definition.
+ * util/rust-attributes.h: Remove now unused prototypes.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * typecheck/rust-hir-type-check-pattern.cc (visit(TupleStructPattern)):
+ Update error for mismatched number of fields to use rich_location.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * backend/rust-compile-pattern.cc: Add compilation support for TupleStructItemsHasRest
+ in CompilePatternCheckExpr(TupleStructPattern) & CompilePatternBindings(TupleStructPattern)
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * hir/rust-ast-lower-pattern.cc (ASTLoweringPattern::visit(TupleStructPattern)):
+ Implement lowering of AST::TupleStructItemsHasRest to HIR.
+ * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit(TupleStructPattern)):
+ Add the respective type checking for AST::TupleStructItemsHasRest
+ * checks/errors/rust-hir-pattern-analysis.cc (lower_tuple_pattern):
+ Add respective pattern for HAS_REST case.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * typecheck/rust-hir-type-check-pattern.cc (visit(StructPattern)): Add type check
+ support for StructPatterns matching against a TUPLE type ADT.
+ * backend/rust-compile-pattern.cc(CompilePatternBindings::visit(StructPattern)):
+ Update assert to allow TUPLE type ADTs.
+ * hir/tree/rust-hir.cc (StructPatternField::as_string()): Improve info dumped.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * ast/rust-pattern.h (StructPatternElements): Rename has_struct_pattern_etc
+ to has_rest_pattern, and has_etc to has_rest to signify presense of rest
+ patterns more clearly.
+ * ast/rust-pattern.cc (StructPatternElements::as_string): Rename variables
+ accordingly.
+ * ast/rust-ast-collector.cc: Rename variables accordingly.
+ * expand/rust-cfg-strip.cc: Rename variables accordingly.
+ * parse/rust-parse-impl.h: Rename variable accordingly.
+ * hir/tree/rust-hir-pattern.h (StructPatternElements): Add a boolean to track
+ presense of rest pattern.
+ * hir/rust-ast-lower-pattern.cc (visit(StructPattern)): Add support for
+ lowering rest pattern to HIR.
+ * typecheck/rust-hir-type-check-pattern.cc (visit(StructPattern)): Remove
+ size check when rest pattern is present.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * backend/rust-compile-extern.h: Add includes.
+ (CompileExternItem::visit): Use get_link_name.
+ (CompileExternItem::get_link_name): New static member function.
+ * util/rust-attribute-values.h (Attributes::LINK_NAME): New
+ static constexpr member variable.
+ * util/rust-attributes.cc (__definitions): New entry for
+ LINK_NAME.
+ * util/rust-ggc.cc: Include "rust-ast.h".
+ (Ident::Ident): Add overload for Rust::Identifier.
+ * util/rust-ggc.h (class Identifier): Forward declare.
+ (Ident::Ident): Add overload for Rust::Identifier.
+
+2025-10-30 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-expand-visitor.cc: Remove old visitors.
+ * expand/rust-expand-visitor.h: Likewise, plus inherit from PointerVisitor.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * expand/rust-macro-expand.cc: Forward invocation tree locus to
+ substitution context.
+ * expand/rust-macro-substitute-ctx.cc: Use origin location for expanded
+ tokens.
+ * expand/rust-macro-substitute-ctx.h (class SubstituteCtx): Save
+ invocation location.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * expand/rust-macro-expand.cc (transcribe_expression): Emit error
+ early.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * expand/rust-macro-substitute-ctx.cc (is_builtin_metavariable): Add
+ function to check builtin metavars knowledge.
+ (SubstituteCtx::check_repetition_amount): Do not process missing
+ fragment.
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-resolve-path.cc: add error diag
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): add error diagnostic
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): check for error
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-expr.cc: remove old hack
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit): handle fnptr
+ * typecheck/rust-tyty.cc (FnPtr::handle_substitions): new
+ * typecheck/rust-tyty.h: likewise
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-fmt.h (class FFIOpt): Adjust internal structure to
+ match a repr(C) rust enum.
+
+2025-10-30 Magnus-Mage <romescha123@gmail.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Implement
+ FormatArgs visitor to reconstruct format_args! macro syntax.
+ * ast/rust-builtin-ast-nodes.h (FormatArguments): Add get_args(),
+ size(), and empty() accessor methods.
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): check for invalid capacity
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-constexpr.cc (eval_constant_expression): port over missing bits
+ (eval_store_expression): likewise
+ (eval_call_expression): likewise
+ (eval_binary_expression): likewise
+ (eval_bit_field_ref): likewise
+ (eval_check_shift_p): likewise
+ (fold_pointer_plus_expression): likewise
+ (maybe_fold_addr_pointer_plus): likewise
+ (fold_expr): likewise
+ (union_active_member): likewise
+ (fold_indirect_ref_1): likewise
+ (rs_fold_indirect_ref): likewise
+ (rs_eval_indirect_ref): likewise
+ (eval_logical_expression): likewise
+ (eval_vector_conditional_expression): likewise
+ (eval_bare_aggregate): likewise
+ (cxx_eval_trinary_expression): likewise
+ (eval_and_check_array_index): likewise
+ (eval_array_reference): likewise
+ (eval_component_reference): likewise
+ (rs_bind_parameters_in_call): likewise
+ (eval_builtin_function_call): likewise
+ (constexpr_fn_retval): likewise
+ (verify_constant): likewise
+ (get_array_or_vector_nelts): likewise
+ (eval_conditional_expression): likewise
+ (eval_switch_expr): likewise
+ (eval_unary_expression): likewise
+ (cxx_eval_outermost_constant_expr): likewise
+ (potential_constant_expression_1): likewise
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::compile_integer_literal): cleanup
+ * backend/rust-constexpr.cc (struct constexpr_global_ctx): port over c++ helpers
+ (decl_really_constant_value): likewise
+ (eval_constant_expression): likewise
+ (non_const_var_error): likewise
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_pattern): Ignore
+ inner patterns which fail to parse.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Remove
+ overload for TraitItemConst.
+ * ast/rust-ast-collector.h (TokenCollector::visit): Likewise.
+ * ast/rust-ast-pointer-visitor.cc (PointerVisitor::visit):
+ Likewise.
+ * ast/rust-ast-pointer-visitor.h (PointerVisitor::visit):
+ Likewise.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
+ * ast/rust-ast-visitor.h (ASTVisitor::visit): Likewise.
+ (DefaultASTVisitor::visit): Likewise.
+ * expand/rust-cfg-strip.cc (CfgStrip::visit): Likewise.
+ * expand/rust-cfg-strip.h (CfgStrip::visit): Likewise.
+ * expand/rust-derive.h (DeriveVisitor::visit): Likewise.
+ * expand/rust-expand-visitor.cc (ExpandVisitor::visit):
+ Likewise.
+ * expand/rust-expand-visitor.h (ExpandVisitor::visit): Likewise.
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
+ * hir/rust-ast-lower-base.h (ASTLoweringBase::visit): Likewise.
+ * util/rust-attributes.cc (AttributeChecker::visit): Likewise.
+ * util/rust-attributes.h (AttributeChecker::visit): Likewise.
+ * ast/rust-ast.cc (ConstantItem::as_string): Handle missing
+ expression.
+ (TraitItemConst::as_string): Remove function definition.
+ (TraitItemConst::accept_vis): Remove function definition.
+ * ast/rust-item.h (ConstantItem::mark_for_strip): Adjust
+ comment.
+ (ConstantItem::has_expr): Make const.
+ (class TraitItemConst): Remove definition.
+ * ast/rust-ast-full-decls.h (class TraitItemConst): Remove
+ declaration.
+ * hir/rust-ast-lower-implitem.cc (ASTLowerTraitItem::visit):
+ Handle ConstantItem instead of TraitItemConst.
+ * hir/rust-ast-lower-implitem.h (ASTLowerTraitItem::visit):
+ Likewise.
+ * parse/rust-parse-impl.h (Parser::parse_trait_const): Return
+ pointer to ConstantItem instead of TraitItemConst.
+ * parse/rust-parse.h (Parser::parse_trait_const): Likewise.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * Make-lang.in: Handle source files in checks/errors/feature.
+ * checks/errors/rust-feature-gate.cc: Move to...
+ * checks/errors/feature/rust-feature-gate.cc: ...here.
+ * checks/errors/rust-feature-gate.h: Move to...
+ * checks/errors/feature/rust-feature-gate.h: ...here.
+ * checks/errors/rust-feature.cc: Move to...
+ * checks/errors/feature/rust-feature.cc: ...here.
+ * checks/errors/rust-feature.h: Move to...
+ * checks/errors/feature/rust-feature.h: ...here.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * Make-lang.in (GRS_OBJS): Remove rust-early-name-resolver.o.
+ * expand/rust-macro-builtins-helpers.h: Remove inclusion of
+ rust-early-name-resolver.h.
+ * expand/rust-macro-builtins.cc: Likewise.
+ * expand/rust-macro-expand.cc: Likewise.
+ * expand/rust-macro-expand.h: Likewise.
+ * resolve/rust-early-name-resolver.cc: Removed.
+ * resolve/rust-early-name-resolver.h: Removed.
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * hir/tree/rust-hir-item.h: add unsafe helper
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): pass in abi and unsafe
+ * typecheck/rust-tyty.cc (BaseType::monomorphized_clone): likewise
+ (FnPtr::as_string): emit more info
+ (FnPtr::clone): update ctor call
+ * typecheck/rust-tyty.h: new ctor params
+ * typecheck/rust-unify.cc (UnifyRules::expect_fnptr): check abi and unsafe
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-unify.cc (UnifyRules::expect_reference): remove clone
+ (UnifyRules::expect_pointer): likewise
+ (UnifyRules::expect_slice): likewise
+ (UnifyRules::expect_tuple): likewise
+ (UnifyRules::expect_int): likewise
+ (UnifyRules::expect_uint): likewise
+ (UnifyRules::expect_float): likewise
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * Make-lang.in (GRS_OBJS): Remove entries.
+ * rust-lang.cc: Remove inclusion of "rust-ast-resolve-item.h".
+ (run_rust_tests): Remove call to rust_simple_path_resolve_test.
+ * resolve/rust-ast-resolve-base.cc: Removed.
+ * resolve/rust-ast-resolve-base.h: Removed.
+ * resolve/rust-ast-resolve-expr.cc: Removed.
+ * resolve/rust-ast-resolve-expr.h: Removed.
+ * resolve/rust-ast-resolve-implitem.h: Removed.
+ * resolve/rust-ast-resolve-item.cc: Removed.
+ * resolve/rust-ast-resolve-item.h: Removed.
+ * resolve/rust-ast-resolve-path.cc: Removed.
+ * resolve/rust-ast-resolve-path.h: Removed.
+ * resolve/rust-ast-resolve-pattern.cc: Removed.
+ * resolve/rust-ast-resolve-pattern.h: Removed.
+ * resolve/rust-ast-resolve-stmt.cc: Removed.
+ * resolve/rust-ast-resolve-stmt.h: Removed.
+ * resolve/rust-ast-resolve-struct-expr-field.cc: Removed.
+ * resolve/rust-ast-resolve-struct-expr-field.h: Removed.
+ * resolve/rust-ast-resolve-toplevel.h: Removed.
+ * resolve/rust-ast-resolve-type.cc: Removed.
+ * resolve/rust-ast-resolve-type.h: Removed.
+ * resolve/rust-ast-resolve.cc: Removed.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Use
+ resolve_type_path_like in overloads for TypePath,
+ StructExprStruct, StructExprStructBase, and
+ StructExprStructFields.
+ (resolve_type_path_like): New static function based off
+ Late::visit overload for TypePath.
+ * util/rust-unwrap-segment.h (unwrap_segment_error_string): New
+ inline static function definitions.
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::visit): add guard
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-context.h: add assertions for context peeks
+ * backend/rust-compile-expr.cc (CompileExpr::visit): check for valid loop context
+ (CompileExpr::array_copied_expr): just reuse array tyty capacity value
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): catch error
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * checks/errors/rust-readonly-check.cc (collect_assignment_tuple): Implement
+ read-only checker for tuple patterns with rest pattern.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * backend/rust-compile-var-decl.h (CompileVarDecl::visit(TuplePattern)): Implement
+ variable declaration bindings for tuple patterns with rest pattern (i.e.
+ TuplePatternItemsHasRest).
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * util/rust-attribute-values.h
+ (Attributes::RUSTC_ALLOW_CONST_FN_UNSTABLE): New static
+ constexpr member variable.
+ * util/rust-attributes.cc (__definitions): Add entry for
+ RUSTC_ALLOW_CONST_FN_UNSTABLE.
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-unify.cc (UnifyRules::commit): commit hook update
+ (UnifyRules::go): insert implicit infer const types
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-unify.cc (UnifyRules::go): unwrap the const type
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-base.cc (walk_types_to_constrain): track the ref as well
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-tyty-subst.cc: const generic arguments dont have a value yet
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-tyty.cc (VariantDef::clone): fix formatting
+ (VariantDef::monomorphized_clone): likewise
+ * typecheck/rust-tyty.h: likewise
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-tyty.cc (InferType::can_eq): remove
+ (ErrorType::can_eq): likewise
+ (ADTType::can_eq): likewise
+ (TupleType::can_eq): likewise
+ (FnType::can_eq): likewise
+ (FnPtr::can_eq): likewise
+ (ClosureType::can_eq): likewise
+ (ArrayType::can_eq): likewise
+ (SliceType::can_eq): likewise
+ (BoolType::can_eq): likewise
+ (IntType::can_eq): likewise
+ (UintType::can_eq): likewise
+ (FloatType::can_eq): likewise
+ (USizeType::can_eq): likewise
+ (ISizeType::can_eq): likewise
+ (CharType::can_eq): likewise
+ (ReferenceType::can_eq): likewise
+ (PointerType::can_eq): likewise
+ (ParamType::can_eq): likewise
+ (ConstType::can_eq): likewise
+ (OpaqueType::can_eq): likewise
+ (StrType::can_eq): likewise
+ (NeverType::can_eq): likewise
+ (PlaceholderType::can_eq): likewise
+ (ProjectionType::can_eq): likewise
+ (DynamicObjectType::can_eq): likewise
+ * typecheck/rust-tyty.h: remove can_eq
+ * typecheck/rust-tyty-cmp.h: Removed.
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-tyty.cc (ParamType::is_equal): uses types_compatable
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-unify.cc (unify_error_type_node): new static node
+ (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_never): likewise
+ (UnifyRules::expect_placeholder): likewise
+ (UnifyRules::expect_projection): likewise
+ (UnifyRules::expect_dyn): likewise
+ (UnifyRules::expect_closure): likewise
+ (UnifyRules::expect_opaque): likewise
+ (UnifyRules::expect_const): likewise
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-unify.cc (UnifyRules::Resolve): check for success
+ (UnifyRules::expect_inference_variable): dont clone
+ (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_never): likewise
+ (UnifyRules::expect_placeholder): likewise
+ (UnifyRules::expect_projection): likewise
+ (UnifyRules::expect_dyn): likewise
+ (UnifyRules::expect_closure): likewise
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-tyty.cc (BaseType::satisfies_bound): use types_compatable instead
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-type-util.cc (types_compatable): add check bounds flag
+ (unify_site_and): likewise
+ * typecheck/rust-type-util.h (types_compatable): likewise
+ (unify_site_and): likewise
+ * typecheck/rust-tyty-bounds.cc: likewise
+ * typecheck/rust-unify.cc (UnifyRules::UnifyRules): likewise
+ (UnifyRules::Resolve): likewise
+ (UnifyRules::resolve_subtype): likewise
+ (UnifyRules::go): likewise
+ * typecheck/rust-unify.h: likewise
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-path-probe.cc (PathProbeType::process_impl_item_candidate):
+ refactor to types_compatable
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-unify.cc (UnifyRules::expect_inference_variable): dont commit
+ (UnifyRules::expect_adt): 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
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-base.h: remove const
+ * backend/rust-compile-expr.cc: likewise
+ * backend/rust-compile.cc (HIRCompileBase::coerce_to_dyn_object): likewise
+ * typecheck/rust-hir-type-bounds.h: likewise
+ * typecheck/rust-type-util.cc (lookup_associated_impl_block): likewise
+ * typecheck/rust-type-util.h (lookup_associated_impl_block): likewise
+ * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::TypeBoundsProbe): likewise
+ (TypeBoundsProbe::Probe): likewise
+ * typecheck/rust-tyty-cmp.h: likewise
+ * typecheck/rust-tyty-subst.cc (SubstitutionRef::monomorphize): likewise
+ * typecheck/rust-tyty.cc (BaseType::satisfies_bound): likewise
+ (BaseType::bounds_compatible): likewise
+ (VariantDef::clone): likewise
+ (VariantDef::monomorphized_clone): likewise
+ (OpaqueType::is_equal): likewise
+ (DynamicObjectType::is_equal): likewise
+ * typecheck/rust-tyty.h: likewise
+
+2025-10-30 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-coercion.cc (TypeCoercionRules::select): respect try flag
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc (Early::finalize_rebind_import):
+ Replace assert with early break and remove early return.
+ (Early::visit): Check for unsuffixed lower self list.
+ * resolve/rust-early-name-resolver-2.0.h: Add visit function prototype.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc (Early::visit): Emit an error
+ on top level rebind self use declaration.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * Make-lang.in (GRS_OBJS): Add "rust-resolve-builtins.o".
+ * resolve/rust-late-name-resolver-2.0.cc: Include
+ "rust-resolve-builtins.h".
+ (next_node_id): Remove function.
+ (next_hir_id): Likewise.
+ (Late::setup_builtin_types): Likewise.
+ (Late::go): Use Builtins::setup_type_ctx instead of
+ Late::setup_builtin_types.
+ * resolve/rust-late-name-resolver-2.0.h
+ (Late::setup_builtin_types): Remove function.
+ * rust-session-manager.cc: Include "rust-resolve-builtins.h".
+ (Session::expansion): Call Builtins::setup_lang_prelude.
+ * resolve/rust-resolve-builtins.cc: New file.
+ * resolve/rust-resolve-builtins.h: New file.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * parse/rust-parse-impl.h (Parser::left_denotation): Remove
+ usage of parse_tuple_index_expr_float.
+ (Parser::parse_closure_expr_pratt): Remove function.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * rust-session-manager.cc (Session::compile_crate): Move the AST dump
+ after parser error check.
+
+2025-10-30 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-expression-yeast.cc (ExpressionYeast::dispatch): Rename to...
+ (ExpressionYeast::reseat): ...this.
+ (ExpressionYeast::visit): Remove.
+ * ast/rust-expression-yeast.h: Inherit from PointerVisitor, override reseat instead
+ of declaring dispatch.
+
+2025-10-30 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * Make-lang.in: Compile it.
+ * ast/rust-builtin-ast-nodes.h: Add missing methods for getting pointers.
+ * ast/rust-expr.h: Likewise.
+ * ast/rust-item.h: Likewise.
+ * ast/rust-path.h: Likewise.
+ * ast/rust-pattern.h: Likewise.
+ * ast/rust-type.h: Likewise.
+ * ast/rust-ast-pointer-visitor.cc: New file.
+ * ast/rust-ast-pointer-visitor.h: New file.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-expr.h (class TupleIndexExpr): Store strip information.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/borrowck/rust-bir-builder-internal.h: Remove
+ inclusion of "rust-name-resolver.h".
+ (BuilderContext::resolver): Change type to nr2.0 resolver.
+ (BuilderContext::BuilderContext): Change initialization of
+ resolver reference.
+ (AbstractBuilder::resolve_label): Assume name resolution 2.0 is
+ enabled.
+ (AbstractBuilder::resolve_variable): Likewise.
+ (AbstractBuilder::resolve_variable_or_fn): Likewise.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/rust-hir-pattern-analysis.cc: Remove inclusion
+ of "options.h".
+ (PatternChecker::PatternChecker): Change initialization of
+ resolver reference.
+ (PatternChecker::visit): Assume name resolution 2.0 is enabled.
+ * checks/errors/rust-hir-pattern-analysis.h: Include nr2.0
+ header instead of nr1.0 header.
+ (PatternChecker::resolver): Change type to nr2.0 resolver.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * rust-session-manager.cc: Remove inclusion of name resolution
+ 1.0 headers.
+ (Session::compile_crate): Assume name resolution 2.0 is enabled.
+ (Session::expansion): Likewise.
+ (Session::load_extern_crate): Likewise.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/privacy/rust-privacy-check.cc: Adjust includes.
+ (Resolver::resolve): Pass 2.0 name resolution context to
+ VisibilityResolver and PrivacyReporter.
+ * checks/errors/privacy/rust-privacy-reporter.cc
+ (PrivacyReporter::PrivacyReporter): Change type of resolver
+ parameter.
+ (is_child_module): Remove static function.
+ (PrivacyReporter::check_for_privacy_violation): Assume nr2.0 is
+ enabled and handle removal of is_child_module.
+ * checks/errors/privacy/rust-privacy-reporter.h: Adjust
+ includes.
+ (PrivacyReporter::PrivacyReporter): Change type of resolver
+ parameter.
+ (PrivacyReporter::resolver): Change member variable type.
+ * checks/errors/privacy/rust-visibility-resolver.cc: Adjust
+ includes.
+ (VisibilityResolver::VisibilityResolver): Change type of
+ resolver parameter.
+ (VisibilityResolver::resolve_module_path): Assume nr2.0 is
+ enabled.
+ * checks/errors/privacy/rust-visibility-resolver.h: Adjust
+ includes.
+ (VisibilityResolver::VisibilityResolver): Change type of
+ resolver parameter.
+ (VisibilityResolver::resolver): Change member variable type.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * ast/rust-pattern.h:
+ - Add a new base abstract class `PatternItems` which are used by pattern items class
+ class derivatives for `TuplePattern`, `TupleStructPattern` & `SlicePattern`.
+ - Standardized the derived class names to have `HasRest` or `NoRest` as suffixes.
+ - Values for the common `ItemType` enum is updated to `HAS_REST` or `NO_REST`.
+ * ast/rust-pattern.cc: Renamed the classes accordingly.
+ * ast/rust-ast-collector.cc: Renamed the classes accordingly.
+ * ast/rust-ast-collector.h: Renamed the classes accordingly.
+ * ast/rust-ast-full-decls.h: Renamed the classes accordingly.
+ * ast/rust-ast-visitor.cc: Renamed the classes accordingly.
+ * ast/rust-ast-visitor.h: Renamed the classes accordingly.
+ * ast/rust-desugar-for-loops.cc: Renamed the classes accordingly.
+ * ast/rust-desugar-question-mark.cc: Renamed the classes accordingly.
+ * expand/rust-cfg-strip.cc: Renamed the classes accordingly.
+ * expand/rust-cfg-strip.h: Renamed the classes accordingly.
+ * expand/rust-derive-clone.cc: Renamed the classes accordingly.
+ * expand/rust-derive-cmp-common.cc: Renamed the classes accordingly.
+ * expand/rust-derive-hash.cc: Renamed the classes accordingly.
+ * expand/rust-derive-ord.cc: Renamed the classes accordingly.
+ * expand/rust-derive-partial-eq.cc: Renamed the classes accordingly.
+ * expand/rust-derive.h: Renamed the classes accordingly.
+ * expand/rust-expand-visitor.cc: Renamed the classes accordingly.
+ * expand/rust-expand-visitor.h: Renamed the classes accordingly.
+ * hir/rust-ast-lower-base.cc: Renamed the classes accordingly.
+ * hir/rust-ast-lower-base.h: Renamed the classes accordingly.
+ * hir/rust-ast-lower-pattern.cc: Renamed the classes accordingly.
+ * hir/tree/rust-hir-pattern.h: Renamed the classes accordingly.
+ * parse/rust-parse-impl.h: Renamed the classes accordingly.
+ * resolve/rust-ast-resolve-base.cc: Renamed the classes accordingly.
+ * resolve/rust-ast-resolve-base.h: Renamed the classes accordingly.
+ * resolve/rust-ast-resolve-pattern.cc: Renamed the classes accordingly.
+ * util/rust-attributes.cc: Renamed the classes accordingly.
+ * util/rust-attributes.h: Renamed the classes accordingly.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Use
+ should_have_str instead of has_str.
+ * ast/rust-ast.cc (Token::as_string): Likewise.
+ * expand/rust-macro-builtins-offset-of.cc
+ (MacroBuiltin::offset_of_handler): Likewise.
+ * lex/rust-lex.cc (Lexer::dump_and_skip): Likewise.
+ * ast/rust-ast.h (class Token): Remove dead code.
+ (Token::has_str): Remove function.
+ (Token::should_have_str): New function.
+ * lex/rust-token.cc (Token::get_str): Remove function
+ definition.
+ * lex/rust-token.h: Include "rust-diagnostics.h".
+ (Token::str): Change type from std::unique_ptr<std::string> to
+ std::string.
+ (Token::Token): Adjust initialization of str member variable and
+ the type of the parameter used to initialize it.
+ (Token::make_identifier): Accept std::string instead of rvalue
+ reference to std::string.
+ (Token::make_int): Likewise.
+ (Token::make_float): Likewise.
+ (Token::make_string): Likewise.
+ (Token::make_byte_string): Likewise.
+ (Token::make_raw_string): Likewise.
+ (Token::make_inner_doc_comment): Likewise.
+ (Token::make_outer_doc_comment): Likewise.
+ (Token::make_lifetime): Likewise.
+ (Token::get_str): Add definition to function declaration.
+ (Token::has_str): Remove member function.
+ (Token::should_have_str): Handle INNER_DOC_COMMENT and
+ OUTER_DOC_COMMENT.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * expand/rust-macro-builtins-format-args.cc
+ (format_args_parse_arguments): Split format expression parsing
+ into...
+ (format_args_parse_expr): ...a new function here, while handling
+ eager expansion.
+ (MacroBuiltin::format_args_handler): Use format_args_parse_expr.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_expr): Avoid skipping
+ or splitting tokens.
+ (Parser::null_denotation): Assume initial token was not skipped
+ and adjust function signature to match. Use
+ parse_path_in_expression instead of
+ parse_path_in_expression_pratt and handle SCOPE_RESOLUTION.
+ (Parser::parse_path_in_expression_pratt): Remove function.
+ * parse/rust-parse.h (null_denotation): Remove initial token
+ parameter.
+ (parse_path_in_expression_pratt): Remove function.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-coercion.cc (TypeCoercionRules::do_coercion): Use as
+ member function.
+ (TypeCoercionRules::coerce_borrowed_pointer): Likewise.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-coercion.cc (TypeCoercionRules::do_coercion):
+ Move nevertype coercion from here...
+ (TypeCoercionRules::coerce_never): ... to here.
+ * typecheck/rust-coercion.h: Add function prototype.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-coercion.cc (TypeCoercionRules::do_coercion): Adapt
+ call to new return type.
+ (TypeCoercionRules::coerce_unsized): Change error handling.
+ * typecheck/rust-coercion.h: Update function prototype and add new
+ CoerceUnsizedError error type.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-coercion.cc (TypeCoercionRules::do_coercion): Refactor
+ common return statement.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Remove
+ unused assignment.
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments):
+ Likewise.
+ * typecheck/rust-tyty.cc (ParamType::handle_substitions): Likewise.
+ * typecheck/rust-unify.cc (UnifyRules::go): Likewise.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait):
+ Construct value in place.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-ast-resolve-stmt.cc (ResolveStmt::visit): Remove
+ unused copy.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::generate_closure_fntype):
+ Unwrap the optional.
+ * backend/rust-compile.cc: Change return type container. Adapt code to
+ new return type.
+ * typecheck/rust-hir-dot-operator.cc: Likewise.
+ * typecheck/rust-hir-path-probe.cc: Likewise.
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItemWithTrait::visit):
+ Likewise.
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit):
+ Likewise.
+ * typecheck/rust-tyty-bounds.cc (TypeBoundPredicate::contains_item):
+ Likewise.
+ (TypeBoundPredicate::lookup_associated_item): Likewise.
+ (TypeBoundPredicateItem::get_parent): Likewise.
+ (TypeBoundPredicate::lookup_associated_type): Likewise.
+ * typecheck/rust-tyty.cc (BaseType::satisfies_bound): Likewise.
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): Change
+ return type.
+ * typecheck/rust-tyty.h: Likewise.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-casts.cc (TypeCastRules::cast_rules): Authorize
+ cast from function pointer to integer like type.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * typecheck/rust-hir-type-check-base.cc (walk_type_to_constrain): Walk
+ through all kind of type to collect ty leaves.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-type.h: Prevent reconstruction on null pointers.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * util/rust-attribute-values.h (Attributes::SIMD_TEST): Remove
+ static constexpr member variable.
+ * util/rust-attributes.cc (__definitions): Remove entry for
+ SIMD_TEST.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_identifier_pattern):
+ Use parse_pattern_no_alt to parse identifier pattern
+ subpatterns.
+ (Parser::parse_ident_leading_pattern): Likewise.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-fmt.cc (Pieces::collect): Handle changes to ffi
+ interface.
+ (Pieces::~Pieces): Remove function definition.
+ (Pieces::Pieces): Likewise.
+ (Pieces::operator=): Likewise.
+ * ast/rust-fmt.h: Include "optional.h".
+ (rust_ffi_alloc): New extern "C" function declaration.
+ (rust_ffi_dealloc): Likewise.
+ (class FFIVec): New class.
+ (class FFIOpt): Likewise.
+ (RustHamster::RustHamster): New constructor accepting const
+ std::string reference.
+ (struct FormatSpec): Use FFIOpt.
+ (struct PieceSlice): Remove struct.
+ (struct RustString): Likewise.
+ (struct FormatArgsHandle): Likewise.
+ (collect_pieces): Change function signature.
+ (clone_pieces): Likewise.
+ (destroy_pieces): Remove extern "C" function declaration.
+ (Pieces::~Pieces): Remove function declaration.
+ (Pieces::operator=): Likewise.
+ (Pieces::get_pieces): Handle changes to class fields.
+ (Pieces::Pieces): Remove copy and move constructor declarations,
+ adjust signature of remaining constructor declaration.
+ (Pieces::pieces_vector): Remove member variable.
+ (Pieces::handle): Likewise.
+ (Pieces::data): Add member variable.
+ * expand/rust-macro-builtins-asm.cc (expand_inline_asm_strings):
+ Use references to avoid copying.
+
+2025-10-30 lishin <lishin1008@gmail.com>
+
+ * backend/rust-compile-pattern.cc (CompilePatternLet::visit):
+ Handle tuple destructuring containing by-ref.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * hir/tree/rust-hir-pattern.h: Add SlicePatternItems base class and
+ SlicePatternItemsNoRest/SlicePatternItemsHasRest derived classes.
+ Update SlicePattern to hold patterns using the new classes.
+ * hir/tree/rust-hir-full-decls.h: Declare new classes.
+ * hir/tree/rust-hir.cc: Add visits for new classes.
+ * hir/tree/rust-hir-visitor.h: Add visits for new classes.
+ * hir/tree/rust-hir-visitor.cc: Implement visits for new classes.
+ * hir/rust-hir-dump.h: Add visits for new classes.
+ * hir/rust-hir-dump.cc: Implement Dump::visit for new classes.
+ * hir/rust-ast-lower-base.h: Declare new lower_slice_pattern_no_rest/has_rest
+ methods.
+ * hir/rust-ast-lower-base.cc: Implement lower_slice_pattern_no_rest/has_rest
+ to lower AST slice pattern items to HIR.
+ * hir/rust-ast-lower-pattern.cc: Update ASTLoweringPattern::visit for
+ SlicePattern to use new lowering methods.
+ * backend/rust-compile-pattern.cc: Update CompilePatternCheckExpr::visit
+ and CompilePatternBindings::visit for SlicePattern to handle
+ SlicePatternItemsNoRest/HasRest.
+ * checks/errors/borrowck/rust-bir-builder-pattern.cc: Update
+ PatternBindingBuilder::visit for SlicePattern to iterate members correctly.
+ * checks/errors/borrowck/rust-bir-builder-struct.h: Add visits for new
+ classes.
+ * checks/errors/borrowck/rust-function-collector.h: Add visits for new
+ classes.
+ * checks/errors/rust-const-checker.h: Add visits for new classes.
+ * checks/errors/rust-const-checker.cc: Implement empty visits for new classes.
+ * checks/errors/rust-hir-pattern-analysis.h: Add visits for new classes.
+ * checks/errors/rust-hir-pattern-analysis.cc: Implement empty visits for new
+ classes.
+ * checks/errors/rust-unsafe-checker.h: Add visits for new classes.
+ * checks/errors/rust-unsafe-checker.cc: Implement empty visits for new
+ classes.
+ * typecheck/rust-hir-type-check-pattern.cc: Update TypeCheckPattern::visit
+ for SlicePattern to handle SlicePatternItemsNoRest/HasRest.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * rust-session-manager.cc (Session::compile_crate): Collect lang
+ items after expansion.
+
+2025-10-30 Ryutaro Okada <1015ryu88@gmail.com>
+
+ * Make-lang.in: Replace old read-only checker with new implementation.
+ * checks/errors/rust-readonly-check.cc (ReadonlyChecker::ReadonlyChecker):
+ Replace old read-only checker with new implementation.
+ * checks/errors/rust-readonly-check.h:
+ Replace old read-only checker with new implementation.
+ * rust-session-manager.cc (Session::compile_crate):
+ Switch to new read-only checker.
+ * checks/errors/rust-readonly-check2.cc: Removed.
+ * checks/errors/rust-readonly-check2.h: Removed.
+
+2025-10-30 Ryutaro Okada <1015ryu88@gmail.com>
+
+ * checks/errors/rust-readonly-check2.cc (ReadonlyChecker::check_variable):
+ Read-only check if the variable is mutable type.
+ (ReadonlyChecker::is_mutable_type): Read-only check if the variable is mutable type.
+ * checks/errors/rust-readonly-check2.h: Read-only check if the variable is mutable type.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * typecheck/rust-hir-type-check-pattern.cc(ClosureParamInfer(IdentifierPattern)):
+ Resolve subpattern types for IdentifierPattern.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * backend/rust-compile-pattern.cc(CompilePatternLet::visit(IdentifierPattern)):
+ Add support for subpatterns.
+ * backend/rust-compile-var-decl.h(CompileVarDecl::visit(IdentifierPattern)):
+ Implement compilation for subpatterns.
+
+2025-10-30 lishin <lishin1008@gmail.com>
+
+ * typecheck/rust-hir-dot-operator.cc (MethodResolver::Select):
+ Skip asserts by checking candidate type and using early-continue.
+ (MethodResolver::try_select_predicate_candidates):
+ Skip invalid candidates.
+
+2025-10-30 lishin <lishin1008@gmail.com>
+
+ * rust-gcc.cc (constructor_expression):
+ Ensure vec_alloc reserves at least one element.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast.cc (Attribute::check_cfg_predicate): Emit an error with
+ empty cfg_attr input.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.hxx
+ (ForeverStack::resolve_segments): Remove usage of optional
+ reference, allow non-final path segments to resolve to types
+ even outside the type namespace, and allow resolution to
+ progress past non-final path segments which resolve to modules.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_stmt_or_expr): Add null check
+ on parse_macro_invocation_partial call.
+ * ast/rust-path.cc (Path::convert_to_simple_path): Do not exclude
+ capitalized "Self".
+
+2025-10-30 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-fragment.cc (Fragment::is_pattern_fragment): New function.
+ (Fragment::take_pattern_fragment): Likewise.
+ (Fragment::assert_single_fragment): Likewise.
+ * ast/rust-ast-fragment.h: Declare them.
+ * ast/rust-ast.cc (SingleASTNode::SingleASTNode): Add new constructor for pattern
+ single AST nodes.
+ (SingleASTNode::operator=): Handle patterns.
+ (SingleASTNode::accept_vis): Likewise.
+ (SingleASTNode::is_error): Likewise.
+ (SingleASTNode::as_string): Likewise.
+ * ast/rust-ast.h: Add get_pattern_ptr() functions.
+ * ast/rust-expr.h: Likewise.
+ * ast/rust-item.h: Likewise.
+ * ast/rust-pattern.h: Likewise.
+ * ast/rust-stmt.h: Likewise.
+ * expand/rust-expand-visitor.cc (derive_item): Use new API enum values.
+ (expand_item_attribute): Likewise.
+ (expand_stmt_attribute): Likewise.
+ (ExpandVisitor::maybe_expand_pattern): New function.
+ (ExpandVisitor::expand_closure_params): Handle patterns.
+ (ExpandVisitor::visit): Add new visitors for patterns and missed exprs.
+ * expand/rust-expand-visitor.h: Declare them.
+ * expand/rust-macro-expand.cc (transcribe_pattern): New function.
+ (transcribe_context): Call it.
+ * expand/rust-macro-expand.h (struct MacroExpander): New Context type.
+
+2025-10-30 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast.h: Change NodeType to enum class Kind.
+ * ast/rust-ast-fragment.cc: Use new names.
+ * ast/rust-ast-fragment.h: Likewise.
+ * ast/rust-ast.cc (SingleASTNode::SingleASTNode): Likewise.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * parse/rust-parse-impl.h
+ (Parser::parse_identifier_or_keyword_token): Record error on
+ failure.
+
+2025-10-30 Ryutaro Okada <1015ryu88@gmail.com>
+
+ * resolve/rust-ast-resolve-stmt.h:
+ Add name resolution processing for discriminant values.
+
+2025-10-30 Ryutaro Okada <1015ryu88@gmail.com>
+
+ * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): fix error code
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * expand/rust-cfg-strip.cc: Include "rust-macro-expand.h".
+ (fails_cfg): Rename to...
+ (CfgStrip::fails_cfg): ...here and handle test attributes.
+ (fails_cfg_with_expand): Rename to...
+ (CfgStrip::fails_cfg_with_expand): ...here and handle test
+ attributes.
+ * expand/rust-cfg-strip.h (struct ExpansionCfg): Forward
+ declare.
+ (CfgStrip::fails_cfg): New member function.
+ (CfgStrip::fails_cfg_with_expand): Likewise.
+ (CfgStrip::CfgStrip): Accept reference to ExpansionCfg.
+ (CfgStrip::expansion_cfg): New member variable.
+ * rust-session-manager.cc (Session::expansion): Pass
+ ExpansionCfg instance to CfgStrip constructor.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc (Early::finalize_rebind_import):
+ Do not abort on wildcard patterns.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-expr.h: Add const getters to llvm members.
+ * hir/rust-ast-lower-expr.cc (check_llvm_asm_support): Check llvm_asm
+ usage validity.
+ (ASTLoweringExpr::visit): Emit an error message instead of aborting.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * expand/rust-macro-builtins-asm.cc (parse_llvm_clobbers): Expect a
+ comma between clobbers.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * expand/rust-macro-builtins-asm.cc (parse_asm): Simplify expression.
+ (parse_llvm_asm): Likewise.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast.h (Stmt::get_node_id): Make virtual.
+ (Type::get_node_id): Likewise.
+ (AssociatedItem::get_node_id): New virtual member function.
+ * ast/rust-expr.h (TypeCastExpr::get_casted_expr_ptr): New
+ member function.
+ (TypeCastExpr::get_type_to_cast_to_ptr): Likewise.
+ (ClosureExprInner::get_definition_expr_ptr): Likewise.
+ * ast/rust-item.h (TypeAlias::get_node_id): New member function
+ to override AssociatedItem::get_node_id.
+ (ConstantItem::get_node_id): Likewise.
+ * expand/rust-expand-visitor.cc
+ (ExpandVisitor::maybe_expand_expr): Adjust
+ macro_invoc_expect_id.
+ (ExpandVisitor::maybe_expand_type): Likewise and add an overload
+ for std::unique_ptr<TypeNoBounds>.
+ (ExpandVisitor::visit): Check macro_invoc_expect_id and
+ generally improve visitors so that the testsuite will still
+ pass.
+ * expand/rust-expand-visitor.h (ExpandVisitor::ExpandVisitor):
+ Initialize member variable macro_invoc_expect_id.
+ (ExpandVisitor::maybe_expand_type): Add an overload for
+ std::unique_ptr<TypeNoBounds>.
+ (ExpandVisitor::expand_macro_children): Adjust
+ macro_invoc_expect_id.
+ (ExpandVisitor::visit): Add an overload for TypeCastExpr.
+ (ExpandVisitor::macro_invoc_expect_id): New member variable.
+
+2025-10-30 lishin <lishin1008@gmail.com>
+
+ * backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit):
+ Check upper compare operator.
+ * hir/rust-ast-lower-pattern.cc (ASTLoweringPattern::visit):
+ Handle lowering of exclusive range pattern.
+ * hir/tree/rust-hir-pattern.h (class RangePattern):
+ Add support for exclusive ranges in HIR representation.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * expand/rust-macro-expand.cc (transcribe_expression): Parse any
+ outer attributes before parsing an expression.
+ * parse/rust-parse.h (Parser::parse_outer_attributes): Make
+ public.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-expr.h (struct TupleClobber): Add constructor.
+ * backend/rust-compile-context.h (struct fncontext): Likewise.
+ * typecheck/rust-hir-dot-operator.h: Likewise.
+ * typecheck/rust-tyty-variance-analysis-private.h (struct Constraint):
+ Likewise.
+ * typecheck/rust-unify.h: Likewise.
+ * ast/rust-ast-builder.cc (Builder::new_lifetime_param): Add memory
+ reservation and construct in place.
+ (Builder::new_generic_args): Likewise.
+ * ast/rust-ast-collector.cc (TokenCollector::newline): Likewise.
+ (TokenCollector::indentation): Likewise.
+ (TokenCollector::comment): Likewise.
+ * ast/rust-desugar-apit.cc: Likewise.
+ * ast/rust-path.cc (Path::convert_to_simple_path): Likewise.
+ (TypePath::as_simple_path): Likewise.
+ * ast/rust-path.h: Likewise.
+ * backend/rust-compile-type.cc (TyTyResolveCompile::visit): Likewise.
+ (TyTyResolveCompile::create_dyn_obj_record): Likewise.
+ * checks/errors/rust-hir-pattern-analysis.cc (Matrix::specialize):
+ Likewise.
+ (WitnessMatrix::apply_constructor): Likewise.
+ (check_match_usefulness): Likewise.
+ * expand/rust-derive-clone.cc (DeriveClone::clone_fn): Likewise.
+ * expand/rust-macro-builtins-asm.cc (parse_clobber_abi): Likewise.
+ * expand/rust-macro-expand.cc (MacroExpander::parse_proc_macro_output):
+ Likewise.
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_generic_args):
+ Likewise.
+ (ASTLoweringBase::lower_extern_block): Likewise.
+ * hir/rust-ast-lower-enumitem.h: Likewise.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
+ * hir/rust-ast-lower-extern.h: Likewise.
+ * hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): Likewise.
+ (ASTLowerTraitItem::visit): Likewise.
+ * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Likewise.
+ * hir/rust-ast-lower-pattern.cc (ASTLoweringPattern::visit): Likewise.
+ * hir/rust-ast-lower.cc (ASTLowering::go): Likewise.
+ (ASTLoweringBlock::visit): Likewise.
+ (ASTLoweringIfLetBlock::desugar_iflet): Likewise.
+ (ASTLoweringExprWithBlock::visit): Likewise.
+ (ASTLowerPathInExpression::visit): Likewise.
+ (ASTLowerQualPathInExpression::visit): Likewise.
+ * hir/tree/rust-hir.cc (PathPattern::convert_to_simple_path): Likewise.
+ (TypePath::as_simple_path): Likewise.
+ * metadata/rust-export-metadata.cc (ExportContext::emit_function):
+ Likewise.
+ * parse/rust-parse-impl.h (Parser::parse_decl_macro_def): Likewise.
+ (Parser::parse_lifetime_params): Likewise.
+ * resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit):
+ Likewise.
+ (ResolveItem::visit): Likewise.
+ (flatten_list): Likewise.
+ * resolve/rust-ast-resolve-pattern.cc (PatternDeclaration::visit):
+ Likewise.
+ * typecheck/rust-autoderef.cc (AutoderefCycle::try_autoderefed):
+ Likewise.
+ * typecheck/rust-coercion.cc (TypeCoercionRules::coerce_unsized):
+ Likewise.
+ * typecheck/rust-hir-dot-operator.cc: Likewise.
+ * typecheck/rust-hir-path-probe.cc: Likewise.
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait):
+ Likewise.
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
+ Likewise.
+ (TypeCheckExpr::resolve_fn_trait_call): 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-pattern.cc (TypeCheckPattern::visit):
+ Likewise.
+ * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::resolve):
+ Likewise.
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit):
+ Likewise.
+ * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn):
+ Likewise.
+ * typecheck/rust-typecheck-context.cc (TypeCheckContext::push_return_type):
+ Likewise.
+ (TypeCheckContext::insert_associated_impl_mapping): Likewise.
+ * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): Likewise.
+ (TypeBoundsProbe::add_trait_bound): Likewise.
+ (TypeBoundPredicate::operator=): Likewise.
+ (TypeBoundPredicateItem::get_tyty_for_receiver): Likewise.
+ (TypeBoundPredicate::get_associated_type_items): Likewise.
+ * typecheck/rust-tyty-call.cc (TypeCheckMethodCallExpr::go): Likewise.
+ * typecheck/rust-tyty-subst.cc (SubstitutionRef::clone_substs):
+ Likewise.
+ (SubstitutionRef::infer_substitions): Likewise.
+ (SubstitutionRef::are_mappings_bound): Likewise.
+ * typecheck/rust-tyty-variance-analysis.cc (GenericTyPerCrateCtx::query_generic_variance):
+ Likewise.
+ (GenericTyVisitorCtx::add_constraint): Likewise.
+ * typecheck/rust-tyty.cc (FnPtr::clone): Likewise.
+ (DynamicObjectType::get_object_items): Likewise.
+ * typecheck/rust-unify.cc (UnifyRules::Resolve): Likewise.
+ (UnifyRules::go): Likewise.
+ (UnifyRules::expect_tuple): Likewise.
+ * util/rust-canonical-path.h: Likewise.
+ * util/rust-token-converter.cc (convert): Likewise.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * util/bi-map.h: Add include directive for required declarations.
+ * util/fnv-hash.h: Likewise.
+ * util/rust-dump.h: Likewise.
+ * util/rust-inline-visitor.h: Likewise.
+ * util/rust-unwrap-segment.h: Likewise.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * util/rust-lang-item.h (RUST_LANG_ITEM_H): Add header guards.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * parse/rust-parse.h: Change class to struct for friend qualification.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * checks/lints/rust-lint-marklive-base.h (RUST_HIR_LIVENESS_BASE):
+ Remove header includes.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-cond-compilation.h: Delete copy constructor for
+ ConfigurationAll and ConfigurationAny.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-type.h: Update member instead of parameter
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-cond-compilation.h: Move vector instead of passing it by
+ value.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-pattern.h: Include header directly.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-cond-compilation.h: Copy cfg_attrs
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-formatting.h (RUST_AST_FORMATTING_H): Include required
+ headers directly.
+
+2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * util/rust-attributes.cc (Attributes::extract_string_literal):
+ New function definition.
+ * util/rust-attributes.h (Attributes::extract_string_literal):
+ New function declaration.
+ * ast/rust-collect-lang-items.cc (get_lang_item_attr): Use
+ extract_string_literal.
+ * backend/rust-compile-base.cc: Include "rust-attributes.h".
+ (HIRCompileBase::handle_link_section_attribute_on_fndecl):
+ Use extract_string_literal.
+ (HIRCompileBase::handle_must_use_attribute_on_fndecl): Likewise.
+ * hir/rust-ast-lower-base.cc
+ (ASTLoweringBase::handle_lang_item_attribute): Likewise.
+ * rust-session-manager.cc (Session::handle_crate_name):
+ Likewise.
+
+2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * hir/tree/rust-hir-pattern.h:
+ - Rename TupleItems to PatternItems.
+ - Rename TuplePatternItemsMultiple/Ranged & TupleStructItemsRange/NoRange to
+ TuplePatternItemsNoRest/HasRest and TupleStructItemsNoRest/HasRest.
+ - Update enum values to NO_REST/HAS_REST.
+ - Rename clone_tuple_items_impl to clone_pattern_items_impl.
+ * hir/tree/rust-hir-full-decls.h: Renamed the classes accordingly.
+ * hir/tree/rust-hir-visitor.h: Renamed the classes accordingly.
+ * hir/tree/rust-hir-visitor.cc: Renamed the classes accordingly.
+ * hir/rust-hir-dump.h: Renamed the classes accordingly.
+ * hir/rust-hir-dump.cc: Renamed the classes accordingly.
+ * hir/tree/rust-hir.cc: Renamed the classes accordingly.
+ * hir/rust-ast-lower-base.cc: Renamed the classes accordingly.
+ * hir/rust-ast-lower-pattern.cc: Renamed the classes accordingly.
+ * backend/rust-compile-pattern.cc: Renamed the classes accordingly.
+ * backend/rust-compile-var-decl.h: Renamed the classes accordingly.
+ * checks/errors/borrowck/rust-bir-builder-pattern.cc: Renamed the classes accordingly.
+ * checks/errors/borrowck/rust-bir-builder-struct.h: Renamed the classes accordingly.
+ * checks/errors/borrowck/rust-function-collector.h: Renamed the classes accordingly.
+ * checks/errors/rust-const-checker.cc: Renamed the classes accordingly.
+ * checks/errors/rust-const-checker.h: Renamed the classes accordingly.
+ * checks/errors/rust-hir-pattern-analysis.cc: Renamed the classes accordingly.
+ * checks/errors/rust-hir-pattern-analysis.h: Renamed the classes accordingly.
+ * checks/errors/rust-unsafe-checker.cc: Renamed the classes accordingly.
+ * checks/errors/rust-unsafe-checker.h: Renamed the classes accordingly.
+ * checks/errors/rust-readonly-check2.cc: Renamed the classes accordingly.
+ * typecheck/rust-hir-type-check-pattern.cc: Update references to renamed classes and enum
+ values.
+
+2025-10-30 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * expand/rust-derive-eq.cc: Use empty vector explicitly.
+
2025-08-05 Ryutaro Okada <1015ryu88@gmail.com>
* Make-lang.in (rust-readonly-check2.cc):
@@ -5197,7 +6640,7 @@
2025-03-21 Owen Avery <powerboat9.gamer@gmail.com>
- * resolve/rust-name-resolver.cc: Include options.txt.
+ * resolve/rust-name-resolver.cc: Include options.h.
(Resolver::insert_resolved_name): Assert that name resolution
2.0 is disabled.
(Resolver::lookup_resolved_name): Likewise.
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 8cdf6c9..e5a8a5e 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -84,6 +84,7 @@ GRS_OBJS = \
rust/rust-ast-dump.o \
rust/rust-ast-collector.o \
rust/rust-ast-visitor.o \
+ rust/rust-ast-pointer-visitor.o \
rust/rust-hir-visitor.o \
rust/rust-hir-dump.o \
rust/rust-session-manager.o \
@@ -147,17 +148,8 @@ GRS_OBJS = \
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 \
rust/rust-name-resolver.o \
- rust/rust-ast-resolve.o \
- rust/rust-ast-resolve-base.o \
- rust/rust-ast-resolve-item.o \
- rust/rust-ast-resolve-pattern.o \
- rust/rust-ast-resolve-expr.o \
- rust/rust-ast-resolve-type.o \
- rust/rust-ast-resolve-path.o \
- rust/rust-ast-resolve-stmt.o \
- rust/rust-ast-resolve-struct-expr-field.o \
+ rust/rust-resolve-builtins.o \
rust/rust-forever-stack.o \
rust/rust-hir-type-check.o \
rust/rust-privacy-check.o \
@@ -209,7 +201,6 @@ GRS_OBJS = \
rust/rust-lint-marklive.o \
rust/rust-lint-unused-var.o \
rust/rust-readonly-check.o \
- rust/rust-readonly-check2.o \
rust/rust-hir-type-check-path.o \
rust/rust-unsafe-checker.o \
rust/rust-hir-pattern-analysis.o \
@@ -443,6 +434,7 @@ RUST_INCLUDES = -I $(srcdir)/rust \
-I $(srcdir)/rust/checks/errors \
-I $(srcdir)/rust/checks/errors/privacy \
-I $(srcdir)/rust/checks/errors/borrowck \
+ -I $(srcdir)/rust/checks/errors/feature \
-I $(srcdir)/rust/util \
-I $(srcdir)/rust/metadata \
-I $(srcdir)/../libgrust
@@ -515,6 +507,11 @@ rust/%.o: rust/checks/errors/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
+# build feature related files in rust folder
+rust/%.o: rust/checks/errors/feature/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
# build privacy pass files in rust folder
rust/%.o: rust/checks/errors/privacy/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index ed10ce7..632f945 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -554,12 +554,12 @@ std::unique_ptr<GenericParam>
Builder::new_lifetime_param (LifetimeParam &param)
{
Lifetime l = new_lifetime (param.get_lifetime ());
+
std::vector<Lifetime> lifetime_bounds;
+ lifetime_bounds.reserve (param.get_lifetime_bounds ().size ());
+
for (auto b : param.get_lifetime_bounds ())
- {
- Lifetime bl = new_lifetime (b);
- lifetime_bounds.push_back (bl);
- }
+ lifetime_bounds.emplace_back (new_lifetime (b));
auto p = new LifetimeParam (l, std::move (lifetime_bounds),
param.get_outer_attrs (), param.get_locus ());
@@ -605,11 +605,11 @@ Builder::new_type_param (
for (const auto &lifetime : tb.get_for_lifetimes ())
{
std::vector<Lifetime> lifetime_bounds;
+ lifetime_bounds.reserve (
+ lifetime.get_lifetime_bounds ().size ());
+
for (const auto &b : lifetime.get_lifetime_bounds ())
- {
- Lifetime bl = new_lifetime (b);
- lifetime_bounds.push_back (std::move (bl));
- }
+ lifetime_bounds.emplace_back (new_lifetime (b));
Lifetime nl = new_lifetime (lifetime.get_lifetime ());
LifetimeParam p (std::move (nl), std::move (lifetime_bounds),
@@ -626,12 +626,11 @@ Builder::new_type_param (
{
const TypePathSegment &segment
= (const TypePathSegment &) (*seg.get ());
- TypePathSegment *s = new TypePathSegment (
+
+ segments.emplace_back (new TypePathSegment (
segment.get_ident_segment (),
segment.get_separating_scope_resolution (),
- segment.get_locus ());
- std::unique_ptr<TypePathSegment> sg (s);
- segments.push_back (std::move (sg));
+ segment.get_locus ()));
}
break;
@@ -642,11 +641,10 @@ Builder::new_type_param (
GenericArgs args
= new_generic_args (generic.get_generic_args ());
- TypePathSegmentGeneric *s = new TypePathSegmentGeneric (
+
+ segments.emplace_back (new TypePathSegmentGeneric (
generic.get_ident_segment (), false, std::move (args),
- generic.get_locus ());
- std::unique_ptr<TypePathSegment> sg (s);
- segments.push_back (std::move (sg));
+ generic.get_locus ()));
}
break;
@@ -664,12 +662,9 @@ Builder::new_type_param (
TypePath p (std::move (segments), path.get_locus (),
path.has_opening_scope_resolution_op ());
- TraitBound *b = new TraitBound (std::move (p), tb.get_locus (),
- tb.is_in_parens (),
- tb.has_opening_question_mark (),
- std::move (for_lifetimes));
- std::unique_ptr<TypeParamBound> bound (b);
- type_param_bounds.push_back (std::move (bound));
+ type_param_bounds.emplace_back (new TraitBound (
+ std::move (p), tb.get_locus (), tb.is_in_parens (),
+ tb.has_opening_question_mark (), std::move (for_lifetimes)));
}
break;
@@ -677,10 +672,9 @@ Builder::new_type_param (
{
const Lifetime &l = (const Lifetime &) *b.get ();
- auto bl = new Lifetime (l.get_lifetime_type (),
- l.get_lifetime_name (), l.get_locus ());
- std::unique_ptr<TypeParamBound> bound (bl);
- type_param_bounds.push_back (std::move (bound));
+ type_param_bounds.emplace_back (
+ new Lifetime (l.get_lifetime_type (), l.get_lifetime_name (),
+ l.get_locus ()));
}
break;
}
@@ -709,18 +703,14 @@ Builder::new_generic_args (GenericArgs &args)
location_t locus = args.get_locus ();
for (const auto &lifetime : args.get_lifetime_args ())
- {
- Lifetime l = new_lifetime (lifetime);
- lifetime_args.push_back (std::move (l));
- }
+ lifetime_args.push_back (new_lifetime (lifetime));
for (auto &binding : args.get_binding_args ())
{
Type &t = *binding.get_type_ptr ().get ();
std::unique_ptr<Type> ty = t.reconstruct ();
- GenericArgsBinding b (binding.get_identifier (), std::move (ty),
- binding.get_locus ());
- binding_args.push_back (std::move (b));
+ binding_args.emplace_back (binding.get_identifier (), std::move (ty),
+ binding.get_locus ());
}
for (auto &arg : args.get_generic_args ())
diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index 3d9ea78..721d274 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -76,13 +76,13 @@ TokenCollector::trailing_comma ()
void
TokenCollector::newline ()
{
- tokens.push_back ({CollectItem::Kind::Newline});
+ tokens.emplace_back (CollectItem::Kind::Newline);
}
void
TokenCollector::indentation ()
{
- tokens.push_back ({indent_level});
+ tokens.emplace_back (indent_level);
}
void
@@ -101,7 +101,7 @@ TokenCollector::decrement_indentation ()
void
TokenCollector::comment (std::string comment)
{
- tokens.push_back ({comment});
+ tokens.emplace_back (comment);
}
void
@@ -355,7 +355,8 @@ TokenCollector::visit (MaybeNamedParam &param)
void
TokenCollector::visit (Token &tok)
{
- std::string data = tok.get_tok_ptr ()->has_str () ? tok.get_str () : "";
+ std::string data
+ = tok.get_tok_ptr ()->should_have_str () ? tok.get_str () : "";
switch (tok.get_id ())
{
case IDENTIFIER:
@@ -2171,19 +2172,6 @@ TokenCollector::visit (SelfParam &param)
}
void
-TokenCollector::visit (TraitItemConst &item)
-{
- auto id = item.get_identifier ().as_string ();
- indentation ();
- push (Rust::Token::make (CONST, item.get_locus ()));
- push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
- push (Rust::Token::make (COLON, UNDEF_LOCATION));
- visit (item.get_type ());
- push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
- newline ();
-}
-
-void
TokenCollector::visit (TraitItemType &item)
{
visit_items_as_lines (item.get_outer_attrs ());
@@ -2632,7 +2620,7 @@ TokenCollector::visit (StructPattern &pattern)
if (elems.has_struct_pattern_fields ())
{
visit_items_joined_by_separator (elems.get_struct_pattern_fields ());
- if (elems.has_etc ())
+ if (elems.has_rest ())
{
push (Rust::Token::make (COMMA, UNDEF_LOCATION));
visit_items_as_lines (elems.get_etc_outer_attrs ());
@@ -2649,13 +2637,13 @@ TokenCollector::visit (StructPattern &pattern)
// void TokenCollector::visit(TupleStructItems& ){}
void
-TokenCollector::visit (TupleStructItemsNoRange &pattern)
+TokenCollector::visit (TupleStructItemsNoRest &pattern)
{
visit_items_joined_by_separator (pattern.get_patterns ());
}
void
-TokenCollector::visit (TupleStructItemsRange &pattern)
+TokenCollector::visit (TupleStructItemsHasRest &pattern)
{
for (auto &lower : pattern.get_lower_patterns ())
{
@@ -2682,13 +2670,13 @@ TokenCollector::visit (TupleStructPattern &pattern)
// {}
void
-TokenCollector::visit (TuplePatternItemsMultiple &pattern)
+TokenCollector::visit (TuplePatternItemsNoRest &pattern)
{
visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
}
void
-TokenCollector::visit (TuplePatternItemsRanged &pattern)
+TokenCollector::visit (TuplePatternItemsHasRest &pattern)
{
for (auto &lower : pattern.get_lower_patterns ())
{
@@ -3009,8 +2997,216 @@ TokenCollector::visit (BareFunctionType &type)
void
TokenCollector::visit (AST::FormatArgs &fmt)
{
- rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor",
- __FILE__, __LINE__);
+ push (Rust::Token::make_identifier (fmt.get_locus (), "format_args"));
+ push (Rust::Token::make (EXCLAM, fmt.get_locus ()));
+ push (Rust::Token::make (LEFT_PAREN, fmt.get_locus ()));
+
+ std::string reconstructed_template = "\"";
+ const auto &template_pieces = fmt.get_template ();
+
+ for (const auto &piece : template_pieces.get_pieces ())
+ {
+ if (piece.tag == Fmt::ffi::Piece::Tag::String)
+ {
+ std::string literal = piece.string._0.to_string ();
+ for (char c : literal)
+ {
+ if (c == '"' || c == '\\')
+ {
+ reconstructed_template += '\\';
+ }
+ else if (c == '\n')
+ {
+ reconstructed_template += "\\n";
+ continue;
+ }
+ else if (c == '\r')
+ {
+ reconstructed_template += "\\r";
+ continue;
+ }
+ else if (c == '\t')
+ {
+ reconstructed_template += "\\t";
+ continue;
+ }
+ reconstructed_template += c;
+ }
+ }
+ else if (piece.tag == Fmt::ffi::Piece::Tag::NextArgument)
+ {
+ reconstructed_template += "{";
+
+ const auto &argument = piece.next_argument._0;
+ const auto &position = argument.position;
+
+ switch (position.tag)
+ {
+ case Fmt::ffi::Position::Tag::ArgumentImplicitlyIs:
+ break;
+ case Fmt::ffi::Position::Tag::ArgumentIs:
+ reconstructed_template
+ += std::to_string (position.argument_is._0);
+ break;
+ case Fmt::ffi::Position::Tag::ArgumentNamed:
+ reconstructed_template += position.argument_named._0.to_string ();
+ break;
+ }
+
+ // Add format specifiers if any (like :?, :x, etc.)
+ const auto &format_spec = argument.format;
+
+ bool has_format_spec = false;
+ std::string format_part;
+
+ // For now, skipping the complex format specifications that use FFIOpt
+ // since FFIOpt::get_opt() has a bug.
+
+ // Alignment
+ if (format_spec.align != Fmt::ffi::Alignment::AlignUnknown)
+ {
+ has_format_spec = true;
+ switch (format_spec.align)
+ {
+ case Fmt::ffi::Alignment::AlignLeft:
+ format_part += "<";
+ break;
+ case Fmt::ffi::Alignment::AlignRight:
+ format_part += ">";
+ break;
+ case Fmt::ffi::Alignment::AlignCenter:
+ format_part += "^";
+ break;
+ case Fmt::ffi::Alignment::AlignUnknown:
+ break;
+ }
+ }
+
+ // Alternate flag
+ if (format_spec.alternate)
+ {
+ has_format_spec = true;
+ format_part += "#";
+ }
+
+ // Zero pad flag
+ if (format_spec.zero_pad)
+ {
+ has_format_spec = true;
+ format_part += "0";
+ }
+
+ // Width
+ if (format_spec.width.tag != Fmt::ffi::Count::Tag::CountImplied)
+ {
+ has_format_spec = true;
+ switch (format_spec.width.tag)
+ {
+ case Fmt::ffi::Count::Tag::CountIs:
+ format_part += std::to_string (format_spec.width.count_is._0);
+ break;
+ case Fmt::ffi::Count::Tag::CountIsParam:
+ format_part
+ += std::to_string (format_spec.width.count_is_param._0)
+ + "$";
+ break;
+ case Fmt::ffi::Count::Tag::CountIsName:
+ format_part
+ += format_spec.width.count_is_name._0.to_string () + "$";
+ break;
+ case Fmt::ffi::Count::Tag::CountIsStar:
+ format_part += "*";
+ break;
+ case Fmt::ffi::Count::Tag::CountImplied:
+ break;
+ }
+ }
+
+ // Precision
+ if (format_spec.precision.tag != Fmt::ffi::Count::Tag::CountImplied)
+ {
+ has_format_spec = true;
+ format_part += ".";
+ switch (format_spec.precision.tag)
+ {
+ case Fmt::ffi::Count::Tag::CountIs:
+ format_part
+ += std::to_string (format_spec.precision.count_is._0);
+ break;
+ case Fmt::ffi::Count::Tag::CountIsParam:
+ format_part
+ += std::to_string (format_spec.precision.count_is_param._0)
+ + "$";
+ break;
+ case Fmt::ffi::Count::Tag::CountIsName:
+ format_part
+ += format_spec.precision.count_is_name._0.to_string ()
+ + "$";
+ break;
+ case Fmt::ffi::Count::Tag::CountIsStar:
+ format_part += "*";
+ break;
+ case Fmt::ffi::Count::Tag::CountImplied:
+ break;
+ }
+ }
+
+ // Type/trait (like ?, x, X, etc.)
+ std::string type_str = format_spec.ty.to_string ();
+ if (!type_str.empty ())
+ {
+ has_format_spec = true;
+ format_part += type_str;
+ }
+
+ // Add the format specification if any
+ if (has_format_spec)
+ {
+ reconstructed_template += ":";
+ reconstructed_template += format_part;
+ }
+
+ reconstructed_template += "}";
+ }
+ }
+ reconstructed_template += "\"";
+
+ push (Rust::Token::make_string (fmt.get_locus (), reconstructed_template));
+
+ // Visit format arguments if any exist
+ auto &arguments = fmt.get_arguments ();
+ if (!arguments.empty ())
+ {
+ push (Rust::Token::make (COMMA, fmt.get_locus ()));
+
+ auto &args = arguments.get_args ();
+ for (size_t i = 0; i < args.size (); ++i)
+ {
+ if (i > 0)
+ {
+ push (Rust::Token::make (COMMA, fmt.get_locus ()));
+ }
+
+ auto kind = args[i].get_kind ();
+
+ // Handle named arguments: name = expr
+ if (kind.kind == FormatArgumentKind::Kind::Named)
+ {
+ auto ident = kind.get_ident ().as_string ();
+ push (Rust::Token::make_identifier (fmt.get_locus (),
+ std::move (ident)));
+ push (Rust::Token::make (EQUAL, fmt.get_locus ()));
+ }
+ // Note: Captured arguments are handled implicitly in the template
+ // reconstruction They don't need explicit "name =" syntax in the
+ // reconstructed macro call
+
+ auto &expr = args[i].get_expr ();
+ expr.accept_vis (*this);
+ }
+ }
+
+ push (Rust::Token::make (RIGHT_PAREN, fmt.get_locus ()));
}
void
diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h
index d3ab18a..3e33476 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -330,7 +330,6 @@ public:
void visit (ConstantItem &const_item);
void visit (StaticItem &static_item);
void visit (SelfParam &param);
- void visit (TraitItemConst &item);
void visit (TraitItemType &item);
void visit (Trait &trait);
void visit (InherentImpl &impl);
@@ -370,12 +369,12 @@ public:
void visit (StructPatternFieldIdent &field);
void visit (StructPattern &pattern);
// void visit(TupleStructItems& tuple_items);
- void visit (TupleStructItemsNoRange &tuple_items);
- void visit (TupleStructItemsRange &tuple_items);
+ void visit (TupleStructItemsNoRest &tuple_items);
+ void visit (TupleStructItemsHasRest &tuple_items);
void visit (TupleStructPattern &pattern);
// void visit(TuplePatternItems& tuple_items);
- void visit (TuplePatternItemsMultiple &tuple_items);
- void visit (TuplePatternItemsRanged &tuple_items);
+ void visit (TuplePatternItemsNoRest &tuple_items);
+ void visit (TuplePatternItemsHasRest &tuple_items);
void visit (TuplePattern &pattern);
void visit (GroupedPattern &pattern);
void visit (SlicePatternItemsNoRest &items);
diff --git a/gcc/rust/ast/rust-ast-formatting.h b/gcc/rust/ast/rust-ast-formatting.h
index aace93f..075c51c 100644
--- a/gcc/rust/ast/rust-ast-formatting.h
+++ b/gcc/rust/ast/rust-ast-formatting.h
@@ -19,6 +19,9 @@
#ifndef RUST_AST_FORMATTING_H
#define RUST_AST_FORMATTING_H
+#include "rust-ast.h"
+#include "rust-system.h"
+
namespace Rust {
namespace AST {
diff --git a/gcc/rust/ast/rust-ast-fragment.cc b/gcc/rust/ast/rust-ast-fragment.cc
index 076cab3..8a547b4 100644
--- a/gcc/rust/ast/rust-ast-fragment.cc
+++ b/gcc/rust/ast/rust-ast-fragment.cc
@@ -107,29 +107,42 @@ Fragment::should_expand () const
bool
Fragment::is_expression_fragment () const
{
- return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION);
+ return is_single_fragment_of_kind (SingleASTNode::Kind::Expr);
}
bool
Fragment::is_type_fragment () const
{
- return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE);
+ return is_single_fragment_of_kind (SingleASTNode::Kind::Type);
+}
+
+bool
+Fragment::is_pattern_fragment () const
+{
+ return is_single_fragment_of_kind (SingleASTNode::Kind::Pattern);
}
std::unique_ptr<Expr>
Fragment::take_expression_fragment ()
{
- assert_single_fragment (SingleASTNode::NodeType::EXPRESSION);
+ assert_single_fragment (SingleASTNode::Kind::Expr);
return nodes[0].take_expr ();
}
std::unique_ptr<Type>
Fragment::take_type_fragment ()
{
- assert_single_fragment (SingleASTNode::NodeType::TYPE);
+ assert_single_fragment (SingleASTNode::Kind::Type);
return nodes[0].take_type ();
}
+std::unique_ptr<Pattern>
+Fragment::take_pattern_fragment ()
+{
+ assert_single_fragment (SingleASTNode::Kind::Pattern);
+ return nodes[0].take_pattern ();
+}
+
void
Fragment::accept_vis (ASTVisitor &vis)
{
@@ -144,21 +157,22 @@ Fragment::is_single_fragment () const
}
bool
-Fragment::is_single_fragment_of_kind (SingleASTNode::NodeType expected) const
+Fragment::is_single_fragment_of_kind (SingleASTNode::Kind expected) const
{
return is_single_fragment () && nodes[0].get_kind () == expected;
}
void
-Fragment::assert_single_fragment (SingleASTNode::NodeType expected) const
-{
- static const std::map<SingleASTNode::NodeType, const char *> str_map = {
- {SingleASTNode::NodeType::ASSOC_ITEM, "associated item"},
- {SingleASTNode::NodeType::ITEM, "item"},
- {SingleASTNode::NodeType::TYPE, "type"},
- {SingleASTNode::NodeType::EXPRESSION, "expr"},
- {SingleASTNode::NodeType::STMT, "stmt"},
- {SingleASTNode::NodeType::EXTERN, "extern"},
+Fragment::assert_single_fragment (SingleASTNode::Kind expected) const
+{
+ static const std::map<SingleASTNode::Kind, const char *> str_map = {
+ {SingleASTNode::Kind::Assoc, "associated item"},
+ {SingleASTNode::Kind::Item, "item"},
+ {SingleASTNode::Kind::Type, "type"},
+ {SingleASTNode::Kind::Expr, "expr"},
+ {SingleASTNode::Kind::Stmt, "stmt"},
+ {SingleASTNode::Kind::Extern, "extern"},
+ {SingleASTNode::Kind::Pattern, "pattern"},
};
auto actual = nodes[0].get_kind ();
diff --git a/gcc/rust/ast/rust-ast-fragment.h b/gcc/rust/ast/rust-ast-fragment.h
index 7d01fd7..23f26d3 100644
--- a/gcc/rust/ast/rust-ast-fragment.h
+++ b/gcc/rust/ast/rust-ast-fragment.h
@@ -86,9 +86,11 @@ public:
bool is_expression_fragment () const;
bool is_type_fragment () const;
+ bool is_pattern_fragment () const;
std::unique_ptr<Expr> take_expression_fragment ();
std::unique_ptr<Type> take_type_fragment ();
+ std::unique_ptr<Pattern> take_pattern_fragment ();
void accept_vis (ASTVisitor &vis);
@@ -119,8 +121,8 @@ private:
* one Node will be extracted from the `nodes` vector
*/
bool is_single_fragment () const;
- bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const;
- void assert_single_fragment (SingleASTNode::NodeType expected) const;
+ bool is_single_fragment_of_kind (SingleASTNode::Kind expected) const;
+ void assert_single_fragment (SingleASTNode::Kind expected) const;
};
enum class InvocKind
diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h
index 09706ce..2903ba7 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -195,7 +195,6 @@ class Enum;
class Union;
class ConstantItem;
class StaticItem;
-class TraitItemConst;
class TraitItemType;
class Trait;
class Impl;
@@ -240,12 +239,12 @@ class StructPatternFieldIdent;
class StructPatternElements;
class StructPattern;
class TupleStructItems;
-class TupleStructItemsNoRange;
-class TupleStructItemsRange;
+class TupleStructItemsNoRest;
+class TupleStructItemsHasRest;
class TupleStructPattern;
class TuplePatternItems;
-class TuplePatternItemsMultiple;
-class TuplePatternItemsRanged;
+class TuplePatternItemsNoRest;
+class TuplePatternItemsHasRest;
class TuplePattern;
class GroupedPattern;
class SlicePatternItemsNoRest;
diff --git a/gcc/rust/ast/rust-ast-pointer-visitor.cc b/gcc/rust/ast/rust-ast-pointer-visitor.cc
new file mode 100644
index 0000000..ee1f001
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-pointer-visitor.cc
@@ -0,0 +1,1475 @@
+// 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-ast-pointer-visitor.h"
+#include "rust-ast-visitor.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace AST {
+
+void
+PointerVisitor::visit (AST::Crate &crate)
+{
+ visit_inner_attrs (crate);
+ for (auto &item : crate.items)
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::AttrInputMetaItemContainer &input)
+{
+ // FIXME: I think we might actually have to reseat sub-items for macro
+ // invocations within attributes correct?
+
+ for (auto &item : input.get_items ())
+ visit (item);
+}
+
+void
+PointerVisitor::visit (AST::IdentifierExpr &ident_expr)
+{
+ visit_outer_attrs (ident_expr);
+}
+
+void
+PointerVisitor::visit (AST::LifetimeParam &lifetime_param)
+{
+ visit_outer_attrs (lifetime_param);
+
+ // Nothing to do for lifetimes right?
+}
+
+void
+PointerVisitor::visit (AST::ConstGenericParam &const_param)
+{
+ visit_outer_attrs (const_param);
+ if (const_param.has_type ())
+ reseat (const_param.get_type_ptr ());
+
+ if (const_param.has_default_value ())
+ visit (const_param.get_default_value_unchecked ());
+}
+
+void
+PointerVisitor::visit (AST::PathInExpression &path)
+{
+ visit_outer_attrs (path);
+
+ if (!path.is_lang_item ())
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (GenericArgsBinding &binding)
+{
+ reseat (binding.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TypePathSegmentGeneric &segment)
+{
+ if (segment.has_generic_args ())
+ visit (segment.get_generic_args ());
+}
+
+void
+PointerVisitor::visit (AST::TypePathFunction &tpf)
+{
+ for (auto &input : tpf.get_params ())
+ reseat (input);
+ if (tpf.has_return_type ())
+ reseat (tpf.get_return_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TypePathSegmentFunction &segment)
+{
+ // FIXME: No reseating here correct? No macros possible or desugar?
+ visit (segment.get_type_path_function ());
+ visit (segment.get_ident_segment ());
+}
+
+void
+PointerVisitor::visit (AST::GenericArgs &args)
+{
+ // Nothing to do for lifetimes?
+ // for (auto &lifetime : args.get_lifetime_args ())
+ // reseat (lifetime);
+
+ // FIXME: Actually this can probably be a macro invocation, so we need to
+ // reseat them?
+ for (auto &generic : args.get_generic_args ())
+ visit (generic);
+
+ for (auto &binding : args.get_binding_args ())
+ visit (binding);
+}
+
+void
+PointerVisitor::visit (AST::PathExprSegment &segment)
+{
+ visit (segment.get_ident_segment ());
+ if (segment.has_generic_args ())
+ visit (segment.get_generic_args ());
+}
+void
+PointerVisitor::visit (AST::TypePath &path)
+{
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (AST::QualifiedPathInExpression &path)
+{
+ visit_outer_attrs (path);
+ visit (path.get_qualified_path_type ());
+
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (AST::QualifiedPathType &path)
+{
+ reseat (path.get_type_ptr ());
+ if (path.has_as_clause ())
+ visit (path.get_as_type_path ());
+}
+
+void
+PointerVisitor::visit (AST::QualifiedPathInType &path)
+{
+ visit (path.get_qualified_path_type ());
+ visit (path.get_associated_segment ());
+
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (AST::LiteralExpr &expr)
+{
+ visit_outer_attrs (expr);
+}
+
+void
+PointerVisitor::visit (AST::AttrInputLiteral &attr_input)
+{
+ visit (attr_input.get_literal ());
+}
+
+void
+PointerVisitor::visit (AST::AttrInputMacro &attr_input)
+{
+ visit (attr_input.get_macro ());
+}
+
+void
+PointerVisitor::visit (AST::MetaItemLitExpr &meta_item)
+{
+ visit (meta_item.get_literal ());
+}
+
+void
+PointerVisitor::visit (AST::SimplePath &path)
+{
+ for (auto &segment : path.get_segments ())
+ visit (segment);
+}
+
+void
+PointerVisitor::visit (AST::MetaItemPathExpr &meta_item)
+{
+ visit (meta_item.get_path ());
+ reseat (meta_item.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::BorrowExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_borrowed_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::DereferenceExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_dereferenced_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ErrorPropagationExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_propagating_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::NegationExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_negated_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ComparisonExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::LazyBooleanExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TypeCastExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_casted_expr_ptr ());
+ reseat (expr.get_type_to_cast_to_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::AssignmentExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::CompoundAssignmentExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_left_expr_ptr ());
+ reseat (expr.get_right_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::GroupedExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ reseat (expr.get_expr_in_parens_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ArrayElemsValues &elems)
+{
+ for (auto &value : elems.get_values ())
+ reseat (value);
+}
+
+void
+PointerVisitor::visit (AST::ArrayElemsCopied &elems)
+{
+ reseat (elems.get_elem_to_copy_ptr ());
+ reseat (elems.get_num_copies_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ArrayExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ visit (expr.get_array_elems ());
+}
+
+void
+PointerVisitor::visit (AST::ArrayIndexExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_array_expr_ptr ());
+ reseat (expr.get_index_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TupleExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ for (auto &elem : expr.get_tuple_elems ())
+ reseat (elem);
+}
+
+void
+PointerVisitor::visit (AST::TupleIndexExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_tuple_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructExprStruct &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ visit (expr.get_struct_name ());
+}
+
+void
+PointerVisitor::visit (AST::StructExprFieldIdentifier &field)
+{}
+
+void
+PointerVisitor::visit (AST::StructExprFieldIdentifierValue &field)
+{
+ reseat (field.get_value_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructExprFieldIndexValue &field)
+{
+ reseat (field.get_value_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructBase &base)
+{
+ reseat (base.get_base_struct_ptr ());
+}
+
+void
+PointerVisitor::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 ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::StructExprStructBase &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ visit (expr.get_struct_name ());
+ visit (expr.get_struct_base ());
+}
+
+void
+PointerVisitor::visit (AST::CallExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_function_expr_ptr ());
+ for (auto &param : expr.get_params ())
+ reseat (param);
+}
+
+void
+PointerVisitor::visit (AST::MethodCallExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_receiver_expr_ptr ());
+ visit (expr.get_method_name ());
+ for (auto &param : expr.get_params ())
+ reseat (param);
+}
+
+void
+PointerVisitor::visit (AST::FieldAccessExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_receiver_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ClosureExprInner &expr)
+{
+ visit_outer_attrs (expr);
+
+ // TODO: Actually we need to handle macro invocations as closure parameters so
+ // this needs to be a reseat
+ for (auto &param : expr.get_params ())
+ visit (param);
+
+ reseat (expr.get_definition_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::BlockExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+
+ if (expr.has_label ())
+ visit (expr.get_label ());
+
+ for (auto &stmt : expr.get_statements ())
+ reseat (stmt);
+
+ if (expr.has_tail_expr ())
+ reseat (expr.get_tail_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ConstBlock &expr)
+{
+ visit (expr.get_const_expr ());
+}
+
+void
+PointerVisitor::visit (AST::AnonConst &expr)
+{
+ if (!expr.is_deferred ())
+ reseat (expr.get_inner_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ClosureExprInnerTyped &expr)
+{
+ visit_outer_attrs (expr);
+
+ // TODO: Same as ClosureExprInner
+ for (auto &param : expr.get_params ())
+ visit (param);
+
+ reseat (expr.get_return_type_ptr ());
+
+ reseat (expr.get_definition_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ClosureParam &param)
+{
+ visit_outer_attrs (param);
+ reseat (param.get_pattern_ptr ());
+ if (param.has_type_given ())
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ContinueExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_label ())
+ visit (expr.get_label_unchecked ());
+}
+
+void
+PointerVisitor::visit (AST::BreakExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_label ())
+ visit (expr.get_label_unchecked ());
+
+ if (expr.has_break_expr ())
+ reseat (expr.get_break_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeFromToExpr &expr)
+{
+ reseat (expr.get_from_expr_ptr ());
+ reseat (expr.get_to_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeFromExpr &expr)
+{
+ reseat (expr.get_from_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeToExpr &expr)
+{
+ reseat (expr.get_to_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeFullExpr &expr)
+{}
+
+void
+PointerVisitor::visit (AST::RangeFromToInclExpr &expr)
+{
+ reseat (expr.get_from_expr_ptr ());
+ reseat (expr.get_to_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangeToInclExpr &expr)
+{
+ reseat (expr.get_to_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ReturnExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_returned_expr ())
+ reseat (expr.get_returned_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TryExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_block_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::BoxExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_boxed_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::UnsafeBlockExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_block_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::LoopLabel &label)
+{
+ visit (label.get_lifetime ());
+}
+
+void
+PointerVisitor::visit (AST::LoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
+ reseat (expr.get_loop_block_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::WhileLoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
+ reseat (expr.get_predicate_expr_ptr ());
+ reseat (expr.get_loop_block_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::WhileLetLoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+ for (auto &pattern : expr.get_patterns ())
+ reseat (pattern);
+
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
+
+ reseat (expr.get_scrutinee_expr_ptr ());
+ reseat (expr.get_loop_block_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ForLoopExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_pattern_ptr ());
+ reseat (expr.get_iterator_expr_ptr ());
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
+ reseat (expr.get_loop_block_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::IfExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_condition_expr_ptr ());
+ visit (expr.get_if_block ());
+}
+
+void
+PointerVisitor::visit (AST::IfExprConseqElse &expr)
+{
+ visit (reinterpret_cast<AST::IfExpr &> (expr));
+ visit (expr.get_else_block ());
+}
+
+void
+PointerVisitor::visit (AST::IfLetExpr &expr)
+{
+ visit_outer_attrs (expr);
+ for (auto &pattern : expr.get_patterns ())
+ reseat (pattern);
+ reseat (expr.get_value_expr_ptr ());
+ visit (expr.get_if_block ());
+}
+
+void
+PointerVisitor::visit (AST::IfLetExprConseqElse &expr)
+{
+ visit (reinterpret_cast<AST::IfLetExpr &> (expr));
+ visit (expr.get_else_block ());
+}
+
+void
+PointerVisitor::visit (AST::MatchArm &arm)
+{
+ visit_outer_attrs (arm);
+ for (auto &pattern : arm.get_patterns ())
+ reseat (pattern);
+ if (arm.has_match_arm_guard ())
+ reseat (arm.get_guard_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::MatchCase &arm)
+{
+ visit (arm.get_arm ());
+ reseat (arm.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::MatchExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit_inner_attrs (expr);
+ reseat (expr.get_scrutinee_expr_ptr ());
+ for (auto &arm : expr.get_match_cases ())
+ visit (arm);
+}
+
+void
+PointerVisitor::visit (AST::AwaitExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_awaited_expr ());
+}
+
+void
+PointerVisitor::visit (AST::AsyncBlockExpr &expr)
+{
+ visit_outer_attrs (expr);
+ reseat (expr.get_block_expr ());
+}
+
+void
+PointerVisitor::visit (AST::InlineAsm &expr)
+{
+ visit_outer_attrs (expr);
+ using RegisterType = AST::InlineAsmOperand::RegisterType;
+ for (auto &operand : expr.get_operands ())
+ {
+ switch (operand.get_register_type ())
+ {
+ case RegisterType::In:
+ {
+ reseat (operand.get_in ().expr);
+ break;
+ }
+ case RegisterType::Out:
+ {
+ reseat (operand.get_out ().expr);
+ break;
+ }
+ case RegisterType::InOut:
+ {
+ reseat (operand.get_in_out ().expr);
+ break;
+ }
+ case RegisterType::SplitInOut:
+ {
+ auto split = operand.get_split_in_out ();
+ reseat (split.in_expr);
+ reseat (split.out_expr);
+ break;
+ }
+ case RegisterType::Const:
+ {
+ reseat (operand.get_const ().anon_const.get_inner_expr_ptr ());
+ break;
+ }
+ case RegisterType::Sym:
+ {
+ reseat (operand.get_sym ().expr);
+ break;
+ }
+ case RegisterType::Label:
+ {
+ reseat (operand.get_label ().expr);
+ break;
+ }
+ }
+ }
+}
+
+void
+PointerVisitor::visit (AST::LlvmInlineAsm &expr)
+{
+ for (auto &output : expr.get_outputs ())
+ reseat (output.expr);
+
+ for (auto &input : expr.get_inputs ())
+ reseat (input.expr);
+}
+
+void
+PointerVisitor::visit (AST::TypeParam &param)
+{
+ visit_outer_attrs (param);
+ // FIXME: Can we do macro expansion here?
+ for (auto &bound : param.get_type_param_bounds ())
+ visit (bound);
+ if (param.has_type ())
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::LifetimeWhereClauseItem &item)
+{
+ visit (item.get_lifetime ());
+ for (auto &bound : item.get_lifetime_bounds ())
+ visit (bound);
+}
+
+void
+PointerVisitor::visit (AST::TypeBoundWhereClauseItem &item)
+{
+ for (auto &lifetime : item.get_for_lifetimes ())
+ visit (lifetime);
+ reseat (item.get_type_ptr ());
+ // FIXME: Likewise?
+ for (auto &param : item.get_type_param_bounds ())
+ visit (param);
+}
+
+void
+PointerVisitor::visit (AST::Visibility &vis)
+{
+ if (vis.has_path ())
+ visit (vis.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::WhereClause &where)
+{
+ for (auto &item : where.get_items ())
+ visit (item);
+}
+
+void
+PointerVisitor::visit (AST::FunctionParam &param)
+{
+ visit_outer_attrs (param);
+ if (param.has_name ())
+ reseat (param.get_pattern_ptr ());
+
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::SelfParam &param)
+{
+ visit_outer_attrs (param);
+
+ if (param.has_lifetime ())
+ visit (param.get_lifetime ());
+
+ if (param.has_type ())
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::Module &module)
+{
+ visit_outer_attrs (module);
+ visit (module.get_visibility ());
+ visit_inner_attrs (module);
+ for (auto &item : module.get_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::ExternCrate &crate)
+{
+ visit_outer_attrs (crate);
+ visit (crate.get_visibility ());
+}
+
+void
+PointerVisitor::visit (AST::UseTreeGlob &use_tree)
+{
+ visit (use_tree.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::UseTreeList &use_tree)
+{
+ visit (use_tree.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::UseTreeRebind &use_tree)
+{
+ visit (use_tree.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::UseDeclaration &use_decl)
+{
+ visit (use_decl.get_visibility ());
+ visit (use_decl.get_tree ());
+}
+
+void
+PointerVisitor::visit_function_params (AST::Function &function)
+{
+ for (auto &param : function.get_function_params ())
+ visit (param);
+}
+
+void
+PointerVisitor::visit (AST::Function &function)
+{
+ visit_outer_attrs (function);
+ visit (function.get_visibility ());
+ visit (function.get_qualifiers ());
+ for (auto &generic : function.get_generic_params ())
+ visit (generic);
+
+ visit_function_params (function);
+
+ if (function.has_return_type ())
+ reseat (function.get_return_type_ptr ());
+ if (function.has_where_clause ())
+ visit (function.get_where_clause ());
+ if (function.has_body ())
+ reseat (*function.get_definition ());
+}
+
+void
+PointerVisitor::visit (AST::TypeAlias &type_alias)
+{
+ visit_outer_attrs (type_alias);
+ visit (type_alias.get_visibility ());
+ for (auto &generic : type_alias.get_generic_params ())
+ visit (generic);
+ if (type_alias.has_where_clause ())
+ visit (type_alias.get_where_clause ());
+ reseat (type_alias.get_type_aliased_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructField &field)
+{
+ visit_outer_attrs (field);
+ visit (field.get_visibility ());
+ reseat (field.get_field_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructStruct &struct_item)
+{
+ visit_outer_attrs (struct_item);
+ visit (struct_item.get_visibility ());
+ for (auto &generic : struct_item.get_generic_params ())
+ visit (generic);
+ if (struct_item.has_where_clause ())
+ visit (struct_item.get_where_clause ());
+ for (auto &field : struct_item.get_fields ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::TupleField &field)
+{
+ visit_outer_attrs (field);
+ visit (field.get_visibility ());
+ reseat (field.get_field_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TupleStruct &tuple_struct)
+{
+ visit_outer_attrs (tuple_struct);
+ visit (tuple_struct.get_visibility ());
+ for (auto &generic : tuple_struct.get_generic_params ())
+ visit (generic);
+ if (tuple_struct.has_where_clause ())
+ visit (tuple_struct.get_where_clause ());
+ for (auto &field : tuple_struct.get_fields ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::EnumItem &item)
+{
+ visit_outer_attrs (item);
+ visit (item.get_visibility ());
+}
+
+void
+PointerVisitor::visit (AST::EnumItemTuple &item)
+{
+ PointerVisitor::visit (static_cast<EnumItem &> (item));
+ for (auto &field : item.get_tuple_fields ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::EnumItemStruct &item)
+{
+ PointerVisitor::visit (static_cast<EnumItem &> (item));
+ for (auto &field : item.get_struct_fields ())
+ visit (field);
+}
+
+void
+PointerVisitor::visit (AST::EnumItemDiscriminant &item)
+{
+ PointerVisitor::visit (static_cast<EnumItem &> (item));
+ reseat (item.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::Enum &enum_item)
+{
+ visit_outer_attrs (enum_item);
+ visit (enum_item.get_visibility ());
+ for (auto &generic : enum_item.get_generic_params ())
+ visit (generic);
+ if (enum_item.has_where_clause ())
+ visit (enum_item.get_where_clause ());
+ for (auto &item : enum_item.get_variants ())
+ visit (item);
+}
+
+void
+PointerVisitor::visit (AST::Union &union_item)
+{
+ visit_outer_attrs (union_item);
+ visit (union_item.get_visibility ());
+ for (auto &generic : union_item.get_generic_params ())
+ visit (generic);
+ if (union_item.has_where_clause ())
+ visit (union_item.get_where_clause ());
+ for (auto &variant : union_item.get_variants ())
+ visit (variant);
+}
+
+void
+PointerVisitor::visit (AST::ConstantItem &const_item)
+{
+ visit_outer_attrs (const_item);
+ visit (const_item.get_visibility ());
+ reseat (const_item.get_type_ptr ());
+ if (const_item.has_expr ())
+ reseat (const_item.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StaticItem &static_item)
+{
+ visit_outer_attrs (static_item);
+ visit (static_item.get_visibility ());
+ reseat (static_item.get_type_ptr ());
+ reseat (static_item.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TraitItemType &item)
+{
+ visit_outer_attrs (item);
+ for (auto &bound : item.get_type_param_bounds ())
+ visit (bound);
+}
+
+void
+PointerVisitor::visit (AST::Trait &trait)
+{
+ visit_outer_attrs (trait);
+ visit (trait.get_visibility ());
+
+ visit_inner_attrs (trait);
+
+ visit (trait.get_implicit_self ());
+
+ for (auto &generic : trait.get_generic_params ())
+ visit (generic);
+
+ if (trait.has_where_clause ())
+ visit (trait.get_where_clause ());
+
+ for (auto &bound : trait.get_type_param_bounds ())
+ visit (bound);
+
+ for (auto &item : trait.get_trait_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::InherentImpl &impl)
+{
+ visit_outer_attrs (impl);
+ visit (impl.get_visibility ());
+
+ for (auto &generic : impl.get_generic_params ())
+ visit (generic);
+ if (impl.has_where_clause ())
+ visit (impl.get_where_clause ());
+ reseat (impl.get_type_ptr ());
+ visit_inner_attrs (impl);
+ for (auto &item : impl.get_impl_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::TraitImpl &impl)
+{
+ visit_outer_attrs (impl);
+ visit (impl.get_visibility ());
+
+ for (auto &generic : impl.get_generic_params ())
+ visit (generic);
+ if (impl.has_where_clause ())
+ visit (impl.get_where_clause ());
+ reseat (impl.get_type_ptr ());
+ visit (impl.get_trait_path ());
+ visit_inner_attrs (impl);
+ for (auto &item : impl.get_impl_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::ExternalTypeItem &item)
+{
+ visit_outer_attrs (item);
+ visit (item.get_visibility ());
+}
+
+void
+PointerVisitor::visit (AST::ExternalStaticItem &item)
+{
+ visit_outer_attrs (item);
+ visit (item.get_visibility ());
+ reseat (item.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ExternBlock &block)
+{
+ visit_outer_attrs (block);
+ visit (block.get_visibility ());
+ visit_inner_attrs (block);
+ for (auto &item : block.get_extern_items ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::MacroMatchFragment &match)
+{}
+
+void
+PointerVisitor::visit (AST::MacroMatchRepetition &match)
+{
+ for (auto &m : match.get_matches ())
+ visit (m);
+}
+
+void
+PointerVisitor::visit (AST::MacroMatcher &matcher)
+{
+ for (auto &m : matcher.get_matches ())
+ visit (m);
+}
+
+void
+PointerVisitor::visit (AST::MacroTranscriber &transcriber)
+{
+ visit (transcriber.get_token_tree ());
+}
+
+void
+PointerVisitor::visit (AST::MacroRule &rule)
+{
+ visit (rule.get_matcher ());
+ visit (rule.get_transcriber ());
+}
+
+void
+PointerVisitor::visit (AST::MacroRulesDefinition &rules_def)
+{
+ visit_outer_attrs (rules_def);
+ for (auto &rule : rules_def.get_macro_rules ())
+ visit (rule);
+}
+
+void
+PointerVisitor::visit (AST::MacroInvocData &data)
+{
+ visit (data.get_path ());
+ visit (data.get_delim_tok_tree ());
+}
+
+void
+PointerVisitor::visit (AST::MacroInvocation &macro_invoc)
+{
+ visit_outer_attrs (macro_invoc);
+ visit (macro_invoc.get_invoc_data ());
+}
+
+void
+PointerVisitor::visit (AST::MetaItemPath &meta_item)
+{
+ visit (meta_item.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::MetaItemSeq &meta_item)
+{
+ visit (meta_item.get_path ());
+ for (auto &inner : meta_item.get_seq ())
+ visit (inner);
+}
+
+void
+PointerVisitor::visit (AST::MetaListPaths &meta_item)
+{
+ for (auto &path : meta_item.get_paths ())
+ visit (path);
+}
+
+void
+PointerVisitor::visit (AST::MetaListNameValueStr &meta_item)
+{
+ for (auto &str : meta_item.get_values ())
+ visit (str);
+}
+
+void
+PointerVisitor::visit (AST::IdentifierPattern &pattern)
+{
+ if (pattern.has_subpattern ())
+ reseat (pattern.get_subpattern_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::RangePatternBoundPath &bound)
+{
+ visit (bound.get_path ());
+}
+
+void
+PointerVisitor::visit (AST::RangePatternBoundQualPath &bound)
+{
+ visit (bound.get_qualified_path ());
+}
+
+void
+PointerVisitor::visit (AST::RangePattern &pattern)
+{
+ // FIXME: So should this be reseat() instead? Can we have macro invocations as
+ // patterns in range patterns?
+ if (pattern.get_has_lower_bound ())
+ visit (pattern.get_lower_bound ());
+ if (pattern.get_has_upper_bound ())
+ visit (pattern.get_upper_bound ());
+}
+
+void
+PointerVisitor::visit (AST::ReferencePattern &pattern)
+{
+ reseat (pattern.get_referenced_pattern_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructPatternFieldTuplePat &field)
+{
+ visit_outer_attrs (field);
+ reseat (field.get_index_pattern_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructPatternFieldIdentPat &field)
+{
+ visit_outer_attrs (field);
+ reseat (field.get_ident_pattern_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::StructPatternFieldIdent &field)
+{
+ visit_outer_attrs (field);
+}
+
+void
+PointerVisitor::visit (AST::StructPatternElements &spe)
+{
+ for (auto &field : spe.get_struct_pattern_fields ())
+ visit (field);
+ for (auto &attribute : spe.get_etc_outer_attrs ())
+ visit (attribute);
+}
+
+void
+PointerVisitor::visit (AST::StructPattern &pattern)
+{
+ visit (pattern.get_path ());
+ visit (pattern.get_struct_pattern_elems ());
+}
+
+void
+PointerVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
+{
+ for (auto &pattern : tuple_items.get_patterns ())
+ reseat (pattern);
+}
+
+void
+PointerVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
+{
+ for (auto &lower : tuple_items.get_lower_patterns ())
+ reseat (lower);
+ for (auto &upper : tuple_items.get_upper_patterns ())
+ reseat (upper);
+}
+
+void
+PointerVisitor::visit (AST::TupleStructPattern &pattern)
+{
+ visit (pattern.get_path ());
+ visit (pattern.get_items ());
+}
+
+void
+PointerVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
+{
+ for (auto &pattern : tuple_items.get_patterns ())
+ reseat (pattern);
+}
+
+void
+PointerVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items)
+{
+ for (auto &lower : tuple_items.get_lower_patterns ())
+ reseat (lower);
+ for (auto &upper : tuple_items.get_upper_patterns ())
+ reseat (upper);
+}
+
+void
+PointerVisitor::visit (AST::TuplePattern &pattern)
+{
+ visit (pattern.get_items ());
+}
+
+void
+PointerVisitor::visit (AST::GroupedPattern &pattern)
+{
+ reseat (pattern.get_pattern_in_parens_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::SlicePatternItemsNoRest &items)
+{
+ for (auto &item : items.get_patterns ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::SlicePatternItemsHasRest &items)
+{
+ for (auto &item : items.get_lower_patterns ())
+ reseat (item);
+ for (auto &item : items.get_upper_patterns ())
+ reseat (item);
+}
+
+void
+PointerVisitor::visit (AST::SlicePattern &pattern)
+{
+ visit (pattern.get_items ());
+}
+
+void
+PointerVisitor::visit (AST::AltPattern &pattern)
+{
+ for (auto &alt : pattern.get_alts ())
+ reseat (alt);
+}
+
+void
+PointerVisitor::visit (AST::EmptyStmt &stmt)
+{}
+
+void
+PointerVisitor::visit (AST::LetStmt &stmt)
+{
+ visit_outer_attrs (stmt);
+ reseat (stmt.get_pattern_ptr ());
+ if (stmt.has_type ())
+ reseat (stmt.get_type_ptr ());
+ if (stmt.has_init_expr ())
+ reseat (stmt.get_init_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ExprStmt &stmt)
+{
+ reseat (stmt.get_expr_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::TraitBound &bound)
+{
+ for (auto &lifetime : bound.get_for_lifetimes ())
+ visit (lifetime);
+ visit (bound.get_type_path ());
+}
+
+void
+PointerVisitor::visit (AST::ImplTraitType &type)
+{
+ for (auto &bound : type.get_type_param_bounds ())
+ visit (bound);
+}
+
+void
+PointerVisitor::visit (AST::TraitObjectType &type)
+{
+ for (auto &bound : type.get_type_param_bounds ())
+ visit (bound);
+}
+
+void
+PointerVisitor::visit (AST::ParenthesisedType &type)
+{
+ reseat (type.get_type_in_parens ());
+}
+
+void
+PointerVisitor::visit (AST::ImplTraitTypeOneBound &type)
+{
+ // FIXME: Do we need to reseat here?
+ visit (type.get_trait_bound ());
+}
+
+void
+PointerVisitor::visit (AST::TraitObjectTypeOneBound &type)
+{
+ // FIXME: Do we need to reseat here?
+ visit (type.get_trait_bound ());
+}
+
+void
+PointerVisitor::visit (AST::TupleType &type)
+{
+ for (auto &elem : type.get_elems ())
+ reseat (elem);
+}
+
+void
+PointerVisitor::visit (AST::NeverType &type)
+{}
+
+void
+PointerVisitor::visit (AST::RawPointerType &type)
+{
+ reseat (type.get_type_pointed_to_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ReferenceType &type)
+{
+ visit (type.get_lifetime ());
+ reseat (type.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::ArrayType &type)
+{
+ reseat (type.get_elem_type_ptr ());
+ visit (type.get_size_expr ());
+}
+
+void
+PointerVisitor::visit (AST::SliceType &type)
+{
+ reseat (type.get_elem_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::InferredType &type)
+{}
+
+void
+PointerVisitor::visit (AST::MaybeNamedParam &param)
+{
+ visit_outer_attrs (param);
+ reseat (param.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::BareFunctionType &type)
+{
+ for (auto &lifetime : type.get_for_lifetimes ())
+ visit (lifetime);
+ visit (type.get_function_qualifiers ());
+ for (auto &param : type.get_function_params ())
+ visit (param);
+ if (type.is_variadic ())
+ for (auto attr : type.get_variadic_attr ())
+ visit (attr);
+ if (type.has_return_type ())
+ reseat (type.get_return_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::FormatArgs &)
+{
+ // FIXME: Do we have anything to do? any subnodes to visit? Probably, right?
+}
+
+void
+PointerVisitor::visit (AST::OffsetOf &offset_of)
+{
+ reseat (offset_of.get_type_ptr ());
+}
+
+void
+PointerVisitor::visit (AST::VariadicParam &param)
+{
+ if (param.has_pattern ())
+ reseat (param.get_pattern_ptr ());
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-pointer-visitor.h b/gcc/rust/ast/rust-ast-pointer-visitor.h
new file mode 100644
index 0000000..8c12b4e
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-pointer-visitor.h
@@ -0,0 +1,234 @@
+// 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_AST_POINTER_VISITOR_H
+#define RUST_AST_POINTER_VISITOR_H
+
+#include "rust-ast-visitor.h"
+#include "rust-ast.h"
+#include "rust-item.h"
+
+namespace Rust {
+namespace AST {
+
+/**
+ * Regular AST visitor which may reseat pointers when necessary.
+ */
+class PointerVisitor : public DefaultASTVisitor
+{
+public:
+ using DefaultASTVisitor::visit;
+
+ virtual void reseat (std::unique_ptr<AST::Expr> &ptr) { visit (ptr); }
+ virtual void reseat (std::unique_ptr<AST::BlockExpr> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::Stmt> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::Item> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::AssociatedItem> &ptr)
+ {
+ visit (ptr);
+ }
+
+ virtual void reseat (std::unique_ptr<AST::ExternalItem> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::Type> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::TypeNoBounds> &ptr) { visit (ptr); }
+
+ virtual void reseat (std::unique_ptr<AST::Pattern> &ptr) { visit (ptr); }
+
+ void visit (AST::Crate &crate) override;
+ void visit (AST::AttrInputMetaItemContainer &input) override;
+ void visit (AST::IdentifierExpr &ident_expr) override;
+ void visit (AST::LifetimeParam &lifetime_param) override;
+ void visit (AST::ConstGenericParam &const_param) override;
+ void visit (AST::PathInExpression &path) override;
+ void visit (GenericArgsBinding &binding) override;
+ void visit (AST::TypePathSegmentGeneric &segment) override;
+ void visit (AST::TypePathFunction &tpf) override;
+ void visit (AST::TypePathSegmentFunction &segment) override;
+ void visit (AST::GenericArgs &args) override;
+ void visit (AST::PathExprSegment &segment) override;
+ void visit (AST::TypePath &path) override;
+ void visit (AST::QualifiedPathInExpression &path) override;
+ void visit (AST::QualifiedPathType &path) override;
+ void visit (AST::QualifiedPathInType &path) override;
+ void visit (AST::LiteralExpr &expr) override;
+ void visit (AST::AttrInputLiteral &attr_input) override;
+ void visit (AST::AttrInputMacro &attr_input) override;
+ void visit (AST::MetaItemLitExpr &meta_item) override;
+ void visit (AST::SimplePath &path) override;
+ void visit (AST::MetaItemPathExpr &meta_item) override;
+ void visit (AST::BorrowExpr &expr) override;
+ void visit (AST::DereferenceExpr &expr) override;
+ void visit (AST::ErrorPropagationExpr &expr) override;
+ void visit (AST::NegationExpr &expr) override;
+ void visit (AST::ArithmeticOrLogicalExpr &expr) override;
+ void visit (AST::ComparisonExpr &expr) override;
+ void visit (AST::LazyBooleanExpr &expr) override;
+ void visit (AST::TypeCastExpr &expr) override;
+ void visit (AST::AssignmentExpr &expr) override;
+ void visit (AST::CompoundAssignmentExpr &expr) override;
+ void visit (AST::GroupedExpr &expr) override;
+ void visit (AST::ArrayElemsValues &elems) override;
+ void visit (AST::ArrayElemsCopied &elems) override;
+ void visit (AST::ArrayExpr &expr) override;
+ void visit (AST::ArrayIndexExpr &expr) override;
+ void visit (AST::TupleExpr &expr) override;
+ void visit (AST::TupleIndexExpr &expr) override;
+ void visit (AST::StructExprStruct &expr) override;
+ void visit (AST::StructExprFieldIdentifier &field) override;
+ void visit (AST::StructExprFieldIdentifierValue &field) override;
+ void visit (AST::StructExprFieldIndexValue &field) override;
+ void visit (AST::StructBase &base) override;
+ void visit (AST::StructExprStructFields &expr) override;
+ void visit (AST::StructExprStructBase &expr) override;
+ void visit (AST::CallExpr &expr) override;
+ void visit (AST::MethodCallExpr &expr) override;
+ void visit (AST::FieldAccessExpr &expr) override;
+ void visit (AST::ClosureExprInner &expr) override;
+ void visit (AST::BlockExpr &expr) override;
+ void visit (AST::ConstBlock &expr) override;
+ void visit (AST::AnonConst &expr) override;
+ void visit (AST::ClosureExprInnerTyped &expr) override;
+ void visit (AST::ClosureParam &param) override;
+ void visit (AST::ContinueExpr &expr) override;
+ void visit (AST::BreakExpr &expr) override;
+ void visit (AST::RangeFromToExpr &expr) override;
+ void visit (AST::RangeFromExpr &expr) override;
+ void visit (AST::RangeToExpr &expr) override;
+ void visit (AST::RangeFullExpr &expr) override;
+ void visit (AST::RangeFromToInclExpr &expr) override;
+ void visit (AST::RangeToInclExpr &expr) override;
+ void visit (AST::ReturnExpr &expr) override;
+ void visit (AST::TryExpr &expr) override;
+ void visit (AST::BoxExpr &expr) override;
+ void visit (AST::UnsafeBlockExpr &expr) override;
+ void visit (AST::LoopLabel &label) override;
+ void visit (AST::LoopExpr &expr) override;
+ void visit (AST::WhileLoopExpr &expr) override;
+ void visit (AST::WhileLetLoopExpr &expr) override;
+ void visit (AST::ForLoopExpr &expr) override;
+ void visit (AST::IfExpr &expr) override;
+ void visit (AST::IfExprConseqElse &expr) override;
+ void visit (AST::IfLetExpr &expr) override;
+ void visit (AST::IfLetExprConseqElse &expr) override;
+ void visit (AST::MatchArm &arm) override;
+ void visit (AST::MatchCase &arm) override;
+ void visit (AST::MatchExpr &expr) override;
+ void visit (AST::AwaitExpr &expr) override;
+ void visit (AST::AsyncBlockExpr &expr) override;
+ void visit (AST::InlineAsm &expr) override;
+ void visit (AST::LlvmInlineAsm &expr) override;
+ void visit (AST::TypeParam &param) override;
+ void visit (AST::LifetimeWhereClauseItem &item) override;
+ void visit (AST::TypeBoundWhereClauseItem &item) override;
+ void visit (AST::Visibility &vis) override;
+ void visit (AST::WhereClause &where) override;
+ void visit (AST::FunctionParam &param) override;
+ void visit (AST::SelfParam &param) override;
+ void visit (AST::Module &module) override;
+ void visit (AST::ExternCrate &crate) override;
+ void visit (AST::UseTreeGlob &use_tree) override;
+ void visit (AST::UseTreeList &use_tree) override;
+ void visit (AST::UseTreeRebind &use_tree) override;
+ void visit (AST::UseDeclaration &use_decl) override;
+ void visit_function_params (AST::Function &function) override;
+ void visit (AST::Function &function) override;
+ void visit (AST::TypeAlias &type_alias) override;
+ void visit (AST::StructField &field) override;
+ void visit (AST::StructStruct &struct_item) override;
+ void visit (AST::TupleField &field) override;
+ void visit (AST::TupleStruct &tuple_struct) override;
+ void visit (AST::EnumItem &item) override;
+ void visit (AST::EnumItemTuple &item) override;
+ void visit (AST::EnumItemStruct &item) override;
+ void visit (AST::EnumItemDiscriminant &item) override;
+ void visit (AST::Enum &enum_item) override;
+ void visit (AST::Union &union_item) override;
+ void visit (AST::ConstantItem &const_item) override;
+ void visit (AST::StaticItem &static_item) override;
+ void visit (AST::TraitItemType &item) override;
+ void visit (AST::Trait &trait) override;
+ void visit (AST::InherentImpl &impl) override;
+ void visit (AST::TraitImpl &impl) override;
+ void visit (AST::ExternalTypeItem &item) override;
+ void visit (AST::ExternalStaticItem &item) override;
+ void visit (AST::ExternBlock &block) override;
+ void visit (AST::MacroMatchFragment &match) override;
+ void visit (AST::MacroMatchRepetition &match) override;
+ void visit (AST::MacroMatcher &matcher) override;
+ void visit (AST::MacroTranscriber &transcriber) override;
+ void visit (AST::MacroRule &rule) override;
+ void visit (AST::MacroRulesDefinition &rules_def) override;
+ void visit (AST::MacroInvocData &data) override;
+ void visit (AST::MacroInvocation &macro_invoc) override;
+ void visit (AST::MetaItemPath &meta_item) override;
+ void visit (AST::MetaItemSeq &meta_item) override;
+ void visit (AST::MetaListPaths &meta_item) override;
+ void visit (AST::MetaListNameValueStr &meta_item) override;
+ void visit (AST::IdentifierPattern &pattern) override;
+ void visit (AST::RangePatternBoundPath &bound) override;
+ void visit (AST::RangePatternBoundQualPath &bound) override;
+ void visit (AST::RangePattern &pattern) override;
+ void visit (AST::ReferencePattern &pattern) override;
+ void visit (AST::StructPatternFieldTuplePat &field) override;
+ void visit (AST::StructPatternFieldIdentPat &field) override;
+ void visit (AST::StructPatternFieldIdent &field) override;
+ void visit (AST::StructPatternElements &spe) override;
+ void visit (AST::StructPattern &pattern) override;
+ void visit (AST::TupleStructItemsNoRest &tuple_items) override;
+ void visit (AST::TupleStructItemsHasRest &tuple_items) override;
+ void visit (AST::TupleStructPattern &pattern) override;
+ void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
+ void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
+ void visit (AST::TuplePattern &pattern) override;
+ void visit (AST::GroupedPattern &pattern) override;
+ void visit (AST::SlicePatternItemsNoRest &items) override;
+ void visit (AST::SlicePatternItemsHasRest &items) override;
+ void visit (AST::SlicePattern &pattern) override;
+ void visit (AST::AltPattern &pattern) override;
+ void visit (AST::EmptyStmt &stmt) override;
+ void visit (AST::LetStmt &stmt) override;
+ void visit (AST::ExprStmt &stmt) override;
+ void visit (AST::TraitBound &bound) override;
+ void visit (AST::ImplTraitType &type) override;
+ void visit (AST::TraitObjectType &type) override;
+ void visit (AST::ParenthesisedType &type) override;
+ void visit (AST::ImplTraitTypeOneBound &type) override;
+ void visit (AST::TraitObjectTypeOneBound &type) override;
+ void visit (AST::TupleType &type) override;
+ void visit (AST::NeverType &type) override;
+ void visit (AST::RawPointerType &type) override;
+ void visit (AST::ReferenceType &type) override;
+ void visit (AST::ArrayType &type) override;
+ void visit (AST::SliceType &type) override;
+ void visit (AST::InferredType &type) override;
+ void visit (AST::MaybeNamedParam &param) override;
+ void visit (AST::BareFunctionType &type) override;
+ void visit (AST::FormatArgs &) override;
+ void visit (AST::OffsetOf &offset_of) override;
+ void visit (AST::VariadicParam &param) override;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index ab8cdbe..afdd2b1 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -248,6 +248,7 @@ void
DefaultASTVisitor::visit (AST::ErrorPropagationExpr &expr)
{
visit_outer_attrs (expr);
+ visit (expr.get_propagating_expr ());
}
void
@@ -1025,15 +1026,6 @@ DefaultASTVisitor::visit (AST::StaticItem &static_item)
}
void
-DefaultASTVisitor::visit (AST::TraitItemConst &item)
-{
- visit_outer_attrs (item);
- visit (item.get_type ());
- if (item.has_expr ())
- visit (item.get_expr ());
-}
-
-void
DefaultASTVisitor::visit (AST::TraitItemType &item)
{
visit_outer_attrs (item);
@@ -1296,14 +1288,14 @@ DefaultASTVisitor::visit (AST::StructPattern &pattern)
}
void
-DefaultASTVisitor::visit (AST::TupleStructItemsNoRange &tuple_items)
+DefaultASTVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
{
for (auto &pattern : tuple_items.get_patterns ())
visit (pattern);
}
void
-DefaultASTVisitor::visit (AST::TupleStructItemsRange &tuple_items)
+DefaultASTVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
{
for (auto &lower : tuple_items.get_lower_patterns ())
visit (lower);
@@ -1319,14 +1311,14 @@ DefaultASTVisitor::visit (AST::TupleStructPattern &pattern)
}
void
-DefaultASTVisitor::visit (AST::TuplePatternItemsMultiple &tuple_items)
+DefaultASTVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
{
for (auto &pattern : tuple_items.get_patterns ())
visit (pattern);
}
void
-DefaultASTVisitor::visit (AST::TuplePatternItemsRanged &tuple_items)
+DefaultASTVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items)
{
for (auto &lower : tuple_items.get_lower_patterns ())
visit (lower);
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 2d81aa1..a7a2ac4 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -164,7 +164,6 @@ public:
virtual void visit (Union &union_item) = 0;
virtual void visit (ConstantItem &const_item) = 0;
virtual void visit (StaticItem &static_item) = 0;
- virtual void visit (TraitItemConst &item) = 0;
virtual void visit (TraitItemType &item) = 0;
virtual void visit (Trait &trait) = 0;
virtual void visit (InherentImpl &impl) = 0;
@@ -204,12 +203,12 @@ public:
virtual void visit (StructPatternFieldIdent &field) = 0;
virtual void visit (StructPattern &pattern) = 0;
// virtual void visit(TupleStructItems& tuple_items) = 0;
- virtual void visit (TupleStructItemsNoRange &tuple_items) = 0;
- virtual void visit (TupleStructItemsRange &tuple_items) = 0;
+ virtual void visit (TupleStructItemsNoRest &tuple_items) = 0;
+ virtual void visit (TupleStructItemsHasRest &tuple_items) = 0;
virtual void visit (TupleStructPattern &pattern) = 0;
// virtual void visit(TuplePatternItems& tuple_items) = 0;
- virtual void visit (TuplePatternItemsMultiple &tuple_items) = 0;
- virtual void visit (TuplePatternItemsRanged &tuple_items) = 0;
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) = 0;
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) = 0;
virtual void visit (TuplePattern &pattern) = 0;
virtual void visit (GroupedPattern &pattern) = 0;
virtual void visit (SlicePatternItemsNoRest &items) = 0;
@@ -349,7 +348,6 @@ public:
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;
@@ -381,11 +379,11 @@ public:
virtual void visit (AST::StructPatternFieldIdentPat &field) override;
virtual void visit (AST::StructPatternFieldIdent &field) override;
virtual void visit (AST::StructPattern &pattern) override;
- virtual void visit (AST::TupleStructItemsNoRange &tuple_items) override;
- virtual void visit (AST::TupleStructItemsRange &tuple_items) override;
+ virtual void visit (AST::TupleStructItemsNoRest &tuple_items) override;
+ virtual void visit (AST::TupleStructItemsHasRest &tuple_items) override;
virtual void visit (AST::TupleStructPattern &pattern) override;
- virtual void visit (AST::TuplePatternItemsMultiple &tuple_items) override;
- virtual void visit (AST::TuplePatternItemsRanged &tuple_items) override;
+ virtual void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
+ virtual void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
virtual void visit (AST::TuplePattern &pattern) override;
virtual void visit (AST::GroupedPattern &pattern) override;
virtual void visit (AST::SlicePatternItemsNoRest &items) override;
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 8e856fb..337a338 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -48,29 +48,33 @@ SingleASTNode::SingleASTNode (SingleASTNode const &other)
kind = other.kind;
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
expr = other.expr->clone_expr ();
break;
- case ITEM:
+ case Kind::Item:
item = other.item->clone_item ();
break;
- case STMT:
+ case Kind::Stmt:
stmt = other.stmt->clone_stmt ();
break;
- case EXTERN:
+ case Kind::Extern:
external_item = other.external_item->clone_external_item ();
break;
- case ASSOC_ITEM:
+ case Kind::Assoc:
assoc_item = other.assoc_item->clone_associated_item ();
break;
- case TYPE:
+ case Kind::Type:
type = other.type->clone_type ();
break;
+
+ case Kind::Pattern:
+ pattern = other.pattern->clone_pattern ();
+ break;
}
}
@@ -80,29 +84,33 @@ SingleASTNode::operator= (SingleASTNode const &other)
kind = other.kind;
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
expr = other.expr->clone_expr ();
break;
- case ITEM:
+ case Kind::Item:
item = other.item->clone_item ();
break;
- case STMT:
+ case Kind::Stmt:
stmt = other.stmt->clone_stmt ();
break;
- case EXTERN:
+ case Kind::Extern:
external_item = other.external_item->clone_external_item ();
break;
- case ASSOC_ITEM:
+ case Kind::Assoc:
assoc_item = other.assoc_item->clone_associated_item ();
break;
- case TYPE:
+ case Kind::Type:
type = other.type->clone_type ();
break;
+
+ case Kind::Pattern:
+ pattern = other.pattern->clone_pattern ();
+ break;
}
return *this;
}
@@ -112,29 +120,33 @@ SingleASTNode::accept_vis (ASTVisitor &vis)
{
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
expr->accept_vis (vis);
break;
- case ITEM:
+ case Kind::Item:
item->accept_vis (vis);
break;
- case STMT:
+ case Kind::Stmt:
stmt->accept_vis (vis);
break;
- case EXTERN:
+ case Kind::Extern:
external_item->accept_vis (vis);
break;
- case ASSOC_ITEM:
+ case Kind::Assoc:
assoc_item->accept_vis (vis);
break;
- case TYPE:
+ case Kind::Type:
type->accept_vis (vis);
break;
+
+ case Kind::Pattern:
+ pattern->accept_vis (vis);
+ break;
}
}
@@ -143,18 +155,20 @@ SingleASTNode::is_error ()
{
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
return expr == nullptr;
- case ITEM:
+ case Kind::Item:
return item == nullptr;
- case STMT:
+ case Kind::Stmt:
return stmt == nullptr;
- case EXTERN:
+ case Kind::Extern:
return external_item == nullptr;
- case ASSOC_ITEM:
+ case Kind::Assoc:
return assoc_item == nullptr;
- case TYPE:
+ case Kind::Type:
return type == nullptr;
+ case Kind::Pattern:
+ return pattern == nullptr;
}
rust_unreachable ();
@@ -166,18 +180,20 @@ SingleASTNode::as_string () const
{
switch (kind)
{
- case EXPRESSION:
+ case Kind::Expr:
return "Expr: " + expr->as_string ();
- case ITEM:
+ case Kind::Item:
return "Item: " + item->as_string ();
- case STMT:
+ case Kind::Stmt:
return "Stmt: " + stmt->as_string ();
- case EXTERN:
+ case Kind::Extern:
return "External Item: " + external_item->as_string ();
- case ASSOC_ITEM:
+ case Kind::Assoc:
return "Associated Item: " + assoc_item->as_string ();
- case TYPE:
+ case Kind::Type:
return "Type: " + type->as_string ();
+ case Kind::Pattern:
+ return "Pattern: " + pattern->as_string ();
}
rust_unreachable ();
@@ -232,7 +248,7 @@ Attribute::as_string () const
bool
Attribute::is_derive () const
{
- return has_attr_input () && get_path () == "derive";
+ return has_attr_input () && get_path () == Values::Attributes::DERIVE;
}
/**
@@ -389,7 +405,7 @@ DelimTokenTree::as_string () const
std::string
Token::as_string () const
{
- if (tok_ref->has_str ())
+ if (tok_ref->should_have_str ())
{
std::string str = tok_ref->get_str ();
@@ -636,14 +652,8 @@ ConstantItem::as_string () const
}
str += "\n Type: " + type->as_string ();
- // DEBUG: null pointer check
- if (const_expr == nullptr)
- {
- rust_debug ("something really terrible has gone wrong - null "
- "pointer expr in const item.");
- return "NULL_POINTER_MARK";
- }
- str += "\n Expression: " + const_expr->as_string ();
+ if (has_expr ())
+ str += "\n Expression: " + const_expr->as_string ();
return str + "\n";
}
@@ -3034,20 +3044,6 @@ ExternalStaticItem::as_string () const
}
std::string
-TraitItemConst::as_string () const
-{
- // TODO: rewrite to work with non-linearisable exprs
- std::string str = append_attributes (outer_attrs, OUTER);
-
- str += "\nconst " + name.as_string () + " : " + type->as_string ();
-
- if (has_expression ())
- str += " = " + expr->as_string ();
-
- return str;
-}
-
-std::string
TraitItemType::as_string () const
{
std::string str = append_attributes (outer_attrs, OUTER);
@@ -3367,7 +3363,13 @@ void
Module::process_file_path ()
{
rust_assert (kind == Module::ModuleKind::UNLOADED);
- rust_assert (module_file.empty ());
+
+ if (!module_file.empty ())
+ {
+ rust_error_at (locus, "error handling module file for %qs",
+ module_name.as_string ().c_str ());
+ return;
+ }
// This corresponds to the path of the file 'including' the module. So the
// file that contains the 'mod <file>;' directive
@@ -4132,6 +4134,12 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const
for (auto it = items.begin () + 1; it != items.end (); ++it)
{
+ if ((*it)->get_kind () == MetaItemInner::Kind::MetaItem
+ && static_cast<MetaItem &> (**it).get_item_kind ()
+ == MetaItem::ItemKind::PathExpr
+ && !static_cast<MetaItemPathExpr &> (**it).get_expr ().is_literal ())
+ continue;
+
Attribute attr = (*it)->to_attribute ();
if (attr.is_empty ())
{
@@ -4149,11 +4157,12 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const
bool
Attribute::check_cfg_predicate (const Session &session) const
{
+ auto string_path = path.as_string ();
/* assume that cfg predicate actually can exist, i.e. attribute has cfg or
* cfg_attr path */
if (!has_attr_input ()
- || (path.as_string () != Values::Attributes::CFG
- && path.as_string () != Values::Attributes::CFG_ATTR))
+ || (string_path != Values::Attributes::CFG
+ && string_path != Values::Attributes::CFG_ATTR))
{
// DEBUG message
rust_debug (
@@ -4169,6 +4178,13 @@ Attribute::check_cfg_predicate (const Session &session) const
return false;
auto &meta_item = static_cast<AttrInputMetaItemContainer &> (*attr_input);
+ if (meta_item.get_items ().empty ()
+ && string_path == Values::Attributes::CFG_ATTR)
+ {
+ rust_error_at (path.get_locus (),
+ "malformed %<cfg_attr%> attribute input");
+ return false;
+ }
return meta_item.get_items ().front ()->check_cfg_predicate (session);
}
@@ -4740,12 +4756,6 @@ StaticItem::accept_vis (ASTVisitor &vis)
}
void
-TraitItemConst::accept_vis (ASTVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
TraitItemType::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 2d2c5d0..8a7e618 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -184,17 +184,6 @@ class Token : public TokenTree, public MacroMatch
{
// A token is a kind of token tree (except delimiter tokens)
// A token is a kind of MacroMatch (except $ and delimiter tokens)
-#if 0
- // TODO: improve member variables - current ones are the same as lexer token
- // Token kind.
- TokenId token_id;
- // Token location.
- location_t locus;
- // Associated text (if any) of token.
- std::string str;
- // Token type hint (if any).
- PrimitiveCoreType type_hint;
-#endif
const_TokenPtr tok_ref;
@@ -209,53 +198,7 @@ public:
return std::unique_ptr<Token> (clone_token_impl ());
}
-#if 0
- /* constructor from general text - avoid using if lexer const_TokenPtr is
- * available */
- Token (TokenId token_id, location_t locus, std::string str,
- PrimitiveCoreType type_hint)
- : token_id (token_id), locus (locus), str (std::move (str)),
- type_hint (type_hint)
- {}
-#endif
- // not doable with new implementation - will have to make a const_TokenPtr
-
// Constructor from lexer const_TokenPtr
-#if 0
- /* TODO: find workaround for std::string being nullptr - probably have to
- * introduce new method in lexer Token, or maybe make conversion method
- * there */
- Token (const_TokenPtr lexer_token_ptr)
- : token_id (lexer_token_ptr->get_id ()),
- locus (lexer_token_ptr->get_locus ()), str (""),
- type_hint (lexer_token_ptr->get_type_hint ())
- {
- // FIXME: change to "should have str" later?
- if (lexer_token_ptr->has_str ())
- {
- str = lexer_token_ptr->get_str ();
-
- // DEBUG
- rust_debug ("ast token created with str '%s'", str.c_str ());
- }
- else
- {
- // FIXME: is this returning correct thing?
- str = lexer_token_ptr->get_token_description ();
-
- // DEBUG
- rust_debug ("ast token created with string '%s'", str.c_str ());
- }
-
- // DEBUG
- if (lexer_token_ptr->should_have_str () && !lexer_token_ptr->has_str ())
- {
- rust_debug (
- "BAD: for token '%s', should have string but does not!",
- lexer_token_ptr->get_token_description ());
- }
- }
-#endif
Token (const_TokenPtr lexer_tok_ptr) : tok_ref (std::move (lexer_tok_ptr)) {}
bool is_string_lit () const
@@ -283,7 +226,7 @@ public:
std::vector<std::unique_ptr<Token>> to_token_stream () const override;
TokenId get_id () const { return tok_ref->get_id (); }
- bool has_str () const { return tok_ref->has_str (); }
+ bool should_have_str () const { return tok_ref->should_have_str (); }
const std::string &get_str () const { return tok_ref->get_str (); }
location_t get_locus () const { return tok_ref->get_locus (); }
@@ -1137,7 +1080,9 @@ public:
virtual void mark_for_strip () = 0;
virtual bool is_marked_for_strip () const = 0;
- NodeId get_node_id () const { return node_id; }
+
+ // TODO: put this in a virtual base class?
+ virtual NodeId get_node_id () const { return node_id; }
virtual Kind get_stmt_kind () = 0;
@@ -1536,7 +1481,8 @@ public:
virtual location_t get_locus () const = 0;
- NodeId get_node_id () const { return node_id; }
+ // TODO: put this in a virtual base class?
+ virtual NodeId get_node_id () const { return node_id; }
virtual Type *reconstruct_impl () const = 0;
protected:
@@ -1799,6 +1745,8 @@ public:
virtual bool is_marked_for_strip () const = 0;
virtual location_t get_locus () const = 0;
+
+ virtual NodeId get_node_id () const = 0;
};
// Item used in trait declarations - abstract base class
@@ -1829,7 +1777,7 @@ public:
return std::unique_ptr<TraitItem> (clone_associated_item_impl ());
}
- NodeId get_node_id () const { return node_id; }
+ NodeId get_node_id () const override { return node_id; }
location_t get_locus () const override { return locus; }
};
@@ -1957,18 +1905,19 @@ public:
class SingleASTNode : public Visitable
{
public:
- enum NodeType
- {
- EXPRESSION,
- ITEM,
- STMT,
- EXTERN,
- ASSOC_ITEM,
- TYPE,
+ enum class Kind
+ {
+ Expr,
+ Item,
+ Stmt,
+ Extern,
+ Assoc,
+ Type,
+ Pattern,
};
private:
- NodeType kind;
+ Kind kind;
// FIXME make this a union
std::unique_ptr<Expr> expr;
@@ -1977,30 +1926,35 @@ private:
std::unique_ptr<ExternalItem> external_item;
std::unique_ptr<AssociatedItem> assoc_item;
std::unique_ptr<Type> type;
+ std::unique_ptr<Pattern> pattern;
public:
SingleASTNode (std::unique_ptr<Expr> expr)
- : kind (EXPRESSION), expr (std::move (expr))
+ : kind (Kind::Expr), expr (std::move (expr))
{}
SingleASTNode (std::unique_ptr<Item> item)
- : kind (ITEM), item (std::move (item))
+ : kind (Kind::Item), item (std::move (item))
{}
SingleASTNode (std::unique_ptr<Stmt> stmt)
- : kind (STMT), stmt (std::move (stmt))
+ : kind (Kind::Stmt), stmt (std::move (stmt))
{}
SingleASTNode (std::unique_ptr<ExternalItem> item)
- : kind (EXTERN), external_item (std::move (item))
+ : kind (Kind::Extern), external_item (std::move (item))
{}
SingleASTNode (std::unique_ptr<AssociatedItem> item)
- : kind (ASSOC_ITEM), assoc_item (std::move (item))
+ : kind (Kind::Assoc), assoc_item (std::move (item))
{}
SingleASTNode (std::unique_ptr<Type> type)
- : kind (TYPE), type (std::move (type))
+ : kind (Kind::Type), type (std::move (type))
+ {}
+
+ SingleASTNode (std::unique_ptr<Pattern> pattern)
+ : kind (Kind::Pattern), pattern (std::move (pattern))
{}
SingleASTNode (SingleASTNode const &other);
@@ -2010,23 +1964,23 @@ public:
SingleASTNode (SingleASTNode &&other) = default;
SingleASTNode &operator= (SingleASTNode &&other) = default;
- NodeType get_kind () const { return kind; }
+ Kind get_kind () const { return kind; }
std::unique_ptr<Expr> &get_expr ()
{
- rust_assert (kind == EXPRESSION);
+ rust_assert (kind == Kind::Expr);
return expr;
}
std::unique_ptr<Item> &get_item ()
{
- rust_assert (kind == ITEM);
+ rust_assert (kind == Kind::Item);
return item;
}
std::unique_ptr<Stmt> &get_stmt ()
{
- rust_assert (kind == STMT);
+ rust_assert (kind == Kind::Stmt);
return stmt;
}
@@ -2071,6 +2025,12 @@ public:
return std::move (type);
}
+ std::unique_ptr<Pattern> take_pattern ()
+ {
+ rust_assert (!is_error ());
+ return std::move (pattern);
+ }
+
void accept_vis (ASTVisitor &vis) override;
bool is_error ();
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h b/gcc/rust/ast/rust-builtin-ast-nodes.h
index 2893e7b..c784ad6 100644
--- a/gcc/rust/ast/rust-builtin-ast-nodes.h
+++ b/gcc/rust/ast/rust-builtin-ast-nodes.h
@@ -134,6 +134,7 @@ public:
FormatArgumentKind get_kind () const { return kind; }
const Expr &get_expr () const { return *expr; }
+ Expr &get_expr () { return *expr; }
private:
FormatArgument (FormatArgumentKind::Kind kind, tl::optional<Identifier> ident,
@@ -164,6 +165,11 @@ public:
void push (FormatArgument &&elt) { args.emplace_back (std::move (elt)); }
const FormatArgument at (size_t idx) const { return args.at (idx); }
+ const std::vector<FormatArgument> &get_args () const { return args; }
+ std::vector<FormatArgument> &get_args () { return args; }
+ size_t size () const { return args.size (); }
+ bool empty () const { return args.empty (); }
+
private:
std::vector<FormatArgument> args;
};
@@ -200,6 +206,7 @@ public:
const Fmt::Pieces &get_template () const { return template_pieces; }
const FormatArguments &get_arguments () const { return arguments; }
+ FormatArguments &get_arguments () { return arguments; }
virtual location_t get_locus () const override;
Expr::Kind get_expr_kind () const override { return Expr::Kind::FormatArgs; }
@@ -255,6 +262,7 @@ public:
virtual location_t get_locus () const override { return loc; }
const Type &get_type () const { return *type; }
Type &get_type () { return *type; }
+ std::unique_ptr<Type> &get_type_ptr () { return type; }
const Identifier &get_field () const { return field; }
bool is_expr_without_block () const override { return false; }
diff --git a/gcc/rust/ast/rust-collect-lang-items.cc b/gcc/rust/ast/rust-collect-lang-items.cc
index 306c6f7..1efe26f 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -43,18 +43,16 @@ get_lang_item_attr (const T &maybe_lang_item)
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;
+ bool is_lang_item = str_path == Values::Attributes::LANG;
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 ();
+ auto lang_item_type_str
+ = Analysis::Attributes::extract_string_literal (attr);
- return LangItem::Parse (lang_item_type_str);
+ rust_assert (lang_item_type_str.has_value ());
+
+ return LangItem::Parse (*lang_item_type_str);
}
}
diff --git a/gcc/rust/ast/rust-cond-compilation.h b/gcc/rust/ast/rust-cond-compilation.h
index 56a5646..5d5fba5 100644
--- a/gcc/rust/ast/rust-cond-compilation.h
+++ b/gcc/rust/ast/rust-cond-compilation.h
@@ -91,9 +91,13 @@ class ConfigurationAll : public ConfigurationPredicate
predicate_list; // inlined form
public:
+ ConfigurationAll (const ConfigurationAll &) = delete;
+
+ ConfigurationAll (ConfigurationAll &&) = default;
+
ConfigurationAll (
std::vector<std::unique_ptr<ConfigurationPredicate>> predicate_list)
- : predicate_list (predicate_list)
+ : predicate_list (std::move (predicate_list))
{}
void accept_vis (ASTVisitor &vis) override;
@@ -103,7 +107,14 @@ protected:
* than base */
ConfigurationAll *clone_configuration_predicate_impl () const override
{
- return new ConfigurationAll (*this);
+ decltype (predicate_list) predicate_list_clone = {};
+ predicate_list_clone.reserve (predicate_list.size ());
+
+ for (const auto &predicate : predicate_list)
+ predicate_list_clone.push_back (
+ predicate->clone_configuration_predicate ());
+
+ return new ConfigurationAll (std::move (predicate_list_clone));
}
};
@@ -114,9 +125,13 @@ class ConfigurationAny : public ConfigurationPredicate
predicate_list; // inlined form
public:
+ ConfigurationAny (const ConfigurationAny &) = delete;
+
+ ConfigurationAny (ConfigurationAny &&) = default;
+
ConfigurationAny (
std::vector<std::unique_ptr<ConfigurationPredicate>> predicate_list)
- : predicate_list (predicate_list)
+ : predicate_list (std::move (predicate_list))
{}
void accept_vis (ASTVisitor &vis) override;
@@ -126,7 +141,14 @@ protected:
* than base */
ConfigurationAny *clone_configuration_predicate_impl () const override
{
- return new ConfigurationAny (*this);
+ decltype (predicate_list) predicate_list_clone = {};
+ predicate_list_clone.reserve (predicate_list.size ());
+
+ for (const auto &predicate : predicate_list)
+ predicate_list_clone.push_back (
+ predicate->clone_configuration_predicate ());
+
+ return new ConfigurationAny (std::move (predicate_list_clone));
}
};
@@ -226,7 +248,7 @@ public:
CfgAttrAttribute (CfgAttrAttribute const &other)
: config_to_include (
other.config_to_include->clone_configuration_predicate ()),
- cfg_attrs (cfg_attrs)
+ cfg_attrs (other.cfg_attrs)
{}
// Overloaded assignment operator to clone
diff --git a/gcc/rust/ast/rust-desugar-apit.cc b/gcc/rust/ast/rust-desugar-apit.cc
index bca14ee..de34e15 100644
--- a/gcc/rust/ast/rust-desugar-apit.cc
+++ b/gcc/rust/ast/rust-desugar-apit.cc
@@ -188,9 +188,10 @@ public:
// Convert to TypePath by creating path segments
std::vector<std::unique_ptr<TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment (
- PathIdentSegment (ident.as_string (), type.get_locus ()), false,
- type.get_locus ())));
+ segments.emplace_back (
+ new TypePathSegment (PathIdentSegment (ident.as_string (),
+ type.get_locus ()),
+ false, type.get_locus ()));
// Create TypePath from segments
auto type_path
@@ -198,6 +199,8 @@ public:
// Convert bounds from impl trait to generic parameter bounds
std::vector<std::unique_ptr<TypeParamBound>> bounds;
+ bounds.reserve (type.get_type_param_bounds ().size ());
+
for (auto &bound : type.get_type_param_bounds ())
bounds.push_back (bound->clone_type_param_bound ());
@@ -228,9 +231,10 @@ public:
// Convert to TypePath by creating path segments
std::vector<std::unique_ptr<TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment (
- PathIdentSegment (ident.as_string (), type.get_locus ()), false,
- type.get_locus ())));
+ segments.emplace_back (
+ new TypePathSegment (PathIdentSegment (ident.as_string (),
+ type.get_locus ()),
+ false, type.get_locus ()));
// Create TypePath from segments
auto type_path
@@ -407,6 +411,9 @@ private:
std::vector<std::unique_ptr<TypeParamBound>>
type_param_bounds;
+ type_param_bounds.reserve (
+ tp.get_type_param_bounds ().size ());
+
for (auto &b : tp.get_type_param_bounds ())
type_param_bounds.push_back (std::move (b));
tp.get_type_param_bounds ().clear ();
@@ -459,9 +466,10 @@ private:
std::vector<SimplePathSegment> simple_segs = {simple_seg};
auto simple_path = SimplePath (simple_segs, false, ident.get_locus ());
std::vector<std::unique_ptr<TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment (
- PathIdentSegment (ident.as_string (), ident.get_locus ()), false,
- ident.get_locus ())));
+ segments.emplace_back (
+ new TypePathSegment (PathIdentSegment (ident.as_string (),
+ ident.get_locus ()),
+ false, ident.get_locus ()));
auto type_path = new TypePath (std::move (segments), ident.get_locus ());
return std::unique_ptr<Type> (type_path);
}
diff --git a/gcc/rust/ast/rust-desugar-for-loops.cc b/gcc/rust/ast/rust-desugar-for-loops.cc
index 5cc1c19..9a12423 100644
--- a/gcc/rust/ast/rust-desugar-for-loops.cc
+++ b/gcc/rust/ast/rust-desugar-for-loops.cc
@@ -51,7 +51,7 @@ DesugarForLoops::DesugarCtx::make_continue_arm ()
patterns.emplace_back (std::move (val));
auto pattern_item = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (patterns)));
+ new TupleStructItemsNoRest (std::move (patterns)));
auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
builder.path_in_expression (LangItem::Kind::OPTION_SOME),
std::move (pattern_item)));
diff --git a/gcc/rust/ast/rust-desugar-question-mark.cc b/gcc/rust/ast/rust-desugar-question-mark.cc
index 01400d8..20a4903 100644
--- a/gcc/rust/ast/rust-desugar-question-mark.cc
+++ b/gcc/rust/ast/rust-desugar-question-mark.cc
@@ -55,7 +55,7 @@ ok_case (Builder &builder)
patterns.emplace_back (std::move (val));
auto pattern_item = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (patterns)));
+ new TupleStructItemsNoRest (std::move (patterns)));
auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
builder.path_in_expression (LangItem::Kind::RESULT_OK),
std::move (pattern_item)));
@@ -82,7 +82,7 @@ err_case (Builder &builder)
patterns.emplace_back (std::move (val));
auto pattern_item = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (patterns)));
+ new TupleStructItemsNoRest (std::move (patterns)));
auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
builder.path_in_expression (LangItem::Kind::RESULT_ERR),
std::move (pattern_item)));
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 7b0df25..3c36238 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -282,6 +282,8 @@ public:
Expr &get_expr () { return *expr; }
+ std::unique_ptr<Expr> &get_expr_ptr () { return expr; }
+
std::string as_string () const override
{
return path.as_string () + " = " + expr->as_string ();
@@ -296,7 +298,11 @@ public:
// we have no idea use which of them, just simply return UNKNOWN_LOCATION
// now.
// Maybe we will figure out when we really need the location in the future.
- location_t get_locus () const override { return UNKNOWN_LOCATION; }
+ location_t get_locus () const override
+ {
+ rust_unreachable ();
+ return UNKNOWN_LOCATION;
+ }
void accept_vis (ASTVisitor &vis) override;
@@ -414,6 +420,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_borrowed_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
bool has_borrow_expr () const { return main_or_left_expr != nullptr; }
bool get_is_mut () const { return mutability == Mutability::Mut; }
@@ -455,6 +467,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_dereferenced_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
Expr::Kind get_expr_kind () const override { return Expr::Kind::Dereference; }
protected:
@@ -488,6 +506,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_propagating_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
Expr::Kind get_expr_kind () const override
{
return Expr::Kind::ErrorPropagation;
@@ -536,6 +560,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_negated_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
Expr::Kind get_expr_kind () const override { return Expr::Kind::Negation; }
protected:
@@ -865,6 +895,12 @@ public:
return *main_or_left_expr;
}
+ std::unique_ptr<Expr> &get_casted_expr_ptr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
TypeNoBounds &get_type_to_cast_to ()
{
@@ -872,6 +908,12 @@ public:
return *type_to_convert_to;
}
+ std::unique_ptr<TypeNoBounds> &get_type_to_cast_to_ptr ()
+ {
+ rust_assert (type_to_convert_to != nullptr);
+ return type_to_convert_to;
+ }
+
Expr::Kind get_expr_kind () const override { return Expr::Kind::TypeCast; }
protected:
@@ -1282,6 +1324,12 @@ public:
return *elem_to_copy;
}
+ std::unique_ptr<Expr> &get_elem_to_copy_ptr ()
+ {
+ rust_assert (elem_to_copy != nullptr);
+ return elem_to_copy;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
Expr &get_num_copies ()
{
@@ -1289,6 +1337,12 @@ public:
return *num_copies;
}
+ std::unique_ptr<Expr> &get_num_copies_ptr ()
+ {
+ rust_assert (num_copies != nullptr);
+ return num_copies;
+ }
+
protected:
ArrayElemsCopied *clone_array_elems_impl () const override
{
@@ -1468,6 +1522,12 @@ public:
return *array_expr;
}
+ std::unique_ptr<Expr> &get_array_expr_ptr ()
+ {
+ rust_assert (array_expr != nullptr);
+ return array_expr;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
Expr &get_index_expr ()
{
@@ -1475,6 +1535,12 @@ public:
return *index_expr;
}
+ std::unique_ptr<Expr> &get_index_expr_ptr ()
+ {
+ rust_assert (index_expr != nullptr);
+ return index_expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -1599,6 +1665,7 @@ class TupleIndexExpr : public ExprWithoutBlock
TupleIndex tuple_index;
location_t locus;
+ bool to_strip;
// i.e. pair.0
@@ -1610,13 +1677,15 @@ public:
TupleIndexExpr (std::unique_ptr<Expr> tuple_expr, TupleIndex index,
std::vector<Attribute> outer_attribs, location_t locus)
: outer_attrs (std::move (outer_attribs)),
- tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus)
+ tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus),
+ to_strip (false)
{}
// Copy constructor requires a clone for tuple_expr
TupleIndexExpr (TupleIndexExpr const &other)
: ExprWithoutBlock (other), outer_attrs (other.outer_attrs),
- tuple_index (other.tuple_index), locus (other.locus)
+ tuple_index (other.tuple_index), locus (other.locus),
+ to_strip (other.to_strip)
{
// guard to prevent null dereference (only required if error state)
if (other.tuple_expr != nullptr)
@@ -1630,6 +1699,7 @@ public:
tuple_index = other.tuple_index;
locus = other.locus;
outer_attrs = other.outer_attrs;
+ to_strip = other.to_strip;
// guard to prevent null dereference (only required if error state)
if (other.tuple_expr != nullptr)
@@ -1649,8 +1719,8 @@ public:
void accept_vis (ASTVisitor &vis) override;
// Invalid if tuple expr is null, so base stripping on that.
- void mark_for_strip () override { tuple_expr = nullptr; }
- bool is_marked_for_strip () const override { return tuple_expr == nullptr; }
+ void mark_for_strip () override { to_strip = true; }
+ bool is_marked_for_strip () const override { return to_strip; }
// TODO: is this better? Or is a "vis_block" better?
Expr &get_tuple_expr ()
@@ -1659,6 +1729,12 @@ public:
return *tuple_expr;
}
+ std::unique_ptr<Expr> &get_tuple_expr_ptr ()
+ {
+ rust_assert (tuple_expr != nullptr);
+ return tuple_expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -1807,6 +1883,12 @@ public:
rust_assert (base_struct != nullptr);
return *base_struct;
}
+
+ std::unique_ptr<Expr> &get_base_struct_ptr ()
+ {
+ rust_assert (base_struct != nullptr);
+ return base_struct;
+ }
};
/* Base AST node for a single struct expression field (in struct instance
@@ -1923,6 +2005,12 @@ public:
rust_assert (value != nullptr);
return *value;
}
+
+ std::unique_ptr<Expr> &get_value_ptr ()
+ {
+ rust_assert (value != nullptr);
+ return value;
+ }
};
// Identifier and value variant of StructExprField AST node
@@ -2293,6 +2381,12 @@ public:
return *receiver;
}
+ std::unique_ptr<Expr> &get_receiver_expr_ptr ()
+ {
+ rust_assert (receiver != nullptr);
+ return receiver;
+ }
+
const PathExprSegment &get_method_name () const { return method_name; }
PathExprSegment &get_method_name () { return method_name; }
@@ -2381,6 +2475,12 @@ public:
return *receiver;
}
+ std::unique_ptr<Expr> &get_receiver_expr_ptr ()
+ {
+ rust_assert (receiver != nullptr);
+ return receiver;
+ }
+
Identifier get_field_name () const { return field; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
@@ -2480,6 +2580,12 @@ public:
return *pattern;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (pattern != nullptr);
+ return pattern;
+ }
+
Type &get_type ()
{
rust_assert (has_type_given ());
@@ -2532,6 +2638,7 @@ public:
Expr::Kind get_expr_kind () const override { return Expr::Kind::Closure; }
virtual Expr &get_definition_expr () = 0;
+ virtual std::unique_ptr<Expr> &get_definition_expr_ptr () = 0;
};
// Represents a non-type-specified closure expression AST node
@@ -2597,6 +2704,12 @@ public:
return *closure_inner;
}
+ std::unique_ptr<Expr> &get_definition_expr_ptr () override
+ {
+ rust_assert (closure_inner != nullptr);
+ return closure_inner;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2827,6 +2940,12 @@ public:
return *expr.value ();
}
+ std::unique_ptr<Expr> &get_inner_expr_ptr ()
+ {
+ rust_assert (expr.has_value ());
+ return expr.value ();
+ }
+
NodeId get_node_id () const override { return node_id; }
/* FIXME: AnonConst are always "internal" and should not have outer attributes
@@ -2922,8 +3041,7 @@ class ClosureExprInnerTyped : public ClosureExpr
{
// TODO: spec says typenobounds
std::unique_ptr<Type> return_type;
- std::unique_ptr<BlockExpr>
- expr; // only used because may be polymorphic in future
+ std::unique_ptr<Expr> expr; // only used because may be polymorphic in future
public:
std::string as_string () const override;
@@ -2947,7 +3065,7 @@ public:
{
// guard to prevent null dereference (only required if error state)
if (other.expr != nullptr)
- expr = other.expr->clone_block_expr ();
+ expr = other.expr->clone_expr ();
if (other.return_type != nullptr)
return_type = other.return_type->clone_type ();
}
@@ -2962,7 +3080,7 @@ public:
// guard to prevent null dereference (only required if error state)
if (other.expr != nullptr)
- expr = other.expr->clone_block_expr ();
+ expr = other.expr->clone_expr ();
else
expr = nullptr;
if (other.return_type != nullptr)
@@ -2985,12 +3103,19 @@ public:
bool is_marked_for_strip () const override { return expr == nullptr; }
// TODO: is this better? Or is a "vis_block" better?
- BlockExpr &get_definition_expr () override
+ Expr &get_definition_expr () override
{
rust_assert (expr != nullptr);
return *expr;
}
+ std::unique_ptr<Expr> &get_definition_expr_ptr () override
+ {
+ rust_assert (expr != nullptr);
+
+ return expr;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
Type &get_return_type ()
{
@@ -3147,6 +3272,12 @@ public:
return *break_expr;
}
+ std::unique_ptr<Expr> &get_break_expr_ptr ()
+ {
+ rust_assert (has_break_expr ());
+ return break_expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -3274,6 +3405,18 @@ public:
return *to;
}
+ std::unique_ptr<Expr> &get_from_expr_ptr ()
+ {
+ rust_assert (from != nullptr);
+ return from;
+ }
+
+ std::unique_ptr<Expr> &get_to_expr_ptr ()
+ {
+ rust_assert (to != nullptr);
+ return to;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3335,6 +3478,12 @@ public:
return *from;
}
+ std::unique_ptr<Expr> &get_from_expr_ptr ()
+ {
+ rust_assert (from != nullptr);
+ return from;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3397,6 +3546,12 @@ public:
return *to;
}
+ std::unique_ptr<Expr> &get_to_expr_ptr ()
+ {
+ rust_assert (to != nullptr);
+ return to;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3510,6 +3665,18 @@ public:
return *to;
}
+ std::unique_ptr<Expr> &get_from_expr_ptr ()
+ {
+ rust_assert (from != nullptr);
+ return from;
+ }
+
+ std::unique_ptr<Expr> &get_to_expr_ptr ()
+ {
+ rust_assert (to != nullptr);
+ return to;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3572,6 +3739,12 @@ public:
return *to;
}
+ std::unique_ptr<Expr> &get_to_expr_ptr ()
+ {
+ rust_assert (to != nullptr);
+ return to;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3645,6 +3818,12 @@ public:
return *expr;
}
+ std::unique_ptr<Expr> &get_boxed_expr_ptr ()
+ {
+ rust_assert (expr != nullptr);
+ return expr;
+ }
+
Expr::Kind get_expr_kind () const override { return Expr::Kind::Box; }
protected:
@@ -3726,6 +3905,12 @@ public:
return *return_expr;
}
+ std::unique_ptr<Expr> &get_returned_expr_ptr ()
+ {
+ rust_assert (return_expr != nullptr);
+ return return_expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -3801,6 +3986,7 @@ public:
// TODO: is this better? Or is a "vis_block" better?
BlockExpr &get_block_expr () { return *block_expr; }
+ std::unique_ptr<BlockExpr> &get_block_expr_ptr () { return block_expr; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -3886,6 +4072,12 @@ public:
return *expr;
}
+ std::unique_ptr<BlockExpr> &get_block_expr_ptr ()
+ {
+ rust_assert (expr != nullptr);
+ return expr;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -3978,6 +4170,12 @@ public:
return *loop_block;
}
+ std::unique_ptr<BlockExpr> &get_loop_block_ptr ()
+ {
+ rust_assert (loop_block != nullptr);
+ return loop_block;
+ }
+
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
@@ -4078,6 +4276,12 @@ public:
return *condition;
}
+ std::unique_ptr<Expr> &get_predicate_expr_ptr ()
+ {
+ rust_assert (condition != nullptr);
+ return condition;
+ }
+
BaseLoopExpr::Kind get_loop_kind () const override
{
return BaseLoopExpr::Kind::While;
@@ -4156,6 +4360,12 @@ public:
return *scrutinee;
}
+ std::unique_ptr<Expr> &get_scrutinee_expr_ptr ()
+ {
+ rust_assert (scrutinee != nullptr);
+ return scrutinee;
+ }
+
// TODO: this mutable getter seems really dodgy. Think up better way.
const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
{
@@ -4233,6 +4443,12 @@ public:
return *iterator_expr;
}
+ std::unique_ptr<Expr> &get_iterator_expr_ptr ()
+ {
+ rust_assert (iterator_expr != nullptr);
+ return iterator_expr;
+ }
+
// TODO: is this better? Or is a "vis_block" better?
Pattern &get_pattern ()
{
@@ -4240,6 +4456,12 @@ public:
return *pattern;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (pattern != nullptr);
+ return pattern;
+ }
+
BaseLoopExpr::Kind get_loop_kind () const override
{
return BaseLoopExpr::Kind::For;
@@ -4892,6 +5114,12 @@ public:
return *branch_value;
}
+ std::unique_ptr<Expr> &get_scrutinee_expr_ptr ()
+ {
+ rust_assert (branch_value != nullptr);
+ return branch_value;
+ }
+
const std::vector<MatchCase> &get_match_cases () const { return match_arms; }
std::vector<MatchCase> &get_match_cases () { return match_arms; }
@@ -5494,6 +5722,8 @@ struct InlineAsmTemplatePiece
struct TupleClobber
{
+ TupleClobber (std::string symbol, location_t loc) : symbol (symbol), loc (loc)
+ {}
// as gccrs still doesn't contain a symbol class I have put them as strings
std::string symbol;
location_t loc;
@@ -5667,6 +5897,10 @@ public:
}
std::vector<TupleTemplateStr> &get_templates () { return templates; }
+ const std::vector<TupleTemplateStr> &get_templates () const
+ {
+ return templates;
+ }
Expr::Kind get_expr_kind () const override
{
@@ -5685,9 +5919,12 @@ public:
void set_outputs (std::vector<LlvmOperand> operands) { outputs = operands; }
std::vector<LlvmOperand> &get_inputs () { return inputs; }
+ const std::vector<LlvmOperand> &get_inputs () const { return inputs; }
std::vector<LlvmOperand> &get_outputs () { return outputs; }
+ const std::vector<LlvmOperand> &get_outputs () const { return outputs; }
std::vector<TupleClobber> &get_clobbers () { return clobbers; }
+ const std::vector<TupleClobber> &get_clobbers () const { return clobbers; }
};
} // namespace AST
diff --git a/gcc/rust/ast/rust-expression-yeast.cc b/gcc/rust/ast/rust-expression-yeast.cc
index 9f6a62f..7626abc 100644
--- a/gcc/rust/ast/rust-expression-yeast.cc
+++ b/gcc/rust/ast/rust-expression-yeast.cc
@@ -21,10 +21,8 @@
#include "rust-desugar-question-mark.h"
#include "rust-desugar-try-block.h"
#include "rust-desugar-for-loops.h"
-#include "rust-ast-full.h"
#include "rust-desugar-while-let.h"
#include "rust-expr.h"
-#include "rust-stmt.h"
namespace Rust {
namespace AST {
@@ -32,7 +30,7 @@ namespace AST {
void
ExpressionYeast::go (AST::Crate &crate)
{
- DefaultASTVisitor::visit (crate);
+ PointerVisitor::visit (crate);
}
void
@@ -54,7 +52,7 @@ ExpressionYeast::dispatch_loops (std::unique_ptr<Expr> &loop_expr)
}
void
-ExpressionYeast::dispatch (std::unique_ptr<Expr> &expr)
+ExpressionYeast::reseat (std::unique_ptr<Expr> &expr)
{
switch (expr->get_expr_kind ())
{
@@ -71,47 +69,8 @@ ExpressionYeast::dispatch (std::unique_ptr<Expr> &expr)
default:
break;
}
-}
-
-void
-ExpressionYeast::visit (ExprStmt &stmt)
-{
- dispatch (stmt.get_expr_ptr ());
-
- DefaultASTVisitor::visit (stmt);
-}
-
-void
-ExpressionYeast::visit (CallExpr &call)
-{
- dispatch (call.get_function_expr_ptr ());
-
- for (auto &arg : call.get_params ())
- dispatch (arg);
-
- DefaultASTVisitor::visit (call);
-}
-
-void
-ExpressionYeast::visit (BlockExpr &block)
-{
- for (auto &stmt : block.get_statements ())
- if (stmt->get_stmt_kind () == Stmt::Kind::Expr)
- dispatch (static_cast<ExprStmt &> (*stmt).get_expr_ptr ());
-
- if (block.has_tail_expr ())
- dispatch (block.get_tail_expr_ptr ());
-
- DefaultASTVisitor::visit (block);
-}
-
-void
-ExpressionYeast::visit (LetStmt &stmt)
-{
- if (stmt.has_init_expr ())
- dispatch (stmt.get_init_expr_ptr ());
- DefaultASTVisitor::visit (stmt);
+ visit (expr);
}
} // namespace AST
diff --git a/gcc/rust/ast/rust-expression-yeast.h b/gcc/rust/ast/rust-expression-yeast.h
index 855918f..3f64b1d 100644
--- a/gcc/rust/ast/rust-expression-yeast.h
+++ b/gcc/rust/ast/rust-expression-yeast.h
@@ -19,7 +19,7 @@
#ifndef RUST_EXPRESSION_YEAST
#define RUST_EXPRESSION_YEAST
-#include "rust-ast-visitor.h"
+#include "rust-ast-pointer-visitor.h"
#include "rust-ast.h"
#include "rust-desugar-question-mark.h"
@@ -28,22 +28,19 @@ namespace AST {
// This visitor takes care of all the expression desugars: try-blocks,
// error-propagation, etc.
-class ExpressionYeast : public AST::DefaultASTVisitor
+class ExpressionYeast : public AST::PointerVisitor
{
- using AST::DefaultASTVisitor::visit;
+ using AST::PointerVisitor::reseat;
+ using AST::PointerVisitor::visit;
public:
void go (AST::Crate &);
private:
// Dispatch to the proper desugar
- void dispatch (std::unique_ptr<Expr> &expr);
- void dispatch_loops (std::unique_ptr<Expr> &loop_expr);
+ void reseat (std::unique_ptr<Expr> &expr) override;
- void visit (AST::ExprStmt &) override;
- void visit (AST::CallExpr &) override;
- void visit (AST::LetStmt &) override;
- void visit (AST::BlockExpr &) override;
+ void dispatch_loops (std::unique_ptr<Expr> &loop_expr);
};
} // namespace AST
diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index a29c820..21f4f03 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -32,41 +32,11 @@ Pieces
Pieces::collect (const std::string &to_parse, bool append_newline,
ffi::ParseMode parse_mode)
{
- auto handle
- = ffi::collect_pieces (to_parse.c_str (), append_newline, parse_mode);
-
- // this performs multiple copies, can we avoid them maybe?
- // TODO: Instead of just creating a vec of, basically, `ffi::Piece`s, we
- // should transform them into the proper C++ type which we can work with. so
- // transform all the strings into C++ strings? all the Option<T> into
- // tl::optional<T>?
- auto pieces_vector = std::vector<ffi::Piece> (handle.piece_slice.base_ptr,
- handle.piece_slice.base_ptr
- + handle.piece_slice.len);
-
- return Pieces (handle, std::move (pieces_vector));
-}
-
-Pieces::~Pieces () { ffi::destroy_pieces (handle); }
-
-Pieces::Pieces (const Pieces &other) : pieces_vector (other.pieces_vector)
-{
- handle = ffi::clone_pieces (other.handle);
+ Pieces ret (to_parse, ffi::FFIVec<ffi::Piece> ());
+ ret.data->second = ffi::collect_pieces (ffi::RustHamster (ret.data->first),
+ append_newline, parse_mode);
+ return ret;
}
-Pieces &
-Pieces::operator= (const Pieces &other)
-{
- handle = ffi::clone_pieces (other.handle);
- pieces_vector = other.pieces_vector;
-
- return *this;
-}
-
-Pieces::Pieces (Pieces &&other)
- : pieces_vector (std::move (other.pieces_vector)),
- handle (clone_pieces (other.handle))
-{}
-
} // namespace Fmt
} // namespace Rust
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 3722db2..e59bed3 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -20,20 +20,171 @@
#define RUST_FMT_H
#include "rust-system.h"
-
-// FIXME: How to encode Option?
+#include "optional.h"
namespace Rust {
namespace Fmt {
namespace ffi {
+extern "C" {
+
+unsigned char *rust_ffi_alloc (size_t count, size_t elem_size, size_t align);
+
+void rust_ffi_dealloc (unsigned char *data, size_t count, size_t elem_size,
+ size_t align);
+
+} // extern "C"
+
+template <typename T> class FFIVec
+{
+ T *data;
+ size_t len;
+ size_t cap;
+
+public:
+ FFIVec () : data ((T *) alignof (T)), len (0), cap (0) {}
+
+ FFIVec (const FFIVec &) = delete;
+ FFIVec &operator= (const FFIVec &) = delete;
+
+ FFIVec (FFIVec &&other) : data (other.data), len (other.len), cap (other.cap)
+ {
+ other.data = (T *) alignof (T);
+ other.len = 0;
+ other.cap = 0;
+ }
+
+ FFIVec &operator= (FFIVec &&other)
+ {
+ this->~FFIVec ();
+ new (this) FFIVec (std::move (other));
+ return *this;
+ }
+
+ ~FFIVec ()
+ {
+ // T can't be zero-sized
+ if (cap)
+ rust_ffi_dealloc ((unsigned char *) data, cap, sizeof (T), alignof (T));
+ }
+
+ size_t size () const { return len; }
+
+ const T &operator[] (size_t idx) const
+ {
+ rust_assert (idx <= len);
+ return data[idx];
+ }
+
+ T *begin () { return data; }
+ const T *begin () const { return data; }
+ T *end () { return data + len; }
+ const T *end () const { return data + len; }
+};
+
+// https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md
+template <typename T,
+ typename =
+ typename std::enable_if<std::is_standard_layout<T>::value>::type>
+class FFIOpt
+{
+public:
+ template <typename U>
+ FFIOpt (U &&val) : some{Some::KIND, std::forward<U> (val)}
+ {}
+
+ FFIOpt () : none{None::KIND} {}
+
+ FFIOpt (const FFIOpt &other)
+ {
+ if (other.has_value ())
+ new (&some) Some{Some::KIND, other.some.val};
+ else
+ new (&none) None{None::KIND};
+ }
+
+ FFIOpt (FFIOpt &&other)
+ {
+ if (other.has_value ())
+ new (&some) Some{Some::KIND, std::move (other.some.val)};
+ else
+ new (&none) None{None::KIND};
+ }
+
+ ~FFIOpt ()
+ {
+ if (has_value ())
+ some.~Some ();
+ else
+ none.~None ();
+ }
+
+ FFIOpt &operator= (const FFIOpt &other)
+ {
+ this->~FFIOpt ();
+ new (this) FFIOpt (other);
+ return *this;
+ }
+
+ FFIOpt &operator= (FFIOpt &&other)
+ {
+ this->~FFIOpt ();
+ new (this) FFIOpt (std::move (other));
+ return *this;
+ }
+
+ tl::optional<std::reference_wrapper<T>> get_opt ()
+ {
+ if (has_value ())
+ return std::ref (some.val);
+ else
+ return tl::nullopt;
+ }
+
+ tl::optional<std::reference_wrapper<const T>> get_opt () const
+ {
+ if (has_value ())
+ return std::ref (some.val);
+ else
+ return tl::nullopt;
+ }
+
+ bool has_value () const { return some.kind == Some::KIND; }
+
+ operator bool () const { return has_value (); }
+
+private:
+ struct Some
+ {
+ static constexpr uint8_t KIND = 0;
+ uint8_t kind;
+ T val;
+ };
+
+ struct None
+ {
+ static constexpr uint8_t KIND = 1;
+ uint8_t kind;
+ };
+
+ union
+ {
+ Some some;
+ None none;
+ };
+};
+
struct RustHamster
{
const char *ptr;
size_t len;
std::string to_string () const;
+
+ explicit RustHamster (const std::string &str)
+ : ptr (str.data ()), len (str.size ())
+ {}
};
/// Enum of alignments which are supported.
@@ -166,33 +317,33 @@ struct Count
struct FormatSpec
{
/// Optionally specified character to fill alignment with.
- const uint32_t *fill;
+ FFIOpt<uint32_t> fill;
/// Span of the optionally specified fill character.
- const InnerSpan *fill_span;
+ FFIOpt<InnerSpan> fill_span;
/// Optionally specified alignment.
Alignment align;
/// The `+` or `-` flag.
- const Sign *sign;
+ FFIOpt<Sign> sign;
/// The `#` flag.
bool alternate;
/// The `0` flag.
bool zero_pad;
/// The `x` or `X` flag. (Only for `Debug`.)
- const DebugHex *debug_hex;
+ FFIOpt<DebugHex> debug_hex;
/// The integer precision to use.
Count precision;
/// The span of the precision formatting flag (for diagnostics).
- const InnerSpan *precision_span;
+ FFIOpt<InnerSpan> precision_span;
/// The string width requested for the resulting format.
Count width;
/// The span of the width formatting flag (for diagnostics).
- const InnerSpan *width_span;
+ FFIOpt<InnerSpan> width_span;
/// The descriptor string representing the name of the format desired for
/// this argument, this can be empty or any number of characters, although
/// it is required to be one word.
RustHamster ty;
/// The span of the descriptor string (for diagnostics).
- const InnerSpan *ty_span;
+ FFIOpt<InnerSpan> ty_span;
};
/// Representation of an argument specification.
@@ -238,26 +389,6 @@ struct Piece
};
};
-struct PieceSlice
-{
- const Piece *base_ptr;
- size_t len;
- size_t cap;
-};
-
-struct RustString
-{
- const unsigned char *ptr;
- size_t len;
- size_t cap;
-};
-
-struct FormatArgsHandle
-{
- PieceSlice piece_slice;
- RustString rust_string;
-};
-
enum ParseMode
{
Format = 0,
@@ -266,12 +397,10 @@ enum ParseMode
extern "C" {
-FormatArgsHandle collect_pieces (const char *input, bool append_newline,
- ParseMode parse_mode);
+FFIVec<Piece> collect_pieces (RustHamster input, bool append_newline,
+ ParseMode parse_mode);
-FormatArgsHandle clone_pieces (const FormatArgsHandle &);
-
-void destroy_pieces (FormatArgsHandle);
+FFIVec<Piece> clone_pieces (const FFIVec<Piece> &);
} // extern "C"
@@ -281,33 +410,20 @@ struct Pieces
{
static Pieces collect (const std::string &to_parse, bool append_newline,
ffi::ParseMode parse_mode);
- ~Pieces ();
-
- Pieces (const Pieces &other);
- Pieces &operator= (const Pieces &other);
- Pieces (Pieces &&other);
-
- const std::vector<ffi::Piece> &get_pieces () const { return pieces_vector; }
-
- // {
- // slice = clone_pieces (&other.slice);
- // to_parse = other.to_parse;
-
- // return *this;
- // }
+ const ffi::FFIVec<ffi::Piece> &get_pieces () const { return data->second; }
private:
- Pieces (ffi::FormatArgsHandle handle, std::vector<ffi::Piece> &&pieces_vector)
- : pieces_vector (std::move (pieces_vector)), handle (handle)
+ Pieces (std::string str, ffi::FFIVec<ffi::Piece> pieces)
+ : data (
+ std::make_shared<decltype (data)::element_type> (std::move (str),
+ std::move (pieces)))
{}
- std::vector<ffi::Piece> pieces_vector;
-
- // this memory is held for FFI reasons - it needs to be released and cloned
- // precisely, so try to not access it/modify it if possible. you should
- // instead work with `pieces_vector`
- ffi::FormatArgsHandle handle;
+ // makes copying simpler
+ // also, we'd need to keep the parsed string in a shared_ptr anyways
+ // since we store pointers into the parsed string
+ std::shared_ptr<std::pair<std::string, ffi::FFIVec<ffi::Piece>>> data;
};
} // namespace Fmt
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index d11eed7..7aea763 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -631,6 +631,12 @@ public:
return *param_name;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (param_name != nullptr);
+ return param_name;
+ }
+
const Pattern &get_pattern () const
{
rust_assert (param_name != nullptr);
@@ -714,6 +720,12 @@ public:
return *param_name;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (param_name != nullptr);
+ return param_name;
+ }
+
bool has_name () const { return param_name != nullptr; }
// TODO: is this better? Or is a "vis_block" better?
@@ -1567,6 +1579,9 @@ public:
location_t get_locus () const override final { return locus; }
+ // needed to override AssociatedItem::get_node_id
+ NodeId get_node_id () const override final { return VisItem::get_node_id (); }
+
void accept_vis (ASTVisitor &vis) override;
// Invalid if existing type is null, so base stripping on that.
@@ -1595,6 +1610,12 @@ public:
return *existing_type;
}
+ std::unique_ptr<Type> &get_type_aliased_ptr ()
+ {
+ rust_assert (existing_type != nullptr);
+ return existing_type;
+ }
+
Identifier get_new_type_name () const { return new_type_name; }
Item::Kind get_item_kind () const override { return Item::Kind::TypeAlias; }
@@ -2515,9 +2536,12 @@ public:
location_t get_locus () const override final { return locus; }
+ // needed to override AssociatedItem::get_node_id
+ NodeId get_node_id () const override final { return VisItem::get_node_id (); }
+
void accept_vis (ASTVisitor &vis) override;
- // Invalid if type or expression are null, so base stripping on that.
+ // Invalid if type and expression are null, so base stripping on that.
void mark_for_strip () override
{
type = nullptr;
@@ -2528,7 +2552,7 @@ public:
return type == nullptr && const_expr == nullptr;
}
- bool has_expr () { return const_expr != nullptr; }
+ bool has_expr () const { return const_expr != nullptr; }
// TODO: is this better? Or is a "vis_block" better?
Expr &get_expr ()
@@ -2695,123 +2719,6 @@ protected:
}
};
-// Constant item within traits
-class TraitItemConst : public TraitItem
-{
- std::vector<Attribute> outer_attrs;
- Identifier name;
- std::unique_ptr<Type> type;
-
- // bool has_expression;
- std::unique_ptr<Expr> expr;
-
-public:
- // Whether the constant item has an associated expression.
- bool has_expression () const { return expr != nullptr; }
-
- TraitItemConst (Identifier name, std::unique_ptr<Type> type,
- std::unique_ptr<Expr> expr,
- std::vector<Attribute> outer_attrs, location_t locus)
- : TraitItem (locus), outer_attrs (std::move (outer_attrs)),
- name (std::move (name)), type (std::move (type)), expr (std::move (expr))
- {}
-
- // Copy constructor with clones
- TraitItemConst (TraitItemConst const &other)
- : TraitItem (other.locus), outer_attrs (other.outer_attrs),
- name (other.name)
- {
- node_id = other.node_id;
-
- // guard to prevent null dereference
- if (other.expr != nullptr)
- expr = other.expr->clone_expr ();
-
- // guard to prevent null dereference (only for error state)
- if (other.type != nullptr)
- type = other.type->clone_type ();
- }
-
- // Overloaded assignment operator to clone
- TraitItemConst &operator= (TraitItemConst const &other)
- {
- TraitItem::operator= (other);
- outer_attrs = other.outer_attrs;
- name = other.name;
- locus = other.locus;
- node_id = other.node_id;
-
- // guard to prevent null dereference
- if (other.expr != nullptr)
- expr = other.expr->clone_expr ();
- else
- expr = nullptr;
-
- // guard to prevent null dereference (only for error state)
- if (other.type != nullptr)
- type = other.type->clone_type ();
- else
- type = nullptr;
-
- return *this;
- }
-
- // move constructors
- TraitItemConst (TraitItemConst &&other) = default;
- TraitItemConst &operator= (TraitItemConst &&other) = default;
-
- std::string as_string () const override;
-
- location_t get_locus () const override { return locus; }
-
- void accept_vis (ASTVisitor &vis) override;
-
- // Invalid if type is null, so base stripping on that.
- void mark_for_strip () override { type = nullptr; }
- bool is_marked_for_strip () const override { return type == nullptr; }
-
- // 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; }
-
- bool has_expr () const { return expr != nullptr; }
-
- // TODO: is this better? Or is a "vis_block" better?
- Expr &get_expr ()
- {
- rust_assert (has_expr ());
- return *expr;
- }
-
- std::unique_ptr<Expr> &get_expr_ptr ()
- {
- rust_assert (has_expr ());
- return expr;
- }
-
- // TODO: is this better? Or is a "vis_block" better?
- Type &get_type ()
- {
- rust_assert (type != nullptr);
- return *type;
- }
-
- std::unique_ptr<Type> &get_type_ptr ()
- {
- rust_assert (type != nullptr);
- return type;
- }
-
- Identifier get_identifier () const { return name; }
-
-protected:
- // Clone function implementation as (not pure) virtual method
- TraitItemConst *clone_associated_item_impl () const override
- {
- return new TraitItemConst (*this);
- }
-};
-
// Type items within traits
class TraitItemType : public TraitItem
{
diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
index 793423a..068e364 100644
--- a/gcc/rust/ast/rust-path.cc
+++ b/gcc/rust/ast/rust-path.cc
@@ -167,14 +167,13 @@ Path::convert_to_simple_path (bool with_opening_scope_resolution) const
for (const auto &segment : segments)
{
// return empty path if doesn't meet simple path segment requirements
- if (segment.is_error () || segment.has_generic_args ()
- || segment.as_string () == "Self")
+ if (segment.is_error () || segment.has_generic_args ())
return SimplePath::create_empty ();
// create segment and add to vector
std::string segment_str = segment.as_string ();
- simple_segments.push_back (
- SimplePathSegment (std::move (segment_str), segment.get_locus ()));
+ simple_segments.emplace_back (std::move (segment_str),
+ segment.get_locus ());
}
// kind of a HACK to get locus depending on opening scope resolution
@@ -258,8 +257,8 @@ TypePath::as_simple_path () const
// create segment and add to vector
std::string segment_str = segment->as_string ();
- simple_segments.push_back (
- SimplePathSegment (std::move (segment_str), segment->get_locus ()));
+ simple_segments.emplace_back (std::move (segment_str),
+ segment->get_locus ());
}
return SimplePath (std::move (simple_segments), has_opening_scope_resolution,
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index a1b19d5..be04882 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -377,6 +377,13 @@ public:
return *type;
}
+ std::unique_ptr<AST::Type> &get_type_ptr ()
+ {
+ rust_assert (has_type ());
+
+ return type;
+ }
+
GenericArg &get_default_value_unchecked ()
{
rust_assert (has_default_value ());
@@ -448,9 +455,7 @@ public:
generic_args.clear ();
generic_args.reserve (other.generic_args.size ());
for (const auto &arg : other.generic_args)
- {
- generic_args.push_back (GenericArg (arg));
- }
+ generic_args.emplace_back (arg);
}
~GenericArgs () = default;
@@ -465,9 +470,7 @@ public:
generic_args.clear ();
generic_args.reserve (other.generic_args.size ());
for (const auto &arg : other.generic_args)
- {
- generic_args.push_back (GenericArg (arg));
- }
+ generic_args.emplace_back (arg);
return *this;
}
@@ -1252,7 +1255,7 @@ 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; }
+ NodeId get_node_id () const override { return node_id; }
void mark_for_strip () override {}
bool is_marked_for_strip () const override { return false; }
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index 15ab0b7..a2fe5d5 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -186,8 +186,8 @@ StructPatternElements::as_string () const
str += "\n " + field->as_string ();
}
- str += "\n Etc: ";
- if (has_struct_pattern_etc)
+ str += "\n Has rest: ";
+ if (has_rest_pattern)
str += "true";
else
str += "false";
@@ -212,7 +212,7 @@ StructPattern::as_string () const
}
std::string
-TupleStructItemsNoRange::as_string () const
+TupleStructItemsNoRest::as_string () const
{
std::string str;
@@ -223,7 +223,7 @@ TupleStructItemsNoRange::as_string () const
}
std::string
-TupleStructItemsRange::as_string () const
+TupleStructItemsHasRest::as_string () const
{
std::string str ("\n Lower patterns: ");
@@ -264,7 +264,7 @@ TupleStructPattern::as_string () const
}
std::string
-TuplePatternItemsMultiple::as_string () const
+TuplePatternItemsNoRest::as_string () const
{
std::string str;
@@ -275,7 +275,7 @@ TuplePatternItemsMultiple::as_string () const
}
std::string
-TuplePatternItemsRanged::as_string () const
+TuplePatternItemsHasRest::as_string () const
{
std::string str;
@@ -421,7 +421,7 @@ SlicePattern::accept_vis (ASTVisitor &vis)
}
void
-TuplePatternItemsRanged::accept_vis (ASTVisitor &vis)
+TuplePatternItemsHasRest::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}
@@ -433,7 +433,7 @@ TuplePattern::accept_vis (ASTVisitor &vis)
}
void
-TuplePatternItemsMultiple::accept_vis (ASTVisitor &vis)
+TuplePatternItemsNoRest::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}
@@ -517,13 +517,13 @@ StructPattern::accept_vis (ASTVisitor &vis)
}
void
-TupleStructItemsNoRange::accept_vis (ASTVisitor &vis)
+TupleStructItemsNoRest::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}
void
-TupleStructItemsRange::accept_vis (ASTVisitor &vis)
+TupleStructItemsHasRest::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 4945ec4..0da1981 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -20,6 +20,7 @@
#define RUST_AST_PATTERN_H
#include "rust-ast.h"
+#include "rust-path.h"
namespace Rust {
namespace AST {
@@ -143,6 +144,12 @@ public:
return *subpattern;
}
+ std::unique_ptr<Pattern> &get_subpattern_ptr ()
+ {
+ rust_assert (has_subpattern ());
+ return subpattern;
+ }
+
Identifier get_ident () const { return variable_ident; }
bool get_is_mut () const { return is_mut; }
@@ -518,6 +525,12 @@ public:
return *pattern;
}
+ std::unique_ptr<Pattern> &get_referenced_pattern_ptr ()
+ {
+ rust_assert (pattern != nullptr);
+ return pattern;
+ }
+
bool is_double_reference () const { return has_two_amps; }
bool get_is_mut () const { return is_mut; }
@@ -681,6 +694,12 @@ public:
return *tuple_pattern;
}
+ std::unique_ptr<Pattern> &get_index_pattern_ptr ()
+ {
+ rust_assert (tuple_pattern != nullptr);
+ return tuple_pattern;
+ }
+
ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; }
protected:
@@ -761,6 +780,12 @@ public:
return *ident_pattern;
}
+ std::unique_ptr<Pattern> &get_ident_pattern_ptr ()
+ {
+ rust_assert (ident_pattern != nullptr);
+ return ident_pattern;
+ }
+
ItemType get_item_type () const override final { return ItemType::IDENT_PAT; }
protected:
@@ -818,7 +843,7 @@ class StructPatternElements
// bool has_struct_pattern_fields;
std::vector<std::unique_ptr<StructPatternField>> fields;
- bool has_struct_pattern_etc;
+ bool has_rest_pattern;
std::vector<Attribute> struct_pattern_etc_attrs;
// StructPatternEtc etc;
@@ -834,29 +859,29 @@ public:
* no etc). */
bool is_empty () const
{
- return !has_struct_pattern_fields () && !has_struct_pattern_etc;
+ return !has_struct_pattern_fields () && !has_rest_pattern;
}
- bool has_etc () const { return has_struct_pattern_etc; }
+ bool has_rest () const { return has_rest_pattern; }
// Constructor for StructPatternElements with both (potentially)
StructPatternElements (
std::vector<std::unique_ptr<StructPatternField>> fields,
std::vector<Attribute> etc_attrs)
- : fields (std::move (fields)), has_struct_pattern_etc (true),
+ : fields (std::move (fields)), has_rest_pattern (true),
struct_pattern_etc_attrs (std::move (etc_attrs))
{}
// Constructor for StructPatternElements with no StructPatternEtc
StructPatternElements (
std::vector<std::unique_ptr<StructPatternField>> fields)
- : fields (std::move (fields)), has_struct_pattern_etc (false),
+ : fields (std::move (fields)), has_rest_pattern (false),
struct_pattern_etc_attrs ()
{}
// Copy constructor with vector clone
StructPatternElements (StructPatternElements const &other)
- : has_struct_pattern_etc (other.has_struct_pattern_etc),
+ : has_rest_pattern (other.has_rest_pattern),
struct_pattern_etc_attrs (other.struct_pattern_etc_attrs)
{
fields.reserve (other.fields.size ());
@@ -868,7 +893,7 @@ public:
StructPatternElements &operator= (StructPatternElements const &other)
{
struct_pattern_etc_attrs = other.struct_pattern_etc_attrs;
- has_struct_pattern_etc = other.has_struct_pattern_etc;
+ has_rest_pattern = other.has_rest_pattern;
fields.clear ();
fields.reserve (other.fields.size ());
@@ -913,7 +938,7 @@ public:
void strip_etc ()
{
- has_struct_pattern_etc = false;
+ has_rest_pattern = false;
struct_pattern_etc_attrs.clear ();
struct_pattern_etc_attrs.shrink_to_fit ();
}
@@ -975,49 +1000,62 @@ protected:
}
};
-// Base abstract class for patterns used in TupleStructPattern
-class TupleStructItems
+// Base abstract class for TupleStructItems, TuplePatternItems &
+// SlicePatternItems
+class PatternItems
{
public:
enum ItemType
{
- RANGE,
- NO_RANGE
+ NO_REST,
+ HAS_REST,
};
- virtual ~TupleStructItems () {}
+ virtual ~PatternItems () {}
// TODO: should this store location data?
// Unique pointer custom clone function
- std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
+ std::unique_ptr<PatternItems> clone_pattern_items () const
{
- return std::unique_ptr<TupleStructItems> (clone_tuple_struct_items_impl ());
+ return std::unique_ptr<PatternItems> (clone_pattern_items_impl ());
}
virtual std::string as_string () const = 0;
-
+ virtual ItemType get_item_type () const = 0;
virtual void accept_vis (ASTVisitor &vis) = 0;
- virtual ItemType get_item_type () const = 0;
+protected:
+ virtual PatternItems *clone_pattern_items_impl () const = 0;
+};
+
+// Base abstract class for patterns used in TupleStructPattern
+class TupleStructItems : public PatternItems
+{
+public:
+ // Unique pointer custom clone function
+ std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
+ {
+ return std::unique_ptr<TupleStructItems> (clone_pattern_items_impl ());
+ }
protected:
// pure virtual clone implementation
- virtual TupleStructItems *clone_tuple_struct_items_impl () const = 0;
+ virtual TupleStructItems *clone_pattern_items_impl () const = 0;
};
// Class for non-ranged tuple struct pattern patterns
-class TupleStructItemsNoRange : public TupleStructItems
+class TupleStructItemsNoRest : public TupleStructItems
{
std::vector<std::unique_ptr<Pattern>> patterns;
public:
- TupleStructItemsNoRange (std::vector<std::unique_ptr<Pattern>> patterns)
+ TupleStructItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
: patterns (std::move (patterns))
{}
// Copy constructor with vector clone
- TupleStructItemsNoRange (TupleStructItemsNoRange const &other)
+ TupleStructItemsNoRest (TupleStructItemsNoRest const &other)
{
patterns.reserve (other.patterns.size ());
for (const auto &e : other.patterns)
@@ -1025,7 +1063,7 @@ public:
}
// Overloaded assignment operator with vector clone
- TupleStructItemsNoRange &operator= (TupleStructItemsNoRange const &other)
+ TupleStructItemsNoRest &operator= (TupleStructItemsNoRest const &other)
{
patterns.clear ();
patterns.reserve (other.patterns.size ());
@@ -1036,9 +1074,8 @@ public:
}
// move constructors
- TupleStructItemsNoRange (TupleStructItemsNoRange &&other) = default;
- TupleStructItemsNoRange &operator= (TupleStructItemsNoRange &&other)
- = default;
+ TupleStructItemsNoRest (TupleStructItemsNoRest &&other) = default;
+ TupleStructItemsNoRest &operator= (TupleStructItemsNoRest &&other) = default;
std::string as_string () const override;
@@ -1051,32 +1088,32 @@ public:
return patterns;
}
- ItemType get_item_type () const override final { return ItemType::NO_RANGE; }
+ ItemType get_item_type () const override final { return ItemType::NO_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TupleStructItemsNoRange *clone_tuple_struct_items_impl () const override
+ TupleStructItemsNoRest *clone_pattern_items_impl () const override
{
- return new TupleStructItemsNoRange (*this);
+ return new TupleStructItemsNoRest (*this);
}
};
// Class for ranged tuple struct pattern patterns
-class TupleStructItemsRange : public TupleStructItems
+class TupleStructItemsHasRest : public TupleStructItems
{
std::vector<std::unique_ptr<Pattern>> lower_patterns;
std::vector<std::unique_ptr<Pattern>> upper_patterns;
public:
- TupleStructItemsRange (std::vector<std::unique_ptr<Pattern>> lower_patterns,
- std::vector<std::unique_ptr<Pattern>> upper_patterns)
+ TupleStructItemsHasRest (std::vector<std::unique_ptr<Pattern>> lower_patterns,
+ std::vector<std::unique_ptr<Pattern>> upper_patterns)
: lower_patterns (std::move (lower_patterns)),
upper_patterns (std::move (upper_patterns))
{}
// Copy constructor with vector clone
- TupleStructItemsRange (TupleStructItemsRange const &other)
+ TupleStructItemsHasRest (TupleStructItemsHasRest const &other)
{
lower_patterns.reserve (other.lower_patterns.size ());
for (const auto &e : other.lower_patterns)
@@ -1088,7 +1125,7 @@ public:
}
// Overloaded assignment operator to clone
- TupleStructItemsRange &operator= (TupleStructItemsRange const &other)
+ TupleStructItemsHasRest &operator= (TupleStructItemsHasRest const &other)
{
lower_patterns.clear ();
lower_patterns.reserve (other.lower_patterns.size ());
@@ -1104,8 +1141,9 @@ public:
}
// move constructors
- TupleStructItemsRange (TupleStructItemsRange &&other) = default;
- TupleStructItemsRange &operator= (TupleStructItemsRange &&other) = default;
+ TupleStructItemsHasRest (TupleStructItemsHasRest &&other) = default;
+ TupleStructItemsHasRest &operator= (TupleStructItemsHasRest &&other)
+ = default;
std::string as_string () const override;
@@ -1131,14 +1169,14 @@ public:
return upper_patterns;
}
- ItemType get_item_type () const override final { return ItemType::RANGE; }
+ ItemType get_item_type () const override final { return ItemType::HAS_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TupleStructItemsRange *clone_tuple_struct_items_impl () const override
+ TupleStructItemsHasRest *clone_pattern_items_impl () const override
{
- return new TupleStructItemsRange (*this);
+ return new TupleStructItemsHasRest (*this);
}
};
@@ -1221,49 +1259,32 @@ protected:
};
// Base abstract class representing TuplePattern patterns
-class TuplePatternItems
+class TuplePatternItems : public PatternItems
{
public:
- enum TuplePatternItemType
- {
- MULTIPLE,
- RANGED,
- };
-
- virtual ~TuplePatternItems () {}
-
- // TODO: should this store location data?
-
// Unique pointer custom clone function
std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items () const
{
- return std::unique_ptr<TuplePatternItems> (
- clone_tuple_pattern_items_impl ());
+ return std::unique_ptr<TuplePatternItems> (clone_pattern_items_impl ());
}
- virtual std::string as_string () const = 0;
-
- virtual void accept_vis (ASTVisitor &vis) = 0;
-
- virtual TuplePatternItemType get_pattern_type () const = 0;
-
protected:
// pure virtual clone implementation
- virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
+ virtual TuplePatternItems *clone_pattern_items_impl () const = 0;
};
-// Class representing TuplePattern patterns where there are multiple patterns
-class TuplePatternItemsMultiple : public TuplePatternItems
+// Class representing TuplePattern patterns which contains no rest pattern
+class TuplePatternItemsNoRest : public TuplePatternItems
{
std::vector<std::unique_ptr<Pattern>> patterns;
public:
- TuplePatternItemsMultiple (std::vector<std::unique_ptr<Pattern>> patterns)
+ TuplePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
: patterns (std::move (patterns))
{}
// Copy constructor with vector clone
- TuplePatternItemsMultiple (TuplePatternItemsMultiple const &other)
+ TuplePatternItemsNoRest (TuplePatternItemsNoRest const &other)
{
patterns.reserve (other.patterns.size ());
for (const auto &e : other.patterns)
@@ -1271,7 +1292,7 @@ public:
}
// Overloaded assignment operator to vector clone
- TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple const &other)
+ TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest const &other)
{
patterns.clear ();
patterns.reserve (other.patterns.size ());
@@ -1282,8 +1303,8 @@ public:
}
// move constructors
- TuplePatternItemsMultiple (TuplePatternItemsMultiple &&other) = default;
- TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple &&other)
+ TuplePatternItemsNoRest (TuplePatternItemsNoRest &&other) = default;
+ TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest &&other)
= default;
std::string as_string () const override;
@@ -1297,35 +1318,33 @@ public:
return patterns;
}
- TuplePatternItemType get_pattern_type () const override
- {
- return TuplePatternItemType::MULTIPLE;
- }
+ ItemType get_item_type () const override { return ItemType::NO_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TuplePatternItemsMultiple *clone_tuple_pattern_items_impl () const override
+ TuplePatternItemsNoRest *clone_pattern_items_impl () const override
{
- return new TuplePatternItemsMultiple (*this);
+ return new TuplePatternItemsNoRest (*this);
}
};
-// Class representing TuplePattern patterns where there are a range of patterns
-class TuplePatternItemsRanged : public TuplePatternItems
+// Class representing TuplePattern patterns which contains a rest pattern
+class TuplePatternItemsHasRest : public TuplePatternItems
{
std::vector<std::unique_ptr<Pattern>> lower_patterns;
std::vector<std::unique_ptr<Pattern>> upper_patterns;
public:
- TuplePatternItemsRanged (std::vector<std::unique_ptr<Pattern>> lower_patterns,
- std::vector<std::unique_ptr<Pattern>> upper_patterns)
+ TuplePatternItemsHasRest (
+ std::vector<std::unique_ptr<Pattern>> lower_patterns,
+ std::vector<std::unique_ptr<Pattern>> upper_patterns)
: lower_patterns (std::move (lower_patterns)),
upper_patterns (std::move (upper_patterns))
{}
// Copy constructor with vector clone
- TuplePatternItemsRanged (TuplePatternItemsRanged const &other)
+ TuplePatternItemsHasRest (TuplePatternItemsHasRest const &other)
{
lower_patterns.reserve (other.lower_patterns.size ());
for (const auto &e : other.lower_patterns)
@@ -1337,7 +1356,7 @@ public:
}
// Overloaded assignment operator to clone
- TuplePatternItemsRanged &operator= (TuplePatternItemsRanged const &other)
+ TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest const &other)
{
lower_patterns.clear ();
lower_patterns.reserve (other.lower_patterns.size ());
@@ -1353,8 +1372,8 @@ public:
}
// move constructors
- TuplePatternItemsRanged (TuplePatternItemsRanged &&other) = default;
- TuplePatternItemsRanged &operator= (TuplePatternItemsRanged &&other)
+ TuplePatternItemsHasRest (TuplePatternItemsHasRest &&other) = default;
+ TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest &&other)
= default;
std::string as_string () const override;
@@ -1381,17 +1400,14 @@ public:
return upper_patterns;
}
- TuplePatternItemType get_pattern_type () const override
- {
- return TuplePatternItemType::RANGED;
- }
+ ItemType get_item_type () const override { return ItemType::HAS_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TuplePatternItemsRanged *clone_tuple_pattern_items_impl () const override
+ TuplePatternItemsHasRest *clone_pattern_items_impl () const override
{
- return new TuplePatternItemsRanged (*this);
+ return new TuplePatternItemsHasRest (*this);
}
};
@@ -1508,6 +1524,12 @@ public:
return *pattern_in_parens;
}
+ std::unique_ptr<Pattern> &get_pattern_in_parens_ptr ()
+ {
+ rust_assert (pattern_in_parens != nullptr);
+ return pattern_in_parens;
+ }
+
NodeId get_node_id () const override { return node_id; }
Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Grouped; }
@@ -1522,35 +1544,18 @@ protected:
};
// Base abstract class representing patterns in a SlicePattern
-class SlicePatternItems
+class SlicePatternItems : public PatternItems
{
public:
- enum SlicePatternItemType
- {
- NO_REST,
- HAS_REST,
- };
-
- virtual ~SlicePatternItems () {}
-
- // TODO: should this store location data?
-
// Unique pointer custom clone function
std::unique_ptr<SlicePatternItems> clone_slice_pattern_items () const
{
- return std::unique_ptr<SlicePatternItems> (
- clone_slice_pattern_items_impl ());
+ return std::unique_ptr<SlicePatternItems> (clone_pattern_items_impl ());
}
- virtual std::string as_string () const = 0;
-
- virtual void accept_vis (ASTVisitor &vis) = 0;
-
- virtual SlicePatternItemType get_pattern_type () const = 0;
-
protected:
// pure virtual clone implementation
- virtual SlicePatternItems *clone_slice_pattern_items_impl () const = 0;
+ virtual SlicePatternItems *clone_pattern_items_impl () const = 0;
};
// Class representing the patterns in a SlicePattern without `..`
@@ -1598,15 +1603,12 @@ public:
return patterns;
}
- SlicePatternItemType get_pattern_type () const override
- {
- return SlicePatternItemType::NO_REST;
- }
+ ItemType get_item_type () const override { return ItemType::NO_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- SlicePatternItemsNoRest *clone_slice_pattern_items_impl () const override
+ SlicePatternItemsNoRest *clone_pattern_items_impl () const override
{
return new SlicePatternItemsNoRest (*this);
}
@@ -1683,15 +1685,12 @@ public:
return upper_patterns;
}
- SlicePatternItemType get_pattern_type () const override
- {
- return SlicePatternItemType::HAS_REST;
- }
+ ItemType get_item_type () const override { return ItemType::HAS_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- SlicePatternItemsHasRest *clone_slice_pattern_items_impl () const override
+ SlicePatternItemsHasRest *clone_pattern_items_impl () const override
{
return new SlicePatternItemsHasRest (*this);
}
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index f843a79..5fb00ef 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -201,6 +201,12 @@ public:
return *variables_pattern;
}
+ std::unique_ptr<Pattern> &get_pattern_ptr ()
+ {
+ rust_assert (variables_pattern != nullptr);
+ return variables_pattern;
+ }
+
Type &get_type ()
{
rust_assert (has_type ());
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 2a3496b..014963f 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -571,6 +571,12 @@ public:
return *type;
}
+ std::unique_ptr<TypeNoBounds> &get_type_pointed_to_ptr ()
+ {
+ rust_assert (type != nullptr);
+ return type;
+ }
+
// Getter for direct access to the type unique_ptr
std::unique_ptr<TypeNoBounds> &get_type_ptr () { return type; }
@@ -646,6 +652,12 @@ public:
return *type;
}
+ std::unique_ptr<TypeNoBounds> &get_type_referenced_ptr ()
+ {
+ rust_assert (type != nullptr);
+ return type;
+ }
+
bool get_has_mut () const { return has_mut; }
Lifetime &get_lifetime () { return lifetime.value (); }
@@ -720,6 +732,12 @@ public:
return *elem_type;
}
+ std::unique_ptr<Type> &get_elem_type_ptr ()
+ {
+ rust_assert (elem_type != nullptr);
+ return elem_type;
+ }
+
// TODO: would a "vis_expr" be better?
AnonConst &get_size_expr ()
{
@@ -986,7 +1004,7 @@ public:
return_type (std::move (type)), locus (locus)
{
if (!variadic_attrs.empty ())
- is_variadic = true;
+ _is_variadic = true;
}
// Copy constructor with clone
@@ -1044,14 +1062,24 @@ public:
return *return_type;
}
+ std::unique_ptr<TypeNoBounds> &get_return_type_ptr ()
+ {
+ rust_assert (has_return_type ());
+ return return_type;
+ }
+
FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; }
BareFunctionType *reconstruct_impl () const override
{
+ std::unique_ptr<TypeNoBounds> ret_type = nullptr;
+ if (return_type != nullptr)
+ ret_type = return_type->reconstruct ();
+
return new BareFunctionType (
for_lifetimes, function_qualifiers, params,
/* FIXME: Should params be reconstruct() as well? */
- _is_variadic, variadic_attrs, return_type->reconstruct (), locus);
+ _is_variadic, variadic_attrs, std::move (ret_type), locus);
}
protected:
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 73c34b2..d1db58e 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -32,6 +32,7 @@
#include "rust-type-util.h"
#include "rust-compile-implitem.h"
#include "rust-attribute-values.h"
+#include "rust-attributes.h"
#include "rust-immutable-name-resolution-context.h"
#include "fold-const.h"
@@ -251,25 +252,21 @@ void
HIRCompileBase::handle_link_section_attribute_on_fndecl (
tree fndecl, const AST::Attribute &attr)
{
- if (!attr.has_attr_input ())
+ auto msg_str = Analysis::Attributes::extract_string_literal (attr);
+
+ if (!msg_str.has_value ())
{
rust_error_at (attr.get_locus (),
- "%<link_section%> expects exactly one argment");
+ "malformed %<link_section%> attribute input");
return;
}
- rust_assert (attr.get_attr_input ().get_attr_input_type ()
- == AST::AttrInput::AttrInputType::LITERAL);
-
- auto &literal = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
- const auto &msg_str = literal.get_literal ().as_string ();
-
if (decl_section_name (fndecl))
{
rust_warning_at (attr.get_locus (), 0, "section name redefined");
}
- set_decl_section_name (fndecl, msg_str.c_str ());
+ set_decl_section_name (fndecl, msg_str->c_str ());
}
void
@@ -416,13 +413,10 @@ HIRCompileBase::handle_must_use_attribute_on_fndecl (tree fndecl,
if (attr.has_attr_input ())
{
- rust_assert (attr.get_attr_input ().get_attr_input_type ()
- == AST::AttrInput::AttrInputType::LITERAL);
+ auto msg_str = Analysis::Attributes::extract_string_literal (attr);
+ rust_assert (msg_str.has_value ());
- auto &literal
- = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
- const auto &msg_str = literal.get_literal ().as_string ();
- tree message = build_string (msg_str.size (), msg_str.c_str ());
+ tree message = build_string (msg_str->size (), msg_str->c_str ());
value = tree_cons (nodiscard, message, NULL_TREE);
}
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index e9b8596..3bf26af 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -56,7 +56,7 @@ protected:
TyTy::BaseType *expected, location_t lvalue_locus,
location_t rvalue_locus);
- tree coerce_to_dyn_object (tree compiled_ref, const TyTy::BaseType *actual,
+ tree coerce_to_dyn_object (tree compiled_ref, TyTy::BaseType *actual,
const TyTy::DynamicObjectType *ty,
location_t locus);
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index d4a642b..e98bbc2 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -34,6 +34,10 @@ namespace Compile {
struct fncontext
{
+ fncontext (tree fndecl, ::Bvariable *ret_addr, TyTy::BaseType *retty)
+ : fndecl (fndecl), ret_addr (ret_addr), retty (retty)
+ {}
+
tree fndecl;
::Bvariable *ret_addr;
TyTy::BaseType *retty;
@@ -154,7 +158,7 @@ public:
if (it == mono_fns.end ())
mono_fns[dId] = {};
- mono_fns[dId].push_back ({ref, fn});
+ mono_fns[dId].emplace_back (ref, fn);
}
void insert_closure_decl (const TyTy::ClosureType *ref, tree fn)
@@ -164,7 +168,7 @@ public:
if (it == mono_closure_fns.end ())
mono_closure_fns[dId] = {};
- mono_closure_fns[dId].push_back ({ref, fn});
+ mono_closure_fns[dId].emplace_back (ref, fn);
}
tree lookup_closure_decl (const TyTy::ClosureType *ref)
@@ -279,7 +283,7 @@ public:
void push_fn (tree fn, ::Bvariable *ret_addr, TyTy::BaseType *retty)
{
- fn_stack.push_back (fncontext{fn, ret_addr, retty});
+ fn_stack.emplace_back (fn, ret_addr, retty);
}
void pop_fn () { fn_stack.pop_back (); }
@@ -318,7 +322,13 @@ public:
void push_loop_context (Bvariable *var) { loop_value_stack.push_back (var); }
- Bvariable *peek_loop_context () { return loop_value_stack.back (); }
+ bool have_loop_context () const { return !loop_value_stack.empty (); }
+
+ Bvariable *peek_loop_context ()
+ {
+ rust_assert (!loop_value_stack.empty ());
+ return loop_value_stack.back ();
+ }
Bvariable *pop_loop_context ()
{
@@ -332,7 +342,11 @@ public:
loop_begin_labels.push_back (label);
}
- tree peek_loop_begin_label () { return loop_begin_labels.back (); }
+ tree peek_loop_begin_label ()
+ {
+ rust_assert (!loop_begin_labels.empty ());
+ return loop_begin_labels.back ();
+ }
tree pop_loop_begin_label ()
{
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 6433923..0a627f3 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -828,6 +828,10 @@ CompileExpr::visit (HIR::BreakExpr &expr)
{
tree compiled_expr = CompileExpr::Compile (expr.get_expr (), ctx);
+ translated = error_mark_node;
+ if (!ctx->have_loop_context ())
+ return;
+
Bvariable *loop_result_holder = ctx->peek_loop_context ();
tree result_reference
= Backend::var_expression (loop_result_holder,
@@ -891,6 +895,10 @@ CompileExpr::visit (HIR::BreakExpr &expr)
void
CompileExpr::visit (HIR::ContinueExpr &expr)
{
+ translated = error_mark_node;
+ if (!ctx->have_loop_context ())
+ return;
+
tree label = ctx->peek_loop_begin_label ();
if (expr.has_label ())
{
@@ -1647,37 +1655,39 @@ CompileExpr::compile_integer_literal (const HIR::LiteralExpr &expr,
const TyTy::BaseType *tyty)
{
rust_assert (expr.get_lit_type () == HIR::Literal::INT);
- const auto literal_value = expr.get_literal ();
-
+ const auto &literal_value = expr.get_literal ();
tree type = TyTyResolveCompile::compile (ctx, tyty);
+ std::string s = literal_value.as_string ();
+ s.erase (std::remove (s.begin (), s.end (), '_'), s.end ());
+
+ int base = 0;
mpz_t ival;
- if (mpz_init_set_str (ival, literal_value.as_string ().c_str (), 10) != 0)
+ if (mpz_init_set_str (ival, s.c_str (), base) != 0)
{
- rust_error_at (expr.get_locus (), "bad number in literal");
+ rust_error_at (expr.get_locus (), "failed to load number literal");
return error_mark_node;
}
+ if (expr.is_negative ())
+ mpz_neg (ival, ival);
- mpz_t type_min;
- mpz_t type_max;
+ mpz_t type_min, type_max;
mpz_init (type_min);
mpz_init (type_max);
get_type_static_bounds (type, type_min, type_max);
- if (expr.is_negative ())
- {
- mpz_neg (ival, ival);
- }
if (mpz_cmp (ival, type_min) < 0 || mpz_cmp (ival, type_max) > 0)
{
rust_error_at (expr.get_locus (),
"integer overflows the respective type %qs",
tyty->get_name ().c_str ());
+ mpz_clear (type_min);
+ mpz_clear (type_max);
+ mpz_clear (ival);
return error_mark_node;
}
tree result = wide_int_to_tree (type, wi::from_mpz (type, ival, true));
-
mpz_clear (type_min);
mpz_clear (type_max);
mpz_clear (ival);
@@ -2000,13 +2010,25 @@ CompileExpr::array_copied_expr (location_t expr_locus,
return error_mark_node;
}
- ctx->push_const_context ();
- tree capacity_expr = CompileExpr::Compile (elems.get_num_copies_expr (), ctx);
- ctx->pop_const_context ();
+ auto capacity_ty = array_tyty.get_capacity ();
+
+ // Check if capacity is a const type
+ if (capacity_ty->get_kind () != TyTy::TypeKind::CONST)
+ {
+ rust_error_at (array_tyty.get_locus (),
+ "array capacity is not a const type");
+ return error_mark_node;
+ }
+
+ auto *capacity_const = capacity_ty->as_const_type ();
- if (!TREE_CONSTANT (capacity_expr))
+ rust_assert (capacity_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value);
+ auto &capacity_value = *static_cast<TyTy::ConstValueType *> (capacity_const);
+ auto cap_tree = capacity_value.get_value ();
+ if (error_operand_p (cap_tree) || !TREE_CONSTANT (cap_tree))
{
- rust_error_at (expr_locus, "non const num copies %qT", array_type);
+ rust_error_at (expr_locus, "non const num copies %qT", cap_tree);
return error_mark_node;
}
@@ -2059,9 +2081,9 @@ CompileExpr::array_copied_expr (location_t expr_locus,
ctx->push_block (init_block);
tree tmp;
- tree stmts = Backend::array_initializer (fndecl, init_block, array_type,
- capacity_expr, translated_expr,
- &tmp, expr_locus);
+ tree stmts
+ = Backend::array_initializer (fndecl, init_block, array_type, cap_tree,
+ translated_expr, &tmp, expr_locus);
ctx->add_statement (stmts);
tree block = ctx->pop_block ();
@@ -2209,11 +2231,10 @@ HIRCompileBase::resolve_unsized_dyn_adjustment (
tree rvalue = expression;
location_t rvalue_locus = locus;
- const TyTy::BaseType *actual = adjustment.get_actual ();
- const TyTy::BaseType *expected = adjustment.get_expected ();
+ auto actual = adjustment.get_actual ();
+ auto expected = adjustment.get_expected ();
- const TyTy::DynamicObjectType *dyn
- = static_cast<const TyTy::DynamicObjectType *> (expected);
+ const auto dyn = static_cast<const TyTy::DynamicObjectType *> (expected);
rust_debug ("resolve_unsized_dyn_adjustment actual={%s} dyn={%s}",
actual->debug_str ().c_str (), dyn->debug_str ().c_str ());
@@ -2617,15 +2638,15 @@ CompileExpr::generate_closure_fntype (HIR::ClosureExpr &expr,
TyTy::TypeBoundPredicateItem item = TyTy::TypeBoundPredicateItem::error ();
if (predicate.get_name ().compare ("FnOnce") == 0)
{
- item = predicate.lookup_associated_item ("call_once");
+ item = predicate.lookup_associated_item ("call_once").value ();
}
else if (predicate.get_name ().compare ("FnMut") == 0)
{
- item = predicate.lookup_associated_item ("call_mut");
+ item = predicate.lookup_associated_item ("call_mut").value ();
}
else if (predicate.get_name ().compare ("Fn") == 0)
{
- item = predicate.lookup_associated_item ("call");
+ item = predicate.lookup_associated_item ("call").value ();
}
else
{
diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index d6aa589..a78f9ee 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -24,6 +24,8 @@
#include "rust-compile-type.h"
#include "rust-diagnostics.h"
#include "rust-hir-full-decls.h"
+#include "rust-attributes.h"
+#include "rust-attribute-values.h"
namespace Rust {
namespace Compile {
@@ -57,8 +59,7 @@ public:
rust_assert (ok);
std::string name = item.get_item_name ().as_string ();
- // FIXME this is assuming C ABI
- std::string asm_name = name;
+ GGC::Ident asm_name = get_link_name (item);
tree type = TyTyResolveCompile::compile (ctx, resolved_type);
bool is_external = true;
@@ -124,16 +125,7 @@ public:
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
std::string ir_symbol_name = function.get_item_name ().as_string ();
- std::string asm_name = function.get_item_name ().as_string ();
- if (fntype->get_abi () == ABI::RUST)
- {
- // then we need to get the canonical path of it and mangle it
- auto canonical_path = ctx->get_mappings ().lookup_canonical_path (
- function.get_mappings ().get_nodeid ());
-
- ir_symbol_name = canonical_path->get () + fntype->subst_as_string ();
- asm_name = ctx->mangle_item (fntype, *canonical_path);
- }
+ GGC::Ident asm_name = get_link_name (function);
const unsigned int flags = Backend::function_is_declaration;
tree fndecl = Backend::function (compiled_fn_type, ir_symbol_name, asm_name,
@@ -158,6 +150,36 @@ private:
ref_locus (ref_locus)
{}
+ template <typename T> static GGC::Ident get_link_name (T &obj)
+ {
+ AST::Attribute *use_attr = nullptr;
+
+ for (auto &attr : obj.get_outer_attrs ())
+ {
+ if (attr.get_path ().as_string () == Values::Attributes::LINK_NAME)
+ {
+ // later attributes override earlier ones
+ // TODO: add warning -- should duplicate
+ // attributes be folded elsewhere?
+ use_attr = &attr;
+ }
+ }
+
+ if (use_attr)
+ {
+ auto link_name
+ = Analysis::Attributes::extract_string_literal (*use_attr);
+
+ if (!link_name.has_value ())
+ rust_error_at (use_attr->get_locus (),
+ "malformed %<link_name%> attribute input");
+ else
+ return *link_name;
+ }
+
+ return obj.get_item_name ();
+ }
+
TyTy::BaseType *concrete;
tree reference;
location_t ref_locus;
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index fe65921..82333dc 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -27,6 +27,7 @@
#include "rust-hir-pattern.h"
#include "rust-system.h"
#include "rust-tyty.h"
+#include "tree.h"
namespace Rust {
namespace Compile {
@@ -158,13 +159,15 @@ CompilePatternCheckExpr::visit (HIR::RangePattern &pattern)
pattern.get_mappings (),
pattern.get_locus (), ctx);
+ ComparisonOperator upper_cmp = pattern.is_inclusive_range ()
+ ? ComparisonOperator::LESS_OR_EQUAL
+ : ComparisonOperator::LESS_THAN;
tree check_lower
= Backend::comparison_expression (ComparisonOperator::GREATER_OR_EQUAL,
match_scrutinee_expr, lower,
pattern.get_locus ());
tree check_upper
- = Backend::comparison_expression (ComparisonOperator::LESS_OR_EQUAL,
- match_scrutinee_expr, upper,
+ = Backend::comparison_expression (upper_cmp, match_scrutinee_expr, upper,
pattern.get_locus ());
check_expr = Backend::arithmetic_or_logical_expression (
ArithmeticOrLogicalOperator::BITWISE_AND, check_lower, check_upper,
@@ -354,17 +357,51 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
HIR::TupleStructItems &items = pattern.get_items ();
switch (items.get_item_type ())
{
- case HIR::TupleStructItems::RANGED:
+ case HIR::TupleStructItems::HAS_REST:
{
- // TODO
- rust_unreachable ();
+ HIR::TupleStructItemsHasRest &items_has_rest
+ = static_cast<HIR::TupleStructItemsHasRest &> (items);
+ size_t num_patterns = items_has_rest.get_lower_patterns ().size ()
+ + items_has_rest.get_upper_patterns ().size ();
+
+ // enums cases shouldn't reach here
+ rust_assert (num_patterns <= variant->num_fields ()
+ && (!adt->is_enum ()));
+
+ size_t tuple_field_index = 0;
+ for (auto &pattern : items_has_rest.get_lower_patterns ())
+ {
+ tree field_expr
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_field_index++,
+ pattern->get_locus ());
+ tree check_expr_sub
+ = CompilePatternCheckExpr::Compile (*pattern, field_expr, ctx);
+ check_expr = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+ check_expr_sub, pattern->get_locus ());
+ }
+ tuple_field_index = variant->num_fields ()
+ - items_has_rest.get_upper_patterns ().size ();
+ for (auto &pattern : items_has_rest.get_upper_patterns ())
+ {
+ tree field_expr
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_field_index++,
+ pattern->get_locus ());
+ tree check_expr_sub
+ = CompilePatternCheckExpr::Compile (*pattern, field_expr, ctx);
+ check_expr = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+ check_expr_sub, pattern->get_locus ());
+ }
}
break;
- case HIR::TupleStructItems::MULTIPLE:
+ case HIR::TupleStructItems::NO_REST:
{
- HIR::TupleStructItemsNoRange &items_no_range
- = static_cast<HIR::TupleStructItemsNoRange &> (items);
+ HIR::TupleStructItemsNoRest &items_no_range
+ = static_cast<HIR::TupleStructItemsNoRest &> (items);
rust_assert (items_no_range.get_patterns ().size ()
== variant->num_fields ());
@@ -428,10 +465,10 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::RANGED:
+ case HIR::TuplePatternItems::HAS_REST:
{
auto &items
- = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+ = static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
size_t tuple_field_index = 0;
// lookup the type to find out number of fields
@@ -477,10 +514,10 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
}
break;
- case HIR::TuplePatternItems::MULTIPLE:
+ case HIR::TuplePatternItems::NO_REST:
{
- auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- pattern.get_items ());
+ auto &items
+ = static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
size_t tuple_field_index = 0;
for (auto &pat : items.get_patterns ())
@@ -532,25 +569,14 @@ CompilePatternCheckExpr::visit (HIR::SlicePattern &pattern)
|| lookup->get_kind () == TyTy::TypeKind::SLICE
|| lookup->get_kind () == TyTy::REF);
- size_t array_element_index = 0;
+ // function ptr that points to either array_index_expression or
+ // slice_index_expression depending on the scrutinee's type
+ tree (*scrutinee_index_expr_func) (tree, tree, location_t) = nullptr;
+
switch (lookup->get_kind ())
{
case TyTy::TypeKind::ARRAY:
- for (auto &pattern_member : pattern.get_items ())
- {
- tree array_index_tree
- = Backend::size_constant_expression (array_element_index++);
- tree element_expr
- = Backend::array_index_expression (match_scrutinee_expr,
- array_index_tree,
- pattern.get_locus ());
- tree check_expr_sub
- = CompilePatternCheckExpr::Compile (*pattern_member, element_expr,
- ctx);
- check_expr = Backend::arithmetic_or_logical_expression (
- ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
- check_expr_sub, pattern.get_locus ());
- }
+ scrutinee_index_expr_func = Backend::array_index_expression;
break;
case TyTy::TypeKind::SLICE:
rust_sorry_at (
@@ -560,25 +586,81 @@ CompilePatternCheckExpr::visit (HIR::SlicePattern &pattern)
case TyTy::TypeKind::REF:
{
rust_assert (RS_DST_FLAG_P (TREE_TYPE (match_scrutinee_expr)));
+ scrutinee_index_expr_func = Backend::slice_index_expression;
tree size_field
= Backend::struct_field_expression (match_scrutinee_expr, 1,
pattern.get_locus ());
- // First compare the size
- check_expr = Backend::comparison_expression (
- ComparisonOperator::EQUAL, size_field,
- build_int_cst (size_type_node, pattern.get_items ().size ()),
- pattern.get_locus ());
+ // for slices, generate a dynamic size comparison expression tree
+ // because size checking is done at runtime.
+ switch (pattern.get_items ().get_item_type ())
+ {
+ case HIR::SlicePatternItems::ItemType::NO_REST:
+ {
+ auto &items = static_cast<HIR::SlicePatternItemsNoRest &> (
+ pattern.get_items ());
+ check_expr = Backend::comparison_expression (
+ ComparisonOperator::EQUAL, size_field,
+ build_int_cst (size_type_node, items.get_patterns ().size ()),
+ pattern.get_locus ());
+ }
+ break;
+ case HIR::SlicePatternItems::ItemType::HAS_REST:
+ {
+ auto &items = static_cast<HIR::SlicePatternItemsHasRest &> (
+ pattern.get_items ());
+ auto pattern_min_cap = items.get_lower_patterns ().size ()
+ + items.get_upper_patterns ().size ();
+ check_expr = Backend::comparison_expression (
+ ComparisonOperator::GREATER_OR_EQUAL, size_field,
+ build_int_cst (size_type_node, pattern_min_cap),
+ pattern.get_locus ());
+ }
+ break;
+ }
+ }
+ break;
+ default:
+ rust_unreachable ();
+ }
+
+ rust_assert (scrutinee_index_expr_func != nullptr);
- // Then compare each element in the slice pattern
- for (auto &pattern_member : pattern.get_items ())
+ // Generate tree to compare every element within array/slice
+ size_t element_index = 0;
+ switch (pattern.get_items ().get_item_type ())
+ {
+ case HIR::SlicePatternItems::ItemType::NO_REST:
+ {
+ auto &items
+ = static_cast<HIR::SlicePatternItemsNoRest &> (pattern.get_items ());
+ for (auto &pattern_member : items.get_patterns ())
{
- tree slice_index_tree
- = Backend::size_constant_expression (array_element_index++);
+ tree index_tree
+ = Backend::size_constant_expression (element_index++);
tree element_expr
- = Backend::slice_index_expression (match_scrutinee_expr,
- slice_index_tree,
- pattern.get_locus ());
+ = scrutinee_index_expr_func (match_scrutinee_expr, index_tree,
+ pattern.get_locus ());
+ tree check_expr_sub
+ = CompilePatternCheckExpr::Compile (*pattern_member, element_expr,
+ ctx);
+ check_expr = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+ check_expr_sub, pattern.get_locus ());
+ }
+ break;
+ }
+ case HIR::SlicePatternItems::ItemType::HAS_REST:
+ {
+ auto &items
+ = static_cast<HIR::SlicePatternItemsHasRest &> (pattern.get_items ());
+ for (auto &pattern_member : items.get_lower_patterns ())
+ {
+ tree index_tree
+ = Backend::size_constant_expression (element_index++);
+ tree element_expr
+ = scrutinee_index_expr_func (match_scrutinee_expr, index_tree,
+ pattern.get_locus ());
tree check_expr_sub
= CompilePatternCheckExpr::Compile (*pattern_member, element_expr,
ctx);
@@ -586,10 +668,82 @@ CompilePatternCheckExpr::visit (HIR::SlicePattern &pattern)
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
check_expr_sub, pattern.get_locus ());
}
+
+ // handle codegen for upper patterns differently for both types
+ switch (lookup->get_kind ())
+ {
+ case TyTy::TypeKind::ARRAY:
+ {
+ // for array type scrutinee, we can simply get the capacity as a
+ // const and calculate how many elements to skip
+ auto array_ty = static_cast<TyTy::ArrayType *> (lookup);
+ auto capacity_ty = array_ty->get_capacity ();
+
+ rust_assert (capacity_ty->get_kind () == TyTy::TypeKind::CONST);
+ auto *capacity_const = capacity_ty->as_const_type ();
+ rust_assert (capacity_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value);
+ auto &capacity_value
+ = *static_cast<TyTy::ConstValueType *> (capacity_const);
+ auto cap_tree = capacity_value.get_value ();
+
+ rust_assert (!error_operand_p (cap_tree));
+
+ size_t cap_wi = (size_t) wi::to_wide (cap_tree).to_uhwi ();
+ element_index = cap_wi - items.get_upper_patterns ().size ();
+ for (auto &pattern_member : items.get_upper_patterns ())
+ {
+ tree index_tree
+ = Backend::size_constant_expression (element_index++);
+ tree element_expr
+ = scrutinee_index_expr_func (match_scrutinee_expr,
+ index_tree,
+ pattern.get_locus ());
+ tree check_expr_sub
+ = CompilePatternCheckExpr::Compile (*pattern_member,
+ element_expr, ctx);
+ check_expr = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+ check_expr_sub, pattern.get_locus ());
+ }
+ }
+ break;
+ case TyTy::TypeKind::REF:
+ {
+ // for slice type scrutinee, size is dyanamic, so number of
+ // elements to skip is calculated during runtime
+ tree slice_size
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pattern.get_locus ());
+ tree upper_patterns_size = Backend::size_constant_expression (
+ items.get_upper_patterns ().size ());
+ tree index_tree = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::SUBTRACT, slice_size,
+ upper_patterns_size, pattern.get_locus ());
+ for (auto &pattern_member : items.get_upper_patterns ())
+ {
+ tree element_expr
+ = scrutinee_index_expr_func (match_scrutinee_expr,
+ index_tree,
+ pattern.get_locus ());
+ tree check_expr_sub
+ = CompilePatternCheckExpr::Compile (*pattern_member,
+ element_expr, ctx);
+ check_expr = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+ check_expr_sub, pattern.get_locus ());
+ index_tree = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::ADD, index_tree,
+ Backend::size_constant_expression (1),
+ pattern.get_locus ());
+ }
+ }
+ break;
+ default:
+ rust_unreachable ();
+ }
}
break;
- default:
- rust_unreachable ();
}
}
@@ -628,25 +782,54 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
HIR::TupleStructItems &items = pattern.get_items ();
switch (items.get_item_type ())
{
- case HIR::TupleStructItems::RANGED:
+ case HIR::TupleStructItems::HAS_REST:
{
- // TODO
- rust_unreachable ();
+ HIR::TupleStructItemsHasRest &items_has_rest
+ = static_cast<HIR::TupleStructItemsHasRest &> (items);
+ size_t num_patterns = items_has_rest.get_lower_patterns ().size ()
+ + items_has_rest.get_upper_patterns ().size ();
+
+ // enums cases shouldn't reach here
+ rust_assert (num_patterns <= variant->num_fields ()
+ && (!adt->is_enum ()));
+
+ size_t tuple_field_index = 0;
+ for (auto &pattern : items_has_rest.get_lower_patterns ())
+ {
+ tree binding
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_field_index++,
+ pattern->get_locus ());
+
+ CompilePatternBindings::Compile (*pattern, binding, ctx);
+ }
+
+ tuple_field_index = variant->num_fields ()
+ - items_has_rest.get_upper_patterns ().size ();
+
+ for (auto &pattern : items_has_rest.get_upper_patterns ())
+ {
+ tree binding
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_field_index++,
+ pattern->get_locus ());
+
+ CompilePatternBindings::Compile (*pattern, binding, ctx);
+ }
}
break;
- case HIR::TupleStructItems::MULTIPLE:
+ case HIR::TupleStructItems::NO_REST:
{
- HIR::TupleStructItemsNoRange &items_no_range
- = static_cast<HIR::TupleStructItemsNoRange &> (items);
-
- rust_assert (items_no_range.get_patterns ().size ()
+ HIR::TupleStructItemsNoRest &items_no_rest
+ = static_cast<HIR::TupleStructItemsNoRest &> (items);
+ rust_assert (items_no_rest.get_patterns ().size ()
== variant->num_fields ());
if (adt->is_enum ())
{
size_t tuple_field_index = 0;
- for (auto &pattern : items_no_range.get_patterns ())
+ for (auto &pattern : items_no_rest.get_patterns ())
{
tree payload_accessor_union
= Backend::struct_field_expression (match_scrutinee_expr, 1,
@@ -668,12 +851,10 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
else
{
size_t tuple_field_index = 0;
- for (auto &pattern : items_no_range.get_patterns ())
+ for (auto &pattern : items_no_rest.get_patterns ())
{
- tree variant_accessor = match_scrutinee_expr;
-
tree binding
- = Backend::struct_field_expression (variant_accessor,
+ = Backend::struct_field_expression (match_scrutinee_expr,
tuple_field_index++,
pattern->get_locus ());
@@ -777,8 +958,9 @@ CompilePatternBindings::visit (HIR::StructPattern &pattern)
rust_assert (ok);
}
- rust_assert (variant->get_variant_type ()
- == TyTy::VariantDef::VariantType::STRUCT);
+ rust_assert (
+ variant->get_variant_type () == TyTy::VariantDef::VariantType::STRUCT
+ || variant->get_variant_type () == TyTy::VariantDef::VariantType::TUPLE);
auto &struct_pattern_elems = pattern.get_struct_pattern_elems ();
for (auto &field : struct_pattern_elems.get_struct_pattern_fields ())
@@ -843,11 +1025,11 @@ CompilePatternBindings::visit (HIR::TuplePattern &pattern)
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::ItemType::RANGED:
+ case HIR::TuplePatternItems::ItemType::HAS_REST:
{
size_t tuple_idx = 0;
auto &items
- = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+ = static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
auto &items_lower = items.get_lower_patterns ();
auto &items_upper = items.get_upper_patterns ();
@@ -887,11 +1069,11 @@ CompilePatternBindings::visit (HIR::TuplePattern &pattern)
return;
}
- case HIR::TuplePatternItems::ItemType::MULTIPLE:
+ case HIR::TuplePatternItems::ItemType::NO_REST:
{
size_t tuple_idx = 0;
- auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- pattern.get_items ());
+ auto &items
+ = static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
for (auto &sub : items.get_patterns ())
{
@@ -930,43 +1112,132 @@ CompilePatternBindings::visit (HIR::SlicePattern &pattern)
|| lookup->get_kind () == TyTy::TypeKind::SLICE
|| lookup->get_kind () == TyTy::REF);
- size_t array_element_index = 0;
+ // function ptr that points to either array_index_expression or
+ // slice_index_expression depending on the scrutinee's type
+ tree (*scrutinee_index_expr_func) (tree, tree, location_t) = nullptr;
+
switch (lookup->get_kind ())
{
case TyTy::TypeKind::ARRAY:
- for (auto &pattern_member : pattern.get_items ())
- {
- tree array_index_tree
- = Backend::size_constant_expression (array_element_index++);
- tree element_expr
- = Backend::array_index_expression (match_scrutinee_expr,
- array_index_tree,
- pattern.get_locus ());
- CompilePatternBindings::Compile (*pattern_member, element_expr, ctx);
- }
+ scrutinee_index_expr_func = Backend::array_index_expression;
break;
case TyTy::TypeKind::SLICE:
- rust_sorry_at (
- pattern.get_locus (),
- "SlicePattern matching against non-ref slices are not yet supported");
+ rust_sorry_at (pattern.get_locus (),
+ "SlicePattern matching against non-ref slices are "
+ "not yet supported");
break;
case TyTy::TypeKind::REF:
+ scrutinee_index_expr_func = Backend::slice_index_expression;
+ break;
+ default:
+ rust_unreachable ();
+ }
+
+ rust_assert (scrutinee_index_expr_func != nullptr);
+
+ size_t element_index = 0;
+
+ switch (pattern.get_items ().get_item_type ())
+ {
+ case HIR::SlicePatternItems::ItemType::NO_REST:
{
- for (auto &pattern_member : pattern.get_items ())
+ auto &items
+ = static_cast<HIR::SlicePatternItemsNoRest &> (pattern.get_items ());
+ for (auto &pattern_member : items.get_patterns ())
{
- tree slice_index_tree
- = Backend::size_constant_expression (array_element_index++);
+ tree index_tree
+ = Backend::size_constant_expression (element_index++);
tree element_expr
- = Backend::slice_index_expression (match_scrutinee_expr,
- slice_index_tree,
- pattern.get_locus ());
+ = scrutinee_index_expr_func (match_scrutinee_expr, index_tree,
+ pattern.get_locus ());
CompilePatternBindings::Compile (*pattern_member, element_expr,
ctx);
}
- break;
}
- default:
- rust_unreachable ();
+ break;
+ case HIR::SlicePatternItems::ItemType::HAS_REST:
+ {
+ auto &items
+ = static_cast<HIR::SlicePatternItemsHasRest &> (pattern.get_items ());
+ for (auto &pattern_member : items.get_lower_patterns ())
+ {
+ tree index_tree
+ = Backend::size_constant_expression (element_index++);
+ tree element_expr
+ = scrutinee_index_expr_func (match_scrutinee_expr, index_tree,
+ pattern.get_locus ());
+ CompilePatternBindings::Compile (*pattern_member, element_expr,
+ ctx);
+ }
+
+ // handle codegen for upper patterns differently for both types
+ switch (lookup->get_kind ())
+ {
+ case TyTy::TypeKind::ARRAY:
+ {
+ auto array_ty = static_cast<TyTy::ArrayType *> (lookup);
+ auto capacity_ty = array_ty->get_capacity ();
+
+ rust_assert (capacity_ty->get_kind () == TyTy::TypeKind::CONST);
+ auto *capacity_const = capacity_ty->as_const_type ();
+ rust_assert (capacity_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value);
+ auto &capacity_value
+ = *static_cast<TyTy::ConstValueType *> (capacity_const);
+ auto cap_tree = capacity_value.get_value ();
+
+ rust_assert (!error_operand_p (cap_tree));
+
+ size_t cap_wi = (size_t) wi::to_wide (cap_tree).to_uhwi ();
+ element_index = cap_wi - items.get_upper_patterns ().size ();
+ for (auto &pattern_member : items.get_upper_patterns ())
+ {
+ tree index_tree
+ = Backend::size_constant_expression (element_index++);
+ tree element_expr
+ = scrutinee_index_expr_func (match_scrutinee_expr,
+ index_tree,
+ pattern.get_locus ());
+ CompilePatternBindings::Compile (*pattern_member,
+ element_expr, ctx);
+ }
+ }
+ break;
+ case TyTy::TypeKind::SLICE:
+ rust_sorry_at (pattern.get_locus (),
+ "SlicePattern matching against non-ref slices are "
+ "not yet supported");
+ break;
+ case TyTy::TypeKind::REF:
+ {
+ tree slice_size
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pattern.get_locus ());
+ tree upper_patterns_size = Backend::size_constant_expression (
+ items.get_upper_patterns ().size ());
+ tree index_tree = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::SUBTRACT, slice_size,
+ upper_patterns_size, pattern.get_locus ());
+ for (auto &pattern_member : items.get_upper_patterns ())
+ {
+ tree element_expr
+ = scrutinee_index_expr_func (match_scrutinee_expr,
+ index_tree,
+ pattern.get_locus ());
+ CompilePatternBindings::Compile (*pattern_member,
+ element_expr, ctx);
+ index_tree = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::ADD, index_tree,
+ Backend::size_constant_expression (1),
+ pattern.get_locus ());
+ }
+ }
+ break;
+ default:
+ rust_unreachable ();
+ }
+ }
+ break;
}
}
@@ -979,6 +1250,11 @@ CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
rust_assert (
ctx->lookup_var_decl (pattern.get_mappings ().get_hirid (), &var));
+ if (pattern.get_is_ref ())
+ {
+ init_expr = address_expression (init_expr, EXPR_LOCATION (init_expr));
+ }
+
auto fnctx = ctx->peek_fn ();
if (ty->is_unit ())
{
@@ -990,6 +1266,11 @@ CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
}
else
{
+ if (pattern.has_subpattern ())
+ {
+ CompilePatternLet::Compile (&pattern.get_subpattern (), init_expr, ty,
+ rval_locus, ctx);
+ }
auto s = Backend::init_statement (fnctx.fndecl, var, init_expr);
ctx->add_statement (s);
}
@@ -1013,22 +1294,65 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
{
rust_assert (pattern.has_tuple_pattern_items ());
- tree tuple_type = TyTyResolveCompile::compile (ctx, ty);
+ bool has_by_ref = false;
+ auto check_refs
+ = [] (const std::vector<std::unique_ptr<HIR::Pattern>> &patterns) {
+ for (const auto &sub : patterns)
+ {
+ switch (sub->get_pattern_type ())
+ {
+ case HIR::Pattern::PatternType::IDENTIFIER:
+ {
+ auto id = static_cast<HIR::IdentifierPattern *> (sub.get ());
+ if (id->get_is_ref ())
+ return true;
+ break;
+ }
+ case HIR::Pattern::PatternType::REFERENCE:
+ return true;
+ default:
+ break;
+ }
+ }
+ return false;
+ };
+ switch (pattern.get_items ().get_item_type ())
+ {
+ case HIR::TuplePatternItems::ItemType::NO_REST:
+ {
+ auto &items
+ = static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
+ has_by_ref = check_refs (items.get_patterns ());
+ break;
+ }
+ case HIR::TuplePatternItems::ItemType::HAS_REST:
+ {
+ auto &items
+ = static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
+ has_by_ref = check_refs (items.get_lower_patterns ())
+ || check_refs (items.get_upper_patterns ());
+ break;
+ }
+ default:
+ break;
+ }
+
+ tree rhs_tuple_type = TYPE_MAIN_VARIANT (TREE_TYPE (init_expr));
tree init_stmt;
Bvariable *tmp_var
= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
- tuple_type, init_expr, false,
+ rhs_tuple_type, init_expr, has_by_ref,
pattern.get_locus (), &init_stmt);
tree access_expr = Backend::var_expression (tmp_var, pattern.get_locus ());
ctx->add_statement (init_stmt);
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::ItemType::RANGED:
+ case HIR::TuplePatternItems::ItemType::HAS_REST:
{
size_t tuple_idx = 0;
auto &items
- = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+ = static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
auto &items_lower = items.get_lower_patterns ();
auto &items_upper = items.get_upper_patterns ();
@@ -1069,11 +1393,11 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
return;
}
- case HIR::TuplePatternItems::ItemType::MULTIPLE:
+ case HIR::TuplePatternItems::ItemType::NO_REST:
{
size_t tuple_idx = 0;
- auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- pattern.get_items ());
+ auto &items
+ = static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
for (auto &sub : items.get_patterns ())
{
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index f3b9dc2..c33d0b0 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -97,8 +97,11 @@ ResolvePathRef::attempt_constructor_expression_lookup (
// this can only be for discriminant variants the others are built up
// using call-expr or struct-init
- rust_assert (variant->get_variant_type ()
- == TyTy::VariantDef::VariantType::NUM);
+ if (variant->get_variant_type () != TyTy::VariantDef::VariantType::NUM)
+ {
+ rust_error_at (expr_locus, "variant expected constructor call");
+ return error_mark_node;
+ }
// we need the actual gcc type
tree compiled_adt_type = TyTyResolveCompile::compile (ctx, adt);
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index 0622954..5b00afa 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -136,13 +136,31 @@ TyTyResolveCompile::visit (const TyTy::InferType &type)
}
void
-TyTyResolveCompile::visit (const TyTy::ParamType &)
+TyTyResolveCompile::visit (const TyTy::ParamType &type)
{
translated = error_mark_node;
}
void
-TyTyResolveCompile::visit (const TyTy::ConstType &)
+TyTyResolveCompile::visit (const TyTy::ConstParamType &type)
+{
+ translated = error_mark_node;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ConstValueType &type)
+{
+ translated = error_mark_node;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ConstInferType &type)
+{
+ translated = error_mark_node;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ConstErrorType &type)
{
translated = error_mark_node;
}
@@ -186,8 +204,8 @@ TyTyResolveCompile::visit (const TyTy::ClosureType &type)
// this should be based on the closure move-ability
tree decl_type = TyTyResolveCompile::compile (ctx, lookup);
tree capture_type = build_reference_type (decl_type);
- fields.push_back (Backend::typed_identifier (mappings_name, capture_type,
- type.get_ident ().locus));
+ fields.emplace_back (mappings_name, capture_type,
+ type.get_ident ().locus);
}
tree type_record = Backend::struct_type (fields);
@@ -217,8 +235,7 @@ TyTyResolveCompile::visit (const TyTy::FnType &type)
auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
location_t return_type_locus
= ctx->get_mappings ().lookup_location (hir_type->get_ref ());
- results.push_back (
- Backend::typed_identifier ("_", ret, return_type_locus));
+ results.emplace_back ("_", ret, return_type_locus);
}
for (auto &param_pair : type.get_params ())
@@ -227,11 +244,10 @@ TyTyResolveCompile::visit (const TyTy::FnType &type)
auto compiled_param_type
= TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
- auto compiled_param = Backend::typed_identifier (
- param_pair.get_pattern ().as_string (), compiled_param_type,
- ctx->get_mappings ().lookup_location (param_tyty->get_ref ()));
-
- parameters.push_back (compiled_param);
+ parameters.emplace_back (param_pair.get_pattern ().as_string (),
+ compiled_param_type,
+ ctx->get_mappings ().lookup_location (
+ param_tyty->get_ref ()));
}
if (!type.is_variadic ())
@@ -277,10 +293,9 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
tree compiled_field_ty
= TyTyResolveCompile::compile (ctx, field->get_field_type ());
- Backend::typed_identifier f (field->get_name (), compiled_field_ty,
- ctx->get_mappings ().lookup_location (
- type.get_ty_ref ()));
- fields.push_back (std::move (f));
+ fields.emplace_back (field->get_name (), compiled_field_ty,
+ ctx->get_mappings ().lookup_location (
+ type.get_ty_ref ()));
}
type_record = type.is_union () ? Backend::union_type (fields, false)
@@ -357,10 +372,9 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
== TyTy::VariantDef::VariantType::TUPLE)
field_name = "__" + field->get_name ();
- Backend::typed_identifier f (
- field_name, compiled_field_ty,
- ctx->get_mappings ().lookup_location (type.get_ty_ref ()));
- fields.push_back (std::move (f));
+ fields.emplace_back (field_name, compiled_field_ty,
+ ctx->get_mappings ().lookup_location (
+ type.get_ty_ref ()));
}
tree variant_record = Backend::struct_type (fields);
@@ -382,10 +396,9 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
TyTy::VariantDef *variant = type.get_variants ().at (i++);
std::string implicit_variant_name = variant->get_identifier ();
- Backend::typed_identifier f (implicit_variant_name, variant_record,
- ctx->get_mappings ().lookup_location (
- type.get_ty_ref ()));
- enum_fields.push_back (std::move (f));
+ enum_fields.emplace_back (implicit_variant_name, variant_record,
+ ctx->get_mappings ().lookup_location (
+ type.get_ty_ref ()));
}
//
@@ -460,10 +473,9 @@ TyTyResolveCompile::visit (const TyTy::TupleType &type)
// this, rather than simply emitting the integer, is that this
// approach makes it simpler to use a C-only debugger, or
// GDB's C mode, when debugging Rust.
- Backend::typed_identifier f ("__" + std::to_string (i), compiled_field_ty,
- ctx->get_mappings ().lookup_location (
- type.get_ty_ref ()));
- fields.push_back (std::move (f));
+ fields.emplace_back ("__" + std::to_string (i), compiled_field_ty,
+ ctx->get_mappings ().lookup_location (
+ type.get_ty_ref ()));
}
tree struct_type_record = Backend::struct_type (fields);
@@ -476,8 +488,22 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type)
{
tree element_type
= TyTyResolveCompile::compile (ctx, type.get_element_type ());
- TyTy::ConstType *const_capacity = type.get_capacity ();
- tree folded_capacity_expr = const_capacity->get_value ();
+ auto const_capacity = type.get_capacity ();
+
+ // Check if capacity is a const type
+ if (const_capacity->get_kind () != TyTy::TypeKind::CONST)
+ {
+ rust_error_at (type.get_locus (), "array capacity is not a const type");
+ translated = error_mark_node;
+ return;
+ }
+
+ auto *capacity_const = const_capacity->as_const_type ();
+
+ rust_assert (capacity_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value);
+ auto &capacity_value = *static_cast<TyTy::ConstValueType *> (capacity_const);
+ auto folded_capacity_expr = capacity_value.get_value ();
// build_index_type takes the maximum index, which is one less than
// the length.
@@ -772,17 +798,15 @@ TyTyResolveCompile::create_dyn_obj_record (const TyTy::DynamicObjectType &type)
tree uint = Backend::integer_type (true, Backend::get_pointer_size ());
tree uintptr_ty = build_pointer_type (uint);
- Backend::typed_identifier f ("pointer", uintptr_ty,
- ctx->get_mappings ().lookup_location (
- type.get_ty_ref ()));
- fields.push_back (std::move (f));
+ fields.emplace_back ("pointer", uintptr_ty,
+ ctx->get_mappings ().lookup_location (
+ type.get_ty_ref ()));
tree vtable_size = build_int_cst (size_type_node, items.size ());
tree vtable_type = Backend::array_type (uintptr_ty, vtable_size);
- Backend::typed_identifier vtf ("vtable", vtable_type,
- ctx->get_mappings ().lookup_location (
- type.get_ty_ref ()));
- fields.push_back (std::move (vtf));
+ fields.emplace_back ("vtable", vtable_type,
+ ctx->get_mappings ().lookup_location (
+ type.get_ty_ref ()));
tree record = Backend::struct_type (fields);
RS_DST_FLAG (record) = 1;
diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h
index 0675343..d6c3259 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -50,7 +50,10 @@ public:
void visit (const TyTy::ReferenceType &) override;
void visit (const TyTy::PointerType &) override;
void visit (const TyTy::ParamType &) override;
- void visit (const TyTy::ConstType &) override;
+ void visit (const TyTy::ConstParamType &) override;
+ void visit (const TyTy::ConstValueType &) override;
+ void visit (const TyTy::ConstInferType &) override;
+ void visit (const TyTy::ConstErrorType &) override;
void visit (const TyTy::StrType &) override;
void visit (const TyTy::NeverType &) override;
void visit (const TyTy::PlaceholderType &) override;
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index 5c6d145..1f306ad 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -64,31 +64,79 @@ public:
ctx->insert_var_decl (stmt_id, var);
vars.push_back (var);
+
+ if (pattern.has_subpattern ())
+ {
+ auto subpattern_vars
+ = CompileVarDecl::compile (fndecl, translated_type,
+ &pattern.get_subpattern (), ctx);
+ vars.insert (vars.end (), subpattern_vars.begin (),
+ subpattern_vars.end ());
+ }
}
void visit (HIR::TuplePattern &pattern) override
{
+ rust_assert (TREE_CODE (translated_type) == RECORD_TYPE);
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::ItemType::MULTIPLE:
+ case HIR::TuplePatternItems::ItemType::NO_REST:
{
- rust_assert (TREE_CODE (translated_type) == RECORD_TYPE);
- auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
+ auto &items_no_rest = static_cast<HIR::TuplePatternItemsNoRest &> (
pattern.get_items ());
- size_t offs = 0;
- for (auto &sub : items.get_patterns ())
+ tree field = TYPE_FIELDS (translated_type);
+ for (auto &sub : items_no_rest.get_patterns ())
{
- tree sub_ty = error_mark_node;
- tree field = TYPE_FIELDS (translated_type);
- for (size_t i = 0; i < offs; i++)
+ gcc_assert (field != NULL_TREE);
+ tree sub_ty = TREE_TYPE (field);
+ CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
+ field = DECL_CHAIN (field);
+ }
+ }
+ break;
+
+ case HIR::TuplePatternItems::ItemType::HAS_REST:
+ {
+ auto &items_has_rest = static_cast<HIR::TuplePatternItemsHasRest &> (
+ pattern.get_items ());
+
+ // count total fields in translated_type
+ size_t total_fields = 0;
+ for (tree t = TYPE_FIELDS (translated_type); t; t = DECL_CHAIN (t))
+ {
+ total_fields++;
+ }
+
+ // process lower patterns
+ tree field = TYPE_FIELDS (translated_type);
+ for (auto &sub : items_has_rest.get_lower_patterns ())
+ {
+ gcc_assert (field != NULL_TREE);
+ tree sub_ty = TREE_TYPE (field);
+ CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
+ field = DECL_CHAIN (field);
+ }
+
+ // process upper patterns
+ if (!items_has_rest.get_upper_patterns ().empty ())
+ {
+ size_t upper_start
+ = total_fields - items_has_rest.get_upper_patterns ().size ();
+ field = TYPE_FIELDS (translated_type);
+ for (size_t i = 0; i < upper_start; i++)
{
field = DECL_CHAIN (field);
gcc_assert (field != NULL_TREE);
}
- sub_ty = TREE_TYPE (field);
- CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
- offs++;
+
+ for (auto &sub : items_has_rest.get_upper_patterns ())
+ {
+ gcc_assert (field != NULL_TREE);
+ tree sub_ty = TREE_TYPE (field);
+ CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
+ field = DECL_CHAIN (field);
+ }
}
}
break;
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index dbd8515..40f16e4 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -183,8 +183,7 @@ HIRCompileBase::coercion_site1 (tree rvalue, TyTy::BaseType *rval,
}
tree
-HIRCompileBase::coerce_to_dyn_object (tree compiled_ref,
- const TyTy::BaseType *actual,
+HIRCompileBase::coerce_to_dyn_object (tree compiled_ref, TyTy::BaseType *actual,
const TyTy::DynamicObjectType *ty,
location_t locus)
{
@@ -201,9 +200,7 @@ HIRCompileBase::coerce_to_dyn_object (tree compiled_ref,
// __trait_object_ptr
// [list of function ptrs]
- std::vector<std::pair<Resolver::TraitReference *, HIR::ImplBlock *>>
- probed_bounds_for_receiver = Resolver::TypeBoundsProbe::Probe (actual);
-
+ auto probed_bounds_for_receiver = Resolver::TypeBoundsProbe::Probe (actual);
tree address_of_compiled_ref = null_pointer_node;
if (!actual->is_unit ())
address_of_compiled_ref = address_expression (compiled_ref, locus);
@@ -241,12 +238,13 @@ HIRCompileBase::compute_address_for_trait_item (
&receiver_bounds,
const TyTy::BaseType *receiver, const TyTy::BaseType *root, location_t locus)
{
- TyTy::TypeBoundPredicateItem predicate_item
+ tl::optional<TyTy::TypeBoundPredicateItem> predicate_item
= predicate->lookup_associated_item (ref->get_identifier ());
- rust_assert (!predicate_item.is_error ());
+ rust_assert (predicate_item.has_value ());
// This is the expected end type
- TyTy::BaseType *trait_item_type = predicate_item.get_tyty_for_receiver (root);
+ TyTy::BaseType *trait_item_type
+ = predicate_item->get_tyty_for_receiver (root);
rust_assert (trait_item_type->get_kind () == TyTy::TypeKind::FNDEF);
TyTy::FnType *trait_item_fntype
= static_cast<TyTy::FnType *> (trait_item_type);
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index d524d09..d04f864 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -101,12 +101,54 @@ struct constexpr_global_ctx
auto_vec<tree, 16> heap_vars;
/* Cleanups that need to be evaluated at the end of CLEANUP_POINT_EXPR. */
vec<tree> *cleanups;
+ /* If non-null, only allow modification of existing values of the variables
+ in this set. Set by modifiable_tracker, below. */
+ hash_set<tree> *modifiable;
/* Number of heap VAR_DECL deallocations. */
unsigned heap_dealloc_count;
/* Constructor. */
constexpr_global_ctx ()
: constexpr_ops_count (0), cleanups (NULL), heap_dealloc_count (0)
{}
+
+ tree get_value (tree t)
+ {
+ if (tree *p = values.get (t))
+ if (*p != void_node)
+ return *p;
+ return NULL_TREE;
+ }
+ tree *get_value_ptr (tree t, bool initializing)
+ {
+ if (modifiable && !modifiable->contains (t))
+ return nullptr;
+ if (tree *p = values.get (t))
+ {
+ if (*p != void_node)
+ return p;
+ else if (initializing)
+ {
+ *p = NULL_TREE;
+ return p;
+ }
+ }
+ return nullptr;
+ }
+ void put_value (tree t, tree v)
+ {
+ bool already_in_map = values.put (t, v);
+ if (!already_in_map && modifiable)
+ modifiable->add (t);
+ }
+ void destroy_value (tree t)
+ {
+ if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL
+ || TREE_CODE (t) == RESULT_DECL)
+ values.put (t, void_node);
+ else
+ values.remove (t);
+ }
+ void clear_value (tree t) { values.remove (t); }
};
/* In constexpr.cc */
@@ -457,23 +499,24 @@ save_fundef_copy (tree fun, tree copy)
static tree constant_value_1 (tree decl, bool strict_p,
bool return_aggregate_cst_ok_p, bool unshare_p);
+static tree decl_really_constant_value (tree decl, bool unshare_p /*= true*/);
tree decl_constant_value (tree decl, bool unshare_p);
static void non_const_var_error (location_t loc, tree r);
static tree eval_constant_expression (const constexpr_ctx *ctx, tree, bool,
- bool *, bool *, tree * = NULL);
+ bool *, bool *, tree *jump_target);
static tree constexpr_fn_retval (const constexpr_ctx *ctx, tree r);
static tree eval_store_expression (const constexpr_ctx *ctx, tree r, bool,
- bool *, bool *);
+ bool *, bool *, tree *jump_target);
static tree eval_call_expression (const constexpr_ctx *ctx, tree r, bool,
- bool *, bool *);
+ bool *, bool *, tree *);
static tree eval_binary_expression (const constexpr_ctx *ctx, tree r, bool,
- bool *, bool *);
+ bool *, bool *, tree *jump_target);
static tree get_function_named_in_call (tree t);
@@ -488,7 +531,8 @@ static tree eval_conditional_expression (const constexpr_ctx *ctx, tree t,
bool *overflow_p, tree *jump_target);
static tree eval_bit_field_ref (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p);
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target);
static tree eval_loop_expr (const constexpr_ctx *ctx, tree t,
bool *non_constant_p, bool *overflow_p,
@@ -500,7 +544,15 @@ static tree eval_switch_expr (const constexpr_ctx *ctx, tree t,
static tree eval_unary_expression (const constexpr_ctx *ctx, tree t,
bool /*lval*/, bool *non_constant_p,
- bool *overflow_p);
+ bool *overflow_p, tree *jump_target);
+static bool eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
+ enum tree_code code, tree type, tree lhs,
+ tree rhs);
+static tree fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
+ tree lhs, tree rhs,
+ bool *non_constant_p,
+ bool *overflow_p, tree *jump_target);
+static tree maybe_fold_addr_pointer_plus (tree t);
/* Variables and functions to manage constexpr call expansion context.
These do not need to be marked for PCH or GC. */
@@ -562,8 +614,9 @@ fold_expr (tree expr)
bool non_constant_p = false;
bool overflow_p = false;
+ tree jump_target = NULL_TREE;
tree folded = eval_constant_expression (&ctx, expr, false, &non_constant_p,
- &overflow_p);
+ &overflow_p, &jump_target);
rust_assert (folded != NULL_TREE);
// more logic here to possibly port
@@ -589,13 +642,13 @@ same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2)
otherwise return NULL_TREE. */
static tree
-union_active_member (const constexpr_ctx *ctx, tree t)
+union_active_member (const constexpr_ctx *ctx, tree t, tree *jump_target)
{
constexpr_ctx new_ctx = *ctx;
new_ctx.quiet = true;
bool non_constant_p = false, overflow_p = false;
tree ctor = eval_constant_expression (&new_ctx, t, false, &non_constant_p,
- &overflow_p);
+ &overflow_p, jump_target);
if (TREE_CODE (ctor) == CONSTRUCTOR && CONSTRUCTOR_NELTS (ctor) == 1
&& CONSTRUCTOR_ELT (ctor, 0)->index
&& TREE_CODE (CONSTRUCTOR_ELT (ctor, 0)->index) == FIELD_DECL)
@@ -607,7 +660,8 @@ union_active_member (const constexpr_ctx *ctx, tree t)
static tree
fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
- tree op, unsigned HOST_WIDE_INT off, bool *empty_base)
+ tree op, unsigned HOST_WIDE_INT off, bool *empty_base,
+ tree *jump_target)
{
tree optype = TREE_TYPE (op);
unsigned HOST_WIDE_INT const_nunits;
@@ -654,7 +708,8 @@ fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
tree index = size_int (idx + tree_to_uhwi (min_val));
op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
NULL_TREE, NULL_TREE);
- return fold_indirect_ref_1 (ctx, loc, type, op, rem, empty_base);
+ return fold_indirect_ref_1 (ctx, loc, type, op, rem, empty_base,
+ jump_target);
}
}
/* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
@@ -663,7 +718,7 @@ fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
{
if (TREE_CODE (optype) == UNION_TYPE)
/* For unions prefer the currently active member. */
- if (tree field = union_active_member (ctx, op))
+ if (tree field = union_active_member (ctx, op, jump_target))
{
unsigned HOST_WIDE_INT el_sz
= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
@@ -672,7 +727,7 @@ fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
tree cop = build3 (COMPONENT_REF, TREE_TYPE (field), op, field,
NULL_TREE);
if (tree ret = fold_indirect_ref_1 (ctx, loc, type, cop, off,
- empty_base))
+ empty_base, jump_target))
return ret;
}
}
@@ -691,8 +746,9 @@ fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
{
tree cop = build3 (COMPONENT_REF, TREE_TYPE (field), op, field,
NULL_TREE);
- if (tree ret = fold_indirect_ref_1 (ctx, loc, type, cop,
- off - upos, empty_base))
+ if (tree ret
+ = fold_indirect_ref_1 (ctx, loc, type, cop, off - upos,
+ empty_base, jump_target))
return ret;
}
}
@@ -721,7 +777,7 @@ fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
static tree
rs_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
- tree op0, bool *empty_base)
+ tree op0, bool *empty_base, tree *jump_target)
{
tree sub = op0;
tree subtype;
@@ -780,7 +836,8 @@ rs_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
tree off = integer_zero_node;
canonicalize_obj_off (op, off);
gcc_assert (integer_zerop (off));
- return fold_indirect_ref_1 (ctx, loc, type, op, 0, empty_base);
+ return fold_indirect_ref_1 (ctx, loc, type, op, 0, empty_base,
+ jump_target);
}
}
else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
@@ -795,7 +852,7 @@ rs_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
tree obj = TREE_OPERAND (op00, 0);
canonicalize_obj_off (obj, off);
return fold_indirect_ref_1 (ctx, loc, type, obj, tree_to_uhwi (off),
- empty_base);
+ empty_base, jump_target);
}
}
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
@@ -804,8 +861,8 @@ rs_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
{
tree type_domain;
tree min_val = size_zero_node;
- tree newsub
- = rs_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub, NULL);
+ tree newsub = rs_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub,
+ NULL, jump_target);
if (newsub)
sub = newsub;
else
@@ -824,7 +881,7 @@ rs_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
static tree
rs_eval_indirect_ref (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p, tree *jump_target)
{
tree orig_op0 = TREE_OPERAND (t, 0);
bool empty_base = false;
@@ -842,13 +899,13 @@ rs_eval_indirect_ref (const constexpr_ctx *ctx, tree t, bool lval,
/* First try to simplify it directly. */
tree r = rs_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
- orig_op0, &empty_base);
+ orig_op0, &empty_base, jump_target);
if (!r)
{
/* If that didn't work, evaluate the operand first. */
- tree op0
- = eval_constant_expression (ctx, orig_op0,
- /*lval*/ false, non_constant_p, overflow_p);
+ tree op0 = eval_constant_expression (ctx, orig_op0,
+ /*lval*/ false, non_constant_p,
+ overflow_p, jump_target);
/* Don't VERIFY_CONSTANT here. */
if (*non_constant_p)
return t;
@@ -862,7 +919,7 @@ rs_eval_indirect_ref (const constexpr_ctx *ctx, tree t, bool lval,
}
r = rs_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), op0,
- &empty_base);
+ &empty_base, jump_target);
if (r == NULL_TREE)
{
/* We couldn't fold to a constant value. Make sure it's not
@@ -891,7 +948,8 @@ rs_eval_indirect_ref (const constexpr_ctx *ctx, tree t, bool lval,
}
}
- r = eval_constant_expression (ctx, r, lval, non_constant_p, overflow_p);
+ r = eval_constant_expression (ctx, r, lval, non_constant_p, overflow_p,
+ jump_target);
if (*non_constant_p)
return t;
@@ -917,17 +975,17 @@ rs_eval_indirect_ref (const constexpr_ctx *ctx, tree t, bool lval,
static tree
eval_logical_expression (const constexpr_ctx *ctx, tree t, tree bailout_value,
tree continue_value, bool lval, bool *non_constant_p,
- bool *overflow_p)
+ bool *overflow_p, tree *jump_target)
{
tree r;
tree lhs = eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p, jump_target);
VERIFY_CONSTANT (lhs);
if (tree_int_cst_equal (lhs, bailout_value))
return lhs;
gcc_assert (tree_int_cst_equal (lhs, continue_value));
r = eval_constant_expression (ctx, TREE_OPERAND (t, 1), lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
VERIFY_CONSTANT (r);
return r;
}
@@ -1243,19 +1301,20 @@ get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1)
static tree
eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target)
{
- tree arg1
- = eval_constant_expression (ctx, TREE_OPERAND (t, 0),
- /*lval*/ false, non_constant_p, overflow_p);
+ tree arg1 = eval_constant_expression (ctx, TREE_OPERAND (t, 0),
+ /*lval*/ false, non_constant_p,
+ overflow_p, jump_target);
VERIFY_CONSTANT (arg1);
- tree arg2
- = eval_constant_expression (ctx, TREE_OPERAND (t, 1),
- /*lval*/ false, non_constant_p, overflow_p);
+ tree arg2 = eval_constant_expression (ctx, TREE_OPERAND (t, 1),
+ /*lval*/ false, non_constant_p,
+ overflow_p, jump_target);
VERIFY_CONSTANT (arg2);
- tree arg3
- = eval_constant_expression (ctx, TREE_OPERAND (t, 2),
- /*lval*/ false, non_constant_p, overflow_p);
+ tree arg3 = eval_constant_expression (ctx, TREE_OPERAND (t, 2),
+ /*lval*/ false, non_constant_p,
+ overflow_p, jump_target);
VERIFY_CONSTANT (arg3);
location_t loc = EXPR_LOCATION (t);
tree type = TREE_TYPE (t);
@@ -1280,7 +1339,7 @@ eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t,
static tree
eval_bare_aggregate (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p, tree *jump_target)
{
vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
bool changed = false;
@@ -1331,8 +1390,9 @@ eval_bare_aggregate (const constexpr_ctx *ctx, tree t, bool lval,
the active union member now so that we can later detect and diagnose
if its initializer attempts to activate another member. */
get_or_insert_ctor_field (ctx->ctor, index);
- tree elt = eval_constant_expression (&new_ctx, value, lval,
- non_constant_p, overflow_p);
+ tree elt
+ = eval_constant_expression (&new_ctx, value, lval, non_constant_p,
+ overflow_p, jump_target);
/* Don't VERIFY_CONSTANT here. */
if (ctx->quiet && *non_constant_p)
break;
@@ -1401,7 +1461,8 @@ eval_bare_aggregate (const constexpr_ctx *ctx, tree t, bool lval,
static tree
cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target)
{
int i;
tree args[3];
@@ -1409,8 +1470,9 @@ cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t, bool lval,
for (i = 0; i < 3; i++)
{
- args[i] = eval_constant_expression (ctx, TREE_OPERAND (t, i), lval,
- non_constant_p, overflow_p);
+ args[i]
+ = eval_constant_expression (ctx, TREE_OPERAND (t, i), lval,
+ non_constant_p, overflow_p, jump_target);
VERIFY_CONSTANT (args[i]);
}
@@ -1555,7 +1617,8 @@ free_constructor (tree t)
static tree eval_and_check_array_index (const constexpr_ctx *ctx, tree t,
bool allow_one_past,
- bool *non_constant_p, bool *overflow_p);
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target);
// forked from gcc/cp/constexpr.cc cxx_eval_array_reference
@@ -1564,11 +1627,11 @@ static tree eval_and_check_array_index (const constexpr_ctx *ctx, tree t,
static tree
eval_array_reference (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p, tree *jump_target)
{
tree oldary = TREE_OPERAND (t, 0);
- tree ary
- = eval_constant_expression (ctx, oldary, lval, non_constant_p, overflow_p);
+ tree ary = eval_constant_expression (ctx, oldary, lval, non_constant_p,
+ overflow_p, jump_target);
if (*non_constant_p)
return t;
if (!lval && TREE_CODE (ary) == VIEW_CONVERT_EXPR
@@ -1577,8 +1640,8 @@ eval_array_reference (const constexpr_ctx *ctx, tree t, bool lval,
ary = TREE_OPERAND (ary, 0);
tree oldidx = TREE_OPERAND (t, 1);
- tree index
- = eval_and_check_array_index (ctx, t, lval, non_constant_p, overflow_p);
+ tree index = eval_and_check_array_index (ctx, t, lval, non_constant_p,
+ overflow_p, jump_target);
if (*non_constant_p)
return t;
@@ -1680,7 +1743,8 @@ eval_array_reference (const constexpr_ctx *ctx, tree t, bool lval,
new_ctx.ctor = build_constructor (elem_type, NULL);
ctx = &new_ctx;
}
- t = eval_constant_expression (ctx, val, lval, non_constant_p, overflow_p);
+ t = eval_constant_expression (ctx, val, lval, non_constant_p, overflow_p,
+ jump_target);
if (!SCALAR_TYPE_P (elem_type) && t != ctx->ctor)
free_constructor (ctx->ctor);
return t;
@@ -1693,7 +1757,8 @@ eval_array_reference (const constexpr_ctx *ctx, tree t, bool lval,
static tree
eval_component_reference (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target)
{
unsigned HOST_WIDE_INT i;
tree field;
@@ -1701,7 +1766,7 @@ eval_component_reference (const constexpr_ctx *ctx, tree t, bool lval,
tree part = TREE_OPERAND (t, 1);
tree orig_whole = TREE_OPERAND (t, 0);
tree whole = eval_constant_expression (ctx, orig_whole, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
if (INDIRECT_REF_P (whole) && integer_zerop (TREE_OPERAND (whole, 0)))
{
if (!ctx->quiet)
@@ -1790,8 +1855,8 @@ eval_component_reference (const constexpr_ctx *ctx, tree t, bool lval,
// back to handle this to assign suitable value to value before sending it in
// eval_constant_expression below
// value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
- return eval_constant_expression (ctx, value, lval, non_constant_p,
- overflow_p);
+ return eval_constant_expression (ctx, value, lval, non_constant_p, overflow_p,
+ jump_target);
}
/* Subroutine of cxx_eval_statement_list. Determine whether the statement
@@ -1850,7 +1915,7 @@ label_matches (const constexpr_ctx *ctx, tree *jump_target, tree stmt)
static tree
eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
bool *non_constant_p, bool *overflow_p,
- tree *jump_target /* = NULL */)
+ tree *jump_target)
{
if (jump_target && *jump_target)
{
@@ -1921,34 +1986,44 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
{
r = DECL_VALUE_EXPR (t);
return eval_constant_expression (ctx, r, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
}
/* fall through */
case CONST_DECL:
- {
- /* We used to not check lval for CONST_DECL, but darwin.cc uses
- CONST_DECL for aggregate constants. */
- if (lval)
- return t;
- else if (t == ctx->object)
- return ctx->ctor;
- if (VAR_P (t))
- if (tree *p = ctx->global->values.get (t))
- if (*p != NULL_TREE)
- {
- r = *p;
- break;
- }
+ /* We used to not check lval for CONST_DECL, but darwin.cc uses
+ CONST_DECL for aggregate constants. */
+ if (lval)
+ return t;
+ else if (t == ctx->object)
+ return ctx->ctor;
+ if (VAR_P (t))
+ {
+ if (tree v = ctx->global->get_value (t))
+ {
+ r = v;
+ break;
+ }
+ }
+ if (COMPLETE_TYPE_P (TREE_TYPE (t))
+ && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/ false))
+ {
+ /* If the class is empty, we aren't actually loading anything. */
+ r = build_constructor (TREE_TYPE (t), NULL);
+ TREE_CONSTANT (r) = true;
+ }
+ else if (ctx->strict)
+ r = decl_really_constant_value (t, /*unshare_p=*/false);
+ else
r = decl_constant_value (t, /*unshare_p=*/false);
- if (TREE_CODE (r) == TARGET_EXPR
- && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
- r = TARGET_EXPR_INITIAL (r);
- if (DECL_P (r))
- {
+ if (TREE_CODE (r) == TARGET_EXPR
+ && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
+ r = TARGET_EXPR_INITIAL (r);
+ if (DECL_P (r) && !(VAR_P (t) && TYPE_REF_P (TREE_TYPE (t))))
+ {
+ if (!ctx->quiet)
non_const_var_error (loc, r);
- return r;
- }
- }
+ *non_constant_p = true;
+ }
break;
case PARM_DECL:
@@ -2014,7 +2089,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
case LTGT_EXPR:
case RANGE_EXPR:
case COMPLEX_EXPR:
- r = eval_binary_expression (ctx, t, lval, non_constant_p, overflow_p);
+ r = eval_binary_expression (ctx, t, lval, non_constant_p, overflow_p,
+ jump_target);
break;
/* fold can introduce non-IF versions of these; still treat them as
@@ -2023,14 +2099,14 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
case TRUTH_ANDIF_EXPR:
r = eval_logical_expression (ctx, t, boolean_false_node,
boolean_true_node, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
break;
case TRUTH_OR_EXPR:
case TRUTH_ORIF_EXPR:
r = eval_logical_expression (ctx, t, boolean_true_node,
boolean_false_node, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
break;
case TARGET_EXPR:
@@ -2079,7 +2155,7 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
/* Pass false for 'lval' because this indicates
initialization of a temporary. */
r = eval_constant_expression (ctx, TREE_OPERAND (t, 1), false,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p, jump_target);
if (*non_constant_p)
break;
/* Adjust the type of the result to the type of the temporary. */
@@ -2096,13 +2172,14 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
break;
case CALL_EXPR:
- r = eval_call_expression (ctx, t, lval, non_constant_p, overflow_p);
+ r = eval_call_expression (ctx, t, lval, non_constant_p, overflow_p,
+ jump_target);
break;
case RETURN_EXPR:
if (TREE_OPERAND (t, 0) != NULL_TREE)
r = eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p, jump_target);
/* FALLTHRU */
case BREAK_STMT:
case CONTINUE_STMT:
@@ -2135,7 +2212,7 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
if (tree init = DECL_INITIAL (r))
{
init = eval_constant_expression (ctx, init, false, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
/* Don't share a CONSTRUCTOR that might be changed. */
init = unshare_constructor (init);
/* Remember that a constant object's constructor has already
@@ -2156,12 +2233,13 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
constant without its operand being, and vice versa. */
case MEM_REF:
case INDIRECT_REF:
- r = rs_eval_indirect_ref (ctx, t, lval, non_constant_p, overflow_p);
+ r = rs_eval_indirect_ref (ctx, t, lval, non_constant_p, overflow_p,
+ jump_target);
break;
case VEC_PERM_EXPR:
- r = cxx_eval_trinary_expression (ctx, t, lval, non_constant_p,
- overflow_p);
+ r = cxx_eval_trinary_expression (ctx, t, lval, non_constant_p, overflow_p,
+ jump_target);
break;
case PAREN_EXPR:
@@ -2169,11 +2247,12 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
/* A PAREN_EXPR resulting from __builtin_assoc_barrier has no effect in
constant expressions since it's unaffected by -fassociative-math. */
r = eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p, jump_target);
break;
case MODIFY_EXPR:
- r = eval_store_expression (ctx, t, false, non_constant_p, overflow_p);
+ r = eval_store_expression (ctx, t, false, non_constant_p, overflow_p,
+ jump_target);
break;
case STATEMENT_LIST:
@@ -2189,13 +2268,14 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
case OBJ_TYPE_REF:
/* Virtual function lookup. We don't need to do anything fancy. */
return eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t), lval,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p, jump_target);
case EXIT_EXPR:
{
tree cond = TREE_OPERAND (t, 0);
- cond = eval_constant_expression (ctx, cond, /*lval*/ false,
- non_constant_p, overflow_p);
+ cond
+ = eval_constant_expression (ctx, cond, /*lval*/ false, non_constant_p,
+ overflow_p, jump_target);
VERIFY_CONSTANT (cond);
if (integer_nonzerop (cond))
*jump_target = t;
@@ -2225,7 +2305,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
else
{
r = eval_constant_expression (ctx, TREE_OPERAND (t, 0), false,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p,
+ jump_target);
if (*non_constant_p)
break;
ctx->global->values.put (t, r);
@@ -2239,7 +2320,7 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
tree oldop = TREE_OPERAND (t, 0);
tree op = eval_constant_expression (ctx, oldop,
/*lval*/ true, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
/* Don't VERIFY_CONSTANT here. */
if (*non_constant_p)
return t;
@@ -2284,7 +2365,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
if (lval)
{
r = eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p,
+ jump_target);
if (r == error_mark_node)
;
else if (r == TREE_OPERAND (t, 0))
@@ -2303,7 +2385,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR:
case FIXED_CONVERT_EXPR:
- r = eval_unary_expression (ctx, t, lval, non_constant_p, overflow_p);
+ r = eval_unary_expression (ctx, t, lval, non_constant_p, overflow_p,
+ jump_target);
break;
case LOOP_EXPR:
@@ -2318,7 +2401,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
break;
case ARRAY_REF:
- r = eval_array_reference (ctx, t, lval, non_constant_p, overflow_p);
+ r = eval_array_reference (ctx, t, lval, non_constant_p, overflow_p,
+ jump_target);
break;
case COMPONENT_REF:
@@ -2332,11 +2416,13 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
*non_constant_p = true;
return t;
}
- r = eval_component_reference (ctx, t, lval, non_constant_p, overflow_p);
+ r = eval_component_reference (ctx, t, lval, non_constant_p, overflow_p,
+ jump_target);
break;
case BIT_FIELD_REF:
- r = eval_bit_field_ref (ctx, t, lval, non_constant_p, overflow_p);
+ r = eval_bit_field_ref (ctx, t, lval, non_constant_p, overflow_p,
+ jump_target);
break;
case COND_EXPR:
@@ -2381,7 +2467,7 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
case VEC_COND_EXPR:
r = eval_vector_conditional_expression (ctx, t, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
break;
case TRY_CATCH_EXPR:
@@ -2407,7 +2493,7 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
/* Evaluate the cleanups. */
FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
eval_constant_expression (ctx, cleanup, false, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
}
break;
@@ -2417,7 +2503,7 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
if (!*non_constant_p)
/* Also evaluate the cleanup. */
eval_constant_expression (ctx, TREE_OPERAND (t, 1), true,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p, jump_target);
break;
case CONSTRUCTOR:
@@ -2429,7 +2515,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
if (TREE_CONSTANT (t))
return fold (t);
}
- r = eval_bare_aggregate (ctx, t, lval, non_constant_p, overflow_p);
+ r = eval_bare_aggregate (ctx, t, lval, non_constant_p, overflow_p,
+ jump_target);
break;
/* FALLTHROUGH. */
@@ -2440,7 +2527,7 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
tree oldop = TREE_OPERAND (t, 0);
tree op = eval_constant_expression (ctx, oldop, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
if (*non_constant_p)
return t;
tree type = TREE_TYPE (t);
@@ -2571,7 +2658,7 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
return ctor;
else
return eval_constant_expression (ctx, ctor, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
}
/* A placeholder without a referent. We can get here when
checking whether NSDMIs are noexcept, or in massage_init_elt;
@@ -2632,7 +2719,8 @@ is_empty_field (tree decl)
static tree
eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target)
{
constexpr_ctx new_ctx = *ctx;
@@ -2653,7 +2741,7 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
if (!SCALAR_TYPE_P (type))
new_ctx.ctor = new_ctx.object = NULL_TREE;
init = eval_constant_expression (&new_ctx, init, false, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
if (*non_constant_p)
return t;
}
@@ -2665,7 +2753,7 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
as a whole; otherwise, only evaluate the innermost piece to avoid
building up unnecessary *_REFs. */
target = eval_constant_expression (ctx, target, true, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
evaluated = true;
if (*non_constant_p)
return t;
@@ -2694,7 +2782,8 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
if (TREE_CODE (probe) == ARRAY_REF)
{
elt = eval_and_check_array_index (ctx, probe, false,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p,
+ jump_target);
if (*non_constant_p)
return t;
}
@@ -2718,8 +2807,9 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
object = probe;
else
{
- probe = eval_constant_expression (ctx, probe, true,
- non_constant_p, overflow_p);
+ probe
+ = eval_constant_expression (ctx, probe, true, non_constant_p,
+ overflow_p, jump_target);
evaluated = true;
if (*non_constant_p)
return t;
@@ -2910,7 +3000,7 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
if (tree tinit = TARGET_EXPR_INITIAL (init))
init = tinit;
init = eval_constant_expression (&new_ctx, init, false, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
/* The hash table might have moved since the get earlier, and the
initializer might have mutated the underlying CONSTRUCTORs, so we must
recompute VALP. */
@@ -3012,22 +3102,115 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
Like cxx_eval_unary_expression, except for binary expressions. */
static tree
eval_binary_expression (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target)
{
+ tree r = NULL_TREE;
tree orig_lhs = TREE_OPERAND (t, 0);
tree orig_rhs = TREE_OPERAND (t, 1);
tree lhs, rhs;
-
lhs = eval_constant_expression (ctx, orig_lhs, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
+ /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer
+ subtraction. */
+ if (*non_constant_p)
+ return t;
+ if (*jump_target)
+ return NULL_TREE;
+
rhs = eval_constant_expression (ctx, orig_rhs, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
+ if (*non_constant_p)
+ return t;
+ if (*jump_target)
+ return NULL_TREE;
location_t loc = EXPR_LOCATION (t);
enum tree_code code = TREE_CODE (t);
tree type = TREE_TYPE (t);
- return fold_binary_loc (loc, code, type, lhs, rhs);
+ if (code == EQ_EXPR || code == NE_EXPR)
+ {
+ bool is_code_eq = (code == EQ_EXPR);
+
+ if (TREE_CODE (lhs) == PTRMEM_CST && TREE_CODE (rhs) == PTRMEM_CST)
+ {
+ tree lmem = PTRMEM_CST_MEMBER (lhs);
+ tree rmem = PTRMEM_CST_MEMBER (rhs);
+ bool eq;
+ if (TREE_CODE (lmem) == TREE_CODE (rmem)
+ && TREE_CODE (lmem) == FIELD_DECL
+ && TREE_CODE (DECL_CONTEXT (lmem)) == UNION_TYPE
+ && same_type_p (DECL_CONTEXT (lmem), DECL_CONTEXT (rmem)))
+ /* If both refer to (possibly different) members of the same union
+ (12.3), they compare equal. */
+ eq = true;
+ // else
+ // eq = cp_tree_equal (lhs, rhs);
+ r = constant_boolean_node (eq == is_code_eq, type);
+ }
+ else if ((TREE_CODE (lhs) == PTRMEM_CST || TREE_CODE (rhs) == PTRMEM_CST)
+ && (null_member_pointer_value_p (lhs)
+ || null_member_pointer_value_p (rhs)))
+ r = constant_boolean_node (!is_code_eq, type);
+ }
+ if (r == NULL_TREE && TREE_CODE_CLASS (code) == tcc_comparison
+ && POINTER_TYPE_P (TREE_TYPE (lhs)))
+ {
+ if (tree lhso = maybe_fold_addr_pointer_plus (lhs))
+ lhs = fold_convert (TREE_TYPE (lhs), lhso);
+ if (tree rhso = maybe_fold_addr_pointer_plus (rhs))
+ rhs = fold_convert (TREE_TYPE (rhs), rhso);
+ }
+ if (code == POINTER_PLUS_EXPR && !*non_constant_p && integer_zerop (lhs)
+ && !integer_zerop (rhs))
+ {
+ if (!ctx->quiet)
+ error ("arithmetic involving a null pointer in %qE", lhs);
+ *non_constant_p = true;
+ return t;
+ }
+ else if (code == POINTER_PLUS_EXPR)
+ {
+ r = fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p,
+ overflow_p, jump_target);
+ if (*jump_target)
+ return NULL_TREE;
+ }
+
+ if (r == NULL_TREE)
+ {
+ r = fold_binary_loc (loc, code, type, lhs, rhs);
+ }
+
+ if (r == NULL_TREE && (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
+ && TREE_CODE (lhs) == INTEGER_CST && TREE_CODE (rhs) == INTEGER_CST
+ && wi::neg_p (wi::to_wide (rhs)))
+ {
+ /* For diagnostics and -fpermissive emulate previous behavior of
+ handling shifts by negative amount. */
+ tree nrhs = const_unop (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
+ if (nrhs)
+ r = fold_binary_loc (loc,
+ code == LSHIFT_EXPR ? RSHIFT_EXPR : LSHIFT_EXPR,
+ type, lhs, nrhs);
+ }
+
+ if (r == NULL_TREE)
+ {
+ if (lhs == orig_lhs && rhs == orig_rhs)
+ r = t;
+ else
+ r = build2_loc (loc, code, type, lhs, rhs);
+ }
+ else if (eval_check_shift_p (loc, ctx, code, type, lhs, rhs))
+ *non_constant_p = true;
+ /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
+ a local array in a constexpr function. */
+ bool ptr = INDIRECT_TYPE_P (TREE_TYPE (lhs));
+ if (!ptr)
+ VERIFY_CONSTANT (r);
+ return r;
}
/* Helper function of cxx_bind_parameters_in_call. Return non-NULL
@@ -3065,7 +3248,7 @@ addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data)
static tree
rs_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
bool *non_constant_p, bool *overflow_p,
- bool *non_constant_args)
+ bool *non_constant_args, tree *jump_target)
{
const int nargs = call_expr_nargs (t);
tree parms = DECL_ARGUMENTS (fun);
@@ -3089,7 +3272,7 @@ rs_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
such as this, but here we do the elision differently: we keep the
TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */
arg = eval_constant_expression (ctx, x, /*lval=*/false, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
/* Don't VERIFY_CONSTANT here. */
if (*non_constant_p && ctx->quiet)
break;
@@ -3155,7 +3338,8 @@ rs_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
static tree
eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
- bool lval, bool *non_constant_p, bool *overflow_p)
+ bool lval, bool *non_constant_p, bool *overflow_p,
+ tree *jump_target)
{
const int nargs = call_expr_nargs (t);
tree *args = (tree *) alloca (nargs * sizeof (tree));
@@ -3258,8 +3442,9 @@ eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
|| potential_constant_expression (arg))
{
bool dummy1 = false, dummy2 = false;
- arg
- = eval_constant_expression (&new_ctx, arg, false, &dummy1, &dummy2);
+ tree dummy_jump_target = NULL_TREE;
+ arg = eval_constant_expression (&new_ctx, arg, false, &dummy1,
+ &dummy2, &dummy_jump_target);
}
if (bi_const_p)
@@ -3355,7 +3540,7 @@ eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
}
return eval_constant_expression (&new_ctx, new_call, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
}
// Subroutine of cxx_eval_constant_expression.
@@ -3363,7 +3548,7 @@ eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
// evaluation.
static tree
eval_call_expression (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p, tree *jump_target)
{
location_t loc = EXPR_LOCATION (t);
tree fun = get_function_named_in_call (t);
@@ -3392,12 +3577,12 @@ eval_call_expression (const constexpr_ctx *ctx, tree t, bool lval,
if (fndecl_built_in_p (fun))
return eval_builtin_function_call (ctx, t, fun, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
bool non_constant_args = false;
new_call.bindings
= rs_bind_parameters_in_call (ctx, t, fun, non_constant_p, overflow_p,
- &non_constant_args);
+ &non_constant_args, jump_target);
/* We build up the bindings list before we know whether we already have this
call cached. If we don't end up saving these bindings, ggc_free them when
@@ -3960,7 +4145,7 @@ constexpr_fn_retval (const constexpr_ctx *ctx, tree body)
bool non_constant_p = false;
bool overflow_p = false;
return eval_constant_expression (ctx, body, false, &non_constant_p,
- &overflow_p);
+ &overflow_p, NULL);
}
case DECL_EXPR:
{
@@ -4024,6 +4209,17 @@ constant_value_1 (tree decl, bool, bool, bool unshare_p)
return unshare_p ? unshare_expr (decl) : decl;
}
+/* Like scalar_constant_value, but can also return aggregate initializers.
+ If UNSHARE_P, return an unshared copy of the initializer. */
+
+tree
+decl_really_constant_value (tree decl, bool unshare_p /*= true*/)
+{
+ return constant_value_1 (decl, /*strict_p=*/true,
+ /*return_aggregate_cst_ok_p=*/true,
+ /*unshare_p=*/unshare_p);
+}
+
// A more relaxed version of decl_really_constant_value, used by the
// common C/C++ code.
tree
@@ -4037,15 +4233,38 @@ decl_constant_value (tree decl, bool unshare_p)
static void
non_const_var_error (location_t loc, tree r)
{
- error_at (loc,
- "the value of %qD is not usable in a constant "
- "expression",
- r);
+ tree type = TREE_TYPE (r);
+
/* Avoid error cascade. */
if (DECL_INITIAL (r) == error_mark_node)
return;
-
- // more in cp/constexpr.cc
+ if (DECL_DECLARED_CONSTEXPR_P (r))
+ inform (DECL_SOURCE_LOCATION (r), "%qD used in its own initializer", r);
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ {
+ if (!DECL_INITIAL (r) || !TREE_CONSTANT (DECL_INITIAL (r))
+ || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r))
+ inform (DECL_SOURCE_LOCATION (r),
+ "%qD was not initialized with a constant "
+ "expression",
+ r);
+ else
+ gcc_unreachable ();
+ }
+ else if (TYPE_REF_P (type))
+ inform (DECL_SOURCE_LOCATION (r),
+ "%qD was not initialized with a constant "
+ "expression",
+ r);
+ else
+ {
+ if (!DECL_DECLARED_CONSTEXPR_P (r))
+ inform (DECL_SOURCE_LOCATION (r), "%qD was not declared %<constexpr%>",
+ r);
+ else
+ inform (DECL_SOURCE_LOCATION (r),
+ "%qD does not have integral or enumeration type", r);
+ }
}
static tree
@@ -4322,7 +4541,7 @@ verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
if (!*non_constant_p && !reduced_constant_expression_p (t) && t != void_node)
{
if (!allow_non_constant)
- error ("%q+E is not a constant expression", t);
+ error_at (EXPR_LOCATION (t), "is not a constant expression");
*non_constant_p = true;
}
if (TREE_OVERFLOW_P (t))
@@ -4427,7 +4646,8 @@ diag_array_subscript (location_t loc, const constexpr_ctx *ctx, tree array,
static tree
get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target)
{
tree nelts;
if (TREE_CODE (type) == ARRAY_TYPE)
@@ -4443,8 +4663,8 @@ get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
rust_unreachable ();
/* For VLAs, the number of elements won't be an integer constant. */
- nelts
- = eval_constant_expression (ctx, nelts, false, non_constant_p, overflow_p);
+ nelts = eval_constant_expression (ctx, nelts, false, non_constant_p,
+ overflow_p, jump_target);
return nelts;
}
@@ -4456,13 +4676,13 @@ get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
static tree
eval_and_check_array_index (const constexpr_ctx *ctx, tree t,
bool allow_one_past, bool *non_constant_p,
- bool *overflow_p)
+ bool *overflow_p, tree *jump_target)
{
location_t loc = rs_expr_loc_or_input_loc (t);
tree ary = TREE_OPERAND (t, 0);
t = TREE_OPERAND (t, 1);
tree index = eval_constant_expression (ctx, t, allow_one_past, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
VERIFY_CONSTANT (index);
if (!tree_fits_shwi_p (index) || tree_int_cst_sgn (index) < 0)
@@ -4473,7 +4693,7 @@ eval_and_check_array_index (const constexpr_ctx *ctx, tree t,
}
tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
VERIFY_CONSTANT (nelts);
if (allow_one_past ? !tree_int_cst_le (index, nelts)
: !tree_int_cst_lt (index, nelts))
@@ -4683,9 +4903,9 @@ eval_conditional_expression (const constexpr_ctx *ctx, tree t, bool lval,
bool *non_constant_p, bool *overflow_p,
tree *jump_target)
{
- tree val
- = eval_constant_expression (ctx, TREE_OPERAND (t, 0),
- /*lval*/ false, non_constant_p, overflow_p);
+ tree val = eval_constant_expression (ctx, TREE_OPERAND (t, 0),
+ /*lval*/ false, non_constant_p,
+ overflow_p, jump_target);
VERIFY_CONSTANT (val);
if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t))
{
@@ -4722,14 +4942,14 @@ eval_conditional_expression (const constexpr_ctx *ctx, tree t, bool lval,
static tree
eval_bit_field_ref (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p, tree *jump_target)
{
tree orig_whole = TREE_OPERAND (t, 0);
tree retval, fldval, utype, mask;
bool fld_seen = false;
HOST_WIDE_INT istart, isize;
tree whole = eval_constant_expression (ctx, orig_whole, lval, non_constant_p,
- overflow_p);
+ overflow_p, jump_target);
tree start, field, value;
unsigned HOST_WIDE_INT i;
@@ -4960,8 +5180,8 @@ eval_switch_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
{
tree cond
= TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_COND (t) : SWITCH_COND (t);
- cond
- = eval_constant_expression (ctx, cond, false, non_constant_p, overflow_p);
+ cond = eval_constant_expression (ctx, cond, false, non_constant_p, overflow_p,
+ jump_target);
VERIFY_CONSTANT (cond);
*jump_target = cond;
@@ -4995,12 +5215,13 @@ eval_switch_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
static tree
eval_unary_expression (const constexpr_ctx *ctx, tree t, bool /*lval*/,
- bool *non_constant_p, bool *overflow_p)
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target)
{
tree r;
tree orig_arg = TREE_OPERAND (t, 0);
tree arg = eval_constant_expression (ctx, orig_arg, /*lval*/ false,
- non_constant_p, overflow_p);
+ non_constant_p, overflow_p, jump_target);
VERIFY_CONSTANT (arg);
location_t loc = EXPR_LOCATION (t);
enum tree_code code = TREE_CODE (t);
@@ -5136,7 +5357,9 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
if (manifestly_const_eval)
instantiate_constexpr_fns (r);
- r = eval_constant_expression (&ctx, r, false, &non_constant_p, &overflow_p);
+ tree jump_target = NULL_TREE;
+ r = eval_constant_expression (&ctx, r, false, &non_constant_p, &overflow_p,
+ &jump_target);
if (!constexpr_dtor)
verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
@@ -5148,7 +5371,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
/* Evaluate the cleanups. */
FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
eval_constant_expression (&ctx, cleanup, false, &non_constant_p,
- &overflow_p);
+ &overflow_p, NULL);
/* Mutable logic is a bit tricky: we want to allow initialization of
constexpr variables with mutable members, but we can't copy those
@@ -5908,7 +6131,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
/* A pointer-to-member constant. */
return true;
- // handle_addr_expr:
#if 0
/* FIXME adjust when issue 1197 is fully resolved. For now don't do
any checking here, as we might dereference the pointer later. If
@@ -6484,6 +6706,170 @@ fold_non_dependent_init (tree t, tsubst_flags_t /*=tf_warning_or_error*/,
return maybe_constant_init (t, object, manifestly_const_eval);
}
+/* Check whether the shift operation with code CODE and type TYPE on LHS
+ and RHS is undefined. If it is, give an error with an explanation,
+ and return true; return false otherwise. */
+
+static bool
+eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
+ enum tree_code code, tree type, tree lhs, tree rhs)
+{
+ if ((code != LSHIFT_EXPR && code != RSHIFT_EXPR)
+ || TREE_CODE (lhs) != INTEGER_CST || TREE_CODE (rhs) != INTEGER_CST)
+ return false;
+
+ tree lhstype = TREE_TYPE (lhs);
+ unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
+
+ /* [expr.shift] The behavior is undefined if the right operand
+ is negative, or greater than or equal to the length in bits
+ of the promoted left operand. */
+ if (tree_int_cst_sgn (rhs) == -1)
+ {
+ if (!ctx->quiet)
+ permerror (loc, "right operand of shift expression %q+E is negative",
+ build2_loc (loc, code, type, lhs, rhs));
+ return (!flag_permissive || ctx->quiet);
+ }
+ if (compare_tree_int (rhs, uprec) >= 0)
+ {
+ if (!ctx->quiet)
+ permerror (loc,
+ "right operand of shift expression %q+E is greater "
+ "than or equal to the precision %wu of the left operand",
+ build2_loc (loc, code, type, lhs, rhs), uprec);
+ return (!flag_permissive || ctx->quiet);
+ }
+
+ /* The value of E1 << E2 is E1 left-shifted E2 bit positions; [...]
+ if E1 has a signed type and non-negative value, and E1x2^E2 is
+ representable in the corresponding unsigned type of the result type,
+ then that value, converted to the result type, is the resulting value;
+ otherwise, the behavior is undefined.
+ For C++20:
+ The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo
+ 2^N, where N is the range exponent of the type of the result. */
+ if (code == LSHIFT_EXPR && !TYPE_OVERFLOW_WRAPS (lhstype))
+ {
+ if (tree_int_cst_sgn (lhs) == -1)
+ {
+ if (!ctx->quiet)
+ permerror (loc, "left operand of shift expression %q+E is negative",
+ build2_loc (loc, code, type, lhs, rhs));
+ return (!flag_permissive || ctx->quiet);
+ }
+ /* For signed x << y the following:
+ (unsigned) x >> ((prec (lhs) - 1) - y)
+ if > 1, is undefined. The right-hand side of this formula
+ is the highest bit of the LHS that can be set (starting from 0),
+ so that the shift doesn't overflow. We then right-shift the LHS
+ to see whether any other bit is set making the original shift
+ undefined -- the result is not representable in the corresponding
+ unsigned type. */
+ tree t = build_int_cst (unsigned_type_node, uprec - 1);
+ t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
+ tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
+ t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
+ if (tree_int_cst_lt (integer_one_node, t))
+ {
+ if (!ctx->quiet)
+ permerror (loc, "shift expression %q+E overflows",
+ build2_loc (loc, code, type, lhs, rhs));
+ return (!flag_permissive || ctx->quiet);
+ }
+ }
+ return false;
+}
+
+/* Helper function for cxx_eval_binary_expression. Try to optimize
+ original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the
+ generic folding should be used. */
+
+static tree
+fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t, tree lhs,
+ tree rhs, bool *non_constant_p, bool *overflow_p,
+ tree *jump_target)
+{
+ STRIP_NOPS (lhs);
+ if (TREE_CODE (lhs) != ADDR_EXPR)
+ return NULL_TREE;
+
+ lhs = TREE_OPERAND (lhs, 0);
+
+ /* &A[i] p+ j => &A[i + j] */
+ if (TREE_CODE (lhs) == ARRAY_REF
+ && TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
+ && TREE_CODE (rhs) == INTEGER_CST && TYPE_SIZE_UNIT (TREE_TYPE (lhs))
+ && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
+ {
+ tree orig_type = TREE_TYPE (t);
+ location_t loc = EXPR_LOCATION (t);
+ tree type = TREE_TYPE (lhs);
+
+ t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (lhs, 1));
+ tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0)));
+ nelts = eval_constant_expression (ctx, nelts, true, non_constant_p,
+ overflow_p, jump_target);
+ if (*non_constant_p)
+ return NULL_TREE;
+ if (*jump_target)
+ return NULL_TREE;
+ /* Don't fold an out-of-bound access. */
+ if (!tree_int_cst_le (t, nelts))
+ return NULL_TREE;
+ rhs = fold_convert (ssizetype, rhs);
+ /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT.
+ constexpr int A[1]; ... (char *)&A[0] + 1 */
+ if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype, rhs,
+ TYPE_SIZE_UNIT (type))))
+ return NULL_TREE;
+ /* Make sure to treat the second operand of POINTER_PLUS_EXPR
+ as signed. */
+ rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, rhs,
+ TYPE_SIZE_UNIT (type));
+ t = size_binop_loc (loc, PLUS_EXPR, rhs, t);
+ t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0), t, NULL_TREE,
+ NULL_TREE);
+ t = build_fold_addr_expr (t);
+ t = fold_convert (orig_type, t);
+ return eval_constant_expression (ctx, t, true, non_constant_p, overflow_p,
+ jump_target);
+ }
+
+ return NULL_TREE;
+}
+
+/* Try to fold expressions like
+ (struct S *) (&a[0].D.2378 + 12)
+ into
+ &MEM <struct T> [(void *)&a + 12B]
+ This is something normally done by gimple_fold_stmt_to_constant_1
+ on GIMPLE, but is undesirable on GENERIC if we are e.g. going to
+ dereference the address because some details are lost.
+ For pointer comparisons we want such folding though so that
+ match.pd address_compare optimization works. */
+
+static tree
+maybe_fold_addr_pointer_plus (tree t)
+{
+ while (CONVERT_EXPR_P (t) && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) != POINTER_PLUS_EXPR)
+ return NULL_TREE;
+ tree op0 = TREE_OPERAND (t, 0);
+ tree op1 = TREE_OPERAND (t, 1);
+ if (TREE_CODE (op1) != INTEGER_CST)
+ return NULL_TREE;
+ while (CONVERT_EXPR_P (op0)
+ && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
+ op0 = TREE_OPERAND (op0, 0);
+ if (TREE_CODE (op0) != ADDR_EXPR)
+ return NULL_TREE;
+ op1 = fold_convert (ptr_type_node, op1);
+ tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1);
+ return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r);
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
index e2cc2dd..de8a830 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -24,7 +24,6 @@
#include "rust-hir-item.h"
#include "rust-hir-type-check.h"
#include "rust-hir-visitor.h"
-#include "rust-name-resolver.h"
#include "rust-bir.h"
#include "rust-bir-free-region.h"
#include "rust-immutable-name-resolution-context.h"
@@ -75,7 +74,7 @@ struct BuilderContext
// External context.
Resolver::TypeCheckContext &tyctx;
- Resolver::Resolver &resolver;
+ const Resolver2_0::NameResolutionContext &resolver;
// BIR output
BasicBlocks basic_blocks;
@@ -104,7 +103,7 @@ struct BuilderContext
public:
BuilderContext ()
: tyctx (*Resolver::TypeCheckContext::get ()),
- resolver (*Resolver::Resolver::get ())
+ resolver (Resolver2_0::ImmutableNameResolutionContext::get ().resolver ())
{
basic_blocks.emplace_back (); // StartBB
}
@@ -403,69 +402,31 @@ protected: // HIR resolution helpers
template <typename T> NodeId resolve_label (T &expr)
{
- NodeId resolved_label;
- if (flag_name_resolution_2_0)
- {
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- auto res = nr_ctx.lookup (expr.get_mappings ().get_nodeid ());
- rust_assert (res.has_value ());
- resolved_label = res.value ();
- }
- else
- {
- bool ok = ctx.resolver.lookup_resolved_label (
- expr.get_mappings ().get_nodeid (), &resolved_label);
- rust_assert (ok);
- }
- return resolved_label;
+ auto res = ctx.resolver.lookup (expr.get_mappings ().get_nodeid ());
+ rust_assert (res.has_value ());
+ return res.value ();
}
template <typename T> PlaceId resolve_variable (T &variable)
{
- NodeId variable_id;
- if (flag_name_resolution_2_0)
- {
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ());
- rust_assert (res.has_value ());
- variable_id = res.value ();
- }
- else
- {
- bool ok = ctx.resolver.lookup_resolved_name (
- variable.get_mappings ().get_nodeid (), &variable_id);
- rust_assert (ok);
- }
- return ctx.place_db.lookup_variable (variable_id);
+ auto res = ctx.resolver.lookup (variable.get_mappings ().get_nodeid ());
+ rust_assert (res.has_value ());
+ return ctx.place_db.lookup_variable (res.value ());
}
template <typename T>
PlaceId resolve_variable_or_fn (T &variable, TyTy::BaseType *ty)
{
ty = (ty) ? ty : lookup_type (variable);
+
// Unlike variables,
// functions do not have to be declared in PlaceDB before use.
- NodeId variable_id;
- if (flag_name_resolution_2_0)
- {
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ());
- rust_assert (res.has_value ());
- variable_id = res.value ();
- }
- else
- {
- bool ok = ctx.resolver.lookup_resolved_name (
- variable.get_mappings ().get_nodeid (), &variable_id);
- rust_assert (ok);
- }
if (ty->is<TyTy::FnType> ())
return ctx.place_db.get_constant (ty);
- else
- return ctx.place_db.lookup_or_add_variable (variable_id, ty);
+
+ auto res = ctx.resolver.lookup (variable.get_mappings ().get_nodeid ());
+ rust_assert (res.has_value ());
+ return ctx.place_db.lookup_or_add_variable (res.value (), ty);
}
protected: // Implicit conversions.
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 2d655f9..e78d750 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
@@ -70,11 +70,34 @@ PatternBindingBuilder::visit (HIR::SlicePattern &pattern)
return ty->as<TyTy::SliceType> ()->get_element_type ();
});
- // Regions are unchnaged.
+ // Regions are unchanged.
- for (auto &item : pattern.get_items ())
+ switch (pattern.get_items ().get_item_type ())
{
- item->accept_vis (*this);
+ case HIR::SlicePatternItems::NO_REST:
+ {
+ auto &items
+ = static_cast<HIR::SlicePatternItemsNoRest &> (pattern.get_items ());
+ for (auto &member : items.get_patterns ())
+ {
+ member->accept_vis (*this);
+ }
+ break;
+ }
+ case HIR::SlicePatternItems::HAS_REST:
+ {
+ auto &items
+ = static_cast<HIR::SlicePatternItemsHasRest &> (pattern.get_items ());
+ for (auto &member : items.get_lower_patterns ())
+ {
+ member->accept_vis (*this);
+ }
+ for (auto &member : items.get_upper_patterns ())
+ {
+ member->accept_vis (*this);
+ }
+ break;
+ }
}
}
@@ -202,17 +225,17 @@ PatternBindingBuilder::visit (HIR::TuplePattern &pattern)
size_t index = 0;
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::MULTIPLE:
+ case HIR::TuplePatternItems::NO_REST:
{
- auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- pattern.get_items ());
+ auto &items
+ = static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
break;
}
- case HIR::TuplePatternItems::RANGED:
+ case HIR::TuplePatternItems::HAS_REST:
{
auto &items
- = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+ = static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
auto tyty = ctx.place_db[init.value ()].tyty;
rust_assert (tyty->get_kind () == TyTy::TUPLE);
@@ -249,10 +272,10 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
size_t index = 0;
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TupleStructItems::RANGED:
+ case HIR::TupleStructItems::HAS_REST:
{
auto &items
- = static_cast<HIR::TupleStructItemsRange &> (pattern.get_items ());
+ = static_cast<HIR::TupleStructItemsHasRest &> (pattern.get_items ());
rust_assert (type->get_kind () == TyTy::ADT);
auto adt_ty = static_cast<TyTy::ADTType *> (type);
@@ -267,10 +290,10 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
visit_tuple_fields (items.get_upper_patterns (), saved, index);
break;
}
- case HIR::TupleStructItems::MULTIPLE:
+ case HIR::TupleStructItems::NO_REST:
{
auto &items
- = static_cast<HIR::TupleStructItemsNoRange &> (pattern.get_items ());
+ = static_cast<HIR::TupleStructItemsNoRest &> (pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
break;
}
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 d87ff8c..6cb87c7 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -225,11 +225,11 @@ protected:
rust_unreachable ();
}
void visit (HIR::StructPattern &pattern) override { rust_unreachable (); }
- void visit (HIR::TupleStructItemsNoRange &tuple_items) override
+ void visit (HIR::TupleStructItemsNoRest &tuple_items) override
{
rust_unreachable ();
}
- void visit (HIR::TupleStructItemsRange &tuple_items) override
+ void visit (HIR::TupleStructItemsHasRest &tuple_items) override
{
rust_unreachable ();
}
@@ -237,15 +237,23 @@ protected:
{
rust_unreachable ();
}
- void visit (HIR::TuplePatternItemsMultiple &tuple_items) override
+ void visit (HIR::TuplePatternItemsNoRest &tuple_items) override
{
rust_unreachable ();
}
- void visit (HIR::TuplePatternItemsRanged &tuple_items) override
+ void visit (HIR::TuplePatternItemsHasRest &tuple_items) override
{
rust_unreachable ();
}
void visit (HIR::TuplePattern &pattern) override { rust_unreachable (); }
+ void visit (HIR::SlicePatternItemsNoRest &tuple_items) override
+ {
+ rust_unreachable ();
+ }
+ void visit (HIR::SlicePatternItemsHasRest &tuple_items) override
+ {
+ rust_unreachable ();
+ }
void visit (HIR::SlicePattern &pattern) override { rust_unreachable (); }
void visit (HIR::AltPattern &pattern) override { rust_unreachable (); }
void visit (HIR::EmptyStmt &stmt) override { rust_unreachable (); }
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index 86f96c1..63f2a95 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -170,12 +170,14 @@ public:
void visit (HIR::StructPatternFieldIdentPat &field) override {}
void visit (HIR::StructPatternFieldIdent &field) override {}
void visit (HIR::StructPattern &pattern) override {}
- void visit (HIR::TupleStructItemsNoRange &tuple_items) override {}
- void visit (HIR::TupleStructItemsRange &tuple_items) override {}
+ void visit (HIR::TupleStructItemsNoRest &tuple_items) override {}
+ void visit (HIR::TupleStructItemsHasRest &tuple_items) override {}
void visit (HIR::TupleStructPattern &pattern) override {}
- void visit (HIR::TuplePatternItemsMultiple &tuple_items) override {}
- void visit (HIR::TuplePatternItemsRanged &tuple_items) override {}
+ void visit (HIR::TuplePatternItemsNoRest &tuple_items) override {}
+ void visit (HIR::TuplePatternItemsHasRest &tuple_items) override {}
void visit (HIR::TuplePattern &pattern) override {}
+ void visit (HIR::SlicePatternItemsNoRest &tuple_items) override {}
+ void visit (HIR::SlicePatternItemsHasRest &tuple_items) override {}
void visit (HIR::SlicePattern &pattern) override {}
void visit (HIR::AltPattern &pattern) override {}
void visit (HIR::EmptyStmt &stmt) override {}
diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc b/gcc/rust/checks/errors/feature/rust-feature-gate.cc
index 44007f9..44007f9 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/feature/rust-feature-gate.cc
diff --git a/gcc/rust/checks/errors/rust-feature-gate.h b/gcc/rust/checks/errors/feature/rust-feature-gate.h
index f1011e5..f1011e5 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.h
+++ b/gcc/rust/checks/errors/feature/rust-feature-gate.h
diff --git a/gcc/rust/checks/errors/rust-feature.cc b/gcc/rust/checks/errors/feature/rust-feature.cc
index 071d3f8..071d3f8 100644
--- a/gcc/rust/checks/errors/rust-feature.cc
+++ b/gcc/rust/checks/errors/feature/rust-feature.cc
diff --git a/gcc/rust/checks/errors/rust-feature.h b/gcc/rust/checks/errors/feature/rust-feature.h
index e7cb0af..e7cb0af 100644
--- a/gcc/rust/checks/errors/rust-feature.h
+++ b/gcc/rust/checks/errors/feature/rust-feature.h
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
index 5291276..90248d3 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
@@ -20,7 +20,7 @@
#include "rust-reachability.h"
#include "rust-hir-type-check.h"
#include "rust-hir-map.h"
-#include "rust-name-resolver.h"
+#include "rust-immutable-name-resolution-context.h"
#include "rust-visibility-resolver.h"
#include "rust-pub-restricted-visitor.h"
#include "rust-privacy-reporter.h"
@@ -35,12 +35,13 @@ Resolver::resolve (HIR::Crate &crate)
{
PrivacyContext ctx;
auto &mappings = Analysis::Mappings::get ();
- auto resolver = Rust::Resolver::Resolver::get ();
+ auto &resolver
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
auto ty_ctx = ::Rust::Resolver::TypeCheckContext::get ();
- VisibilityResolver (mappings, *resolver).go (crate);
+ VisibilityResolver (mappings, resolver).go (crate);
PubRestrictedVisitor (mappings).go (crate);
- PrivacyReporter (mappings, *resolver, *ty_ctx).go (crate);
+ PrivacyReporter (mappings, resolver, *ty_ctx).go (crate);
auto visitor = ReachabilityVisitor (ctx, *ty_ctx);
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index 4af9639..c1a3d45 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -28,7 +28,8 @@ namespace Rust {
namespace Privacy {
PrivacyReporter::PrivacyReporter (
- Analysis::Mappings &mappings, Resolver::Resolver &resolver,
+ Analysis::Mappings &mappings,
+ const Resolver2_0::NameResolutionContext &resolver,
const Rust::Resolver::TypeCheckContext &ty_ctx)
: mappings (mappings), resolver (resolver), ty_ctx (ty_ctx),
current_module (tl::nullopt)
@@ -90,59 +91,18 @@ PrivacyReporter::go (HIR::Crate &crate)
}
}
-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)
- return false;
-
- // Visit all toplevel children
- for (auto &child : *children)
- if (child == possible_child)
- return true;
-
- // Now descend recursively in the child module tree
- for (auto &child : *children)
- if (is_child_module (mappings, child, possible_child))
- return true;
-
- return false;
-}
-
// FIXME: This function needs a lot of refactoring
void
PrivacyReporter::check_for_privacy_violation (const NodeId &use_id,
const location_t locus)
{
- 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
- else if (!resolver.lookup_resolved_name (use_id, &ref_node_id))
- resolver.lookup_resolved_type (use_id, &ref_node_id);
+ NodeId ref_node_id;
// FIXME: Assert here. For now, we return since this causes issues when
// checking inferred types (#1260)
- // rust_assert (ref_node_id != UNKNOWN_NODEID);
- if (ref_node_id == UNKNOWN_NODEID)
+ if (auto id = resolver.lookup (use_id))
+ ref_node_id = *id;
+ else
return;
auto vis = mappings.lookup_visibility (ref_node_id);
@@ -175,7 +135,9 @@ PrivacyReporter::check_for_privacy_violation (const NodeId &use_id,
// FIXME: This needs a LOT of TLC: hinting about the definition, a
// string to say if it's a module, function, type, etc...
- if (!is_child_module (mappings, mod_node_id, current_module.value ()))
+
+ if (!resolver.values.is_module_descendant (mod_node_id,
+ current_module.value ()))
valid = false;
}
break;
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
index 72716a6..d64b7a7 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
@@ -22,8 +22,9 @@
#include "rust-hir-expr.h"
#include "rust-hir-map.h"
#include "rust-hir-visitor.h"
+#include "rust-hir-type-check.h"
#include "rust-mapping-common.h"
-#include "rust-name-resolver.h"
+#include "rust-name-resolution-context.h"
namespace Rust {
namespace Privacy {
@@ -38,7 +39,7 @@ class PrivacyReporter : public HIR::HIRExpressionVisitor,
{
public:
PrivacyReporter (Analysis::Mappings &mappings,
- Rust::Resolver::Resolver &resolver,
+ const Resolver2_0::NameResolutionContext &resolver,
const Rust::Resolver::TypeCheckContext &ty_ctx);
/**
@@ -157,7 +158,7 @@ types
virtual void visit (HIR::ExprStmt &stmt);
Analysis::Mappings &mappings;
- Rust::Resolver::Resolver &resolver;
+ const Resolver2_0::NameResolutionContext &resolver;
const Rust::Resolver::TypeCheckContext &ty_ctx;
// `None` means we're in the root module - the crate
diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
index c59763d..4240673 100644
--- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
+++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
@@ -20,16 +20,14 @@
#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"
+#include "rust-name-resolution-context.h"
namespace Rust {
namespace Privacy {
-VisibilityResolver::VisibilityResolver (Analysis::Mappings &mappings,
- Resolver::Resolver &resolver)
+VisibilityResolver::VisibilityResolver (
+ Analysis::Mappings &mappings,
+ const Resolver2_0::NameResolutionContext &resolver)
: mappings (mappings), resolver (resolver)
{}
@@ -64,23 +62,12 @@ VisibilityResolver::resolve_module_path (const HIR::SimplePath &restriction,
= Error (restriction.get_locus (),
"cannot use non-module path as privacy restrictor");
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (flag_name_resolution_2_0)
+ NodeId ref_node_id;
+ if (auto id = resolver.lookup (ast_node_id))
{
- 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;
- }
+ ref_node_id = *id;
}
- else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ else
{
invalid_path.emit ();
return false;
diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h
index 4dfba4c..ddd70a8 100644
--- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h
+++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h
@@ -24,7 +24,7 @@
#include "rust-hir-stmt.h"
#include "rust-hir-item.h"
#include "rust-hir-map.h"
-#include "rust-name-resolver.h"
+#include "rust-name-resolution-context.h"
#include "rust-hir-visitor.h"
namespace Rust {
@@ -34,7 +34,7 @@ class VisibilityResolver : public HIR::HIRVisItemVisitor
{
public:
VisibilityResolver (Analysis::Mappings &mappings,
- Rust::Resolver::Resolver &resolver);
+ const Resolver2_0::NameResolutionContext &resolver);
/**
* Perform visibility resolving on an entire crate
@@ -93,7 +93,7 @@ public:
private:
Analysis::Mappings &mappings;
- Rust::Resolver::Resolver &resolver;
+ const Resolver2_0::NameResolutionContext &resolver;
DefId current_module;
};
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index c40f9db..782d694 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -813,11 +813,11 @@ ConstChecker::visit (StructPattern &)
{}
void
-ConstChecker::visit (TupleStructItemsNoRange &)
+ConstChecker::visit (TupleStructItemsNoRest &)
{}
void
-ConstChecker::visit (TupleStructItemsRange &)
+ConstChecker::visit (TupleStructItemsHasRest &)
{}
void
@@ -825,11 +825,11 @@ ConstChecker::visit (TupleStructPattern &)
{}
void
-ConstChecker::visit (TuplePatternItemsMultiple &)
+ConstChecker::visit (TuplePatternItemsNoRest &)
{}
void
-ConstChecker::visit (TuplePatternItemsRanged &)
+ConstChecker::visit (TuplePatternItemsHasRest &)
{}
void
@@ -837,6 +837,14 @@ ConstChecker::visit (TuplePattern &)
{}
void
+ConstChecker::visit (SlicePatternItemsNoRest &)
+{}
+
+void
+ConstChecker::visit (SlicePatternItemsHasRest &)
+{}
+
+void
ConstChecker::visit (SlicePattern &)
{}
diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h
index eb63095..d464b7b 100644
--- a/gcc/rust/checks/errors/rust-const-checker.h
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -180,12 +180,14 @@ private:
virtual void visit (StructPatternFieldIdentPat &field) override;
virtual void visit (StructPatternFieldIdent &field) override;
virtual void visit (StructPattern &pattern) override;
- virtual void visit (TupleStructItemsNoRange &tuple_items) override;
- virtual void visit (TupleStructItemsRange &tuple_items) override;
+ virtual void visit (TupleStructItemsNoRest &tuple_items) override;
+ virtual void visit (TupleStructItemsHasRest &tuple_items) override;
virtual void visit (TupleStructPattern &pattern) override;
- virtual void visit (TuplePatternItemsMultiple &tuple_items) override;
- virtual void visit (TuplePatternItemsRanged &tuple_items) override;
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) override;
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) override;
virtual void visit (TuplePattern &pattern) override;
+ virtual void visit (SlicePatternItemsNoRest &items) override;
+ virtual void visit (SlicePatternItemsHasRest &items) override;
virtual void visit (SlicePattern &pattern) override;
virtual void visit (AltPattern &pattern) override;
virtual void visit (EmptyStmt &stmt) override;
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index 2566971..f132e04 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -28,15 +28,12 @@
#include "rust-tyty.h"
#include "rust-immutable-name-resolution-context.h"
-// for flag_name_resolution_2_0
-#include "options.h"
-
namespace Rust {
namespace Analysis {
PatternChecker::PatternChecker ()
: tyctx (*Resolver::TypeCheckContext::get ()),
- resolver (*Resolver::Resolver::get ()),
+ resolver (Resolver2_0::ImmutableNameResolutionContext::get ().resolver ()),
mappings (Analysis::Mappings::get ())
{}
@@ -238,17 +235,9 @@ PatternChecker::visit (CallExpr &expr)
NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid ();
NodeId 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
- return;
- }
- else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ if (auto id = resolver.lookup (ast_node_id))
+ ref_node_id = *id;
+ else
return;
if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id))
@@ -640,11 +629,11 @@ PatternChecker::visit (StructPattern &)
{}
void
-PatternChecker::visit (TupleStructItemsNoRange &)
+PatternChecker::visit (TupleStructItemsNoRest &)
{}
void
-PatternChecker::visit (TupleStructItemsRange &)
+PatternChecker::visit (TupleStructItemsHasRest &)
{}
void
@@ -652,11 +641,11 @@ PatternChecker::visit (TupleStructPattern &)
{}
void
-PatternChecker::visit (TuplePatternItemsMultiple &)
+PatternChecker::visit (TuplePatternItemsNoRest &)
{}
void
-PatternChecker::visit (TuplePatternItemsRanged &)
+PatternChecker::visit (TuplePatternItemsHasRest &)
{}
void
@@ -664,6 +653,14 @@ PatternChecker::visit (TuplePattern &)
{}
void
+PatternChecker::visit (SlicePatternItemsNoRest &)
+{}
+
+void
+PatternChecker::visit (SlicePatternItemsHasRest &)
+{}
+
+void
PatternChecker::visit (SlicePattern &)
{}
@@ -980,7 +977,7 @@ Matrix::specialize (const Constructor &ctor) const
if (ctor.is_covered_by (hd.ctor ()))
{
pats.pop_head_constructor (ctor, subfields_place_info.size ());
- new_rows.push_back (MatrixRow (pats, row.is_under_guard ()));
+ new_rows.emplace_back (pats, row.is_under_guard ());
}
}
@@ -1186,7 +1183,7 @@ WitnessMatrix::apply_constructor (const Constructor &ctor,
}
}
- stack.push_back (WitnessPat (ctor, subfield, ty));
+ stack.emplace_back (ctor, subfield, ty);
}
}
@@ -1213,27 +1210,54 @@ lower_tuple_pattern (Resolver::TypeCheckContext *ctx,
std::vector<DeconstructedPat> fields;
switch (elems.get_item_type ())
{
- case HIR::TupleStructItems::ItemType::MULTIPLE:
+ case HIR::TupleStructItems::ItemType::NO_REST:
{
- HIR::TupleStructItemsNoRange &multiple
- = static_cast<HIR::TupleStructItemsNoRange &> (elems);
+ HIR::TupleStructItemsNoRest &items_no_rest
+ = static_cast<HIR::TupleStructItemsNoRest &> (elems);
rust_assert (variant->get_fields ().size ()
- == multiple.get_patterns ().size ());
+ == items_no_rest.get_patterns ().size ());
- for (size_t i = 0; i < multiple.get_patterns ().size (); i++)
+ for (size_t i = 0; i < items_no_rest.get_patterns ().size (); i++)
{
fields.push_back (
- lower_pattern (ctx, *multiple.get_patterns ().at (i),
+ lower_pattern (ctx, *items_no_rest.get_patterns ().at (i),
variant->get_fields ().at (i)->get_field_type ()));
}
return DeconstructedPat (ctor, arity, fields, pattern.get_locus ());
}
break;
- case HIR::TupleStructItems::ItemType::RANGED:
+ case HIR::TupleStructItems::ItemType::HAS_REST:
{
- // TODO: ranged tuple struct items
- rust_unreachable ();
+ HIR::TupleStructItemsHasRest &items_has_rest
+ = static_cast<HIR::TupleStructItemsHasRest &> (elems);
+
+ size_t num_patterns = items_has_rest.get_lower_patterns ().size ()
+ + items_has_rest.get_upper_patterns ().size ();
+
+ rust_assert (num_patterns <= variant->num_fields ());
+
+ size_t i = 0;
+ for (auto &pattern_member : items_has_rest.get_lower_patterns ())
+ {
+ fields.push_back (lower_pattern (
+ ctx, *pattern_member,
+ variant->get_fields ().at (i++)->get_field_type ()));
+ }
+ while (i < variant->num_fields ()
+ - items_has_rest.get_upper_patterns ().size ())
+ {
+ fields.push_back (
+ DeconstructedPat::make_wildcard (pattern.get_locus ()));
+ i++;
+ }
+ for (auto &pattern_member : items_has_rest.get_upper_patterns ())
+ {
+ fields.push_back (lower_pattern (
+ ctx, *pattern_member,
+ variant->get_fields ().at (i++)->get_field_type ()));
+ }
+ return DeconstructedPat (ctor, arity, fields, pattern.get_locus ());
}
break;
default:
@@ -1597,7 +1621,7 @@ check_match_usefulness (Resolver::TypeCheckContext *ctx,
MatchArm lowered = lower_arm (ctx, arm, scrutinee_ty);
PatOrWild pat = PatOrWild::make_pattern (lowered.get_pat ());
pats.push (pat);
- rows.push_back (MatrixRow (pats, lowered.has_guard ()));
+ rows.emplace_back (pats, lowered.has_guard ());
}
std::vector<PlaceInfo> place_infos = {{PlaceInfo (scrutinee_ty)}};
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
index dd44abc..645e61d 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
@@ -26,7 +26,7 @@
#include "rust-tyty.h"
#include "optional.h"
#include "rust-hir-visitor.h"
-#include "rust-name-resolver.h"
+#include "rust-immutable-name-resolution-context.h"
namespace Rust {
namespace Analysis {
@@ -46,7 +46,7 @@ public:
private:
Resolver::TypeCheckContext &tyctx;
- Resolver::Resolver &resolver;
+ const Resolver2_0::NameResolutionContext &resolver;
Analysis::Mappings &mappings;
virtual void visit (Lifetime &lifetime) override;
@@ -153,12 +153,14 @@ private:
virtual void visit (StructPatternFieldIdentPat &field) override;
virtual void visit (StructPatternFieldIdent &field) override;
virtual void visit (StructPattern &pattern) override;
- virtual void visit (TupleStructItemsNoRange &tuple_items) override;
- virtual void visit (TupleStructItemsRange &tuple_items) override;
+ virtual void visit (TupleStructItemsNoRest &tuple_items) override;
+ virtual void visit (TupleStructItemsHasRest &tuple_items) override;
virtual void visit (TupleStructPattern &pattern) override;
- virtual void visit (TuplePatternItemsMultiple &tuple_items) override;
- virtual void visit (TuplePatternItemsRanged &tuple_items) override;
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) override;
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) override;
virtual void visit (TuplePattern &pattern) override;
+ virtual void visit (SlicePatternItemsNoRest &items) override;
+ virtual void visit (SlicePatternItemsHasRest &items) override;
virtual void visit (SlicePattern &pattern) override;
virtual void visit (AltPattern &pattern) override;
virtual void visit (EmptyStmt &stmt) override;
diff --git a/gcc/rust/checks/errors/rust-readonly-check.cc b/gcc/rust/checks/errors/rust-readonly-check.cc
index c128933..f484047 100644
--- a/gcc/rust/checks/errors/rust-readonly-check.cc
+++ b/gcc/rust/checks/errors/rust-readonly-check.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2021-2025 Free Software Foundation, Inc.
+// Copyright (C) 2025 Free Software Foundation, Inc.
// This file is part of GCC.
@@ -17,184 +17,252 @@
// <http://www.gnu.org/licenses/>.
#include "rust-readonly-check.h"
-#include "rust-tree.h"
-#include "rust-gcc.h"
-#include "print-tree.h"
+#include "rust-hir-expr.h"
+#include "rust-hir-node.h"
+#include "rust-hir-path.h"
+#include "rust-hir-map.h"
+#include "rust-hir-pattern.h"
+#include "rust-mapping-common.h"
+#include "rust-system.h"
+#include "rust-immutable-name-resolution-context.h"
+#include "rust-tyty.h"
namespace Rust {
-namespace Analysis {
+namespace HIR {
-static std::map<tree, int> assignment_map = {};
+static std::set<HirId> already_assigned_variables = {};
+
+ReadonlyChecker::ReadonlyChecker ()
+ : resolver (*Resolver::Resolver::get ()),
+ mappings (Analysis::Mappings::get ()),
+ context (*Resolver::TypeCheckContext::get ())
+{}
+
+void
+ReadonlyChecker::go (Crate &crate)
+{
+ for (auto &item : crate.get_items ())
+ item->accept_vis (*this);
+}
-// ported over from c-family/c-warn.cc
void
-readonly_error (location_t loc, tree arg, enum lvalue_use use)
+ReadonlyChecker::visit (AssignmentExpr &expr)
{
- gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement
- || use == lv_asm);
- STRIP_ANY_LOCATION_WRAPPER (arg);
- /* Using this macro rather than (for example) arrays of messages
- ensures that all the format strings are checked at compile
- time. */
-#define READONLY_MSG(A, I, D, AS) \
- (use == lv_assign \
- ? (A) \
- : (use == lv_increment ? (I) : (use == lv_decrement ? (D) : (AS))))
- if (TREE_CODE (arg) == COMPONENT_REF)
+ Expr &lhs = expr.get_lhs ();
+ mutable_context.enter (expr.get_mappings ().get_hirid ());
+ lhs.accept_vis (*this);
+ mutable_context.exit ();
+}
+
+void
+ReadonlyChecker::visit (PathInExpression &expr)
+{
+ if (!mutable_context.is_in_context ())
+ return;
+
+ NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
+ NodeId def_id;
+
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+ if (auto id = nr_ctx.lookup (ast_node_id))
+ def_id = *id;
+ else
+ return;
+
+ auto hir_id = mappings.lookup_node_to_hir (def_id);
+ if (!hir_id)
+ return;
+
+ // Check if the local variable is mutable.
+ auto maybe_pattern = mappings.lookup_hir_pattern (*hir_id);
+ if (maybe_pattern
+ && maybe_pattern.value ()->get_pattern_type ()
+ == HIR::Pattern::PatternType::IDENTIFIER)
+ check_variable (static_cast<IdentifierPattern *> (maybe_pattern.value ()),
+ expr.get_locus ());
+
+ // Check if the static item is mutable.
+ auto maybe_item = mappings.lookup_hir_item (*hir_id);
+ if (maybe_item
+ && maybe_item.value ()->get_item_kind () == HIR::Item::ItemKind::Static)
{
- if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
- error_at (loc,
- READONLY_MSG (G_ ("assignment of member "
- "%qD in read-only object"),
- G_ ("increment of member "
- "%qD in read-only object"),
- G_ ("decrement of member "
- "%qD in read-only object"),
- G_ ("member %qD in read-only object "
- "used as %<asm%> output")),
- TREE_OPERAND (arg, 1));
- else
- error_at (
- loc,
- READONLY_MSG (G_ ("assignment of read-only member %qD"),
- G_ ("increment of read-only member %qD"),
- G_ ("decrement of read-only member %qD"),
- G_ ("read-only member %qD used as %<asm%> output")),
- TREE_OPERAND (arg, 1));
+ auto static_item = static_cast<HIR::StaticItem *> (*maybe_item);
+ if (!static_item->is_mut ())
+ rust_error_at (expr.get_locus (),
+ "assignment of read-only location '%s'",
+ static_item->get_identifier ().as_string ().c_str ());
}
- else if (VAR_P (arg))
- error_at (loc,
- READONLY_MSG (G_ ("assignment of read-only variable %qD"),
- G_ ("increment of read-only variable %qD"),
- G_ ("decrement of read-only variable %qD"),
- G_ (
- "read-only variable %qD used as %<asm%> output")),
- arg);
- else if (TREE_CODE (arg) == PARM_DECL)
- error_at (loc,
- READONLY_MSG (G_ ("assignment of read-only parameter %qD"),
- G_ ("increment of read-only parameter %qD"),
- G_ ("decrement of read-only parameter %qD"),
- G_ (
- "read-only parameter %qD use as %<asm%> output")),
- arg);
- else if (TREE_CODE (arg) == RESULT_DECL)
+
+ // Check if the constant item is mutable.
+ if (maybe_item
+ && maybe_item.value ()->get_item_kind () == HIR::Item::ItemKind::Constant)
{
- error_at (loc,
- READONLY_MSG (G_ ("assignment of "
- "read-only named return value %qD"),
- G_ ("increment of "
- "read-only named return value %qD"),
- G_ ("decrement of "
- "read-only named return value %qD"),
- G_ ("read-only named return value %qD "
- "used as %<asm%>output")),
- arg);
+ auto const_item = static_cast<HIR::ConstantItem *> (*maybe_item);
+ rust_error_at (expr.get_locus (), "assignment of read-only location '%s'",
+ const_item->get_identifier ().as_string ().c_str ());
}
- else if (TREE_CODE (arg) == FUNCTION_DECL)
- error_at (loc,
- READONLY_MSG (G_ ("assignment of function %qD"),
- G_ ("increment of function %qD"),
- G_ ("decrement of function %qD"),
- G_ ("function %qD used as %<asm%> output")),
- arg);
- else
- error_at (loc,
- READONLY_MSG (G_ ("assignment of read-only location %qE"),
- G_ ("increment of read-only location %qE"),
- G_ ("decrement of read-only location %qE"),
- G_ (
- "read-only location %qE used as %<asm%> output")),
- arg);
}
-static void
-emit_error (tree *t, tree lhs, enum lvalue_use use)
+void
+ReadonlyChecker::check_variable (IdentifierPattern *pattern,
+ location_t assigned_loc)
{
- readonly_error (EXPR_LOCATION (*t), lhs, use);
- TREE_OPERAND (*t, 0) = error_mark_node;
+ if (!mutable_context.is_in_context ())
+ return;
+
+ TyTy::BaseType *type;
+ if (context.lookup_type (pattern->get_mappings ().get_hirid (), &type)
+ && is_mutable_type (type))
+ return;
+ if (pattern->is_mut ())
+ return;
+
+ auto hir_id = pattern->get_mappings ().get_hirid ();
+ if (already_assigned_variables.count (hir_id) > 0)
+ rust_error_at (assigned_loc, "assignment of read-only variable '%s'",
+ pattern->as_string ().c_str ());
+ already_assigned_variables.insert (hir_id);
}
-static void
-check_modify_expr (tree *t)
+void
+ReadonlyChecker::collect_assignment_identifier (IdentifierPattern &pattern,
+ bool has_init_expr)
{
- 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))
+ if (has_init_expr)
{
- if (TREE_CODE (lhs) != VAR_DECL)
- emit_error (t, lhs, lv_assign);
- else if (!DECL_ARTIFICIAL (lhs))
- {
- 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);
- }
- }
+ HirId pattern_id = pattern.get_mappings ().get_hirid ();
+ already_assigned_variables.insert (pattern_id);
}
}
-static void
-check_decl (tree *t)
+void
+ReadonlyChecker::collect_assignment_tuple (TuplePattern &tuple_pattern,
+ bool has_init_expr)
{
- switch (TREE_CODE (*t))
+ switch (tuple_pattern.get_items ().get_item_type ())
{
- case MODIFY_EXPR:
- check_modify_expr (t);
+ case HIR::TuplePatternItems::ItemType::NO_REST:
+ {
+ auto &items_no_rest = static_cast<HIR::TuplePatternItemsNoRest &> (
+ tuple_pattern.get_items ());
+ for (auto &sub : items_no_rest.get_patterns ())
+ {
+ collect_assignment (*sub, has_init_expr);
+ }
+ }
+ break;
+ case HIR::TuplePatternItems::ItemType::HAS_REST:
+ {
+ auto &items_has_rest = static_cast<HIR::TuplePatternItemsHasRest &> (
+ tuple_pattern.get_items ());
+ for (auto &sub : items_has_rest.get_lower_patterns ())
+ collect_assignment (*sub, has_init_expr);
+ for (auto &sub : items_has_rest.get_upper_patterns ())
+ collect_assignment (*sub, has_init_expr);
+ }
+ break;
+ default:
break;
+ }
+}
+void
+ReadonlyChecker::collect_assignment (Pattern &pattern, bool has_init_expr)
+{
+ switch (pattern.get_pattern_type ())
+ {
+ case HIR::Pattern::PatternType::IDENTIFIER:
+ {
+ collect_assignment_identifier (static_cast<IdentifierPattern &> (
+ pattern),
+ has_init_expr);
+ }
+ break;
+ case HIR::Pattern::PatternType::TUPLE:
+ {
+ auto &tuple_pattern = static_cast<HIR::TuplePattern &> (pattern);
+ collect_assignment_tuple (tuple_pattern, has_init_expr);
+ }
+ break;
default:
break;
}
}
-static tree
-readonly_walk_fn (tree *t, int *, void *)
+void
+ReadonlyChecker::visit (LetStmt &stmt)
+{
+ HIR::Pattern &pattern = stmt.get_pattern ();
+ collect_assignment (pattern, stmt.has_init_expr ());
+}
+
+void
+ReadonlyChecker::visit (FieldAccessExpr &expr)
{
- check_decl (t);
- return NULL_TREE;
+ if (mutable_context.is_in_context ())
+ {
+ expr.get_receiver_expr ().accept_vis (*this);
+ }
}
void
-ReadonlyCheck::Lint (Compile::Context &ctx)
+ReadonlyChecker::visit (TupleIndexExpr &expr)
{
- assignment_map.clear ();
- for (auto &fndecl : ctx.get_func_decls ())
+ if (mutable_context.is_in_context ())
{
- for (tree p = DECL_ARGUMENTS (fndecl); p != NULL_TREE; p = DECL_CHAIN (p))
- {
- check_decl (&p);
- }
+ expr.get_tuple_expr ().accept_vis (*this);
+ }
+}
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
- &readonly_walk_fn, &ctx);
+void
+ReadonlyChecker::visit (ArrayIndexExpr &expr)
+{
+ if (mutable_context.is_in_context ())
+ {
+ expr.get_array_expr ().accept_vis (*this);
}
+}
- assignment_map.clear ();
- for (auto &var : ctx.get_var_decls ())
+void
+ReadonlyChecker::visit (TupleExpr &expr)
+{
+ if (mutable_context.is_in_context ())
{
- tree decl = var->get_decl ();
- check_decl (&decl);
+ // TODO: Add check for tuple expression
}
+}
- assignment_map.clear ();
- for (auto &const_decl : ctx.get_const_decls ())
+void
+ReadonlyChecker::visit (LiteralExpr &expr)
+{
+ if (mutable_context.is_in_context ())
{
- check_decl (&const_decl);
+ rust_error_at (expr.get_locus (), "assignment of read-only location");
}
}
-} // namespace Analysis
+void
+ReadonlyChecker::visit (DereferenceExpr &expr)
+{
+ if (!mutable_context.is_in_context ())
+ return;
+ TyTy::BaseType *to_deref_type;
+ auto to_deref = expr.get_expr ().get_mappings ().get_hirid ();
+ if (!context.lookup_type (to_deref, &to_deref_type))
+ return;
+ if (!is_mutable_type (to_deref_type))
+ rust_error_at (expr.get_locus (), "assignment of read-only location");
+}
+
+bool
+ReadonlyChecker::is_mutable_type (TyTy::BaseType *type)
+{
+ if (type->get_kind () == TyTy::TypeKind::REF)
+ return static_cast<TyTy::ReferenceType *> (type)->is_mutable ();
+ if (type->get_kind () == TyTy::TypeKind::POINTER)
+ return static_cast<TyTy::PointerType *> (type)->is_mutable ();
+ return false;
+}
+} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-readonly-check.h b/gcc/rust/checks/errors/rust-readonly-check.h
index b39eee3..3525620 100644
--- a/gcc/rust/checks/errors/rust-readonly-check.h
+++ b/gcc/rust/checks/errors/rust-readonly-check.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2021-2025 Free Software Foundation, Inc.
+// Copyright (C) 2025 Free Software Foundation, Inc.
// This file is part of GCC.
@@ -16,21 +16,54 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#ifndef RUST_READONLY_CHECK
-#define RUST_READONLY_CHECK
-
-#include "rust-compile-context.h"
+#include "rust-hir-visitor.h"
+#include "rust-name-resolver.h"
+#include "rust-stacked-contexts.h"
+#include "rust-hir-type-check.h"
namespace Rust {
-namespace Analysis {
-
-class ReadonlyCheck
+namespace HIR {
+class ReadonlyChecker : public DefaultHIRVisitor
{
public:
- static void Lint (Compile::Context &ctx);
-};
+ ReadonlyChecker ();
+
+ void go (HIR::Crate &crate);
+
+private:
+ enum class lvalue_use
+ {
+ assign,
+ increment,
+ decrement,
+ };
+
+ Resolver::Resolver &resolver;
+ Analysis::Mappings &mappings;
+ Resolver::TypeCheckContext &context;
+ StackedContexts<HirId> mutable_context;
-} // namespace Analysis
-} // namespace Rust
+ using DefaultHIRVisitor::visit;
+
+ virtual void visit (AssignmentExpr &expr) override;
+ virtual void visit (PathInExpression &expr) override;
+ virtual void visit (FieldAccessExpr &expr) override;
+ virtual void visit (ArrayIndexExpr &expr) override;
+ virtual void visit (TupleExpr &expr) override;
+ virtual void visit (TupleIndexExpr &expr) override;
+ virtual void visit (LetStmt &stmt) override;
+ virtual void visit (LiteralExpr &expr) override;
+ virtual void visit (DereferenceExpr &expr) override;
+
+ void collect_assignment (Pattern &pattern, bool has_init_expr);
+ void collect_assignment_identifier (IdentifierPattern &pattern,
+ bool has_init_expr);
+ void collect_assignment_tuple (TuplePattern &pattern, bool has_init_expr);
+
+ void check_variable (IdentifierPattern *pattern, location_t assigned_loc);
+
+ bool is_mutable_type (TyTy::BaseType *type);
+};
-#endif // RUST_READONLY_CHECK
+} // namespace HIR
+} // namespace Rust \ No newline at end of file
diff --git a/gcc/rust/checks/errors/rust-readonly-check2.cc b/gcc/rust/checks/errors/rust-readonly-check2.cc
deleted file mode 100644
index 2fa92ae..0000000
--- a/gcc/rust/checks/errors/rust-readonly-check2.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// 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-readonly-check2.h"
-#include "rust-hir-expr.h"
-#include "rust-hir-node.h"
-#include "rust-hir-path.h"
-#include "rust-hir-map.h"
-#include "rust-hir-pattern.h"
-#include "rust-mapping-common.h"
-#include "rust-system.h"
-#include "rust-immutable-name-resolution-context.h"
-#include "rust-tyty.h"
-
-namespace Rust {
-namespace HIR {
-
-static std::set<HirId> already_assigned_variables = {};
-
-ReadonlyChecker::ReadonlyChecker ()
- : resolver (*Resolver::Resolver::get ()),
- mappings (Analysis::Mappings::get ()),
- context (*Resolver::TypeCheckContext::get ())
-{}
-
-void
-ReadonlyChecker::go (Crate &crate)
-{
- for (auto &item : crate.get_items ())
- item->accept_vis (*this);
-}
-
-void
-ReadonlyChecker::visit (AssignmentExpr &expr)
-{
- Expr &lhs = expr.get_lhs ();
- mutable_context.enter (expr.get_mappings ().get_hirid ());
- lhs.accept_vis (*this);
- mutable_context.exit ();
-}
-
-void
-ReadonlyChecker::visit (PathInExpression &expr)
-{
- if (!mutable_context.is_in_context ())
- return;
-
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
- NodeId def_id;
-
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- if (auto id = nr_ctx.lookup (ast_node_id))
- def_id = *id;
- else
- return;
-
- auto hir_id = mappings.lookup_node_to_hir (def_id);
- if (!hir_id)
- return;
-
- // Check if the local variable is mutable.
- auto maybe_pattern = mappings.lookup_hir_pattern (*hir_id);
- if (maybe_pattern
- && maybe_pattern.value ()->get_pattern_type ()
- == HIR::Pattern::PatternType::IDENTIFIER)
- check_variable (static_cast<IdentifierPattern *> (maybe_pattern.value ()),
- expr.get_locus ());
-
- // Check if the static item is mutable.
- auto maybe_item = mappings.lookup_hir_item (*hir_id);
- if (maybe_item
- && maybe_item.value ()->get_item_kind () == HIR::Item::ItemKind::Static)
- {
- auto static_item = static_cast<HIR::StaticItem *> (*maybe_item);
- if (!static_item->is_mut ())
- rust_error_at (expr.get_locus (),
- "assignment of read-only location '%s'",
- static_item->get_identifier ().as_string ().c_str ());
- }
-
- // Check if the constant item is mutable.
- if (maybe_item
- && maybe_item.value ()->get_item_kind () == HIR::Item::ItemKind::Constant)
- {
- auto const_item = static_cast<HIR::ConstantItem *> (*maybe_item);
- rust_error_at (expr.get_locus (), "assignment of read-only location '%s'",
- const_item->get_identifier ().as_string ().c_str ());
- }
-}
-
-void
-ReadonlyChecker::check_variable (IdentifierPattern *pattern,
- location_t assigned_loc)
-{
- if (!mutable_context.is_in_context ())
- return;
- if (pattern->is_mut ())
- return;
-
- auto hir_id = pattern->get_mappings ().get_hirid ();
- if (already_assigned_variables.count (hir_id) > 0)
- rust_error_at (assigned_loc, "assignment of read-only variable '%s'",
- pattern->as_string ().c_str ());
- already_assigned_variables.insert (hir_id);
-}
-
-void
-ReadonlyChecker::collect_assignment_identifier (IdentifierPattern &pattern,
- bool has_init_expr)
-{
- if (has_init_expr)
- {
- HirId pattern_id = pattern.get_mappings ().get_hirid ();
- already_assigned_variables.insert (pattern_id);
- }
-}
-
-void
-ReadonlyChecker::collect_assignment_tuple (TuplePattern &tuple_pattern,
- bool has_init_expr)
-{
- switch (tuple_pattern.get_items ().get_item_type ())
- {
- case HIR::TuplePatternItems::ItemType::MULTIPLE:
- {
- auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- tuple_pattern.get_items ());
- for (auto &sub : items.get_patterns ())
- {
- collect_assignment (*sub, has_init_expr);
- }
- }
- break;
- default:
- break;
- }
-}
-
-void
-ReadonlyChecker::collect_assignment (Pattern &pattern, bool has_init_expr)
-{
- switch (pattern.get_pattern_type ())
- {
- case HIR::Pattern::PatternType::IDENTIFIER:
- {
- collect_assignment_identifier (static_cast<IdentifierPattern &> (
- pattern),
- has_init_expr);
- }
- break;
- case HIR::Pattern::PatternType::TUPLE:
- {
- auto &tuple_pattern = static_cast<HIR::TuplePattern &> (pattern);
- collect_assignment_tuple (tuple_pattern, has_init_expr);
- }
- break;
- default:
- break;
- }
-}
-
-void
-ReadonlyChecker::visit (LetStmt &stmt)
-{
- HIR::Pattern &pattern = stmt.get_pattern ();
- collect_assignment (pattern, stmt.has_init_expr ());
-}
-
-void
-ReadonlyChecker::visit (FieldAccessExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- expr.get_receiver_expr ().accept_vis (*this);
- }
-}
-
-void
-ReadonlyChecker::visit (TupleIndexExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- expr.get_tuple_expr ().accept_vis (*this);
- }
-}
-
-void
-ReadonlyChecker::visit (ArrayIndexExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- expr.get_array_expr ().accept_vis (*this);
- }
-}
-
-void
-ReadonlyChecker::visit (TupleExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- // TODO: Add check for tuple expression
- }
-}
-
-void
-ReadonlyChecker::visit (LiteralExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- rust_error_at (expr.get_locus (), "assignment of read-only location");
- }
-}
-
-void
-ReadonlyChecker::visit (DereferenceExpr &expr)
-{
- if (!mutable_context.is_in_context ())
- return;
- TyTy::BaseType *to_deref_type;
- auto to_deref = expr.get_expr ().get_mappings ().get_hirid ();
- if (!context.lookup_type (to_deref, &to_deref_type))
- return;
- if (to_deref_type->get_kind () == TyTy::TypeKind::REF)
- {
- auto ref_type = static_cast<TyTy::ReferenceType *> (to_deref_type);
- if (!ref_type->is_mutable ())
- rust_error_at (expr.get_locus (), "assignment of read-only location");
- }
- if (to_deref_type->get_kind () == TyTy::TypeKind::POINTER)
- {
- auto ptr_type = static_cast<TyTy::PointerType *> (to_deref_type);
- if (!ptr_type->is_mutable ())
- rust_error_at (expr.get_locus (), "assignment of read-only location");
- }
-}
-} // namespace HIR
-} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-readonly-check2.h b/gcc/rust/checks/errors/rust-readonly-check2.h
deleted file mode 100644
index 06af9db..0000000
--- a/gcc/rust/checks/errors/rust-readonly-check2.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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-hir-visitor.h"
-#include "rust-name-resolver.h"
-#include "rust-stacked-contexts.h"
-#include "rust-hir-type-check.h"
-
-namespace Rust {
-namespace HIR {
-class ReadonlyChecker : public DefaultHIRVisitor
-{
-public:
- ReadonlyChecker ();
-
- void go (HIR::Crate &crate);
-
-private:
- enum class lvalue_use
- {
- assign,
- increment,
- decrement,
- };
-
- Resolver::Resolver &resolver;
- Analysis::Mappings &mappings;
- Resolver::TypeCheckContext &context;
- StackedContexts<HirId> mutable_context;
-
- using DefaultHIRVisitor::visit;
-
- virtual void visit (AssignmentExpr &expr) override;
- virtual void visit (PathInExpression &expr) override;
- virtual void visit (FieldAccessExpr &expr) override;
- virtual void visit (ArrayIndexExpr &expr) override;
- virtual void visit (TupleExpr &expr) override;
- virtual void visit (TupleIndexExpr &expr) override;
- virtual void visit (LetStmt &stmt) override;
- virtual void visit (LiteralExpr &expr) override;
- virtual void visit (DereferenceExpr &expr) override;
-
- void collect_assignment (Pattern &pattern, bool has_init_expr);
- void collect_assignment_identifier (IdentifierPattern &pattern,
- bool has_init_expr);
- void collect_assignment_tuple (TuplePattern &pattern, bool has_init_expr);
-
- void check_variable (IdentifierPattern *pattern, location_t assigned_loc);
-};
-
-} // namespace HIR
-} // namespace Rust \ No newline at end of file
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 405c59b..607d20f 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -926,11 +926,11 @@ UnsafeChecker::visit (StructPattern &)
{}
void
-UnsafeChecker::visit (TupleStructItemsNoRange &)
+UnsafeChecker::visit (TupleStructItemsNoRest &)
{}
void
-UnsafeChecker::visit (TupleStructItemsRange &)
+UnsafeChecker::visit (TupleStructItemsHasRest &)
{}
void
@@ -938,11 +938,11 @@ UnsafeChecker::visit (TupleStructPattern &)
{}
void
-UnsafeChecker::visit (TuplePatternItemsMultiple &)
+UnsafeChecker::visit (TuplePatternItemsNoRest &)
{}
void
-UnsafeChecker::visit (TuplePatternItemsRanged &)
+UnsafeChecker::visit (TuplePatternItemsHasRest &)
{}
void
@@ -950,6 +950,14 @@ UnsafeChecker::visit (TuplePattern &)
{}
void
+UnsafeChecker::visit (SlicePatternItemsNoRest &)
+{}
+
+void
+UnsafeChecker::visit (SlicePatternItemsHasRest &)
+{}
+
+void
UnsafeChecker::visit (SlicePattern &)
{}
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h
index dc3b482..420668f 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -161,12 +161,14 @@ private:
virtual void visit (StructPatternFieldIdentPat &field) override;
virtual void visit (StructPatternFieldIdent &field) override;
virtual void visit (StructPattern &pattern) override;
- virtual void visit (TupleStructItemsNoRange &tuple_items) override;
- virtual void visit (TupleStructItemsRange &tuple_items) override;
+ virtual void visit (TupleStructItemsNoRest &tuple_items) override;
+ virtual void visit (TupleStructItemsHasRest &tuple_items) override;
virtual void visit (TupleStructPattern &pattern) override;
- virtual void visit (TuplePatternItemsMultiple &tuple_items) override;
- virtual void visit (TuplePatternItemsRanged &tuple_items) override;
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) override;
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) override;
virtual void visit (TuplePattern &pattern) override;
+ virtual void visit (SlicePatternItemsNoRest &items) override;
+ virtual void visit (SlicePatternItemsHasRest &items) override;
virtual void visit (SlicePattern &pattern) override;
virtual void visit (AltPattern &pattern) override;
virtual void visit (EmptyStmt &stmt) override;
diff --git a/gcc/rust/checks/lints/rust-lint-marklive-base.h b/gcc/rust/checks/lints/rust-lint-marklive-base.h
index 2a97577..dec9396 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive-base.h
+++ b/gcc/rust/checks/lints/rust-lint-marklive-base.h
@@ -19,9 +19,6 @@
#ifndef RUST_HIR_LIVENESS_BASE
#define RUST_HIR_LIVENESS_BASE
-#include "rust-diagnostics.h"
-#include "rust-lint-marklive.h"
-#include "rust-lint-marklive-base.h"
#include "rust-hir-visitor.h"
#include "rust-hir-map.h"
diff --git a/gcc/rust/expand/rust-cfg-strip.cc b/gcc/rust/expand/rust-cfg-strip.cc
index 58d8071..3c5e74e 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -22,6 +22,7 @@
#include "rust-path.h"
#include "rust-session-manager.h"
#include "rust-attribute-values.h"
+#include "rust-macro-expand.h"
namespace Rust {
@@ -30,7 +31,7 @@ namespace Rust {
* should be stripped. Note that attributes must be expanded before calling.
*/
bool
-fails_cfg (const AST::AttrVec &attrs)
+CfgStrip::fails_cfg (const AST::AttrVec &attrs) const
{
auto &session = Session::get_instance ();
@@ -39,6 +40,9 @@ fails_cfg (const AST::AttrVec &attrs)
if (attr.get_path () == Values::Attributes::CFG
&& !attr.check_cfg_predicate (session))
return true;
+ else if (!expansion_cfg.should_test
+ && attr.get_path () == Values::Attributes::TEST)
+ return true;
}
return false;
}
@@ -48,7 +52,7 @@ fails_cfg (const AST::AttrVec &attrs)
* should be stripped. Will expand attributes as well.
*/
bool
-fails_cfg_with_expand (AST::AttrVec &attrs)
+CfgStrip::fails_cfg_with_expand (AST::AttrVec &attrs) const
{
auto &session = Session::get_instance ();
@@ -85,6 +89,9 @@ fails_cfg_with_expand (AST::AttrVec &attrs)
attr.as_string ().c_str ());
}
}
+ else if (!expansion_cfg.should_test
+ && attr.get_path () == Values::Attributes::TEST)
+ return true;
}
return false;
}
@@ -2062,38 +2069,6 @@ CfgStrip::visit (AST::StaticItem &static_item)
}
void
-CfgStrip::visit (AST::TraitItemConst &item)
-{
- // initial test based on outer attrs
- expand_cfg_attrs (item.get_outer_attrs ());
- if (fails_cfg_with_expand (item.get_outer_attrs ()))
- {
- item.mark_for_strip ();
- return;
- }
-
- AST::DefaultASTVisitor::visit (item);
-
- // strip any sub-types
- auto &type = item.get_type ();
-
- if (type.is_marked_for_strip ())
- rust_error_at (type.get_locus (), "cannot strip type in this position");
-
- /* strip any internal sub-expressions - expression itself isn't
- * allowed to have external attributes in this position so can't be
- * stripped */
- if (item.has_expression ())
- {
- auto &expr = item.get_expr ();
- if (expr.is_marked_for_strip ())
- rust_error_at (expr.get_locus (),
- "cannot strip expression in this position - outer "
- "attributes not allowed");
- }
-}
-
-void
CfgStrip::visit (AST::TraitItemType &item)
{
// initial test based on outer attrs
@@ -2374,7 +2349,7 @@ CfgStrip::visit (AST::StructPattern &pattern)
maybe_strip_pointer_allow_strip (elems.get_struct_pattern_fields ());
// assuming you can strip the ".." part
- if (elems.has_etc ())
+ if (elems.has_rest ())
{
expand_cfg_attrs (elems.get_etc_outer_attrs ());
if (fails_cfg_with_expand (elems.get_etc_outer_attrs ()))
@@ -2383,7 +2358,7 @@ CfgStrip::visit (AST::StructPattern &pattern)
}
void
-CfgStrip::visit (AST::TupleStructItemsNoRange &tuple_items)
+CfgStrip::visit (AST::TupleStructItemsNoRest &tuple_items)
{
AST::DefaultASTVisitor::visit (tuple_items);
// can't strip individual patterns, only sub-patterns
@@ -2396,7 +2371,7 @@ CfgStrip::visit (AST::TupleStructItemsNoRange &tuple_items)
}
}
void
-CfgStrip::visit (AST::TupleStructItemsRange &tuple_items)
+CfgStrip::visit (AST::TupleStructItemsHasRest &tuple_items)
{
AST::DefaultASTVisitor::visit (tuple_items);
// can't strip individual patterns, only sub-patterns
@@ -2429,7 +2404,7 @@ CfgStrip::visit (AST::TupleStructPattern &pattern)
}
void
-CfgStrip::visit (AST::TuplePatternItemsMultiple &tuple_items)
+CfgStrip::visit (AST::TuplePatternItemsNoRest &tuple_items)
{
AST::DefaultASTVisitor::visit (tuple_items);
@@ -2444,7 +2419,7 @@ CfgStrip::visit (AST::TuplePatternItemsMultiple &tuple_items)
}
void
-CfgStrip::visit (AST::TuplePatternItemsRanged &tuple_items)
+CfgStrip::visit (AST::TuplePatternItemsHasRest &tuple_items)
{
AST::DefaultASTVisitor::visit (tuple_items);
diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h
index 767cf28..42cd266 100644
--- a/gcc/rust/expand/rust-cfg-strip.h
+++ b/gcc/rust/expand/rust-cfg-strip.h
@@ -23,14 +23,23 @@
#include "rust-item.h"
namespace Rust {
+
+// forward declare
+struct ExpansionCfg;
+
// Visitor used to maybe_strip attributes.
class CfgStrip : public AST::DefaultASTVisitor
{
private:
+ bool fails_cfg (const AST::AttrVec &attrs) const;
+
+ bool fails_cfg_with_expand (AST::AttrVec &attrs) const;
+
public:
using DefaultASTVisitor::visit;
- CfgStrip () {}
+ CfgStrip (const ExpansionCfg &expansion_cfg) : expansion_cfg (expansion_cfg)
+ {}
/* Run the AttrVisitor on an entire crate */
void go (AST::Crate &crate);
@@ -147,7 +156,6 @@ public:
void visit (AST::Union &union_item) override;
void visit (AST::ConstantItem &const_item) override;
void visit (AST::StaticItem &static_item) override;
- void visit (AST::TraitItemConst &item) override;
void visit (AST::TraitItemType &item) override;
void visit (AST::Trait &trait) override;
void visit (AST::InherentImpl &impl) override;
@@ -166,11 +174,11 @@ public:
void visit (AST::StructPatternFieldIdentPat &field) override;
void visit (AST::StructPatternFieldIdent &field) override;
void visit (AST::StructPattern &pattern) override;
- void visit (AST::TupleStructItemsNoRange &tuple_items) override;
- void visit (AST::TupleStructItemsRange &tuple_items) override;
+ void visit (AST::TupleStructItemsNoRest &tuple_items) override;
+ void visit (AST::TupleStructItemsHasRest &tuple_items) override;
void visit (AST::TupleStructPattern &pattern) override;
- void visit (AST::TuplePatternItemsMultiple &tuple_items) override;
- void visit (AST::TuplePatternItemsRanged &tuple_items) override;
+ void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
+ void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
void visit (AST::GroupedPattern &pattern) override;
void visit (AST::SlicePatternItemsNoRest &items) override;
void visit (AST::SlicePatternItemsHasRest &items) override;
@@ -194,6 +202,9 @@ public:
{
DefaultASTVisitor::visit (item);
}
+
+private:
+ const ExpansionCfg &expansion_cfg;
};
} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc
index 321fa00..27dcc66 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -64,11 +64,10 @@ DeriveClone::clone_fn (std::unique_ptr<Expr> &&clone_expr)
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 (tl::nullopt,
- /* is_mut */ false, loc));
-
std::vector<std::unique_ptr<Param>> params;
- params.push_back (std::move (self));
+
+ params.emplace_back (new SelfParam (tl::nullopt,
+ /* is_mut */ false, loc));
return std::unique_ptr<AssociatedItem> (
new Function ({"clone"}, builder.fn_qualifiers (), /* generics */ {},
@@ -211,7 +210,7 @@ DeriveClone::clone_enum_tuple (PathInExpression variant_path,
}
auto pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (patterns)));
+ new TupleStructItemsNoRest (std::move (patterns)));
auto pattern = std::unique_ptr<Pattern> (new ReferencePattern (
std::unique_ptr<Pattern> (new TupleStructPattern (
diff --git a/gcc/rust/expand/rust-derive-cmp-common.cc b/gcc/rust/expand/rust-derive-cmp-common.cc
index 22ca16f..9890bb7 100644
--- a/gcc/rust/expand/rust-derive-cmp-common.cc
+++ b/gcc/rust/expand/rust-derive-cmp-common.cc
@@ -101,9 +101,9 @@ EnumMatchBuilder::tuple (EnumItem &variant_raw)
auto other_variant_path = builder.variant_path (enum_path, variant_path);
auto self_pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (self_patterns)));
+ new TupleStructItemsNoRest (std::move (self_patterns)));
auto other_pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (other_patterns)));
+ new TupleStructItemsNoRest (std::move (other_patterns)));
auto self_pattern = std::unique_ptr<Pattern> (
new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
@@ -114,7 +114,7 @@ EnumMatchBuilder::tuple (EnumItem &variant_raw)
other_variant_path, std::move (other_pattern_items))),
false, false, builder.loc));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
vec (std::move (self_pattern), std::move (other_pattern)));
auto pattern
@@ -176,7 +176,7 @@ EnumMatchBuilder::strukt (EnumItem &variant_raw)
std::move (other_elts))),
false, false, builder.loc));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
vec (std::move (self_pattern), std::move (other_pattern)));
auto pattern
diff --git a/gcc/rust/expand/rust-derive-eq.cc b/gcc/rust/expand/rust-derive-eq.cc
index 7da137f..17332a4 100644
--- a/gcc/rust/expand/rust-derive-eq.cc
+++ b/gcc/rust/expand/rust-derive-eq.cc
@@ -128,9 +128,13 @@ DeriveEq::eq_impls (
auto eq_impl = builder.trait_impl (eq, std::move (eq_generics.self_type),
std::move (trait_items),
std::move (eq_generics.impl));
+
+ // StructuralEq is a marker trait
+ decltype (trait_items) steq_trait_items = {};
+
auto steq_impl
= builder.trait_impl (steq, std::move (steq_generics.self_type),
- std::move (trait_items),
+ std::move (steq_trait_items),
std::move (steq_generics.impl));
return vec (std::move (eq_impl), std::move (steq_impl));
diff --git a/gcc/rust/expand/rust-derive-hash.cc b/gcc/rust/expand/rust-derive-hash.cc
index 94aede2..616bfdb 100644
--- a/gcc/rust/expand/rust-derive-hash.cc
+++ b/gcc/rust/expand/rust-derive-hash.cc
@@ -151,7 +151,7 @@ DeriveHash::match_enum_tuple (PathInExpression variant_path,
}
auto patterns_elts = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (self_patterns)));
+ new TupleStructItemsNoRest (std::move (self_patterns)));
auto pattern = std::unique_ptr<Pattern> (
new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
variant_path, std::move (patterns_elts))),
diff --git a/gcc/rust/expand/rust-derive-ord.cc b/gcc/rust/expand/rust-derive-ord.cc
index afc4b71..6f3981f 100644
--- a/gcc/rust/expand/rust-derive-ord.cc
+++ b/gcc/rust/expand/rust-derive-ord.cc
@@ -120,7 +120,7 @@ DeriveOrd::make_equal ()
if (ordering == Ordering::Partial)
{
auto pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (vec (std::move (equal))));
+ new TupleStructItemsNoRest (vec (std::move (equal))));
equal
= std::make_unique<TupleStructPattern> (builder.path_in_expression (
diff --git a/gcc/rust/expand/rust-derive-partial-eq.cc b/gcc/rust/expand/rust-derive-partial-eq.cc
index a0bf87a..287d8a7 100644
--- a/gcc/rust/expand/rust-derive-partial-eq.cc
+++ b/gcc/rust/expand/rust-derive-partial-eq.cc
@@ -146,7 +146,7 @@ DerivePartialEq::match_enum_identifier (
builder.ref_pattern (
std::unique_ptr<Pattern> (new PathInExpression (variant_path))));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
std::move (inner_ref_patterns));
auto pattern = std::make_unique<TuplePattern> (std::move (tuple_items), loc);
@@ -186,9 +186,9 @@ DerivePartialEq::match_enum_tuple (PathInExpression variant_path,
}
auto self_pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (self_patterns)));
+ new TupleStructItemsNoRest (std::move (self_patterns)));
auto other_pattern_items = std::unique_ptr<TupleStructItems> (
- new TupleStructItemsNoRange (std::move (other_patterns)));
+ new TupleStructItemsNoRest (std::move (other_patterns)));
auto self_pattern = std::unique_ptr<Pattern> (
new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
@@ -199,7 +199,7 @@ DerivePartialEq::match_enum_tuple (PathInExpression variant_path,
variant_path, std::move (other_pattern_items))),
false, false, loc));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
vec (std::move (self_pattern), std::move (other_pattern)));
auto pattern = std::make_unique<TuplePattern> (std::move (tuple_items), loc);
@@ -254,7 +254,7 @@ DerivePartialEq::match_enum_struct (PathInExpression variant_path,
variant_path, loc, std::move (other_elts))),
false, false, loc));
- auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ auto tuple_items = std::make_unique<TuplePatternItemsNoRest> (
vec (std::move (self_pattern), std::move (other_pattern)));
auto pattern = std::make_unique<TuplePattern> (std::move (tuple_items), loc);
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index 10c146c..d28bba9 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -192,7 +192,6 @@ private:
virtual void visit (EnumItemDiscriminant &item) override final{};
virtual void visit (ConstantItem &const_item) override final{};
virtual void visit (StaticItem &static_item) override final{};
- virtual void visit (TraitItemConst &item) override final{};
virtual void visit (TraitItemType &item) override final{};
virtual void visit (Trait &trait) override final{};
virtual void visit (InherentImpl &impl) override final{};
@@ -224,11 +223,11 @@ private:
virtual void visit (StructPatternFieldIdentPat &field) override final{};
virtual void visit (StructPatternFieldIdent &field) override final{};
virtual void visit (StructPattern &pattern) override final{};
- virtual void visit (TupleStructItemsNoRange &tuple_items) override final{};
- virtual void visit (TupleStructItemsRange &tuple_items) override final{};
+ virtual void visit (TupleStructItemsNoRest &tuple_items) override final{};
+ virtual void visit (TupleStructItemsHasRest &tuple_items) override final{};
virtual void visit (TupleStructPattern &pattern) override final{};
- virtual void visit (TuplePatternItemsMultiple &tuple_items) override final{};
- virtual void visit (TuplePatternItemsRanged &tuple_items) override final{};
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) override final{};
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) override final{};
virtual void visit (TuplePattern &pattern) override final{};
virtual void visit (GroupedPattern &pattern) override final{};
virtual void visit (SlicePatternItemsNoRest &items) override final{};
@@ -262,4 +261,4 @@ private:
} // namespace AST
} // namespace Rust
-#endif // DERIVE_VISITOR_H
+#endif // DERIVE_VISITOR_H \ No newline at end of file
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index 8f6e7fa..4593cc3 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -18,6 +18,7 @@
#include "rust-expand-visitor.h"
#include "rust-ast-fragment.h"
+#include "rust-item.h"
#include "rust-proc-macro.h"
#include "rust-attributes.h"
#include "rust-ast.h"
@@ -62,7 +63,7 @@ derive_item (AST::Item &item, AST::SimplePath &to_derive,
{
switch (node.get_kind ())
{
- case AST::SingleASTNode::ITEM:
+ case AST::SingleASTNode::Kind::Item:
result.push_back (node.take_item ());
break;
default:
@@ -85,7 +86,7 @@ expand_item_attribute (AST::Item &item, AST::SimplePath &name,
{
switch (node.get_kind ())
{
- case AST::SingleASTNode::ITEM:
+ case AST::SingleASTNode::Kind::Item:
result.push_back (node.take_item ());
break;
default:
@@ -114,7 +115,7 @@ expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
{
switch (node.get_kind ())
{
- case AST::SingleASTNode::STMT:
+ case AST::SingleASTNode::Kind::Stmt:
result.push_back (node.take_stmt ());
break;
default:
@@ -329,10 +330,15 @@ ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
void
ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
{
+ NodeId old_expect = expr->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
+
expander.push_context (MacroExpander::ContextType::EXPR);
expr->accept_vis (*this);
expander.pop_context ();
+ std::swap (macro_invoc_expect_id, old_expect);
+
auto final_fragment = expander.take_expanded_fragment ();
if (final_fragment.should_expand ()
&& final_fragment.is_expression_fragment ())
@@ -342,14 +348,54 @@ ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
void
ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
{
- expander.push_context (MacroExpander::ContextType::TYPE);
+ NodeId old_expect = type->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
+ expander.push_context (MacroExpander::ContextType::TYPE);
type->accept_vis (*this);
+ expander.pop_context ();
+
+ std::swap (macro_invoc_expect_id, old_expect);
+
auto final_fragment = expander.take_expanded_fragment ();
if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
type = final_fragment.take_type_fragment ();
+}
+
+// HACK: maybe we shouldn't have TypeNoBounds as a base class
+void
+ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type)
+{
+ NodeId old_expect = type->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
+ expander.push_context (MacroExpander::ContextType::TYPE);
+ type->accept_vis (*this);
expander.pop_context ();
+
+ std::swap (macro_invoc_expect_id, old_expect);
+
+ auto final_fragment = expander.take_expanded_fragment ();
+ if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
+ type = std::make_unique<AST::ParenthesisedType> (
+ final_fragment.take_type_fragment (), BUILTINS_LOCATION);
+}
+
+void
+ExpandVisitor::maybe_expand_pattern (std::unique_ptr<AST::Pattern> &pattern)
+{
+ NodeId old_expect = pattern->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
+
+ expander.push_context (MacroExpander::ContextType::PATTERN);
+ pattern->accept_vis (*this);
+ expander.pop_context ();
+
+ std::swap (macro_invoc_expect_id, old_expect);
+
+ auto final_fragment = expander.take_expanded_fragment ();
+ if (final_fragment.should_expand () && final_fragment.is_pattern_fragment ())
+ pattern = final_fragment.take_pattern_fragment ();
}
// FIXME: Can this be refactored into a `scoped` method? Which takes a
@@ -424,6 +470,8 @@ ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> &params)
{
for (auto &param : params)
{
+ maybe_expand_pattern (param.get_pattern_ptr ());
+
if (param.has_type_given ())
maybe_expand_type (param.get_type_ptr ());
}
@@ -465,6 +513,14 @@ ExpandVisitor::visit (AST::ConstGenericParam &)
void
ExpandVisitor::visit (AST::MacroInvocation &macro_invoc)
{
+ if (macro_invoc_expect_id != macro_invoc.get_node_id ())
+ {
+ rust_internal_error_at (
+ macro_invoc.get_locus (),
+ "attempting to expand node with id %d into position with node id %d",
+ (int) macro_invoc.get_node_id (), (int) macro_invoc_expect_id);
+ }
+
// TODO: Can we do the AST fragment replacing here? Probably not, right?
expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
? AST::InvocKind::Semicoloned
@@ -542,12 +598,6 @@ ExpandVisitor::visit (AST::MetaItemPathExpr &)
{}
void
-ExpandVisitor::visit (AST::ErrorPropagationExpr &expr)
-{
- visit (expr.get_propagating_expr ());
-}
-
-void
ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
{
maybe_expand_expr (expr.get_left_expr_ptr ());
@@ -569,6 +619,13 @@ ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
}
void
+ExpandVisitor::visit (AST::TypeCastExpr &expr)
+{
+ maybe_expand_expr (expr.get_casted_expr_ptr ());
+ maybe_expand_type (expr.get_type_to_cast_to_ptr ());
+}
+
+void
ExpandVisitor::visit (AST::AssignmentExpr &expr)
{
maybe_expand_expr (expr.get_left_expr_ptr ());
@@ -602,20 +659,11 @@ ExpandVisitor::visit (AST::CallExpr &expr)
}
void
-ExpandVisitor::visit (AST::MethodCallExpr &expr)
-{
- visit (expr.get_receiver_expr ());
-
- for (auto &param : expr.get_params ())
- maybe_expand_expr (param);
-}
-
-void
ExpandVisitor::visit (AST::ClosureExprInner &expr)
{
expand_closure_params (expr.get_params ());
- visit (expr.get_definition_expr ());
+ maybe_expand_expr (expr.get_definition_expr_ptr ());
}
void
@@ -677,22 +725,10 @@ ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
}
void
-ExpandVisitor::visit (AST::MatchExpr &expr)
+ExpandVisitor::visit (AST::TupleExpr &expr)
{
- visit (expr.get_scrutinee_expr ());
-
- for (auto &match_case : expr.get_match_cases ())
- {
- auto &arm = match_case.get_arm ();
-
- for (auto &pattern : arm.get_patterns ())
- visit (pattern);
-
- if (arm.has_match_arm_guard ())
- maybe_expand_expr (arm.get_guard_expr_ptr ());
-
- maybe_expand_expr (match_case.get_expr_ptr ());
- }
+ for (auto &sub : expr.get_tuple_elems ())
+ maybe_expand_expr (sub);
}
void
@@ -838,15 +874,6 @@ ExpandVisitor::visit (AST::StaticItem &static_item)
}
void
-ExpandVisitor::visit (AST::TraitItemConst &const_item)
-{
- maybe_expand_type (const_item.get_type_ptr ());
-
- if (const_item.has_expr ())
- maybe_expand_expr (const_item.get_expr_ptr ());
-}
-
-void
ExpandVisitor::visit (AST::Trait &trait)
{
for (auto &generic : trait.get_generic_params ())
@@ -970,13 +997,70 @@ ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
void
ExpandVisitor::visit (AST::GroupedPattern &pattern)
{
- visit (pattern.get_pattern_in_parens ());
+ maybe_expand_pattern (pattern.get_pattern_in_parens_ptr ());
+}
+
+void
+ExpandVisitor::visit (AST::SlicePatternItemsNoRest &items)
+{
+ for (auto &sub : items.get_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::SlicePatternItemsHasRest &items)
+{
+ for (auto &sub : items.get_lower_patterns ())
+ maybe_expand_pattern (sub);
+ for (auto &sub : items.get_upper_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::AltPattern &pattern)
+{
+ for (auto &alt : pattern.get_alts ())
+ maybe_expand_pattern (alt);
+}
+
+void
+ExpandVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
+{
+ for (auto &sub : tuple_items.get_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
+{
+ for (auto &sub : tuple_items.get_lower_patterns ())
+ maybe_expand_pattern (sub);
+
+ for (auto &sub : tuple_items.get_upper_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
+{
+ for (auto &sub : tuple_items.get_patterns ())
+ maybe_expand_pattern (sub);
+}
+
+void
+ExpandVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items)
+{
+ for (auto &sub : tuple_items.get_lower_patterns ())
+ maybe_expand_pattern (sub);
+
+ for (auto &sub : tuple_items.get_upper_patterns ())
+ maybe_expand_pattern (sub);
}
void
ExpandVisitor::visit (AST::LetStmt &stmt)
{
- visit (stmt.get_pattern ());
+ maybe_expand_pattern (stmt.get_pattern_ptr ());
if (stmt.has_type ())
maybe_expand_type (stmt.get_type_ptr ());
@@ -1006,10 +1090,18 @@ ExpandVisitor::visit (AST::BareFunctionType &type)
void
ExpandVisitor::visit (AST::FunctionParam &param)
{
+ maybe_expand_pattern (param.get_pattern_ptr ());
maybe_expand_type (param.get_type_ptr ());
}
void
+ExpandVisitor::visit (AST::VariadicParam &param)
+{
+ if (param.has_pattern ())
+ maybe_expand_pattern (param.get_pattern_ptr ());
+}
+
+void
ExpandVisitor::visit (AST::SelfParam &param)
{
/* TODO: maybe check for invariants being violated - e.g. both type and
diff --git a/gcc/rust/expand/rust-expand-visitor.h b/gcc/rust/expand/rust-expand-visitor.h
index 845e10c..b79eb66 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -19,7 +19,9 @@
#ifndef RUST_EXPAND_VISITOR_H
#define RUST_EXPAND_VISITOR_H
+#include "rust-ast-pointer-visitor.h"
#include "rust-ast-visitor.h"
+#include "rust-item.h"
#include "rust-macro-expand.h"
#include "rust-proc-macro.h"
@@ -35,27 +37,48 @@ bool is_derive (AST::Attribute &attr);
*/
bool is_builtin (AST::Attribute &attr);
-class ExpandVisitor : public AST::DefaultASTVisitor
+class ExpandVisitor : public AST::PointerVisitor
{
public:
- ExpandVisitor (MacroExpander &expander) : expander (expander) {}
+ ExpandVisitor (MacroExpander &expander)
+ : expander (expander), macro_invoc_expect_id (UNKNOWN_NODEID)
+ {}
/* Expand all of the macro invocations currently contained in a crate */
void go (AST::Crate &crate);
- using AST::DefaultASTVisitor::visit;
+ using AST::PointerVisitor::reseat;
+ using AST::PointerVisitor::visit;
- /*
- Maybe expand a macro invocation in lieu of an expression
- expr : Core guidelines R33, this function reseat the pointer.
- */
- void maybe_expand_expr (std::unique_ptr<AST::Expr> &expr);
+ void reseat (std::unique_ptr<AST::Expr> &ptr) override
+ {
+ maybe_expand_expr (ptr);
+ }
- /*
- Maybe expand a macro invocation in lieu of a type
- type : Core guidelines R33, this function reseat the pointer.
+ void reseat (std::unique_ptr<AST::Type> &ptr) override
+ {
+ maybe_expand_type (ptr);
+ }
+
+ void reseat (std::unique_ptr<AST::TypeNoBounds> &ptr) override
+ {
+ maybe_expand_type (ptr);
+ }
+
+ void reseat (std::unique_ptr<AST::Pattern> &ptr) override
+ {
+ maybe_expand_pattern (ptr);
+ }
+
+ /**
+ * Maybe expand a macro invocation in lieu of an expression, type or pattern.
+ *
+ * @ptr Core guidelines R33, this function reseats the pointer.
*/
- void maybe_expand_type (std::unique_ptr<AST::Type> &type);
+ void maybe_expand_expr (std::unique_ptr<AST::Expr> &ptr);
+ void maybe_expand_type (std::unique_ptr<AST::Type> &ptr);
+ void maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type);
+ void maybe_expand_pattern (std::unique_ptr<AST::Pattern> &ptr);
/**
* Expand all macro invocations in lieu of types within a vector of struct
@@ -128,7 +151,10 @@ public:
auto &value = *it;
// Perform expansion
+ NodeId old_expect = value->get_node_id ();
+ std::swap (macro_invoc_expect_id, old_expect);
value->accept_vis (*this);
+ std::swap (macro_invoc_expect_id, old_expect);
auto final_fragment = expander.take_expanded_fragment ();
@@ -210,17 +236,16 @@ public:
void visit (AST::AttrInputMacro &) override;
void visit (AST::MetaItemLitExpr &) override;
void visit (AST::MetaItemPathExpr &) override;
- void visit (AST::ErrorPropagationExpr &expr) override;
void visit (AST::ArithmeticOrLogicalExpr &expr) override;
void visit (AST::ComparisonExpr &expr) override;
void visit (AST::LazyBooleanExpr &expr) override;
+ void visit (AST::TypeCastExpr &expr) override;
void visit (AST::AssignmentExpr &expr) override;
void visit (AST::CompoundAssignmentExpr &expr) override;
void visit (AST::GroupedExpr &expr) override;
void visit (AST::StructExprStruct &expr) override;
void visit (AST::CallExpr &expr) override;
- void visit (AST::MethodCallExpr &expr) override;
void visit (AST::ClosureExprInner &expr) override;
void visit (AST::BlockExpr &expr) override;
@@ -231,7 +256,7 @@ public:
void visit (AST::IfExprConseqElse &expr) override;
void visit (AST::IfLetExpr &expr) override;
void visit (AST::IfLetExprConseqElse &expr) override;
- void visit (AST::MatchExpr &expr) override;
+ void visit (AST::TupleExpr &expr) override;
void visit (AST::TypeParam &param) override;
void visit (AST::LifetimeWhereClauseItem &) override;
void visit (AST::TypeBoundWhereClauseItem &item) override;
@@ -251,7 +276,6 @@ public:
void visit (AST::Union &union_item) override;
void visit (AST::ConstantItem &const_item) override;
void visit (AST::StaticItem &static_item) override;
- void visit (AST::TraitItemConst &item) override;
void visit (AST::Trait &trait) override;
void visit (AST::InherentImpl &impl) override;
void visit (AST::TraitImpl &impl) override;
@@ -269,12 +293,20 @@ public:
void visit (AST::MetaListNameValueStr &) override;
void visit (AST::StructPatternFieldIdent &field) override;
void visit (AST::GroupedPattern &pattern) override;
+ void visit (AST::SlicePatternItemsNoRest &items) override;
+ void visit (AST::SlicePatternItemsHasRest &items) override;
+ void visit (AST::AltPattern &pattern) override;
+ void visit (AST::TupleStructItemsNoRest &tuple_items) override;
+ void visit (AST::TupleStructItemsHasRest &tuple_items) override;
+ void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
+ void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
void visit (AST::LetStmt &stmt) override;
void visit (AST::ExprStmt &stmt) override;
void visit (AST::BareFunctionType &type) override;
- void visit (AST::FunctionParam &type) override;
+ void visit (AST::FunctionParam &param) override;
+ void visit (AST::VariadicParam &param) override;
void visit (AST::SelfParam &type) override;
template <typename T>
@@ -287,6 +319,7 @@ public:
private:
MacroExpander &expander;
+ NodeId macro_invoc_expect_id;
};
} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 61222db..c991ca7 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -101,7 +101,7 @@ parse_clobber_abi (InlineAsmContext inline_asm_ctx)
if (token->get_id () == STRING_LITERAL)
{
// TODO: Caring for span in here.
- new_abis.push_back ({token->as_string (), token->get_locus ()});
+ new_abis.emplace_back (token->as_string (), token->get_locus ());
}
else
{
@@ -787,12 +787,12 @@ expand_inline_asm_strings (InlineAsmContext inline_asm_ctx)
auto pieces = Fmt::Pieces::collect (template_str.symbol, false,
Fmt::ffi::ParseMode::InlineAsm);
- auto pieces_vec = pieces.get_pieces ();
+ auto &pieces_vec = pieces.get_pieces ();
std::string transformed_template_str = "";
for (size_t i = 0; i < pieces_vec.size (); i++)
{
- auto piece = pieces_vec[i];
+ auto &piece = pieces_vec[i];
if (piece.tag == Fmt::ffi::Piece::Tag::String)
{
transformed_template_str += piece.string._0.to_string ();
@@ -880,7 +880,8 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
// context.
if (resulting_context)
{
- auto node = (*resulting_context).inline_asm.clone_expr_without_block ();
+ auto resulting_ctx = resulting_context.value ();
+ auto node = resulting_ctx.inline_asm.clone_expr_without_block ();
std::vector<AST::SingleASTNode> single_vec = {};
@@ -1124,8 +1125,11 @@ parse_llvm_clobbers (LlvmAsmContext &ctx)
{
ctx.llvm_asm.get_clobbers ().push_back (
{strip_double_quotes (token->as_string ()), token->get_locus ()});
+
+ parser.skip_token (STRING_LITERAL);
}
- parser.skip_token (STRING_LITERAL);
+
+ parser.maybe_skip_token (COMMA);
token = parser.peek_current_token ();
}
}
@@ -1177,12 +1181,13 @@ parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
auto asm_ctx = LlvmAsmContext (llvm_asm, parser, last_token_id);
- auto resulting_context
+ tl::optional<LlvmAsmContext> 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 ();
+ auto resulting_ctx = resulting_context.value ();
+ auto node = resulting_ctx.llvm_asm.clone_expr_without_block ();
std::vector<AST::SingleASTNode> single_vec = {};
@@ -1190,12 +1195,13 @@ parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
// 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)));
+ {
+ single_vec.emplace_back (
+ std::make_unique<AST::ExprStmt> (std::move (node), invoc_locus,
+ true /* has semicolon */));
+ }
else
- single_vec.emplace_back (AST::SingleASTNode (std::move (node)));
+ single_vec.emplace_back (std::move (node));
AST::Fragment fragment_ast
= AST::Fragment (single_vec,
diff --git a/gcc/rust/expand/rust-macro-builtins-format-args.cc b/gcc/rust/expand/rust-macro-builtins-format-args.cc
index b20c849..eb2a1cc 100644
--- a/gcc/rust/expand/rust-macro-builtins-format-args.cc
+++ b/gcc/rust/expand/rust-macro-builtins-format-args.cc
@@ -37,39 +37,42 @@ struct FormatArgsParseError
} kind;
};
-static tl::expected<FormatArgsInput, FormatArgsParseError>
-format_args_parse_arguments (AST::MacroInvocData &invoc)
+static inline tl::expected<std::string, AST::Fragment>
+format_args_parse_expr (location_t invoc_locus, AST::MacroInvocData &invoc,
+ Parser<MacroInvocLexer> &parser,
+ BuiltinMacro macro_kind)
{
- MacroInvocLexer lex (invoc.get_delim_tok_tree ().to_token_stream ());
- Parser<MacroInvocLexer> parser (lex);
-
- // TODO: check if EOF - return that format_args!() requires at least one
- // argument
-
- auto args = AST::FormatArguments ();
- auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
- std::unique_ptr<AST::Expr> format_expr = nullptr;
+ std::unique_ptr<AST::Expr> format_expr = parser.parse_expr ();
+ rust_assert (format_expr);
- // TODO: Handle the case where we're not parsing a string literal (macro
- // invocation for e.g.)
- switch (parser.peek_current_token ()->get_id ())
+ if (format_expr->get_expr_kind () == AST::Expr::Kind::MacroInvocation)
{
- case STRING_LITERAL:
- case RAW_STRING_LITERAL:
- format_expr = parser.parse_literal_expr ();
- default:
- // do nothing
- ;
+ std::vector<std::unique_ptr<AST::MacroInvocation>> pending;
+ pending.emplace_back (
+ static_cast<AST::MacroInvocation *> (format_expr.release ()));
+ return tl::unexpected<AST::Fragment> (
+ make_eager_builtin_invocation (macro_kind, invoc_locus,
+ invoc.get_delim_tok_tree (),
+ std::move (pending)));
}
- 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)
- .get_literal ()
- .as_string ();
+ rust_assert (format_expr->is_literal ());
+ return static_cast<AST::LiteralExpr &> (*format_expr)
+ .get_literal ()
+ .as_string ();
+}
+
+static inline tl::expected<AST::FormatArguments, FormatArgsParseError>
+format_args_parse_arguments (AST::MacroInvocData &invoc,
+ Parser<MacroInvocLexer> &parser,
+ TokenId last_token_id)
+{
+ // TODO: check if EOF - return that format_args!() requires at least one
+ // argument
+ auto args = AST::FormatArguments ();
// TODO: Allow implicit captures ONLY if the the first arg is a string literal
// and not a macro invocation
@@ -126,7 +129,7 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
// we need to skip commas, don't we?
}
- return FormatArgsInput{std::move (format_str), std::move (args)};
+ return args;
}
tl::optional<AST::Fragment>
@@ -135,9 +138,24 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
AST::InvocKind semicolon,
AST::FormatArgs::Newline nl)
{
- auto input = format_args_parse_arguments (invoc);
+ 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);
+
+ auto format_str = format_args_parse_expr (invoc_locus, invoc, parser,
+ nl == AST::FormatArgs::Newline::Yes
+ ? BuiltinMacro::FormatArgsNl
+ : BuiltinMacro::FormatArgs);
+
+ if (!format_str)
+ {
+ return std::move (format_str.error ());
+ }
+
+ auto args = format_args_parse_arguments (invoc, parser, last_token_id);
- if (!input)
+ if (!args)
{
rust_error_at (invoc_locus,
"could not parse arguments to %<format_args!()%>");
@@ -173,7 +191,7 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
bool append_newline = nl == AST::FormatArgs::Newline::Yes;
- auto fmt_str = std::move (input->format_str);
+ auto fmt_str = std::move (format_str.value ());
if (append_newline)
fmt_str += '\n';
@@ -189,7 +207,7 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
// for creating the `template`
auto fmt_args_node = AST::FormatArgs (invoc_locus, std::move (pieces),
- std::move (input->args));
+ std::move (args.value ()));
auto expanded
= Fmt::expand_format_args (fmt_args_node,
diff --git a/gcc/rust/expand/rust-macro-builtins-helpers.h b/gcc/rust/expand/rust-macro-builtins-helpers.h
index 32cf58f..ce63017 100644
--- a/gcc/rust/expand/rust-macro-builtins-helpers.h
+++ b/gcc/rust/expand/rust-macro-builtins-helpers.h
@@ -22,7 +22,6 @@
#include "rust-ast.h"
#include "rust-cfg-strip.h"
#include "rust-diagnostics.h"
-#include "rust-early-name-resolver.h"
#include "rust-expr.h"
#include "rust-lex.h"
#include "rust-macro-builtins.h"
diff --git a/gcc/rust/expand/rust-macro-builtins-offset-of.cc b/gcc/rust/expand/rust-macro-builtins-offset-of.cc
index 53efe74..02c637b 100644
--- a/gcc/rust/expand/rust-macro-builtins-offset-of.cc
+++ b/gcc/rust/expand/rust-macro-builtins-offset-of.cc
@@ -56,7 +56,7 @@ MacroBuiltin::offset_of_handler (location_t invoc_locus,
parser.skip_token (COMMA);
auto field_tok = parser.parse_identifier_or_keyword_token ();
- auto invalid_field = !field_tok || !field_tok->has_str ();
+ auto invalid_field = !field_tok || !field_tok->should_have_str ();
if (invalid_field)
rust_error_at (invoc_locus, "could not parse field argument for %qs",
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index a7ae220..948f389 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -29,7 +29,6 @@
#include "rust-ast.h"
#include "rust-cfg-strip.h"
#include "rust-diagnostics.h"
-#include "rust-early-name-resolver.h"
#include "rust-expr.h"
#include "rust-lex.h"
#include "rust-macro-invoc-lexer.h"
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 4c54cef..52f8e2b 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -27,7 +27,6 @@
#include "rust-macro.h"
#include "rust-parse.h"
#include "rust-cfg-strip.h"
-#include "rust-early-name-resolver.h"
#include "rust-proc-macro.h"
#include "rust-token-tree-desugar.h"
@@ -961,9 +960,14 @@ transcribe_expression (Parser<MacroInvocLexer> &parser)
auto &lexer = parser.get_token_source ();
auto start = lexer.get_offs ();
- auto expr = parser.parse_expr ();
+ auto attrs = parser.parse_outer_attributes ();
+ auto expr = parser.parse_expr (std::move (attrs));
if (expr == nullptr)
- return AST::Fragment::create_error ();
+ {
+ for (auto error : parser.get_errors ())
+ error.emit ();
+ return AST::Fragment::create_error ();
+ }
// FIXME: make this an error for some edititons
if (parser.peek_current_token ()->get_id () == SEMICOLON)
@@ -999,6 +1003,27 @@ transcribe_type (Parser<MacroInvocLexer> &parser)
return AST::Fragment ({std::move (type)}, lexer.get_token_slice (start, end));
}
+/**
+ * Transcribe one pattern from a macro invocation
+ *
+ * @param parser Parser to extract statements from
+ */
+static AST::Fragment
+transcribe_pattern (Parser<MacroInvocLexer> &parser)
+{
+ auto &lexer = parser.get_token_source ();
+ auto start = lexer.get_offs ();
+
+ auto pattern = parser.parse_pattern ();
+ for (auto err : parser.get_errors ())
+ err.emit ();
+
+ auto end = lexer.get_offs ();
+
+ return AST::Fragment ({std::move (pattern)},
+ lexer.get_token_slice (start, end));
+}
+
static AST::Fragment
transcribe_context (MacroExpander::ContextType ctx,
Parser<MacroInvocLexer> &parser, bool semicolon,
@@ -1011,6 +1036,7 @@ transcribe_context (MacroExpander::ContextType ctx,
// -- Trait --> parser.parse_trait_item();
// -- Impl --> parser.parse_impl_item();
// -- Extern --> parser.parse_extern_item();
+ // -- Pattern --> parser.parse_pattern();
// -- None --> [has semicolon?]
// -- Yes --> parser.parse_stmt();
// -- No --> [switch invocation.delimiter()]
@@ -1039,6 +1065,8 @@ transcribe_context (MacroExpander::ContextType ctx,
break;
case MacroExpander::ContextType::TYPE:
return transcribe_type (parser);
+ case MacroExpander::ContextType::PATTERN:
+ return transcribe_pattern (parser);
break;
case MacroExpander::ContextType::STMT:
return transcribe_many_stmts (parser, last_token_id, semicolon);
@@ -1080,8 +1108,9 @@ 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, definition);
+ auto substitute_context
+ = SubstituteCtx (invoc_stream, macro_rule_tokens, matched_fragments,
+ definition, invoc_token_tree.get_locus ());
std::vector<std::unique_ptr<AST::Token>> substituted_tokens
= substitute_context.substitute_tokens ();
@@ -1128,11 +1157,7 @@ MacroExpander::transcribe_rule (
// emit any errors
if (parser.has_errors ())
- {
- for (auto &err : parser.get_errors ())
- rust_error_at (err.locus, "%s", err.message.c_str ());
- return AST::Fragment::create_error ();
- }
+ return AST::Fragment::create_error ();
// are all the tokens used?
bool did_delimit = parser.skip_token (last_token_id);
@@ -1165,7 +1190,7 @@ MacroExpander::parse_proc_macro_output (ProcMacro::TokenStream ts)
auto result = parser.parse_item (false);
if (result == nullptr)
break;
- nodes.push_back ({std::move (result)});
+ nodes.emplace_back (std::move (result));
}
break;
case ContextType::STMT:
@@ -1174,7 +1199,7 @@ MacroExpander::parse_proc_macro_output (ProcMacro::TokenStream ts)
auto result = parser.parse_stmt ();
if (result == nullptr)
break;
- nodes.push_back ({std::move (result)});
+ nodes.emplace_back (std::move (result));
}
break;
case ContextType::TRAIT:
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index 360294c..c3d5e7d 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -27,7 +27,6 @@
#include "rust-ast.h"
#include "rust-macro.h"
#include "rust-hir-map.h"
-#include "rust-early-name-resolver.h"
#include "rust-name-resolver.h"
#include "rust-macro-invoc-lexer.h"
#include "rust-proc-macro-invoc-lexer.h"
@@ -291,6 +290,7 @@ struct MacroExpander
TRAIT,
IMPL,
TRAIT_IMPL,
+ PATTERN,
};
ExpansionCfg cfg;
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc
index ac36ed8..36bae5b 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.cc
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc
@@ -40,7 +40,7 @@ SubstituteCtx::substitute_dollar_crate (
if (*def_crate == current_crate)
{
expanded.push_back (std::make_unique<AST::Token> (
- Rust::Token::make_identifier (UNKNOWN_LOCATION, "crate")));
+ Rust::Token::make_identifier (origin, "crate")));
}
else
{
@@ -49,9 +49,9 @@ SubstituteCtx::substitute_dollar_crate (
rust_assert (name);
expanded.push_back (std::make_unique<AST::Token> (
- Rust::Token::make (SCOPE_RESOLUTION, UNKNOWN_LOCATION)));
+ Rust::Token::make (SCOPE_RESOLUTION, origin)));
expanded.push_back (std::make_unique<AST::Token> (
- Rust::Token::make_identifier (UNKNOWN_LOCATION, std::string (*name))));
+ Rust::Token::make_identifier (origin, std::string (*name))));
}
return true;
@@ -108,6 +108,12 @@ SubstituteCtx::substitute_metavar (
return true;
}
+static bool
+is_builtin_metavariable (AST::Token &token)
+{
+ return token.get_id () == CRATE;
+}
+
bool
SubstituteCtx::check_repetition_amount (size_t pattern_start,
size_t pattern_end,
@@ -125,6 +131,10 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
|| frag_token->get_id () == IDENTIFIER)
{
auto it = fragments.find (frag_token->get_str ());
+
+ if (is_builtin_metavariable (*frag_token))
+ continue;
+
if (it == fragments.end ())
{
// If the repetition is not anything we know (ie no declared
@@ -136,6 +146,7 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
frag_token->get_str ().c_str ());
is_valid = false;
+ continue;
}
auto &fragment = *it->second;
@@ -226,7 +237,7 @@ SubstituteCtx::substitute_repetition (
}
auto substitute_context
- = SubstituteCtx (input, new_macro, sub_map, definition);
+ = SubstituteCtx (input, new_macro, sub_map, definition, origin);
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 c5c4956..3829a5a 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.h
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.h
@@ -27,6 +27,8 @@ class SubstituteCtx
std::vector<std::unique_ptr<AST::Token>> &macro;
std::map<std::string, MatchedFragmentContainer *> &fragments;
AST::MacroRulesDefinition &definition;
+ // Macro invocation location
+ location_t origin;
/**
* Find the repetition amount to use when expanding a repetition, and
@@ -43,9 +45,9 @@ public:
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)
+ AST::MacroRulesDefinition &definition, location_t origin)
: input (input), macro (macro), fragments (fragments),
- definition (definition)
+ definition (definition), origin (origin)
{}
/**
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index b723f59..1c8e5b6 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -372,9 +372,6 @@ void
ASTLoweringBase::visit (AST::StaticItem &)
{}
void
-ASTLoweringBase::visit (AST::TraitItemConst &)
-{}
-void
ASTLoweringBase::visit (AST::TraitItemType &)
{}
void
@@ -473,20 +470,20 @@ ASTLoweringBase::visit (AST::StructPattern &)
{}
// void ASTLoweringBase::visit(TupleStructItemstuple_items) {}
void
-ASTLoweringBase::visit (AST::TupleStructItemsNoRange &)
+ASTLoweringBase::visit (AST::TupleStructItemsNoRest &)
{}
void
-ASTLoweringBase::visit (AST::TupleStructItemsRange &)
+ASTLoweringBase::visit (AST::TupleStructItemsHasRest &)
{}
void
ASTLoweringBase::visit (AST::TupleStructPattern &)
{}
// void ASTLoweringBase::visit(TuplePatternItemstuple_items) {}
void
-ASTLoweringBase::visit (AST::TuplePatternItemsMultiple &)
+ASTLoweringBase::visit (AST::TuplePatternItemsNoRest &)
{}
void
-ASTLoweringBase::visit (AST::TuplePatternItemsRanged &)
+ASTLoweringBase::visit (AST::TuplePatternItemsHasRest &)
{}
void
ASTLoweringBase::visit (AST::TuplePattern &)
@@ -622,11 +619,10 @@ ASTLoweringBase::lower_generic_params (
std::vector<std::unique_ptr<AST::GenericParam>> &params)
{
std::vector<std::unique_ptr<HIR::GenericParam>> lowered;
+ lowered.reserve (params.size ());
+
for (auto &ast_param : params)
- {
- auto hir_param = ASTLowerGenericParam::translate (*ast_param);
- lowered.push_back (std::unique_ptr<HIR::GenericParam> (hir_param));
- }
+ lowered.emplace_back (ASTLowerGenericParam::translate (*ast_param));
return lowered;
}
@@ -659,18 +655,16 @@ HIR::GenericArgs
ASTLoweringBase::lower_generic_args (AST::GenericArgs &args)
{
std::vector<HIR::GenericArgsBinding> binding_args;
+ binding_args.reserve (args.get_binding_args ().size ());
+
for (auto &binding : args.get_binding_args ())
- {
- HIR::GenericArgsBinding b = lower_binding (binding);
- binding_args.push_back (std::move (b));
- }
+ binding_args.emplace_back (lower_binding (binding));
std::vector<HIR::Lifetime> lifetime_args;
+ lifetime_args.reserve (args.get_lifetime_args ().size ());
+
for (auto &lifetime : args.get_lifetime_args ())
- {
- HIR::Lifetime l = lower_lifetime (lifetime);
- lifetime_args.push_back (std::move (l));
- }
+ lifetime_args.emplace_back (lower_lifetime (lifetime));
std::vector<std::unique_ptr<HIR::Type>> type_args;
std::vector<HIR::ConstGenericArg> const_args;
@@ -681,16 +675,15 @@ ASTLoweringBase::lower_generic_args (AST::GenericArgs &args)
{
case AST::GenericArg::Kind::Type:
{
- auto type = ASTLoweringType::translate (arg.get_type ());
- type_args.emplace_back (std::unique_ptr<HIR::Type> (type));
+ type_args.emplace_back (
+ ASTLoweringType::translate (arg.get_type ()));
break;
}
case AST::GenericArg::Kind::Const:
{
auto expr = ASTLoweringExpr::translate (arg.get_expression ());
- const_args.emplace_back (
- HIR::ConstGenericArg (std::unique_ptr<HIR::Expr> (expr),
- expr->get_locus ()));
+ const_args.emplace_back (std::unique_ptr<HIR::Expr> (expr),
+ expr->get_locus ());
break;
}
default:
@@ -850,9 +843,10 @@ void
ASTLoweringBase::handle_lang_item_attribute (const ItemWrapper &item,
const AST::Attribute &attr)
{
- auto &literal = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
- const auto &lang_item_type_str = literal.get_literal ().as_string ();
- auto lang_item_type = LangItem::Parse (lang_item_type_str);
+ auto lang_item_type_str = Analysis::Attributes::extract_string_literal (attr);
+ rust_assert (lang_item_type_str.has_value ());
+
+ auto lang_item_type = LangItem::Parse (*lang_item_type_str);
if (lang_item_type)
mappings.insert_lang_item (*lang_item_type,
@@ -877,41 +871,71 @@ ASTLoweringBase::attribute_handled_in_another_pass (
std::unique_ptr<HIR::TuplePatternItems>
ASTLoweringBase::lower_tuple_pattern_multiple (
- AST::TuplePatternItemsMultiple &pattern)
+ AST::TuplePatternItemsNoRest &pattern)
{
std::vector<std::unique_ptr<HIR::Pattern>> patterns;
+ patterns.reserve (pattern.get_patterns ().size ());
+
for (auto &p : pattern.get_patterns ())
- {
- HIR::Pattern *translated = ASTLoweringPattern::translate (*p);
- patterns.push_back (std::unique_ptr<HIR::Pattern> (translated));
- }
+ patterns.emplace_back (ASTLoweringPattern::translate (*p));
return std::unique_ptr<HIR::TuplePatternItems> (
- new HIR::TuplePatternItemsMultiple (std::move (patterns)));
+ new HIR::TuplePatternItemsNoRest (std::move (patterns)));
}
std::unique_ptr<TuplePatternItems>
ASTLoweringBase::lower_tuple_pattern_ranged (
- AST::TuplePatternItemsRanged &pattern)
+ AST::TuplePatternItemsHasRest &pattern)
{
std::vector<std::unique_ptr<HIR::Pattern>> lower_patterns;
+ lower_patterns.reserve (pattern.get_lower_patterns ().size ());
std::vector<std::unique_ptr<HIR::Pattern>> upper_patterns;
+ upper_patterns.reserve (pattern.get_upper_patterns ().size ());
for (auto &p : pattern.get_lower_patterns ())
- {
- HIR::Pattern *translated = ASTLoweringPattern::translate (*p);
- lower_patterns.push_back (std::unique_ptr<HIR::Pattern> (translated));
- }
+ lower_patterns.emplace_back (ASTLoweringPattern::translate (*p));
for (auto &p : pattern.get_upper_patterns ())
- {
- HIR::Pattern *translated = ASTLoweringPattern::translate (*p);
- upper_patterns.push_back (std::unique_ptr<HIR::Pattern> (translated));
- }
+ upper_patterns.emplace_back (ASTLoweringPattern::translate (*p));
return std::unique_ptr<HIR::TuplePatternItems> (
- new HIR::TuplePatternItemsRanged (std::move (lower_patterns),
- std::move (upper_patterns)));
+ new HIR::TuplePatternItemsHasRest (std::move (lower_patterns),
+ std::move (upper_patterns)));
+}
+
+std::unique_ptr<HIR::SlicePatternItems>
+ASTLoweringBase::lower_slice_pattern_no_rest (
+ AST::SlicePatternItemsNoRest &pattern)
+{
+ std::vector<std::unique_ptr<HIR::Pattern>> patterns;
+ patterns.reserve (pattern.get_patterns ().size ());
+ for (auto &p : pattern.get_patterns ())
+ patterns.emplace_back (ASTLoweringPattern::translate (*p));
+
+ return std::unique_ptr<HIR::SlicePatternItems> (
+ new HIR::SlicePatternItemsNoRest (std::move (patterns)));
+}
+
+std::unique_ptr<HIR::SlicePatternItems>
+ASTLoweringBase::lower_slice_pattern_has_rest (
+ AST::SlicePatternItemsHasRest &pattern)
+{
+ std::vector<std::unique_ptr<HIR::Pattern>> lower_patterns;
+ lower_patterns.reserve (pattern.get_lower_patterns ().size ());
+ std::vector<std::unique_ptr<HIR::Pattern>> upper_patterns;
+ upper_patterns.reserve (pattern.get_upper_patterns ().size ());
+
+ for (auto &p : pattern.get_lower_patterns ())
+ lower_patterns.emplace_back (
+ std::unique_ptr<HIR::Pattern> (ASTLoweringPattern::translate (*p)));
+
+ for (auto &p : pattern.get_upper_patterns ())
+ upper_patterns.emplace_back (
+ std::unique_ptr<HIR::Pattern> (ASTLoweringPattern::translate (*p)));
+
+ return std::unique_ptr<HIR::SlicePatternItems> (
+ new HIR::SlicePatternItemsHasRest (std::move (lower_patterns),
+ std::move (upper_patterns)));
}
std::unique_ptr<HIR::RangePatternBound>
@@ -1008,14 +1032,15 @@ ASTLoweringBase::lower_extern_block (AST::ExternBlock &extern_block)
mappings.get_next_localdef_id (crate_num));
std::vector<std::unique_ptr<HIR::ExternalItem>> extern_items;
+ extern_items.reserve (extern_block.get_extern_items ().size ());
+
for (auto &item : extern_block.get_extern_items ())
{
if (item->is_marked_for_strip ())
continue;
- HIR::ExternalItem *lowered
- = ASTLoweringExternItem::translate (item.get (), mapping.get_hirid ());
- extern_items.push_back (std::unique_ptr<HIR::ExternalItem> (lowered));
+ extern_items.emplace_back (
+ ASTLoweringExternItem::translate (item.get (), mapping.get_hirid ()));
}
ABI abi = ABI::C;
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index e86aacb..933f77b 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -189,7 +189,6 @@ public:
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;
@@ -228,12 +227,12 @@ public:
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::TupleStructItemsNoRest &tuple_items) override;
+ virtual void visit (AST::TupleStructItemsHasRest &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::TuplePatternItemsNoRest &tuple_items) override;
+ virtual void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
virtual void visit (AST::TuplePattern &pattern) override;
virtual void visit (AST::GroupedPattern &pattern) override;
virtual void visit (AST::SlicePatternItemsNoRest &items) override;
@@ -317,10 +316,16 @@ protected:
attribute_handled_in_another_pass (const std::string &attribute_path) const;
std::unique_ptr<TuplePatternItems>
- lower_tuple_pattern_multiple (AST::TuplePatternItemsMultiple &pattern);
+ lower_tuple_pattern_multiple (AST::TuplePatternItemsNoRest &pattern);
std::unique_ptr<TuplePatternItems>
- lower_tuple_pattern_ranged (AST::TuplePatternItemsRanged &pattern);
+ lower_tuple_pattern_ranged (AST::TuplePatternItemsHasRest &pattern);
+
+ std::unique_ptr<SlicePatternItems>
+ lower_slice_pattern_no_rest (AST::SlicePatternItemsNoRest &pattern);
+
+ std::unique_ptr<SlicePatternItems>
+ lower_slice_pattern_has_rest (AST::SlicePatternItemsHasRest &pattern);
std::unique_ptr<HIR::RangePatternBound>
lower_range_pattern_bound (AST::RangePatternBound &bound);
diff --git a/gcc/rust/hir/rust-ast-lower-enumitem.h b/gcc/rust/hir/rust-ast-lower-enumitem.h
index 1b95345..8e28c08 100644
--- a/gcc/rust/hir/rust-ast-lower-enumitem.h
+++ b/gcc/rust/hir/rust-ast-lower-enumitem.h
@@ -80,6 +80,8 @@ public:
item.get_visibility ().as_string ().c_str ());
std::vector<HIR::TupleField> fields;
+ fields.reserve (item.get_tuple_fields ().size ());
+
for (auto &field : item.get_tuple_fields ())
{
HIR::Visibility vis = translate_visibility (field.get_visibility ());
@@ -90,11 +92,8 @@ public:
crate_num, field.get_node_id (), mappings.get_next_hir_id (crate_num),
mappings.get_next_localdef_id (crate_num));
- HIR::TupleField translated_field (field_mapping,
- std::unique_ptr<HIR::Type> (type),
- vis, field.get_locus (),
- field.get_outer_attrs ());
- fields.push_back (std::move (translated_field));
+ fields.emplace_back (field_mapping, std::unique_ptr<HIR::Type> (type),
+ vis, field.get_locus (), field.get_outer_attrs ());
}
translated
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc
index 4ed51d9..a1e24ee 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -81,11 +81,10 @@ void
ASTLoweringExpr::visit (AST::TupleExpr &expr)
{
std::vector<std::unique_ptr<HIR::Expr>> tuple_elements;
+ tuple_elements.reserve (expr.get_tuple_elems ().size ());
+
for (auto &e : expr.get_tuple_elems ())
- {
- HIR::Expr *t = ASTLoweringExpr::translate (*e);
- tuple_elements.push_back (std::unique_ptr<HIR::Expr> (t));
- }
+ tuple_elements.emplace_back (ASTLoweringExpr::translate (*e));
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
@@ -221,12 +220,12 @@ 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;
+ params.reserve (in_params.size ());
+
for (auto &param : in_params)
- {
- auto trans = ASTLoweringExpr::translate (*param);
- params.push_back (std::unique_ptr<HIR::Expr> (trans));
- }
+ params.emplace_back (ASTLoweringExpr::translate (*param));
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (
@@ -248,11 +247,10 @@ ASTLoweringExpr::visit (AST::MethodCallExpr &expr)
auto const &in_params = expr.get_params ();
std::vector<std::unique_ptr<HIR::Expr>> params;
+ params.reserve (in_params.size ());
+
for (auto &param : in_params)
- {
- auto trans = ASTLoweringExpr::translate (*param);
- params.push_back (std::unique_ptr<HIR::Expr> (trans));
- }
+ params.emplace_back (ASTLoweringExpr::translate (*param));
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
@@ -338,11 +336,10 @@ void
ASTLoweringExpr::visit (AST::ArrayElemsValues &elems)
{
std::vector<std::unique_ptr<HIR::Expr>> elements;
+ elements.reserve (elems.get_values ().size ());
+
for (auto &elem : elems.get_values ())
- {
- HIR::Expr *translated_elem = ASTLoweringExpr::translate (*elem);
- elements.push_back (std::unique_ptr<HIR::Expr> (translated_elem));
- }
+ elements.emplace_back (ASTLoweringExpr::translate (*elem));
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (mappings.get_current_crate (),
@@ -569,13 +566,12 @@ ASTLoweringExpr::visit (AST::StructExprStructFields &struct_expr)
}
auto const &in_fields = struct_expr.get_fields ();
+
std::vector<std::unique_ptr<HIR::StructExprField>> fields;
+ fields.reserve (in_fields.size ());
+
for (auto &field : in_fields)
- {
- HIR::StructExprField *translated
- = ASTLowerStructExprField::translate (*field);
- fields.push_back (std::unique_ptr<HIR::StructExprField> (translated));
- }
+ fields.emplace_back (ASTLowerStructExprField::translate (*field));
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, struct_expr.get_node_id (),
@@ -814,11 +810,10 @@ ASTLoweringExpr::visit (AST::ClosureExprInner &expr)
= ASTLoweringExpr::translate (expr.get_definition_expr ());
std::vector<HIR::ClosureParam> closure_params;
+ closure_params.reserve (expr.get_params ().size ());
+
for (auto &param : expr.get_params ())
- {
- HIR::ClosureParam p = lower_closure_param (param);
- closure_params.push_back (std::move (p));
- }
+ closure_params.emplace_back (lower_closure_param (param));
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
@@ -841,11 +836,10 @@ ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
= ASTLoweringExpr::translate (expr.get_definition_expr ());
std::vector<HIR::ClosureParam> closure_params;
+ closure_params.reserve (expr.get_params ().size ());
+
for (auto &param : expr.get_params ())
- {
- HIR::ClosureParam p = lower_closure_param (param);
- closure_params.push_back (std::move (p));
- }
+ closure_params.emplace_back (lower_closure_param (param));
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
@@ -1000,6 +994,23 @@ ASTLoweringExpr::visit (AST::InlineAsm &expr)
expr.get_options (), mapping);
}
+namespace {
+// We're not really supporting llvm_asm, only the bare minimum for libcore's
+// blackbox
+// llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
+bool
+check_llvm_asm_support (const std::vector<LlvmOperand> &inputs,
+ const std::vector<LlvmOperand> &outputs,
+ const AST::LlvmInlineAsm &expr)
+{
+ return outputs.size () == 0 && inputs.size () <= 1
+ && expr.get_clobbers ().size () <= 1
+ && expr.get_templates ().size () == 1
+ && expr.get_templates ()[0].symbol == "";
+}
+
+} // namespace
+
void
ASTLoweringExpr::visit (AST::LlvmInlineAsm &expr)
{
@@ -1009,7 +1020,10 @@ ASTLoweringExpr::visit (AST::LlvmInlineAsm &expr)
mappings.get_next_localdef_id (crate_num));
std::vector<LlvmOperand> inputs;
+ inputs.reserve (expr.get_inputs ().size ());
+
std::vector<LlvmOperand> outputs;
+ outputs.reserve (expr.get_outputs ().size ());
for (auto i : expr.get_inputs ())
{
@@ -1029,13 +1043,15 @@ ASTLoweringExpr::visit (AST::LlvmInlineAsm &expr)
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 == "");
+ if (!check_llvm_asm_support (inputs, outputs, expr))
+ {
+ rust_error_at (expr.get_locus (), "unsupported %qs construct",
+ "llvm_asm");
+ rust_inform (
+ expr.get_locus (),
+ "%<llvm_asm%> has been replaced with %<asm%>, gccrs only supports a "
+ "subset of %<llvm_asm%> to compile libcore");
+ }
translated
= new HIR::LlvmInlineAsm (expr.get_locus (), inputs, outputs,
diff --git a/gcc/rust/hir/rust-ast-lower-extern.h b/gcc/rust/hir/rust-ast-lower-extern.h
index 3dca1b6..1f3ceda 100644
--- a/gcc/rust/hir/rust-ast-lower-extern.h
+++ b/gcc/rust/hir/rust-ast-lower-extern.h
@@ -109,9 +109,8 @@ public:
mappings.get_next_localdef_id (
crate_num));
- function_params.push_back (
- HIR::NamedFunctionParam (mapping, param_name,
- std::unique_ptr<HIR::Type> (param_type)));
+ function_params.emplace_back (mapping, param_name,
+ std::unique_ptr<HIR::Type> (param_type));
}
auto crate_num = mappings.get_current_crate ();
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc
index 5db11cb..8fd9d16 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.cc
+++ b/gcc/rust/hir/rust-ast-lower-implitem.cc
@@ -115,7 +115,7 @@ ASTLowerImplItem::visit (AST::Function &function)
{
HIR::WhereClauseItem *i
= ASTLowerWhereClauseItem::translate (*item.get ());
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
+ where_clause_items.emplace_back (i);
}
HIR::WhereClause where_clause (std::move (where_clause_items));
@@ -162,10 +162,9 @@ ASTLowerImplItem::visit (AST::Function &function)
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- auto hir_param
- = HIR::FunctionParam (mapping, std::move (translated_pattern),
- std::move (translated_type), param.get_locus ());
- function_params.push_back (std::move (hir_param));
+ function_params.emplace_back (mapping, std::move (translated_pattern),
+ std::move (translated_type),
+ param.get_locus ());
}
bool terminated = false;
@@ -272,10 +271,9 @@ ASTLowerTraitItem::visit (AST::Function &func)
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- auto hir_param
- = HIR::FunctionParam (mapping, std::move (translated_pattern),
- std::move (translated_type), param.get_locus ());
- function_params.push_back (std::move (hir_param));
+ function_params.emplace_back (mapping, std::move (translated_pattern),
+ std::move (translated_type),
+ param.get_locus ());
}
if (func.has_self_param ())
@@ -320,10 +318,10 @@ ASTLowerTraitItem::visit (AST::Function &func)
}
void
-ASTLowerTraitItem::visit (AST::TraitItemConst &constant)
+ASTLowerTraitItem::visit (AST::ConstantItem &constant)
{
HIR::Type *type = ASTLoweringType::translate (constant.get_type ());
- HIR::Expr *expr = constant.has_expression ()
+ HIR::Expr *expr = constant.has_expr ()
? ASTLoweringExpr::translate (constant.get_expr ())
: nullptr;
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
index 8331bba..dfcf567 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -49,7 +49,7 @@ class ASTLowerTraitItem : public ASTLoweringBase
public:
static HIR::TraitItem *translate (AST::AssociatedItem &item);
void visit (AST::Function &func) override;
- void visit (AST::TraitItemConst &constant) override;
+ void visit (AST::ConstantItem &constant) override;
void visit (AST::TraitItemType &type) override;
private:
diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc
index 4e5a747..81815ff 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -72,7 +72,7 @@ ASTLoweringItem::visit (AST::Module &module)
// The item may be null if it doesn't need to live in the HIR - for
// example, macro rules definitions
if (transitem)
- items.push_back (std::unique_ptr<Item> (transitem));
+ items.emplace_back (transitem);
}
// should be lowered/copied from module.get_in/outer_attrs()
@@ -90,12 +90,11 @@ void
ASTLoweringItem::visit (AST::TypeAlias &alias)
{
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ where_clause_items.reserve (alias.get_where_clause ().get_items ().size ());
+
for (auto &item : alias.get_where_clause ().get_items ())
- {
- HIR::WhereClauseItem *i
- = ASTLowerWhereClauseItem::translate (*item.get ());
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
- }
+ where_clause_items.emplace_back (
+ ASTLowerWhereClauseItem::translate (*item.get ()));
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = translate_visibility (alias.get_visibility ());
@@ -130,17 +129,19 @@ ASTLoweringItem::visit (AST::TupleStruct &struct_decl)
}
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ where_clause_items.reserve (
+ struct_decl.get_where_clause ().get_items ().size ());
+
for (auto &item : struct_decl.get_where_clause ().get_items ())
- {
- HIR::WhereClauseItem *i
- = ASTLowerWhereClauseItem::translate (*item.get ());
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
- }
+ where_clause_items.emplace_back (
+ ASTLowerWhereClauseItem::translate (*item.get ()));
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = translate_visibility (struct_decl.get_visibility ());
std::vector<HIR::TupleField> fields;
+ fields.reserve (struct_decl.get_fields ().size ());
+
for (AST::TupleField &field : struct_decl.get_fields ())
{
if (field.get_field_type ().is_marked_for_strip ())
@@ -155,11 +156,8 @@ ASTLoweringItem::visit (AST::TupleStruct &struct_decl)
mappings.get_next_hir_id (crate_num),
mappings.get_next_localdef_id (crate_num));
- HIR::TupleField translated_field (mapping,
- std::unique_ptr<HIR::Type> (type), vis,
- field.get_locus (),
- field.get_outer_attrs ());
- fields.push_back (std::move (translated_field));
+ fields.emplace_back (mapping, std::unique_ptr<HIR::Type> (type), vis,
+ field.get_locus (), field.get_outer_attrs ());
}
auto crate_num = mappings.get_current_crate ();
@@ -185,12 +183,12 @@ ASTLoweringItem::visit (AST::StructStruct &struct_decl)
}
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ where_clause_items.reserve (
+ struct_decl.get_where_clause ().get_items ().size ());
+
for (auto &item : struct_decl.get_where_clause ().get_items ())
- {
- HIR::WhereClauseItem *i
- = ASTLowerWhereClauseItem::translate (*item.get ());
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
- }
+ where_clause_items.emplace_back (
+ ASTLowerWhereClauseItem::translate (*item.get ()));
HIR::WhereClause where_clause (std::move (where_clause_items));
@@ -245,25 +243,26 @@ ASTLoweringItem::visit (AST::Enum &enum_decl)
}
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ where_clause_items.reserve (
+ enum_decl.get_where_clause ().get_items ().size ());
+
for (auto &item : enum_decl.get_where_clause ().get_items ())
- {
- HIR::WhereClauseItem *i
- = ASTLowerWhereClauseItem::translate (*item.get ());
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
- }
+ where_clause_items.emplace_back (
+ ASTLowerWhereClauseItem::translate (*item.get ()));
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = translate_visibility (enum_decl.get_visibility ());
// bool is_unit = enum_decl.is_zero_variant ();
std::vector<std::unique_ptr<HIR::EnumItem>> items;
+ items.reserve (enum_decl.get_variants ().size ());
+
for (auto &variant : enum_decl.get_variants ())
{
if (variant->is_marked_for_strip ())
continue;
- HIR::EnumItem *hir_item = ASTLoweringEnumItem::translate (variant.get ());
- items.push_back (std::unique_ptr<HIR::EnumItem> (hir_item));
+ items.emplace_back (ASTLoweringEnumItem::translate (variant.get ()));
}
auto crate_num = mappings.get_current_crate ();
@@ -288,17 +287,16 @@ ASTLoweringItem::visit (AST::Union &union_decl)
{
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
if (union_decl.has_generics ())
- {
- generic_params = lower_generic_params (union_decl.get_generic_params ());
- }
+ generic_params = lower_generic_params (union_decl.get_generic_params ());
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ where_clause_items.reserve (
+ union_decl.get_where_clause ().get_items ().size ());
+
for (auto &item : union_decl.get_where_clause ().get_items ())
- {
- HIR::WhereClauseItem *i
- = ASTLowerWhereClauseItem::translate (*item.get ());
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
- }
+ where_clause_items.emplace_back (
+ ASTLowerWhereClauseItem::translate (*item.get ()));
+
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = translate_visibility (union_decl.get_visibility ());
@@ -390,12 +388,12 @@ ASTLoweringItem::visit (AST::Function &function)
return;
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ where_clause_items.reserve (
+ function.get_where_clause ().get_items ().size ());
+
for (auto &item : function.get_where_clause ().get_items ())
- {
- HIR::WhereClauseItem *i
- = ASTLowerWhereClauseItem::translate (*item.get ());
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
- }
+ where_clause_items.emplace_back (
+ ASTLowerWhereClauseItem::translate (*item.get ()));
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::FunctionQualifiers qualifiers
@@ -418,10 +416,41 @@ ASTLoweringItem::visit (AST::Function &function)
: nullptr;
std::vector<HIR::FunctionParam> function_params;
+ function_params.reserve (function.get_function_params ().size ());
+
+ auto crate_num = mappings.get_current_crate ();
for (auto &p : function.get_function_params ())
{
- if (p->is_variadic () || p->is_self ())
+ if (p->is_variadic ())
continue;
+ if (p->is_self ())
+ {
+ rich_location r (line_table, p->get_locus ());
+ r.add_range (function.get_locus ());
+ rust_error_at (
+ r, "%<self%> parameter is only allowed in associated functions");
+
+ // rustc creates a synthetic regular fn-param here pointing to a
+ // generic Self as far as i can see but that seems over the top for
+ // now.
+ //
+ // see this example (invalid code):
+ //
+ // pub trait X {
+ // fn x() {
+ // fn f(&mut self) {}
+ // f();
+ // }
+ // }
+ //
+ // without a synthetic param we wont get the number of args error as
+ // well but i think this is fine for now.
+ //
+ // problem is what we make the param type to become...
+
+ continue;
+ }
+
auto param = static_cast<AST::FunctionParam &> (*p);
auto translated_pattern = std::unique_ptr<HIR::Pattern> (
@@ -434,10 +463,9 @@ ASTLoweringItem::visit (AST::Function &function)
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- auto hir_param
- = HIR::FunctionParam (mapping, std::move (translated_pattern),
- std::move (translated_type), param.get_locus ());
- function_params.push_back (std::move (hir_param));
+ function_params.emplace_back (mapping, std::move (translated_pattern),
+ std::move (translated_type),
+ param.get_locus ());
}
bool terminated = false;
@@ -446,7 +474,6 @@ ASTLoweringItem::visit (AST::Function &function)
ASTLoweringBlock::translate (*function.get_definition ().value (),
&terminated));
- auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
mappings.get_next_hir_id (crate_num),
mappings.get_next_localdef_id (crate_num));
@@ -479,11 +506,12 @@ void
ASTLoweringItem::visit (AST::InherentImpl &impl_block)
{
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ where_clause_items.reserve (
+ impl_block.get_where_clause ().get_items ().size ());
+
for (auto &item : impl_block.get_where_clause ().get_items ())
- {
- HIR::WhereClauseItem *i = ASTLowerWhereClauseItem::translate (*item);
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
- }
+ where_clause_items.emplace_back (
+ ASTLowerWhereClauseItem::translate (*item));
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = translate_visibility (impl_block.get_visibility ());
@@ -540,7 +568,7 @@ ASTLoweringItem::visit (AST::InherentImpl &impl_block)
HIR::ImplItem *lowered
= ASTLowerImplItem::translate (*impl_item, mapping.get_hirid ());
rust_assert (lowered != nullptr);
- impl_items.push_back (std::unique_ptr<HIR::ImplItem> (lowered));
+ impl_items.emplace_back (lowered);
impl_item_ids.push_back (lowered->get_impl_mappings ().get_hirid ());
}
@@ -563,12 +591,12 @@ void
ASTLoweringItem::visit (AST::Trait &trait)
{
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ where_clause_items.reserve (trait.get_where_clause ().get_items ().size ());
+
for (auto &item : trait.get_where_clause ().get_items ())
- {
- HIR::WhereClauseItem *i
- = ASTLowerWhereClauseItem::translate (*item.get ());
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
- }
+ where_clause_items.emplace_back (
+ ASTLowerWhereClauseItem::translate (*item.get ()));
+
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = translate_visibility (trait.get_visibility ());
@@ -589,23 +617,24 @@ ASTLoweringItem::visit (AST::Trait &trait)
if (trait.has_type_param_bounds ())
{
for (auto &bound : trait.get_type_param_bounds ())
- {
- HIR::TypeParamBound *b = lower_bound (*bound);
- type_param_bounds.push_back (
- std::unique_ptr<HIR::TypeParamBound> (b));
- }
+ type_param_bounds.emplace_back (lower_bound (*bound));
}
+ auto trait_item_size = trait.get_trait_items ().size ();
+
std::vector<std::unique_ptr<HIR::TraitItem>> trait_items;
+ trait_items.reserve (trait_item_size);
std::vector<HirId> trait_item_ids;
+ trait_item_ids.reserve (trait_item_size);
+
for (auto &item : trait.get_trait_items ())
{
if (item->is_marked_for_strip ())
continue;
HIR::TraitItem *lowered = ASTLowerTraitItem::translate (*item);
- trait_items.push_back (std::unique_ptr<HIR::TraitItem> (lowered));
trait_item_ids.push_back (lowered->get_mappings ().get_hirid ());
+ trait_items.emplace_back (lowered);
}
auto crate_num = mappings.get_current_crate ();
@@ -636,13 +665,16 @@ ASTLoweringItem::visit (AST::Trait &trait)
void
ASTLoweringItem::visit (AST::TraitImpl &impl_block)
{
- std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
bool unsafe = impl_block.is_unsafe ();
+
+ std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ where_clause_items.reserve (
+ impl_block.get_where_clause ().get_items ().size ());
+
for (auto &item : impl_block.get_where_clause ().get_items ())
- {
- HIR::WhereClauseItem *i = ASTLowerWhereClauseItem::translate (*item);
- where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
- }
+ where_clause_items.emplace_back (
+ ASTLowerWhereClauseItem::translate (*item));
+
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = translate_visibility (impl_block.get_visibility ());
@@ -690,8 +722,13 @@ ASTLoweringItem::visit (AST::TraitImpl &impl_block)
mappings.get_next_hir_id (crate_num),
mappings.get_next_localdef_id (crate_num));
+ auto impl_items_size = impl_block.get_impl_items ().size ();
+
std::vector<std::unique_ptr<HIR::ImplItem>> impl_items;
+ impl_items.reserve (impl_items_size);
std::vector<HirId> impl_item_ids;
+ impl_item_ids.reserve (impl_items_size);
+
for (auto &impl_item : impl_block.get_impl_items ())
{
if (impl_item->is_marked_for_strip ())
@@ -700,8 +737,8 @@ ASTLoweringItem::visit (AST::TraitImpl &impl_block)
HIR::ImplItem *lowered
= ASTLowerImplItem::translate (*impl_item, mapping.get_hirid ());
rust_assert (lowered != nullptr);
- impl_items.push_back (std::unique_ptr<HIR::ImplItem> (lowered));
impl_item_ids.push_back (lowered->get_impl_mappings ().get_hirid ());
+ impl_items.emplace_back (lowered);
}
BoundPolarity polarity = impl_block.is_exclam ()
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
index 8aabcd8..4250adb 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -81,26 +81,45 @@ ASTLoweringPattern::visit (AST::TupleStructPattern &pattern)
auto &items = pattern.get_items ();
switch (items.get_item_type ())
{
- case AST::TupleStructItems::RANGE:
+ case AST::TupleStructItems::HAS_REST:
{
- // TODO
- rust_unreachable ();
+ AST::TupleStructItemsHasRest &items_has_rest
+ = static_cast<AST::TupleStructItemsHasRest &> (items);
+
+ std::vector<std::unique_ptr<HIR::Pattern>> lower_patterns;
+ lower_patterns.reserve (items_has_rest.get_lower_patterns ().size ());
+ for (auto &pattern_member : items_has_rest.get_lower_patterns ())
+ {
+ lower_patterns.emplace_back (
+ ASTLoweringPattern::translate (*pattern_member));
+ }
+
+ std::vector<std::unique_ptr<HIR::Pattern>> upper_patterns;
+ upper_patterns.reserve (items_has_rest.get_upper_patterns ().size ());
+ for (auto &pattern_member : items_has_rest.get_upper_patterns ())
+ {
+ upper_patterns.emplace_back (
+ ASTLoweringPattern::translate (*pattern_member));
+ }
+
+ lowered = new HIR::TupleStructItemsHasRest (std::move (lower_patterns),
+ std::move (upper_patterns));
}
break;
- case AST::TupleStructItems::NO_RANGE:
+ case AST::TupleStructItems::NO_REST:
{
- AST::TupleStructItemsNoRange &items_no_range
- = static_cast<AST::TupleStructItemsNoRange &> (items);
+ AST::TupleStructItemsNoRest &items_no_rest
+ = static_cast<AST::TupleStructItemsNoRest &> (items);
std::vector<std::unique_ptr<HIR::Pattern>> patterns;
- for (auto &inner_pattern : items_no_range.get_patterns ())
- {
- HIR::Pattern *p = ASTLoweringPattern::translate (*inner_pattern);
- patterns.push_back (std::unique_ptr<HIR::Pattern> (p));
- }
+ patterns.reserve (items_no_rest.get_patterns ().size ());
+
+ for (auto &inner_pattern : items_no_rest.get_patterns ())
+ patterns.emplace_back (
+ ASTLoweringPattern::translate (*inner_pattern));
- lowered = new HIR::TupleStructItemsNoRange (std::move (patterns));
+ lowered = new HIR::TupleStructItemsNoRest (std::move (patterns));
}
break;
}
@@ -121,7 +140,6 @@ ASTLoweringPattern::visit (AST::StructPattern &pattern)
= ASTLowerPathInExpression::translate (pattern.get_path ());
auto &raw_elems = pattern.get_struct_pattern_elems ();
- rust_assert (!raw_elems.has_etc ());
std::vector<std::unique_ptr<HIR::StructPatternField>> fields;
for (auto &field : raw_elems.get_struct_pattern_fields ())
@@ -196,7 +214,7 @@ ASTLoweringPattern::visit (AST::StructPattern &pattern)
mappings.insert_node_to_hir (field_node_id, field_id);
// add it to the lowered fields list
- fields.push_back (std::unique_ptr<HIR::StructPatternField> (f));
+ fields.emplace_back (f);
}
auto crate_num = mappings.get_current_crate ();
@@ -204,7 +222,8 @@ ASTLoweringPattern::visit (AST::StructPattern &pattern)
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- HIR::StructPatternElements elems (std::move (fields));
+ HIR::StructPatternElements elems (
+ std::move (fields), pattern.get_struct_pattern_elems ().has_rest ());
translated = new HIR::StructPattern (mapping, *path, std::move (elems));
}
@@ -223,21 +242,20 @@ void
ASTLoweringPattern::visit (AST::TuplePattern &pattern)
{
std::unique_ptr<HIR::TuplePatternItems> items;
- switch (pattern.get_items ().get_pattern_type ())
+ switch (pattern.get_items ().get_item_type ())
{
- case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE:
+ case AST::TuplePatternItems::ItemType::NO_REST:
{
- AST::TuplePatternItemsMultiple &ref
- = static_cast<AST::TuplePatternItemsMultiple &> (
- pattern.get_items ());
+ AST::TuplePatternItemsNoRest &ref
+ = static_cast<AST::TuplePatternItemsNoRest &> (pattern.get_items ());
items = lower_tuple_pattern_multiple (ref);
}
break;
- case AST::TuplePatternItems::TuplePatternItemType::RANGED:
+ case AST::TuplePatternItems::ItemType::HAS_REST:
{
- AST::TuplePatternItemsRanged &ref
- = static_cast<AST::TuplePatternItemsRanged &> (pattern.get_items ());
+ AST::TuplePatternItemsHasRest &ref
+ = static_cast<AST::TuplePatternItemsHasRest &> (pattern.get_items ());
items = lower_tuple_pattern_ranged (ref);
}
break;
@@ -268,8 +286,6 @@ ASTLoweringPattern::visit (AST::LiteralPattern &pattern)
void
ASTLoweringPattern::visit (AST::RangePattern &pattern)
{
- if (pattern.get_range_kind () == AST::RangeKind::EXCLUDED)
- rust_unreachable (); // Not supported yet
auto upper_bound = lower_range_pattern_bound (pattern.get_upper_bound ());
auto lower_bound = lower_range_pattern_bound (pattern.get_lower_bound ());
@@ -278,9 +294,11 @@ ASTLoweringPattern::visit (AST::RangePattern &pattern)
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- translated
- = new HIR::RangePattern (mapping, std::move (lower_bound),
- std::move (upper_bound), pattern.get_locus ());
+ bool is_inclusive = (pattern.get_range_kind () == AST::RangeKind::INCLUDED);
+
+ translated = new HIR::RangePattern (mapping, std::move (lower_bound),
+ std::move (upper_bound),
+ pattern.get_locus (), is_inclusive);
}
void
@@ -322,26 +340,22 @@ ASTLoweringPattern::visit (AST::ReferencePattern &pattern)
void
ASTLoweringPattern::visit (AST::SlicePattern &pattern)
{
- std::vector<std::unique_ptr<HIR::Pattern>> items;
+ std::unique_ptr<HIR::SlicePatternItems> items;
- switch (pattern.get_items ().get_pattern_type ())
+ switch (pattern.get_items ().get_item_type ())
{
- case AST::SlicePatternItems::SlicePatternItemType::NO_REST:
+ case AST::SlicePatternItems::ItemType::NO_REST:
{
- AST::SlicePatternItemsNoRest &ref
+ auto &ref
= static_cast<AST::SlicePatternItemsNoRest &> (pattern.get_items ());
- for (auto &p : ref.get_patterns ())
- {
- HIR::Pattern *item = ASTLoweringPattern::translate (*p);
- items.push_back (std::unique_ptr<HIR::Pattern> (item));
- }
+ items = ASTLoweringBase::lower_slice_pattern_no_rest (ref);
}
break;
- case AST::SlicePatternItems::SlicePatternItemType::HAS_REST:
+ case AST::SlicePatternItems::ItemType::HAS_REST:
{
- rust_error_at (pattern.get_locus (),
- "lowering of slice patterns with rest elements are not "
- "supported yet");
+ auto &ref
+ = static_cast<AST::SlicePatternItemsHasRest &> (pattern.get_items ());
+ items = ASTLoweringBase::lower_slice_pattern_has_rest (ref);
}
break;
}
@@ -364,12 +378,10 @@ ASTLoweringPattern::visit (AST::AltPattern &pattern)
UNKNOWN_LOCAL_DEFID);
std::vector<std::unique_ptr<HIR::Pattern>> alts;
+ alts.reserve (pattern.get_alts ().size ());
for (auto &alt : pattern.get_alts ())
- {
- alts.push_back (
- std::unique_ptr<HIR::Pattern> (ASTLoweringPattern::translate (*alt)));
- }
+ alts.emplace_back (ASTLoweringPattern::translate (*alt));
translated
= new HIR::AltPattern (mapping, std::move (alts), pattern.get_locus ());
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index e6e327f..5b8e7c5 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -80,7 +80,7 @@ ASTLowering::go ()
{
auto translated = ASTLoweringItem::translate (*item);
if (translated != nullptr)
- items.push_back (std::unique_ptr<HIR::Item> (translated));
+ items.emplace_back (translated);
}
auto &mappings = Analysis::Mappings::get ();
@@ -127,7 +127,7 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
block_did_terminate |= terminated;
if (translated_stmt)
- block_stmts.push_back (std::unique_ptr<HIR::Stmt> (translated_stmt));
+ block_stmts.emplace_back (translated_stmt);
}
if (expr.has_tail_expr () && block_did_terminate)
@@ -231,6 +231,7 @@ ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr &expr,
{
HIR::Expr *kase_expr;
std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns;
+ match_arm_patterns.reserve (expr.get_patterns ().size ());
*branch_value = ASTLoweringExpr::translate (expr.get_value_expr ());
kase_expr = ASTLoweringExpr::translate (expr.get_if_block ());
@@ -241,10 +242,7 @@ ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr &expr,
rust_assert (expr.get_patterns ().size () == 1);
for (auto &pattern : expr.get_patterns ())
- {
- HIR::Pattern *ptrn = ASTLoweringPattern::translate (*pattern);
- match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
- }
+ match_arm_patterns.emplace_back (ASTLoweringPattern::translate (*pattern));
// The match arm corresponding to the if let pattern when it matches.
HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (), nullptr,
@@ -255,9 +253,8 @@ ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr &expr,
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- HIR::MatchCase kase (std::move (mapping), std::move (arm),
- std::unique_ptr<HIR::Expr> (kase_expr));
- match_arms.push_back (std::move (kase));
+ match_arms.emplace_back (std::move (mapping), std::move (arm),
+ std::unique_ptr<HIR::Expr> (kase_expr));
// The default match arm when the if let pattern does not match
std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns_wildcard;
@@ -265,19 +262,14 @@ ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr &expr,
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));
+ match_arm_patterns_wildcard.emplace_back (
+ new HIR::WildcardPattern (mapping_default, expr.get_locus ()));
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));
+ match_arms.emplace_back (std::move (mapping_default), std::move (arm_default),
+ std::unique_ptr<HIR::Expr> (kase_else_expr));
}
void
@@ -442,11 +434,12 @@ ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
}
std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns;
+ match_arm_patterns.reserve (
+ match_case.get_arm ().get_patterns ().size ());
+
for (auto &pattern : match_case.get_arm ().get_patterns ())
- {
- HIR::Pattern *ptrn = ASTLoweringPattern::translate (*pattern);
- match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
- }
+ match_arm_patterns.emplace_back (
+ ASTLoweringPattern::translate (*pattern));
HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (),
std::unique_ptr<HIR::Expr> (kase_guard_expr),
@@ -457,9 +450,8 @@ ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- HIR::MatchCase kase (std::move (mapping), std::move (arm),
- std::unique_ptr<HIR::Expr> (kase_expr));
- match_arms.push_back (std::move (kase));
+ match_arms.emplace_back (std::move (mapping), std::move (arm),
+ std::unique_ptr<HIR::Expr> (kase_expr));
}
auto crate_num = mappings.get_current_crate ();
@@ -490,8 +482,11 @@ ASTLowerPathInExpression::visit (AST::PathInExpression &expr)
return;
}
- std::vector<HIR::PathExprSegment> path_segments;
auto &segments = expr.get_segments ();
+
+ std::vector<HIR::PathExprSegment> path_segments;
+ path_segments.reserve (segments.size ());
+
for (auto &s : segments)
{
path_segments.push_back (lower_path_expr_seg ((s)));
@@ -531,8 +526,11 @@ ASTLowerQualPathInExpression::visit (AST::QualifiedPathInExpression &expr)
HIR::QualifiedPathType qual_path_type
= lower_qual_path_type (expr.get_qualified_path_type ());
- std::vector<HIR::PathExprSegment> path_segments;
auto &segments = expr.get_segments ();
+
+ std::vector<HIR::PathExprSegment> path_segments;
+ path_segments.reserve (segments.size ());
+
for (auto &s : segments)
{
path_segments.push_back (lower_path_expr_seg ((s)));
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index a0cdcb2..49ce143 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -2307,20 +2307,20 @@ Dump::visit (StructPattern &e)
}
void
-Dump::visit (TupleStructItemsNoRange &e)
+Dump::visit (TupleStructItemsNoRest &e)
{
- begin ("TupleStructItemsNoRange");
+ begin ("TupleStructItemsNoRest");
visit_collection ("patterns", e.get_patterns ());
- end ("TupleStructItemsNoRange");
+ end ("TupleStructItemsNoRest");
}
void
-Dump::visit (TupleStructItemsRange &e)
+Dump::visit (TupleStructItemsHasRest &e)
{
- begin ("TupleStructItemsRange");
+ begin ("TupleStructItemsHasRest");
visit_collection ("lower_patterns", e.get_lower_patterns ());
visit_collection ("upper_patterns", e.get_upper_patterns ());
- end ("TupleStructItemsRange");
+ end ("TupleStructItemsHasRest");
}
void
@@ -2337,20 +2337,20 @@ Dump::visit (TupleStructPattern &e)
}
void
-Dump::visit (TuplePatternItemsMultiple &e)
+Dump::visit (TuplePatternItemsNoRest &e)
{
- begin ("TuplePatternItemsMultiple");
+ begin ("TuplePatternItemsNoRest");
visit_collection ("patterns", e.get_patterns ());
- end ("TuplePatternItemsMultiple");
+ end ("TuplePatternItemsNoRest");
}
void
-Dump::visit (TuplePatternItemsRanged &e)
+Dump::visit (TuplePatternItemsHasRest &e)
{
- begin ("TuplePatternItemsRanged");
+ begin ("TuplePatternItemsHasRest");
visit_collection ("lower_patterns", e.get_lower_patterns ());
visit_collection ("upper_patterns", e.get_upper_patterns ());
- end ("TuplePatternItemsRanged");
+ end ("TuplePatternItemsHasRest");
}
void
@@ -2363,11 +2363,28 @@ Dump::visit (TuplePattern &e)
}
void
+Dump::visit (SlicePatternItemsNoRest &e)
+{
+ begin ("SlicePatternItemsNoRest");
+ visit_collection ("patterns", e.get_patterns ());
+ end ("SlicePatternItemsNoRest");
+}
+
+void
+Dump::visit (SlicePatternItemsHasRest &e)
+{
+ begin ("SlicePatternItemsHasRest");
+ visit_collection ("lower_patterns", e.get_lower_patterns ());
+ visit_collection ("upper_patterns", e.get_upper_patterns ());
+ end ("SlicePatternItemsHasRest");
+}
+
+void
Dump::visit (SlicePattern &e)
{
begin ("SlicePattern");
do_mappings (e.get_mappings ());
- visit_collection ("items", e.get_items ());
+ visit_field ("items", e.get_items ());
end ("SlicePattern");
}
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index 3e6ae30..4dfc885 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -223,14 +223,18 @@ private:
virtual void visit (StructPatternFieldIdent &) override;
virtual void visit (StructPattern &) override;
- virtual void visit (TupleStructItemsNoRange &) override;
- virtual void visit (TupleStructItemsRange &) override;
+ virtual void visit (TupleStructItemsNoRest &) override;
+ virtual void visit (TupleStructItemsHasRest &) override;
virtual void visit (TupleStructPattern &) override;
- virtual void visit (TuplePatternItemsMultiple &) override;
- virtual void visit (TuplePatternItemsRanged &) override;
+ virtual void visit (TuplePatternItemsNoRest &) override;
+ virtual void visit (TuplePatternItemsHasRest &) override;
virtual void visit (TuplePattern &) override;
+
+ virtual void visit (SlicePatternItemsNoRest &) override;
+ virtual void visit (SlicePatternItemsHasRest &) override;
virtual void visit (SlicePattern &) override;
+
virtual void visit (AltPattern &) override;
virtual void visit (EmptyStmt &) override;
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 57b3a4d..aec2f36 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -199,13 +199,15 @@ class StructPatternFieldIdentPat;
class StructPatternFieldIdent;
class StructPattern;
class TupleStructItems;
-class TupleStructItemsNoRange;
-class TupleStructItemsRange;
+class TupleStructItemsNoRest;
+class TupleStructItemsHasRest;
class TupleStructPattern;
class TuplePatternItems;
-class TuplePatternItemsMultiple;
-class TuplePatternItemsRanged;
+class TuplePatternItemsNoRest;
+class TuplePatternItemsHasRest;
class TuplePattern;
+class SlicePatternItemsNoRest;
+class SlicePatternItemsHasRest;
class SlicePattern;
class AltPattern;
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index d9df602..eb9cec7 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -452,6 +452,7 @@ public:
bool is_unsafe () const { return unsafety == Unsafety::Unsafe; }
bool is_async () const { return async_status == Async::Yes; }
+ Unsafety get_unsafety () const { return unsafety; }
ABI get_abi () const { return abi; }
};
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index 9c636ca..89b9cc6 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -350,6 +350,7 @@ class RangePattern : public Pattern
/* location only stored to avoid a dereference - lower pattern should give
* correct location so maybe change in future */
location_t locus;
+ bool is_inclusive;
Analysis::NodeMapping mappings;
public:
@@ -359,10 +360,10 @@ public:
RangePattern (Analysis::NodeMapping mappings,
std::unique_ptr<RangePatternBound> lower,
std::unique_ptr<RangePatternBound> upper, location_t locus,
- bool has_ellipsis_syntax = false)
+ bool is_inclusive, bool has_ellipsis_syntax = false)
: lower (std::move (lower)), upper (std::move (upper)),
has_ellipsis_syntax (has_ellipsis_syntax), locus (locus),
- mappings (mappings)
+ is_inclusive (is_inclusive), mappings (mappings)
{}
// Copy constructor with clone
@@ -370,7 +371,7 @@ public:
: lower (other.lower->clone_range_pattern_bound ()),
upper (other.upper->clone_range_pattern_bound ()),
has_ellipsis_syntax (other.has_ellipsis_syntax), locus (other.locus),
- mappings (other.mappings)
+ is_inclusive (other.is_inclusive), mappings (other.mappings)
{}
// Overloaded assignment operator to clone
@@ -380,6 +381,7 @@ public:
upper = other.upper->clone_range_pattern_bound ();
has_ellipsis_syntax = other.has_ellipsis_syntax;
locus = other.locus;
+ is_inclusive = other.is_inclusive;
mappings = other.mappings;
return *this;
@@ -395,6 +397,7 @@ public:
void accept_vis (HIRPatternVisitor &vis) override;
bool get_has_ellipsis_syntax () { return has_ellipsis_syntax; };
+ bool is_inclusive_range () const { return is_inclusive; }
const Analysis::NodeMapping &get_mappings () const override final
{
@@ -680,6 +683,7 @@ protected:
class StructPatternElements
{
std::vector<std::unique_ptr<StructPatternField>> fields;
+ bool has_rest_pattern;
public:
// Returns whether there are any struct pattern fields
@@ -689,10 +693,18 @@ public:
* no etc). */
bool is_empty () const { return !has_struct_pattern_fields (); }
+ bool has_rest () const { return has_rest_pattern; }
+
// Constructor for StructPatternElements with both (potentially)
StructPatternElements (
std::vector<std::unique_ptr<StructPatternField>> fields)
- : fields (std::move (fields))
+ : fields (std::move (fields)), has_rest_pattern (false)
+ {}
+
+ StructPatternElements (
+ std::vector<std::unique_ptr<StructPatternField>> fields,
+ bool has_rest_pattern)
+ : fields (std::move (fields)), has_rest_pattern (has_rest_pattern)
{}
// Copy constructor with vector clone
@@ -700,7 +712,8 @@ public:
{
fields.reserve (other.fields.size ());
for (const auto &e : other.fields)
- fields.push_back (e->clone_struct_pattern_field ());
+ fields.emplace_back (e->clone_struct_pattern_field ());
+ has_rest_pattern = other.has_rest_pattern;
}
// Overloaded assignment operator with vector clone
@@ -709,8 +722,8 @@ public:
fields.clear ();
fields.reserve (other.fields.size ());
for (const auto &e : other.fields)
- fields.push_back (e->clone_struct_pattern_field ());
-
+ fields.emplace_back (e->clone_struct_pattern_field ());
+ has_rest_pattern = other.has_rest_pattern;
return *this;
}
@@ -778,24 +791,25 @@ protected:
}
};
-// Base abstract class for TupleStructItems and TuplePatternItems
-class TupleItems : public FullVisitable
+// Base abstract class for TupleStructItems, TuplePatternItems &
+// SlicePatternItems
+class PatternItems : public FullVisitable
{
public:
enum ItemType
{
- MULTIPLE,
- RANGED,
+ NO_REST,
+ HAS_REST,
};
- virtual ~TupleItems () {}
+ virtual ~PatternItems () {}
// TODO: should this store location data?
// Unique pointer custom clone function
- std::unique_ptr<TupleItems> clone_tuple_items () const
+ std::unique_ptr<PatternItems> clone_pattern_items () const
{
- return std::unique_ptr<TupleItems> (clone_tuple_items_impl ());
+ return std::unique_ptr<PatternItems> (clone_pattern_items_impl ());
}
virtual ItemType get_item_type () const = 0;
@@ -804,36 +818,36 @@ public:
protected:
// pure virtual clone implementation
- virtual TupleItems *clone_tuple_items_impl () const = 0;
+ virtual PatternItems *clone_pattern_items_impl () const = 0;
};
// Base abstract class for patterns used in TupleStructPattern
-class TupleStructItems : public TupleItems
+class TupleStructItems : public PatternItems
{
public:
// Unique pointer custom clone function
std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
{
- return std::unique_ptr<TupleStructItems> (clone_tuple_items_impl ());
+ return std::unique_ptr<TupleStructItems> (clone_pattern_items_impl ());
}
protected:
// pure virtual clone implementation
- virtual TupleStructItems *clone_tuple_items_impl () const override = 0;
+ virtual TupleStructItems *clone_pattern_items_impl () const override = 0;
};
-// Class for non-ranged tuple struct pattern patterns
-class TupleStructItemsNoRange : public TupleStructItems
+// Class for patterns within a tuple struct pattern, without a rest pattern
+class TupleStructItemsNoRest : public TupleStructItems
{
std::vector<std::unique_ptr<Pattern>> patterns;
public:
- TupleStructItemsNoRange (std::vector<std::unique_ptr<Pattern>> patterns)
+ TupleStructItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
: patterns (std::move (patterns))
{}
// Copy constructor with vector clone
- TupleStructItemsNoRange (TupleStructItemsNoRange const &other)
+ TupleStructItemsNoRest (TupleStructItemsNoRest const &other)
{
patterns.reserve (other.patterns.size ());
for (const auto &e : other.patterns)
@@ -841,7 +855,7 @@ public:
}
// Overloaded assignment operator with vector clone
- TupleStructItemsNoRange &operator= (TupleStructItemsNoRange const &other)
+ TupleStructItemsNoRest &operator= (TupleStructItemsNoRest const &other)
{
patterns.clear ();
patterns.reserve (other.patterns.size ());
@@ -852,9 +866,8 @@ public:
}
// move constructors
- TupleStructItemsNoRange (TupleStructItemsNoRange &&other) = default;
- TupleStructItemsNoRange &operator= (TupleStructItemsNoRange &&other)
- = default;
+ TupleStructItemsNoRest (TupleStructItemsNoRest &&other) = default;
+ TupleStructItemsNoRest &operator= (TupleStructItemsNoRest &&other) = default;
std::string as_string () const override;
@@ -866,32 +879,33 @@ public:
return patterns;
}
- ItemType get_item_type () const override final { return ItemType::MULTIPLE; }
+ ItemType get_item_type () const override final { return ItemType::NO_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TupleStructItemsNoRange *clone_tuple_items_impl () const override
+ TupleStructItemsNoRest *clone_pattern_items_impl () const override
{
- return new TupleStructItemsNoRange (*this);
+ return new TupleStructItemsNoRest (*this);
}
};
-// Class for ranged tuple struct pattern patterns
-class TupleStructItemsRange : public TupleStructItems
+// Class for patterns within a tuple struct pattern, with a rest pattern
+// included
+class TupleStructItemsHasRest : public TupleStructItems
{
std::vector<std::unique_ptr<Pattern>> lower_patterns;
std::vector<std::unique_ptr<Pattern>> upper_patterns;
public:
- TupleStructItemsRange (std::vector<std::unique_ptr<Pattern>> lower_patterns,
- std::vector<std::unique_ptr<Pattern>> upper_patterns)
+ TupleStructItemsHasRest (std::vector<std::unique_ptr<Pattern>> lower_patterns,
+ std::vector<std::unique_ptr<Pattern>> upper_patterns)
: lower_patterns (std::move (lower_patterns)),
upper_patterns (std::move (upper_patterns))
{}
// Copy constructor with vector clone
- TupleStructItemsRange (TupleStructItemsRange const &other)
+ TupleStructItemsHasRest (TupleStructItemsHasRest const &other)
{
lower_patterns.reserve (other.lower_patterns.size ());
for (const auto &e : other.lower_patterns)
@@ -903,7 +917,7 @@ public:
}
// Overloaded assignment operator to clone
- TupleStructItemsRange &operator= (TupleStructItemsRange const &other)
+ TupleStructItemsHasRest &operator= (TupleStructItemsHasRest const &other)
{
lower_patterns.clear ();
lower_patterns.reserve (other.lower_patterns.size ());
@@ -919,8 +933,9 @@ public:
}
// move constructors
- TupleStructItemsRange (TupleStructItemsRange &&other) = default;
- TupleStructItemsRange &operator= (TupleStructItemsRange &&other) = default;
+ TupleStructItemsHasRest (TupleStructItemsHasRest &&other) = default;
+ TupleStructItemsHasRest &operator= (TupleStructItemsHasRest &&other)
+ = default;
std::string as_string () const override;
@@ -945,14 +960,14 @@ public:
return upper_patterns;
}
- ItemType get_item_type () const override final { return ItemType::RANGED; }
+ ItemType get_item_type () const override final { return ItemType::HAS_REST; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TupleStructItemsRange *clone_tuple_items_impl () const override
+ TupleStructItemsHasRest *clone_pattern_items_impl () const override
{
- return new TupleStructItemsRange (*this);
+ return new TupleStructItemsHasRest (*this);
}
};
@@ -1025,32 +1040,32 @@ protected:
};
// Base abstract class representing TuplePattern patterns
-class TuplePatternItems : public TupleItems
+class TuplePatternItems : public PatternItems
{
public:
// Unique pointer custom clone function
std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items () const
{
- return std::unique_ptr<TuplePatternItems> (clone_tuple_items_impl ());
+ return std::unique_ptr<TuplePatternItems> (clone_pattern_items_impl ());
}
protected:
// pure virtual clone implementation
- virtual TuplePatternItems *clone_tuple_items_impl () const override = 0;
+ virtual TuplePatternItems *clone_pattern_items_impl () const override = 0;
};
-// Class representing TuplePattern patterns where there are multiple patterns
-class TuplePatternItemsMultiple : public TuplePatternItems
+// Class representing patterns within a TuplePattern, without a rest pattern
+class TuplePatternItemsNoRest : public TuplePatternItems
{
std::vector<std::unique_ptr<Pattern>> patterns;
public:
- TuplePatternItemsMultiple (std::vector<std::unique_ptr<Pattern>> patterns)
+ TuplePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
: patterns (std::move (patterns))
{}
// Copy constructor with vector clone
- TuplePatternItemsMultiple (TuplePatternItemsMultiple const &other)
+ TuplePatternItemsNoRest (TuplePatternItemsNoRest const &other)
{
patterns.reserve (other.patterns.size ());
for (const auto &e : other.patterns)
@@ -1058,7 +1073,7 @@ public:
}
// Overloaded assignment operator to vector clone
- TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple const &other)
+ TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest const &other)
{
patterns.clear ();
patterns.reserve (other.patterns.size ());
@@ -1069,15 +1084,15 @@ public:
}
// move constructors
- TuplePatternItemsMultiple (TuplePatternItemsMultiple &&other) = default;
- TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple &&other)
+ TuplePatternItemsNoRest (TuplePatternItemsNoRest &&other) = default;
+ TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest &&other)
= default;
std::string as_string () const override;
void accept_vis (HIRFullVisitor &vis) override;
- ItemType get_item_type () const override { return ItemType::MULTIPLE; }
+ ItemType get_item_type () const override { return ItemType::NO_REST; }
std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
@@ -1088,27 +1103,29 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TuplePatternItemsMultiple *clone_tuple_items_impl () const override
+ TuplePatternItemsNoRest *clone_pattern_items_impl () const override
{
- return new TuplePatternItemsMultiple (*this);
+ return new TuplePatternItemsNoRest (*this);
}
};
-// Class representing TuplePattern patterns where there are a range of patterns
-class TuplePatternItemsRanged : public TuplePatternItems
+// Class representing patterns within a TuplePattern, with a rest pattern
+// included
+class TuplePatternItemsHasRest : public TuplePatternItems
{
std::vector<std::unique_ptr<Pattern>> lower_patterns;
std::vector<std::unique_ptr<Pattern>> upper_patterns;
public:
- TuplePatternItemsRanged (std::vector<std::unique_ptr<Pattern>> lower_patterns,
- std::vector<std::unique_ptr<Pattern>> upper_patterns)
+ TuplePatternItemsHasRest (
+ std::vector<std::unique_ptr<Pattern>> lower_patterns,
+ std::vector<std::unique_ptr<Pattern>> upper_patterns)
: lower_patterns (std::move (lower_patterns)),
upper_patterns (std::move (upper_patterns))
{}
// Copy constructor with vector clone
- TuplePatternItemsRanged (TuplePatternItemsRanged const &other)
+ TuplePatternItemsHasRest (TuplePatternItemsHasRest const &other)
{
lower_patterns.reserve (other.lower_patterns.size ());
for (const auto &e : other.lower_patterns)
@@ -1120,7 +1137,7 @@ public:
}
// Overloaded assignment operator to clone
- TuplePatternItemsRanged &operator= (TuplePatternItemsRanged const &other)
+ TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest const &other)
{
lower_patterns.clear ();
lower_patterns.reserve (other.lower_patterns.size ());
@@ -1136,15 +1153,15 @@ public:
}
// move constructors
- TuplePatternItemsRanged (TuplePatternItemsRanged &&other) = default;
- TuplePatternItemsRanged &operator= (TuplePatternItemsRanged &&other)
+ TuplePatternItemsHasRest (TuplePatternItemsHasRest &&other) = default;
+ TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest &&other)
= default;
std::string as_string () const override;
void accept_vis (HIRFullVisitor &vis) override;
- ItemType get_item_type () const override { return ItemType::RANGED; }
+ ItemType get_item_type () const override { return ItemType::HAS_REST; }
std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
{
@@ -1167,9 +1184,9 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TuplePatternItemsRanged *clone_tuple_items_impl () const override
+ TuplePatternItemsHasRest *clone_pattern_items_impl () const override
{
- return new TuplePatternItemsRanged (*this);
+ return new TuplePatternItemsHasRest (*this);
}
};
@@ -1234,10 +1251,161 @@ protected:
}
};
+// Base abstract class representing SlicePattern patterns
+class SlicePatternItems : public PatternItems
+{
+public:
+ // Unique pointer custom clone function
+ std::unique_ptr<SlicePatternItems> clone_slice_pattern_items () const
+ {
+ return std::unique_ptr<SlicePatternItems> (clone_pattern_items_impl ());
+ }
+
+protected:
+ // pure virtual clone implementation
+ virtual SlicePatternItems *clone_pattern_items_impl () const override = 0;
+};
+
+// Class representing patterns within a SlicePattern, without a rest pattern
+class SlicePatternItemsNoRest : public SlicePatternItems
+{
+ std::vector<std::unique_ptr<Pattern>> patterns;
+
+public:
+ SlicePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
+ : patterns (std::move (patterns))
+ {}
+
+ // Copy constructor with vector clone
+ SlicePatternItemsNoRest (SlicePatternItemsNoRest const &other)
+ {
+ patterns.reserve (other.patterns.size ());
+ for (const auto &e : other.patterns)
+ patterns.push_back (e->clone_pattern ());
+ }
+
+ // Overloaded assignment operator to vector clone
+ SlicePatternItemsNoRest &operator= (SlicePatternItemsNoRest const &other)
+ {
+ patterns.clear ();
+ patterns.reserve (other.patterns.size ());
+ for (const auto &e : other.patterns)
+ patterns.push_back (e->clone_pattern ());
+
+ return *this;
+ }
+
+ // move constructors
+ SlicePatternItemsNoRest (SlicePatternItemsNoRest &&other) = default;
+ SlicePatternItemsNoRest &operator= (SlicePatternItemsNoRest &&other)
+ = default;
+
+ std::string as_string () const override;
+
+ void accept_vis (HIRFullVisitor &vis) override;
+
+ ItemType get_item_type () const override { return ItemType::NO_REST; }
+
+ std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
+ const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
+ {
+ return patterns;
+ }
+
+protected:
+ /* Use covariance to implement clone function as returning this object rather
+ * than base */
+ SlicePatternItemsNoRest *clone_pattern_items_impl () const override
+ {
+ return new SlicePatternItemsNoRest (*this);
+ }
+};
+
+// Class representing patterns within a SlicePattern, with a rest pattern
+// included
+class SlicePatternItemsHasRest : public SlicePatternItems
+{
+ std::vector<std::unique_ptr<Pattern>> lower_patterns;
+ std::vector<std::unique_ptr<Pattern>> upper_patterns;
+
+public:
+ SlicePatternItemsHasRest (
+ std::vector<std::unique_ptr<Pattern>> lower_patterns,
+ std::vector<std::unique_ptr<Pattern>> upper_patterns)
+ : lower_patterns (std::move (lower_patterns)),
+ upper_patterns (std::move (upper_patterns))
+ {}
+
+ // Copy constructor with vector clone
+ SlicePatternItemsHasRest (SlicePatternItemsHasRest const &other)
+ {
+ lower_patterns.reserve (other.lower_patterns.size ());
+ for (const auto &e : other.lower_patterns)
+ lower_patterns.push_back (e->clone_pattern ());
+
+ upper_patterns.reserve (other.upper_patterns.size ());
+ for (const auto &e : other.upper_patterns)
+ upper_patterns.push_back (e->clone_pattern ());
+ }
+
+ // Overloaded assignment operator to clone
+ SlicePatternItemsHasRest &operator= (SlicePatternItemsHasRest const &other)
+ {
+ lower_patterns.clear ();
+ lower_patterns.reserve (other.lower_patterns.size ());
+ for (const auto &e : other.lower_patterns)
+ lower_patterns.push_back (e->clone_pattern ());
+
+ lower_patterns.clear ();
+ upper_patterns.reserve (other.upper_patterns.size ());
+ for (const auto &e : other.upper_patterns)
+ upper_patterns.push_back (e->clone_pattern ());
+
+ return *this;
+ }
+
+ // move constructors
+ SlicePatternItemsHasRest (SlicePatternItemsHasRest &&other) = default;
+ SlicePatternItemsHasRest &operator= (SlicePatternItemsHasRest &&other)
+ = default;
+
+ std::string as_string () const override;
+
+ void accept_vis (HIRFullVisitor &vis) override;
+
+ ItemType get_item_type () const override { return ItemType::HAS_REST; }
+
+ std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
+ {
+ return lower_patterns;
+ }
+ const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
+ {
+ return lower_patterns;
+ }
+
+ std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
+ {
+ return upper_patterns;
+ }
+ const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
+ {
+ return upper_patterns;
+ }
+
+protected:
+ /* Use covariance to implement clone function as returning this object rather
+ * than base */
+ SlicePatternItemsHasRest *clone_pattern_items_impl () const override
+ {
+ return new SlicePatternItemsHasRest (*this);
+ }
+};
+
// HIR node representing patterns that can match slices and arrays
class SlicePattern : public Pattern
{
- std::vector<std::unique_ptr<Pattern>> items;
+ std::unique_ptr<SlicePatternItems> items;
location_t locus;
Analysis::NodeMapping mappings;
@@ -1245,30 +1413,23 @@ public:
std::string as_string () const override;
SlicePattern (Analysis::NodeMapping mappings,
- std::vector<std::unique_ptr<Pattern>> items, location_t locus)
+ std::unique_ptr<SlicePatternItems> items, location_t locus)
: items (std::move (items)), locus (locus), mappings (mappings)
{}
- // Copy constructor with vector clone
+ // Copy constructor requires clone
SlicePattern (SlicePattern const &other)
- : locus (other.locus), mappings (other.mappings)
- {
- items.reserve (other.items.size ());
- for (const auto &e : other.items)
- items.push_back (e->clone_pattern ());
- }
+ : items (other.items->clone_slice_pattern_items ()), locus (other.locus),
+ mappings (other.mappings)
+ {}
// Overloaded assignment operator to vector clone
SlicePattern &operator= (SlicePattern const &other)
{
+ items = other.items->clone_slice_pattern_items ();
locus = other.locus;
mappings = other.mappings;
- items.clear ();
- items.reserve (other.items.size ());
- for (const auto &e : other.items)
- items.push_back (e->clone_pattern ());
-
return *this;
}
@@ -1276,11 +1437,8 @@ public:
SlicePattern (SlicePattern &&other) = default;
SlicePattern &operator= (SlicePattern &&other) = default;
- std::vector<std::unique_ptr<Pattern>> &get_items () { return items; }
- const std::vector<std::unique_ptr<Pattern>> &get_items () const
- {
- return items;
- }
+ SlicePatternItems &get_items () { return *items; }
+ const SlicePatternItems &get_items () const { return *items; }
location_t get_locus () const override { return locus; }
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.cc b/gcc/rust/hir/tree/rust-hir-visitor.cc
index 58c1e1a..1e201a5 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.cc
+++ b/gcc/rust/hir/tree/rust-hir-visitor.cc
@@ -1023,14 +1023,14 @@ DefaultHIRVisitor::walk (StructPattern &pattern)
}
void
-DefaultHIRVisitor::walk (TupleStructItemsNoRange &tuple_items)
+DefaultHIRVisitor::walk (TupleStructItemsNoRest &tuple_items)
{
for (auto &item : tuple_items.get_patterns ())
item->accept_vis (*this);
}
void
-DefaultHIRVisitor::walk (TupleStructItemsRange &tuple_items)
+DefaultHIRVisitor::walk (TupleStructItemsHasRest &tuple_items)
{
for (auto &lower : tuple_items.get_lower_patterns ())
lower->accept_vis (*this);
@@ -1046,14 +1046,14 @@ DefaultHIRVisitor::walk (TupleStructPattern &pattern)
}
void
-DefaultHIRVisitor::walk (TuplePatternItemsMultiple &tuple_items)
+DefaultHIRVisitor::walk (TuplePatternItemsNoRest &tuple_items)
{
for (auto &pattern : tuple_items.get_patterns ())
pattern->accept_vis (*this);
}
void
-DefaultHIRVisitor::walk (TuplePatternItemsRanged &tuple_items)
+DefaultHIRVisitor::walk (TuplePatternItemsHasRest &tuple_items)
{
for (auto &lower : tuple_items.get_lower_patterns ())
lower->accept_vis (*this);
@@ -1068,10 +1068,25 @@ DefaultHIRVisitor::walk (TuplePattern &pattern)
}
void
+DefaultHIRVisitor::walk (SlicePatternItemsNoRest &items)
+{
+ for (auto &pattern : items.get_patterns ())
+ pattern->accept_vis (*this);
+}
+
+void
+DefaultHIRVisitor::walk (SlicePatternItemsHasRest &items)
+{
+ for (auto &lower : items.get_lower_patterns ())
+ lower->accept_vis (*this);
+ for (auto &upper : items.get_upper_patterns ())
+ upper->accept_vis (*this);
+}
+
+void
DefaultHIRVisitor::walk (SlicePattern &pattern)
{
- for (auto &item : pattern.get_items ())
- item->accept_vis (*this);
+ pattern.get_items ().accept_vis (*this);
}
void
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 7996260..77760b0 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -132,12 +132,14 @@ public:
virtual void visit (StructPatternFieldIdentPat &field) = 0;
virtual void visit (StructPatternFieldIdent &field) = 0;
virtual void visit (StructPattern &pattern) = 0;
- virtual void visit (TupleStructItemsNoRange &tuple_items) = 0;
- virtual void visit (TupleStructItemsRange &tuple_items) = 0;
+ virtual void visit (TupleStructItemsNoRest &tuple_items) = 0;
+ virtual void visit (TupleStructItemsHasRest &tuple_items) = 0;
virtual void visit (TupleStructPattern &pattern) = 0;
- virtual void visit (TuplePatternItemsMultiple &tuple_items) = 0;
- virtual void visit (TuplePatternItemsRanged &tuple_items) = 0;
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) = 0;
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) = 0;
virtual void visit (TuplePattern &pattern) = 0;
+ virtual void visit (SlicePatternItemsNoRest &items) = 0;
+ virtual void visit (SlicePatternItemsHasRest &items) = 0;
virtual void visit (SlicePattern &pattern) = 0;
virtual void visit (AltPattern &pattern) = 0;
virtual void visit (EmptyStmt &stmt) = 0;
@@ -305,12 +307,14 @@ public:
}
virtual void visit (StructPatternFieldIdent &node) override { walk (node); }
virtual void visit (StructPattern &node) override { walk (node); }
- virtual void visit (TupleStructItemsNoRange &node) override { walk (node); }
- virtual void visit (TupleStructItemsRange &node) override { walk (node); }
+ virtual void visit (TupleStructItemsNoRest &node) override { walk (node); }
+ virtual void visit (TupleStructItemsHasRest &node) override { walk (node); }
virtual void visit (TupleStructPattern &node) override { walk (node); }
- virtual void visit (TuplePatternItemsMultiple &node) override { walk (node); }
- virtual void visit (TuplePatternItemsRanged &node) override { walk (node); }
+ virtual void visit (TuplePatternItemsNoRest &node) override { walk (node); }
+ virtual void visit (TuplePatternItemsHasRest &node) override { walk (node); }
virtual void visit (TuplePattern &node) override { walk (node); }
+ virtual void visit (SlicePatternItemsNoRest &node) override { walk (node); }
+ virtual void visit (SlicePatternItemsHasRest &node) override { walk (node); }
virtual void visit (SlicePattern &node) override { walk (node); }
virtual void visit (AltPattern &node) override { walk (node); }
virtual void visit (EmptyStmt &node) override { walk (node); }
@@ -438,12 +442,14 @@ protected:
virtual void walk (StructPatternFieldIdentPat &) final;
virtual void walk (StructPatternFieldIdent &) final;
virtual void walk (StructPattern &) final;
- virtual void walk (TupleStructItemsNoRange &) final;
- virtual void walk (TupleStructItemsRange &) final;
+ virtual void walk (TupleStructItemsNoRest &) final;
+ virtual void walk (TupleStructItemsHasRest &) final;
virtual void walk (TupleStructPattern &) final;
- virtual void walk (TuplePatternItemsMultiple &) final;
- virtual void walk (TuplePatternItemsRanged &) final;
+ virtual void walk (TuplePatternItemsNoRest &) final;
+ virtual void walk (TuplePatternItemsHasRest &) final;
virtual void walk (TuplePattern &) final;
+ virtual void walk (SlicePatternItemsNoRest &) final;
+ virtual void walk (SlicePatternItemsHasRest &) final;
virtual void walk (SlicePattern &) final;
virtual void walk (AltPattern &) final;
virtual void walk (EmptyStmt &) final;
@@ -586,13 +592,16 @@ public:
virtual void visit (StructPatternFieldIdent &) override {}
virtual void visit (StructPattern &) override {}
- virtual void visit (TupleStructItemsNoRange &) override {}
- virtual void visit (TupleStructItemsRange &) override {}
+ virtual void visit (TupleStructItemsNoRest &) override {}
+ virtual void visit (TupleStructItemsHasRest &) override {}
virtual void visit (TupleStructPattern &) override {}
- virtual void visit (TuplePatternItemsMultiple &) override {}
- virtual void visit (TuplePatternItemsRanged &) override {}
+ virtual void visit (TuplePatternItemsNoRest &) override {}
+ virtual void visit (TuplePatternItemsHasRest &) override {}
virtual void visit (TuplePattern &) override {}
+
+ virtual void visit (SlicePatternItemsNoRest &) override {}
+ virtual void visit (SlicePatternItemsHasRest &) override {}
virtual void visit (SlicePattern &) override {}
virtual void visit (AltPattern &) override {}
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index a802e8c..ce10b02 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -2239,8 +2239,8 @@ PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const
// create segment and add to vector
std::string segment_str = segment.as_string ();
- simple_segments.push_back (
- AST::SimplePathSegment (std::move (segment_str), segment.get_locus ()));
+ simple_segments.emplace_back (std::move (segment_str),
+ segment.get_locus ());
}
// kind of a HACK to get locus depending on opening scope resolution
@@ -2281,9 +2281,8 @@ TypePath::as_simple_path () const
// create segment and add to vector
std::string segment_str = segment->as_string ();
- simple_segments.push_back (
- AST::SimplePathSegment (std::move (segment_str),
- segment->get_locus ()));
+ simple_segments.emplace_back (std::move (segment_str),
+ segment->get_locus ());
}
return AST::SimplePath (std::move (simple_segments),
@@ -2387,11 +2386,11 @@ RangePatternBoundLiteral::as_string () const
}
std::string
-SlicePattern::as_string () const
+SlicePatternItemsNoRest::as_string () const
{
- std::string str ("SlicePattern: ");
+ std::string str;
- for (const auto &pattern : items)
+ for (const auto &pattern : patterns)
{
str += "\n " + pattern->as_string ();
}
@@ -2400,6 +2399,46 @@ SlicePattern::as_string () const
}
std::string
+SlicePatternItemsHasRest::as_string () const
+{
+ std::string str;
+
+ str += "\n Lower patterns: ";
+ if (lower_patterns.empty ())
+ {
+ str += "none";
+ }
+ else
+ {
+ for (const auto &lower : lower_patterns)
+ {
+ str += "\n " + lower->as_string ();
+ }
+ }
+
+ str += "\n Upper patterns: ";
+ if (upper_patterns.empty ())
+ {
+ str += "none";
+ }
+ else
+ {
+ for (const auto &upper : upper_patterns)
+ {
+ str += "\n " + upper->as_string ();
+ }
+ }
+
+ return str;
+}
+
+std::string
+SlicePattern::as_string () const
+{
+ return "SlicePattern: " + items->as_string ();
+}
+
+std::string
AltPattern::as_string () const
{
std::string str ("AltPattern: ");
@@ -2413,7 +2452,7 @@ AltPattern::as_string () const
}
std::string
-TuplePatternItemsMultiple::as_string () const
+TuplePatternItemsNoRest::as_string () const
{
std::string str;
@@ -2426,7 +2465,7 @@ TuplePatternItemsMultiple::as_string () const
}
std::string
-TuplePatternItemsRanged::as_string () const
+TuplePatternItemsHasRest::as_string () const
{
std::string str;
@@ -2480,10 +2519,29 @@ StructPatternField::as_string () const
* just the body */
for (const auto &attr : outer_attrs)
{
- str += "\n " + attr.as_string ();
+ str += "\n " + attr.as_string ();
}
}
+ str += "\n item type: ";
+ switch (get_item_type ())
+ {
+ case ItemType::TUPLE_PAT:
+ str += "TUPLE_PAT";
+ break;
+ case ItemType::IDENT_PAT:
+ str += "IDENT_PAT";
+ break;
+ case ItemType::IDENT:
+ str += "IDENT";
+ break;
+ default:
+ str += "UNKNOWN";
+ break;
+ }
+
+ str += "\n mapping: " + mappings.as_string ();
+
return str;
}
@@ -2620,7 +2678,7 @@ IdentifierPattern::as_string () const
}
std::string
-TupleStructItemsNoRange::as_string () const
+TupleStructItemsNoRest::as_string () const
{
std::string str;
@@ -2633,7 +2691,7 @@ TupleStructItemsNoRange::as_string () const
}
std::string
-TupleStructItemsRange::as_string () const
+TupleStructItemsHasRest::as_string () const
{
std::string str ("\n Lower patterns: ");
@@ -4471,13 +4529,13 @@ StructPattern::accept_vis (HIRFullVisitor &vis)
}
void
-TupleStructItemsNoRange::accept_vis (HIRFullVisitor &vis)
+TupleStructItemsNoRest::accept_vis (HIRFullVisitor &vis)
{
vis.visit (*this);
}
void
-TupleStructItemsRange::accept_vis (HIRFullVisitor &vis)
+TupleStructItemsHasRest::accept_vis (HIRFullVisitor &vis)
{
vis.visit (*this);
}
@@ -4489,13 +4547,13 @@ TupleStructPattern::accept_vis (HIRFullVisitor &vis)
}
void
-TuplePatternItemsMultiple::accept_vis (HIRFullVisitor &vis)
+TuplePatternItemsNoRest::accept_vis (HIRFullVisitor &vis)
{
vis.visit (*this);
}
void
-TuplePatternItemsRanged::accept_vis (HIRFullVisitor &vis)
+TuplePatternItemsHasRest::accept_vis (HIRFullVisitor &vis)
{
vis.visit (*this);
}
@@ -4507,6 +4565,18 @@ TuplePattern::accept_vis (HIRFullVisitor &vis)
}
void
+SlicePatternItemsNoRest::accept_vis (HIRFullVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+SlicePatternItemsHasRest::accept_vis (HIRFullVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
SlicePattern::accept_vis (HIRFullVisitor &vis)
{
vis.visit (*this);
diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index 76ff15c..214161f 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -236,10 +236,11 @@ Lexer::dump_and_skip (int n)
out << "<id=";
out << tok->token_id_to_str ();
- out << (tok->has_str () ? (std::string (", text=") + tok->get_str ()
- + std::string (", typehint=")
- + std::string (tok->get_type_hint_str ()))
- : "")
+ out << (tok->should_have_str ()
+ ? (std::string (", text=") + tok->get_str ()
+ + std::string (", typehint=")
+ + std::string (tok->get_type_hint_str ()))
+ : "")
<< " ";
out << Linemap::location_to_string (loc) << '\n';
}
diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc
index c396e10..43682af 100644
--- a/gcc/rust/lex/rust-token.cc
+++ b/gcc/rust/lex/rust-token.cc
@@ -178,29 +178,6 @@ nfc_normalize_token_string (location_t loc, TokenId id, const std::string &str)
return str;
}
-const std::string &
-Token::get_str () const
-{
- if (token_id_is_keyword (token_id))
- return token_id_keyword_string (token_id);
-
- // FIXME: attempt to return null again
- // gcc_assert(str != NULL);
-
- // HACK: allow referencing an empty string
- static const std::string empty = "";
-
- if (str == NULL)
- {
- rust_error_at (get_locus (),
- "attempted to get string for %qs, which has no string. "
- "returning empty string instead",
- get_token_description ());
- return empty;
- }
- return *str;
-}
-
namespace {
enum class Context
{
diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h
index 2021aec..71a7503 100644
--- a/gcc/rust/lex/rust-token.h
+++ b/gcc/rust/lex/rust-token.h
@@ -22,6 +22,7 @@
#include "rust-system.h"
#include "rust-linemap.h"
#include "rust-unicode.h"
+#include "rust-diagnostics.h"
namespace Rust {
@@ -249,7 +250,7 @@ private:
// Token location.
location_t locus;
// Associated text (if any) of token.
- std::unique_ptr<std::string> str;
+ std::string str;
// TODO: maybe remove issues and just store std::string as value?
/* Type hint for token based on lexer data (e.g. type suffix). Does not exist
* for most tokens. */
@@ -257,23 +258,21 @@ private:
// Token constructor from token id and location. Has a null string.
Token (TokenId token_id, location_t location)
- : token_id (token_id), locus (location), str (nullptr),
- type_hint (CORETYPE_UNKNOWN)
+ : token_id (token_id), locus (location), type_hint (CORETYPE_UNKNOWN)
{}
// Token constructor from token id, location, and a string.
- Token (TokenId token_id, location_t location, std::string &&paramStr)
+ Token (TokenId token_id, location_t location, std::string paramStr)
: token_id (token_id), locus (location), type_hint (CORETYPE_UNKNOWN)
{
// Normalize identifier tokens
- str = std::make_unique<std::string> (
- nfc_normalize_token_string (location, token_id, paramStr));
+ str = nfc_normalize_token_string (location, token_id, std::move (paramStr));
}
// Token constructor from token id, location, and a char.
Token (TokenId token_id, location_t location, char paramChar)
- : token_id (token_id), locus (location),
- str (new std::string (1, paramChar)), type_hint (CORETYPE_UNKNOWN)
+ : token_id (token_id), locus (location), str (1, paramChar),
+ type_hint (CORETYPE_UNKNOWN)
{
// Do not need to normalize 1byte char
}
@@ -283,19 +282,17 @@ private:
: token_id (token_id), locus (location), type_hint (CORETYPE_UNKNOWN)
{
// Normalize identifier tokens
- str = std::make_unique<std::string> (
- nfc_normalize_token_string (location, token_id,
- paramCodepoint.as_string ()));
+ str = nfc_normalize_token_string (location, token_id,
+ paramCodepoint.as_string ());
}
// Token constructor from token id, location, a string, and type hint.
- Token (TokenId token_id, location_t location, std::string &&paramStr,
+ Token (TokenId token_id, location_t location, std::string paramStr,
PrimitiveCoreType parType)
: token_id (token_id), locus (location), type_hint (parType)
{
// Normalize identifier tokens
- str = std::make_unique<std::string> (
- nfc_normalize_token_string (location, token_id, paramStr));
+ str = nfc_normalize_token_string (location, token_id, std::move (paramStr));
}
public:
@@ -322,7 +319,7 @@ public:
}
// Makes and returns a new TokenPtr of type IDENTIFIER.
- static TokenPtr make_identifier (location_t locus, std::string &&str)
+ static TokenPtr make_identifier (location_t locus, std::string str)
{
// return std::make_shared<Token> (IDENTIFIER, locus, str);
return TokenPtr (new Token (IDENTIFIER, locus, std::move (str)));
@@ -331,7 +328,7 @@ public:
static TokenPtr make_identifier (const Identifier &ident);
// Makes and returns a new TokenPtr of type INT_LITERAL.
- static TokenPtr make_int (location_t locus, std::string &&str,
+ static TokenPtr make_int (location_t locus, std::string str,
PrimitiveCoreType type_hint = CORETYPE_UNKNOWN)
{
// return std::make_shared<Token> (INT_LITERAL, locus, str, type_hint);
@@ -340,7 +337,7 @@ public:
}
// Makes and returns a new TokenPtr of type FLOAT_LITERAL.
- static TokenPtr make_float (location_t locus, std::string &&str,
+ static TokenPtr make_float (location_t locus, std::string str,
PrimitiveCoreType type_hint = CORETYPE_UNKNOWN)
{
// return std::make_shared<Token> (FLOAT_LITERAL, locus, str, type_hint);
@@ -349,7 +346,7 @@ public:
}
// Makes and returns a new TokenPtr of type STRING_LITERAL.
- static TokenPtr make_string (location_t locus, std::string &&str)
+ static TokenPtr make_string (location_t locus, std::string str)
{
// return std::make_shared<Token> (STRING_LITERAL, locus, str,
// CORETYPE_STR);
@@ -372,32 +369,32 @@ public:
}
// Makes and returns a new TokenPtr of type BYTE_STRING_LITERAL (fix).
- static TokenPtr make_byte_string (location_t locus, std::string &&str)
+ static TokenPtr make_byte_string (location_t locus, std::string str)
{
// return std::make_shared<Token> (BYTE_STRING_LITERAL, locus, str);
return TokenPtr (new Token (BYTE_STRING_LITERAL, locus, std::move (str)));
}
// Makes and returns a new TokenPtr of type RAW_STRING_LITERAL.
- static TokenPtr make_raw_string (location_t locus, std::string &&str)
+ static TokenPtr make_raw_string (location_t locus, std::string str)
{
return TokenPtr (new Token (RAW_STRING_LITERAL, locus, std::move (str)));
}
// Makes and returns a new TokenPtr of type INNER_DOC_COMMENT.
- static TokenPtr make_inner_doc_comment (location_t locus, std::string &&str)
+ static TokenPtr make_inner_doc_comment (location_t locus, std::string str)
{
return TokenPtr (new Token (INNER_DOC_COMMENT, locus, std::move (str)));
}
// Makes and returns a new TokenPtr of type OUTER_DOC_COMMENT.
- static TokenPtr make_outer_doc_comment (location_t locus, std::string &&str)
+ static TokenPtr make_outer_doc_comment (location_t locus, std::string str)
{
return TokenPtr (new Token (OUTER_DOC_COMMENT, locus, std::move (str)));
}
// Makes and returns a new TokenPtr of type LIFETIME.
- static TokenPtr make_lifetime (location_t locus, std::string &&str)
+ static TokenPtr make_lifetime (location_t locus, std::string str)
{
// return std::make_shared<Token> (LIFETIME, locus, str);
return TokenPtr (new Token (LIFETIME, locus, std::move (str)));
@@ -413,16 +410,18 @@ public:
void set_locus (location_t locus) { this->locus = locus; }
// Gets string description of the token.
- const std::string &
- get_str () const; /*{
-// FIXME: put in header again when fix null problem
-//gcc_assert(str != nullptr);
-if (str == nullptr) {
-error_at(get_locus(), "attempted to get string for '%s', which has no string.
-returning empty string instead.", get_token_description()); return "";
-}
-return *str;
-}*/
+ const std::string &get_str () const
+ {
+ if (token_id_is_keyword (token_id))
+ return token_id_keyword_string (token_id);
+
+ if (!should_have_str ())
+ rust_internal_error_at (
+ locus, "attempting to get string for %qs, which should have no string",
+ get_token_description ());
+
+ return str;
+ }
// Gets token's type hint info.
PrimitiveCoreType get_type_hint () const
@@ -464,14 +463,11 @@ return *str;
}
}
- /* Returns whether the token actually has a string (regardless of whether it
- * should or not). */
- bool has_str () const { return str != nullptr; }
-
// Returns whether the token should have a string.
bool should_have_str () const
{
- return is_literal () || token_id == IDENTIFIER || token_id == LIFETIME;
+ return is_literal () || token_id == IDENTIFIER || token_id == LIFETIME
+ || token_id == INNER_DOC_COMMENT || token_id == OUTER_DOC_COMMENT;
}
// Returns whether the token is a pure decimal int literal
diff --git a/gcc/rust/metadata/rust-export-metadata.cc b/gcc/rust/metadata/rust-export-metadata.cc
index 1829a85..4dfc280 100644
--- a/gcc/rust/metadata/rust-export-metadata.cc
+++ b/gcc/rust/metadata/rust-export-metadata.cc
@@ -91,8 +91,8 @@ ExportContext::emit_function (const HIR::Function &fn)
AST::Function &function = static_cast<AST::Function &> (vis_item);
std::vector<std::unique_ptr<AST::ExternalItem>> external_items;
- external_items.push_back (std::unique_ptr<AST::ExternalItem> (
- static_cast<AST::ExternalItem *> (&function)));
+ external_items.emplace_back (
+ static_cast<AST::ExternalItem *> (&function));
AST::ExternBlock extern_block (get_string_from_abi (Rust::ABI::RUST),
std::move (external_items),
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 14bccbd..ec4c1c1 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -1053,6 +1053,7 @@ Parser<ManagedTokenSource>::parse_identifier_or_keyword_token ()
}
else
{
+ add_error (Error (t->get_locus (), "expected keyword or identifier"));
return nullptr;
}
}
@@ -1716,10 +1717,9 @@ Parser<ManagedTokenSource>::parse_decl_macro_def (AST::Visibility vis,
return nullptr;
}
- AST::MacroRule macro_rule
- = AST::MacroRule (std::move (matcher), std::move (transcriber), locus);
std::vector<AST::MacroRule> macro_rules;
- macro_rules.push_back (macro_rule);
+ macro_rules.emplace_back (std::move (matcher), std::move (transcriber),
+ locus);
return std::unique_ptr<AST::MacroRulesDefinition> (
AST::MacroRulesDefinition::decl_macro (std::move (rule_name),
@@ -3316,8 +3316,8 @@ Parser<ManagedTokenSource>::parse_lifetime_params ()
break;
}
- lifetime_params.push_back (std::unique_ptr<AST::LifetimeParam> (
- new AST::LifetimeParam (std::move (lifetime_param.value ()))));
+ lifetime_params.emplace_back (
+ new AST::LifetimeParam (std::move (lifetime_param.value ())));
if (lexer.peek_token ()->get_id () != COMMA)
break;
@@ -3356,8 +3356,8 @@ Parser<ManagedTokenSource>::parse_lifetime_params (EndTokenPred is_end_token)
return {};
}
- lifetime_params.push_back (std::unique_ptr<AST::LifetimeParam> (
- new AST::LifetimeParam (std::move (lifetime_param))));
+ lifetime_params.emplace_back (
+ new AST::LifetimeParam (std::move (lifetime_param)));
if (lexer.peek_token ()->get_id () != COMMA)
break;
@@ -5219,7 +5219,7 @@ Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs,
// Parses a constant trait item.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::TraitItemConst>
+std::unique_ptr<AST::ConstantItem>
Parser<ManagedTokenSource>::parse_trait_const (AST::AttrVec outer_attrs)
{
location_t locus = lexer.peek_token ()->get_locus ();
@@ -5257,10 +5257,9 @@ Parser<ManagedTokenSource>::parse_trait_const (AST::AttrVec outer_attrs)
return nullptr;
}
- return std::unique_ptr<AST::TraitItemConst> (
- new AST::TraitItemConst (std::move (ident), std::move (type),
- std::move (const_body), std::move (outer_attrs),
- locus));
+ return std::unique_ptr<AST::ConstantItem> (new AST::ConstantItem (
+ std::move (ident), AST::Visibility::create_private (), std::move (type),
+ std::move (const_body), std::move (outer_attrs), locus));
}
/* Parses a struct "impl" item (both inherent impl and trait impl can be
@@ -10484,16 +10483,22 @@ Parser<ManagedTokenSource>::parse_pattern ()
return first;
std::vector<std::unique_ptr<AST::Pattern>> alts;
- alts.push_back (std::move (first));
+ if (first != nullptr)
+ alts.push_back (std::move (first));
do
{
lexer.skip_token ();
- alts.push_back (parse_pattern_no_alt ());
+ auto follow = parse_pattern_no_alt ();
+ if (follow != nullptr)
+ alts.push_back (std::move (follow));
}
while (lexer.peek_token ()->get_id () == PIPE);
+ if (alts.empty ())
+ return nullptr;
+
/* alternates */
return std::unique_ptr<AST::Pattern> (
new AST::AltPattern (std::move (alts), start_locus));
@@ -10812,9 +10817,9 @@ Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern ()
return nullptr;
}
- // create ranged tuple pattern items with only upper items
- std::unique_ptr<AST::TuplePatternItemsRanged> items (
- new AST::TuplePatternItemsRanged (
+ // create tuple pattern items with only upper pattern items
+ std::unique_ptr<AST::TuplePatternItemsHasRest> items (
+ new AST::TuplePatternItemsHasRest (
std::vector<std::unique_ptr<AST::Pattern>> (), std::move (patterns)));
return std::unique_ptr<AST::TuplePattern> (
new AST::TuplePattern (std::move (items), paren_locus));
@@ -10822,8 +10827,8 @@ Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern ()
else if (lexer.peek_token ()->get_id () == RIGHT_PAREN)
{
skip_token (RIGHT_PAREN);
- auto items = std::unique_ptr<AST::TuplePatternItemsMultiple> (
- new AST::TuplePatternItemsMultiple (
+ auto items = std::unique_ptr<AST::TuplePatternItemsNoRest> (
+ new AST::TuplePatternItemsNoRest (
std::vector<std::unique_ptr<AST::Pattern>> ()));
return std::unique_ptr<AST::TuplePattern> (
new AST::TuplePattern (std::move (items), paren_locus));
@@ -10887,8 +10892,8 @@ Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern ()
// non-ranged tuple pattern
lexer.skip_token ();
- std::unique_ptr<AST::TuplePatternItemsMultiple> items (
- new AST::TuplePatternItemsMultiple (std::move (patterns)));
+ std::unique_ptr<AST::TuplePatternItemsNoRest> items (
+ new AST::TuplePatternItemsNoRest (std::move (patterns)));
return std::unique_ptr<AST::TuplePattern> (
new AST::TuplePattern (std::move (items), paren_locus));
}
@@ -10928,9 +10933,9 @@ Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern ()
return nullptr;
}
- std::unique_ptr<AST::TuplePatternItemsRanged> items (
- new AST::TuplePatternItemsRanged (std::move (patterns),
- std::move (upper_patterns)));
+ std::unique_ptr<AST::TuplePatternItemsHasRest> items (
+ new AST::TuplePatternItemsHasRest (std::move (patterns),
+ std::move (upper_patterns)));
return std::unique_ptr<AST::TuplePattern> (
new AST::TuplePattern (std::move (items), paren_locus));
}
@@ -11113,7 +11118,7 @@ Parser<ManagedTokenSource>::parse_identifier_pattern ()
lexer.skip_token ();
// parse required pattern to bind
- bind_pattern = parse_pattern ();
+ bind_pattern = parse_pattern_no_alt ();
if (bind_pattern == nullptr)
{
Error error (lexer.peek_token ()->get_locus (),
@@ -11240,7 +11245,8 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern ()
// identifier with pattern bind
lexer.skip_token ();
- std::unique_ptr<AST::Pattern> bind_pattern = parse_pattern ();
+ std::unique_ptr<AST::Pattern> bind_pattern
+ = parse_pattern_no_alt ();
if (bind_pattern == nullptr)
{
Error error (
@@ -11325,9 +11331,9 @@ Parser<ManagedTokenSource>::parse_tuple_struct_items ()
rust_debug (
"finished parsing tuple struct items ranged (upper/none only)");
- return std::unique_ptr<AST::TupleStructItemsRange> (
- new AST::TupleStructItemsRange (std::move (lower_patterns),
- std::move (upper_patterns)));
+ return std::unique_ptr<AST::TupleStructItemsHasRest> (
+ new AST::TupleStructItemsHasRest (std::move (lower_patterns),
+ std::move (upper_patterns)));
}
// has at least some lower patterns
@@ -11369,8 +11375,8 @@ Parser<ManagedTokenSource>::parse_tuple_struct_items ()
switch (t->get_id ())
{
case RIGHT_PAREN:
- return std::unique_ptr<AST::TupleStructItemsNoRange> (
- new AST::TupleStructItemsNoRange (std::move (lower_patterns)));
+ return std::unique_ptr<AST::TupleStructItemsNoRest> (
+ new AST::TupleStructItemsNoRest (std::move (lower_patterns)));
case DOT_DOT:
{
// has an upper range that must be parsed separately
@@ -11402,9 +11408,9 @@ Parser<ManagedTokenSource>::parse_tuple_struct_items ()
t = lexer.peek_token ();
}
- return std::unique_ptr<AST::TupleStructItemsRange> (
- new AST::TupleStructItemsRange (std::move (lower_patterns),
- std::move (upper_patterns)));
+ return std::unique_ptr<AST::TupleStructItemsHasRest> (
+ new AST::TupleStructItemsHasRest (std::move (lower_patterns),
+ std::move (upper_patterns)));
}
default:
// error
@@ -11424,7 +11430,7 @@ Parser<ManagedTokenSource>::parse_struct_pattern_elems ()
std::vector<std::unique_ptr<AST::StructPatternField>> fields;
AST::AttrVec etc_attrs;
- bool has_etc = false;
+ bool has_rest = false;
// try parsing struct pattern fields
const_TokenPtr t = lexer.peek_token ();
@@ -11437,7 +11443,7 @@ Parser<ManagedTokenSource>::parse_struct_pattern_elems ()
{
lexer.skip_token ();
etc_attrs = std::move (outer_attrs);
- has_etc = true;
+ has_rest = true;
break;
}
@@ -11462,7 +11468,7 @@ Parser<ManagedTokenSource>::parse_struct_pattern_elems ()
t = lexer.peek_token ();
}
- if (has_etc)
+ if (has_rest)
return AST::StructPatternElements (std::move (fields),
std::move (etc_attrs));
else
@@ -11761,6 +11767,8 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr ()
std::unique_ptr<AST::MacroInvocation> invoc
= parse_macro_invocation_partial (std::move (path),
std::move (outer_attrs));
+ if (invoc == nullptr)
+ return ExprOrStmt::create_error ();
if (restrictions.consume_semi && maybe_skip_token (SEMICOLON))
{
@@ -11772,9 +11780,12 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr ()
TokenId after_macro = lexer.peek_token ()->get_id ();
- if (invoc->get_invoc_data ().get_delim_tok_tree ().get_delim_type ()
- == AST::CURLY
- && after_macro != DOT && after_macro != QUESTION_MARK)
+ AST::DelimType delim_type = invoc->get_invoc_data ()
+ .get_delim_tok_tree ()
+ .get_delim_type ();
+
+ if (delim_type == AST::CURLY && after_macro != DOT
+ && after_macro != QUESTION_MARK)
{
rust_debug ("braced macro statement");
return ExprOrStmt (
@@ -12149,20 +12160,12 @@ Parser<ManagedTokenSource>::parse_expr (int right_binding_power,
return nullptr;
}
- if (current_token->get_id () == LEFT_SHIFT)
- {
- lexer.split_current_token (LEFT_ANGLE, LEFT_ANGLE);
- current_token = lexer.peek_token ();
- }
-
- lexer.skip_token ();
-
ParseRestrictions null_denotation_restrictions = restrictions;
null_denotation_restrictions.expr_can_be_stmt = false;
// parse null denotation (unary part of expression)
std::unique_ptr<AST::Expr> expr
- = null_denotation (current_token, {}, null_denotation_restrictions);
+ = null_denotation ({}, null_denotation_restrictions);
return left_denotations (std::move (expr), right_binding_power,
std::move (outer_attrs), restrictions);
@@ -12230,8 +12233,7 @@ Parser<ManagedTokenSource>::parse_expr (AST::AttrVec outer_attrs,
/* Determines action to take when finding token at beginning of expression. */
template <typename ManagedTokenSource>
std::unique_ptr<AST::Expr>
-Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
- AST::AttrVec outer_attrs,
+Parser<ManagedTokenSource>::null_denotation (AST::AttrVec outer_attrs,
ParseRestrictions restrictions)
{
/* note: tok is previous character in input stream, not current one, as
@@ -12241,6 +12243,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
* denotation and then a left denotation), null denotations handle primaries
* and unary operands (but only prefix unary operands) */
+ auto tok = lexer.peek_token ();
+
switch (tok->get_id ())
{
case IDENTIFIER:
@@ -12249,28 +12253,26 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
case DOLLAR_SIGN:
case CRATE:
case SUPER:
+ case SCOPE_RESOLUTION:
{
// DEBUG
rust_debug ("beginning null denotation identifier handling");
/* best option: parse as path, then extract identifier, macro,
* struct/enum, or just path info from it */
- AST::PathInExpression path = parse_path_in_expression_pratt (tok);
+ AST::PathInExpression path = parse_path_in_expression ();
return null_denotation_path (std::move (path), std::move (outer_attrs),
restrictions);
}
- case SCOPE_RESOLUTION:
- {
- // TODO: fix: this is for global paths, i.e. std::string::whatever
- Error error (tok->get_locus (),
- "found null denotation scope resolution operator, and "
- "have not written handling for it");
- add_error (std::move (error));
-
- return nullptr;
- }
default:
+ if (tok->get_id () == LEFT_SHIFT)
+ {
+ lexer.split_current_token (LEFT_ANGLE, LEFT_ANGLE);
+ tok = lexer.peek_token ();
+ }
+
+ lexer.skip_token ();
return null_denotation_not_path (std::move (tok), std::move (outer_attrs),
restrictions);
}
@@ -13035,12 +13037,6 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
// array or slice index expression (pseudo binary infix)
return parse_index_expr (tok, std::move (left), std::move (outer_attrs),
restrictions);
- case FLOAT_LITERAL:
- /* HACK: get around lexer mis-identifying '.0' or '.1' or whatever as a
- * float literal - TODO does this happen anymore? It shouldn't. */
- return parse_tuple_index_expr_float (tok, std::move (left),
- std::move (outer_attrs),
- restrictions);
default:
add_error (Error (tok->get_locus (),
"found unexpected token %qs in left denotation",
@@ -14436,119 +14432,6 @@ Parser<ManagedTokenSource>::parse_struct_expr_tuple_partial (
std::move (outer_attrs), path_locus));
}
-/* Parses a path in expression with the first token passed as a parameter (as
- * it is skipped in token stream). Note that this only parses segment-first
- * paths, not global ones. */
-template <typename ManagedTokenSource>
-AST::PathInExpression
-Parser<ManagedTokenSource>::parse_path_in_expression_pratt (const_TokenPtr tok)
-{
- // HACK-y way of making up for pratt-parsing consuming first token
-
- // DEBUG
- rust_debug ("current peek token when starting path pratt parse: '%s'",
- lexer.peek_token ()->get_token_description ());
-
- // create segment vector
- std::vector<AST::PathExprSegment> segments;
-
- std::string initial_str;
-
- switch (tok->get_id ())
- {
- case IDENTIFIER:
- initial_str = tok->get_str ();
- break;
- case SUPER:
- initial_str = Values::Keywords::SUPER;
- break;
- case SELF:
- initial_str = Values::Keywords::SELF;
- break;
- case SELF_ALIAS:
- initial_str = Values::Keywords::SELF_ALIAS;
- break;
- case CRATE:
- initial_str = Values::Keywords::CRATE;
- break;
- case DOLLAR_SIGN:
- if (lexer.peek_token ()->get_id () == CRATE)
- {
- initial_str = "$crate";
- break;
- }
- gcc_fallthrough ();
- default:
- add_error (Error (tok->get_locus (),
- "unrecognised token %qs in path in expression",
- tok->get_token_description ()));
-
- return AST::PathInExpression::create_error ();
- }
-
- // parse required initial segment
- AST::PathExprSegment initial_segment (initial_str, tok->get_locus ());
- // parse generic args (and turbofish), if they exist
- /* use lookahead to determine if they actually exist (don't want to
- * accidently parse over next ident segment) */
- if (lexer.peek_token ()->get_id () == SCOPE_RESOLUTION
- && lexer.peek_token (1)->get_id () == LEFT_ANGLE)
- {
- // skip scope resolution
- lexer.skip_token ();
-
- AST::GenericArgs generic_args = parse_path_generic_args ();
-
- initial_segment
- = AST::PathExprSegment (AST::PathIdentSegment (initial_str,
- tok->get_locus ()),
- tok->get_locus (), std::move (generic_args));
- }
- if (initial_segment.is_error ())
- {
- // skip after somewhere?
- // don't necessarily throw error but yeah
-
- // DEBUG
- rust_debug ("initial segment is error - returning null");
-
- return AST::PathInExpression::create_error ();
- }
- segments.push_back (std::move (initial_segment));
-
- // parse optional segments (as long as scope resolution operator exists)
- const_TokenPtr t = lexer.peek_token ();
- while (t->get_id () == SCOPE_RESOLUTION)
- {
- // skip scope resolution operator
- lexer.skip_token ();
-
- // parse the actual segment - it is an error if it doesn't exist now
- AST::PathExprSegment segment = parse_path_expr_segment ();
- if (segment.is_error ())
- {
- // skip after somewhere?
- Error error (t->get_locus (),
- "could not parse path expression segment");
- add_error (std::move (error));
-
- return AST::PathInExpression::create_error ();
- }
-
- segments.push_back (std::move (segment));
-
- t = lexer.peek_token ();
- }
-
- // DEBUG:
- rust_debug (
- "current token (just about to return path to null denotation): '%s'",
- lexer.peek_token ()->get_token_description ());
-
- return AST::PathInExpression (std::move (segments), {}, tok->get_locus (),
- false);
-}
-
// Parses a closure expression with pratt parsing (from null denotation).
template <typename ManagedTokenSource>
std::unique_ptr<AST::ClosureExpr>
@@ -14686,35 +14569,6 @@ Parser<ManagedTokenSource>::parse_closure_expr_pratt (const_TokenPtr tok,
}
}
-/* Parses a tuple index expression (pratt-parsed) from a 'float' token as a
- * result of lexer misidentification. */
-template <typename ManagedTokenSource>
-std::unique_ptr<AST::TupleIndexExpr>
-Parser<ManagedTokenSource>::parse_tuple_index_expr_float (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> tuple_expr,
- AST::AttrVec outer_attrs, ParseRestrictions restrictions ATTRIBUTE_UNUSED)
-{
- // only works on float literals
- if (tok->get_id () != FLOAT_LITERAL)
- return nullptr;
-
- // DEBUG:
- rust_debug ("exact string form of float: '%s'", tok->get_str ().c_str ());
-
- // get float string and remove dot and initial 0
- std::string index_str = tok->get_str ();
- index_str.erase (index_str.begin ());
-
- // get int from string
- int index = atoi (index_str.c_str ());
-
- location_t locus = tuple_expr->get_locus ();
-
- return std::unique_ptr<AST::TupleIndexExpr> (
- new AST::TupleIndexExpr (std::move (tuple_expr), index,
- std::move (outer_attrs), locus));
-}
-
// Returns true if the next token is END, ELSE, or EOF;
template <typename ManagedTokenSource>
bool
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 8253885..7b40463 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -212,6 +212,11 @@ public:
std::unique_ptr<AST::MacroInvocation>
parse_macro_invocation (AST::AttrVec outer_attrs);
+ /*
+ * This has to be public for parsing expressions with outer attributes
+ */
+ AST::AttrVec parse_outer_attributes ();
+
private:
void skip_after_semicolon ();
void skip_after_end ();
@@ -228,7 +233,6 @@ private:
// AST-related stuff - maybe move or something?
AST::Attribute parse_inner_attribute ();
- AST::AttrVec parse_outer_attributes ();
AST::Attribute parse_outer_attribute ();
std::unique_ptr<AST::AttrInput> parse_attr_input ();
std::tuple<AST::SimplePath, std::unique_ptr<AST::AttrInput>, location_t>
@@ -368,7 +372,7 @@ private:
AST::AttrVec outer_attrs);
std::unique_ptr<AST::TraitItemType>
parse_trait_type (AST::AttrVec outer_attrs, AST::Visibility);
- std::unique_ptr<AST::TraitItemConst>
+ std::unique_ptr<AST::ConstantItem>
parse_trait_const (AST::AttrVec outer_attrs);
tl::expected<std::unique_ptr<AST::Param>, ParseSelfError> parse_self_param ();
@@ -393,7 +397,7 @@ private:
AST::AttrVec outer_attrs = AST::AttrVec (),
ParseRestrictions restrictions = ParseRestrictions ());
std::unique_ptr<AST::Expr>
- null_denotation (const_TokenPtr t, AST::AttrVec outer_attrs = AST::AttrVec (),
+ null_denotation (AST::AttrVec outer_attrs = AST::AttrVec (),
ParseRestrictions restrictions = ParseRestrictions ());
std::unique_ptr<AST::Expr>
null_denotation_path (AST::PathInExpression path, AST::AttrVec outer_attrs,
@@ -598,7 +602,6 @@ private:
std::unique_ptr<AST::CallExpr>
parse_struct_expr_tuple_partial (AST::PathInExpression path,
AST::AttrVec outer_attrs);
- AST::PathInExpression parse_path_in_expression_pratt (const_TokenPtr tok);
std::unique_ptr<AST::ClosureExpr>
parse_closure_expr_pratt (const_TokenPtr tok,
AST::AttrVec outer_attrs = AST::AttrVec ());
@@ -782,7 +785,7 @@ private:
// don't want to make things *only* AttributeParser uses public
// TODO: fold more of AttributeParser into Parser?
- friend class ::Rust::AST::AttributeParser;
+ friend struct ::Rust::AST::AttributeParser;
};
std::string extract_module_path (const AST::AttrVec &inner_attrs,
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc
deleted file mode 100644
index 3c7b425..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ /dev/null
@@ -1,691 +0,0 @@
-// Copyright (C) 2020-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-ast-resolve-base.h"
-#include "rust-ast-resolve-expr.h"
-#include "rust-ast-resolve-path.h"
-#include "rust-item.h"
-#include "rust-path.h"
-
-namespace Rust {
-namespace Resolver {
-
-bool
-ResolverBase::resolve_visibility (const AST::Visibility &vis)
-{
- if (vis.has_path ())
- {
- auto path = vis.get_path ();
- ResolvePath::go (path);
-
- // Do we need to lookup something here?
- // Is it just about resolving the names correctly so we can look them up
- // later?
- }
-
- return true;
-}
-
-// Default visitors implementations
-
-void
-ResolverBase::visit (AST::Token &)
-{}
-
-void
-ResolverBase::visit (AST::DelimTokenTree &)
-{}
-
-void
-ResolverBase::visit (AST::AttrInputMetaItemContainer &)
-{}
-
-void
-ResolverBase::visit (AST::IdentifierExpr &)
-{}
-
-void
-ResolverBase::visit (AST::Lifetime &)
-{}
-
-void
-ResolverBase::visit (AST::LifetimeParam &)
-{}
-
-void
-ResolverBase::visit (AST::ConstGenericParam &)
-{}
-
-void
-ResolverBase::visit (AST::PathInExpression &)
-{}
-
-void
-ResolverBase::visit (AST::TypePathSegment &)
-{}
-
-void
-ResolverBase::visit (AST::TypePathSegmentGeneric &)
-{}
-
-void
-ResolverBase::visit (AST::TypePathSegmentFunction &)
-{}
-
-void
-ResolverBase::visit (AST::TypePath &)
-{}
-
-void
-ResolverBase::visit (AST::QualifiedPathInExpression &)
-{}
-
-void
-ResolverBase::visit (AST::QualifiedPathInType &)
-{}
-
-void
-ResolverBase::visit (AST::LiteralExpr &)
-{}
-
-void
-ResolverBase::visit (AST::AttrInputLiteral &)
-{}
-
-void
-ResolverBase::visit (AST::AttrInputMacro &)
-{}
-
-void
-ResolverBase::visit (AST::MetaItemLitExpr &)
-{}
-
-void
-ResolverBase::visit (AST::MetaItemPathExpr &)
-{}
-
-void
-ResolverBase::visit (AST::BorrowExpr &)
-{}
-
-void
-ResolverBase::visit (AST::DereferenceExpr &)
-{}
-
-void
-ResolverBase::visit (AST::ErrorPropagationExpr &)
-{}
-
-void
-ResolverBase::visit (AST::NegationExpr &)
-{}
-
-void
-ResolverBase::visit (AST::ArithmeticOrLogicalExpr &)
-{}
-
-void
-ResolverBase::visit (AST::ComparisonExpr &)
-{}
-
-void
-ResolverBase::visit (AST::LazyBooleanExpr &)
-{}
-
-void
-ResolverBase::visit (AST::TypeCastExpr &)
-{}
-
-void
-ResolverBase::visit (AST::AssignmentExpr &)
-{}
-
-void
-ResolverBase::visit (AST::CompoundAssignmentExpr &)
-{}
-
-void
-ResolverBase::visit (AST::GroupedExpr &)
-{}
-
-void
-ResolverBase::visit (AST::ArrayElemsValues &)
-{}
-
-void
-ResolverBase::visit (AST::ArrayElemsCopied &)
-{}
-
-void
-ResolverBase::visit (AST::ArrayExpr &)
-{}
-
-void
-ResolverBase::visit (AST::ArrayIndexExpr &)
-{}
-
-void
-ResolverBase::visit (AST::TupleExpr &)
-{}
-
-void
-ResolverBase::visit (AST::TupleIndexExpr &)
-{}
-
-void
-ResolverBase::visit (AST::StructExprStruct &)
-{}
-
-void
-ResolverBase::visit (AST::StructExprFieldIdentifier &)
-{}
-
-void
-ResolverBase::visit (AST::StructExprFieldIdentifierValue &)
-{}
-
-void
-ResolverBase::visit (AST::StructExprFieldIndexValue &)
-{}
-
-void
-ResolverBase::visit (AST::StructExprStructFields &)
-{}
-
-void
-ResolverBase::visit (AST::StructExprStructBase &)
-{}
-
-void
-ResolverBase::visit (AST::CallExpr &)
-{}
-
-void
-ResolverBase::visit (AST::MethodCallExpr &)
-{}
-
-void
-ResolverBase::visit (AST::FieldAccessExpr &)
-{}
-
-void
-ResolverBase::visit (AST::ClosureExprInner &)
-{}
-
-void
-ResolverBase::visit (AST::BlockExpr &)
-{}
-
-void
-ResolverBase::visit (AST::AnonConst &)
-{}
-
-void
-ResolverBase::visit (AST::ConstBlock &)
-{}
-
-void
-ResolverBase::visit (AST::ClosureExprInnerTyped &)
-{}
-
-void
-ResolverBase::visit (AST::ContinueExpr &)
-{}
-
-void
-ResolverBase::visit (AST::BreakExpr &)
-{}
-
-void
-ResolverBase::visit (AST::RangeFromToExpr &)
-{}
-
-void
-ResolverBase::visit (AST::RangeFromExpr &)
-{}
-
-void
-ResolverBase::visit (AST::RangeToExpr &)
-{}
-
-void
-ResolverBase::visit (AST::RangeFullExpr &)
-{}
-
-void
-ResolverBase::visit (AST::RangeFromToInclExpr &)
-{}
-
-void
-ResolverBase::visit (AST::RangeToInclExpr &)
-{}
-
-void
-ResolverBase::visit (AST::BoxExpr &)
-{}
-
-void
-ResolverBase::visit (AST::ReturnExpr &)
-{}
-
-void
-ResolverBase::visit (AST::TryExpr &)
-{}
-
-void
-ResolverBase::visit (AST::UnsafeBlockExpr &)
-{}
-
-void
-ResolverBase::visit (AST::LoopExpr &)
-{}
-
-void
-ResolverBase::visit (AST::WhileLoopExpr &)
-{}
-
-void
-ResolverBase::visit (AST::WhileLetLoopExpr &)
-{}
-
-void
-ResolverBase::visit (AST::ForLoopExpr &)
-{}
-
-void
-ResolverBase::visit (AST::IfExpr &)
-{}
-
-void
-ResolverBase::visit (AST::IfExprConseqElse &)
-{}
-
-void
-ResolverBase::visit (AST::IfLetExpr &)
-{}
-
-void
-ResolverBase::visit (AST::IfLetExprConseqElse &)
-{}
-
-void
-ResolverBase::visit (AST::MatchExpr &)
-{}
-
-void
-ResolverBase::visit (AST::AwaitExpr &)
-{}
-
-void
-ResolverBase::visit (AST::AsyncBlockExpr &)
-{}
-
-void
-ResolverBase::visit (AST::InlineAsm &)
-{}
-
-void
-ResolverBase::visit (AST::LlvmInlineAsm &)
-{}
-
-void
-ResolverBase::visit (AST::TypeParam &)
-{}
-
-void
-ResolverBase::visit (AST::LifetimeWhereClauseItem &)
-{}
-
-void
-ResolverBase::visit (AST::TypeBoundWhereClauseItem &)
-{}
-
-void
-ResolverBase::visit (AST::Module &)
-{}
-
-void
-ResolverBase::visit (AST::ExternCrate &)
-{}
-
-void
-ResolverBase::visit (AST::UseTreeGlob &)
-{}
-
-void
-ResolverBase::visit (AST::UseTreeList &)
-{}
-
-void
-ResolverBase::visit (AST::UseTreeRebind &)
-{}
-
-void
-ResolverBase::visit (AST::UseDeclaration &)
-{}
-
-void
-ResolverBase::visit (AST::Function &)
-{}
-
-void
-ResolverBase::visit (AST::TypeAlias &)
-{}
-
-void
-ResolverBase::visit (AST::StructStruct &)
-{}
-
-void
-ResolverBase::visit (AST::TupleStruct &)
-{}
-
-void
-ResolverBase::visit (AST::EnumItem &)
-{}
-
-void
-ResolverBase::visit (AST::EnumItemTuple &)
-{}
-
-void
-ResolverBase::visit (AST::EnumItemStruct &)
-{}
-
-void
-ResolverBase::visit (AST::EnumItemDiscriminant &)
-{}
-
-void
-ResolverBase::visit (AST::Enum &)
-{}
-
-void
-ResolverBase::visit (AST::Union &)
-{}
-
-void
-ResolverBase::visit (AST::ConstantItem &)
-{}
-
-void
-ResolverBase::visit (AST::StaticItem &)
-{}
-
-void
-ResolverBase::visit (AST::TraitItemConst &)
-{}
-
-void
-ResolverBase::visit (AST::TraitItemType &)
-{}
-
-void
-ResolverBase::visit (AST::Trait &)
-{}
-
-void
-ResolverBase::visit (AST::InherentImpl &)
-{}
-
-void
-ResolverBase::visit (AST::TraitImpl &)
-{}
-
-void
-ResolverBase::visit (AST::ExternalTypeItem &)
-{}
-
-void
-ResolverBase::visit (AST::ExternalStaticItem &)
-{}
-
-void
-ResolverBase::visit (AST::ExternBlock &)
-{}
-
-void
-ResolverBase::visit (AST::MacroMatchFragment &)
-{}
-
-void
-ResolverBase::visit (AST::MacroMatchRepetition &)
-{}
-
-void
-ResolverBase::visit (AST::MacroMatcher &)
-{}
-
-void
-ResolverBase::visit (AST::MacroRulesDefinition &)
-{}
-
-void
-ResolverBase::visit (AST::MacroInvocation &)
-{}
-
-void
-ResolverBase::visit (AST::MetaItemPath &)
-{}
-
-void
-ResolverBase::visit (AST::MetaItemSeq &)
-{}
-
-void
-ResolverBase::visit (AST::MetaWord &)
-{}
-
-void
-ResolverBase::visit (AST::MetaNameValueStr &)
-{}
-
-void
-ResolverBase::visit (AST::MetaListPaths &)
-{}
-
-void
-ResolverBase::visit (AST::MetaListNameValueStr &)
-{}
-
-void
-ResolverBase::visit (AST::LiteralPattern &)
-{}
-
-void
-ResolverBase::visit (AST::IdentifierPattern &)
-{}
-
-void
-ResolverBase::visit (AST::WildcardPattern &)
-{}
-
-void
-ResolverBase::visit (AST::RestPattern &)
-{}
-
-void
-ResolverBase::visit (AST::RangePatternBoundLiteral &)
-{}
-
-void
-ResolverBase::visit (AST::RangePatternBoundPath &)
-{}
-
-void
-ResolverBase::visit (AST::RangePatternBoundQualPath &)
-{}
-
-void
-ResolverBase::visit (AST::RangePattern &)
-{}
-
-void
-ResolverBase::visit (AST::ReferencePattern &)
-{}
-
-void
-ResolverBase::visit (AST::StructPatternFieldTuplePat &)
-{}
-
-void
-ResolverBase::visit (AST::StructPatternFieldIdentPat &)
-{}
-
-void
-ResolverBase::visit (AST::StructPatternFieldIdent &)
-{}
-
-void
-ResolverBase::visit (AST::StructPattern &)
-{}
-
-void
-ResolverBase::visit (AST::TupleStructItemsNoRange &)
-{}
-
-void
-ResolverBase::visit (AST::TupleStructItemsRange &)
-{}
-
-void
-ResolverBase::visit (AST::TupleStructPattern &)
-{}
-
-void
-ResolverBase::visit (AST::TuplePatternItemsMultiple &)
-{}
-
-void
-ResolverBase::visit (AST::TuplePatternItemsRanged &)
-{}
-
-void
-ResolverBase::visit (AST::TuplePattern &)
-{}
-
-void
-ResolverBase::visit (AST::GroupedPattern &)
-{}
-
-void
-ResolverBase::visit (AST::SlicePatternItemsNoRest &)
-{}
-
-void
-ResolverBase::visit (AST::SlicePatternItemsHasRest &)
-{}
-
-void
-ResolverBase::visit (AST::SlicePattern &)
-{}
-
-void
-ResolverBase::visit (AST::AltPattern &)
-{}
-
-void
-ResolverBase::visit (AST::EmptyStmt &)
-{}
-
-void
-ResolverBase::visit (AST::LetStmt &)
-{}
-
-void
-ResolverBase::visit (AST::ExprStmt &)
-{}
-
-void
-ResolverBase::visit (AST::TraitBound &)
-{}
-
-void
-ResolverBase::visit (AST::ImplTraitType &)
-{}
-
-void
-ResolverBase::visit (AST::TraitObjectType &)
-{}
-
-void
-ResolverBase::visit (AST::ParenthesisedType &)
-{}
-
-void
-ResolverBase::visit (AST::ImplTraitTypeOneBound &)
-{}
-
-void
-ResolverBase::visit (AST::TraitObjectTypeOneBound &)
-{}
-
-void
-ResolverBase::visit (AST::TupleType &)
-{}
-
-void
-ResolverBase::visit (AST::NeverType &)
-{}
-
-void
-ResolverBase::visit (AST::RawPointerType &)
-{}
-
-void
-ResolverBase::visit (AST::ReferenceType &)
-{}
-
-void
-ResolverBase::visit (AST::ArrayType &)
-{}
-
-void
-ResolverBase::visit (AST::SliceType &)
-{}
-
-void
-ResolverBase::visit (AST::InferredType &)
-{}
-
-void
-ResolverBase::visit (AST::BareFunctionType &)
-{}
-
-void
-ResolverBase::visit (AST::SelfParam &)
-{}
-
-void
-ResolverBase::visit (AST::VariadicParam &)
-{}
-
-void
-ResolverBase::visit (AST::FunctionParam &)
-{}
-
-void
-ResolverBase::visit (AST::FormatArgs &fmt)
-{}
-
-void
-ResolverBase::visit (AST::OffsetOf &offset_of)
-{}
-
-} // namespace Resolver
-} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
deleted file mode 100644
index 89c5c35..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_BASE_H
-#define RUST_AST_RESOLVE_BASE_H
-
-#include "rust-ast-visitor.h"
-#include "rust-ast.h"
-#include "rust-builtin-ast-nodes.h"
-#include "rust-expr.h"
-#include "rust-name-resolver.h"
-#include "rust-diagnostics.h"
-#include "rust-location.h"
-
-namespace Rust {
-namespace Resolver {
-inline void
-redefined_error (const rich_location &loc)
-{
- rust_error_at (loc, "redefined multiple times");
-}
-
-class ResolverBase : public AST::ASTVisitor
-{
-public:
- virtual ~ResolverBase () {}
-
- void visit (AST::Token &);
- void visit (AST::DelimTokenTree &);
- void visit (AST::AttrInputMetaItemContainer &);
- void visit (AST::IdentifierExpr &);
- void visit (AST::Lifetime &);
- void visit (AST::LifetimeParam &);
- void visit (AST::ConstGenericParam &);
- void visit (AST::PathInExpression &);
- void visit (AST::TypePathSegment &);
- void visit (AST::TypePathSegmentGeneric &);
- void visit (AST::TypePathSegmentFunction &);
- void visit (AST::TypePath &);
- void visit (AST::QualifiedPathInExpression &);
- void visit (AST::QualifiedPathInType &);
- void visit (AST::LiteralExpr &);
- void visit (AST::AttrInputLiteral &);
- void visit (AST::AttrInputMacro &);
- void visit (AST::MetaItemLitExpr &);
- void visit (AST::MetaItemPathExpr &);
- void visit (AST::BorrowExpr &);
- void visit (AST::DereferenceExpr &);
- void visit (AST::ErrorPropagationExpr &);
- void visit (AST::NegationExpr &);
- void visit (AST::ArithmeticOrLogicalExpr &);
- void visit (AST::ComparisonExpr &);
- void visit (AST::LazyBooleanExpr &);
- void visit (AST::TypeCastExpr &);
- void visit (AST::AssignmentExpr &);
- void visit (AST::CompoundAssignmentExpr &);
- void visit (AST::GroupedExpr &);
- void visit (AST::ArrayElemsValues &);
- void visit (AST::ArrayElemsCopied &);
- void visit (AST::ArrayExpr &);
- void visit (AST::ArrayIndexExpr &);
- void visit (AST::TupleExpr &);
- void visit (AST::TupleIndexExpr &);
- void visit (AST::StructExprStruct &);
- void visit (AST::StructExprFieldIdentifier &);
- void visit (AST::StructExprFieldIdentifierValue &);
- void visit (AST::StructExprFieldIndexValue &);
- void visit (AST::StructExprStructFields &);
- void visit (AST::StructExprStructBase &);
- void visit (AST::CallExpr &);
- void visit (AST::MethodCallExpr &);
- void visit (AST::FieldAccessExpr &);
- void visit (AST::ClosureExprInner &);
- void visit (AST::BlockExpr &);
- void visit (AST::AnonConst &);
- void visit (AST::ConstBlock &);
- void visit (AST::ClosureExprInnerTyped &);
- void visit (AST::ContinueExpr &);
- void visit (AST::BreakExpr &);
- void visit (AST::RangeFromToExpr &);
- void visit (AST::RangeFromExpr &);
- void visit (AST::RangeToExpr &);
- void visit (AST::RangeFullExpr &);
- void visit (AST::RangeFromToInclExpr &);
- void visit (AST::RangeToInclExpr &);
- void visit (AST::BoxExpr &);
- void visit (AST::ReturnExpr &);
- void visit (AST::TryExpr &);
- void visit (AST::UnsafeBlockExpr &);
- void visit (AST::LoopExpr &);
- void visit (AST::WhileLoopExpr &);
- void visit (AST::WhileLetLoopExpr &);
- void visit (AST::ForLoopExpr &);
- void visit (AST::IfExpr &);
- void visit (AST::IfExprConseqElse &);
- void visit (AST::IfLetExpr &);
- void visit (AST::IfLetExprConseqElse &);
-
- void visit (AST::MatchExpr &);
- void visit (AST::AwaitExpr &);
- void visit (AST::AsyncBlockExpr &);
- void visit (AST::InlineAsm &);
- void visit (AST::LlvmInlineAsm &);
-
- void visit (AST::TypeParam &);
-
- void visit (AST::LifetimeWhereClauseItem &);
- void visit (AST::TypeBoundWhereClauseItem &);
- void visit (AST::Module &);
- void visit (AST::ExternCrate &);
-
- void visit (AST::UseTreeGlob &);
- void visit (AST::UseTreeList &);
- void visit (AST::UseTreeRebind &);
- void visit (AST::UseDeclaration &);
- void visit (AST::Function &);
- void visit (AST::TypeAlias &);
- void visit (AST::StructStruct &);
- void visit (AST::TupleStruct &);
- void visit (AST::EnumItem &);
- void visit (AST::EnumItemTuple &);
- void visit (AST::EnumItemStruct &);
- void visit (AST::EnumItemDiscriminant &);
- void visit (AST::Enum &);
- void visit (AST::Union &);
- void visit (AST::ConstantItem &);
- void visit (AST::StaticItem &);
- void visit (AST::TraitItemConst &);
- void visit (AST::TraitItemType &);
- void visit (AST::Trait &);
- void visit (AST::InherentImpl &);
- void visit (AST::TraitImpl &);
-
- void visit (AST::ExternalTypeItem &);
- void visit (AST::ExternalStaticItem &);
- void visit (AST::ExternBlock &);
-
- void visit (AST::MacroMatchFragment &);
- void visit (AST::MacroMatchRepetition &);
- void visit (AST::MacroMatcher &);
- void visit (AST::MacroRulesDefinition &);
- void visit (AST::MacroInvocation &);
- void visit (AST::MetaItemPath &);
- void visit (AST::MetaItemSeq &);
- void visit (AST::MetaWord &);
- void visit (AST::MetaNameValueStr &);
- void visit (AST::MetaListPaths &);
- void visit (AST::MetaListNameValueStr &);
-
- void visit (AST::LiteralPattern &);
- void visit (AST::IdentifierPattern &);
- void visit (AST::WildcardPattern &);
- void visit (AST::RestPattern &);
-
- void visit (AST::RangePatternBoundLiteral &);
- void visit (AST::RangePatternBoundPath &);
- void visit (AST::RangePatternBoundQualPath &);
- void visit (AST::RangePattern &);
- void visit (AST::ReferencePattern &);
-
- void visit (AST::StructPatternFieldTuplePat &);
- void visit (AST::StructPatternFieldIdentPat &);
- void visit (AST::StructPatternFieldIdent &);
- void visit (AST::StructPattern &);
-
- void visit (AST::TupleStructItemsNoRange &);
- void visit (AST::TupleStructItemsRange &);
- void visit (AST::TupleStructPattern &);
-
- void visit (AST::TuplePatternItemsMultiple &);
- void visit (AST::TuplePatternItemsRanged &);
- void visit (AST::TuplePattern &);
- void visit (AST::GroupedPattern &);
- void visit (AST::SlicePatternItemsNoRest &);
- void visit (AST::SlicePatternItemsHasRest &);
- void visit (AST::SlicePattern &);
- void visit (AST::AltPattern &);
-
- void visit (AST::EmptyStmt &);
- void visit (AST::LetStmt &);
- void visit (AST::ExprStmt &);
-
- void visit (AST::TraitBound &);
- void visit (AST::ImplTraitType &);
- void visit (AST::TraitObjectType &);
- void visit (AST::ParenthesisedType &);
- void visit (AST::ImplTraitTypeOneBound &);
- void visit (AST::TraitObjectTypeOneBound &);
- void visit (AST::TupleType &);
- void visit (AST::NeverType &);
- void visit (AST::RawPointerType &);
- void visit (AST::ReferenceType &);
- void visit (AST::ArrayType &);
- void visit (AST::SliceType &);
- void visit (AST::InferredType &);
- void visit (AST::BareFunctionType &);
- void visit (AST::FunctionParam &param);
- void visit (AST::VariadicParam &param);
- void visit (AST::SelfParam &param);
-
- void visit (AST::FormatArgs &fmt);
- void visit (AST::OffsetOf &offset_of);
-
-protected:
- ResolverBase ()
- : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ()),
- resolved_node (UNKNOWN_NODEID)
- {}
-
- /**
- * Resolve a visibility's path through the name resolver
- */
- bool resolve_visibility (const AST::Visibility &vis);
-
- Resolver *resolver;
- Analysis::Mappings &mappings;
- NodeId resolved_node;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_AST_RESOLVE_BASE_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
deleted file mode 100644
index a410193..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ /dev/null
@@ -1,816 +0,0 @@
-// Copyright (C) 2020-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-ast-resolve-expr.h"
-#include "rust-ast-resolve-stmt.h"
-#include "rust-ast-resolve-struct-expr-field.h"
-#include "rust-ast-resolve-type.h"
-#include "rust-ast-resolve-pattern.h"
-#include "rust-ast-resolve-path.h"
-#include "rust-expr.h"
-#include "rust-ice-finalizer.h"
-
-namespace Rust {
-namespace Resolver {
-
-void
-ResolveExpr::go (AST::Expr &expr, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix, bool funny_error)
-{
- ResolveExpr resolver (prefix, canonical_prefix, funny_error);
- expr.accept_vis (resolver);
-}
-
-void
-ResolveExpr::visit (AST::TupleIndexExpr &expr)
-{
- ResolveExpr::go (expr.get_tuple_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::TupleExpr &expr)
-{
- if (expr.is_unit ())
- return;
-
- for (auto &elem : expr.get_tuple_elems ())
- ResolveExpr::go (*elem, prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::PathInExpression &expr)
-{
- ResolvePath::go (expr);
-}
-
-void
-ResolveExpr::visit (AST::QualifiedPathInExpression &expr)
-{
- ResolvePath::go (expr);
-}
-
-void
-ResolveExpr::visit (AST::ReturnExpr &expr)
-{
- if (expr.has_returned_expr ())
- ResolveExpr::go (expr.get_returned_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::CallExpr &expr)
-{
- ResolveExpr::go (expr.get_function_expr (), prefix, canonical_prefix);
- for (auto &param : expr.get_params ())
- ResolveExpr::go (*param, prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::MethodCallExpr &expr)
-{
- ResolveExpr::go (expr.get_receiver_expr (), prefix, canonical_prefix);
-
- if (expr.get_method_name ().has_generic_args ())
- {
- AST::GenericArgs &args = expr.get_method_name ().get_generic_args ();
- ResolveGenericArgs::go (args, prefix, canonical_prefix);
- }
-
- auto const &in_params = expr.get_params ();
- for (auto &param : in_params)
- ResolveExpr::go (*param, prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::ErrorPropagationExpr &expr)
-{
- ResolveExpr::go (expr.get_propagating_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::AssignmentExpr &expr)
-{
- ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::IdentifierExpr &expr)
-{
- if (resolver->get_name_scope ().lookup (
- CanonicalPath::new_seg (expr.get_node_id (), expr.as_string ()),
- &resolved_node))
- {
- resolver->insert_resolved_name (expr.get_node_id (), resolved_node);
- }
- else if (resolver->get_type_scope ().lookup (
- CanonicalPath::new_seg (expr.get_node_id (), expr.as_string ()),
- &resolved_node))
- {
- resolver->insert_resolved_type (expr.get_node_id (), resolved_node);
- }
- else if (funny_error)
- {
- /* This was a "break rust" or "break gcc", and the identifier failed to
- resolve. Emit a funny ICE. We set the finalizer to our custom one,
- and use the lower-level emit_diagnostic () instead of the more common
- internal_error_no_backtrace () in order to pass our locus. */
- diagnostics::text_finalizer (global_dc) = funny_ice_text_finalizer;
- emit_diagnostic (diagnostics::kind::ice_nobt, expr.get_locus (), -1,
- "are you trying to break %s? how dare you?",
- expr.as_string ().c_str ());
- }
- else
- {
- rust_error_at (expr.get_locus (), ErrorCode::E0425,
- "cannot find value %qs in this scope",
- expr.as_string ().c_str ());
- }
-}
-
-void
-ResolveExpr::visit (AST::ArithmeticOrLogicalExpr &expr)
-{
- ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::CompoundAssignmentExpr &expr)
-{
- ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::ComparisonExpr &expr)
-{
- ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::LazyBooleanExpr &expr)
-{
- ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::NegationExpr &expr)
-{
- ResolveExpr::go (expr.get_negated_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::TypeCastExpr &expr)
-{
- ResolveType::go (expr.get_type_to_cast_to ());
- ResolveExpr::go (expr.get_casted_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::IfExpr &expr)
-{
- ResolveExpr::go (expr.get_condition_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::IfExprConseqElse &expr)
-{
- ResolveExpr::go (expr.get_condition_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_else_block (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::IfLetExpr &expr)
-{
- ResolveExpr::go (expr.get_value_expr (), prefix, canonical_prefix);
-
- NodeId scope_node_id = expr.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- resolver->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_label_scope ().peek ());
-
- // We know expr.get_patterns () has one pattern at most
- // so there's no reason to handle it like an AltPattern.
- std::vector<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- for (auto &pattern : expr.get_patterns ())
- {
- PatternDeclaration::go (*pattern, Rib::ItemType::Var, bindings);
- }
-
- ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix);
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveExpr::visit (AST::IfLetExprConseqElse &expr)
-{
- ResolveExpr::go (expr.get_value_expr (), prefix, canonical_prefix);
-
- NodeId scope_node_id = expr.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- resolver->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_label_scope ().peek ());
-
- // We know expr.get_patterns () has one pattern at most
- // so there's no reason to handle it like an AltPattern.
- std::vector<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- for (auto &pattern : expr.get_patterns ())
- {
- PatternDeclaration::go (*pattern, Rib::ItemType::Var, bindings);
- }
-
- ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_else_block (), prefix, canonical_prefix);
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveExpr::visit (AST::BlockExpr &expr)
-{
- NodeId scope_node_id = expr.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- resolver->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_label_scope ().peek ());
-
- if (expr.has_label ())
- {
- auto label = expr.get_label ();
- if (label.get_lifetime ().get_lifetime_type ()
- != AST::Lifetime::LifetimeType::NAMED)
- {
- rust_error_at (label.get_locus (),
- "Labels must be a named lifetime value");
- return;
- }
-
- auto label_name = label.get_lifetime ().get_lifetime_name ();
- auto label_lifetime_node_id = label.get_lifetime ().get_node_id ();
- resolver->get_label_scope ().insert (
- 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 defined multiple times");
- rust_error_at (locus, "was defined here");
- });
- }
-
- for (auto &s : expr.get_statements ())
- {
- if (s->is_item ())
- ResolveStmt::go (*s, prefix, canonical_prefix,
- CanonicalPath::create_empty ());
- }
-
- for (auto &s : expr.get_statements ())
- {
- if (!s->is_item ())
- ResolveStmt::go (*s, prefix, canonical_prefix,
- CanonicalPath::create_empty ());
- }
-
- if (expr.has_tail_expr ())
- ResolveExpr::go (expr.get_tail_expr (), prefix, canonical_prefix);
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveExpr::visit (AST::AnonConst &expr)
-{
- ResolveExpr::go (expr.get_inner_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::ConstBlock &expr)
-{
- ResolveExpr::go (expr.get_const_expr (), prefix, canonical_prefix);
-}
-
-void
-translate_operand (AST::InlineAsm &expr, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
-{
- const auto &operands = expr.get_operands ();
- using RegisterType = AST::InlineAsmOperand::RegisterType;
- for (auto &operand : operands)
- {
- switch (operand.get_register_type ())
- {
- case RegisterType::In:
- {
- auto in = operand.get_in ();
- ResolveExpr::go (*in.expr, prefix, canonical_prefix);
- break;
- }
- case RegisterType::Out:
- {
- auto out = operand.get_out ();
- ResolveExpr::go (*out.expr, prefix, canonical_prefix);
- break;
- }
- case RegisterType::InOut:
- {
- auto in_out = operand.get_in_out ();
- ResolveExpr::go (*in_out.expr, prefix, canonical_prefix);
- break;
- }
- case RegisterType::SplitInOut:
- {
- auto split_in_out = operand.get_split_in_out ();
- ResolveExpr::go (*split_in_out.in_expr, prefix, canonical_prefix);
- ResolveExpr::go (*split_in_out.out_expr, prefix, canonical_prefix);
- break;
- }
- case RegisterType::Const:
- {
- auto anon_const = operand.get_const ().anon_const;
- ResolveExpr::go (anon_const.get_inner_expr (), prefix,
- canonical_prefix);
- break;
- }
- case RegisterType::Sym:
- {
- auto sym = operand.get_sym ();
- ResolveExpr::go (*sym.expr, prefix, canonical_prefix);
- break;
- }
- case RegisterType::Label:
- {
- auto label = operand.get_label ();
- ResolveExpr::go (*label.expr, prefix, canonical_prefix);
- break;
- }
- }
- }
-}
-void
-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)
-{
- expr.get_block_expr ().accept_vis (*this);
-}
-
-void
-ResolveExpr::visit (AST::ArrayElemsValues &elems)
-{
- for (auto &elem : elems.get_values ())
- ResolveExpr::go (*elem, prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::ArrayExpr &expr)
-{
- expr.get_array_elems ()->accept_vis (*this);
-}
-
-void
-ResolveExpr::visit (AST::ArrayIndexExpr &expr)
-{
- ResolveExpr::go (expr.get_array_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_index_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::ArrayElemsCopied &expr)
-{
- ResolveExpr::go (expr.get_num_copies (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_elem_to_copy (), prefix, canonical_prefix);
-}
-
-// this this an empty struct constructor like 'S {}'
-void
-ResolveExpr::visit (AST::StructExprStruct &struct_expr)
-{
- ResolveExpr::go (struct_expr.get_struct_name (), prefix, canonical_prefix);
-}
-
-// this this a struct constructor with fields
-void
-ResolveExpr::visit (AST::StructExprStructFields &struct_expr)
-{
- ResolveExpr::go (struct_expr.get_struct_name (), prefix, canonical_prefix);
-
- if (struct_expr.has_struct_base ())
- {
- AST::StructBase &base = struct_expr.get_struct_base ();
- ResolveExpr::go (base.get_base_struct (), prefix, canonical_prefix);
- }
-
- auto const &struct_fields = struct_expr.get_fields ();
- for (auto &struct_field : struct_fields)
- {
- ResolveStructExprField::go (*struct_field, prefix, canonical_prefix);
- }
-}
-
-void
-ResolveExpr::visit (AST::GroupedExpr &expr)
-{
- ResolveExpr::go (expr.get_expr_in_parens (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::FieldAccessExpr &expr)
-{
- ResolveExpr::go (expr.get_receiver_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::LoopExpr &expr)
-{
- if (expr.has_loop_label ())
- {
- auto label = expr.get_loop_label ();
- if (label.get_lifetime ().get_lifetime_type ()
- != AST::Lifetime::LifetimeType::NAMED)
- {
- rust_error_at (label.get_locus (),
- "Labels must be a named lifetime value");
- return;
- }
-
- auto label_name = label.get_lifetime ().get_lifetime_name ();
- auto label_lifetime_node_id = label.get_lifetime ().get_node_id ();
- resolver->get_label_scope ().insert (
- 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 defined multiple times");
- rust_error_at (locus, "was defined here");
- });
- }
- ResolveExpr::go (expr.get_loop_block (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::BreakExpr &expr)
-{
- if (expr.has_label ())
- {
- auto label = expr.get_label_unchecked ().get_lifetime ();
- if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED)
- {
- rust_error_at (label.get_locus (),
- "Labels must be a named lifetime value");
- return;
- }
-
- NodeId resolved_node = UNKNOWN_NODEID;
- if (!resolver->get_label_scope ().lookup (
- CanonicalPath::new_seg (label.get_node_id (),
- label.get_lifetime_name ()),
- &resolved_node))
- {
- rust_error_at (label.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);
- }
-
- if (expr.has_break_expr ())
- {
- bool funny_error = false;
- 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 &> (break_expr).as_string ();
- if (ident == "rust" || ident == "gcc")
- funny_error = true;
- }
- ResolveExpr::go (break_expr, prefix, canonical_prefix, funny_error);
- }
-}
-
-void
-ResolveExpr::visit (AST::WhileLoopExpr &expr)
-{
- if (expr.has_loop_label ())
- {
- auto label = expr.get_loop_label ();
- if (label.get_lifetime ().get_lifetime_type ()
- != AST::Lifetime::LifetimeType::NAMED)
- {
- rust_error_at (label.get_locus (),
- "Labels must be a named lifetime value");
- return;
- }
-
- auto label_name = label.get_lifetime ().get_lifetime_name ();
- auto label_lifetime_node_id = label.get_lifetime ().get_node_id ();
- resolver->get_label_scope ().insert (
- 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 defined multiple times");
- rust_error_at (locus, "was defined here");
- });
- }
-
- ResolveExpr::go (expr.get_predicate_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_loop_block (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::ForLoopExpr &expr)
-{
- if (expr.has_loop_label ())
- {
- auto label = expr.get_loop_label ();
- if (label.get_lifetime ().get_lifetime_type ()
- != AST::Lifetime::LifetimeType::NAMED)
- {
- rust_error_at (label.get_locus (),
- "Labels must be a named lifetime value");
- return;
- }
-
- auto label_name = label.get_lifetime ().get_lifetime_name ();
- auto label_lifetime_node_id = label.get_lifetime ().get_node_id ();
- resolver->get_label_scope ().insert (
- 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 defined multiple times");
- rust_error_at (locus, "was defined here");
- });
- }
-
- // this needs a new rib to contain the pattern
- NodeId scope_node_id = expr.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- resolver->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_label_scope ().peek ());
-
- // resolve the expression
- PatternDeclaration::go (expr.get_pattern (), Rib::ItemType::Var);
- ResolveExpr::go (expr.get_iterator_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_loop_block (), prefix, canonical_prefix);
-
- // done
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveExpr::visit (AST::ContinueExpr &expr)
-{
- if (expr.has_label ())
- {
- auto label = expr.get_label_unchecked ();
- if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED)
- {
- rust_error_at (label.get_locus (),
- "Labels must be a named lifetime value");
- return;
- }
-
- NodeId resolved_node = UNKNOWN_NODEID;
- if (!resolver->get_label_scope ().lookup (
- CanonicalPath::new_seg (label.get_node_id (),
- label.get_lifetime_name ()),
- &resolved_node))
- {
- 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);
- }
-}
-
-void
-ResolveExpr::visit (AST::BorrowExpr &expr)
-{
- ResolveExpr::go (expr.get_borrowed_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::DereferenceExpr &expr)
-{
- ResolveExpr::go (expr.get_dereferenced_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::MatchExpr &expr)
-{
- ResolveExpr::go (expr.get_scrutinee_expr (), prefix, canonical_prefix);
- for (auto &match_case : expr.get_match_cases ())
- {
- // each arm is in its own scope
- NodeId scope_node_id = match_case.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- 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_label_scope ().peek ());
-
- // resolve
- AST::MatchArm &arm = match_case.get_arm ();
- if (arm.has_match_arm_guard ())
- ResolveExpr::go (arm.get_guard_expr (), prefix, canonical_prefix);
-
- // We know expr.get_patterns () has one pattern at most
- // so there's no reason to handle it like an AltPattern.
- std::vector<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- // insert any possible new patterns
- for (auto &pattern : arm.get_patterns ())
- {
- PatternDeclaration::go (*pattern, Rib::ItemType::Var, bindings);
- }
-
- // resolve the body
- ResolveExpr::go (match_case.get_expr (), prefix, canonical_prefix);
-
- // done
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
- }
-}
-
-void
-ResolveExpr::visit (AST::RangeFromToExpr &expr)
-{
- ResolveExpr::go (expr.get_from_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_to_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::RangeFromExpr &expr)
-{
- ResolveExpr::go (expr.get_from_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::RangeToExpr &expr)
-{
- ResolveExpr::go (expr.get_to_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::RangeFullExpr &)
-{
- // nothing to do
-}
-
-void
-ResolveExpr::visit (AST::RangeFromToInclExpr &expr)
-{
- ResolveExpr::go (expr.get_from_expr (), prefix, canonical_prefix);
- ResolveExpr::go (expr.get_to_expr (), prefix, canonical_prefix);
-}
-
-void
-ResolveExpr::visit (AST::ClosureExprInner &expr)
-{
- NodeId scope_node_id = expr.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- resolver->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_label_scope ().peek ());
-
- std::vector<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- for (auto &p : expr.get_params ())
- {
- resolve_closure_param (p, bindings);
- }
-
- resolver->push_closure_context (expr.get_node_id ());
-
- ResolveExpr::go (expr.get_definition_expr (), prefix, canonical_prefix);
-
- resolver->pop_closure_context ();
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveExpr::visit (AST::ClosureExprInnerTyped &expr)
-{
- NodeId scope_node_id = expr.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- resolver->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_label_scope ().peek ());
-
- std::vector<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- for (auto &p : expr.get_params ())
- {
- resolve_closure_param (p, bindings);
- }
-
- ResolveType::go (expr.get_return_type ());
-
- resolver->push_closure_context (expr.get_node_id ());
-
- ResolveExpr::go (expr.get_definition_expr (), prefix, canonical_prefix);
-
- resolver->pop_closure_context ();
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveExpr::resolve_closure_param (AST::ClosureParam &param,
- std::vector<PatternBinding> &bindings)
-{
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, bindings);
-
- if (param.has_type_given ())
- ResolveType::go (param.get_type ());
-}
-
-ResolveExpr::ResolveExpr (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix,
- bool funny_error)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix),
- funny_error (funny_error)
-{}
-
-} // namespace Resolver
-} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
deleted file mode 100644
index aad1605..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_EXPR_H
-#define RUST_AST_RESOLVE_EXPR_H
-
-#include "rust-ast-resolve-base.h"
-#include "rust-ast.h"
-#include "rust-ast-resolve-pattern.h"
-#include "rust-expr.h"
-
-namespace Rust {
-namespace Resolver {
-
-class ResolveExpr : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::Expr &expr, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix,
- bool funny_error = false);
-
- void visit (AST::TupleIndexExpr &expr) override;
- void visit (AST::TupleExpr &expr) override;
- void visit (AST::PathInExpression &expr) override;
- void visit (AST::QualifiedPathInExpression &expr) override;
- void visit (AST::ReturnExpr &expr) override;
- void visit (AST::CallExpr &expr) override;
- void visit (AST::MethodCallExpr &expr) override;
- void visit (AST::AssignmentExpr &expr) override;
- void visit (AST::IdentifierExpr &expr) override;
- void visit (AST::ArithmeticOrLogicalExpr &expr) override;
- void visit (AST::CompoundAssignmentExpr &expr) override;
- void visit (AST::ComparisonExpr &expr) override;
- void visit (AST::LazyBooleanExpr &expr) override;
- void visit (AST::NegationExpr &expr) override;
- void visit (AST::TypeCastExpr &expr) override;
- void visit (AST::IfExpr &expr) override;
- void visit (AST::IfExprConseqElse &expr) override;
- void visit (AST::IfLetExpr &expr) override;
- void visit (AST::IfLetExprConseqElse &expr) override;
- void visit (AST::BlockExpr &expr) override;
- void visit (AST::AnonConst &expr) override;
- void visit (AST::ConstBlock &expr) override;
- void visit (AST::InlineAsm &expr) override;
- void visit (AST::LlvmInlineAsm &expr) override;
- void visit (AST::UnsafeBlockExpr &expr) override;
- void visit (AST::ArrayElemsValues &elems) override;
- void visit (AST::ArrayExpr &expr) override;
- void visit (AST::ArrayIndexExpr &expr) override;
- void visit (AST::ArrayElemsCopied &elems) override;
- void visit (AST::StructExprStruct &struct_expr) override;
- void visit (AST::StructExprStructFields &struct_expr) override;
- void visit (AST::GroupedExpr &expr) override;
- void visit (AST::FieldAccessExpr &expr) override;
- void visit (AST::LoopExpr &expr) override;
- void visit (AST::BreakExpr &expr) override;
- void visit (AST::WhileLoopExpr &expr) override;
- void visit (AST::ForLoopExpr &expr) override;
- void visit (AST::ContinueExpr &expr) override;
- void visit (AST::BorrowExpr &expr) override;
- void visit (AST::DereferenceExpr &expr) override;
- void visit (AST::MatchExpr &expr) override;
- void visit (AST::RangeFromToExpr &expr) override;
- void visit (AST::RangeFromExpr &expr) override;
- void visit (AST::RangeToExpr &expr) override;
- void visit (AST::RangeFullExpr &expr) override;
- void visit (AST::RangeFromToInclExpr &expr) override;
- void visit (AST::ClosureExprInner &expr) override;
- void visit (AST::ClosureExprInnerTyped &expr) override;
- void visit (AST::ErrorPropagationExpr &expr) override;
-
-protected:
- void resolve_closure_param (AST::ClosureParam &param,
- std::vector<PatternBinding> &bindings);
-
-private:
- ResolveExpr (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix, bool funny_error);
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
- bool funny_error;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_AST_RESOLVE_EXPR_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
deleted file mode 100644
index 2081697..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_IMPLITEM_H
-#define RUST_AST_RESOLVE_IMPLITEM_H
-
-#include "rust-ast-resolve-base.h"
-#include "rust-ast-resolve-type.h"
-#include "rust-ast-full.h"
-
-namespace Rust {
-namespace Resolver {
-
-class ResolveToplevelImplItem : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::AssociatedItem &item, const CanonicalPath &prefix)
- {
- if (item.is_marked_for_strip ())
- return;
-
- ResolveToplevelImplItem resolver (prefix);
- item.accept_vis (resolver);
- }
-
- void visit (AST::TypeAlias &type) override
- {
- auto decl = CanonicalPath::new_seg (type.get_node_id (),
- type.get_new_type_name ().as_string ());
- auto path = prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, type.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
- }
-
- void visit (AST::ConstantItem &constant) override
- {
- auto decl = CanonicalPath::new_seg (constant.get_node_id (),
- constant.get_identifier ());
- auto path = prefix.append (decl);
-
- resolver->get_name_scope ().insert (
- path, constant.get_node_id (), constant.get_locus (), false,
- Rib::ItemType::Const,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, constant.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
- }
-
- void visit (AST::Function &function) override
- {
- auto decl
- = CanonicalPath::new_seg (function.get_node_id (),
- function.get_function_name ().as_string ());
- auto path = prefix.append (decl);
-
- resolver->get_name_scope ().insert (
- path, function.get_node_id (), function.get_locus (), false,
- Rib::ItemType::Function,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, function.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
- }
-
-private:
- ResolveToplevelImplItem (const CanonicalPath &prefix)
- : ResolverBase (), prefix (prefix)
- {
- rust_assert (!prefix.is_empty ());
- }
-
- const CanonicalPath &prefix;
-};
-
-class ResolveTopLevelTraitItems : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::AssociatedItem *item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- {
- ResolveTopLevelTraitItems resolver (prefix, canonical_prefix);
- item->accept_vis (resolver);
- };
-
- void visit (AST::Function &function) override
- {
- auto decl
- = CanonicalPath::new_seg (function.get_node_id (),
- function.get_function_name ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_name_scope ().insert (
- path, function.get_node_id (), function.get_locus (), false,
- Rib::ItemType::Function,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, function.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- mappings.insert_canonical_path (function.get_node_id (), cpath);
- }
-
- void visit (AST::TraitItemConst &constant) override
- {
- auto decl
- = CanonicalPath::new_seg (constant.get_node_id (),
- constant.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_name_scope ().insert (
- path, constant.get_node_id (), constant.get_locus (), false,
- Rib::ItemType::Const,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, constant.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- mappings.insert_canonical_path (constant.get_node_id (), cpath);
- }
-
- void visit (AST::TraitItemType &type) override
- {
- auto decl = CanonicalPath::new_seg (type.get_node_id (),
- type.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, type.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- mappings.insert_canonical_path (type.get_node_id (), cpath);
- }
-
-private:
- ResolveTopLevelTraitItems (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
- {}
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-};
-
-class ResolveToplevelExternItem : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::ExternalItem &item, const CanonicalPath &prefix)
- {
- ResolveToplevelExternItem resolver (prefix);
- item.accept_vis (resolver);
- };
-
- void visit (AST::Function &function) override
- {
- auto decl
- = CanonicalPath::new_seg (function.get_node_id (),
- function.get_function_name ().as_string ());
- auto path = prefix.append (decl);
-
- resolver->get_name_scope ().insert (
- path, function.get_node_id (), function.get_locus (), false,
- Rib::ItemType::Function,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, function.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- }
-
- void visit (AST::ExternalStaticItem &item) override
- {
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
-
- resolver->get_name_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false,
- Rib::ItemType::Static,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- }
-
- void visit (AST::ExternalTypeItem &type) override
- {
- auto decl = CanonicalPath::new_seg (type.get_node_id (),
- type.get_identifier ().as_string ());
- auto path = prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, type.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- }
-
-private:
- ResolveToplevelExternItem (const CanonicalPath &prefix)
- : ResolverBase (), prefix (prefix)
- {}
-
- const CanonicalPath &prefix;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_AST_RESOLVE_IMPLITEM_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
deleted file mode 100644
index 1d5ebed..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ /dev/null
@@ -1,1247 +0,0 @@
-// Copyright (C) 2020-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-ast-resolve-item.h"
-#include "rust-ast-full-decls.h"
-#include "rust-ast-resolve-toplevel.h"
-#include "rust-ast-resolve-type.h"
-#include "rust-ast-resolve-pattern.h"
-#include "rust-ast-resolve-path.h"
-
-#include "rust-item.h"
-#include "selftest.h"
-
-namespace Rust {
-namespace Resolver {
-
-ResolveTraitItems::ResolveTraitItems (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
-{}
-
-void
-ResolveTraitItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
-{
- if (item->is_marked_for_strip ())
- return;
-
- ResolveTraitItems resolver (prefix, canonical_prefix);
- item->accept_vis (resolver);
-}
-
-void
-ResolveTraitItems::visit (AST::Function &function)
-{
- auto decl
- = CanonicalPath::new_seg (function.get_node_id (),
- function.get_function_name ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (function.get_node_id (), cpath);
-
- NodeId scope_node_id = function.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- 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_label_scope ().peek ());
-
- if (function.has_generics ())
- ResolveGenericParams::go (function.get_generic_params (), prefix,
- canonical_prefix);
-
- if (function.has_return_type ())
- ResolveType::go (function.get_return_type ());
-
- // self turns into (self: Self) as a function param
- std::vector<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- // we make a new scope so the names of parameters are resolved and shadowed
- // correctly
- for (auto &p : function.get_function_params ())
- {
- if (p->is_variadic ())
- {
- auto param = static_cast<AST::VariadicParam &> (*p);
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
- bindings);
- }
- else if (p->is_self ())
- {
- auto &param = static_cast<AST::SelfParam &> (*p);
- // FIXME: which location should be used for Rust::Identifier `self`?
- AST::IdentifierPattern self_pattern (
- param.get_node_id (), {"self"}, param.get_locus (),
- param.get_has_ref (), param.get_is_mut (),
- std::unique_ptr<AST::Pattern> (nullptr));
-
- PatternDeclaration::go (self_pattern, Rib::ItemType::Param);
-
- if (param.has_type ())
- {
- // This shouldn't happen the parser should already error for this
- rust_assert (!param.get_has_ref ());
- ResolveType::go (param.get_type ());
- }
- else
- {
- // here we implicitly make self have a type path of Self
- std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<AST::TypePathSegment> (
- new AST::TypePathSegment ("Self", false, param.get_locus ())));
-
- AST::TypePath self_type_path (std::move (segments),
- param.get_locus ());
- ResolveType::go (self_type_path);
- }
- }
- else
- {
- auto &param = static_cast<AST::FunctionParam &> (*p);
- ResolveType::go (param.get_type ());
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
- bindings);
- }
- }
-
- if (function.has_where_clause ())
- ResolveWhereClause::Resolve (function.get_where_clause ());
-
- // trait items have an optional body
- if (function.has_body ())
- ResolveExpr::go (*function.get_definition ().value (), path, cpath);
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-void
-ResolveTraitItems::visit (AST::TraitItemType &type)
-{
- auto decl = CanonicalPath::new_seg (type.get_node_id (),
- type.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (type.get_node_id (), cpath);
-
- for (auto &bound : type.get_type_param_bounds ())
- ResolveTypeBound::go (*bound);
-}
-
-void
-ResolveTraitItems::visit (AST::TraitItemConst &constant)
-{
- auto decl = CanonicalPath::new_seg (constant.get_node_id (),
- constant.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (constant.get_node_id (), cpath);
-
- ResolveType::go (constant.get_type ());
-
- if (constant.has_expr ())
- ResolveExpr::go (constant.get_expr (), path, cpath);
-}
-
-ResolveItem::ResolveItem (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
-{}
-
-void
-ResolveItem::go (AST::Item &item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
-{
- ResolveItem resolver (prefix, canonical_prefix);
- item.accept_vis (resolver);
-}
-
-void
-ResolveItem::visit (AST::TypeAlias &alias)
-{
- auto talias
- = CanonicalPath::new_seg (alias.get_node_id (),
- alias.get_new_type_name ().as_string ());
- auto path = prefix.append (talias);
- auto cpath = canonical_prefix.append (talias);
- mappings.insert_canonical_path (alias.get_node_id (), cpath);
-
- NodeId scope_node_id = alias.get_node_id ();
- resolver->get_type_scope ().push (scope_node_id);
-
- if (alias.has_generics ())
- ResolveGenericParams::go (alias.get_generic_params (), prefix,
- canonical_prefix);
-
- if (alias.has_where_clause ())
- ResolveWhereClause::Resolve (alias.get_where_clause ());
-
- ResolveType::go (alias.get_type_aliased ());
-
- resolver->get_type_scope ().pop ();
-}
-
-void
-ResolveItem::visit (AST::Module &module)
-{
- auto mod = CanonicalPath::new_seg (module.get_node_id (),
- module.get_name ().as_string ());
- auto path = prefix.append (mod);
- auto cpath = canonical_prefix.append (mod);
- mappings.insert_canonical_path (module.get_node_id (), cpath);
-
- resolve_visibility (module.get_visibility ());
-
- NodeId scope_node_id = module.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- 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_label_scope ().peek ());
-
- // FIXME: Should we reinsert a child here? Any reason we ResolveTopLevel::go
- // in ResolveTopLevel::visit (AST::Module) as well as here?
- for (auto &item : module.get_items ())
- ResolveTopLevel::go (*item, CanonicalPath::create_empty (), cpath);
-
- resolver->push_new_module_scope (module.get_node_id ());
- for (auto &item : module.get_items ())
- ResolveItem::go (*item, path, cpath);
-
- resolver->pop_module_scope ();
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveItem::visit (AST::TupleStruct &struct_decl)
-{
- auto decl
- = CanonicalPath::new_seg (struct_decl.get_node_id (),
- struct_decl.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
-
- resolve_visibility (struct_decl.get_visibility ());
-
- NodeId scope_node_id = struct_decl.get_node_id ();
- resolver->get_type_scope ().push (scope_node_id);
-
- if (struct_decl.has_generics ())
- ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
- canonical_prefix);
-
- if (struct_decl.has_where_clause ())
- ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
-
- for (AST::TupleField &field : struct_decl.get_fields ())
- {
- if (field.get_field_type ().is_marked_for_strip ())
- continue;
-
- resolve_visibility (field.get_visibility ());
-
- ResolveType::go (field.get_field_type ());
- }
-
- resolver->get_type_scope ().pop ();
-}
-
-void
-ResolveItem::visit (AST::Enum &enum_decl)
-{
- auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (),
- enum_decl.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (enum_decl.get_node_id (), cpath);
-
- resolve_visibility (enum_decl.get_visibility ());
-
- NodeId scope_node_id = enum_decl.get_node_id ();
- resolver->get_type_scope ().push (scope_node_id);
-
- if (enum_decl.has_generics ())
- ResolveGenericParams::go (enum_decl.get_generic_params (), prefix,
- canonical_prefix);
-
- if (enum_decl.has_where_clause ())
- ResolveWhereClause::Resolve (enum_decl.get_where_clause ());
-
- /* The actual fields are inside the variants. */
- for (auto &variant : enum_decl.get_variants ())
- ResolveItem::go (*variant, path, cpath);
-
- resolver->get_type_scope ().pop ();
-}
-
-/* EnumItem doesn't need to be handled, no fields. */
-void
-ResolveItem::visit (AST::EnumItem &item)
-{
- // Since at this point we cannot have visibilities on enum items anymore, we
- // can skip handling them
-
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-}
-
-void
-ResolveItem::visit (AST::EnumItemTuple &item)
-{
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- for (auto &field : item.get_tuple_fields ())
- {
- if (field.get_field_type ().is_marked_for_strip ())
- continue;
-
- ResolveType::go (field.get_field_type ());
- }
-}
-
-void
-ResolveItem::visit (AST::EnumItemStruct &item)
-{
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- for (auto &field : item.get_struct_fields ())
- {
- if (field.get_field_type ().is_marked_for_strip ())
- continue;
-
- ResolveType::go (field.get_field_type ());
- }
-}
-
-void
-ResolveItem::visit (AST::EnumItemDiscriminant &item)
-{
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- ResolveExpr::go (item.get_expr (), path, cpath);
-}
-
-void
-ResolveItem::visit (AST::StructStruct &struct_decl)
-{
- auto decl
- = CanonicalPath::new_seg (struct_decl.get_node_id (),
- struct_decl.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
-
- resolve_visibility (struct_decl.get_visibility ());
-
- NodeId scope_node_id = struct_decl.get_node_id ();
- resolver->get_type_scope ().push (scope_node_id);
-
- if (struct_decl.has_generics ())
- ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
- canonical_prefix);
-
- if (struct_decl.has_where_clause ())
- ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
-
- for (AST::StructField &field : struct_decl.get_fields ())
- {
- if (field.get_field_type ().is_marked_for_strip ())
- continue;
-
- resolve_visibility (field.get_visibility ());
-
- ResolveType::go (field.get_field_type ());
- }
-
- resolver->get_type_scope ().pop ();
-}
-
-void
-ResolveItem::visit (AST::Union &union_decl)
-{
- auto decl
- = CanonicalPath::new_seg (union_decl.get_node_id (),
- union_decl.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (union_decl.get_node_id (), cpath);
-
- resolve_visibility (union_decl.get_visibility ());
-
- NodeId scope_node_id = union_decl.get_node_id ();
- resolver->get_type_scope ().push (scope_node_id);
-
- if (union_decl.has_generics ())
- ResolveGenericParams::go (union_decl.get_generic_params (), prefix,
- canonical_prefix);
-
- if (union_decl.has_where_clause ())
- ResolveWhereClause::Resolve (union_decl.get_where_clause ());
-
- for (AST::StructField &field : union_decl.get_variants ())
- {
- if (field.get_field_type ().is_marked_for_strip ())
- continue;
-
- ResolveType::go (field.get_field_type ());
- }
-
- resolver->get_type_scope ().pop ();
-}
-
-void
-ResolveItem::visit (AST::StaticItem &var)
-{
- auto decl = CanonicalPath::new_seg (var.get_node_id (),
- var.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (var.get_node_id (), cpath);
-
- ResolveType::go (var.get_type ());
- ResolveExpr::go (var.get_expr (), path, cpath);
-}
-
-void
-ResolveItem::visit (AST::ConstantItem &constant)
-{
- auto decl = CanonicalPath::new_seg (constant.get_node_id (),
- constant.get_identifier ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (constant.get_node_id (), cpath);
-
- resolve_visibility (constant.get_visibility ());
-
- ResolveType::go (constant.get_type ());
- if (constant.has_expr ())
- ResolveExpr::go (constant.get_expr (), path, cpath);
-}
-
-void
-ResolveItem::visit (AST::Function &function)
-{
- auto decl
- = CanonicalPath::new_seg (function.get_node_id (),
- function.get_function_name ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- mappings.insert_canonical_path (function.get_node_id (), cpath);
-
- resolve_visibility (function.get_visibility ());
-
- NodeId scope_node_id = function.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- 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_label_scope ().peek ());
-
- if (function.has_generics ())
- ResolveGenericParams::go (function.get_generic_params (), prefix,
- canonical_prefix);
-
- // resolve any where clause items
- if (function.has_where_clause ())
- ResolveWhereClause::Resolve (function.get_where_clause ());
-
- if (function.has_return_type ())
- ResolveType::go (function.get_return_type ());
-
- if (function.has_self_param ())
- {
- // self turns into (self: Self) as a function param
- AST::Param &s_param = function.get_self_param ();
- auto &self_param = static_cast<AST::SelfParam &> (s_param);
-
- // FIXME: which location should be used for Rust::Identifier `self`?
- AST::IdentifierPattern self_pattern (
- self_param.get_node_id (), {"self"}, self_param.get_locus (),
- self_param.get_has_ref (), self_param.get_is_mut (),
- std::unique_ptr<AST::Pattern> (nullptr));
- PatternDeclaration::go (self_pattern, Rib::ItemType::Param);
-
- if (self_param.has_type ())
- {
- // This shouldn't happen the parser should already error for this
- rust_assert (!self_param.get_has_ref ());
- ResolveType::go (self_param.get_type ());
- }
- else
- {
- // here we implicitly make self have a type path of Self
- std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<AST::TypePathSegment> (
- new AST::TypePathSegment ("Self", false, self_param.get_locus ())));
-
- AST::TypePath self_type_path (std::move (segments),
- self_param.get_locus ());
- ResolveType::go (self_type_path);
- }
- }
-
- std::vector<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- // we make a new scope so the names of parameters are resolved and shadowed
- // correctly
- for (auto &p : function.get_function_params ())
- {
- if (p->is_variadic ())
- {
- auto &param = static_cast<AST::VariadicParam &> (*p);
- if (param.has_pattern ())
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
- bindings);
- }
- else if (p->is_self ())
- {
- auto &param = static_cast<AST::SelfParam &> (*p);
- if (param.has_type ())
- ResolveType::go (param.get_type ());
- }
- else
- {
- auto &param = static_cast<AST::FunctionParam &> (*p);
- ResolveType::go (param.get_type ());
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
- bindings);
- }
- }
-
- // resolve the function body
- ResolveExpr::go (*function.get_definition ().value (), path, cpath);
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveItem::visit (AST::InherentImpl &impl_block)
-{
- NodeId scope_node_id = impl_block.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
- resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-
- resolve_visibility (impl_block.get_visibility ());
-
- if (impl_block.has_generics ())
- ResolveGenericParams::go (impl_block.get_generic_params (), prefix,
- canonical_prefix);
-
- // resolve any where clause items
- if (impl_block.has_where_clause ())
- ResolveWhereClause::Resolve (impl_block.get_where_clause ());
-
- // FIXME this needs to be protected behind nominal type-checks see:
- // rustc --explain E0118
- // issue #2634
- ResolveType::go (impl_block.get_type ());
-
- // Setup paths
- CanonicalPath self_cpath = CanonicalPath::create_empty ();
- bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_type (), self_cpath);
- 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 ());
-
- CanonicalPath impl_type = self_cpath;
- CanonicalPath impl_type_seg
- = CanonicalPath::inherent_impl_seg (impl_block.get_node_id (), impl_type);
- CanonicalPath impl_prefix = prefix.append (impl_type_seg);
-
- // see https://godbolt.org/z/a3vMbsT6W
- CanonicalPath cpath = CanonicalPath::create_empty ();
- if (canonical_prefix.size () <= 1)
- {
- cpath = impl_prefix;
- }
- else
- {
- cpath = canonical_prefix.append (impl_type_seg);
- }
-
- // done setup paths
-
- auto Self
- = CanonicalPath::get_big_self (impl_block.get_type ().get_node_id ());
-
- resolver->get_type_scope ().insert (Self,
- impl_block.get_type ().get_node_id (),
- impl_block.get_type ().get_locus ());
-
- for (auto &impl_item : impl_block.get_impl_items ())
- {
- rust_debug (
- "AST::InherentImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
- impl_prefix.get ().c_str (), cpath.get ().c_str ());
- resolve_impl_item (*impl_item, impl_prefix, cpath);
- }
-
- resolver->get_type_scope ().peek ()->clear_name (
- Self, impl_block.get_type ().get_node_id ());
-
- resolver->get_type_scope ().pop ();
- resolver->get_name_scope ().pop ();
-}
-
-void
-ResolveItem::visit (AST::TraitImpl &impl_block)
-{
- NodeId scope_node_id = impl_block.get_node_id ();
-
- resolve_visibility (impl_block.get_visibility ());
-
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- 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_label_scope ().peek ());
-
- if (impl_block.has_generics ())
- ResolveGenericParams::go (impl_block.get_generic_params (), prefix,
- canonical_prefix);
-
- // resolve any where clause items
- if (impl_block.has_where_clause ())
- ResolveWhereClause::Resolve (impl_block.get_where_clause ());
-
- // CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
- NodeId trait_resolved_node = ResolveType::go (impl_block.get_trait_path ());
- if (trait_resolved_node == UNKNOWN_NODEID)
- {
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
- return;
- }
-
- // CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
- NodeId type_resolved_node = ResolveType::go (impl_block.get_type ());
- if (type_resolved_node == UNKNOWN_NODEID)
- {
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
- return;
- }
-
- bool ok = true;
-
- // setup paths
- CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
-
- ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path (),
- canonical_trait_type);
- 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 ());
-
- CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
- ok = ResolveTypeToCanonicalPath::go (impl_block.get_type (),
- canonical_impl_type);
- 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 ());
-
- // raw paths
- CanonicalPath impl_type_seg = canonical_impl_type;
- CanonicalPath trait_type_seg = canonical_trait_type;
- CanonicalPath projection
- = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
- trait_type_seg, impl_type_seg);
- CanonicalPath impl_prefix = prefix.append (projection);
-
- // setup canonical-path
- CanonicalPath canonical_projection
- = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
- canonical_trait_type,
- canonical_impl_type);
- CanonicalPath cpath = CanonicalPath::create_empty ();
- if (canonical_prefix.size () <= 1)
- {
- cpath = canonical_projection;
- }
- else
- {
- cpath = canonical_prefix.append (canonical_projection);
- }
-
- // DONE setup canonical-path
-
- auto Self
- = CanonicalPath::get_big_self (impl_block.get_type ().get_node_id ());
-
- resolver->get_type_scope ().insert (Self,
- impl_block.get_type ().get_node_id (),
- impl_block.get_type ().get_locus ());
-
- for (auto &impl_item : impl_block.get_impl_items ())
- {
- rust_debug (
- "AST::TraitImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
- impl_prefix.get ().c_str (), cpath.get ().c_str ());
- resolve_impl_item (*impl_item, impl_prefix, cpath);
- }
-
- Rib *r = resolver->get_type_scope ().peek ();
- r->clear_name (Self, impl_block.get_type ().get_node_id ());
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveItem::visit (AST::Trait &trait)
-{
- NodeId scope_node_id = trait.get_node_id ();
-
- resolve_visibility (trait.get_visibility ());
-
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
- resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-
- 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 (
- trait.get_node_id (), trait.get_implicit_self ().get_node_id ());
-
- if (trait.has_type_param_bounds ())
- {
- for (auto &bound : trait.get_type_param_bounds ())
- {
- ResolveTypeBound::go (*bound);
- }
- }
-
- // resolve any where clause items
- if (trait.has_where_clause ())
- ResolveWhereClause::Resolve (trait.get_where_clause ());
-
- // resolve the paths
- CanonicalPath path = CanonicalPath::create_empty ();
- CanonicalPath cpath = CanonicalPath::create_empty ();
- //
-
- for (auto &item : trait.get_trait_items ())
- {
- ResolveTraitItems::go (item.get (), path, cpath);
- }
-
- resolver->get_type_scope ().pop ();
- resolver->get_name_scope ().pop ();
-}
-
-void
-ResolveItem::visit (AST::ExternBlock &extern_block)
-{
- resolve_visibility (extern_block.get_visibility ());
-
- for (auto &item : extern_block.get_extern_items ())
- {
- resolve_extern_item (*item);
- }
-}
-
-void
-ResolveItem::resolve_impl_item (AST::AssociatedItem &item,
- const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
-{
- ResolveImplItems::go (item, prefix, canonical_prefix);
-}
-
-void
-ResolveItem::resolve_extern_item (AST::ExternalItem &item)
-{
- ResolveExternItem::go (item, prefix, canonical_prefix);
-}
-
-static void flatten_glob (const AST::UseTreeGlob &glob,
- std::vector<Import> &imports);
-static void flatten_rebind (const AST::UseTreeRebind &glob,
- std::vector<Import> &imports);
-static void flatten_list (const AST::UseTreeList &glob,
- std::vector<Import> &imports);
-
-static void
-flatten (const AST::UseTree *tree, std::vector<Import> &imports)
-{
- switch (tree->get_kind ())
- {
- case AST::UseTree::Glob:
- {
- auto glob = static_cast<const AST::UseTreeGlob *> (tree);
- flatten_glob (*glob, imports);
- break;
- }
- case AST::UseTree::Rebind:
- {
- auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
- flatten_rebind (*rebind, imports);
- break;
- }
- case AST::UseTree::List:
- {
- auto list = static_cast<const AST::UseTreeList *> (tree);
- flatten_list (*list, imports);
- break;
- }
- break;
- }
-}
-
-static void
-flatten_glob (const AST::UseTreeGlob &glob, std::vector<Import> &imports)
-{
- if (glob.has_path ())
- imports.emplace_back (glob.get_path (), true, std::string ());
-}
-
-static void
-flatten_rebind (const AST::UseTreeRebind &rebind, std::vector<Import> &imports)
-{
- auto path = rebind.get_path ();
-
- std::string label;
- if (rebind.has_identifier ())
- label = rebind.get_identifier ().as_string ();
- else
- label = path.get_final_segment ().as_string ();
-
- imports.emplace_back (path, false, label);
-}
-
-static void
-flatten_list (const AST::UseTreeList &list, std::vector<Import> &imports)
-{
- auto prefix = AST::SimplePath::create_empty ();
- if (list.has_path ())
- prefix = list.get_path ();
-
- for (const auto &tree : list.get_trees ())
- {
- // append imports to the main list, then modify them in-place
- auto start_idx = imports.size ();
- flatten (tree.get (), imports);
-
- for (auto import = imports.begin () + start_idx; import != imports.end ();
- import++)
- {
- // 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));
- }
- }
-}
-
-void
-Import::add_prefix (AST::SimplePath prefix)
-{
- AST::SimplePath old_path (std::move (path));
- path = std::move (prefix);
- std::move (old_path.get_segments ().begin (), old_path.get_segments ().end (),
- std::back_inserter (path.get_segments ()));
-}
-
-/**
- * Flatten a UseDeclaration's UseTree into multiple simple paths to resolve.
- *
- * Given the following use declarations:
- * ```
- * use some::path::to_resolve; #1
- * use some::path::to_glob::*; #2
- * use some::path::{one, two}; #2
- * ```
- *
- * In the first case, we simply want to return a vector with a single
- * SimplePath:
- * [some::path::to_resolve]
- *
- * In the second case, we want to resolve the glob's "origin path":
- * [some::path::to_glob]
- *
- * Finally in the third case, we want to create two SimplePaths to resolve:
- * [some::path::one, some::path::two]
- */
-static std::vector<Import>
-flatten_use_dec_to_imports (const AST::UseDeclaration &use_item)
-{
- auto imports = std::vector<Import> ();
-
- const auto &tree = use_item.get_tree ();
- flatten (tree.get (), imports);
-
- return imports;
-}
-
-void
-ResolveItem::visit (AST::UseDeclaration &use_item)
-{
- std::vector<Import> to_resolve = flatten_use_dec_to_imports (use_item);
-
- // FIXME: I think this does not actually resolve glob use-decls and is going
- // the wrong way about it. RFC #1560 specifies the following:
- //
- // > When we find a glob import, we have to record a 'back link', so that when
- // a public name is added for the supplying module, we can add it for the
- // importing module.
- //
- // Which is the opposite of what we're doing if I understand correctly?
-
- NodeId current_module = resolver->peek_current_module_scope ();
- for (auto &import : to_resolve)
- {
- auto &path = import.get_path ();
-
- rust_debug ("resolving use-decl path: [%s]", path.as_string ().c_str ());
- NodeId resolved_node_id = ResolvePath::go (path);
- bool ok = resolved_node_id != UNKNOWN_NODEID;
- if (!ok)
- continue;
-
- if (import.is_glob ())
- continue;
-
- auto decl = CanonicalPath::new_seg (resolved_node_id, import.get_name ());
- mappings.insert_module_child_item (current_module, decl);
-
- resolver->get_type_scope ().insert (decl, resolved_node_id,
- path.get_locus (),
- Rib::ItemType::Type);
- rust_debug ("use-decl rexporting: [%s]", decl.get ().c_str ());
- }
-}
-
-ResolveImplItems::ResolveImplItems (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolveItem (prefix, canonical_prefix)
-{}
-
-void
-ResolveImplItems::go (AST::AssociatedItem &item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
-{
- if (item.is_marked_for_strip ())
- return;
-
- ResolveImplItems resolver (prefix, canonical_prefix);
- item.accept_vis (resolver);
-}
-
-void
-ResolveImplItems::visit (AST::TypeAlias &alias)
-{
- ResolveItem::visit (alias);
-
- resolve_visibility (alias.get_visibility ());
-
- // FIXME this stops the erronious unused decls which will be fixed later on
- resolver->get_type_scope ().append_reference_for_def (alias.get_node_id (),
- alias.get_node_id ());
-}
-
-void
-ResolveExternItem::go (AST::ExternalItem &item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
-{
- ResolveExternItem resolver (prefix, canonical_prefix);
- item.accept_vis (resolver);
-}
-
-void
-ResolveExternItem::visit (AST::Function &function)
-{
- NodeId scope_node_id = function.get_node_id ();
- auto decl
- = CanonicalPath::new_seg (function.get_node_id (),
- function.get_function_name ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- mappings.insert_canonical_path (function.get_node_id (), cpath);
-
- resolve_visibility (function.get_visibility ());
-
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- 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_label_scope ().peek ());
-
- // resolve the generics
- if (function.has_generics ())
- ResolveGenericParams::go (function.get_generic_params (), prefix,
- canonical_prefix);
-
- if (function.has_return_type ())
- ResolveType::go (function.get_return_type ());
-
- // we make a new scope so the names of parameters are resolved and shadowed
- // correctly
- for (auto &param : function.get_function_params ())
- if (!param->is_variadic ())
- {
- auto &p = static_cast<AST::FunctionParam &> (*param);
- ResolveType::go (p.get_type ());
- }
-
- // done
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveExternItem::visit (AST::ExternalStaticItem &item)
-{
- resolve_visibility (item.get_visibility ());
-
- ResolveType::go (item.get_type ());
-}
-
-} // namespace Resolver
-} // namespace Rust
-
-#if CHECKING_P
-
-namespace selftest {
-
-static void
-rust_flatten_nested_glob (void)
-{
- auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
- auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
- auto foobar = Rust::AST::SimplePath ({foo, bar});
-
- auto glob
- = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED,
- foobar, UNDEF_LOCATION);
-
- auto imports = std::vector<Rust::Resolver::Import> ();
- Rust::Resolver::flatten_glob (glob, imports);
-
- ASSERT_TRUE (!imports.empty ());
- ASSERT_EQ (imports.size (), 1);
- ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo");
- ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar");
-}
-
-static void
-rust_flatten_glob (void)
-{
- auto frob = Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION);
-
- auto glob
- = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED,
- frob, UNDEF_LOCATION);
-
- auto imports = std::vector<Rust::Resolver::Import> ();
- Rust::Resolver::flatten_glob (glob, imports);
-
- ASSERT_TRUE (!imports.empty ());
- ASSERT_EQ (imports.size (), 1);
- ASSERT_EQ (imports[0].get_path (), "frobulator");
-}
-
-static void
-rust_flatten_rebind_none (void)
-{
- auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
- auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
- auto foobar = Rust::AST::SimplePath ({foo, bar});
-
- auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE,
- foobar, UNDEF_LOCATION);
-
- auto imports = std::vector<Rust::Resolver::Import> ();
- Rust::Resolver::flatten_rebind (rebind, imports);
-
- ASSERT_TRUE (!imports.empty ());
- ASSERT_EQ (imports.size (), 1);
- ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo");
- ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar");
-}
-
-static void
-rust_flatten_rebind (void)
-{
- auto frob = Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION);
-
- auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER,
- frob, UNDEF_LOCATION, {"saindoux"});
-
- auto imports = std::vector<Rust::Resolver::Import> ();
- Rust::Resolver::flatten_rebind (rebind, imports);
-
- ASSERT_TRUE (!imports.empty ());
- ASSERT_EQ (imports.size (), 1);
- ASSERT_EQ (imports[0].get_path (), "frobulator");
- ASSERT_EQ (imports[0].get_name (), "saindoux");
-}
-
-static void
-rust_flatten_rebind_nested (void)
-{
- auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
- auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
- auto baz = Rust::AST::SimplePathSegment ("baz", UNDEF_LOCATION);
-
- auto foo_bar_baz = Rust::AST::SimplePath ({foo, bar, baz});
-
- auto rebind
- = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER,
- foo_bar_baz, UNDEF_LOCATION, {"saindoux"});
-
- auto imports = std::vector<Rust::Resolver::Import> ();
- Rust::Resolver::flatten_rebind (rebind, imports);
-
- ASSERT_TRUE (!imports.empty ());
- ASSERT_EQ (imports.size (), 1);
- ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo");
- ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar");
- ASSERT_EQ (imports[0].get_path ().get_segments ()[2].as_string (), "baz");
- ASSERT_EQ (imports[0].get_name (), "saindoux");
-}
-
-static void
-rust_flatten_list (void)
-{
- auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
- auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
- auto foo_bar = Rust::AST::SimplePath ({foo, bar});
-
- auto baz = Rust::AST::SimplePath::from_str ("baz", UNDEF_LOCATION);
- auto bul = Rust::AST::SimplePath::from_str ("bul", UNDEF_LOCATION);
-
- // use foo::bar::{baz, bul};
-
- auto use0 = std::unique_ptr<Rust::AST::UseTree> (
- new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, baz,
- UNDEF_LOCATION));
- auto use1 = std::unique_ptr<Rust::AST::UseTree> (
- new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, bul,
- UNDEF_LOCATION));
-
- auto uses = std::vector<std::unique_ptr<Rust::AST::UseTree>> ();
- uses.emplace_back (std::move (use0));
- uses.emplace_back (std::move (use1));
-
- auto list
- = Rust::AST::UseTreeList (Rust::AST::UseTreeList::PATH_PREFIXED, foo_bar,
- std::move (uses), UNDEF_LOCATION);
-
- auto imports = std::vector<Rust::Resolver::Import> ();
- Rust::Resolver::flatten_list (list, imports);
-
- ASSERT_TRUE (!imports.empty ());
- ASSERT_EQ (imports.size (), 2);
- ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo");
- ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar");
- ASSERT_EQ (imports[0].get_path ().get_segments ()[2].as_string (), "baz");
- ASSERT_EQ (imports[1].get_path ().get_segments ()[0].as_string (), "foo");
- ASSERT_EQ (imports[1].get_path ().get_segments ()[1].as_string (), "bar");
- ASSERT_EQ (imports[1].get_path ().get_segments ()[2].as_string (), "bul");
-}
-
-static void
-rust_use_dec_flattening (void)
-{
- rust_flatten_glob ();
- rust_flatten_nested_glob ();
- rust_flatten_rebind_none ();
- rust_flatten_rebind ();
- rust_flatten_rebind_nested ();
- rust_flatten_list ();
-}
-
-void
-rust_simple_path_resolve_test (void)
-{
- rust_use_dec_flattening ();
-}
-
-} // namespace selftest
-
-#endif // CHECKING_P
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
deleted file mode 100644
index d31f910..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_ITEM_H
-#define RUST_AST_RESOLVE_ITEM_H
-
-#include "rust-ast-full-decls.h"
-#include "rust-ast-resolve-base.h"
-
-#include "config.h"
-
-namespace Rust {
-namespace Resolver {
-
-class ResolveTraitItems : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::AssociatedItem *item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-
- void visit (AST::Function &type) override;
- void visit (AST::TraitItemType &type) override;
- void visit (AST::TraitItemConst &constant) override;
-
-private:
- ResolveTraitItems (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-};
-
-class ResolveItem : public ResolverBase
-{
-public:
- using Rust::Resolver::ResolverBase::visit;
-
- static void go (AST::Item &item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-
- void visit (AST::TypeAlias &alias) override;
- void visit (AST::Module &module) override;
- void visit (AST::TupleStruct &struct_decl) override;
- void visit (AST::Enum &enum_decl) override;
- /* EnumItem doesn't need to be handled, no fields. */
- void visit (AST::EnumItem &item) override;
- void visit (AST::EnumItemTuple &item) override;
- void visit (AST::EnumItemStruct &item) override;
- void visit (AST::EnumItemDiscriminant &item) override;
- void visit (AST::StructStruct &struct_decl) override;
- void visit (AST::Union &union_decl) override;
- void visit (AST::StaticItem &var) override;
- void visit (AST::ConstantItem &constant) override;
- void visit (AST::Function &function) override;
- void visit (AST::InherentImpl &impl_block) override;
- void visit (AST::TraitImpl &impl_block) override;
- void visit (AST::Trait &trait) override;
- void visit (AST::ExternBlock &extern_block) override;
- void visit (AST::UseDeclaration &) override;
-
-protected:
- void resolve_impl_item (AST::AssociatedItem &item,
- const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
- void resolve_extern_item (AST::ExternalItem &item);
-
- ResolveItem (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-};
-
-class ResolveImplItems : public ResolveItem
-{
- using Rust::Resolver::ResolveItem::visit;
-
-public:
- static void go (AST::AssociatedItem &item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-
- void visit (AST::TypeAlias &alias) override;
-
-private:
- ResolveImplItems (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-};
-
-class ResolveExternItem : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::ExternalItem &item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-
- void visit (AST::Function &function) override;
- void visit (AST::ExternalStaticItem &item) override;
-
-private:
- ResolveExternItem (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
- {}
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-};
-
-class Import
-{
-public:
- Import (AST::SimplePath path, bool is_glob, std::string name)
- : path (path), is_glob_f (is_glob), name (name)
- {}
-
- AST::SimplePath &get_path () { return path; }
-
- const AST::SimplePath &get_path () const { return path; }
-
- bool is_glob () const { return is_glob_f; }
-
- const std::string &get_name () const { return name; }
-
- void add_prefix (AST::SimplePath prefix);
-
-private:
- AST::SimplePath path;
- bool is_glob_f;
- std::string name;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#if CHECKING_P
-
-namespace selftest {
-extern void rust_simple_path_resolve_test (void);
-} // namespace selftest
-
-#endif // CHECKING_P
-
-#endif // RUST_AST_RESOLVE_ITEM_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc
deleted file mode 100644
index fb6715d..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ /dev/null
@@ -1,558 +0,0 @@
-// 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-ast-resolve-path.h"
-#include "rust-ast-resolve-type.h"
-#include "rust-hir-map.h"
-#include "rust-path.h"
-
-namespace Rust {
-namespace Resolver {
-
-ResolvePath::ResolvePath () : ResolverBase () {}
-
-NodeId
-ResolvePath::go (AST::PathInExpression &expr)
-{
- ResolvePath resolver;
- return resolver.resolve_path (expr);
-}
-
-NodeId
-ResolvePath::go (AST::QualifiedPathInExpression &expr)
-{
- ResolvePath resolver;
- return resolver.resolve_path (expr);
-}
-
-NodeId
-ResolvePath::go (AST::SimplePath &expr)
-{
- ResolvePath resolver;
- return resolver.resolve_path (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;
- for (size_t i = 0; i < expr.get_segments ().size (); i++)
- {
- auto &segment = expr.get_segments ().at (i);
- const AST::PathIdentSegment &ident_seg = segment.get_ident_segment ();
- bool is_first_segment = i == 0;
- resolved_node_id = UNKNOWN_NODEID;
-
- 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,
- "%qs in paths can only be used in start position",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
-
- NodeId crate_scope_id = resolver->peek_crate_module_scope ();
- 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;
-
- 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 ())
- {
- if (module_scope_id == crate_scope_id)
- {
- rust_error_at (segment.get_locus (),
- "cannot use %<super%> at the crate scope");
- return UNKNOWN_NODEID;
- }
-
- module_scope_id = resolver->peek_parent_module_scope ();
- previous_resolved_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;
- }
-
- // resolve any generic args
- if (segment.has_generic_args ())
- ResolveGenericArgs::go (segment.get_generic_args ());
-
- // logic is awkward here there are a few cases
- //
- // T::Default
- // mod::foo::impl_item
- // super::super::module::item
- // self
- // self::foo
- // self::foo::baz
- //
- // T::Default we can only resolve the T and cant do anything about Default
- // its dependant on associated types
- //
- // mod::foo::impl_item
- // we can resolve mod::foo but nothing about impl_item but we need to
- // _always resolve generic arguments
- //
- // self is a simple single lookup
- //
- // we have module_scope_id for the next module_scope to lookup
- // resolved_node_id is the thing we have resolve this segment to
- //
- // new algo?
- // we can only use module resolution when the previous segment is either
- // unknown or equal to this module_scope_id
- //
- // can only use old resolution when previous segment is unkown
-
- if (is_first_segment)
- {
- // name scope first
- NodeId resolved_node = UNKNOWN_NODEID;
- const CanonicalPath path
- = CanonicalPath::new_seg (segment.get_node_id (),
- ident_seg.as_string ());
- if (resolver->get_name_scope ().lookup (path, &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))
- {
- 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;
-
- 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
- {
- // no error handling here since we might be able to resolve via
- // the module hierarchy and handle errors at the end
- }
- }
-
- if (resolved_node_id == UNKNOWN_NODEID
- && previous_resolved_node_id == module_scope_id)
- {
- tl::optional<CanonicalPath &> resolved_child
- = mappings.lookup_module_child (module_scope_id,
- ident_seg.as_string ());
- if (resolved_child.has_value ())
- {
- NodeId resolved_node = resolved_child->get_node_id ();
- if (resolver->get_name_scope ().decl_was_declared_here (
- resolved_node))
- {
- resolved_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;
-
- 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 %<%s%> in this scope",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
- }
- }
-
- bool did_resolve_segment = resolved_node_id != UNKNOWN_NODEID;
- if (did_resolve_segment)
- {
- if (mappings.node_is_module (resolved_node_id)
- || mappings.node_is_crate (resolved_node_id))
- {
- module_scope_id = resolved_node_id;
- }
- previous_resolved_node_id = resolved_node_id;
- }
- else if (is_first_segment)
- {
- rust_error_at (segment.get_locus (), ErrorCode::E0433,
- "Cannot find path %<%s%> in this scope",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
- }
-
- resolved_node = resolved_node_id;
- if (resolved_node_id != UNKNOWN_NODEID)
- {
- // name scope first
- if (resolver->get_name_scope ().decl_was_declared_here (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))
- {
- 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
- {
- rust_unreachable ();
- }
- }
- return resolved_node_id;
-}
-
-NodeId
-ResolvePath::resolve_path (AST::QualifiedPathInExpression &expr)
-{
- auto &root_segment = expr.get_qualified_path_type ();
- ResolveType::go (root_segment.get_type ());
- if (root_segment.has_as_clause ())
- ResolveType::go (root_segment.get_as_type_path ());
-
- for (auto &segment : expr.get_segments ())
- {
- // we cant actually do anything with the segment itself since this is all
- // the job of the type system to figure it out but we can resolve any
- // generic arguments used
- if (segment.has_generic_args ())
- ResolveGenericArgs::go (segment.get_generic_args ());
- }
-
- // cannot fully resolve a qualified path as it is dependant on associated
- // items
- return UNKNOWN_NODEID;
-}
-
-NodeId
-ResolvePath::resolve_path (AST::SimplePath &expr)
-{
- NodeId crate_scope_id = resolver->peek_crate_module_scope ();
- NodeId module_scope_id = resolver->peek_current_module_scope ();
-
- NodeId previous_resolved_node_id = UNKNOWN_NODEID;
- NodeId resolved_node_id = UNKNOWN_NODEID;
- for (size_t i = 0; i < expr.get_segments ().size (); i++)
- {
- AST::SimplePathSegment &segment = expr.get_segments ().at (i);
- bool is_first_segment = i == 0;
- bool is_final_segment = i >= (expr.get_segments ().size () - 1);
- resolved_node_id = UNKNOWN_NODEID;
-
- 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;
-
- 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 (),
- "cannot use %<super%> at the crate scope");
- return UNKNOWN_NODEID;
- }
-
- module_scope_id = resolver->peek_parent_module_scope ();
- previous_resolved_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;
- }
-
- tl::optional<CanonicalPath &> resolved_child
- = mappings.lookup_module_child (module_scope_id,
- segment.get_segment_name ());
- if (resolved_child.has_value ())
- {
- NodeId resolved_node = resolved_child->get_node_id ();
- if (resolver->get_name_scope ().decl_was_declared_here (
- resolved_node))
- {
- resolved_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;
-
- 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 %<%s%> in this scope",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
- }
-
- if (resolved_node_id == UNKNOWN_NODEID && is_first_segment)
- {
- // name scope first
- NodeId resolved_node = UNKNOWN_NODEID;
- const CanonicalPath path
- = CanonicalPath::new_seg (segment.get_node_id (),
- segment.get_segment_name ());
- if (resolver->get_name_scope ().lookup (path, &resolved_node))
- {
- resolved_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;
-
- 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);
- }
- }
-
- // if we still have not resolved and this is the final segment and the
- // final segment is self its likely the case: pub use
- //
- // result::Result::{self, Err, Ok};
- //
- // Then the resolved_node_id is just the previous one so long as it is a
- // resolved node id
- // rust_debug_loc (segment.get_locus (),
- // "trying to resolve seg: [%s] first [%s] last [%s]",
- // segment.get_segment_name ().c_str (),
- // is_first_segment ? "true" : "false",
- // is_final_segment ? "true" : "false");
- if (resolved_node_id == UNKNOWN_NODEID && !is_first_segment
- && is_final_segment && segment.is_lower_self_seg ())
- resolved_node_id = previous_resolved_node_id;
-
- // final check
- if (resolved_node_id == UNKNOWN_NODEID)
- {
- rust_error_at (segment.get_locus (),
- "cannot find simple path segment %<%s%> in this scope",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
-
- if (mappings.node_is_module (resolved_node_id))
- {
- module_scope_id = resolved_node_id;
- }
-
- previous_resolved_node_id = resolved_node_id;
- }
-
- resolved_node = resolved_node_id;
- if (resolved_node_id != UNKNOWN_NODEID)
- {
- // name scope first
- if (resolver->get_name_scope ().decl_was_declared_here (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))
- {
- 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
- {
- rust_unreachable ();
- }
- }
- return resolved_node_id;
-}
-
-} // namespace Resolver
-} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.h b/gcc/rust/resolve/rust-ast-resolve-path.h
deleted file mode 100644
index cddb54a..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-path.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_PATH_H
-#define RUST_AST_RESOLVE_PATH_H
-
-#include "rust-ast-resolve-base.h"
-
-namespace Rust {
-namespace Resolver {
-
-class ResolvePath : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static NodeId go (AST::PathInExpression &expr);
- static NodeId go (AST::QualifiedPathInExpression &expr);
- static NodeId go (AST::SimplePath &expr);
-
-private:
- ResolvePath ();
-
- NodeId resolve_path (AST::PathInExpression &expr);
- NodeId resolve_path (AST::QualifiedPathInExpression &expr);
- NodeId resolve_path (AST::SimplePath &expr);
-
- void
- resolve_simple_path_segments (CanonicalPath prefix, size_t offs,
- const std::vector<AST::SimplePathSegment> &segs,
- NodeId expr_node_id, location_t expr_locus);
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // !RUST_AST_RESOLVE_PATH_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
deleted file mode 100644
index 3b80f9f..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ /dev/null
@@ -1,419 +0,0 @@
-// Copyright (C) 2020-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-ast-resolve-pattern.h"
-#include "rust-ast-resolve-path.h"
-
-namespace Rust {
-namespace Resolver {
-
-void
-PatternDeclaration::go (AST::Pattern &pattern, Rib::ItemType type)
-{
- std::vector<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
- PatternDeclaration::go (pattern, type, bindings);
-}
-
-void
-PatternDeclaration::go (AST::Pattern &pattern, Rib::ItemType type,
- std::vector<PatternBinding> &bindings)
-{
- PatternDeclaration resolver (bindings, type);
- pattern.accept_vis (resolver);
-
- for (auto &map_entry : resolver.missing_bindings)
- {
- auto ident = map_entry.first; // key
- auto info = map_entry.second; // value
-
- rust_error_at (info.get_locus (), ErrorCode::E0408,
- "variable '%s' is not bound in all patterns",
- ident.as_string ().c_str ());
- }
-
- for (auto &map_entry : resolver.inconsistent_bindings)
- {
- auto ident = map_entry.first; // key
- auto info = map_entry.second; // value
-
- rust_error_at (
- info.get_locus (), ErrorCode::E0409,
- "variable '%s' is bound inconsistently across pattern alternatives",
- ident.as_string ().c_str ());
- }
-}
-
-void
-PatternDeclaration::visit (AST::IdentifierPattern &pattern)
-{
- if (pattern.has_subpattern ())
- {
- pattern.get_subpattern ().accept_vis (*this);
- }
-
- Mutability mut = pattern.get_is_mut () ? Mutability::Mut : Mutability::Imm;
- add_new_binding (pattern.get_ident (), pattern.get_node_id (),
- BindingTypeInfo (mut, pattern.get_is_ref (),
- pattern.get_locus ()));
-}
-
-void
-PatternDeclaration::visit (AST::GroupedPattern &pattern)
-{
- pattern.get_pattern_in_parens ().accept_vis (*this);
-}
-
-void
-PatternDeclaration::visit (AST::ReferencePattern &pattern)
-{
- pattern.get_referenced_pattern ().accept_vis (*this);
-}
-
-void
-PatternDeclaration::visit (AST::PathInExpression &pattern)
-{
- ResolvePath::go (pattern);
-}
-
-void
-PatternDeclaration::visit (AST::TupleStructPattern &pattern)
-{
- ResolvePath::go (pattern.get_path ());
-
- AST::TupleStructItems &items = pattern.get_items ();
- switch (items.get_item_type ())
- {
- case AST::TupleStructItems::RANGE:
- {
- // TODO
- rust_unreachable ();
- }
- break;
-
- case AST::TupleStructItems::NO_RANGE:
- {
- auto &items_no_range
- = static_cast<AST::TupleStructItemsNoRange &> (items);
-
- for (auto &inner_pattern : items_no_range.get_patterns ())
- {
- inner_pattern->accept_vis (*this);
- }
- }
- break;
- }
-}
-
-void
-PatternDeclaration::visit (AST::StructPattern &pattern)
-{
- ResolvePath::go (pattern.get_path ());
-
- auto &struct_pattern_elems = pattern.get_struct_pattern_elems ();
- for (auto &field : struct_pattern_elems.get_struct_pattern_fields ())
- {
- switch (field->get_item_type ())
- {
- case AST::StructPatternField::ItemType::TUPLE_PAT:
- {
- AST::StructPatternFieldTuplePat &tuple
- = static_cast<AST::StructPatternFieldTuplePat &> (*field);
-
- tuple.get_index_pattern ().accept_vis (*this);
- }
- break;
-
- case AST::StructPatternField::ItemType::IDENT_PAT:
- {
- AST::StructPatternFieldIdentPat &ident
- = static_cast<AST::StructPatternFieldIdentPat &> (*field);
-
- ident.get_ident_pattern ().accept_vis (*this);
- }
- break;
-
- case AST::StructPatternField::ItemType::IDENT:
- {
- auto &ident = static_cast<AST::StructPatternFieldIdent &> (*field);
-
- Mutability mut
- = ident.is_mut () ? Mutability::Mut : Mutability::Imm;
-
- add_new_binding (ident.get_identifier (), ident.get_node_id (),
- BindingTypeInfo (mut, ident.is_ref (),
- ident.get_locus ()));
- }
- break;
- }
- }
-}
-
-void
-PatternDeclaration::visit (AST::TuplePattern &pattern)
-{
- auto &items = pattern.get_items ();
- switch (items.get_pattern_type ())
- {
- case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE:
- {
- auto &ref = static_cast<AST::TuplePatternItemsMultiple &> (
- pattern.get_items ());
-
- for (auto &p : ref.get_patterns ())
- p->accept_vis (*this);
- }
- break;
-
- case AST::TuplePatternItems::TuplePatternItemType::RANGED:
- {
- auto &ref
- = static_cast<AST::TuplePatternItemsRanged &> (pattern.get_items ());
-
- for (auto &p : ref.get_lower_patterns ())
- p->accept_vis (*this);
- for (auto &p : ref.get_upper_patterns ())
- p->accept_vis (*this);
- }
- break;
- }
-}
-
-void
-PatternDeclaration::visit (AST::AltPattern &pattern)
-{
- // push a new set of 'Or' bindings to the stack. Accounts for the
- // alternatives. e.g. in `p_0 | p_1`, bindings to the same identifier between
- // p_0 and p_1 shouldn't cause an error.
- bindings_with_ctx.push_back (
- PatternBinding (PatternBoundCtx::Or, std::set<Identifier> ()));
-
- // This is a hack to avoid creating a separate visitor class for the
- // consistency checks. We empty out the binding_info_map before each iteration
- // to separate between the alts' binding_maps. And right after the alt
- // visit...
- auto tmp_binding_map = binding_info_map;
- binding_info_map.clear ();
-
- std::vector<BindingMap> alts_binding_maps;
-
- for (auto &alt : pattern.get_alts ())
- {
- // before this visit, the binding_info_map is guaranteed to be empty
- rust_assert (binding_info_map.empty ());
-
- // push a new `Product` context to correctly reject multiple bindings
- // within this single alt.
- bindings_with_ctx.push_back (
- PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ()));
-
- alt->accept_vis (*this);
-
- // ...the binding_info_map is (potentially) populated. We copy it to the
- // vector, and empty it out to be ready for the next iteration. And after
- // all the iterations are finished...
- alts_binding_maps.push_back (binding_info_map);
- binding_info_map.clear ();
-
- // Remove the last (i.e. `Product`) context and add the bindings from the
- // visited alt to the one before last (i.e. `Or`). Now (after checking
- // with the alt internally), the bindings from this alt will reside in the
- // `Or` context.
- auto last_bound_idents = bindings_with_ctx.back ().idents;
- bindings_with_ctx.pop_back ();
-
- for (auto &ident : last_bound_idents)
- {
- bindings_with_ctx.back ().idents.insert (ident);
- }
- }
-
- // Now we can finally check for consistency.
- check_bindings_consistency (alts_binding_maps);
-
- // Now we remove the `Or` context we pushed earlier.
- // e.g. in `(a, (p_0 | p_1), c)`: after finishing up inside the alt pattern,
- // we return to the tuple (`Product`) context and push the new bindings.
- auto idents = bindings_with_ctx.back ().idents;
- bindings_with_ctx.pop_back ();
- for (auto &ident : idents)
- bindings_with_ctx.back ().idents.insert (ident.as_string ());
-
- // ...we repopulate the binding_info_map correctly (the initial bindings
- // stored in the tmp_binding_map + all the bindings from all the alts)
- binding_info_map = tmp_binding_map;
- for (auto &alt_map : alts_binding_maps)
- for (auto &map_entry : alt_map)
- binding_info_map.insert (map_entry);
-}
-
-void
-PatternDeclaration::add_new_binding (Identifier ident, NodeId node_id,
- BindingTypeInfo info)
-{
- bool has_binding_ctx = bindings_with_ctx.size () > 0;
- rust_assert (has_binding_ctx);
-
- bool identifier_or_bound = false, identifier_product_bound = false;
-
- for (auto binding : bindings_with_ctx)
- {
- bool identifier_bound_here
- = (binding.idents.find (ident) != binding.idents.end ());
- if (identifier_bound_here)
- {
- identifier_product_bound |= binding.ctx == PatternBoundCtx::Product;
- identifier_or_bound |= binding.ctx == PatternBoundCtx::Or;
- }
- }
-
- if (identifier_product_bound)
- {
- if (type == Rib::ItemType::Param)
- {
- rust_error_at (info.get_locus (), ErrorCode::E0415,
- "identifier '%s' is bound more than once in the "
- "same parameter list",
- ident.as_string ().c_str ());
- }
- else
- {
- rust_error_at (
- info.get_locus (), ErrorCode::E0416,
- "identifier '%s' is bound more than once in the same pattern",
- ident.as_string ().c_str ());
- }
-
- return;
- }
-
- if (!identifier_or_bound)
- {
- bindings_with_ctx.back ().idents.insert (ident);
- resolver->get_name_scope ().insert (
- CanonicalPath::new_seg (node_id, ident.as_string ()), node_id,
- info.get_locus (), type);
- }
-
- binding_info_map.insert ({ident, info});
-}
-
-// Verifies that all the alts in an AltPattern have the same set of bindings
-// with the same mutability and reference states.
-void
-PatternDeclaration::check_bindings_consistency (
- std::vector<BindingMap> &binding_maps)
-{
- for (size_t i = 0; i < binding_maps.size (); i++)
- {
- auto &outer_bindings_map = binding_maps[i];
-
- for (size_t j = 0; j < binding_maps.size (); j++)
- {
- // skip comparing the current outer map with itself.
- if (j == i)
- continue;
-
- auto &inner_bindings_map = binding_maps[j];
-
- // iterate over the inner map entries and check if they exist in outer
- // map
- for (auto map_entry : inner_bindings_map)
- {
- auto ident = map_entry.first; // key
- auto inner_info = map_entry.second; // value
- bool ident_is_outer_bound = outer_bindings_map.count (ident);
-
- if (!ident_is_outer_bound && !missing_bindings.count (ident))
- missing_bindings.insert ({ident, inner_info});
-
- else if (outer_bindings_map.count (ident)
- && outer_bindings_map[ident] != inner_info
- && !inconsistent_bindings.count (ident))
- inconsistent_bindings.insert ({ident, inner_info});
- }
- }
- }
-}
-
-static void
-resolve_range_pattern_bound (AST::RangePatternBound &bound)
-{
- switch (bound.get_bound_type ())
- {
- case AST::RangePatternBound::RangePatternBoundType::LITERAL:
- // Nothing to resolve for a literal.
- break;
-
- case AST::RangePatternBound::RangePatternBoundType::PATH:
- {
- auto &ref = static_cast<AST::RangePatternBoundPath &> (bound);
-
- ResolvePath::go (ref.get_path ());
- }
- break;
-
- case AST::RangePatternBound::RangePatternBoundType::QUALPATH:
- {
- auto &ref = static_cast<AST::RangePatternBoundQualPath &> (bound);
-
- ResolvePath::go (ref.get_qualified_path ());
- }
- break;
- }
-}
-
-void
-PatternDeclaration::visit (AST::RangePattern &pattern)
-{
- resolve_range_pattern_bound (pattern.get_upper_bound ());
- resolve_range_pattern_bound (pattern.get_lower_bound ());
-}
-
-void
-PatternDeclaration::visit (AST::SlicePattern &pattern)
-{
- auto &items = pattern.get_items ();
- switch (items.get_pattern_type ())
- {
- case AST::SlicePatternItems::SlicePatternItemType::NO_REST:
- {
- auto &ref
- = static_cast<AST::SlicePatternItemsNoRest &> (pattern.get_items ());
-
- for (auto &p : ref.get_patterns ())
- p->accept_vis (*this);
- }
- break;
-
- case AST::SlicePatternItems::SlicePatternItemType::HAS_REST:
- {
- auto &ref
- = static_cast<AST::SlicePatternItemsHasRest &> (pattern.get_items ());
-
- for (auto &p : ref.get_lower_patterns ())
- p->accept_vis (*this);
- for (auto &p : ref.get_upper_patterns ())
- p->accept_vis (*this);
- }
- break;
- }
-}
-
-} // namespace Resolver
-} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h
deleted file mode 100644
index 876de16..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_PATTERN_H
-#define RUST_AST_RESOLVE_PATTERN_H
-
-#include "rust-ast-resolve-base.h"
-#include "rust-ast-full.h"
-
-namespace Rust {
-namespace Resolver {
-
-// Specifies whether the set of already bound patterns are related by 'Or' or
-// 'Product'. Used to check for multiple bindings to the same identifier.
-enum PatternBoundCtx
-{
- // A product pattern context (e.g. struct and tuple patterns)
- Product,
- // An or-pattern context (e.g. p_0 | p_1 | ...)
- Or,
-};
-
-struct PatternBinding
-{
- PatternBoundCtx ctx;
- std::set<Identifier> idents;
-
- PatternBinding (PatternBoundCtx ctx, std::set<Identifier> idents)
- : ctx (ctx), idents (idents)
- {}
-};
-
-// Info that gets stored in the map. Helps us detect if two bindings to the same
-// identifier have different mutability or ref states.
-class BindingTypeInfo
-{
- Mutability mut;
- bool is_ref;
- location_t locus;
-
-public:
- BindingTypeInfo (Mutability mut, bool is_ref, location_t locus)
- : mut (mut), is_ref (is_ref), locus (locus)
- {}
-
- BindingTypeInfo (BindingTypeInfo const &other)
- : mut (other.mut), is_ref (other.is_ref), locus (other.get_locus ())
- {}
-
- BindingTypeInfo (){};
-
- location_t get_locus () const { return locus; }
- Mutability get_mut () const { return mut; }
- bool get_is_ref () const { return is_ref; }
-
- BindingTypeInfo operator= (BindingTypeInfo const &other)
- {
- mut = other.mut;
- is_ref = other.is_ref;
- locus = other.get_locus ();
-
- return *this;
- }
-
- bool operator== (BindingTypeInfo const &other)
- {
- return mut == other.mut && is_ref == other.is_ref;
- }
-
- bool operator!= (BindingTypeInfo const &other)
- {
- return !BindingTypeInfo::operator== (other);
- }
-};
-
-typedef std::map<Identifier, BindingTypeInfo> BindingMap;
-
-class PatternDeclaration : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::Pattern &pattern, Rib::ItemType type);
- static void go (AST::Pattern &pattern, Rib::ItemType type,
- std::vector<PatternBinding> &bindings);
-
- void visit (AST::IdentifierPattern &pattern) override;
- void visit (AST::GroupedPattern &pattern) override;
- void visit (AST::ReferencePattern &pattern) override;
- void visit (AST::PathInExpression &pattern) override;
- void visit (AST::StructPattern &pattern) override;
- void visit (AST::TupleStructPattern &pattern) override;
- void visit (AST::TuplePattern &pattern) override;
- void visit (AST::RangePattern &pattern) override;
- void visit (AST::AltPattern &pattern) override;
- void visit (AST::SlicePattern &pattern) override;
-
- void add_new_binding (Identifier ident, NodeId node_id, BindingTypeInfo info);
- void check_bindings_consistency (std::vector<BindingMap> &binding_maps);
-
-private:
- PatternDeclaration (std::vector<PatternBinding> &bindings_with_ctx,
- Rib::ItemType type)
- : ResolverBase (), bindings_with_ctx (bindings_with_ctx), type (type)
- {}
-
- // To avoid having a separate visitor for consistency checks, we store
- // bindings in two forms:
-
- // 1) Bindings as a vector of context-related sets.
- // Used for checking multiple bindings to the same identifier (i.e. E0415,
- // E0416).
- std::vector<PatternBinding> &bindings_with_ctx;
-
- // 2) Bindings as a map between identifiers and binding info.
- // Used for checking consistency between alt patterns (i.e. E0408, E0409).
- BindingMap binding_info_map;
-
- // we need to insert the missing and inconsistent bindings (found in
- // check_bindings_consistency) into maps to avoid duplication of error
- // messages.
- BindingMap inconsistent_bindings;
- BindingMap missing_bindings;
-
- Rib::ItemType type;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_AST_RESOLVE_PATTERN_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.cc b/gcc/rust/resolve/rust-ast-resolve-stmt.cc
deleted file mode 100644
index bfba302..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (C) 2020-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-ast-resolve-toplevel.h"
-#include "rust-ast-resolve-item.h"
-#include "rust-ast-resolve-stmt.h"
-#include "rust-ast-resolve-implitem.h"
-
-namespace Rust {
-namespace Resolver {
-
-void
-ResolveStmt::visit (AST::ExternBlock &extern_block)
-{
- resolve_visibility (extern_block.get_visibility ());
- for (auto &item : extern_block.get_extern_items ())
- {
- ResolveToplevelExternItem::go (*item, CanonicalPath::create_empty ());
- ResolveExternItem::go (*item, prefix, canonical_prefix);
- }
-}
-
-void
-ResolveStmt::visit (AST::Trait &trait)
-{
- ResolveTopLevel::go (trait, prefix, canonical_prefix);
- ResolveItem::go (trait, prefix, canonical_prefix);
-}
-
-void
-ResolveStmt::visit (AST::InherentImpl &impl_block)
-{
- ResolveTopLevel::go (impl_block, prefix, canonical_prefix);
- ResolveItem::go (impl_block, prefix, canonical_prefix);
-}
-
-void
-ResolveStmt::visit (AST::TraitImpl &impl_block)
-{
- ResolveTopLevel::go (impl_block, prefix, canonical_prefix);
- 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
deleted file mode 100644
index d714511..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_STMT_H
-#define RUST_AST_RESOLVE_STMT_H
-
-#include "rust-ast-resolve-base.h"
-#include "rust-ast-resolve-type.h"
-#include "rust-ast-resolve-pattern.h"
-#include "rust-ast-resolve-expr.h"
-#include "rust-item.h"
-
-namespace Rust {
-namespace Resolver {
-
-class ResolveStmt : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::Stmt &stmt, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix,
- const CanonicalPath &enum_prefix)
- {
- if (stmt.is_marked_for_strip ())
- return;
-
- ResolveStmt resolver (prefix, canonical_prefix, enum_prefix);
- stmt.accept_vis (resolver);
- }
-
- void visit (AST::ExprStmt &stmt) override
- {
- ResolveExpr::go (stmt.get_expr (), prefix, canonical_prefix);
- }
-
- void visit (AST::ConstantItem &constant) override
- {
- auto decl = CanonicalPath::new_seg (constant.get_node_id (),
- constant.get_identifier ());
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (constant.get_node_id (), cpath);
-
- resolver->get_name_scope ().insert (
- path, constant.get_node_id (), constant.get_locus (), false,
- Rib::ItemType::Const,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, constant.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- ResolveType::go (constant.get_type ());
- if (constant.has_expr ())
- ResolveExpr::go (constant.get_expr (), prefix, canonical_prefix);
- }
-
- void visit (AST::LetStmt &stmt) override
- {
- if (stmt.has_init_expr ())
- 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 ())
- ResolveType::go (stmt.get_type ());
- }
-
- void visit (AST::TupleStruct &struct_decl) override
- {
- auto decl
- = CanonicalPath::new_seg (struct_decl.get_node_id (),
- struct_decl.get_identifier ().as_string ());
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
-
- 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);
- 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 ())
- ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
- canonical_prefix);
-
- for (AST::TupleField &field : struct_decl.get_fields ())
- ResolveType::go (field.get_field_type ());
-
- resolver->get_type_scope ().pop ();
- }
-
- void visit (AST::Enum &enum_decl) override
- {
- auto decl
- = CanonicalPath::new_seg (enum_decl.get_node_id (),
- enum_decl.get_identifier ().as_string ());
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (enum_decl.get_node_id (), cpath);
-
- resolver->get_type_scope ().insert (
- path, enum_decl.get_node_id (), enum_decl.get_locus (), false,
- Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, enum_decl.get_locus ());
- r.add_range (locus);
- 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 ())
- ResolveGenericParams::go (enum_decl.get_generic_params (), prefix,
- canonical_prefix);
-
- for (auto &variant : enum_decl.get_variants ())
- ResolveStmt::go (*variant, path, canonical_prefix, path);
-
- resolver->get_type_scope ().pop ();
- }
-
- void visit (AST::EnumItem &item) override
- {
- auto decl = enum_prefix.append (
- CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ()));
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- resolver->get_type_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- // Done, no fields.
- }
-
- void visit (AST::EnumItemTuple &item) override
- {
- auto decl = enum_prefix.append (
- CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ()));
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- resolver->get_type_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- for (auto &field : item.get_tuple_fields ())
- {
- if (field.get_field_type ().is_marked_for_strip ())
- continue;
-
- ResolveType::go (field.get_field_type ());
- }
- }
-
- void visit (AST::EnumItemStruct &item) override
- {
- auto decl = enum_prefix.append (
- CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ()));
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- resolver->get_type_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- for (auto &field : item.get_struct_fields ())
- {
- if (field.get_field_type ().is_marked_for_strip ())
- continue;
-
- ResolveType::go (field.get_field_type ());
- }
- }
-
- void visit (AST::EnumItemDiscriminant &item) override
- {
- auto decl = enum_prefix.append (
- CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ()));
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- resolver->get_type_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- // Done, no fields.
- }
-
- void visit (AST::StructStruct &struct_decl) override
- {
- auto decl
- = CanonicalPath::new_seg (struct_decl.get_node_id (),
- struct_decl.get_identifier ().as_string ());
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
-
- 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);
- 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 ())
- ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
- canonical_prefix);
-
- for (AST::StructField &field : struct_decl.get_fields ())
- {
- if (field.get_field_type ().is_marked_for_strip ())
- continue;
-
- ResolveType::go (field.get_field_type ());
- }
-
- resolver->get_type_scope ().pop ();
- }
-
- void visit (AST::Union &union_decl) override
- {
- auto decl
- = CanonicalPath::new_seg (union_decl.get_node_id (),
- union_decl.get_identifier ().as_string ());
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (union_decl.get_node_id (), cpath);
-
- resolver->get_type_scope ().insert (
- path, union_decl.get_node_id (), union_decl.get_locus (), false,
- Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, union_decl.get_locus ());
- r.add_range (locus);
- 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 ())
- ResolveGenericParams::go (union_decl.get_generic_params (), prefix,
- canonical_prefix);
-
- for (AST::StructField &field : union_decl.get_variants ())
- {
- if (field.get_field_type ().is_marked_for_strip ())
- continue;
-
- ResolveType::go (field.get_field_type ());
- }
-
- resolver->get_type_scope ().pop ();
- }
-
- void visit (AST::Function &function) override
- {
- auto decl
- = CanonicalPath::new_seg (function.get_node_id (),
- function.get_function_name ().as_string ());
- auto path = decl; // this ensures we have the correct relative resolution
- auto cpath = canonical_prefix.append (decl);
- mappings.insert_canonical_path (function.get_node_id (), cpath);
-
- resolver->get_name_scope ().insert (
- path, function.get_node_id (), function.get_locus (), false,
- Rib::ItemType::Function,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, function.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- NodeId scope_node_id = function.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- 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_label_scope ().peek ());
-
- if (function.has_generics ())
- ResolveGenericParams::go (function.get_generic_params (), prefix,
- canonical_prefix);
-
- if (function.has_return_type ())
- ResolveType::go (function.get_return_type ());
-
- std::vector<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- // we make a new scope so the names of parameters are resolved and shadowed
- // correctly
- for (auto &p : function.get_function_params ())
- {
- if (p->is_variadic ())
- {
- auto &param = static_cast<AST::VariadicParam &> (*p);
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
- bindings);
- }
-
- else if (p->is_self ())
- {
- auto &param = static_cast<AST::SelfParam &> (*p);
- ResolveType::go (param.get_type ());
- }
- else
- {
- auto &param = static_cast<AST::FunctionParam &> (*p);
-
- ResolveType::go (param.get_type ());
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
- bindings);
- }
- }
-
- // resolve the function body
- ResolveExpr::go (*function.get_definition ().value (), path, cpath);
-
- resolver->get_name_scope ().pop ();
- resolver->get_type_scope ().pop ();
- resolver->get_label_scope ().pop ();
- }
-
- void visit (AST::ExternBlock &extern_block) override;
- 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,
- const CanonicalPath &canonical_prefix,
- const CanonicalPath &enum_prefix)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix),
- enum_prefix (enum_prefix)
- {}
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-
- /* item declaration statements are not given a canonical path, but enum items
- * (variants) do inherit the enum path/identifier name. */
- const CanonicalPath &enum_prefix;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_AST_RESOLVE_STMT_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.cc b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.cc
deleted file mode 100644
index 9b38e6a..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (C) 2020-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-ast-resolve-struct-expr-field.h"
-#include "rust-ast-resolve-expr.h"
-
-namespace Rust {
-namespace Resolver {
-
-void
-ResolveStructExprField::go (AST::StructExprField &field,
- const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
-{
- ResolveStructExprField resolver (prefix, canonical_prefix);
- field.accept_vis (resolver);
-}
-
-ResolveStructExprField::ResolveStructExprField (
- const CanonicalPath &prefix, const CanonicalPath &canonical_prefix)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
-{}
-
-void
-ResolveStructExprField::visit (AST::StructExprFieldIdentifierValue &field)
-{
- ResolveExpr::go (field.get_value (), prefix, canonical_prefix);
-}
-
-void
-ResolveStructExprField::visit (AST::StructExprFieldIndexValue &field)
-{
- ResolveExpr::go (field.get_value (), prefix, canonical_prefix);
-}
-
-void
-ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field)
-{
- AST::IdentifierExpr expr (field.get_field_name (), {}, field.get_locus ());
- expr.set_node_id (field.get_node_id ());
-
- ResolveExpr::go (expr, prefix, canonical_prefix);
-}
-
-} // namespace Resolver
-} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h
deleted file mode 100644
index 87fa60d..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_STRUCT_EXPR_FIELD
-#define RUST_AST_RESOLVE_STRUCT_EXPR_FIELD
-
-#include "rust-ast-resolve-base.h"
-
-namespace Rust {
-namespace Resolver {
-
-// this resolves values being assigned not that the field actually exists yet.
-
-class ResolveStructExprField : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::StructExprField &field, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-
- void visit (AST::StructExprFieldIdentifierValue &field) override;
-
- void visit (AST::StructExprFieldIndexValue &field) override;
-
- void visit (AST::StructExprFieldIdentifier &field) override;
-
-private:
- ResolveStructExprField (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_AST_RESOLVE_STRUCT_EXPR_FIELD
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
deleted file mode 100644
index f52fb8a..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ /dev/null
@@ -1,500 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_TOPLEVEL_H
-#define RUST_AST_RESOLVE_TOPLEVEL_H
-
-#include "rust-ast-resolve-base.h"
-#include "rust-ast-resolve-implitem.h"
-#include "rust-name-resolver.h"
-
-namespace Rust {
-namespace Resolver {
-
-class ResolveTopLevel : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::Item &item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- {
- if (item.is_marked_for_strip ())
- return;
-
- ResolveTopLevel resolver (prefix, canonical_prefix);
- item.accept_vis (resolver);
-
- NodeId current_module = resolver.resolver->peek_current_module_scope ();
- resolver.mappings.insert_child_item_to_parent_module_mapping (
- item.get_node_id (), current_module);
- }
-
- void visit (AST::Module &module) override
- {
- auto mod = CanonicalPath::new_seg (module.get_node_id (),
- module.get_name ().as_string ());
- auto path = prefix.append (mod);
- auto cpath = canonical_prefix.append (mod);
-
- resolver->get_name_scope ().insert (
- path, module.get_node_id (), module.get_locus (), false,
- Rib::ItemType::Module,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, module.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, mod);
- mappings.insert_module_child (current_module, module.get_node_id ());
-
- resolver->push_new_module_scope (module.get_node_id ());
- for (auto &item : module.get_items ())
- ResolveTopLevel::go (*item, path, cpath);
-
- resolver->pop_module_scope ();
-
- mappings.insert_canonical_path (module.get_node_id (), cpath);
- }
-
- void visit (AST::TypeAlias &alias) override
- {
- auto talias
- = CanonicalPath::new_seg (alias.get_node_id (),
- alias.get_new_type_name ().as_string ());
- auto path = prefix.append (talias);
- auto cpath = canonical_prefix.append (talias);
-
- resolver->get_type_scope ().insert (
- path, alias.get_node_id (), alias.get_locus (), false,
- Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, alias.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, talias);
- mappings.insert_canonical_path (alias.get_node_id (), cpath);
- }
-
- void visit (AST::TupleStruct &struct_decl) override
- {
- auto decl
- = CanonicalPath::new_seg (struct_decl.get_node_id (),
- struct_decl.get_identifier ().as_string ());
- 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);
- redefined_error (r);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
- }
-
- void visit (AST::Enum &enum_decl) override
- {
- auto decl
- = CanonicalPath::new_seg (enum_decl.get_node_id (),
- enum_decl.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, enum_decl.get_node_id (), enum_decl.get_locus (), false,
- Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, enum_decl.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- resolver->push_new_module_scope (enum_decl.get_node_id ());
- for (auto &variant : enum_decl.get_variants ())
- ResolveTopLevel::go (*variant, path, cpath);
-
- resolver->pop_module_scope ();
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_canonical_path (enum_decl.get_node_id (), cpath);
- }
-
- void visit (AST::EnumItem &item) override
- {
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_module_child (current_module, item.get_node_id ());
- }
-
- void visit (AST::EnumItemTuple &item) override
- {
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_module_child (current_module, item.get_node_id ());
- }
-
- void visit (AST::EnumItemStruct &item) override
- {
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_module_child (current_module, item.get_node_id ());
- }
-
- void visit (AST::EnumItemDiscriminant &item) override
- {
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- mappings.insert_canonical_path (item.get_node_id (), cpath);
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_module_child (current_module, item.get_node_id ());
- }
-
- void visit (AST::StructStruct &struct_decl) override
- {
- auto decl
- = CanonicalPath::new_seg (struct_decl.get_node_id (),
- struct_decl.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- 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);
- mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
- }
-
- void visit (AST::Union &union_decl) override
- {
- auto decl
- = CanonicalPath::new_seg (union_decl.get_node_id (),
- union_decl.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, union_decl.get_node_id (), union_decl.get_locus (), false,
- Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, union_decl.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_canonical_path (union_decl.get_node_id (), cpath);
- }
-
- void visit (AST::StaticItem &var) override
- {
- auto decl = CanonicalPath::new_seg (var.get_node_id (),
- var.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- 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);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_canonical_path (var.get_node_id (), cpath);
- }
-
- void visit (AST::ConstantItem &constant) override
- {
- auto decl = CanonicalPath::new_seg (constant.get_node_id (),
- constant.get_identifier ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_name_scope ().insert (
- path, constant.get_node_id (), constant.get_locus (), false,
- Rib::ItemType::Const,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, constant.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_canonical_path (constant.get_node_id (), cpath);
- }
-
- void visit (AST::Function &function) override
- {
- auto decl
- = CanonicalPath::new_seg (function.get_node_id (),
- function.get_function_name ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_name_scope ().insert (
- path, function.get_node_id (), function.get_locus (), false,
- Rib::ItemType::Function,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, function.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_canonical_path (function.get_node_id (), cpath);
- }
-
- void visit (AST::InherentImpl &impl_block) override
- {
- std::string raw_impl_type_path = impl_block.get_type ().as_string ();
- CanonicalPath impl_type_seg
- = CanonicalPath::new_seg (impl_block.get_type ().get_node_id (),
- raw_impl_type_path);
-
- CanonicalPath impl_type
- = CanonicalPath::inherent_impl_seg (impl_block.get_node_id (),
- impl_type_seg);
- CanonicalPath impl_prefix = prefix.append (impl_type_seg);
-
- for (auto &impl_item : impl_block.get_impl_items ())
- ResolveToplevelImplItem::go (*impl_item, impl_prefix);
- }
-
- void visit (AST::TraitImpl &impl_block) override
- {
- std::string raw_impl_type_path = impl_block.get_type ().as_string ();
- CanonicalPath impl_type_seg
- = CanonicalPath::new_seg (impl_block.get_type ().get_node_id (),
- raw_impl_type_path);
-
- std::string raw_trait_type_path = impl_block.get_trait_path ().as_string ();
- CanonicalPath trait_type_seg
- = CanonicalPath::new_seg (impl_block.get_trait_path ().get_node_id (),
- raw_trait_type_path);
-
- CanonicalPath projection
- = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
- trait_type_seg,
- impl_type_seg);
- CanonicalPath impl_prefix = prefix.append (projection);
-
- resolver->get_name_scope ().insert (
- impl_prefix, impl_block.get_node_id (), impl_block.get_locus (), false,
- Rib::ItemType::TraitImpl,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, impl_block.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- for (auto &impl_item : impl_block.get_impl_items ())
- ResolveToplevelImplItem::go (*impl_item, impl_prefix);
- }
-
- void visit (AST::Trait &trait) override
- {
- auto decl = CanonicalPath::new_seg (trait.get_node_id (),
- trait.get_identifier ().as_string ());
- auto path = prefix.append (decl);
- auto cpath = canonical_prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, trait.get_node_id (), trait.get_locus (), false,
- Rib::ItemType::Trait,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, trait.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- for (auto &item : trait.get_trait_items ())
- ResolveTopLevelTraitItems::go (item.get (), path, cpath);
-
- NodeId current_module = resolver->peek_current_module_scope ();
- mappings.insert_module_child_item (current_module, decl);
- mappings.insert_canonical_path (trait.get_node_id (), cpath);
- }
-
- void visit (AST::ExternBlock &extern_block) override
- {
- for (auto &item : extern_block.get_extern_items ())
- {
- ResolveToplevelExternItem::go (*item, prefix);
- }
- }
-
- void visit (AST::ExternCrate &extern_crate) override
- {
- if (extern_crate.is_marked_for_strip ())
- return;
-
- NodeId resolved_crate = UNKNOWN_NODEID;
- if (extern_crate.references_self ())
- {
- CrateNum crate_num = mappings.get_current_crate ();
- resolved_crate = mappings.crate_num_to_nodeid (crate_num).value ();
- }
- else
- {
- auto cnum
- = mappings.lookup_crate_name (extern_crate.get_referenced_crate ());
- if (!cnum)
- {
- rust_error_at (extern_crate.get_locus (), "unknown crate %qs",
- extern_crate.get_referenced_crate ().c_str ());
- return;
- }
- if (auto resolved = mappings.crate_num_to_nodeid (*cnum))
- resolved_crate = resolved.value ();
- else
- {
- rust_internal_error_at (extern_crate.get_locus (),
- "failed to resolve crate to nodeid");
- return;
- }
- }
-
- if (resolved_crate == UNKNOWN_NODEID)
- {
- rust_error_at (extern_crate.get_locus (), "failed to resolve crate");
- return;
- }
-
- // mark the node as resolved
- resolver->insert_resolved_name (extern_crate.get_node_id (),
- resolved_crate);
- CanonicalPath decl
- = extern_crate.has_as_clause ()
- ? CanonicalPath::new_seg (extern_crate.get_node_id (),
- extern_crate.get_as_clause ())
- : CanonicalPath::new_seg (extern_crate.get_node_id (),
- extern_crate.get_referenced_crate ());
-
- resolver->get_type_scope ().insert (
- decl, resolved_crate, extern_crate.get_locus (), false,
- Rib::ItemType::ExternCrate,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, extern_crate.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
- }
-
-private:
- ResolveTopLevel (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
- {}
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_AST_RESOLVE_TOPLEVEL_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
deleted file mode 100644
index a040228..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ /dev/null
@@ -1,785 +0,0 @@
-// Copyright (C) 2020-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-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)
-{
- type.get_elem_type ().accept_vis (*this);
- ResolveExpr::go (type.get_size_expr (), CanonicalPath::create_empty (),
- CanonicalPath::create_empty ());
-}
-
-void
-ResolveType::visit (AST::TraitObjectTypeOneBound &type)
-{
- ResolveTypeBound::go (type.get_trait_bound ());
-}
-
-void
-ResolveType::visit (AST::TraitObjectType &type)
-{
- for (auto &bound : type.get_type_param_bounds ())
- {
- /* NodeId bound_resolved_id = */
- ResolveTypeBound::go (*bound);
- }
-}
-
-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 ());
-}
-
-void
-ResolveType::visit (AST::RawPointerType &type)
-{
- resolved_node = ResolveType::go (type.get_type_pointed_to ());
-}
-
-void
-ResolveType::visit (AST::InferredType &)
-{
- // nothing to do
-}
-
-void
-ResolveType::visit (AST::NeverType &)
-{
- resolved_node = resolver->get_never_type_node_id ();
-}
-
-void
-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 ().get ());
-}
-
-// resolve relative type-paths
-
-bool
-ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
-{
- auto resolver = Resolver::get ();
- auto &mappings = Analysis::Mappings::get ();
-
- NodeId module_scope_id = resolver->peek_current_module_scope ();
- NodeId previous_resolved_node_id = module_scope_id;
- for (size_t i = 0; i < path.get_segments ().size (); i++)
- {
- auto &segment = path.get_segments ().at (i);
- bool is_first_segment = i == 0;
- 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 ();
-
- resolved_node_id = UNKNOWN_NODEID;
-
- if (segment->is_lang_item ())
- {
- resolved_node_id = Analysis::Mappings::get ().get_lang_item_node (
- segment->get_lang_item ());
- previous_resolved_node_id = resolved_node_id;
- }
- else
- {
- 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,
- "%qs in paths can only be used in start position",
- segment->as_string ().c_str ());
- return false;
- }
-
- 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 ())
- {
- case AST::TypePathSegment::SegmentType::GENERIC:
- {
- AST::TypePathSegmentGeneric *s
- = static_cast<AST::TypePathSegmentGeneric *> (segment.get ());
- if (s->has_generic_args ())
- ResolveGenericArgs::go (s->get_generic_args ());
- }
- break;
-
- case AST::TypePathSegment::SegmentType::REG:
- // nothing to do
- break;
-
- case AST::TypePathSegment::SegmentType::FUNCTION:
- AST::TypePathSegmentFunction *fnseg
- = static_cast<AST::TypePathSegmentFunction *> (segment.get ());
-
- AST::TypePathFunction &fn = fnseg->get_type_path_function ();
- for (auto &param : fn.get_params ())
- {
- ResolveType::go (*param);
- }
-
- if (fn.has_return_type ())
- {
- ResolveType::go (fn.get_return_type ());
- }
-
- break;
- }
-
- if (is_first_segment)
- {
- // name scope first
- NodeId resolved_node = UNKNOWN_NODEID;
- const CanonicalPath path
- = CanonicalPath::new_seg (segment->get_node_id (), ident_string);
- if (resolver->get_type_scope ().lookup (path, &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))
- {
- 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_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;
-
- 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;
- }
- }
-
- if (resolved_node_id == UNKNOWN_NODEID
- && previous_resolved_node_id == module_scope_id)
- {
- tl::optional<CanonicalPath &> resolved_child
- = mappings.lookup_module_child (module_scope_id, ident_string);
- if (resolved_child.has_value ())
- {
- NodeId resolved_node = resolved_child->get_node_id ();
- if (resolver->get_name_scope ().decl_was_declared_here (
- resolved_node))
- {
- resolved_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;
-
- 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",
- segment->as_string ().c_str ());
- return false;
- }
- }
- }
-
- bool did_resolve_segment = resolved_node_id != UNKNOWN_NODEID;
- if (did_resolve_segment)
- {
- if (mappings.node_is_module (resolved_node_id)
- || mappings.node_is_crate (resolved_node_id))
- {
- module_scope_id = resolved_node_id;
- }
- previous_resolved_node_id = resolved_node_id;
- }
- else if (is_first_segment)
- {
- rust_error_at (segment->get_locus (), ErrorCode::E0412,
- "could not resolve type path %qs",
- segment->get_ident_segment ().as_string ().c_str ());
- return false;
- }
- }
-
- if (resolved_node_id != UNKNOWN_NODEID)
- {
- // name scope first
- if (resolver->get_name_scope ().decl_was_declared_here (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))
- {
- 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
- {
- rust_unreachable ();
- }
- }
-
- return true;
-}
-
-// qualified type paths
-
-ResolveRelativeQualTypePath::ResolveRelativeQualTypePath ()
- : failure_flag (false)
-{}
-
-bool
-ResolveRelativeQualTypePath::go (AST::QualifiedPathInType &path)
-{
- ResolveRelativeQualTypePath o;
-
- // resolve the type and trait path
- auto &qualified_path = path.get_qualified_path_type ();
- if (!o.resolve_qual_seg (qualified_path))
- return false;
-
- // qualified types are similar to other paths in that we cannot guarantee
- // that we can resolve the path at name resolution. We must look up
- // associated types and type information to figure this out properly
-
- std::unique_ptr<AST::TypePathSegment> &associated
- = path.get_associated_segment ();
-
- associated->accept_vis (o);
- if (o.failure_flag)
- return false;
-
- for (auto &seg : path.get_segments ())
- {
- seg->accept_vis (o);
- if (o.failure_flag)
- return false;
- }
-
- return true;
-}
-
-bool
-ResolveRelativeQualTypePath::resolve_qual_seg (AST::QualifiedPathType &seg)
-{
- if (seg.is_error ())
- {
- rust_error_at (seg.get_locus (), "segment has error: %s",
- seg.as_string ().c_str ());
- return false;
- }
-
- auto &type = seg.get_type ();
- ResolveType::go (type);
-
- if (seg.has_as_clause ())
- ResolveType::go (seg.get_as_type_path ());
-
- return true;
-}
-
-void
-ResolveRelativeQualTypePath::visit (AST::TypePathSegmentGeneric &seg)
-{
- if (seg.is_error ())
- {
- failure_flag = true;
- rust_error_at (seg.get_locus (), "segment has error: %s",
- seg.as_string ().c_str ());
- return;
- }
-
- ResolveGenericArgs::go (seg.get_generic_args ());
-}
-
-void
-ResolveRelativeQualTypePath::visit (AST::TypePathSegment &seg)
-{
- if (seg.is_error ())
- {
- failure_flag = true;
- rust_error_at (seg.get_locus (), "segment has error: %s",
- seg.as_string ().c_str ());
- return;
- }
-}
-
-// resolve to canonical path
-
-bool
-ResolveTypeToCanonicalPath::go (AST::Type &type, CanonicalPath &result)
-{
- ResolveTypeToCanonicalPath resolver;
- type.accept_vis (resolver);
- result = resolver.result;
- return !resolver.result.is_empty ();
-}
-
-void
-ResolveTypeToCanonicalPath::visit (AST::TypePath &path)
-{
- NodeId resolved_node = UNKNOWN_NODEID;
- if (!resolver->lookup_resolved_name (path.get_node_id (), &resolved_node))
- {
- resolver->lookup_resolved_type (path.get_node_id (), &resolved_node);
- }
-
- if (resolved_node == UNKNOWN_NODEID)
- return;
-
- if (auto type_path = mappings.lookup_canonical_path (resolved_node))
- {
- auto &final_seg = path.get_segments ().back ();
- switch (final_seg->get_type ())
- {
- case AST::TypePathSegment::SegmentType::GENERIC:
- {
- AST::TypePathSegmentGeneric *s
- = static_cast<AST::TypePathSegmentGeneric *> (final_seg.get ());
-
- std::vector<CanonicalPath> args;
- if (s->has_generic_args ())
- {
- ResolveGenericArgs::go (s->get_generic_args ());
- for (auto &generic : s->get_generic_args ().get_generic_args ())
- {
- // FIXME: What do we want to do here in case there is a
- // constant or an ambiguous const generic?
- // TODO: At that point, will all generics have been
- // disambiguated? Can we thus canonical resolve types and
- // const and `rust_unreachable` on ambiguous types?
- // This is probably fine as we just want to canonicalize
- // types, right?
- if (generic.get_kind () == AST::GenericArg::Kind::Type)
- {
- CanonicalPath arg = CanonicalPath::create_empty ();
- bool ok
- = ResolveTypeToCanonicalPath::go (generic.get_type (),
- arg);
- if (ok)
- args.push_back (std::move (arg));
- }
- }
- }
-
- result = *type_path;
- if (!args.empty ())
- {
- // append this onto the path
- std::string buf;
- for (size_t i = 0; i < args.size (); i++)
- {
- bool has_next = (i + 1) < args.size ();
- const auto &arg = args.at (i);
-
- buf += arg.get ();
- if (has_next)
- buf += ", ";
- }
-
- std::string arg_seg = "<" + buf + ">";
- CanonicalPath argument_seg
- = CanonicalPath::new_seg (s->get_node_id (), arg_seg);
- result = result.append (argument_seg);
- }
- }
- break;
-
- default:
- result = *type_path;
- break;
- }
- }
-}
-
-void
-ResolveTypeToCanonicalPath::visit (AST::ReferenceType &type)
-{
- CanonicalPath path = CanonicalPath::create_empty ();
- bool ok = ResolveTypeToCanonicalPath::go (type.get_type_referenced (), path);
- if (ok)
- {
- std::string ref_type_str = type.is_mut () ? "mut" : "";
- std::string ref_path = "&" + ref_type_str + " " + path.get ();
- result = CanonicalPath::new_seg (type.get_node_id (), ref_path);
- }
-}
-
-void
-ResolveTypeToCanonicalPath::visit (AST::RawPointerType &type)
-{
- CanonicalPath path = CanonicalPath::create_empty ();
- bool ok = ResolveTypeToCanonicalPath::go (type.get_type_pointed_to (), path);
- if (ok)
- {
- std::string ptr_type_str
- = type.get_pointer_type () == AST::RawPointerType::CONST ? "const"
- : "mut";
- std::string ptr_path = "*" + ptr_type_str + " " + path.get ();
- result = CanonicalPath::new_seg (type.get_node_id (), ptr_path);
- }
-}
-
-void
-ResolveTypeToCanonicalPath::visit (AST::SliceType &type)
-{
- CanonicalPath path = CanonicalPath::create_empty ();
- bool ok = ResolveTypeToCanonicalPath::go (type.get_elem_type (), path);
- if (ok)
- {
- std::string slice_path = "[" + path.get () + "]";
- result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
- }
-}
-
-void
-ResolveTypeToCanonicalPath::visit (AST::TraitObjectTypeOneBound &type)
-{
- CanonicalPath path = CanonicalPath::create_empty ();
- bool ok
- = ResolveTypeToCanonicalPath::go (type.get_trait_bound ().get_type_path (),
- path);
- if (ok)
- {
- std::string slice_path = "<dyn " + path.get () + ">";
- result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
- }
-}
-
-void
-ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type)
-{
- 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
-ResolveTypeToCanonicalPath::visit (AST::NeverType &type)
-{
- result = CanonicalPath::new_seg (type.get_node_id (), "!");
-}
-
-void
-ResolveTypeToCanonicalPath::visit (AST::TupleType &type)
-{
- if (!type.is_unit_type ())
- rust_unreachable ();
-
- result = CanonicalPath::new_seg (type.get_node_id (), "()");
-}
-
-ResolveTypeToCanonicalPath::ResolveTypeToCanonicalPath ()
- : ResolverBase (), result (CanonicalPath::create_empty ())
-{}
-
-bool
-ResolveGenericArgs::is_const_value_name (const CanonicalPath &path)
-{
- NodeId resolved;
- auto found = resolver->get_name_scope ().lookup (path, &resolved);
-
- return found;
-}
-
-bool
-ResolveGenericArgs::is_type_name (const CanonicalPath &path)
-{
- NodeId resolved;
- auto found = resolver->get_type_scope ().lookup (path, &resolved);
-
- return found;
-}
-
-void
-ResolveGenericArgs::disambiguate (AST::GenericArg &arg)
-{
- auto path = canonical_prefix.append (
- CanonicalPath::new_seg (UNKNOWN_NODEID, arg.get_path ()));
-
- auto is_type = is_type_name (path);
- auto is_value = is_const_value_name (path);
-
- // In case we cannot find anything, we resolve the ambiguity to a type.
- // This causes the typechecker to error out properly and when necessary.
- // But types also take priority over const values in the case of
- // ambiguities, hence the weird control flow
- if (is_type || (!is_type && !is_value))
- arg = arg.disambiguate_to_type ();
- else if (is_value)
- arg = arg.disambiguate_to_const ();
-}
-
-void
-ResolveGenericArgs::resolve_disambiguated_generic (AST::GenericArg &arg)
-{
- switch (arg.get_kind ())
- {
- case AST::GenericArg::Kind::Const:
- ResolveExpr::go (arg.get_expression (), prefix, canonical_prefix);
- break;
- case AST::GenericArg::Kind::Type:
- ResolveType::go (arg.get_type ());
- break;
- default:
- rust_unreachable ();
- }
-}
-void
-ResolveGenericArgs::go (AST::GenericArgs &generic_args)
-{
- auto empty = CanonicalPath::create_empty ();
-
- go (generic_args, empty, empty);
-}
-
-void
-ResolveGenericArgs::go (AST::GenericArgs &generic_args,
- const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
-{
- auto resolver = ResolveGenericArgs (prefix, canonical_prefix);
-
- for (auto &arg : generic_args.get_generic_args ())
- {
- if (arg.get_kind () == AST::GenericArg::Kind::Either)
- resolver.disambiguate (arg);
-
- resolver.resolve_disambiguated_generic (arg);
- }
-
- for (auto &binding : generic_args.get_binding_args ())
- {
- ResolveType::go (binding.get_type ());
- }
-}
-
-} // namespace Resolver
-} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
deleted file mode 100644
index f1481fc..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright (C) 2020-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_AST_RESOLVE_TYPE_H
-#define RUST_AST_RESOLVE_TYPE_H
-
-#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 {
-
-class ResolveRelativeTypePath
-{
-public:
- static bool go (AST::TypePath &path, NodeId &resolved_node_id);
-};
-
-class ResolveRelativeQualTypePath : public ResolverBase
-{
- using ResolverBase::visit;
-
-public:
- static bool go (AST::QualifiedPathInType &path);
-
- void visit (AST::TypePathSegmentGeneric &seg) override;
-
- void visit (AST::TypePathSegment &seg) override;
-
-protected:
- bool resolve_qual_seg (AST::QualifiedPathType &seg);
-
-private:
- ResolveRelativeQualTypePath ();
-
- bool failure_flag;
-};
-
-class ResolveType : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- 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 () {}
-};
-
-class ResolveTypeBound : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static NodeId go (AST::TypeParamBound &type)
- {
- ResolveTypeBound resolver;
- type.accept_vis (resolver);
- return resolver.resolved_node;
- };
-
- void visit (AST::TraitBound &bound) override
- {
- resolved_node = ResolveType::go (bound.get_type_path ());
- }
-
-private:
- ResolveTypeBound () : ResolverBase () {}
-};
-
-class ResolveGenericParams : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (std::vector<std::unique_ptr<AST::GenericParam>> &params,
- const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- {
- 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);
- }
-
- static void go_single (AST::GenericParam &param, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- {
- ResolveGenericParams resolver (prefix, canonical_prefix);
-
- param.accept_vis (resolver);
- resolver.first_pass = false;
- param.accept_vis (resolver);
- }
-
- void visit (AST::ConstGenericParam &param) override
- {
- 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);
- }
-
- 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);
- }
- }
-
-private:
- ResolveGenericParams (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), first_pass (true), prefix (prefix),
- canonical_prefix (canonical_prefix)
- {}
-
- bool first_pass;
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-};
-
-class ResolveWhereClause : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void Resolve (AST::WhereClause &where_clause)
- {
- ResolveWhereClause r;
- for (auto &clause : where_clause.get_items ())
- clause->accept_vis (r);
- }
-
- void visit (AST::TypeBoundWhereClauseItem &item) override
- {
- ResolveType::go (item.get_type ());
- if (item.has_type_param_bounds ())
- {
- for (auto &bound : item.get_type_param_bounds ())
- {
- ResolveTypeBound::go (*bound);
- }
- }
- }
-
-private:
- ResolveWhereClause () : ResolverBase () {}
-};
-
-class ResolveTypeToCanonicalPath : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static bool go (AST::Type &type, CanonicalPath &result);
-
- void visit (AST::TypePath &path) override;
-
- void visit (AST::ReferenceType &type) override;
-
- void visit (AST::RawPointerType &type) override;
-
- void visit (AST::SliceType &type) override;
-
- void visit (AST::TraitObjectTypeOneBound &type) override;
-
- void visit (AST::TraitObjectType &type) override;
-
- void visit (AST::NeverType &type) override;
-
- void visit (AST::TupleType &type) override;
-
-private:
- ResolveTypeToCanonicalPath ();
-
- CanonicalPath result;
-};
-
-class ResolveGenericArgs : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::GenericArgs &generic_args);
- static void go (AST::GenericArgs &generic_args, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix);
-
-private:
- ResolveGenericArgs (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
- {}
-
- bool is_type_name (const CanonicalPath &path);
- bool is_const_value_name (const CanonicalPath &path);
-
- /**
- * Resolve a disambiguated generic arg
- */
- void disambiguate (AST::GenericArg &arg);
-
- /**
- * Resolve a disambiguated generic arg
- */
- void resolve_disambiguated_generic (AST::GenericArg &arg);
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_AST_RESOLVE_TYPE_H
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
deleted file mode 100644
index 2208f70..0000000
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (C) 2020-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-ast-resolve.h"
-#include "rust-ast-full.h"
-#include "rust-tyty.h"
-#include "rust-ast-resolve-toplevel.h"
-#include "rust-ast-resolve-item.h"
-#include "rust-ast-resolve-expr.h"
-#include "rust-ast-resolve-struct-expr-field.h"
-
-extern bool saw_errors (void);
-
-namespace Rust {
-namespace Resolver {
-
-// NameResolution
-
-NameResolution *
-NameResolution::get ()
-{
- static NameResolution *instance;
- if (instance == nullptr)
- instance = new NameResolution ();
-
- return instance;
-}
-
-NameResolution::NameResolution ()
- : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ())
-{
- // these are global
- resolver->get_type_scope ().push (mappings.get_next_node_id ());
- resolver->insert_builtin_types (resolver->get_type_scope ().peek ());
- resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-}
-
-void
-NameResolution::Resolve (AST::Crate &crate)
-{
- auto resolver = get ();
- resolver->go (crate);
-}
-
-void
-NameResolution::go (AST::Crate &crate)
-{
- // lookup current crate name
- CrateNum cnum = mappings.get_current_crate ();
-
- // Clones the crate name instead of references due to gcc's possibly
- // dangling references warnings
- const auto crate_name = mappings.get_crate_name (cnum).value ();
-
- // setup the ribs
- NodeId scope_node_id = crate.get_node_id ();
- resolver->get_name_scope ().push (scope_node_id);
- resolver->get_type_scope ().push (scope_node_id);
- 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_label_scope ().peek ());
-
- // get the root segment
- CanonicalPath crate_prefix
- = CanonicalPath::new_seg (scope_node_id, crate_name);
- crate_prefix.set_crate_num (cnum);
-
- // setup a dummy crate node
- resolver->get_name_scope ().insert (
- CanonicalPath::new_seg (crate.get_node_id (), "__$$crate__"),
- crate.get_node_id (), UNDEF_LOCATION);
-
- // setup the root scope
- resolver->push_new_module_scope (scope_node_id);
-
- // first gather the top-level namespace names then we drill down so this
- // allows for resolving forward declarations since an impl block might have
- // a Self type Foo which is defined after the impl block for example.
- for (auto &item : crate.items)
- ResolveTopLevel::go (*item, CanonicalPath::create_empty (), crate_prefix);
-
- // FIXME remove this
- if (saw_errors ())
- {
- resolver->pop_module_scope ();
- return;
- }
-
- // next we can drill down into the items and their scopes
- for (auto &item : crate.items)
- ResolveItem::go (*item, CanonicalPath::create_empty (), crate_prefix);
-
- // done
- resolver->pop_module_scope ();
-}
-
-} // namespace Resolver
-} // namespace Rust
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 4fd1dd2..0dff831 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -438,7 +438,9 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
// 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);
+ // Erroneous `self` or `{self}` use declaration
+ if (segments.size () == 1)
+ break;
declared_name = segments[segments.size () - 2].as_string ();
}
else
@@ -447,8 +449,8 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
break;
}
case AST::UseTreeRebind::NewBindType::WILDCARD:
- rust_unreachable ();
- break;
+ // We don't want to insert it into the trie
+ return;
}
for (auto &&definition : data.definitions ())
@@ -459,6 +461,19 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
void
Early::visit (AST::UseDeclaration &decl)
{
+ // We do not want to visit the use trees, we're only looking for top level
+ // rebind. eg. `use something;` or `use something::other;`
+ if (decl.get_tree ()->get_kind () == AST::UseTree::Kind::Rebind)
+ {
+ auto &rebind = static_cast<AST::UseTreeRebind &> (*decl.get_tree ());
+ if (rebind.get_path ().get_final_segment ().is_lower_self_seg ())
+ {
+ collect_error (
+ Error (decl.get_locus (), ErrorCode::E0429,
+ "%<self%> imports are only allowed within a { } list"));
+ }
+ }
+
auto &imports = toplevel.get_imports_to_resolve ();
auto current_import = imports.find (decl.get_node_id ());
if (current_import != imports.end ())
@@ -484,5 +499,31 @@ Early::visit (AST::UseDeclaration &decl)
DefaultResolver::visit (decl);
}
+void
+Early::visit (AST::UseTreeList &use_list)
+{
+ if (!use_list.has_path ())
+ {
+ for (auto &&tree : use_list.get_trees ())
+ {
+ if (tree->get_kind () == AST::UseTree::Kind::Rebind)
+ {
+ auto &rebind = static_cast<AST::UseTreeRebind &> (*tree);
+ auto path_size = rebind.get_path ().get_segments ().size ();
+ if (path_size == 1
+ && rebind.get_path ()
+ .get_final_segment ()
+ .is_lower_self_seg ())
+ {
+ collect_error (Error (rebind.get_locus (), ErrorCode::E0431,
+ "%<self%> import can only appear in an "
+ "import list with a non-empty prefix"));
+ }
+ }
+ }
+ }
+ DefaultResolver::visit (use_list);
+}
+
} // 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 960de0e..3940386 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -61,6 +61,7 @@ public:
void visit (AST::Function &) override;
void visit (AST::StructStruct &) override;
void visit (AST::UseDeclaration &) override;
+ void visit (AST::UseTreeList &) override;
struct ImportData
{
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc b/gcc/rust/resolve/rust-early-name-resolver.cc
deleted file mode 100644
index 7b365ef..0000000
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ /dev/null
@@ -1,589 +0,0 @@
-// Copyright (C) 2020-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-early-name-resolver.h"
-#include "rust-pattern.h"
-#include "rust-name-resolver.h"
-#include "rust-macro-builtins.h"
-#include "rust-attribute-values.h"
-
-namespace Rust {
-namespace Resolver {
-
-// Check if a module contains the `#[macro_use]` attribute
-static bool
-is_macro_use_module (const AST::Module &mod)
-{
- for (const auto &attr : mod.get_outer_attrs ())
- if (attr.get_path ().as_string () == Values::Attributes::MACRO_USE)
- return true;
-
- return false;
-}
-
-std::vector<std::unique_ptr<AST::Item>>
-EarlyNameResolver::accumulate_escaped_macros (AST::Module &module)
-{
- if (!is_macro_use_module (module))
- return {};
-
- // Parse the module's items if they haven't been expanded and the file
- // should be parsed (i.e isn't hidden behind an untrue or impossible cfg
- // directive)
- if (module.get_kind () == AST::Module::UNLOADED)
- module.load_items ();
-
- std::vector<std::unique_ptr<AST::Item>> escaped_macros;
-
- scoped (module.get_node_id (), [&module, &escaped_macros, this] {
- for (auto &item : module.get_items ())
- {
- if (item->get_item_kind () == AST::Item::Kind::Module)
- {
- auto &module = *static_cast<AST::Module *> (item.get ());
- auto new_macros = accumulate_escaped_macros (module);
-
- std::move (new_macros.begin (), new_macros.end (),
- std::back_inserter (escaped_macros));
-
- continue;
- }
-
- if (item->get_item_kind () == AST::Item::Kind::MacroRulesDefinition)
- escaped_macros.emplace_back (item->clone_item ());
- }
- });
-
- return escaped_macros;
-}
-
-EarlyNameResolver::EarlyNameResolver ()
- : current_scope (UNKNOWN_NODEID), resolver (*Resolver::get ()),
- mappings (Analysis::Mappings::get ())
-{}
-
-void
-EarlyNameResolver::go (AST::Crate &crate)
-{
- visit (crate);
-}
-
-void
-EarlyNameResolver::resolve_generic_args (AST::GenericArgs &generic_args)
-{
- for (auto &arg : generic_args.get_generic_args ())
- arg.accept_vis (*this);
-
- for (auto &arg : generic_args.get_binding_args ())
- arg.get_type ().accept_vis (*this);
-}
-
-void
-EarlyNameResolver::resolve_qualified_path_type (AST::QualifiedPathType &path)
-{
- path.get_type ().accept_vis (*this);
-
- if (path.has_as_clause ())
- path.get_as_type_path ().accept_vis (*this);
-}
-
-void
-EarlyNameResolver::visit (AST::Crate &crate)
-{
- std::vector<std::unique_ptr<AST::Item>> new_items;
- auto items = crate.take_items ();
-
- scoped (crate.get_node_id (), [&items, &new_items, this] {
- for (auto &&item : items)
- {
- auto new_macros = std::vector<std::unique_ptr<AST::Item>> ();
-
- if (item->get_item_kind () == AST::Item::Kind::Module)
- new_macros = accumulate_escaped_macros (
- *static_cast<AST::Module *> (item.get ()));
-
- new_items.emplace_back (std::move (item));
- std::move (new_macros.begin (), new_macros.end (),
- std::back_inserter (new_items));
- }
- });
-
- crate.set_items (std::move (new_items));
-
- scoped (crate.get_node_id (), [&crate, this] () {
- for (auto &item : crate.items)
- item->accept_vis (*this);
- });
-}
-
-void
-EarlyNameResolver::visit (AST::DelimTokenTree &)
-{}
-
-void
-EarlyNameResolver::visit (AST::AttrInputMetaItemContainer &)
-{}
-
-void
-EarlyNameResolver::visit (AST::IdentifierExpr &)
-{}
-
-void
-EarlyNameResolver::visit (AST::LifetimeParam &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ConstGenericParam &)
-{}
-
-// FIXME: ARTHUR: Do we need to perform macro resolution for paths as well?
-// std::arch::asm!()?
-void
-EarlyNameResolver::visit (AST::PathInExpression &path)
-{
- if (!path.is_lang_item ())
- for (auto &segment : path.get_segments ())
- if (segment.has_generic_args ())
- resolve_generic_args (segment.get_generic_args ());
-}
-
-void
-EarlyNameResolver::visit (AST::TypePathSegmentGeneric &segment)
-{
- if (segment.has_generic_args ())
- resolve_generic_args (segment.get_generic_args ());
-}
-
-void
-EarlyNameResolver::visit (AST::QualifiedPathInExpression &path)
-{
- resolve_qualified_path_type (path.get_qualified_path_type ());
-
- for (auto &segment : path.get_segments ())
- if (segment.has_generic_args ())
- resolve_generic_args (segment.get_generic_args ());
-}
-
-void
-EarlyNameResolver::visit (AST::QualifiedPathInType &path)
-{
- resolve_qualified_path_type (path.get_qualified_path_type ());
-
- for (auto &segment : path.get_segments ())
- segment->accept_vis (*this);
-}
-
-void
-EarlyNameResolver::visit (AST::LiteralExpr &)
-{}
-
-void
-EarlyNameResolver::visit (AST::AttrInputLiteral &)
-{}
-
-void
-EarlyNameResolver::visit (AST::AttrInputMacro &)
-{}
-
-void
-EarlyNameResolver::visit (AST::MetaItemLitExpr &)
-{}
-
-void
-EarlyNameResolver::visit (AST::MetaItemPathExpr &)
-{}
-
-void
-EarlyNameResolver::visit (AST::StructExprStruct &)
-{}
-
-void
-EarlyNameResolver::visit (AST::StructExprFieldIdentifier &)
-{}
-
-void
-EarlyNameResolver::visit (AST::StructExprStructBase &)
-{}
-
-void
-EarlyNameResolver::visit (AST::BlockExpr &expr)
-{
- scoped (expr.get_node_id (), [&expr, this] () {
- for (auto &stmt : expr.get_statements ())
- stmt->accept_vis (*this);
-
- if (expr.has_tail_expr ())
- expr.get_tail_expr ().accept_vis (*this);
- });
-}
-
-void
-EarlyNameResolver::visit (AST::ContinueExpr &)
-{}
-
-void
-EarlyNameResolver::visit (AST::RangeFullExpr &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ForLoopExpr &expr)
-{
- scoped (expr.get_node_id (), [&expr, this] () {
- expr.get_pattern ().accept_vis (*this);
- expr.get_iterator_expr ().accept_vis (*this);
- expr.get_loop_block ().accept_vis (*this);
- });
-}
-
-void
-EarlyNameResolver::visit (AST::IfLetExpr &expr)
-{
- expr.get_value_expr ().accept_vis (*this);
-
- scoped (expr.get_node_id (),
- [&expr, this] () { expr.get_if_block ().accept_vis (*this); });
-}
-
-void
-EarlyNameResolver::visit (AST::MatchExpr &expr)
-{
- expr.get_scrutinee_expr ().accept_vis (*this);
-
- scoped (expr.get_node_id (), [&expr, this] () {
- for (auto &arm : expr.get_match_cases ())
- {
- scoped (arm.get_node_id (), [&arm, this] () {
- if (arm.get_arm ().has_match_arm_guard ())
- arm.get_arm ().get_guard_expr ().accept_vis (*this);
-
- for (auto &pattern : arm.get_arm ().get_patterns ())
- pattern->accept_vis (*this);
-
- arm.get_expr ().accept_vis (*this);
- });
- }
- });
-}
-
-void
-EarlyNameResolver::visit (AST::LifetimeWhereClauseItem &)
-{}
-
-void
-EarlyNameResolver::visit (AST::Module &module)
-{
- if (module.get_kind () == AST::Module::UNLOADED)
- module.load_items ();
-
- // so we need to only go "one scope down" for fetching macros. Macros within
- // functions are still scoped only within that function. But we have to be
- // careful because nested modules with #[macro_use] actually works!
- std::vector<std::unique_ptr<AST::Item>> new_items;
- auto items = module.take_items ();
-
- scoped (module.get_node_id (), [&items, &new_items, this] {
- for (auto &&item : items)
- {
- auto new_macros = std::vector<std::unique_ptr<AST::Item>> ();
-
- if (item->get_item_kind () == AST::Item::Kind::Module)
- new_macros = accumulate_escaped_macros (
- *static_cast<AST::Module *> (item.get ()));
-
- new_items.emplace_back (std::move (item));
- std::move (new_macros.begin (), new_macros.end (),
- std::back_inserter (new_items));
- }
- });
-
- module.set_items (std::move (new_items));
-
- scoped (module.get_node_id (), [&module, this] () {
- for (auto &item : module.get_items ())
- item->accept_vis (*this);
- });
-}
-
-void
-EarlyNameResolver::visit (AST::ExternCrate &)
-{}
-
-void
-EarlyNameResolver::visit (AST::UseTreeGlob &)
-{}
-
-void
-EarlyNameResolver::visit (AST::UseTreeList &)
-{}
-
-void
-EarlyNameResolver::visit (AST::UseTreeRebind &)
-{}
-
-void
-EarlyNameResolver::visit (AST::UseDeclaration &)
-{}
-
-void
-EarlyNameResolver::visit (AST::EnumItem &)
-{}
-
-void
-EarlyNameResolver::visit (AST::Union &)
-{}
-
-void
-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);
-
- scoped (trait.get_node_id (), [&trait, this] () {
- for (auto &item : trait.get_trait_items ())
- item->accept_vis (*this);
- });
-}
-
-void
-EarlyNameResolver::visit (AST::InherentImpl &impl)
-{
- impl.get_type ().accept_vis (*this);
-
- for (auto &generic : impl.get_generic_params ())
- generic->accept_vis (*this);
-
- scoped (impl.get_node_id (), [&impl, this] () {
- for (auto &item : impl.get_impl_items ())
- item->accept_vis (*this);
- });
-}
-
-void
-EarlyNameResolver::visit (AST::TraitImpl &impl)
-{
- impl.get_type ().accept_vis (*this);
-
- for (auto &generic : impl.get_generic_params ())
- generic->accept_vis (*this);
-
- scoped (impl.get_node_id (), [&impl, this] () {
- for (auto &item : impl.get_impl_items ())
- item->accept_vis (*this);
- });
-}
-
-void
-EarlyNameResolver::visit (AST::ExternalTypeItem &item)
-{
- // nothing to do?
-}
-
-void
-EarlyNameResolver::visit (AST::ExternBlock &block)
-{
- scoped (block.get_node_id (), [&block, this] () {
- for (auto &item : block.get_extern_items ())
- item->accept_vis (*this);
- });
-}
-
-void
-EarlyNameResolver::visit (AST::MacroMatchRepetition &)
-{}
-
-void
-EarlyNameResolver::visit (AST::MacroMatcher &)
-{}
-
-void
-EarlyNameResolver::visit (AST::MacroRulesDefinition &rules_def)
-{
- auto path = CanonicalPath::new_seg (rules_def.get_node_id (),
- rules_def.get_rule_name ().as_string ());
- resolver.get_macro_scope ().insert (path, rules_def.get_node_id (),
- rules_def.get_locus ());
-
- /* Since the EarlyNameResolver runs multiple time (fixed point algorithm)
- * we could be inserting the same macro def over and over again until we
- * implement some optimizations */
- // FIXME: ARTHUR: Remove that lookup and add proper optimizations instead
- if (mappings.lookup_macro_def (rules_def.get_node_id ()))
- return;
-
- mappings.insert_macro_def (&rules_def);
- rust_debug_loc (rules_def.get_locus (), "inserting macro def: [%s]",
- path.get ().c_str ());
-}
-
-void
-EarlyNameResolver::visit (AST::MacroInvocation &invoc)
-{
- auto &invoc_data = invoc.get_invoc_data ();
- auto has_semicolon = invoc.has_semicolon ();
-
- if (invoc.get_kind () == AST::MacroInvocation::InvocKind::Builtin)
- for (auto &pending_invoc : invoc.get_pending_eager_invocations ())
- pending_invoc->accept_vis (*this);
-
- // ??
- // switch on type of macro:
- // - '!' syntax macro (inner switch)
- // - procedural macro - "A token-based function-like macro"
- // - 'macro_rules' (by example/pattern-match) macro? or not? "an
- // AST-based function-like macro"
- // - else is unreachable
- // - attribute syntax macro (inner switch)
- // - procedural macro attribute syntax - "A token-based attribute
- // macro"
- // - legacy macro attribute syntax? - "an AST-based attribute macro"
- // - non-macro attribute: mark known
- // - else is unreachable
- // - derive macro (inner switch)
- // - derive or legacy derive - "token-based" vs "AST-based"
- // - else is unreachable
- // - derive container macro - unreachable
-
- // lookup the rules for this macro
- NodeId resolved_node = UNKNOWN_NODEID;
- NodeId source_node = UNKNOWN_NODEID;
- if (has_semicolon)
- source_node = invoc.get_macro_node_id ();
- else
- source_node = invoc.get_node_id ();
- auto seg
- = CanonicalPath::new_seg (source_node, invoc_data.get_path ().as_string ());
-
- bool found = resolver.get_macro_scope ().lookup (seg, &resolved_node);
- if (!found)
- {
- rust_error_at (invoc.get_locus (), ErrorCode::E0433,
- "could not resolve macro invocation %qs",
- seg.get ().c_str ());
- return;
- }
-
- // lookup the rules
- auto rules_def = mappings.lookup_macro_def (resolved_node);
-
- auto &outer_attrs = rules_def.value ()->get_outer_attrs ();
- bool is_builtin
- = std::any_of (outer_attrs.begin (), outer_attrs.end (),
- [] (AST::Attribute attr) {
- return attr.get_path ()
- == Values::Attributes::RUSTC_BUILTIN_MACRO;
- });
-
- if (is_builtin)
- {
- auto builtin_kind = builtin_macro_from_string (
- rules_def.value ()->get_rule_name ().as_string ());
- invoc.map_to_builtin (builtin_kind.value ());
- }
-
- auto attributes = rules_def.value ()->get_outer_attrs ();
-
- /* Since the EarlyNameResolver runs multiple time (fixed point algorithm)
- * we could be inserting the same macro def over and over again until we
- * implement some optimizations */
- // FIXME: ARTHUR: Remove that lookup and add proper optimizations instead
- if (mappings.lookup_macro_invocation (invoc))
- return;
-
- mappings.insert_macro_invocation (invoc, *rules_def);
-}
-
-// FIXME: ARTHUR: Do we need to resolve these as well here?
-
-void
-EarlyNameResolver::visit (AST::MetaItemPath &)
-{}
-
-void
-EarlyNameResolver::visit (AST::MetaItemSeq &)
-{}
-
-void
-EarlyNameResolver::visit (AST::MetaNameValueStr &)
-{}
-
-void
-EarlyNameResolver::visit (AST::MetaListPaths &)
-{}
-
-void
-EarlyNameResolver::visit (AST::MetaListNameValueStr &)
-{}
-
-void
-EarlyNameResolver::visit (AST::RangePatternBoundLiteral &)
-{}
-
-void
-EarlyNameResolver::visit (AST::RangePatternBoundPath &)
-{}
-
-void
-EarlyNameResolver::visit (AST::RangePatternBoundQualPath &)
-{}
-
-void
-EarlyNameResolver::visit (AST::StructPatternFieldIdent &)
-{}
-
-void
-EarlyNameResolver::visit (AST::StructPattern &)
-{}
-
-void
-EarlyNameResolver::visit (AST::TupleStructPattern &pattern)
-{
- pattern.get_items ().accept_vis (*this);
-}
-
-void
-EarlyNameResolver::visit (AST::TupleType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::RawPointerType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ReferenceType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ArrayType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::SliceType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::InferredType &)
-{}
-
-} // namespace Resolver
-} // namespace Rust
diff --git a/gcc/rust/resolve/rust-early-name-resolver.h b/gcc/rust/resolve/rust-early-name-resolver.h
deleted file mode 100644
index d3c5225..0000000
--- a/gcc/rust/resolve/rust-early-name-resolver.h
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (C) 2020-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_EARLY_NAME_RESOLVER_H
-#define RUST_EARLY_NAME_RESOLVER_H
-
-#include "rust-name-resolver.h"
-#include "rust-system.h"
-#include "rust-ast.h"
-#include "rust-ast-visitor.h"
-
-namespace Rust {
-namespace Resolver {
-
-class EarlyNameResolver : public AST::DefaultASTVisitor
-{
-public:
- EarlyNameResolver ();
-
- void go (AST::Crate &crate);
-
-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
- * no errors can be committed
- */
- void scoped (NodeId scope_id, std::function<void ()> fn)
- {
- auto old_scope = current_scope;
- current_scope = scope_id;
- resolver.get_macro_scope ().push (scope_id);
- resolver.push_new_macro_rib (resolver.get_macro_scope ().peek ());
-
- fn ();
-
- resolver.get_macro_scope ().pop ();
- current_scope = old_scope;
- }
-
- /**
- * Accumulate all of the nested macros which escape their module through the
- * use of the #[macro_use] attribute.
- *
- * This function recursively accumulates macros in all of the nested modules
- * of an item container (an AST::Crate or an AST::Module) and returns this new
- * list of items. You can then use the `take_items` and `set_items` functions
- * on these containers to replace their list of items.
- */
- std::vector<std::unique_ptr<AST::Item>>
- accumulate_escaped_macros (AST::Module &module);
-
- /**
- * The "scope" we are currently in.
- *
- * This involves lexical scopes:
- *
- * ```rust
- * // current_scope = crate_id;
- * macro_rules! foo { () => {} )
- *
- * {
- * // current_scope = current_block_id;
- * macro_rules! foo { () => { something!(); } }
- * }
- * // current_scope = crate_id;
- * ```
- *
- * as well as any sort of scope-like structure that might impact import name
- * resolution or macro name resolution:
- *
- * ```rust
- * macro_rules! foo {
- * () => { fn empty() {} }
- * }
- *
- *
- * trait Foo {
- * fn foo() {
- * fn inner_foo() {
- * macro_rules! foo { () => {} )
- *
- * foo!();
- * }
- *
- * foo!();
- * }
- *
- * foo!();
- * }
- *
- * foo!();
- * ```
- */
- NodeId current_scope;
-
- /* The crate's scope */
- NodeId crate_scope;
-
- Resolver &resolver;
- Analysis::Mappings &mappings;
-
- /**
- * Early name-resolve generic args, which can be macro invocations
- */
- void resolve_generic_args (AST::GenericArgs &generic_args);
-
- /**
- * Early name-resolve a qualified path type, which can contain macro
- * invocations
- */
- void resolve_qualified_path_type (AST::QualifiedPathType &path);
-
- virtual void visit (AST::Crate &crate);
- virtual void visit (AST::DelimTokenTree &delim_tok_tree);
- virtual void visit (AST::AttrInputMetaItemContainer &input);
- virtual void visit (AST::IdentifierExpr &ident_expr);
- virtual void visit (AST::LifetimeParam &lifetime_param);
- virtual void visit (AST::ConstGenericParam &const_param);
- virtual void visit (AST::PathInExpression &path);
- virtual void visit (AST::TypePathSegmentGeneric &segment);
- virtual void visit (AST::QualifiedPathInExpression &path);
- virtual void visit (AST::QualifiedPathInType &path);
- 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::MetaItemPathExpr &meta_item);
- virtual void visit (AST::StructExprStruct &expr);
- virtual void visit (AST::StructExprFieldIdentifier &field);
- virtual void visit (AST::StructExprStructBase &expr);
- virtual void visit (AST::BlockExpr &expr);
- virtual void visit (AST::ContinueExpr &expr);
- virtual void visit (AST::RangeFullExpr &expr);
- virtual void visit (AST::ForLoopExpr &expr);
- virtual void visit (AST::IfLetExpr &expr);
- virtual void visit (AST::MatchExpr &expr);
- virtual void visit (AST::LifetimeWhereClauseItem &item);
- virtual void visit (AST::Module &module);
- virtual void visit (AST::ExternCrate &crate);
- 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::EnumItem &item);
- virtual void visit (AST::Union &union_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 (AST::ExternalTypeItem &item);
- virtual void visit (AST::ExternBlock &block);
- 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::MetaNameValueStr &meta_item);
- virtual void visit (AST::MetaListPaths &meta_item);
- virtual void visit (AST::MetaListNameValueStr &meta_item);
- virtual void visit (AST::RangePatternBoundLiteral &bound);
- virtual void visit (AST::RangePatternBoundPath &bound);
- virtual void visit (AST::RangePatternBoundQualPath &bound);
- virtual void visit (AST::StructPatternFieldIdent &field);
- virtual void visit (AST::StructPattern &pattern);
- virtual void visit (AST::TupleStructPattern &pattern);
- virtual void visit (AST::TupleType &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);
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_EARLY_NAME_RESOLVER_H
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index 1ed87b3..848f5e6 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -531,7 +531,7 @@ ForeverStack<N>::resolve_segments (
|| seg.is_lower_self_seg ()))
return tl::nullopt;
- tl::optional<typename ForeverStack<N>::Node &> child = tl::nullopt;
+ tl::optional<std::reference_wrapper<Node>> child = tl::nullopt;
/*
* On every iteration this loop either
@@ -583,10 +583,17 @@ ForeverStack<N>::resolve_segments (
break;
}
- if (N == Namespace::Types)
+ auto rib_lookup = current_node->rib.get (seg.as_string ());
+ if (rib_lookup && !rib_lookup->is_ambiguous ())
{
- auto rib_lookup = current_node->rib.get (seg.as_string ());
- if (rib_lookup && !rib_lookup->is_ambiguous ())
+ if (Analysis::Mappings::get ()
+ .lookup_glob_container (rib_lookup->get_node_id ())
+ .has_value ())
+ {
+ child = dfs_node (root, rib_lookup->get_node_id ()).value ();
+ break;
+ }
+ else
{
insert_segment_resolution (outer_seg,
rib_lookup->get_node_id ());
@@ -611,9 +618,9 @@ ForeverStack<N>::resolve_segments (
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 ();
+ // if child didn't point to a value
+ // the while loop above would have returned or kept looping
+ current_node = &child->get ();
insert_segment_resolution (outer_seg, current_node->id);
}
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 e39ca15..96b38f4 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -24,6 +24,7 @@
#include "rust-late-name-resolver-2.0.h"
#include "rust-default-resolver.h"
#include "rust-name-resolution-context.h"
+#include "rust-resolve-builtins.h"
#include "rust-path.h"
#include "rust-system.h"
#include "rust-tyty.h"
@@ -38,84 +39,10 @@ Late::Late (NameResolutionContext &ctx)
: DefaultResolver (ctx), funny_error (false), block_big_self (false)
{}
-static NodeId
-next_node_id ()
-{
- return Analysis::Mappings::get ().get_next_node_id ();
-};
-
-static HirId
-next_hir_id ()
-{
- return Analysis::Mappings::get ().get_next_hir_id ();
-};
-
-void
-Late::setup_builtin_types ()
-{
- // access the global type context to setup the TyTys
- auto &ty_ctx = *Resolver::TypeCheckContext::get ();
-
- // Late builtin type struct helper
- struct LType
- {
- std::string name;
- NodeId node_id;
- NodeId hir_id;
- TyTy::BaseType *type;
-
- explicit LType (std::string name, TyTy::BaseType *type)
- : name (name), node_id (next_node_id ()), hir_id (type->get_ref ()),
- type (type)
- {}
- };
-
- static const LType builtins[] = {
- {LType ("bool", new TyTy::BoolType (next_hir_id ()))},
- {LType ("u8", new TyTy::UintType (next_hir_id (), TyTy::UintType::U8))},
- {LType ("u16", new TyTy::UintType (next_hir_id (), TyTy::UintType::U16))},
- {LType ("u32", new TyTy::UintType (next_hir_id (), TyTy::UintType::U32))},
- {LType ("u64", new TyTy::UintType (next_hir_id (), TyTy::UintType::U64))},
- {LType ("u128", new TyTy::UintType (next_hir_id (), TyTy::UintType::U128))},
- {LType ("i8", new TyTy::IntType (next_hir_id (), TyTy::IntType::I8))},
- {LType ("i16", new TyTy::IntType (next_hir_id (), TyTy::IntType::I16))},
- {LType ("i32", new TyTy::IntType (next_hir_id (), TyTy::IntType::I32))},
- {LType ("i64", new TyTy::IntType (next_hir_id (), TyTy::IntType::I64))},
- {LType ("i128", new TyTy::IntType (next_hir_id (), TyTy::IntType::I128))},
- {LType ("f32", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F32))},
- {LType ("f64", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F64))},
- {LType ("usize", new TyTy::USizeType (next_hir_id ()))},
- {LType ("isize", new TyTy::ISizeType (next_hir_id ()))},
- {LType ("char", new TyTy::CharType (next_hir_id ()))},
- {LType ("str", new TyTy::StrType (next_hir_id ()))},
- {LType ("!", new TyTy::NeverType (next_hir_id ()))},
-
- // the unit type `()` does not play a part in name-resolution - so we only
- // insert it in the type context...
- };
-
- // 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);
- }
- });
-
- // ...here!
- auto *unit_type = TyTy::TupleType::get_unit_type ();
- ty_ctx.insert_builtin (unit_type->get_ref (), next_node_id (), unit_type);
-}
-
void
Late::go (AST::Crate &crate)
{
- setup_builtin_types ();
+ Builtins::setup_type_ctx ();
visit (crate);
}
@@ -521,20 +448,22 @@ Late::visit_impl_type (AST::Type &type)
block_big_self = false;
}
-void
-Late::visit (AST::TypePath &type)
+template <typename P>
+static void
+resolve_type_path_like (NameResolutionContext &ctx, bool block_big_self,
+ P &type)
{
// should we add type path resolution in `ForeverStack` directly? Since it's
// quite more complicated.
// maybe we can overload `resolve_path<Namespace::Types>` to only do
// typepath-like path resolution? that sounds good
- DefaultResolver::visit (type);
-
// prevent "impl Self {}" and similar
if (type.get_segments ().size () == 1
- && !type.get_segments ().front ()->is_lang_item ()
- && type.get_segments ().front ()->is_big_self_seg () && block_big_self)
+ && !unwrap_segment_get_lang_item (type.get_segments ().front ())
+ .has_value ()
+ && unwrap_type_segment (type.get_segments ().front ()).is_big_self_seg ()
+ && block_big_self)
{
rust_error_at (type.get_locus (),
"%<Self%> is not valid in the self type of an impl block");
@@ -547,17 +476,17 @@ Late::visit (AST::TypePath &type)
if (!resolved.has_value ())
{
- if (!ctx.lookup (type.get_segments ().front ()->get_node_id ()))
+ if (!ctx.lookup (unwrap_segment_node_id (type.get_segments ().front ())))
rust_error_at (type.get_locus (), ErrorCode::E0412,
"could not resolve type path %qs",
- type.make_debug_string ().c_str ());
+ unwrap_segment_error_string (type).c_str ());
return;
}
if (resolved->is_ambiguous ())
{
rust_error_at (type.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
- type.make_debug_string ().c_str ());
+ unwrap_segment_error_string (type).c_str ());
return;
}
@@ -574,6 +503,14 @@ Late::visit (AST::TypePath &type)
}
void
+Late::visit (AST::TypePath &type)
+{
+ DefaultResolver::visit (type);
+
+ resolve_type_path_like (ctx, block_big_self, type);
+}
+
+void
Late::visit (AST::Visibility &vis)
{
if (!vis.has_path ())
@@ -649,10 +586,7 @@ Late::visit (AST::StructExprStruct &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 ()));
+ resolve_type_path_like (ctx, block_big_self, s.get_struct_name ());
}
void
@@ -663,10 +597,7 @@ Late::visit (AST::StructExprStructBase &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 ()));
+ resolve_type_path_like (ctx, block_big_self, s.get_struct_name ());
}
void
@@ -680,10 +611,7 @@ Late::visit (AST::StructExprStructFields &s)
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 ()));
+ resolve_type_path_like (ctx, block_big_self, s.get_struct_name ());
}
// needed because Late::visit (AST::GenericArg &) is non-virtual
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 95540e3..608ae38 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -75,9 +75,6 @@ public:
private:
void resolve_label (AST::Lifetime &lifetime);
- /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
- void setup_builtin_types ();
-
bool funny_error;
/* used to prevent "impl Self {}", "impl (Self, i32) {}", etc */
diff --git a/gcc/rust/resolve/rust-resolve-builtins.cc b/gcc/rust/resolve/rust-resolve-builtins.cc
new file mode 100644
index 0000000..b16db9a
--- /dev/null
+++ b/gcc/rust/resolve/rust-resolve-builtins.cc
@@ -0,0 +1,125 @@
+// 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-resolve-builtins.h"
+#include "rust-name-resolution-context.h"
+#include "rust-tyty.h"
+#include "rust-hir-type-check.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+namespace Builtins {
+
+// Use X-macros
+
+#define TYPE_UINT(n, enum_ident) TYPE1 (n, UintType, UintType::enum_ident)
+#define TYPE_INT(n, enum_ident) TYPE1 (n, IntType, IntType::enum_ident)
+
+#define BUILTIN_TYPES \
+ TYPE0 ("bool", BoolType) \
+ TYPE_UINT ("u8", U8) \
+ TYPE_UINT ("u16", U16) \
+ TYPE_UINT ("u32", U32) \
+ TYPE_UINT ("u64", U64) \
+ TYPE_UINT ("u128", U128) \
+ TYPE_INT ("i8", I8) \
+ TYPE_INT ("i16", I16) \
+ TYPE_INT ("i32", I32) \
+ TYPE_INT ("i64", I64) \
+ TYPE_INT ("i128", I128) \
+ TYPE1 ("f32", FloatType, FloatType::F32) \
+ TYPE1 ("f64", FloatType, FloatType::F64) \
+ TYPE0 ("usize", USizeType) \
+ TYPE0 ("isize", ISizeType) \
+ TYPE0 ("char", CharType) \
+ TYPE0 ("str", StrType) \
+ TYPE0 ("!", NeverType)
+
+// Define constants using X macros
+
+#define TYPE0(...) 1 +
+#define TYPE1(...) 1 +
+static constexpr size_t builtin_count = BUILTIN_TYPES 0;
+#undef TYPE0
+#undef TYPE1
+
+#define TYPE0(n, ...) n,
+#define TYPE1(n, ...) n,
+static constexpr const char *builtin_names[] = {BUILTIN_TYPES};
+#undef TYPE0
+#undef TYPE1
+
+static NodeId builtin_node_ids[builtin_count];
+
+void
+setup_lang_prelude (NameResolutionContext &ctx)
+{
+ auto &mappings = Analysis::Mappings::get ();
+
+ // insert into prelude rib
+ ctx.scoped (Rib::Kind::Prelude, 0, [&mappings, &ctx] (void) -> void {
+ for (size_t i = 0; i < builtin_count; i++)
+ {
+ NodeId node_id = mappings.get_next_node_id ();
+ rust_assert (ctx.types.insert (Identifier (builtin_names[i]), node_id));
+ builtin_node_ids[i] = node_id;
+ }
+ });
+}
+
+void
+setup_type_ctx ()
+{
+ auto &mappings = Analysis::Mappings::get ();
+ auto &ty_ctx = *Resolver::TypeCheckContext::get ();
+
+ HirId hir_ids[builtin_count];
+ for (size_t i = 0; i < builtin_count; i++)
+ hir_ids[i] = mappings.get_next_hir_id ();
+
+ TyTy::BaseType *types[builtin_count];
+ {
+ size_t i = 0;
+#define TYPE_BASE(stub) \
+ types[i] = new TyTy::stub; \
+ i++;
+#define TYPE0(n, ty) TYPE_BASE (ty (hir_ids[i]))
+#define TYPE1(n, ty, p1) TYPE_BASE (ty (hir_ids[i], TyTy::p1))
+ BUILTIN_TYPES
+#undef TYPE_BASE
+#undef TYPE0
+#undef TYPE1
+ }
+
+ for (size_t i = 0; i < builtin_count; i++)
+ {
+ NodeId node_id = builtin_node_ids[i];
+ HirId hir_id = hir_ids[i];
+ mappings.insert_node_to_hir (node_id, hir_id);
+ ty_ctx.insert_builtin (hir_id, node_id, types[i]);
+ }
+
+ // handle unit type separately
+ auto *unit_type = TyTy::TupleType::get_unit_type ();
+ ty_ctx.insert_builtin (unit_type->get_ref (), mappings.get_next_node_id (),
+ unit_type);
+}
+
+} // namespace Builtins
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-resolve-builtins.h b/gcc/rust/resolve/rust-resolve-builtins.h
new file mode 100644
index 0000000..e7e1bd2
--- /dev/null
+++ b/gcc/rust/resolve/rust-resolve-builtins.h
@@ -0,0 +1,37 @@
+// 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_RESOLVE_BUILTINS_H
+#define RUST_RESOLVE_BUILTINS_H
+
+namespace Rust {
+namespace Resolver2_0 {
+
+// forward declare
+class NameResolutionContext;
+
+namespace Builtins {
+
+void setup_lang_prelude (NameResolutionContext &ctx);
+void setup_type_ctx ();
+
+} // namespace Builtins
+} // namespace Resolver2_0
+} // namespace Rust
+
+#endif // RUST_RESOLVE_BUILTINS_H
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 398dea1..8f950d17 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1258,7 +1258,7 @@ constructor_expression (tree type_tree, bool is_variant,
return error_mark_node;
vec<constructor_elt, va_gc> *init;
- vec_alloc (init, vals.size ());
+ vec_alloc (init, union_index != -1 ? 1 : vals.size ());
tree sink = NULL_TREE;
bool is_constant = true;
diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index 93ce041..1088845 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -34,7 +34,6 @@
#include "selftest.h"
#include "rust-cfg-parser.h"
#include "rust-privacy-ctx.h"
-#include "rust-ast-resolve-item.h"
#include "rust-lex.h"
#include "optional.h"
#include "rust-unicode.h"
@@ -442,7 +441,6 @@ run_rust_tests ()
rust_cfg_parser_test ();
rust_privacy_ctx_test ();
rust_crate_name_validation_test ();
- rust_simple_path_resolve_test ();
}
} // namespace selftest
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 17f9c06..6418118 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -29,7 +29,6 @@
#include "rust-lex.h"
#include "rust-parse.h"
#include "rust-macro-expand.h"
-#include "rust-ast-resolve.h"
#include "rust-ast-lower.h"
#include "rust-hir-type-check.h"
#include "rust-privacy-check.h"
@@ -46,10 +45,10 @@
#include "rust-imports.h"
#include "rust-extern-crate.h"
#include "rust-attributes.h"
-#include "rust-early-name-resolver.h"
#include "rust-name-resolution-context.h"
#include "rust-early-name-resolver-2.0.h"
#include "rust-late-name-resolver-2.0.h"
+#include "rust-resolve-builtins.h"
#include "rust-cfg-strip.h"
#include "rust-expand-visitor.h"
#include "rust-unicode.h"
@@ -422,32 +421,31 @@ Session::handle_crate_name (const char *filename,
{
if (attr.get_path () != "crate_name")
continue;
- if (!attr.has_attr_input ())
+
+ auto msg_str = Analysis::Attributes::extract_string_literal (attr);
+ if (!msg_str.has_value ())
{
rust_error_at (attr.get_locus (),
- "%<crate_name%> accepts one argument");
+ "malformed %<crate_name%> attribute input");
continue;
}
- auto &literal
- = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
- const auto &msg_str = literal.get_literal ().as_string ();
- if (!validate_crate_name (msg_str, error))
+ if (!validate_crate_name (*msg_str, error))
{
error.locus = attr.get_locus ();
error.emit ();
continue;
}
- if (options.crate_name_set_manually && (options.crate_name != msg_str))
+ if (options.crate_name_set_manually && (options.crate_name != *msg_str))
{
rust_error_at (attr.get_locus (),
"%<-frust-crate-name%> and %<#[crate_name]%> are "
"required to match, but %qs does not match %qs",
- options.crate_name.c_str (), msg_str.c_str ());
+ options.crate_name.c_str (), msg_str->c_str ());
}
crate_name_found = true;
- options.set_crate_name (msg_str);
+ options.set_crate_name (*msg_str);
}
options.crate_name_set_manually |= crate_name_found;
@@ -551,10 +549,6 @@ Session::compile_crate (const char *filename)
handle_crate_name (filename, *ast_crate.get ());
// dump options except lexer dump
- if (options.dump_option_enabled (CompileOptions::AST_DUMP_PRETTY))
- {
- dump_ast_pretty (*ast_crate.get ());
- }
if (options.dump_option_enabled (CompileOptions::TARGET_OPTION_DUMP))
{
options.target_data.dump_target_options ();
@@ -563,6 +557,11 @@ Session::compile_crate (const char *filename)
if (saw_errors ())
return;
+ if (options.dump_option_enabled (CompileOptions::AST_DUMP_PRETTY))
+ {
+ dump_ast_pretty (*ast_crate.get ());
+ }
+
// setup the mappings for this AST
CrateNum current_crate = mappings.get_current_crate ();
AST::Crate &parsed_crate
@@ -613,13 +612,13 @@ 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::CollectLangItems ().go (parsed_crate);
+
rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))
{
@@ -644,10 +643,7 @@ Session::compile_crate (const char *filename)
return;
// resolution pipeline stage
- if (flag_name_resolution_2_0)
- Resolver2_0::Late (name_resolution_ctx).go (parsed_crate);
- else
- Resolver::NameResolution::Resolve (parsed_crate);
+ Resolver2_0::Late (name_resolution_ctx).go (parsed_crate);
if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP))
dump_name_resolution (name_resolution_ctx);
@@ -738,7 +734,7 @@ Session::compile_crate (const char *filename)
// lints
Analysis::ScanDeadcode::Scan (hir);
Analysis::UnusedVariables::Lint (*ctx);
- Analysis::ReadonlyCheck::Lint (*ctx);
+ HIR::ReadonlyChecker ().go (hir);
// metadata
bool specified_emit_metadata
@@ -758,6 +754,9 @@ Session::compile_crate (const char *filename)
}
}
+ if (saw_errors ())
+ return;
+
// pass to GCC middle-end
ctx->write_to_backend ();
}
@@ -937,28 +936,23 @@ Session::expansion (AST::Crate &crate, Resolver2_0::NameResolutionContext &ctx)
MacroExpander expander (crate, cfg, *this);
std::vector<Error> macro_errors;
+ Resolver2_0::Builtins::setup_lang_prelude (ctx);
+
while (!fixed_point_reached && iterations < cfg.recursion_limit)
{
- CfgStrip ().go (crate);
+ CfgStrip (cfg).go (crate);
// Errors might happen during cfg strip pass
- bool visitor_dirty = false;
- if (flag_name_resolution_2_0)
- {
- Resolver2_0::Early early (ctx);
- early.go (crate);
- macro_errors = early.get_macro_resolve_errors ();
- visitor_dirty = early.is_dirty ();
- }
- else
- Resolver::EarlyNameResolver ().go (crate);
+ Resolver2_0::Early early (ctx);
+ early.go (crate);
+ macro_errors = early.get_macro_resolve_errors ();
if (saw_errors ())
break;
ExpandVisitor (expander).go (crate);
- fixed_point_reached = !expander.has_changed () && !visitor_dirty;
+ fixed_point_reached = !expander.has_changed () && !early.is_dirty ();
expander.reset_changed_state ();
iterations++;
@@ -993,8 +987,7 @@ Session::expansion (AST::Crate &crate, Resolver2_0::NameResolutionContext &ctx)
// HACK: we may need a final TopLevel pass
// however, this should not count towards the recursion limit
// and we don't need a full Early pass
- if (flag_name_resolution_2_0)
- Resolver2_0::TopLevel (ctx).go (crate);
+ Resolver2_0::TopLevel (ctx).go (crate);
}
// error reporting - check unused macros, get missing fragment specifiers
@@ -1190,14 +1183,6 @@ Session::load_extern_crate (const std::string &crate_name, location_t locus)
mappings.insert_bang_proc_macros (crate_num, bang_macros);
mappings.insert_derive_proc_macros (crate_num, derive_macros);
- // if flag_name_resolution_2_0 is enabled
- // then we perform resolution later
- if (!flag_name_resolution_2_0)
- {
- // name resolve it
- Resolver::NameResolution::Resolve (parsed_crate);
- }
-
// always restore the crate_num
mappings.set_current_crate (saved_crate_num);
diff --git a/gcc/rust/typecheck/rust-autoderef.cc b/gcc/rust/typecheck/rust-autoderef.cc
index 10a59bd..8cc2b7b 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -425,8 +425,7 @@ AutoderefCycle::try_autoderefed (TyTy::BaseType *r)
TyTy::ReferenceType *r1
= new TyTy::ReferenceType (r->get_ref (), TyTy::TyVar (r->get_ref ()),
Mutability::Imm);
- adjustments.push_back (
- Adjustment (Adjustment::AdjustmentType::IMM_REF, r, r1));
+ adjustments.emplace_back (Adjustment::AdjustmentType::IMM_REF, r, r1);
if (select (*r1))
return true;
@@ -436,8 +435,7 @@ AutoderefCycle::try_autoderefed (TyTy::BaseType *r)
TyTy::ReferenceType *r2
= new TyTy::ReferenceType (r->get_ref (), TyTy::TyVar (r->get_ref ()),
Mutability::Mut);
- adjustments.push_back (
- Adjustment (Adjustment::AdjustmentType::MUT_REF, r, r2));
+ adjustments.emplace_back (Adjustment::AdjustmentType::MUT_REF, r, r2);
if (select (*r2))
return true;
diff --git a/gcc/rust/typecheck/rust-casts.cc b/gcc/rust/typecheck/rust-casts.cc
index f06d9ed..7d08601 100644
--- a/gcc/rust/typecheck/rust-casts.cc
+++ b/gcc/rust/typecheck/rust-casts.cc
@@ -277,6 +277,7 @@ TypeCastRules::cast_rules ()
break;
case TyTy::TypeKind::REF:
+ case TyTy::TypeKind::FNPTR:
case TyTy::TypeKind::POINTER:
switch (to.get_ty ()->get_kind ())
{
@@ -286,8 +287,9 @@ TypeCastRules::cast_rules ()
case TyTy::TypeKind::INT:
{
// refs should not cast to numeric type
- bool from_ptr
- = from.get_ty ()->get_kind () == TyTy::TypeKind::POINTER;
+ auto kind = from.get_ty ()->get_kind ();
+ bool from_ptr = kind == TyTy::TypeKind::POINTER
+ || kind == TyTy::TypeKind::FNPTR;
if (from_ptr)
{
return TypeCoercionRules::CoercionResult{
diff --git a/gcc/rust/typecheck/rust-coercion.cc b/gcc/rust/typecheck/rust-coercion.cc
index fd12839..e027d9c 100644
--- a/gcc/rust/typecheck/rust-coercion.cc
+++ b/gcc/rust/typecheck/rust-coercion.cc
@@ -61,60 +61,21 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
// see:
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs
- // handle never
- // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155
if (receiver->get_kind () == TyTy::TypeKind::NEVER)
{
- // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
- // type variable, we want `?T` to fallback to `!` if not
- // otherwise constrained. An example where this arises:
- //
- // let _: Option<?T> = Some({ return; });
- //
- // here, we would coerce from `!` to `?T`.
- if (expected->has_substitutions_defined () && !expected->is_concrete ())
- {
- location_t locus = mappings.lookup_location (receiver->get_ref ());
- TyTy::TyVar implicit_var
- = TyTy::TyVar::get_implicit_infer_var (locus);
- try_result = CoercionResult{{}, implicit_var.get_tyty ()};
- return true;
- }
- else
- {
- bool expected_is_infer_var
- = expected->get_kind () == TyTy::TypeKind::INFER;
- bool expected_is_general_infer_var
- = expected_is_infer_var
- && (static_cast<TyTy::InferType *> (expected)->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::GENERAL);
-
- // FIXME this 'expected_is_general_infer_var' case needs to eventually
- // should go away see: compile/never_type_err1.rs
- //
- // I think we need inference obligations to say that yes we have a
- // general inference variable but we add the oligation to the expected
- // type that it could default to '!'
- if (expected_is_general_infer_var)
- try_result = CoercionResult{{}, receiver};
- else
- try_result = CoercionResult{{}, expected->clone ()};
-
- return true;
- }
+ try_result = coerce_never (receiver);
+ return true;
}
// unsize
- bool unsafe_error = false;
- CoercionResult unsize_coercion
- = coerce_unsized (receiver, expected, unsafe_error);
- bool valid_unsize_coercion = !unsize_coercion.is_error ();
- if (valid_unsize_coercion)
+ tl::expected<CoercionResult, CoerceUnsizedError> unsize_coercion
+ = coerce_unsized (receiver, expected);
+ if (unsize_coercion)
{
- try_result = unsize_coercion;
+ try_result = unsize_coercion.value ();
return true;
}
- else if (unsafe_error)
+ else if (unsize_coercion.error () == CoerceUnsizedError::Unsafe)
{
// location_t lhs = mappings.lookup_location (receiver->get_ref ());
// location_t rhs = mappings.lookup_location (expected->get_ref ());
@@ -127,15 +88,14 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
{
case TyTy::TypeKind::POINTER:
{
- TyTy::PointerType *ptr = static_cast<TyTy::PointerType *> (expected);
+ auto *ptr = expected->as<TyTy::PointerType> ();
try_result = coerce_unsafe_ptr (receiver, ptr, ptr->mutability ());
return !try_result.is_error ();
}
case TyTy::TypeKind::REF:
{
- TyTy::ReferenceType *ptr
- = static_cast<TyTy::ReferenceType *> (expected);
+ auto *ptr = expected->as<TyTy::ReferenceType> ();
try_result
= coerce_borrowed_pointer (receiver, ptr, ptr->mutability ());
return !try_result.is_error ();
@@ -174,6 +134,44 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
}
TypeCoercionRules::CoercionResult
+TypeCoercionRules::coerce_never (TyTy::BaseType *receiver)
+{
+ // handle never
+ // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155
+
+ // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
+ // type variable, we want `?T` to fallback to `!` if not
+ // otherwise constrained. An example where this arises:
+ //
+ // let _: Option<?T> = Some({ return; });
+ //
+ // here, we would coerce from `!` to `?T`.
+ if (expected->has_substitutions_defined () && !expected->is_concrete ())
+ {
+ location_t locus = mappings.lookup_location (receiver->get_ref ());
+ TyTy::TyVar implicit_var = TyTy::TyVar::get_implicit_infer_var (locus);
+ return CoercionResult{{}, implicit_var.get_tyty ()};
+ }
+
+ bool expected_is_infer_var = expected->get_kind () == TyTy::TypeKind::INFER;
+ bool expected_is_general_infer_var
+ = expected_is_infer_var
+ && (static_cast<TyTy::InferType *> (expected)->get_infer_kind ()
+ == TyTy::InferType::InferTypeKind::GENERAL);
+
+ // FIXME this 'expected_is_general_infer_var' case needs to eventually
+ // should go away see: compile/never_type_err1.rs
+ //
+ // I think we need inference obligations to say that yes we have a
+ // general inference variable but we add the oligation to the expected
+ // type that it could default to '!'
+ if (expected_is_general_infer_var)
+ return CoercionResult{{}, receiver};
+ else
+ return CoercionResult{{}, expected->clone ()};
+}
+
+TypeCoercionRules::CoercionResult
TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
TyTy::PointerType *expected,
Mutability to_mutbl)
@@ -273,12 +271,9 @@ TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver,
{
case TyTy::TypeKind::REF:
{
- TyTy::ReferenceType *from
- = static_cast<TyTy::ReferenceType *> (receiver);
- from_mutbl = from->mutability ();
+ from_mutbl = receiver->as<TyTy::ReferenceType> ()->mutability ();
}
break;
-
default:
{
rust_debug ("coerce_borrowed_pointer -- unify");
@@ -318,9 +313,10 @@ TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver,
// &[T; n] or &mut [T; n] -> &[T]
// or &mut [T; n] -> &mut [T]
// or &Concrete -> &Trait, etc.
-TypeCoercionRules::CoercionResult
+tl::expected<TypeCoercionRules::CoercionResult,
+ TypeCoercionRules::CoerceUnsizedError>
TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
- TyTy::BaseType *target, bool &unsafe_error)
+ TyTy::BaseType *target)
{
rust_debug ("coerce_unsized(source={%s}, target={%s})",
source->debug_str ().c_str (), target->debug_str ().c_str ());
@@ -344,11 +340,11 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
Mutability to_mutbl = target_ref->mutability ();
if (!coerceable_mutability (from_mutbl, to_mutbl))
{
- unsafe_error = true;
location_t lhs = mappings.lookup_location (source->get_ref ());
location_t rhs = mappings.lookup_location (target->get_ref ());
mismatched_mutability_error (locus, lhs, rhs);
- return TypeCoercionRules::CoercionResult::get_error ();
+ return tl::unexpected<CoerceUnsizedError> (
+ CoerceUnsizedError::Unsafe);
}
ty_a = source_ref->get_base ();
@@ -356,8 +352,8 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
needs_reborrow = true;
expected_mutability = to_mutbl;
- adjustments.push_back (
- Adjustment (Adjustment::AdjustmentType::INDIRECTION, source_ref, ty_a));
+ adjustments.emplace_back (Adjustment::AdjustmentType::INDIRECTION,
+ source_ref, ty_a);
}
else if (source_is_ref && target_is_ptr)
{
@@ -369,11 +365,11 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
Mutability to_mutbl = target_ref->mutability ();
if (!coerceable_mutability (from_mutbl, to_mutbl))
{
- unsafe_error = true;
location_t lhs = mappings.lookup_location (source->get_ref ());
location_t rhs = mappings.lookup_location (target->get_ref ());
mismatched_mutability_error (locus, lhs, rhs);
- return TypeCoercionRules::CoercionResult::get_error ();
+ return tl::unexpected<CoerceUnsizedError> (
+ CoerceUnsizedError::Unsafe);
}
ty_a = source_ref->get_base ();
@@ -381,8 +377,8 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
needs_reborrow = true;
expected_mutability = to_mutbl;
- adjustments.push_back (
- Adjustment (Adjustment::AdjustmentType::INDIRECTION, source_ref, ty_a));
+ adjustments.emplace_back (Adjustment::AdjustmentType::INDIRECTION,
+ source_ref, ty_a);
}
// FIXME
@@ -401,17 +397,14 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
{
bool bounds_compatible = b->bounds_compatible (*a, locus, false);
if (!bounds_compatible)
- {
- unsafe_error = true;
- return TypeCoercionRules::CoercionResult::get_error ();
- }
+ return tl::unexpected<CoerceUnsizedError> (CoerceUnsizedError::Unsafe);
// return the unsize coercion
TyTy::BaseType *result = b->clone ();
// result->set_ref (a->get_ref ());
// append a dyn coercion adjustment
- adjustments.push_back (Adjustment (Adjustment::UNSIZE, a, result));
+ adjustments.emplace_back (Adjustment::UNSIZE, a, result);
// reborrow if needed
if (needs_reborrow)
@@ -424,7 +417,7 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
Adjustment::AdjustmentType borrow_type
= expected_mutability == Mutability::Imm ? Adjustment::IMM_REF
: Adjustment::MUT_REF;
- adjustments.push_back (Adjustment (borrow_type, result, reborrow));
+ adjustments.emplace_back (borrow_type, result, reborrow);
result = reborrow;
}
@@ -432,7 +425,7 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
}
adjustments.clear ();
- return TypeCoercionRules::CoercionResult::get_error ();
+ return tl::unexpected<CoerceUnsizedError> (CoerceUnsizedError::Regular);
}
bool
@@ -446,7 +439,8 @@ TypeCoercionRules::select (TyTy::BaseType &autoderefed)
= unify_site_and (autoderefed.get_ref (), TyTy::TyWithLocation (expected),
TyTy::TyWithLocation (&autoderefed),
UNDEF_LOCATION /* locus */, false /*emit_errors*/,
- false /*commit_if_ok*/, true /*infer*/, true /*cleanup*/);
+ !try_flag /*commit_if_ok*/, try_flag /*infer*/,
+ try_flag /*cleanup*/);
bool ok = result->get_kind () != TyTy::TypeKind::ERROR;
if (!ok)
return false;
diff --git a/gcc/rust/typecheck/rust-coercion.h b/gcc/rust/typecheck/rust-coercion.h
index b268966..864f48a 100644
--- a/gcc/rust/typecheck/rust-coercion.h
+++ b/gcc/rust/typecheck/rust-coercion.h
@@ -21,6 +21,7 @@
#include "rust-autoderef.h"
#include "rust-hir-type-check.h"
+#include "expected.h"
namespace Rust {
namespace Resolver {
@@ -28,6 +29,12 @@ namespace Resolver {
class TypeCoercionRules : protected AutoderefCycle
{
public:
+ enum class CoerceUnsizedError
+ {
+ Regular,
+ Unsafe
+ };
+
struct CoercionResult
{
std::vector<Adjustment> adjustments;
@@ -51,6 +58,7 @@ public:
bool allow_autoderef,
bool is_cast_site = false);
+ CoercionResult coerce_never (TyTy::BaseType *receiver);
CoercionResult coerce_unsafe_ptr (TyTy::BaseType *receiver,
TyTy::PointerType *expected,
Mutability mutability);
@@ -59,8 +67,8 @@ public:
TyTy::ReferenceType *expected,
Mutability mutability);
- CoercionResult coerce_unsized (TyTy::BaseType *receiver,
- TyTy::BaseType *expected, bool &unsafe_error);
+ tl::expected<CoercionResult, CoerceUnsizedError>
+ coerce_unsized (TyTy::BaseType *receiver, TyTy::BaseType *expected);
static bool coerceable_mutability (Mutability from_mutbl,
Mutability to_mutbl);
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc
index 7b7944c..296cc44 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.cc
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc
@@ -51,6 +51,9 @@ MethodResolver::Select (std::set<MethodCandidate> &candidates,
{
TyTy::BaseType *candidate_type = candidate.candidate.ty;
rust_assert (candidate_type->get_kind () == TyTy::TypeKind::FNDEF);
+ if (candidate_type == nullptr
+ || candidate_type->get_kind () != TyTy::TypeKind::FNDEF)
+ continue;
TyTy::FnType &fn = *static_cast<TyTy::FnType *> (candidate_type);
// match the number of arguments
@@ -136,11 +139,11 @@ MethodResolver::assemble_inherent_impl_candidates (
TyTy::BaseType *ty = nullptr;
if (!query_type (func->get_mappings ().get_hirid (), &ty))
return true;
- rust_assert (ty != nullptr);
- if (ty->get_kind () == TyTy::TypeKind::ERROR)
+ if (ty == nullptr || ty->get_kind () == TyTy::TypeKind::ERROR)
+ return true;
+ if (ty->get_kind () != TyTy::TypeKind::FNDEF)
return true;
- rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
const TyTy::BaseType *impl_self
= TypeCheckItem::ResolveImplBlockSelf (*impl);
@@ -175,7 +178,7 @@ MethodResolver::assemble_inherent_impl_candidates (
return true;
}
- inherent_impl_fns.push_back ({func, impl, fnty});
+ inherent_impl_fns.emplace_back (func, impl, fnty);
return true;
});
@@ -220,10 +223,11 @@ MethodResolver::assemble_trait_impl_candidates (
TyTy::BaseType *ty = nullptr;
if (!query_type (func->get_mappings ().get_hirid (), &ty))
continue;
- if (ty->get_kind () == TyTy::TypeKind::ERROR)
+ if (ty == nullptr || ty->get_kind () == TyTy::TypeKind::ERROR)
+ continue;
+ if (ty->get_kind () != TyTy::TypeKind::FNDEF)
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);
@@ -259,7 +263,7 @@ MethodResolver::assemble_trait_impl_candidates (
continue;
}
- impl_candidates.push_back ({func, impl, fnty});
+ impl_candidates.emplace_back (func, impl, fnty);
return true;
}
@@ -282,11 +286,11 @@ MethodResolver::assemble_trait_impl_candidates (
return true;
TyTy::BaseType *ty = item_ref->get_tyty ();
- rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
+ if (ty == nullptr || ty->get_kind () != TyTy::TypeKind::FNDEF)
+ return true;
TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
- trait_item_candidate candidate{func, trait, fnty, trait_ref, item_ref};
- trait_candidates.push_back (candidate);
+ trait_candidates.emplace_back (func, trait, fnty, trait_ref, item_ref);
return true;
});
@@ -299,7 +303,8 @@ MethodResolver::try_select_predicate_candidates (TyTy::BaseType &receiver)
for (const auto &predicate : predicate_items)
{
const TyTy::FnType *fn = predicate.fntype;
- rust_assert (fn->is_method ());
+ if (!fn->is_method ())
+ continue;
TyTy::BaseType *fn_self = fn->get_self_type ();
rust_debug ("dot-operator predicate fn_self={%s} can_eq receiver={%s}",
@@ -346,7 +351,8 @@ MethodResolver::try_select_inherent_impl_candidates (
continue;
TyTy::FnType *fn = impl_item.ty;
- rust_assert (fn->is_method ());
+ if (!fn->is_method ())
+ continue;
TyTy::BaseType *fn_self = fn->get_self_type ();
@@ -384,7 +390,8 @@ MethodResolver::try_select_trait_impl_candidates (
for (auto trait_item : candidates)
{
TyTy::FnType *fn = trait_item.ty;
- rust_assert (fn->is_method ());
+ if (!fn->is_method ())
+ continue;
TyTy::BaseType *fn_self = fn->get_self_type ();
rust_debug ("dot-operator trait_item fn_self={%s} can_eq receiver={%s}",
@@ -464,20 +471,17 @@ MethodResolver::get_predicate_items (
std::vector<predicate_candidate> predicate_items;
for (auto &bound : specified_bounds)
{
- TyTy::TypeBoundPredicateItem lookup
+ tl::optional<TyTy::TypeBoundPredicateItem> lookup
= bound.lookup_associated_item (segment_name.as_string ());
- if (lookup.is_error ())
+ if (!lookup.has_value ())
continue;
- TyTy::BaseType *ty = lookup.get_tyty_for_receiver (&receiver);
+ TyTy::BaseType *ty = lookup->get_tyty_for_receiver (&receiver);
if (ty->get_kind () == TyTy::TypeKind::FNDEF)
{
TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
if (fnty->is_method ())
- {
- predicate_candidate candidate{lookup, fnty};
- predicate_items.push_back (candidate);
- }
+ predicate_items.emplace_back (lookup.value (), fnty);
}
}
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.h b/gcc/rust/typecheck/rust-hir-dot-operator.h
index cc40472..d2f11d1 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.h
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.h
@@ -49,6 +49,10 @@ class MethodResolver : private TypeCheckBase, protected AutoderefCycle
public:
struct predicate_candidate
{
+ predicate_candidate (TyTy::TypeBoundPredicateItem lookup,
+ TyTy::FnType *fntype)
+ : lookup (lookup), fntype (fntype)
+ {}
TyTy::TypeBoundPredicateItem lookup;
TyTy::FnType *fntype;
};
@@ -67,6 +71,11 @@ public:
struct impl_item_candidate
{
+ impl_item_candidate (HIR::Function *item, HIR::ImplBlock *impl_block,
+ TyTy::FnType *ty)
+ : item (item), impl_block (impl_block), ty (ty)
+ {}
+
HIR::Function *item;
HIR::ImplBlock *impl_block;
TyTy::FnType *ty;
@@ -74,6 +83,13 @@ public:
struct trait_item_candidate
{
+ trait_item_candidate (const HIR::TraitItemFunc *item,
+ const HIR::Trait *trait, TyTy::FnType *ty,
+ const TraitReference *reference,
+ const TraitItemReference *item_ref)
+ : item (item), trait (trait), ty (ty), reference (reference),
+ item_ref (item_ref)
+ {}
const HIR::TraitItemFunc *item;
const HIR::Trait *trait;
TyTy::FnType *ty;
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.cc b/gcc/rust/typecheck/rust-hir-path-probe.cc
index c02702f..59118e6 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.cc
+++ b/gcc/rust/typecheck/rust-hir-path-probe.cc
@@ -302,11 +302,10 @@ PathProbeType::process_impl_item_candidate (HirId id, HIR::ImplItem *item,
if (!query_type (impl_ty_id, &impl_block_ty))
return;
- if (!receiver->can_eq (impl_block_ty, false))
- {
- if (!impl_block_ty->can_eq (receiver, false))
- return;
- }
+ if (!types_compatable (TyTy::TyWithLocation (receiver),
+ TyTy::TyWithLocation (impl_block_ty),
+ impl->get_locus (), false))
+ return;
// lets visit the impl_item
item->accept_vis (*this);
@@ -367,15 +366,15 @@ PathProbeType::process_predicate_for_candidates (
{
const TraitReference *trait_ref = predicate.get ();
- TyTy::TypeBoundPredicateItem item
+ tl::optional<TyTy::TypeBoundPredicateItem> item
= predicate.lookup_associated_item (search.as_string ());
- if (item.is_error ())
+ if (!item.has_value ())
return;
- if (ignore_mandatory_trait_items && item.needs_implementation ())
+ if (ignore_mandatory_trait_items && item->needs_implementation ())
return;
- const TraitItemReference *trait_item_ref = item.get_raw_item ();
+ const TraitItemReference *trait_item_ref = item->get_raw_item ();
PathProbeCandidate::CandidateType candidate_type;
switch (trait_item_ref->get_trait_item_type ())
{
@@ -395,9 +394,9 @@ PathProbeType::process_predicate_for_candidates (
break;
}
- TyTy::BaseType *trait_item_tyty = item.get_raw_item ()->get_tyty ();
+ TyTy::BaseType *trait_item_tyty = item->get_raw_item ()->get_tyty ();
if (receiver->get_kind () != TyTy::DYNAMIC)
- trait_item_tyty = item.get_tyty_for_receiver (receiver);
+ trait_item_tyty = item->get_tyty_for_receiver (receiver);
PathProbeCandidate::TraitItemCandidate trait_item_candidate{trait_ref,
trait_item_ref,
@@ -425,10 +424,10 @@ PathProbeType::union_bounds (
}
std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> union_set;
+
for (auto it = mapper.begin (); it != mapper.end (); it++)
- {
- union_set.push_back ({it->second.first, it->second.second});
- }
+ union_set.emplace_back (it->second.first, it->second.second);
+
return union_set;
}
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 0fd0147..03121d1 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -224,8 +224,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
apply_sized);
context->insert_type (generic_param->get_mappings (), param_type);
- substitutions.push_back (
- TyTy::SubstitutionParamMapping (typaram, param_type));
+ substitutions.emplace_back (typaram, param_type);
if (is_self)
{
@@ -247,17 +246,17 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
// copy the substitition mappings
std::vector<TyTy::SubstitutionParamMapping> self_subst_copy;
+ self_subst_copy.reserve (substitutions.size ());
+
for (auto &sub : substitutions)
self_subst_copy.push_back (sub.clone ());
// They also inherit themselves as a bound this enables a trait item to
// reference other Self::trait_items
- auto self_hrtb
- = TyTy::TypeBoundPredicate (trait_reference->get_mappings ().get_defid (),
- std::move (self_subst_copy),
- BoundPolarity::RegularBound,
- trait_reference->get_locus ());
- specified_bounds.push_back (self_hrtb);
+ specified_bounds.emplace_back (trait_reference->get_mappings ().get_defid (),
+ std::move (self_subst_copy),
+ BoundPolarity::RegularBound,
+ trait_reference->get_locus ());
// look for any
std::vector<TyTy::TypeBoundPredicate> super_traits;
@@ -291,6 +290,8 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
{
// make a copy of the substs
std::vector<TyTy::SubstitutionParamMapping> item_subst;
+ item_subst.reserve (substitutions.size ());
+
for (auto &sub : substitutions)
item_subst.push_back (sub.clone ());
@@ -553,9 +554,9 @@ AssociatedImplTrait::setup_associated_types (
generic_param->get_mappings ().get_hirid (), &l);
if (ok && l->get_kind () == TyTy::TypeKind::PARAM)
{
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param),
- static_cast<TyTy::ParamType *> (l)));
+ substitutions.emplace_back (static_cast<HIR::TypeParam &> (
+ *generic_param),
+ static_cast<TyTy::ParamType *> (l));
}
}
break;
@@ -579,14 +580,13 @@ AssociatedImplTrait::setup_associated_types (
if (p.needs_substitution () && infer)
{
TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
- subst_args.push_back (
- TyTy::SubstitutionArg (&p, infer_var.get_tyty ()));
+ subst_args.emplace_back (&p, infer_var.get_tyty ());
}
else
{
auto param = p.get_param_ty ();
auto resolved = param->destructure ();
- subst_args.push_back (TyTy::SubstitutionArg (&p, resolved));
+ subst_args.emplace_back (&p, resolved);
param_mappings[param->get_symbol ()] = resolved->get_ref ();
}
}
diff --git a/gcc/rust/typecheck/rust-hir-type-bounds.h b/gcc/rust/typecheck/rust-hir-type-bounds.h
index 5384700..392ff20 100644
--- a/gcc/rust/typecheck/rust-hir-type-bounds.h
+++ b/gcc/rust/typecheck/rust-hir-type-bounds.h
@@ -30,7 +30,7 @@ class TypeBoundsProbe : public TypeCheckBase
{
public:
static std::vector<std::pair<TraitReference *, HIR::ImplBlock *>>
- Probe (const TyTy::BaseType *receiver);
+ Probe (TyTy::BaseType *receiver);
static bool is_bound_satisfied_for_type (TyTy::BaseType *receiver,
TraitReference *ref);
@@ -46,9 +46,9 @@ private:
void assemble_builtin_candidate (LangItem::Kind item);
private:
- TypeBoundsProbe (const TyTy::BaseType *receiver);
+ TypeBoundsProbe (TyTy::BaseType *receiver);
- const TyTy::BaseType *receiver;
+ TyTy::BaseType *receiver;
std::vector<std::pair<TraitReference *, HIR::ImplBlock *>> trait_references;
};
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 68001bf..f878720 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -56,7 +56,9 @@ walk_types_to_constrain (std::set<HirId> &constrained_symbols,
if (arg != nullptr)
{
const auto p = arg->get_root ();
+ constrained_symbols.insert (p->get_ref ());
constrained_symbols.insert (p->get_ty_ref ());
+
if (p->has_substitutions_defined ())
{
walk_types_to_constrain (constrained_symbols,
@@ -66,6 +68,83 @@ walk_types_to_constrain (std::set<HirId> &constrained_symbols,
}
}
+static void
+walk_type_to_constrain (std::set<HirId> &constrained_symbols, TyTy::BaseType &r)
+{
+ switch (r.get_kind ())
+ {
+ case TyTy::TypeKind::POINTER:
+ {
+ auto &p = static_cast<TyTy::PointerType &> (r);
+ walk_type_to_constrain (constrained_symbols, *p.get_base ());
+ }
+ break;
+ case TyTy::TypeKind::REF:
+ {
+ auto &ref = static_cast<TyTy::ReferenceType &> (r);
+ walk_type_to_constrain (constrained_symbols, *ref.get_base ());
+ }
+ break;
+ case TyTy::TypeKind::ARRAY:
+ {
+ auto &arr = static_cast<TyTy::ArrayType &> (r);
+ walk_type_to_constrain (constrained_symbols, *arr.get_element_type ());
+ }
+ break;
+ case TyTy::TypeKind::FNDEF:
+ {
+ auto &fn = static_cast<TyTy::FnType &> (r);
+ for (auto &param : fn.get_params ())
+ walk_type_to_constrain (constrained_symbols, *param.get_type ());
+ walk_type_to_constrain (constrained_symbols, *fn.get_return_type ());
+ }
+ break;
+ case TyTy::TypeKind::PARAM:
+ {
+ auto &param = static_cast<TyTy::ParamType &> (r);
+ constrained_symbols.insert (param.get_ty_ref ());
+ }
+ break;
+ case TyTy::SLICE:
+ {
+ auto &slice = static_cast<TyTy::SliceType &> (r);
+ walk_type_to_constrain (constrained_symbols,
+ *slice.get_element_type ());
+ }
+ break;
+ case TyTy::FNPTR:
+ {
+ auto &ptr = static_cast<TyTy::FnPtr &> (r);
+ for (auto &param : ptr.get_params ())
+ walk_type_to_constrain (constrained_symbols, *param.get_tyty ());
+ walk_type_to_constrain (constrained_symbols, *ptr.get_return_type ());
+ }
+ break;
+ case TyTy::TUPLE:
+ {
+ auto &tuple = static_cast<TyTy::TupleType &> (r);
+ for (auto &ty : tuple.get_fields ())
+ walk_type_to_constrain (constrained_symbols, *ty.get_tyty ());
+ }
+ break;
+ case TyTy::DYNAMIC:
+ {
+ auto &dyn = static_cast<TyTy::DynamicObjectType &> (r);
+ constrained_symbols.insert (dyn.get_ty_ref ());
+ }
+ break;
+ case TyTy::CLOSURE:
+ {
+ auto &clos = static_cast<TyTy::ClosureType &> (r);
+ walk_type_to_constrain (constrained_symbols, clos.get_parameters ());
+ walk_type_to_constrain (constrained_symbols, *clos.get_return_type ());
+ }
+ break;
+ default:
+ break;
+ }
+}
+
bool
TypeCheckBase::check_for_unconstrained (
const std::vector<TyTy::SubstitutionParamMapping> &params_to_constrain,
@@ -87,21 +166,13 @@ 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;
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)
- {
- const TyTy::ParamType *p = static_cast<const TyTy::ParamType *> (root);
- constrained_symbols.insert (p->get_ty_ref ());
- }
+ walk_type_to_constrain (constrained_symbols, *reference);
// check for unconstrained
bool unconstrained = false;
@@ -296,17 +367,17 @@ TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
tree capacity = Compile::HIRCompileBase::query_compile_const_expr (
ctx, expected_ty, *literal_capacity);
- TyTy::ConstType *capacity_expr
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "",
- expected_ty, capacity, {},
- literal_capacity->get_locus (),
- literal_capacity->get_mappings ().get_hirid (),
- literal_capacity->get_mappings ().get_hirid (),
- {});
-
- TyTy::ArrayType *array
- = new TyTy::ArrayType (array_mapping.get_hirid (), locus,
- capacity_expr, TyTy::TyVar (u8->get_ref ()));
+ HirId capacity_expr_id = literal_capacity->get_mappings ().get_hirid ();
+ auto capacity_expr
+ = new TyTy::ConstValueType (capacity, expected_ty, capacity_expr_id,
+ capacity_expr_id);
+ context->insert_type (literal_capacity->get_mappings (),
+ capacity_expr->as_base_type ());
+
+ TyTy::ArrayType *array = new TyTy::ArrayType (
+ array_mapping.get_hirid (), locus,
+ TyTy::TyVar (capacity_expr->as_base_type ()->get_ty_ref ()),
+ TyTy::TyVar (u8->get_ref ()));
context->insert_type (array_mapping, array);
infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
@@ -341,7 +412,7 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
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");
+ rust_error_at (attr.get_locus (), "malformed %<repr%> attribute");
continue;
}
@@ -350,7 +421,11 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
const AST::AttrInput &input = attr.get_attr_input ();
bool is_token_tree = input.get_attr_input_type ()
== AST::AttrInput::AttrInputType::TOKEN_TREE;
- rust_assert (is_token_tree);
+ if (!is_token_tree)
+ {
+ rust_error_at (attr.get_locus (), "malformed %<repr%> attribute");
+ continue;
+ }
const auto &option = static_cast<const AST::DelimTokenTree &> (input);
AST::AttrInputMetaItemContainer *meta_items
= option.parse_to_meta_item ();
@@ -526,22 +601,21 @@ TypeCheckBase::resolve_generic_params (
= Compile::HIRCompileBase::query_compile_const_expr (
ctx, specified_type, expr);
- TyTy::ConstType *default_const_decl
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
- param.get_name (), specified_type,
- default_value, {}, param.get_locus (),
- expr.get_mappings ().get_hirid (),
- expr.get_mappings ().get_hirid (), {});
+ auto default_const_decl
+ = new TyTy::ConstValueType (default_value, specified_type,
+ expr.get_mappings ().get_hirid (),
+ expr.get_mappings ().get_hirid (),
+ {});
context->insert_type (expr.get_mappings (), default_const_decl);
}
- TyTy::ConstType *const_decl
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Decl,
- param.get_name (), specified_type,
- error_mark_node, {}, param.get_locus (),
- param.get_mappings ().get_hirid (),
- param.get_mappings ().get_hirid (), {});
+ TyTy::BaseGeneric *const_decl
+ = new TyTy::ConstParamType (param.get_name (), param.get_locus (),
+ specified_type,
+ param.get_mappings ().get_hirid (),
+ param.get_mappings ().get_hirid (),
+ {});
context->insert_type (generic_param->get_mappings (), const_decl);
TyTy::SubstitutionParamMapping p (*generic_param, const_decl);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 438200b..7885dfc 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -34,6 +34,7 @@
#include "rust-immutable-name-resolution-context.h"
#include "rust-compile-base.h"
#include "rust-tyty-util.h"
+#include "rust-tyty.h"
#include "tree.h"
namespace Rust {
@@ -125,7 +126,13 @@ TypeCheckExpr::visit (HIR::TupleIndexExpr &expr)
}
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (resolved);
- rust_assert (!adt->is_enum ());
+ if (!adt->is_tuple_struct ())
+ {
+ rust_error_at (expr.get_locus (),
+ "expected tuple or tuple struct, found %qs",
+ adt->get_name ().c_str ());
+ return;
+ }
rust_assert (adt->number_of_variants () == 1);
TyTy::VariantDef *variant = adt->get_variants ().at (0);
@@ -160,7 +167,7 @@ TypeCheckExpr::visit (HIR::TupleExpr &expr)
for (auto &elem : expr.get_tuple_elems ())
{
auto field_ty = TypeCheckExpr::Resolve (*elem);
- fields.push_back (TyTy::TyVar (field_ty->get_ref ()));
+ fields.emplace_back (field_ty->get_ref ());
}
infered = new TyTy::TupleType (expr.get_mappings ().get_hirid (),
expr.get_locus (), fields);
@@ -629,10 +636,9 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
if (s->is_unit_check_needed () && !resolved->is_unit ())
{
auto unit = TyTy::TupleType::get_unit_type ();
- resolved
- = unify_site (s->get_mappings ().get_hirid (),
- TyTy::TyWithLocation (unit),
- TyTy::TyWithLocation (resolved), s->get_locus ());
+ unify_site (s->get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (unit),
+ TyTy::TyWithLocation (resolved), s->get_locus ());
}
}
@@ -669,16 +675,9 @@ TypeCheckExpr::visit (HIR::AnonConst &expr)
return;
}
- auto locus = expr.get_locus ();
- auto infer_ty_var = TyTy::TyVar::get_implicit_infer_var (locus);
-
- HirId next = mappings.get_next_hir_id ();
- infered = new TyTy::ConstType (TyTy::ConstType::ConstKind::Infer, "",
- infer_ty_var.get_tyty (), error_mark_node, {},
- locus, next, next, {});
-
- context->insert_implicit_type (infered->get_ref (), infered);
- mappings.insert_location (infered->get_ref (), locus);
+ TyTy::TyVar var
+ = TyTy::TyVar::get_implicit_const_infer_var (expr.get_locus ());
+ infered = var.get_tyty ();
}
void
@@ -730,7 +729,7 @@ TypeCheckExpr::visit (HIR::RangeFromToExpr &expr)
// substitute it in
std::vector<TyTy::SubstitutionArg> subst_mappings;
const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
- subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified));
+ subst_mappings.emplace_back (param_ref, unified);
TyTy::SubstitutionArgumentMappings subst (
subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
@@ -774,7 +773,7 @@ TypeCheckExpr::visit (HIR::RangeFromExpr &expr)
// substitute it in
std::vector<TyTy::SubstitutionArg> subst_mappings;
const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
- subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty));
+ subst_mappings.emplace_back (param_ref, from_ty);
TyTy::SubstitutionArgumentMappings subst (
subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
@@ -818,7 +817,7 @@ TypeCheckExpr::visit (HIR::RangeToExpr &expr)
// substitute it in
std::vector<TyTy::SubstitutionArg> subst_mappings;
const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
- subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty));
+ subst_mappings.emplace_back (param_ref, from_ty);
TyTy::SubstitutionArgumentMappings subst (
subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
@@ -991,7 +990,7 @@ TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr)
// substitute it in
std::vector<TyTy::SubstitutionArg> subst_mappings;
const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
- subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified));
+ subst_mappings.emplace_back (param_ref, unified);
TyTy::SubstitutionArgumentMappings subst (
subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
@@ -1091,15 +1090,19 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
auto capacity_expr_ty
= TypeCheckExpr::Resolve (elems.get_num_copies_expr ());
+ if (capacity_expr_ty->is<TyTy::ErrorType> ())
+ return;
context->insert_type (elems.get_num_copies_expr ().get_mappings (),
expected_ty);
- unify_site (
+ auto result = unify_site (
expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (expected_ty),
TyTy::TyWithLocation (capacity_expr_ty,
elems.get_num_copies_expr ().get_locus ()),
expr.get_locus ());
+ if (result->is<TyTy::ErrorType> ())
+ return;
capacity_expr = &elems.get_num_copies_expr ();
capacity_type = expected_ty;
@@ -1152,14 +1155,23 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
tree capacity_value
= Compile::HIRCompileBase::query_compile_const_expr (ctx, capacity_type,
*capacity_expr);
- HirId size_id = capacity_expr->get_mappings ().get_hirid ();
- TyTy::ConstType *const_type
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "", expected_ty,
- capacity_value, {}, capacity_expr->get_locus (),
- size_id, size_id);
+
+ // Create ConstValueType with ref == ty_ref (both pointing to capacity_expr)
+ // ty_ref gets updated during substitution via set_ty_ref()
+ HirId capacity_expr_id = capacity_expr->get_mappings ().get_hirid ();
+ auto const_type
+ = new TyTy::ConstValueType (capacity_value, expected_ty, capacity_expr_id,
+ capacity_expr_id);
+
+ // Insert the ConstValueType at its ref
+ context->insert_type (capacity_expr->get_mappings (),
+ const_type->as_base_type ());
+
infered
= new TyTy::ArrayType (expr.get_mappings ().get_hirid (), expr.get_locus (),
- const_type, TyTy::TyVar (element_type->get_ref ()));
+ TyTy::TyVar (
+ const_type->as_base_type ()->get_ty_ref ()),
+ TyTy::TyVar (element_type->get_ref ()));
}
// empty struct
@@ -1888,7 +1900,7 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
// auto resolve because the hir id's match
,
expr.get_locus ());
- args.get_type_args ().push_back (std::unique_ptr<HIR::Type> (implicit_tuple));
+ args.get_type_args ().emplace_back (implicit_tuple);
// apply the arguments
predicate.apply_generic_arguments (&args, false, false);
@@ -1974,13 +1986,13 @@ TypeCheckExpr::resolve_operator_overload (
std::vector<TyTy::SubstitutionArg> mappings;
auto &self_param_mapping = trait_subst[0];
- mappings.push_back (TyTy::SubstitutionArg (&self_param_mapping, lhs));
+ mappings.emplace_back (&self_param_mapping, lhs);
if (rhs != nullptr)
{
rust_assert (trait_subst.size () == 2);
auto &rhs_param_mapping = trait_subst[1];
- mappings.push_back (TyTy::SubstitutionArg (&rhs_param_mapping, lhs));
+ mappings.emplace_back (&rhs_param_mapping, lhs);
}
std::map<std::string, TyTy::BaseType *> binding_args;
@@ -2033,24 +2045,6 @@ TypeCheckExpr::resolve_operator_overload (
rust_debug ("is_impl_item_candidate: %s",
resolved_candidate.is_impl_candidate () ? "true" : "false");
- if (resolved_candidate.is_impl_candidate ())
- {
- auto infer_arguments = TyTy::SubstitutionArgumentMappings::error ();
- HIR::ImplBlock &impl = *resolved_candidate.item.impl.parent;
- TyTy::BaseType *impl_self_infer
- = TypeCheckItem::ResolveImplBlockSelfWithInference (impl,
- expr.get_locus (),
- &infer_arguments);
- if (impl_self_infer->get_kind () == TyTy::TypeKind::ERROR)
- {
- return false;
- }
- if (!infer_arguments.is_empty ())
- {
- lookup = SubstMapperInternal::Resolve (lookup, infer_arguments);
- }
- }
-
// in the case where we resolve to a trait bound we have to be careful we are
// able to do so there is a case where we are currently resolving the deref
// operator overload function which is generic and this might resolve to the
@@ -2312,7 +2306,7 @@ TypeCheckExpr::resolve_fn_trait_call (HIR::CallExpr &expr,
for (auto &arg : expr.get_arguments ())
{
TyTy::BaseType *a = TypeCheckExpr::Resolve (*arg);
- call_args.push_back (TyTy::TyVar (a->get_ref ()));
+ call_args.emplace_back (a->get_ref ());
}
// crate implicit tuple
@@ -2325,9 +2319,8 @@ TypeCheckExpr::resolve_fn_trait_call (HIR::CallExpr &expr,
context->insert_implicit_type (implicit_arg_id, tuple);
std::vector<TyTy::Argument> args;
- TyTy::Argument a (mapping, tuple,
- expr.get_locus () /*FIXME is there a better location*/);
- args.push_back (std::move (a));
+ args.emplace_back (mapping, tuple,
+ expr.get_locus () /*FIXME is there a better location*/);
TyTy::BaseType *function_ret_tyty
= TyTy::TypeCheckMethodCallExpr::go (fn, expr.get_mappings (), args,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index c8544a1..e7f6632 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -121,7 +121,7 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
UNDEF_LOCATION, false, Mutability::Imm,
std::unique_ptr<HIR::Pattern> (nullptr)));
- params.push_back (TyTy::FnParam (std::move (param_pattern), param_tyty));
+ params.emplace_back (std::move (param_pattern), param_tyty);
context->insert_type (param.get_mappings (), param_tyty);
@@ -324,7 +324,7 @@ TypeCheckImplItem::visit (HIR::Function &function)
}
context->insert_type (self_param.get_mappings (), self_type);
- params.push_back (TyTy::FnParam (std::move (self_pattern), self_type));
+ params.emplace_back (std::move (self_pattern), self_type);
}
for (auto &param : function.get_function_params ())
@@ -335,8 +335,8 @@ TypeCheckImplItem::visit (HIR::Function &function)
context->insert_type (param.get_mappings (), param_tyty);
TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
- params.push_back (
- TyTy::FnParam (param.get_param_name ().clone_pattern (), param_tyty));
+ params.emplace_back (param.get_param_name ().clone_pattern (),
+ param_tyty);
}
auto &nr_ctx
@@ -469,8 +469,8 @@ TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
}
// get the item from the predicate
- resolved_trait_item = trait_reference.lookup_associated_item (raw_trait_item);
- rust_assert (!resolved_trait_item.is_error ());
+ resolved_trait_item
+ = trait_reference.lookup_associated_item (raw_trait_item).value ();
// merge the attributes
const HIR::TraitItem *hir_trait_item
@@ -519,8 +519,8 @@ TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
}
// get the item from the predicate
- resolved_trait_item = trait_reference.lookup_associated_item (raw_trait_item);
- rust_assert (!resolved_trait_item.is_error ());
+ resolved_trait_item
+ = trait_reference.lookup_associated_item (raw_trait_item).value ();
// merge the attributes
const HIR::TraitItem *hir_trait_item
@@ -578,8 +578,8 @@ TypeCheckImplItemWithTrait::visit (HIR::Function &function)
}
// get the item from the predicate
- resolved_trait_item = trait_reference.lookup_associated_item (raw_trait_item);
- rust_assert (!resolved_trait_item.is_error ());
+ resolved_trait_item
+ = trait_reference.lookup_associated_item (raw_trait_item).value ();
// merge the attributes
const HIR::TraitItem *hir_trait_item
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 3ba607b..4987c88a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -115,13 +115,13 @@ TypeCheckItem::ResolveImplBlockSelfWithInference (
if (p.needs_substitution ())
{
TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
- args.push_back (TyTy::SubstitutionArg (&p, infer_var.get_tyty ()));
+ args.emplace_back (&p, infer_var.get_tyty ());
}
else
{
auto param = p.get_param_ty ();
auto resolved = param->destructure ();
- args.push_back (TyTy::SubstitutionArg (&p, resolved));
+ args.emplace_back (&p, resolved);
}
}
@@ -554,8 +554,8 @@ TypeCheckItem::visit (HIR::Function &function)
auto param_tyty = TypeCheckType::Resolve (param.get_type ());
context->insert_type (param.get_mappings (), param_tyty);
TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
- params.push_back (
- TyTy::FnParam (param.get_param_name ().clone_pattern (), param_tyty));
+ params.emplace_back (param.get_param_name ().clone_pattern (),
+ param_tyty);
}
auto &nr_ctx
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index cc5c412..ffa0990 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -77,9 +77,9 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
// lookup the associated item from the specified bound
HIR::PathExprSegment &item_seg = expr.get_segments ().at (0);
HIR::PathIdentSegment item_seg_identifier = item_seg.get_segment ();
- TyTy::TypeBoundPredicateItem item
+ tl::optional<TyTy::TypeBoundPredicateItem> item
= specified_bound.lookup_associated_item (item_seg_identifier.as_string ());
- if (item.is_error ())
+ if (!item.has_value ())
{
rust_error_at (item_seg.get_locus (), "unknown associated item");
return;
@@ -116,9 +116,9 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
// and we dont need to worry if the trait item is actually implemented or
// not because this will have already been validated as part of the trait
// impl block
- infered = item.get_tyty_for_receiver (root);
+ infered = item->get_tyty_for_receiver (root);
root_resolved_node_id
- = item.get_raw_item ()->get_mappings ().get_nodeid ();
+ = item->get_raw_item ()->get_mappings ().get_nodeid ();
}
else
{
@@ -517,9 +517,8 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
const auto &predicate
= impl_block_ty->lookup_predicate (trait_ref.get_defid ());
if (!predicate.is_error ())
- impl_block_ty
- = associated->setup_associated_types (prev_segment, predicate,
- nullptr, false);
+ associated->setup_associated_types (prev_segment, predicate,
+ nullptr, false);
}
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index be926fc..7dae303 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -21,6 +21,8 @@
#include "rust-hir-type-check-expr.h"
#include "rust-type-util.h"
#include "rust-immutable-name-resolution-context.h"
+#include "rust-tyty.h"
+#include "tree.h"
namespace Rust {
namespace Resolver {
@@ -160,19 +162,32 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
infered = pattern_ty;
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
- rust_assert (adt->number_of_variants () > 0);
- TyTy::VariantDef *variant = adt->get_variants ().at (0);
+ TyTy::VariantDef *variant = nullptr;
if (adt->is_enum ())
{
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)
+ {
+ rust_error_at (
+ pattern.get_locus (), ErrorCode::E0532,
+ "expected tuple struct or tuple variant, found enum %qs",
+ pattern_ty->get_name ().c_str ());
+ return;
+ }
ok = adt->lookup_variant_by_id (variant_id, &variant);
rust_assert (ok);
}
+ else
+ {
+ rust_assert (adt->number_of_variants () > 0);
+ variant = adt->get_variants ().at (0);
+ }
+
+ rust_assert (variant != nullptr);
// error[E0532]: expected tuple struct or tuple variant, found struct
// variant `Foo::D`, E0532 by rustc 1.49.0 , E0164 by rustc 1.71.0
@@ -200,33 +215,144 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
auto &items = pattern.get_items ();
switch (items.get_item_type ())
{
- case HIR::TupleStructItems::RANGED:
+ case HIR::TupleStructItems::HAS_REST:
{
- // TODO
- rust_unreachable ();
+ HIR::TupleStructItemsHasRest &items_has_rest
+ = static_cast<HIR::TupleStructItemsHasRest &> (items);
+ auto &lower_patterns = items_has_rest.get_lower_patterns ();
+ auto &upper_patterns = items_has_rest.get_upper_patterns ();
+ size_t pattern_min_cap
+ = lower_patterns.size () + upper_patterns.size ();
+ if (variant->num_fields () < pattern_min_cap)
+ {
+ if (!lower_patterns.empty ())
+ {
+ // TODO initialize rich_locus with loc of ADT definition instead
+ rich_location rich_locus (line_table,
+ lower_patterns[0]->get_locus ());
+ for (auto &pattern : lower_patterns)
+ {
+ if (pattern == lower_patterns[0])
+ continue;
+ rich_locus.add_range (pattern->get_locus (),
+ SHOW_RANGE_WITH_CARET);
+ }
+ for (auto &pattern : upper_patterns)
+ {
+ rich_locus.add_range (pattern->get_locus (),
+ SHOW_RANGE_WITH_CARET);
+ }
+ rust_error_at (rich_locus, ErrorCode::E0023,
+ "this pattern has %lu %s but the corresponding "
+ "tuple variant has %lu %s",
+ (unsigned long) (pattern_min_cap),
+ pattern_min_cap == 1 ? "field" : "fields",
+ (unsigned long) variant->num_fields (),
+ variant->num_fields () == 1 ? "field"
+ : "fields");
+ }
+ else
+ {
+ // TODO initialize rich_locus with loc of ADT definition instead
+ rich_location rich_locus (line_table,
+ upper_patterns[0]->get_locus ());
+ for (auto &pattern : upper_patterns)
+ {
+ if (pattern == upper_patterns[0])
+ continue;
+ rich_locus.add_range (pattern->get_locus (),
+ SHOW_RANGE_WITH_CARET);
+ }
+ rust_error_at (rich_locus, ErrorCode::E0023,
+ "this pattern has %lu %s but the corresponding "
+ "tuple variant has %lu %s",
+ (unsigned long) (pattern_min_cap),
+ pattern_min_cap == 1 ? "field" : "fields",
+ (unsigned long) variant->num_fields (),
+ variant->num_fields () == 1 ? "field"
+ : "fields");
+ }
+ // we continue on to try and setup the types as best we can for
+ // type checking
+ }
+
+ // iterate the fields manually to set them up
+ size_t i = 0;
+ for (auto &pattern : lower_patterns)
+ {
+ if (i >= variant->num_fields ())
+ break;
+
+ TyTy::StructFieldType *field = variant->get_field_at_index (i++);
+ TyTy::BaseType *fty = field->get_field_type ();
+
+ // setup the type on this pattern type
+ context->insert_type (pattern->get_mappings (), fty);
+ TypeCheckPattern::Resolve (*pattern, fty);
+ }
+
+ i = variant->num_fields () - upper_patterns.size ();
+ for (auto &pattern : upper_patterns)
+ {
+ if (i >= variant->num_fields ())
+ break;
+
+ TyTy::StructFieldType *field = variant->get_field_at_index (i++);
+ TyTy::BaseType *fty = field->get_field_type ();
+
+ // setup the type on this pattern type
+ context->insert_type (pattern->get_mappings (), fty);
+ TypeCheckPattern::Resolve (*pattern, fty);
+ }
}
break;
- case HIR::TupleStructItems::MULTIPLE:
+ case HIR::TupleStructItems::NO_REST:
{
- HIR::TupleStructItemsNoRange &items_no_range
- = static_cast<HIR::TupleStructItemsNoRange &> (items);
+ HIR::TupleStructItemsNoRest &items_no_rest
+ = static_cast<HIR::TupleStructItemsNoRest &> (items);
+ auto &patterns = items_no_rest.get_patterns ();
- if (items_no_range.get_patterns ().size () != variant->num_fields ())
+ if (patterns.size () != variant->num_fields ())
{
- rust_error_at (
- pattern.get_locus (), ErrorCode::E0023,
- "this pattern has %lu fields but the corresponding "
- "tuple variant has %lu field",
- (unsigned long) items_no_range.get_patterns ().size (),
- (unsigned long) variant->num_fields ());
+ if (patterns.empty ())
+ {
+ rust_error_at (pattern.get_locus (), ErrorCode::E0023,
+ "this pattern has %lu %s but the corresponding "
+ "tuple variant has %lu %s",
+ (unsigned long) patterns.size (),
+ patterns.size () == 1 ? "field" : "fields",
+ (unsigned long) variant->num_fields (),
+ variant->num_fields () == 1 ? "field"
+ : "fields");
+ }
+ else
+ {
+ rich_location rich_locus (line_table,
+ patterns[0]->get_locus ());
+ for (auto &pattern : items_no_rest.get_patterns ())
+ {
+ if (pattern == patterns[0])
+ continue;
+ rich_locus.add_range (pattern->get_locus (),
+ SHOW_RANGE_WITH_CARET);
+ }
+ rust_error_at (rich_locus, ErrorCode::E0023,
+ "this pattern has %lu %s but the corresponding "
+ "tuple variant has %lu %s",
+ (unsigned long) patterns.size (),
+ patterns.size () == 1 ? "field" : "fields",
+ (unsigned long) variant->num_fields (),
+ variant->num_fields () == 1 ? "field"
+ : "fields");
+ }
// we continue on to try and setup the types as best we can for
// type checking
}
// iterate the fields and set them up, I wish we had ZIP
size_t i = 0;
- for (auto &pattern : items_no_range.get_patterns ())
+ for (auto &pattern : items_no_rest.get_patterns ())
{
if (i >= variant->num_fields ())
break;
@@ -299,7 +425,30 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
// error[E0532]: expected tuple struct or tuple variant, found struct
// variant `Foo::D`
- if (variant->get_variant_type () != TyTy::VariantDef::VariantType::STRUCT)
+ bool error_E0532 = false;
+ if (variant->get_variant_type () == TyTy::VariantDef::VariantType::TUPLE)
+ {
+ // Tuple structs can still be matched with struct patterns via index
+ // numbers e.g. Foo {0: a, .., 3: b}, so check whether the fields are of
+ // type TUPLE_PAT. Throw E0532 if not.
+ auto &struct_pattern_elems = pattern.get_struct_pattern_elems ();
+ for (auto &field : struct_pattern_elems.get_struct_pattern_fields ())
+ {
+ if (field->get_item_type ()
+ != HIR::StructPatternField::ItemType::TUPLE_PAT)
+ {
+ error_E0532 = true;
+ break;
+ }
+ }
+ }
+ else if (variant->get_variant_type ()
+ != TyTy::VariantDef::VariantType::STRUCT)
+ {
+ error_E0532 = true;
+ }
+
+ if (error_E0532)
{
std::string variant_type
= TyTy::VariantDef::variant_type_string (variant->get_variant_type ());
@@ -407,7 +556,8 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
// Expects enum struct or struct struct.
// error[E0027]: pattern does not mention fields `x`, `y`
// error[E0026]: variant `Foo::D` does not have a field named `b`
- if (named_fields.size () != variant->num_fields ())
+ if (!pattern.get_struct_pattern_elems ().has_rest ()
+ && named_fields.size () != variant->num_fields ())
{
std::map<std::string, bool> missing_names;
@@ -463,10 +613,10 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::ItemType::MULTIPLE:
+ case HIR::TuplePatternItems::ItemType::NO_REST:
{
- auto &ref = static_cast<HIR::TuplePatternItemsMultiple &> (
- pattern.get_items ());
+ auto &ref
+ = static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
const auto &patterns = ref.get_patterns ();
size_t nitems_to_resolve = patterns.size ();
@@ -486,17 +636,17 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
TyTy::BaseType *par_type = par.get_field (i);
TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
- pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
+ pattern_elems.emplace_back (elem->get_ref ());
}
infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (),
pattern.get_locus (), pattern_elems);
}
break;
- case HIR::TuplePatternItems::ItemType::RANGED:
+ case HIR::TuplePatternItems::ItemType::HAS_REST:
{
- HIR::TuplePatternItemsRanged &ref
- = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+ HIR::TuplePatternItemsHasRest &ref
+ = static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
const auto &lower = ref.get_lower_patterns ();
const auto &upper = ref.get_upper_patterns ();
@@ -507,37 +657,45 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
{
emit_pattern_size_error (pattern, par.get_fields ().size (),
min_size_required);
- // TODO attempt to continue to do typechecking even after wrong size
- break;
+ // continue and attempt to resolve individual items in the pattern
}
// Resolve lower patterns
std::vector<TyTy::TyVar> pattern_elems;
- for (size_t i = 0; i < lower.size (); i++)
+ size_t nlower_items_to_resolve
+ = std::min (lower.size (), par.get_fields ().size ());
+ for (size_t i = 0; i < nlower_items_to_resolve; i++)
{
auto &p = lower[i];
TyTy::BaseType *par_type = par.get_field (i);
TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
- pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
+ pattern_elems.emplace_back (elem->get_ref ());
}
+ if (lower.size () > par.get_fields ().size ())
+ break;
+
// Pad pattern_elems until needing to resolve upper patterns
- size_t rest_end = par.get_fields ().size () - upper.size ();
+ size_t rest_end
+ = std::max (par.get_fields ().size () - upper.size (), lower.size ());
for (size_t i = lower.size (); i < rest_end; i++)
{
TyTy::BaseType *par_type = par.get_field (i);
- pattern_elems.push_back (TyTy::TyVar (par_type->get_ref ()));
+ pattern_elems.emplace_back (par_type->get_ref ());
}
+ size_t nupper_items_to_resolve
+ = std::min (upper.size (),
+ par.get_fields ().size () - pattern_elems.size ());
// Resolve upper patterns
- for (size_t i = 0; i < upper.size (); i++)
+ for (size_t i = 0; i < nupper_items_to_resolve; i++)
{
auto &p = upper[i];
TyTy::BaseType *par_type = par.get_field (rest_end + i);
TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
- pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
+ pattern_elems.emplace_back (elem->get_ref ());
}
infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (),
@@ -642,7 +800,32 @@ TypeCheckPattern::visit (HIR::SlicePattern &pattern)
auto &array_ty_ty = static_cast<TyTy::ArrayType &> (*parent);
parent_element_ty = array_ty_ty.get_element_type ();
auto capacity = array_ty_ty.get_capacity ();
- tree cap = capacity->get_value ();
+
+ tree cap = error_mark_node;
+ if (capacity->get_kind () != TyTy::TypeKind::CONST)
+ {
+ // Error case - capacity is not a const type
+ break;
+ }
+
+ auto *capacity_const = capacity->as_const_type ();
+ switch (capacity_const->const_kind ())
+ {
+ case TyTy::BaseConstType::ConstKind::Value:
+ {
+ const auto &const_value
+ = *static_cast<TyTy::ConstValueType *> (capacity);
+ cap = const_value.get_value ();
+ }
+ break;
+
+ case TyTy::BaseConstType::ConstKind::Decl:
+ case TyTy::BaseConstType::ConstKind::Infer:
+ case TyTy::BaseConstType::ConstKind::Error:
+ cap = error_mark_node;
+ break;
+ }
+
if (error_operand_p (cap))
{
rust_error_at (parent->get_locus (),
@@ -651,14 +834,45 @@ TypeCheckPattern::visit (HIR::SlicePattern &pattern)
break;
}
auto cap_wi = wi::to_wide (cap).to_uhwi ();
- if (cap_wi != pattern.get_items ().size ())
+
+ // size check during compile time
+ switch (pattern.get_items ().get_item_type ())
{
- rust_error_at (pattern.get_locus (), ErrorCode::E0527,
- "pattern requires %lu elements but array has %lu",
- (unsigned long) pattern.get_items ().size (),
- (unsigned long) cap_wi);
+ case HIR::SlicePatternItems::ItemType::NO_REST:
+ {
+ auto &ref = static_cast<HIR::SlicePatternItemsNoRest &> (
+ pattern.get_items ());
+ if (cap_wi != ref.get_patterns ().size ())
+ {
+ rust_error_at (
+ pattern.get_locus (), ErrorCode::E0527,
+ "pattern requires %lu elements but array has %lu",
+ (unsigned long) ref.get_patterns ().size (),
+ (unsigned long) cap_wi);
+ break;
+ }
+ }
+ break;
+ case HIR::SlicePatternItems::ItemType::HAS_REST:
+ {
+ auto &ref = static_cast<HIR::SlicePatternItemsHasRest &> (
+ pattern.get_items ());
+ auto pattern_min_cap = ref.get_lower_patterns ().size ()
+ + ref.get_upper_patterns ().size ();
+
+ if (cap_wi < pattern_min_cap)
+ {
+ rust_error_at (pattern.get_locus (), ErrorCode::E0528,
+ "pattern requires at least %lu elements but "
+ "array has %lu",
+ (unsigned long) pattern_min_cap,
+ (unsigned long) cap_wi);
+ break;
+ }
+ }
break;
}
+
break;
}
case TyTy::SLICE:
@@ -694,10 +908,32 @@ TypeCheckPattern::visit (HIR::SlicePattern &pattern)
infered->set_ref (pattern.get_mappings ().get_hirid ());
// Type check every item in the SlicePattern against parent's element ty
- // TODO update this after adding support for RestPattern in SlicePattern
- for (const auto &item : pattern.get_items ())
+ switch (pattern.get_items ().get_item_type ())
{
- TypeCheckPattern::Resolve (*item, parent_element_ty);
+ case HIR::SlicePatternItems::ItemType::NO_REST:
+ {
+ auto &ref
+ = static_cast<HIR::SlicePatternItemsNoRest &> (pattern.get_items ());
+ for (const auto &pattern_member : ref.get_patterns ())
+ {
+ TypeCheckPattern::Resolve (*pattern_member, parent_element_ty);
+ }
+ break;
+ }
+ case HIR::SlicePatternItems::ItemType::HAS_REST:
+ {
+ auto &ref
+ = static_cast<HIR::SlicePatternItemsHasRest &> (pattern.get_items ());
+ for (const auto &pattern_member : ref.get_lower_patterns ())
+ {
+ TypeCheckPattern::Resolve (*pattern_member, parent_element_ty);
+ }
+ for (const auto &pattern_member : ref.get_upper_patterns ())
+ {
+ TypeCheckPattern::Resolve (*pattern_member, parent_element_ty);
+ }
+ break;
+ }
}
}
@@ -814,6 +1050,11 @@ ClosureParamInfer::visit (HIR::WildcardPattern &pattern)
void
ClosureParamInfer::visit (HIR::IdentifierPattern &pattern)
{
+ if (pattern.has_subpattern ())
+ {
+ ClosureParamInfer::Resolve (pattern.get_subpattern ());
+ }
+
HirId id = pattern.get_mappings ().get_hirid ();
infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
TyTy::InferType::TypeHint::Default (),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index 4ef8348..eb44279 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -214,8 +214,7 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
rust_assert (ok);
adtFieldIndexToField[field_index] = implicit_field;
- struct_expr.get_fields ().push_back (
- std::unique_ptr<HIR::StructExprField> (implicit_field));
+ struct_expr.get_fields ().emplace_back (implicit_field);
}
}
}
@@ -245,11 +244,11 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
field.release ();
std::vector<std::unique_ptr<HIR::StructExprField> > ordered_fields;
+ ordered_fields.reserve (adtFieldIndexToField.size ());
+
for (size_t i = 0; i < adtFieldIndexToField.size (); i++)
- {
- ordered_fields.push_back (
- std::unique_ptr<HIR::StructExprField> (adtFieldIndexToField[i]));
- }
+ ordered_fields.emplace_back (adtFieldIndexToField[i]);
+
struct_expr.set_fields_as_owner (std::move (ordered_fields));
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 78037bd..799efc8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -97,15 +97,20 @@ TypeCheckType::visit (HIR::BareFunctionType &fntype)
}
std::vector<TyTy::TyVar> params;
+ params.reserve (fntype.get_function_params ().size ());
+
for (auto &param : fntype.get_function_params ())
{
TyTy::BaseType *ptype = TypeCheckType::Resolve (param.get_type ());
- params.push_back (TyTy::TyVar (ptype->get_ref ()));
+ params.emplace_back (ptype->get_ref ());
}
- translated = new TyTy::FnPtr (fntype.get_mappings ().get_hirid (),
- fntype.get_locus (), std::move (params),
- TyTy::TyVar (return_type->get_ref ()));
+ translated
+ = new TyTy::FnPtr (fntype.get_mappings ().get_hirid (), fntype.get_locus (),
+ std::move (params),
+ TyTy::TyVar (return_type->get_ref ()),
+ fntype.get_function_qualifiers ().get_abi (),
+ fntype.get_function_qualifiers ().get_unsafety ());
}
void
@@ -118,10 +123,12 @@ TypeCheckType::visit (HIR::TupleType &tuple)
}
std::vector<TyTy::TyVar> fields;
+ fields.reserve (tuple.get_elems ().size ());
+
for (auto &elem : tuple.get_elems ())
{
auto field_ty = TypeCheckType::Resolve (*elem);
- fields.push_back (TyTy::TyVar (field_ty->get_ref ()));
+ fields.emplace_back (field_ty->get_ref ());
}
translated = new TyTy::TupleType (tuple.get_mappings ().get_hirid (),
@@ -207,9 +214,9 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
// lookup the associated item from the specified bound
HIR::TypePathSegment &item_seg = path.get_associated_segment ();
HIR::PathIdentSegment item_seg_identifier = item_seg.get_ident_segment ();
- TyTy::TypeBoundPredicateItem item
+ tl::optional<TyTy::TypeBoundPredicateItem> item
= specified_bound.lookup_associated_item (item_seg_identifier.as_string ());
- if (item.is_error ())
+ if (!item.has_value ())
{
std::string item_seg_ident_name, rich_msg;
item_seg_ident_name = qual_path_type.get_trait ().as_string ();
@@ -261,7 +268,7 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
// and we dont need to worry if the trait item is actually implemented or
// not because this will have already been validated as part of the trait
// impl block
- translated = item.get_tyty_for_receiver (root);
+ translated = item->get_tyty_for_receiver (root);
}
else
{
@@ -699,38 +706,47 @@ TypeCheckType::visit (HIR::ArrayType &type)
rust_assert (ok);
context->insert_type (type.get_size_expr ().get_mappings (), expected_ty);
- TyTy::ConstType *const_type = nullptr;
+ TyTy::BaseConstType *const_type = nullptr;
if (capacity_type->get_kind () == TyTy::TypeKind::CONST)
{
- const_type = static_cast<TyTy::ConstType *> (capacity_type);
+ const_type = capacity_type->as_const_type ();
unify_site (type.get_size_expr ().get_mappings ().get_hirid (),
TyTy::TyWithLocation (expected_ty),
- TyTy::TyWithLocation (const_type->get_ty (),
+ TyTy::TyWithLocation (const_type->get_specified_type (),
type.get_size_expr ().get_locus ()),
type.get_size_expr ().get_locus ());
}
else
{
HirId size_id = type.get_size_expr ().get_mappings ().get_hirid ();
- unify_site (size_id, TyTy::TyWithLocation (expected_ty),
- TyTy::TyWithLocation (capacity_type,
- type.get_size_expr ().get_locus ()),
- type.get_size_expr ().get_locus ());
-
- auto ctx = Compile::Context::get ();
- tree capacity_expr = Compile::HIRCompileBase::query_compile_const_expr (
- ctx, capacity_type, type.get_size_expr ());
-
- const_type = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "",
- expected_ty, capacity_expr, {},
- type.get_size_expr ().get_locus (),
- size_id, size_id);
+ TyTy::BaseType *result
+ = unify_site (size_id, TyTy::TyWithLocation (expected_ty),
+ TyTy::TyWithLocation (capacity_type,
+ type.get_size_expr ().get_locus ()),
+ type.get_size_expr ().get_locus ());
+
+ if (result->is<TyTy::ErrorType> ())
+ const_type = new TyTy::ConstErrorType (expected_ty, size_id, size_id);
+ else
+ {
+ auto ctx = Compile::Context::get ();
+ tree capacity_expr
+ = Compile::HIRCompileBase::query_compile_const_expr (
+ ctx, capacity_type, type.get_size_expr ());
+
+ const_type = new TyTy::ConstValueType (capacity_expr, expected_ty,
+ size_id, size_id);
+ context->insert_type (type.get_size_expr ().get_mappings (),
+ const_type->as_base_type ());
+ }
}
translated
= new TyTy::ArrayType (type.get_mappings ().get_hirid (), type.get_locus (),
- const_type, TyTy::TyVar (element_type->get_ref ()));
+ TyTy::TyVar (
+ const_type->as_base_type ()->get_ty_ref ()),
+ TyTy::TyVar (element_type->get_ref ()));
}
void
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index aba4ab5..64f4314 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -260,7 +260,7 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
}
context->insert_type (self_param.get_mappings (), self_type);
- params.push_back (TyTy::FnParam (std::move (self_pattern), self_type));
+ params.emplace_back (std::move (self_pattern), self_type);
}
for (auto &param : function.get_function_params ())
@@ -270,8 +270,8 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
context->insert_type (param.get_mappings (), 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));
+ params.emplace_back (param.get_param_name ().clone_pattern (),
+ param_tyty);
}
auto &nr_ctx
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
index c5b823e..238ede4 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.cc
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -268,12 +268,30 @@ SubstMapperInternal::visit (TyTy::ParamType &type)
}
void
-SubstMapperInternal::visit (TyTy::ConstType &type)
+SubstMapperInternal::visit (TyTy::ConstParamType &type)
{
resolved = type.handle_substitions (mappings);
}
void
+SubstMapperInternal::visit (TyTy::ConstValueType &type)
+{
+ resolved = type.clone ();
+}
+
+void
+SubstMapperInternal::visit (TyTy::ConstInferType &type)
+{
+ resolved = type.clone ();
+}
+
+void
+SubstMapperInternal::visit (TyTy::ConstErrorType &type)
+{
+ resolved = type.clone ();
+}
+
+void
SubstMapperInternal::visit (TyTy::PlaceholderType &type)
{
rust_assert (type.can_resolve ());
@@ -310,15 +328,15 @@ SubstMapperInternal::visit (TyTy::SliceType &type)
{
resolved = type.handle_substitions (mappings);
}
-
-// nothing to do for these
void
-SubstMapperInternal::visit (TyTy::InferType &type)
+SubstMapperInternal::visit (TyTy::FnPtr &type)
{
- resolved = type.clone ();
+ resolved = type.handle_substitions (mappings);
}
+
+// nothing to do for these
void
-SubstMapperInternal::visit (TyTy::FnPtr &type)
+SubstMapperInternal::visit (TyTy::InferType &type)
{
resolved = type.clone ();
}
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index 2389d83..98f9e72 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -61,7 +61,10 @@ public:
void visit (TyTy::ReferenceType &) override { rust_unreachable (); }
void visit (TyTy::PointerType &) override { rust_unreachable (); }
void visit (TyTy::ParamType &) override { rust_unreachable (); }
- void visit (TyTy::ConstType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstParamType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstValueType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstInferType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstErrorType &) override { rust_unreachable (); }
void visit (TyTy::StrType &) override { rust_unreachable (); }
void visit (TyTy::NeverType &) override { rust_unreachable (); }
void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); }
@@ -93,7 +96,10 @@ public:
void visit (TyTy::ReferenceType &type) override;
void visit (TyTy::PointerType &type) override;
void visit (TyTy::ParamType &type) override;
- void visit (TyTy::ConstType &type) override;
+ void visit (TyTy::ConstParamType &type) override;
+ void visit (TyTy::ConstValueType &type) override;
+ void visit (TyTy::ConstInferType &type) override;
+ void visit (TyTy::ConstErrorType &type) override;
void visit (TyTy::PlaceholderType &type) override;
void visit (TyTy::ProjectionType &type) override;
void visit (TyTy::ClosureType &type) override;
@@ -147,13 +153,16 @@ public:
void visit (TyTy::ReferenceType &) override { rust_unreachable (); }
void visit (TyTy::PointerType &) override { rust_unreachable (); }
void visit (TyTy::ParamType &) override { rust_unreachable (); }
- void visit (TyTy::ConstType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstParamType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstValueType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstInferType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstErrorType &) override { rust_unreachable (); }
void visit (TyTy::StrType &) override { rust_unreachable (); }
void visit (TyTy::NeverType &) override { rust_unreachable (); }
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 (); }
+ void visit (TyTy::OpaqueType &) override { rust_unreachable (); }
private:
SubstMapperFromExisting (TyTy::BaseType *concrete, TyTy::BaseType *receiver);
@@ -188,7 +197,10 @@ public:
void visit (const TyTy::ReferenceType &) override {}
void visit (const TyTy::PointerType &) override {}
void visit (const TyTy::ParamType &) override {}
- void visit (const TyTy::ConstType &) override {}
+ void visit (const TyTy::ConstParamType &) override {}
+ void visit (const TyTy::ConstValueType &) override {}
+ void visit (const TyTy::ConstInferType &) override {}
+ void visit (const TyTy::ConstErrorType &) override {}
void visit (const TyTy::StrType &) override {}
void visit (const TyTy::NeverType &) override {}
void visit (const TyTy::PlaceholderType &) override {}
diff --git a/gcc/rust/typecheck/rust-type-util.cc b/gcc/rust/typecheck/rust-type-util.cc
index 2d66166..6f30ebf 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -152,11 +152,12 @@ query_type (HirId reference, TyTy::BaseType **result)
bool
types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
- location_t unify_locus, bool emit_errors)
+ location_t unify_locus, bool emit_errors, bool check_bounds)
{
TyTy::BaseType *result
= unify_site_and (UNKNOWN_HIRID, lhs, rhs, unify_locus, emit_errors,
- false /*commit*/, true /*infer*/, true /*cleanup*/);
+ false /*commit*/, true /*infer*/, true /*cleanup*/,
+ check_bounds);
return result->get_kind () != TyTy::TypeKind::ERROR;
}
@@ -173,32 +174,34 @@ unify_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
std::vector<UnifyRules::CommitSite> commits;
std::vector<UnifyRules::InferenceSite> infers;
return UnifyRules::Resolve (lhs, rhs, unify_locus, true /*commit*/,
- true /*emit_error*/, false /*infer*/, commits,
- infers);
+ true /*emit_error*/, false /*infer*/,
+ true /*check_bounds*/, commits, infers);
}
TyTy::BaseType *
unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
location_t unify_locus, bool emit_errors, bool commit_if_ok,
- bool implicit_infer_vars, bool cleanup)
+ bool implicit_infer_vars, bool cleanup, bool check_bounds)
{
TypeCheckContext &context = *TypeCheckContext::get ();
TyTy::BaseType *expected = lhs.get_ty ();
TyTy::BaseType *expr = rhs.get_ty ();
- rust_debug_loc (
- unify_locus,
- "begin unify_site_and commit %s infer %s id={%u} expected={%s} expr={%s}",
- commit_if_ok ? "true" : "false", implicit_infer_vars ? "true" : "false",
- id == UNKNOWN_HIRID ? 0 : id, expected->debug_str ().c_str (),
- expr->debug_str ().c_str ());
+ rust_debug_loc (unify_locus,
+ "begin unify_site_and commit %s infer %s check_bounds %s "
+ "id={%u} expected={%s} expr={%s}",
+ commit_if_ok ? "true" : "false",
+ implicit_infer_vars ? "true" : "false",
+ check_bounds ? "true" : "false", id == UNKNOWN_HIRID ? 0 : id,
+ expected->debug_str ().c_str (), expr->debug_str ().c_str ());
std::vector<UnifyRules::CommitSite> commits;
std::vector<UnifyRules::InferenceSite> infers;
TyTy::BaseType *result
= UnifyRules::Resolve (lhs, rhs, unify_locus, false /*commit inline*/,
- emit_errors, implicit_infer_vars, commits, infers);
+ emit_errors, implicit_infer_vars, check_bounds,
+ commits, infers);
bool ok = result->get_kind () != TyTy::TypeKind::ERROR;
rust_debug_loc (unify_locus,
@@ -228,7 +231,8 @@ unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
// remove the inference variable
context.clear_type (i.infer);
- delete i.infer;
+ // FIXME: Don't delete - result might point to this
+ // delete i.infer;
}
}
return result;
@@ -325,7 +329,7 @@ cast_site (HirId id, TyTy::TyWithLocation from, TyTy::TyWithLocation to,
AssociatedImplTrait *
lookup_associated_impl_block (const TyTy::TypeBoundPredicate &bound,
- const TyTy::BaseType *binding, bool *ambigious)
+ TyTy::BaseType *binding, bool *ambigious)
{
auto context = TypeCheckContext::get ();
diff --git a/gcc/rust/typecheck/rust-type-util.h b/gcc/rust/typecheck/rust-type-util.h
index dd97f1e..7f4a94e 100644
--- a/gcc/rust/typecheck/rust-type-util.h
+++ b/gcc/rust/typecheck/rust-type-util.h
@@ -28,7 +28,8 @@ namespace Resolver {
bool query_type (HirId reference, TyTy::BaseType **result);
bool types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
- location_t unify_locus, bool emit_errors);
+ location_t unify_locus, bool emit_errors,
+ bool check_bounds = true);
TyTy::BaseType *unify_site (HirId id, TyTy::TyWithLocation lhs,
TyTy::TyWithLocation rhs, location_t unify_locus);
@@ -37,7 +38,7 @@ TyTy::BaseType *unify_site_and (HirId id, TyTy::TyWithLocation lhs,
TyTy::TyWithLocation rhs,
location_t unify_locus, bool emit_errors,
bool commit_if_ok, bool implicit_infer_vars,
- bool cleanup);
+ bool cleanup, bool check_bounds = true);
TyTy::BaseType *coercion_site (HirId id, TyTy::TyWithLocation lhs,
TyTy::TyWithLocation rhs,
@@ -52,7 +53,7 @@ TyTy::BaseType *cast_site (HirId id, TyTy::TyWithLocation from,
AssociatedImplTrait *
lookup_associated_impl_block (const TyTy::TypeBoundPredicate &bound,
- const TyTy::BaseType *binding,
+ TyTy::BaseType *binding,
bool *ambigious = nullptr);
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc
index c74a920..3419ef6 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -154,7 +154,7 @@ void
TypeCheckContext::push_return_type (TypeCheckContextItem item,
TyTy::BaseType *return_type)
{
- return_type_stack.push_back ({std::move (item), return_type});
+ return_type_stack.emplace_back (std::move (item), return_type);
}
void
@@ -310,7 +310,7 @@ TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
associated_traits_to_impls[trait_id] = {};
}
- associated_traits_to_impls[trait_id].push_back ({impl_type, impl_id});
+ associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
}
bool
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 6cf9b04..a59de99 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -26,12 +26,12 @@
namespace Rust {
namespace Resolver {
-TypeBoundsProbe::TypeBoundsProbe (const TyTy::BaseType *receiver)
+TypeBoundsProbe::TypeBoundsProbe (TyTy::BaseType *receiver)
: TypeCheckBase (), receiver (receiver)
{}
std::vector<std::pair<TraitReference *, HIR::ImplBlock *>>
-TypeBoundsProbe::Probe (const TyTy::BaseType *receiver)
+TypeBoundsProbe::Probe (TyTy::BaseType *receiver)
{
TypeBoundsProbe probe (receiver);
probe.scan ();
@@ -75,22 +75,18 @@ TypeBoundsProbe::process_impl_block (
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;
- if (!receiver->can_eq (impl_type, false))
- {
- if (!impl_type->can_eq (receiver, false))
- return true;
- }
+ if (!types_compatable (TyTy::TyWithLocation (receiver),
+ TyTy::TyWithLocation (impl_type), impl->get_locus (),
+ false /*emit_errors*/, false /*check-bounds*/))
+ return true;
- possible_trait_paths.push_back ({&impl->get_trait_ref (), impl});
+ possible_trait_paths.emplace_back (&impl->get_trait_ref (), impl);
return true;
}
@@ -110,7 +106,7 @@ TypeBoundsProbe::scan ()
TraitReference *trait_ref = TraitResolver::Resolve (*trait_path);
if (!trait_ref->is_error ())
- trait_references.push_back ({trait_ref, path.second});
+ trait_references.emplace_back (trait_ref, path.second);
}
// marker traits...
@@ -185,7 +181,7 @@ TypeBoundsProbe::add_trait_bound (HIR::Trait *trait)
{
auto trait_ref = TraitResolver::Resolve (*trait);
- trait_references.push_back ({trait_ref, mappings.lookup_builtin_marker ()});
+ trait_references.emplace_back (trait_ref, mappings.lookup_builtin_marker ());
}
void
@@ -306,11 +302,9 @@ TypeCheckBase::get_predicate_from_bound (
std::vector<HIR::GenericArgsBinding> bindings;
location_t output_locus = fn.get_return_type ().get_locus ();
- HIR::GenericArgsBinding binding (Identifier (
- trait_item->trait_identifier ()),
- fn.get_return_type ().clone_type (),
- output_locus);
- bindings.push_back (std::move (binding));
+ bindings.emplace_back (Identifier (trait_item->trait_identifier ()),
+ fn.get_return_type ().clone_type (),
+ output_locus);
args = HIR::GenericArgs ({} /* lifetimes */,
std::move (inputs) /* type_args*/,
@@ -468,8 +462,8 @@ TypeBoundPredicate::operator= (const TypeBoundPredicate &other)
{
TyTy::BaseType *argument
= m.get_tyty () == nullptr ? nullptr : m.get_tyty ()->clone ();
- SubstitutionArg c (&substitutions.at (i++), argument);
- copied_arg_mappings.push_back (std::move (c));
+
+ copied_arg_mappings.emplace_back (&substitutions.at (i++), argument);
}
used_arguments
@@ -577,10 +571,13 @@ TypeBoundPredicate::apply_argument_mappings (
std::string identifier = it.first;
TyTy::BaseType *type = it.second;
- TypeBoundPredicateItem item = lookup_associated_item (identifier);
- rust_assert (!item.is_error ());
+ tl::optional<TypeBoundPredicateItem> item
+ = lookup_associated_item (identifier);
- const auto item_ref = item.get_raw_item ();
+ if (!item.has_value ())
+ continue;
+
+ const auto item_ref = item->get_raw_item ();
item_ref->associated_type_set (type);
}
@@ -601,7 +598,7 @@ TypeBoundPredicate::contains_item (const std::string &search) const
return trait_ref->lookup_trait_item (search, &trait_item_ref);
}
-TypeBoundPredicateItem
+tl::optional<TypeBoundPredicateItem>
TypeBoundPredicate::lookup_associated_item (const std::string &search) const
{
auto trait_ref = get ();
@@ -613,11 +610,11 @@ TypeBoundPredicate::lookup_associated_item (const std::string &search) const
for (auto &super_trait : super_traits)
{
auto lookup = super_trait.lookup_associated_item (search);
- if (!lookup.is_error ())
+ if (lookup.has_value ())
return lookup;
}
- return TypeBoundPredicateItem::error ();
+ return tl::nullopt;
}
TypeBoundPredicateItem::TypeBoundPredicateItem (
@@ -658,7 +655,7 @@ TypeBoundPredicateItem::get_parent () const
return &parent;
}
-TypeBoundPredicateItem
+tl::optional<TypeBoundPredicateItem>
TypeBoundPredicate::lookup_associated_item (
const Resolver::TraitItemReference *ref) const
{
@@ -691,8 +688,7 @@ TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver)
TyTy::BaseType *argument
= is_implicit_self ? receiver->clone () : mapping.get_tyty ();
- SubstitutionArg arg (mapping.get_param_mapping (), argument);
- adjusted_mappings.push_back (std::move (arg));
+ adjusted_mappings.emplace_back (mapping.get_param_mapping (), argument);
}
SubstitutionArgumentMappings adjusted (adjusted_mappings, {},
@@ -735,10 +731,11 @@ TypeBoundPredicate::handle_substitions (
std::string identifier = it.first;
TyTy::BaseType *type = it.second;
- TypeBoundPredicateItem item = lookup_associated_item (identifier);
- if (!item.is_error ())
+ tl::optional<TypeBoundPredicateItem> item
+ = lookup_associated_item (identifier);
+ if (item.has_value ())
{
- const auto item_ref = item.get_raw_item ();
+ const auto item_ref = item->get_raw_item ();
item_ref->associated_type_set (type);
}
}
@@ -802,18 +799,18 @@ TypeBoundPredicate::get_trait_hierachy (
TypeBoundPredicateItem
TypeBoundPredicate::lookup_associated_type (const std::string &search)
{
- TypeBoundPredicateItem item = lookup_associated_item (search);
+ tl::optional<TypeBoundPredicateItem> item = lookup_associated_item (search);
// only need to check that it is infact an associated type because other
// wise if it was not found it will just be an error node anyway
- if (!item.is_error ())
+ if (item.has_value ())
{
- const auto raw = item.get_raw_item ();
+ const auto raw = item->get_raw_item ();
if (raw->get_trait_item_type ()
!= Resolver::TraitItemReference::TraitItemType::TYPE)
return TypeBoundPredicateItem::error ();
}
- return item;
+ return item.value ();
}
std::vector<TypeBoundPredicateItem>
@@ -827,10 +824,7 @@ TypeBoundPredicate::get_associated_type_items ()
= trait_item.get_trait_item_type ()
== Resolver::TraitItemReference::TraitItemType::TYPE;
if (is_associated_type)
- {
- TypeBoundPredicateItem item (*this, &trait_item);
- items.push_back (std::move (item));
- }
+ items.emplace_back (*this, &trait_item);
}
return items;
}
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index 63bb1ff..e82e618 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -59,7 +59,7 @@ TypeCheckCallExpr::visit (ADTType &type)
if (variant.get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
{
rust_error_at (
- call.get_locus (), ErrorCode::E0423,
+ call.get_locus (), ErrorCode::E0618,
"expected function, tuple struct or tuple variant, found struct %qs",
type.get_name ().c_str ());
return;
@@ -327,8 +327,8 @@ TypeCheckMethodCallExpr::go (FnType *ref, HIR::MethodCallExpr &call,
return new ErrorType (ref->get_ref ());
}
- Argument a (arg->get_mappings (), argument_expr_tyty, arg->get_locus ());
- args.push_back (std::move (a));
+ args.emplace_back (arg->get_mappings (), argument_expr_tyty,
+ arg->get_locus ());
}
TypeCheckMethodCallExpr checker (call.get_mappings (), args,
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index 9e4aab5..025a1ad 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -60,9 +60,12 @@ public:
void visit (PlaceholderType &) override { rust_unreachable (); }
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 (); }
- void visit (ConstType &type) override { rust_unreachable (); }
+ void visit (ClosureType &) override { rust_unreachable (); }
+ void visit (OpaqueType &) override { rust_unreachable (); }
+ void visit (ConstParamType &) override { rust_unreachable (); }
+ void visit (ConstValueType &) override { rust_unreachable (); }
+ void visit (ConstInferType &) override { rust_unreachable (); }
+ void visit (ConstErrorType &) override { rust_unreachable (); }
// tuple-structs
void visit (ADTType &type) override;
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h
deleted file mode 100644
index c22dfdd..0000000
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ /dev/null
@@ -1,1645 +0,0 @@
-// Copyright (C) 2020-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_TYTY_CMP_H
-#define RUST_TYTY_CMP_H
-
-#include "rust-diagnostics.h"
-#include "rust-tyty.h"
-#include "rust-tyty-visitor.h"
-#include "rust-hir-map.h"
-#include "rust-hir-type-check.h"
-
-namespace Rust {
-namespace TyTy {
-
-class BaseCmp : public TyConstVisitor
-{
-public:
- virtual bool can_eq (const BaseType *other)
- {
- if (other->get_kind () == TypeKind::PARAM)
- {
- const ParamType *p = static_cast<const ParamType *> (other);
- other = p->resolve ();
- }
- if (other->get_kind () == TypeKind::PLACEHOLDER)
- {
- const PlaceholderType *p = static_cast<const PlaceholderType *> (other);
- if (p->can_resolve ())
- {
- other = p->resolve ();
- }
- }
- if (other->get_kind () == TypeKind::PROJECTION)
- {
- const ProjectionType *p = static_cast<const ProjectionType *> (other);
- other = p->get ();
- }
-
- other->accept_vis (*this);
- return ok;
- }
-
- virtual void visit (const TupleType &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 ());
- }
- }
-
- virtual void visit (const ADTType &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 ());
- }
- }
-
- virtual void visit (const InferType &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 ());
- }
- }
-
- virtual void visit (const FnType &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 ());
- }
- }
-
- virtual void visit (const FnPtr &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 ());
- }
- }
-
- virtual void visit (const ArrayType &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 ());
- }
- }
-
- virtual void visit (const SliceType &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 ());
- }
- }
-
- virtual void visit (const BoolType &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 ());
- }
- }
-
- virtual void visit (const IntType &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 ());
- }
- }
-
- virtual void visit (const UintType &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 ());
- }
- }
-
- virtual void visit (const USizeType &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 ());
- }
- }
-
- virtual void visit (const ISizeType &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 ());
- }
- }
-
- virtual void visit (const FloatType &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 ());
- }
- }
-
- virtual void visit (const ErrorType &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 ());
- }
- }
-
- virtual void visit (const CharType &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 ());
- }
- }
-
- virtual void visit (const ReferenceType &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 ());
- }
- }
-
- virtual void visit (const PointerType &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 ());
- }
- }
-
- virtual void visit (const StrType &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 ());
- }
- }
-
- virtual void visit (const NeverType &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 ());
- }
- }
-
- virtual void visit (const ProjectionType &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 ());
- }
- }
-
- virtual void visit (const PlaceholderType &type) override
- {
- // it is ok for types to can eq to a placeholder
- ok = true;
- }
-
- virtual void visit (const ParamType &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 ());
- }
- }
-
- virtual void visit (const DynamicObjectType &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 ());
- }
- }
-
- virtual void visit (const ClosureType &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 ());
- }
- }
-
- 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 ());
- }
- }
-
- virtual void visit (const ConstType &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 ()),
- context (Resolver::TypeCheckContext::get ()), ok (false),
- emit_error_flag (emit_errors)
- {}
-
- Analysis::Mappings &mappings;
- Resolver::TypeCheckContext *context;
-
- bool ok;
- bool emit_error_flag;
-
-private:
- /* Returns a pointer to the ty that created this rule. */
- virtual const BaseType *get_base () const = 0;
-};
-
-class InferCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- InferCmp (const InferType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const BoolType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const IntType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::INTEGRAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const UintType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::INTEGRAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const USizeType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::INTEGRAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const ISizeType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::INTEGRAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const FloatType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const ArrayType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const SliceType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const ADTType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const TupleType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const InferType &type) override
- {
- switch (base->get_infer_kind ())
- {
- case InferType::InferTypeKind::GENERAL:
- ok = true;
- return;
-
- case InferType::InferTypeKind::INTEGRAL:
- {
- if (type.get_infer_kind () == InferType::InferTypeKind::INTEGRAL)
- {
- ok = true;
- return;
- }
- else if (type.get_infer_kind () == InferType::InferTypeKind::GENERAL)
- {
- ok = true;
- return;
- }
- }
- break;
-
- case InferType::InferTypeKind::FLOAT:
- {
- if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
- {
- ok = true;
- return;
- }
- else if (type.get_infer_kind () == InferType::InferTypeKind::GENERAL)
- {
- ok = true;
- return;
- }
- }
- break;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const CharType &type) override
- {
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
- }
-
- void visit (const ReferenceType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const PointerType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const ParamType &) override { ok = true; }
-
- void visit (const DynamicObjectType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
- void visit (const ClosureType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- ok = true;
- return;
- }
-
- BaseCmp::visit (type);
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const InferType *base;
-};
-
-class FnCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- FnCmp (const FnType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const InferType &type) override
- {
- ok = type.get_infer_kind () == InferType::InferTypeKind::GENERAL;
- }
-
- void visit (const FnType &type) override
- {
- if (base->num_params () != type.num_params ())
- {
- BaseCmp::visit (type);
- return;
- }
-
- for (size_t i = 0; i < base->num_params (); i++)
- {
- auto a = base->param_at (i).get_type ();
- auto b = type.param_at (i).get_type ();
-
- if (!a->can_eq (b, emit_error_flag))
- {
- emit_error_flag = false;
- BaseCmp::visit (type);
- return;
- }
- }
-
- if (!base->get_return_type ()->can_eq (type.get_return_type (),
- emit_error_flag))
- {
- emit_error_flag = false;
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const FnType *base;
-};
-
-class FnptrCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- FnptrCmp (const FnPtr *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
- void visit (const FnPtr &type) override
- {
- if (base->num_params () != type.num_params ())
- {
- BaseCmp::visit (type);
- return;
- }
-
- auto this_ret_type = base->get_return_type ();
- auto other_ret_type = type.get_return_type ();
- if (!this_ret_type->can_eq (other_ret_type, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
-
- for (size_t i = 0; i < base->num_params (); i++)
- {
- auto this_param = base->get_param_type_at (i);
- auto other_param = type.get_param_type_at (i);
- if (!this_param->can_eq (other_param, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
- }
-
- ok = true;
- }
-
- void visit (const FnType &type) override
- {
- if (base->num_params () != type.num_params ())
- {
- BaseCmp::visit (type);
- return;
- }
-
- auto this_ret_type = base->get_return_type ();
- auto other_ret_type = type.get_return_type ();
- if (!this_ret_type->can_eq (other_ret_type, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
-
- 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).get_type ();
- if (!this_param->can_eq (other_param, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const FnPtr *base;
-};
-
-class ClosureCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- ClosureCmp (const ClosureType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
- void visit (const ClosureType &type) override
- {
- if (base->get_def_id () != type.get_def_id ())
- {
- BaseCmp::visit (type);
- return;
- }
-
- if (!base->get_parameters ().can_eq (&type.get_parameters (), false))
- {
- BaseCmp::visit (type);
- return;
- }
-
- if (!base->get_result_type ().can_eq (&type.get_result_type (), false))
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const ClosureType *base;
-};
-
-class ArrayCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- ArrayCmp (const ArrayType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const ArrayType &type) override
- {
- // check base type
- const BaseType *base_element = base->get_element_type ();
- const BaseType *other_element = type.get_element_type ();
- if (!base_element->can_eq (other_element, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const ArrayType *base;
-};
-
-class SliceCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- SliceCmp (const SliceType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const SliceType &type) override
- {
- // check base type
- const BaseType *base_element = base->get_element_type ();
- const BaseType *other_element = type.get_element_type ();
- if (!base_element->can_eq (other_element, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const SliceType *base;
-};
-
-class BoolCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- BoolCmp (const BoolType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const BoolType &type) override { ok = true; }
-
- void visit (const InferType &type) override
- {
- ok = type.get_infer_kind () == InferType::InferTypeKind::GENERAL;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const BoolType *base;
-};
-
-class IntCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- IntCmp (const IntType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const InferType &type) override
- {
- ok = type.get_infer_kind () != InferType::InferTypeKind::FLOAT;
- }
-
- void visit (const IntType &type) override
- {
- ok = type.get_int_kind () == base->get_int_kind ();
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const IntType *base;
-};
-
-class UintCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- UintCmp (const UintType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const InferType &type) override
- {
- ok = type.get_infer_kind () != InferType::InferTypeKind::FLOAT;
- }
-
- void visit (const UintType &type) override
- {
- ok = type.get_uint_kind () == base->get_uint_kind ();
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const UintType *base;
-};
-
-class FloatCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- FloatCmp (const FloatType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const InferType &type) override
- {
- ok = type.get_infer_kind () != InferType::InferTypeKind::INTEGRAL;
- }
-
- void visit (const FloatType &type) override
- {
- ok = type.get_float_kind () == base->get_float_kind ();
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const FloatType *base;
-};
-
-class ADTCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- ADTCmp (const ADTType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const ADTType &type) override
- {
- if (base->get_adt_kind () != type.get_adt_kind ())
- {
- BaseCmp::visit (type);
- return;
- }
-
- if (base->get_identifier ().compare (type.get_identifier ()) != 0)
- {
- BaseCmp::visit (type);
- return;
- }
-
- if (base->number_of_variants () != type.number_of_variants ())
- {
- BaseCmp::visit (type);
- return;
- }
-
- for (size_t i = 0; i < type.number_of_variants (); ++i)
- {
- TyTy::VariantDef *a = base->get_variants ().at (i);
- TyTy::VariantDef *b = type.get_variants ().at (i);
-
- if (a->num_fields () != b->num_fields ())
- {
- BaseCmp::visit (type);
- return;
- }
-
- for (size_t j = 0; j < a->num_fields (); j++)
- {
- TyTy::StructFieldType *base_field = a->get_field_at_index (j);
- TyTy::StructFieldType *other_field = b->get_field_at_index (j);
-
- TyTy::BaseType *this_field_ty = base_field->get_field_type ();
- TyTy::BaseType *other_field_ty = other_field->get_field_type ();
-
- if (!this_field_ty->can_eq (other_field_ty, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
- }
- }
-
- ok = true;
- }
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const ADTType *base;
-};
-
-class TupleCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- TupleCmp (const TupleType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const TupleType &type) override
- {
- if (base->num_fields () != type.num_fields ())
- {
- BaseCmp::visit (type);
- return;
- }
-
- for (size_t i = 0; i < base->num_fields (); i++)
- {
- BaseType *bo = base->get_field (i);
- BaseType *fo = type.get_field (i);
-
- if (!bo->can_eq (fo, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
- }
-
- ok = true;
- }
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const TupleType *base;
-};
-
-class USizeCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- USizeCmp (const USizeType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const InferType &type) override
- {
- ok = type.get_infer_kind () != InferType::InferTypeKind::FLOAT;
- }
-
- void visit (const USizeType &type) override { ok = true; }
-
-private:
- const BaseType *get_base () const override { return base; }
- const USizeType *base;
-};
-
-class ISizeCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- ISizeCmp (const ISizeType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const InferType &type) override
- {
- ok = type.get_infer_kind () != InferType::InferTypeKind::FLOAT;
- }
-
- void visit (const ISizeType &type) override { ok = true; }
-
-private:
- const BaseType *get_base () const override { return base; }
- const ISizeType *base;
-};
-
-class CharCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- CharCmp (const CharType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const InferType &type) override
- {
- ok = type.get_infer_kind () == InferType::InferTypeKind::GENERAL;
- }
-
- void visit (const CharType &type) override { ok = true; }
-
-private:
- const BaseType *get_base () const override { return base; }
- const CharType *base;
-};
-
-class ReferenceCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- ReferenceCmp (const ReferenceType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const ReferenceType &type) override
- {
- auto base_type = base->get_base ();
- auto other_base_type = type.get_base ();
-
- bool mutability_ok = base->is_mutable () ? type.is_mutable () : true;
- if (!mutability_ok)
- {
- BaseCmp::visit (type);
- return;
- }
-
- if (!base_type->can_eq (other_base_type, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const ReferenceType *base;
-};
-
-class PointerCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- PointerCmp (const PointerType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const PointerType &type) override
- {
- auto base_type = base->get_base ();
- auto other_base_type = type.get_base ();
-
- bool mutability_ok = base->is_mutable () ? type.is_mutable () : true;
- if (!mutability_ok)
- {
- BaseCmp::visit (type);
- return;
- }
-
- if (!base_type->can_eq (other_base_type, emit_error_flag))
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const PointerType *base;
-};
-
-class ParamCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- ParamCmp (const ParamType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- // param types are a placeholder we shouldn't have cases where we unify
- // against it. eg: struct foo<T> { a: T }; When we invoke it we can do either:
- //
- // foo<i32>{ a: 123 }.
- // Then this enforces the i32 type to be referenced on the
- // field via an hirid.
- //
- // rust also allows for a = foo{a:123}; Where we can use an Inference Variable
- // to handle the typing of the struct
- bool can_eq (const BaseType *other) override
- {
- if (!base->can_resolve ())
- return BaseCmp::can_eq (other);
-
- auto lookup = base->resolve ();
- return lookup->can_eq (other, emit_error_flag);
- }
-
- // imagine the case where we have:
- // struct Foo<T>(T);
- // Then we declare a generic impl block
- // impl <X>Foo<X> { ... }
- // both of these types are compatible so we mostly care about the number of
- // generic arguments
- void visit (const ParamType &) override { ok = true; }
-
- void visit (const TupleType &) override { ok = true; }
-
- void visit (const InferType &) override { ok = true; }
-
- void visit (const FnType &) override { ok = true; }
-
- void visit (const FnPtr &) override { ok = true; }
-
- void visit (const ADTType &) override { ok = true; }
-
- void visit (const ArrayType &) override { ok = true; }
-
- void visit (const SliceType &) override { ok = true; }
-
- void visit (const BoolType &) override { ok = true; }
-
- void visit (const IntType &) override { ok = true; }
-
- void visit (const UintType &) override { ok = true; }
-
- void visit (const USizeType &) override { ok = true; }
-
- void visit (const ISizeType &) override { ok = true; }
-
- void visit (const FloatType &) override { ok = true; }
-
- void visit (const CharType &) override { ok = true; }
-
- void visit (const ReferenceType &) override { ok = true; }
-
- void visit (const PointerType &) override { ok = true; }
-
- void visit (const StrType &) override { ok = true; }
-
- void visit (const NeverType &) override { ok = true; }
-
- void visit (const DynamicObjectType &) override { ok = true; }
-
- void visit (const PlaceholderType &type) override
- {
- ok = base->get_symbol ().compare (type.get_symbol ()) == 0;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const ParamType *base;
-};
-
-class StrCmp : public BaseCmp
-{
- // FIXME we will need a enum for the StrType like ByteBuf etc..
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- StrCmp (const StrType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const StrType &type) override { ok = true; }
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const StrType *base;
-};
-
-class NeverCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- NeverCmp (const NeverType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const NeverType &type) override { ok = true; }
-
- void visit (const InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCmp::visit (type);
- return;
- }
-
- ok = true;
- }
-
-private:
- const BaseType *get_base () const override { return base; }
- const NeverType *base;
-};
-
-class PlaceholderCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- PlaceholderCmp (const PlaceholderType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- bool can_eq (const BaseType *other) override
- {
- if (!base->can_resolve ())
- return BaseCmp::can_eq (other);
-
- BaseType *lookup = base->resolve ();
- return lookup->can_eq (other, emit_error_flag);
- }
-
- void visit (const TupleType &) override { ok = true; }
-
- void visit (const ADTType &) override { ok = true; }
-
- void visit (const InferType &) override { ok = true; }
-
- void visit (const FnType &) override { ok = true; }
-
- void visit (const FnPtr &) override { ok = true; }
-
- void visit (const ArrayType &) override { ok = true; }
-
- void visit (const BoolType &) override { ok = true; }
-
- void visit (const IntType &) override { ok = true; }
-
- void visit (const UintType &) override { ok = true; }
-
- void visit (const USizeType &) override { ok = true; }
-
- void visit (const ISizeType &) override { ok = true; }
-
- void visit (const FloatType &) override { ok = true; }
-
- void visit (const ErrorType &) override { ok = true; }
-
- void visit (const CharType &) override { ok = true; }
-
- void visit (const ReferenceType &) override { ok = true; }
-
- void visit (const ParamType &) override { ok = true; }
-
- void visit (const StrType &) override { ok = true; }
-
- void visit (const NeverType &) override { ok = true; }
-
- void visit (const SliceType &) override { ok = true; }
-
-private:
- const BaseType *get_base () const override { return base; }
-
- const PlaceholderType *base;
-};
-
-class DynamicCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- DynamicCmp (const DynamicObjectType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- void visit (const DynamicObjectType &type) override
- {
- if (base->num_specified_bounds () != type.num_specified_bounds ())
- {
- BaseCmp::visit (type);
- return;
- }
-
- location_t ref_locus = mappings.lookup_location (type.get_ref ());
- ok = base->bounds_compatible (type, ref_locus, false);
- }
-
-private:
- const BaseType *get_base () const override { return base; }
-
- 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;
-};
-
-class ConstCmp : public BaseCmp
-{
- using Rust::TyTy::BaseCmp::visit;
-
-public:
- ConstCmp (const ConstType *base, bool emit_errors)
- : BaseCmp (base, emit_errors), base (base)
- {}
-
- // TODO
-
-private:
- const BaseType *get_base () const override { return base; }
-
- const ConstType *base;
-};
-
-} // namespace TyTy
-} // namespace Rust
-
-#endif // RUST_TYTY_CMP_H
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index 817910b..e82e8a3 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -54,8 +54,8 @@ SubstitutionParamMapping::as_string () const
SubstitutionParamMapping
SubstitutionParamMapping::clone () const
{
- return SubstitutionParamMapping (generic,
- static_cast<ParamType *> (param->clone ()));
+ return SubstitutionParamMapping (generic, static_cast<BaseGeneric *> (
+ param->clone ()));
}
BaseGeneric *
@@ -167,7 +167,12 @@ SubstitutionParamMapping::fill_param_ty (
}
else if (type.get_kind () == TyTy::TypeKind::CONST)
{
- param = static_cast<BaseGeneric *> (type.clone ());
+ rust_assert (param->get_kind () == TyTy::TypeKind::CONST);
+ auto *const_type = type.as_const_type ();
+ if (const_type->const_kind () == TyTy::BaseConstType::ConstKind::Decl)
+ param = static_cast<BaseGeneric *> (type.clone ());
+ else
+ param->set_ty_ref (type.get_ref ());
}
else if (param->get_kind () == TypeKind::PARAM)
{
@@ -554,6 +559,7 @@ std::vector<SubstitutionParamMapping>
SubstitutionRef::clone_substs () const
{
std::vector<SubstitutionParamMapping> clone;
+ clone.reserve (substitutions.size ());
for (auto &sub : substitutions)
clone.push_back (sub.clone ());
@@ -767,7 +773,7 @@ SubstitutionRef::get_mappings_from_generic_args (
}
else if (generic.get_kind () == HIR::GenericParam::GenericKind::CONST)
{
- if (!resolved->is<ConstType> ())
+ if (resolved->get_kind () != TyTy::TypeKind::CONST)
{
rich_location r (line_table, arg->get_locus ());
r.add_fixit_remove (arg->get_locus ());
@@ -777,9 +783,8 @@ SubstitutionRef::get_mappings_from_generic_args (
}
}
- SubstitutionArg subst_arg (&param_mapping, resolved);
+ mappings.emplace_back (&param_mapping, resolved);
offs++;
- mappings.push_back (std::move (subst_arg));
}
for (auto &arg : args.get_const_args ())
@@ -802,40 +807,73 @@ SubstitutionRef::get_mappings_from_generic_args (
// get the const generic specified type
const auto base_generic = param_mapping.get_param_ty ();
- rust_assert (base_generic->is<ConstType> ());
+ rust_assert (base_generic->get_kind () == TyTy::TypeKind::CONST);
const auto const_param
- = static_cast<const TyTy::ConstType *> (base_generic);
- auto specified_type = const_param->get_ty ();
+ = static_cast<const TyTy::ConstParamType *> (base_generic);
+ auto specified_type = const_param->get_specified_type ();
// validate this const generic is of the correct type
- auto coereced_type
- = Resolver::coercion_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (specified_type),
- TyTy::TyWithLocation (expr_type,
- expr.get_locus ()),
- arg.get_locus ());
- if (coereced_type->is<ErrorType> ())
- return SubstitutionArgumentMappings::error ();
-
- // const fold it
- auto ctx = Compile::Context::get ();
- tree folded
- = Compile::HIRCompileBase::query_compile_const_expr (ctx, coereced_type,
- expr);
+ TyTy::BaseType *coereced_type = nullptr;
+ if (expr_type->get_kind () == TyTy::TypeKind::CONST)
+ {
+ auto const_expr_type = expr_type->as_const_type ();
+ auto const_value_type = const_expr_type->get_specified_type ();
+ coereced_type
+ = Resolver::coercion_site (expr.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (specified_type),
+ TyTy::TyWithLocation (const_value_type,
+ expr.get_locus ()),
+ arg.get_locus ());
+ }
+ else
+ {
+ coereced_type
+ = Resolver::coercion_site (expr.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (specified_type),
+ TyTy::TyWithLocation (expr_type,
+ expr.get_locus ()),
+ arg.get_locus ());
+ }
- if (folded == error_mark_node)
+ if (coereced_type == nullptr || coereced_type->is<ErrorType> ())
return SubstitutionArgumentMappings::error ();
- // create const type
- auto const_value
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "",
- coereced_type, folded, {}, expr.get_locus (),
- expr.get_mappings ().get_hirid (),
- expr.get_mappings ().get_hirid (), {});
+ TyTy::BaseType *const_value_ty = nullptr;
+ if (expr_type->get_kind () == TyTy::TypeKind::CONST)
+ const_value_ty = expr_type;
+ else
+ {
+ // const fold it if available
+ auto ctx = Compile::Context::get ();
+ tree folded
+ = Compile::HIRCompileBase::query_compile_const_expr (ctx,
+ coereced_type,
+ expr);
+
+ if (folded == error_mark_node)
+ {
+ rich_location r (line_table, arg.get_locus ());
+ r.add_range (expr.get_locus ());
+ rust_error_at (r, "failed to resolve const expression");
+ return SubstitutionArgumentMappings::error ();
+ }
+
+ // Use a fresh HirId to avoid conflicts with the expr's type
+ auto &global_mappings = Analysis::Mappings::get ();
+ HirId const_value_id = global_mappings.get_next_hir_id ();
+ const_value_ty
+ = new TyTy::ConstValueType (folded, coereced_type, const_value_id,
+ const_value_id, {});
+
+ // Insert the ConstValueType into the context so it can be looked up
+ auto context = Resolver::TypeCheckContext::get ();
+ context->insert_type (
+ Analysis::NodeMapping (0, 0, const_value_ty->get_ref (), 0),
+ const_value_ty);
+ }
- SubstitutionArg subst_arg (&param_mapping, const_value);
+ mappings.emplace_back (&param_mapping, const_value_ty);
offs++;
- mappings.push_back (std::move (subst_arg));
}
// we must need to fill out defaults
@@ -865,8 +903,7 @@ SubstitutionRef::get_mappings_from_generic_args (
return SubstitutionArgumentMappings::error ();
}
- SubstitutionArg subst_arg (&param, resolved);
- mappings.push_back (std::move (subst_arg));
+ mappings.emplace_back (&param, resolved);
}
}
@@ -892,30 +929,24 @@ SubstitutionRef::infer_substitions (location_t locus)
if (have_mapping)
{
- args.push_back (SubstitutionArg (&p, it->second));
+ args.emplace_back (&p, it->second);
}
else if (generic.get_kind () == HIR::GenericParam::GenericKind::TYPE)
{
TyVar infer_var = TyVar::get_implicit_infer_var (locus);
- args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
+ args.emplace_back (&p, infer_var.get_tyty ());
argument_mappings[symbol] = infer_var.get_tyty ();
}
else if (generic.get_kind () == HIR::GenericParam::GenericKind::CONST)
{
- const auto const_param = p.get_param_ty ();
- rust_assert (const_param->is<TyTy::ConstType> ());
- const auto &const_type
- = *static_cast<const TyTy::ConstType *> (const_param);
-
- TyVar infer_var
- = TyVar::get_implicit_const_infer_var (const_type, locus);
- args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
+ TyVar infer_var = TyVar::get_implicit_const_infer_var (locus);
+ args.emplace_back (&p, infer_var.get_tyty ());
argument_mappings[symbol] = infer_var.get_tyty ();
}
}
else
{
- args.push_back (SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
+ args.emplace_back (&p, p.get_param_ty ()->resolve ());
}
}
@@ -961,10 +992,7 @@ SubstitutionRef::adjust_mappings_for_this (
bool ok = !arg.is_error ();
if (ok || (trait_mode && i == 0))
- {
- SubstitutionArg adjusted (&subst, arg.get_tyty ());
- resolved_mappings.push_back (std::move (adjusted));
- }
+ resolved_mappings.emplace_back (&subst, arg.get_tyty ());
}
if (resolved_mappings.empty ())
@@ -1008,10 +1036,7 @@ SubstitutionRef::are_mappings_bound (SubstitutionArgumentMappings &mappings)
bool ok = !arg.is_error ();
if (ok)
- {
- SubstitutionArg adjusted (&subst, arg.get_tyty ());
- resolved_mappings.push_back (std::move (adjusted));
- }
+ resolved_mappings.emplace_back (&subst, arg.get_tyty ());
}
return !resolved_mappings.empty ();
@@ -1032,10 +1057,7 @@ SubstitutionRef::solve_mappings_from_receiver_for_self (
SubstitutionArg &arg = mappings.get_mappings ().at (i);
if (param_mapping.needs_substitution ())
- {
- SubstitutionArg adjusted (&param_mapping, arg.get_tyty ());
- resolved_mappings.push_back (std::move (adjusted));
- }
+ resolved_mappings.emplace_back (&param_mapping, arg.get_tyty ());
}
return SubstitutionArgumentMappings (resolved_mappings,
@@ -1067,7 +1089,7 @@ SubstitutionRef::monomorphize ()
if (!pty->can_resolve ())
continue;
- const TyTy::BaseType *binding = pty->resolve ();
+ TyTy::BaseType *binding = pty->resolve ();
if (binding->get_kind () == TyTy::TypeKind::PARAM)
continue;
diff --git a/gcc/rust/typecheck/rust-tyty-util.cc b/gcc/rust/typecheck/rust-tyty-util.cc
index 4bc1723..72761d9 100644
--- a/gcc/rust/typecheck/rust-tyty-util.cc
+++ b/gcc/rust/typecheck/rust-tyty-util.cc
@@ -30,7 +30,8 @@ TyVar::TyVar (HirId ref) : ref (ref)
auto context = Resolver::TypeCheckContext::get ();
BaseType *lookup = nullptr;
bool ok = context->lookup_type (ref, &lookup);
- rust_assert (ok);
+ if (!ok || lookup == nullptr || lookup->get_kind () == TypeKind::ERROR)
+ return;
}
BaseType *
@@ -39,7 +40,8 @@ TyVar::get_tyty () const
auto context = Resolver::TypeCheckContext::get ();
BaseType *lookup = nullptr;
bool ok = context->lookup_type (ref, &lookup);
- rust_assert (ok);
+ if (!ok || lookup == nullptr)
+ return nullptr;
return lookup;
}
@@ -60,17 +62,14 @@ TyVar::get_implicit_infer_var (location_t locus)
}
TyVar
-TyVar::get_implicit_const_infer_var (const ConstType &const_type,
- location_t locus)
+TyVar::get_implicit_const_infer_var (location_t locus)
{
auto &mappings = Analysis::Mappings::get ();
auto context = Resolver::TypeCheckContext::get ();
+ TyVar ty_infer = get_implicit_infer_var (locus);
HirId next = mappings.get_next_hir_id ();
- auto infer
- = new ConstType (ConstType::ConstKind::Infer, const_type.get_symbol (),
- const_type.get_ty (), error_mark_node,
- const_type.get_specified_bounds (), locus, next, next, {});
+ auto infer = new ConstInferType (ty_infer.get_tyty (), next, next, {});
context->insert_implicit_type (infer->get_ref (), infer);
mappings.insert_location (infer->get_ref (), locus);
@@ -98,7 +97,10 @@ TyVar::subst_covariant_var (TyTy::BaseType *orig, TyTy::BaseType *subst)
TyVar
TyVar::clone () const
{
- TyTy::BaseType *c = get_tyty ()->clone ();
+ TyTy::BaseType *base = get_tyty ();
+ if (base == nullptr || base->get_kind () == TypeKind::ERROR)
+ return TyVar::get_implicit_infer_var (UNKNOWN_LOCATION);
+ TyTy::BaseType *c = base->clone ();
return TyVar (c->get_ref ());
}
@@ -108,6 +110,10 @@ TyVar::monomorphized_clone () const
auto &mappings = Analysis::Mappings::get ();
auto context = Resolver::TypeCheckContext::get ();
+ TyTy::BaseType *base = get_tyty ();
+ if (base == nullptr || base->get_kind () == TypeKind::ERROR)
+ return TyVar::get_implicit_infer_var (UNKNOWN_LOCATION);
+
// this needs a new hirid
TyTy::BaseType *c = get_tyty ()->monomorphized_clone ();
c->set_ref (mappings.get_next_hir_id ());
diff --git a/gcc/rust/typecheck/rust-tyty-util.h b/gcc/rust/typecheck/rust-tyty-util.h
index 1c8fd72..26101fd 100644
--- a/gcc/rust/typecheck/rust-tyty-util.h
+++ b/gcc/rust/typecheck/rust-tyty-util.h
@@ -43,8 +43,7 @@ public:
static TyVar get_implicit_infer_var (location_t locus);
- static TyVar get_implicit_const_infer_var (const TyTy::ConstType &const_type,
- location_t locus);
+ static TyVar get_implicit_const_infer_var (location_t locus);
static TyVar subst_covariant_var (TyTy::BaseType *orig,
TyTy::BaseType *subst);
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
index deb76a7..b7ca5e1 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
@@ -47,6 +47,10 @@ struct Term
/** Variance constraint of a type parameter. */
struct Constraint
{
+ Constraint (SolutionIndex target_index, Term *term)
+ : target_index (target_index), term (term)
+ {}
+
SolutionIndex target_index;
Term *term;
};
@@ -171,7 +175,10 @@ public:
void visit (OpaqueType &type) override {}
- void visit (ConstType &type) override {}
+ void visit (TyTy::ConstParamType &) override {}
+ void visit (TyTy::ConstValueType &) override {}
+ void visit (TyTy::ConstInferType &) override {}
+ void visit (TyTy::ConstErrorType &) 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 7971ccf..d640d55 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
@@ -321,6 +321,8 @@ GenericTyPerCrateCtx::query_generic_variance (const ADTType &type)
auto num_types = type.get_num_type_params ();
std::vector<Variance> result;
+ result.reserve (num_lifetimes + num_types);
+
for (size_t i = 0; i < num_lifetimes + num_types; ++i)
{
result.push_back (solutions[solution_index.value () + i]);
@@ -410,7 +412,7 @@ GenericTyVisitorCtx::add_constraint (SolutionIndex index, Term term)
}
else
{
- ctx.constraints.push_back ({index, new Term (term)});
+ ctx.constraints.emplace_back (index, new Term (term));
}
}
diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h
index 7783075..f7f3665e 100644
--- a/gcc/rust/typecheck/rust-tyty-visitor.h
+++ b/gcc/rust/typecheck/rust-tyty-visitor.h
@@ -45,7 +45,10 @@ public:
virtual void visit (ReferenceType &type) = 0;
virtual void visit (PointerType &type) = 0;
virtual void visit (ParamType &type) = 0;
- virtual void visit (ConstType &type) = 0;
+ virtual void visit (ConstParamType &type) = 0;
+ virtual void visit (ConstValueType &type) = 0;
+ virtual void visit (ConstInferType &type) = 0;
+ virtual void visit (ConstErrorType &type) = 0;
virtual void visit (StrType &type) = 0;
virtual void visit (NeverType &type) = 0;
virtual void visit (PlaceholderType &type) = 0;
@@ -76,7 +79,10 @@ public:
virtual void visit (const ReferenceType &type) = 0;
virtual void visit (const PointerType &type) = 0;
virtual void visit (const ParamType &type) = 0;
- virtual void visit (const ConstType &type) = 0;
+ virtual void visit (const ConstParamType &type) = 0;
+ virtual void visit (const ConstValueType &type) = 0;
+ virtual void visit (const ConstInferType &type) = 0;
+ virtual void visit (const ConstErrorType &type) = 0;
virtual void visit (const StrType &type) = 0;
virtual void visit (const NeverType &type) = 0;
virtual void visit (const PlaceholderType &type) = 0;
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index db96773..da5c350 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -16,29 +16,23 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "rust-system.h"
#include "rust-tyty.h"
-
-#include "optional.h"
#include "rust-tyty-subst.h"
#include "rust-tyty-visitor.h"
#include "rust-hir-map.h"
#include "rust-location.h"
-#include "rust-linemap.h"
-
+#include "rust-type-util.h"
+#include "rust-hir-type-bounds.h"
#include "rust-substitution-mapper.h"
#include "rust-hir-trait-reference.h"
#include "rust-hir-trait-resolve.h"
-#include "rust-tyty-cmp.h"
-#include "rust-type-util.h"
-#include "rust-hir-type-bounds.h"
-#include "print-tree.h"
#include "tree-pretty-print.h"
+#include "optional.h"
#include "options.h"
-#include "rust-system.h"
#include "tree.h"
#include "fold-const.h"
-#include <string>
namespace Rust {
namespace TyTy {
@@ -295,8 +289,7 @@ BaseType::get_locus () const
// FIXME this is missing locus
bool
-BaseType::satisfies_bound (const TypeBoundPredicate &predicate,
- bool emit_error) const
+BaseType::satisfies_bound (const TypeBoundPredicate &predicate, bool emit_error)
{
const Resolver::TraitReference *query = predicate.get ();
for (const auto &bound : specified_bounds)
@@ -351,41 +344,20 @@ BaseType::satisfies_bound (const TypeBoundPredicate &predicate,
return false;
std::string item_name = item->get_impl_item_name ();
- TypeBoundPredicateItem lookup
+ tl::optional<TypeBoundPredicateItem> lookup
= predicate.lookup_associated_item (item_name);
- if (lookup.is_error ())
+ if (!lookup.has_value ())
return false;
- const auto *item_ref = lookup.get_raw_item ();
+ const auto *item_ref = lookup->get_raw_item ();
TyTy::BaseType *bound_ty = item_ref->get_tyty ();
- // compare the types
- if (!bound_ty->can_eq (impl_item_ty, false))
- {
- if (!impl_item_ty->can_eq (bound_ty, false))
- {
- if (emit_error)
- {
- rich_location r (line_table,
- mappings.lookup_location (get_ref ()));
- r.add_range (predicate.get_locus ());
- r.add_range (mappings.lookup_location (i.get_hirid ()));
-
- std::string rich_msg
- = "expected " + bound_ty->destructure ()->get_name ()
- + ", found "
- + impl_item_ty->destructure ()->get_name ();
- r.add_fixit_replace (rich_msg.c_str ());
-
- rust_error_at (
- r, ErrorCode::E0271,
- "type mismatch, expected %qs but got %qs",
- bound_ty->destructure ()->get_name ().c_str (),
- impl_item_ty->destructure ()->get_name ().c_str ());
- }
- return false;
- }
- }
+ if (!Resolver::types_compatable (
+ TyTy::TyWithLocation (bound_ty, predicate.get_locus ()),
+ TyTy::TyWithLocation (impl_item_ty, item->get_locus ()),
+ mappings.lookup_location (get_ref ()), false /*emit-error*/,
+ false /*check-bounds*/))
+ return false;
}
return true;
@@ -395,8 +367,7 @@ BaseType::satisfies_bound (const TypeBoundPredicate &predicate,
}
bool
-BaseType::bounds_compatible (const BaseType &other, location_t locus,
- bool emit_error) const
+BaseType::bounds_compatible (BaseType &other, location_t locus, bool emit_error)
{
std::vector<std::reference_wrapper<const TypeBoundPredicate>>
unsatisfied_bounds;
@@ -501,6 +472,23 @@ BaseType::destructure ()
x = pr;
}
+ else if (x->get_kind () == TypeKind::CONST)
+ {
+ auto p = x->as_const_type ();
+ if (p->const_kind () == BaseConstType::ConstKind::Decl)
+ {
+ auto decl = static_cast<ConstParamType *> (p);
+ auto pr = decl->resolve ();
+ if (pr == x)
+ return pr;
+
+ x = pr;
+ }
+ else
+ {
+ return x;
+ }
+ }
else if (auto p = x->try_as<PlaceholderType> ())
{
if (!p->can_resolve ())
@@ -546,6 +534,23 @@ BaseType::destructure () const
x = pr;
}
+ else if (x->get_kind () == TypeKind::CONST)
+ {
+ auto p = x->as_const_type ();
+ if (p->const_kind () == BaseConstType::ConstKind::Decl)
+ {
+ auto decl = static_cast<const ConstParamType *> (p);
+ auto pr = decl->resolve ();
+ if (pr == x)
+ return pr;
+
+ x = pr;
+ }
+ else
+ {
+ return x;
+ }
+ }
else if (auto p = x->try_as<const PlaceholderType> ())
{
if (!p->can_resolve ())
@@ -583,7 +588,7 @@ BaseType::monomorphized_clone () const
{
TyVar elm = arr->get_var_element_type ().monomorphized_clone ();
return new ArrayType (arr->get_ref (), arr->get_ty_ref (), ident.locus,
- arr->get_capacity (), elm,
+ arr->get_capacity_var (), elm,
arr->get_combined_refs ());
}
else if (auto slice = x->try_as<const SliceType> ())
@@ -637,8 +642,8 @@ BaseType::monomorphized_clone () const
TyVar retty = fn->get_var_return_type ().monomorphized_clone ();
return new FnPtr (fn->get_ref (), fn->get_ty_ref (), ident.locus,
- std::move (cloned_params), retty,
- fn->get_combined_refs ());
+ std::move (cloned_params), retty, fn->get_abi (),
+ fn->get_unsafety (), fn->get_combined_refs ());
}
else if (auto adt = x->try_as<const ADTType> ())
{
@@ -780,7 +785,8 @@ BaseType::is_concrete () const
{
const TyTy::BaseType *x = destructure ();
- if (x->is<ParamType> () || x->is<ProjectionType> ())
+ if (x->is<ParamType> () || x->is<ProjectionType> ()
+ || x->is<ConstParamType> ())
{
return false;
}
@@ -862,10 +868,6 @@ BaseType::is_concrete () const
return false;
return closure->get_result_type ().is_concrete ();
}
- else if (auto const_type = x->try_as<const ConstType> ())
- {
- return const_type->get_value () != error_mark_node;
- }
else if (x->is<InferType> () || x->is<BoolType> () || x->is<CharType> ()
|| x->is<IntType> () || x->is<UintType> () || x->is<FloatType> ()
|| x->is<USizeType> () || x->is<ISizeType> () || x->is<NeverType> ()
@@ -1113,13 +1115,6 @@ InferType::as_string () const
return "<infer::error>";
}
-bool
-InferType::can_eq (const BaseType *other, bool emit_errors) const
-{
- InferCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
InferType::clone () const
{
@@ -1410,12 +1405,6 @@ ErrorType::as_string () const
return "<tyty::error>";
}
-bool
-ErrorType::can_eq (const BaseType *other, bool emit_errors) const
-{
- return get_kind () == other->get_kind ();
-}
-
BaseType *
ErrorType::clone () const
{
@@ -1800,13 +1789,6 @@ ADTType::as_string () const
}
bool
-ADTType::can_eq (const BaseType *other, bool emit_errors) const
-{
- ADTCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
-bool
ADTType::is_equal (const BaseType &other) const
{
if (get_kind () != other.get_kind ())
@@ -2037,13 +2019,6 @@ TupleType::get_field (size_t index) const
}
bool
-TupleType::can_eq (const BaseType *other, bool emit_errors) const
-{
- TupleCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
-bool
TupleType::is_equal (const BaseType &other) const
{
if (get_kind () != other.get_kind ())
@@ -2126,13 +2101,6 @@ FnType::as_string () const
}
bool
-FnType::can_eq (const BaseType *other, bool emit_errors) const
-{
- FnCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
-bool
FnType::is_equal (const BaseType &other) const
{
if (get_kind () != other.get_kind ())
@@ -2331,14 +2299,13 @@ FnPtr::as_string () const
params_str += p.get_tyty ()->as_string () + " ,";
}
- return "fnptr (" + params_str + ") -> " + get_return_type ()->as_string ();
-}
+ std::string unsafety = "";
+ if (get_unsafety () == Unsafety::Unsafe)
+ unsafety = "unsafe ";
-bool
-FnPtr::can_eq (const BaseType *other, bool emit_errors) const
-{
- FnptrCmp r (this, emit_errors);
- return r.can_eq (other);
+ std::string abi = get_string_from_abi (get_abi ());
+ return unsafety + "abi:" + abi + " " + "fnptr (" + params_str + ") -> "
+ + get_return_type ()->as_string ();
}
bool
@@ -2368,12 +2335,48 @@ BaseType *
FnPtr::clone () const
{
std::vector<TyVar> cloned_params;
+ cloned_params.reserve (params.size ());
+
for (auto &p : params)
- cloned_params.push_back (TyVar (p.get_ref ()));
+ cloned_params.emplace_back (p.get_ref ());
return new FnPtr (get_ref (), get_ty_ref (), ident.locus,
- std::move (cloned_params), result_type,
- get_combined_refs ());
+ std::move (cloned_params), result_type, get_abi (),
+ get_unsafety (), get_combined_refs ());
+}
+
+FnPtr *
+FnPtr::handle_substitions (SubstitutionArgumentMappings &mappings)
+{
+ auto &mappings_table = Analysis::Mappings::get ();
+
+ auto fn = clone ()->as<FnPtr> ();
+ fn->set_ref (mappings_table.get_next_hir_id ());
+ fn->set_ty_ref (mappings_table.get_next_hir_id ());
+
+ if (!fn->result_type.get_tyty ()->is_concrete ())
+ {
+ BaseType *concrete
+ = Resolver::SubstMapperInternal::Resolve (fn->result_type.get_tyty (),
+ mappings);
+ fn->result_type
+ = TyVar::subst_covariant_var (fn->result_type.get_tyty (), concrete);
+ }
+
+ for (size_t i = 0; i < fn->params.size (); i++)
+ {
+ TyVar &field = fn->params.at (i);
+ if (!field.get_tyty ()->is_concrete ())
+ {
+ BaseType *concrete
+ = Resolver::SubstMapperInternal::Resolve (field.get_tyty (),
+ mappings);
+ fn->params[i]
+ = TyVar::subst_covariant_var (field.get_tyty (), concrete);
+ }
+ }
+
+ return fn;
}
void
@@ -2396,13 +2399,6 @@ ClosureType::as_string () const
}
bool
-ClosureType::can_eq (const BaseType *other, bool emit_errors) const
-{
- ClosureCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
-bool
ClosureType::is_equal (const BaseType &other) const
{
if (other.get_kind () != TypeKind::CLOSURE)
@@ -2499,15 +2495,10 @@ ArrayType::accept_vis (TyConstVisitor &vis) const
std::string
ArrayType::as_string () const
{
- return "[" + get_element_type ()->as_string () + "; " + capacity->as_string ()
- + "]";
-}
+ auto cap = get_capacity ();
+ std::string capacity_str = cap->as_string ();
-bool
-ArrayType::can_eq (const BaseType *other, bool emit_errors) const
-{
- ArrayCmp r (this, emit_errors);
- return r.can_eq (other);
+ return "[" + get_element_type ()->as_string () + "; " + capacity_str + "]";
}
bool
@@ -2537,6 +2528,12 @@ ArrayType::get_var_element_type () const
}
BaseType *
+ArrayType::get_capacity () const
+{
+ return capacity.get_tyty ();
+}
+
+BaseType *
ArrayType::clone () const
{
return new ArrayType (get_ref (), get_ty_ref (), ident.locus, capacity,
@@ -2561,7 +2558,7 @@ ArrayType::handle_substitions (SubstitutionArgumentMappings &mappings)
BaseType *concrete_cap
= Resolver::SubstMapperInternal::Resolve (cap, mappings);
rust_assert (concrete_cap->get_kind () == TyTy::TypeKind::CONST);
- ref->capacity = static_cast<TyTy::ConstType *> (concrete_cap);
+ ref->capacity = TyVar::subst_covariant_var (cap, concrete_cap);
return ref;
}
@@ -2585,13 +2582,6 @@ SliceType::as_string () const
}
bool
-SliceType::can_eq (const BaseType *other, bool emit_errors) const
-{
- SliceCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
-bool
SliceType::is_equal (const BaseType &other) const
{
if (get_kind () != other.get_kind ())
@@ -2678,13 +2668,6 @@ BoolType::as_string () const
return "bool";
}
-bool
-BoolType::can_eq (const BaseType *other, bool emit_errors) const
-{
- BoolCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
BoolType::clone () const
{
@@ -2751,13 +2734,6 @@ IntType::as_string () const
return "__unknown_int_type";
}
-bool
-IntType::can_eq (const BaseType *other, bool emit_errors) const
-{
- IntCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
IntType::clone () const
{
@@ -2836,13 +2812,6 @@ UintType::as_string () const
return "__unknown_uint_type";
}
-bool
-UintType::can_eq (const BaseType *other, bool emit_errors) const
-{
- UintCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
UintType::clone () const
{
@@ -2915,13 +2884,6 @@ FloatType::as_string () const
return "__unknown_float_type";
}
-bool
-FloatType::can_eq (const BaseType *other, bool emit_errors) const
-{
- FloatCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
FloatType::clone () const
{
@@ -2977,13 +2939,6 @@ USizeType::as_string () const
return "usize";
}
-bool
-USizeType::can_eq (const BaseType *other, bool emit_errors) const
-{
- USizeCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
USizeType::clone () const
{
@@ -3028,13 +2983,6 @@ ISizeType::as_string () const
return "isize";
}
-bool
-ISizeType::can_eq (const BaseType *other, bool emit_errors) const
-{
- ISizeCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
ISizeType::clone () const
{
@@ -3079,13 +3027,6 @@ CharType::as_string () const
return "char";
}
-bool
-CharType::can_eq (const BaseType *other, bool emit_errors) const
-{
- CharCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
CharType::clone () const
{
@@ -3200,13 +3141,6 @@ ReferenceType::get_name () const
}
bool
-ReferenceType::can_eq (const BaseType *other, bool emit_errors) const
-{
- ReferenceCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
-bool
ReferenceType::is_equal (const BaseType &other) const
{
if (get_kind () != other.get_kind ())
@@ -3362,13 +3296,6 @@ PointerType::get_name () const
}
bool
-PointerType::can_eq (const BaseType *other, bool emit_errors) const
-{
- PointerCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
-bool
PointerType::is_equal (const BaseType &other) const
{
if (get_kind () != other.get_kind ())
@@ -3478,13 +3405,6 @@ ParamType::get_name () const
return destructure ()->get_name ();
}
-bool
-ParamType::can_eq (const BaseType *other, bool emit_errors) const
-{
- ParamCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
ParamType::clone () const
{
@@ -3543,7 +3463,9 @@ ParamType::is_equal (const BaseType &other) const
return false;
if (can_resolve ())
- return resolve ()->can_eq (other2.resolve (), false);
+ return Resolver::types_compatable (TyTy::TyWithLocation (resolve ()),
+ TyTy::TyWithLocation (other2.resolve ()),
+ UNKNOWN_LOCATION, false, false);
return get_symbol ().compare (other2.get_symbol ()) == 0;
}
@@ -3564,7 +3486,7 @@ ParamType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
{
const ParamType &pp = *static_cast<const ParamType *> (resolved);
if (pp.can_resolve ())
- resolved = pp.resolve ();
+ pp.resolve ();
}
// this is the new subst that this needs to pass
@@ -3586,155 +3508,382 @@ ParamType::is_implicit_self_trait () const
return is_trait_self;
}
-// ConstType
+static std::string
+generate_tree_str (tree value)
+{
+ char *buf = nullptr;
+ size_t size = 0;
-ConstType::ConstType (ConstKind kind, std::string symbol, TyTy::BaseType *ty,
- tree value,
- std::vector<TypeBoundPredicate> specified_bounds,
- location_t locus, HirId ref, HirId ty_ref,
- std::set<HirId> refs)
- : BaseGeneric (ref, ty_ref, KIND,
- {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID,
- symbol.empty () ? "<n/a>"
- : symbol),
+ FILE *stream = open_memstream (&buf, &size);
+ if (!stream)
+ return "<error>";
+
+ print_generic_stmt (stream, value, TDF_NONE);
+ fclose (stream);
+
+ std::string result = (buf ? std::string (buf, size) : "<error>");
+ free (buf);
+
+ if (!result.empty () && result.back () == '\n')
+ result.pop_back ();
+
+ return result;
+}
+
+// ---
+
+ConstParamType::ConstParamType (std::string symbol, location_t locus,
+ BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs)
+ : BaseConstType (type),
+ BaseGeneric (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
locus},
- specified_bounds, refs),
- const_kind (kind), ty (ty), value (value), symbol (symbol)
+ {}, refs),
+ symbol (symbol)
{}
+BaseConstType::ConstKind
+ConstParamType::const_kind () const
+{
+ return BaseConstType::ConstKind::Decl;
+}
+
+std::string
+ConstParamType::get_symbol () const
+{
+ return symbol;
+}
+
+bool
+ConstParamType::can_resolve () const
+{
+ return get_ref () != get_ty_ref ();
+}
+
+BaseType *
+ConstParamType::resolve () const
+{
+ TyVar var (get_ty_ref ());
+ BaseType *r = var.get_tyty ();
+
+ while (r->get_kind () == TypeKind::CONST)
+ {
+ TyVar v (r->get_ty_ref ());
+ BaseType *n = v.get_tyty ();
+
+ // fix infinite loop
+ if (r == n)
+ break;
+
+ r = n;
+ }
+
+ if (r->get_kind () == TypeKind::CONST && (r->get_ref () == r->get_ty_ref ()))
+ {
+ auto *const_type = r->as_const_type ();
+ if (const_type->const_kind () != BaseConstType::ConstKind::Value)
+ return TyVar (r->get_ty_ref ()).get_tyty ();
+ }
+
+ return r;
+}
+
void
-ConstType::accept_vis (TyVisitor &vis)
+ConstParamType::accept_vis (TyVisitor &vis)
{
vis.visit (*this);
}
void
-ConstType::accept_vis (TyConstVisitor &vis) const
+ConstParamType::accept_vis (TyConstVisitor &vis) const
{
vis.visit (*this);
}
-void
-ConstType::set_value (tree v)
+std::string
+ConstParamType::as_string () const
+{
+ if (!can_resolve ())
+ {
+ return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
+ }
+
+ BaseType *lookup = resolve ();
+ // Avoid infinite recursion if resolve() returns this same type
+ if (lookup == this->as_base_type ())
+ {
+ return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
+ }
+
+ return get_symbol () + "=" + lookup->as_string ();
+}
+
+BaseType *
+ConstParamType::clone () const
{
- value = v;
- const_kind = ConstType::ConstKind::Value;
+ return new ConstParamType (get_symbol (), ident.locus, specified_type,
+ get_ref (), get_ty_ref (), get_combined_refs ());
}
std::string
-ConstType::as_string () const
+ConstParamType::get_name () const
{
- return get_name ();
+ if (!can_resolve ())
+ return get_symbol ();
+
+ BaseType *lookup = resolve ();
+ // Avoid infinite recursion if resolve() returns this same type
+ if (lookup == this->as_base_type ())
+ return get_symbol ();
+
+ return lookup->get_name ();
}
bool
-ConstType::can_eq (const BaseType *other, bool emit_errors) const
+ConstParamType::is_equal (const BaseType &other) const
{
- ConstCmp r (this, emit_errors);
- return r.can_eq (other);
+ if (get_kind () != other.get_kind ())
+ {
+ if (!can_resolve ())
+ return false;
+
+ return resolve ()->is_equal (other);
+ }
+
+ auto other_const = other.as_const_type ();
+ if (other_const->const_kind () != BaseConstType::ConstKind::Decl)
+ return false;
+
+ auto &other2 = static_cast<const ConstParamType &> (*other_const);
+ if (can_resolve () != other2.can_resolve ())
+ return false;
+
+ if (can_resolve ())
+ return Resolver::types_compatable (TyTy::TyWithLocation (resolve ()),
+ TyTy::TyWithLocation (other2.resolve ()),
+ ident.locus, false);
+
+ return get_symbol ().compare (other2.get_symbol ()) == 0;
}
BaseType *
-ConstType::clone () const
+ConstParamType::handle_substitions (
+ SubstitutionArgumentMappings &subst_mappings)
{
- return new ConstType (const_kind, symbol, ty, value, get_specified_bounds (),
- ident.locus, ref, ty_ref, get_combined_refs ());
+ SubstitutionArg arg = SubstitutionArg::error ();
+ bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
+ if (!ok || arg.is_error ())
+ return this;
+
+ ConstParamType *p = static_cast<ConstParamType *> (clone ());
+ const BaseType *resolved = arg.get_tyty ();
+
+ // this is the new subst that this needs to pass
+ p->set_ref (mappings.get_next_hir_id ());
+ p->set_ty_ref (resolved->get_ref ());
+
+ return p;
}
-std::string
-ConstType::get_symbol () const
+// --- ConstValueType
+
+ConstValueType::ConstValueType (tree value, BaseType *type, HirId ref,
+ HirId ty_ref, std::set<HirId> refs)
+ : BaseType (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
+ refs),
+ BaseConstType (type), folded_val (value)
+{}
+
+BaseConstType::ConstKind
+ConstValueType::const_kind () const
{
- return symbol;
+ return BaseConstType::ConstKind::Value;
}
-bool
-ConstType::can_resolve () const
+void
+ConstValueType::accept_vis (TyVisitor &vis)
{
- return false;
+ vis.visit (*this);
+}
+
+void
+ConstValueType::accept_vis (TyConstVisitor &vis) const
+{
+ vis.visit (*this);
+}
+
+std::string
+ConstValueType::as_string () const
+{
+ return generate_tree_str (folded_val);
}
BaseType *
-ConstType::resolve () const
+ConstValueType::clone () const
{
- rust_unreachable ();
- return nullptr;
+ return new ConstValueType (folded_val, specified_type, get_ref (),
+ get_ty_ref (), get_combined_refs ());
}
-static std::string
-generate_tree_str (tree value)
+std::string
+ConstValueType::get_name () const
{
- char *buf = nullptr;
- size_t size = 0;
+ return as_string ();
+}
- FILE *stream = open_memstream (&buf, &size);
- if (!stream)
- return "<error>";
+bool
+ConstValueType::is_equal (const BaseType &other) const
+{
+ if (get_kind () != other.get_kind ())
+ return false;
- print_generic_stmt (stream, value, TDF_NONE);
- fclose (stream);
+ auto other_const = other.as_const_type ();
+ if (other_const->const_kind () != BaseConstType::ConstKind::Value)
+ return false;
- std::string result = (buf ? std::string (buf, size) : "<error>");
- free (buf);
+ auto &other2 = static_cast<const ConstValueType &> (*other_const);
+ return folded_val == other2.folded_val;
+}
- if (!result.empty () && result.back () == '\n')
- result.pop_back ();
+tree
+ConstValueType::get_value () const
+{
+ return folded_val;
+}
- return result;
+// --- ConstInferType
+
+ConstInferType::ConstInferType (BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs)
+ : BaseType (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
+ refs),
+ BaseConstType (type)
+{}
+
+BaseConstType::ConstKind
+ConstInferType::const_kind () const
+{
+ return BaseConstType::ConstKind::Infer;
+}
+
+void
+ConstInferType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+ConstInferType::accept_vis (TyConstVisitor &vis) const
+{
+ vis.visit (*this);
}
std::string
-ConstType::get_name () const
+ConstInferType::as_string () const
{
- if (value == error_mark_node)
- {
- switch (get_const_kind ())
- {
- case Rust::TyTy::ConstType::Decl:
- return "ConstType:<" + get_ty ()->get_name () + " " + get_symbol ()
- + ">";
+ return specified_type->get_name () + "-?";
+}
- case Rust::TyTy::ConstType::Infer:
- return "ConstType:<" + get_ty ()->get_name () + " ?" + ">";
+BaseType *
+ConstInferType::clone () const
+{
+ auto &mappings = Analysis::Mappings::get ();
+ auto context = Resolver::TypeCheckContext::get ();
- default:
- return "ConstType:<" + get_ty ()->get_name () + " - <error>" + ">";
- }
- }
+ ConstInferType *clone
+ = new ConstInferType (specified_type, mappings.get_next_hir_id (),
+ get_ty_ref (), get_combined_refs ());
+
+ context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
+ UNKNOWN_NODEID,
+ clone->get_ref (),
+ UNKNOWN_LOCAL_DEFID),
+ clone);
+ mappings.insert_location (clone->get_ref (),
+ mappings.lookup_location (get_ref ()));
+
+ clone->append_reference (get_ref ());
- return generate_tree_str (value);
+ return clone;
+}
+
+std::string
+ConstInferType::get_name () const
+{
+ return as_string ();
}
bool
-ConstType::is_equal (const BaseType &other) const
+ConstInferType::is_equal (const BaseType &other) const
{
if (get_kind () != other.get_kind ())
- {
- return false;
- }
+ return false;
- const ConstType &rhs = static_cast<const ConstType &> (other);
- if (!get_ty ()->is_equal (*rhs.get_ty ()))
+ auto other_const = other.as_const_type ();
+ if (other_const->const_kind () != BaseConstType::ConstKind::Infer)
return false;
- tree lv = get_value ();
- tree rv = rhs.get_value ();
+ return get_ref () == other.get_ref ();
+}
+
+// --- ConstErrorType
+
+ConstErrorType::ConstErrorType (BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs)
+ : BaseType (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
+ refs),
+ BaseConstType (type)
+{}
- return operand_equal_p (lv, rv, 0);
+BaseConstType::ConstKind
+ConstErrorType::const_kind () const
+{
+ return BaseConstType::ConstKind::Error;
}
-ConstType *
-ConstType::handle_substitions (SubstitutionArgumentMappings &mappings)
+void
+ConstErrorType::accept_vis (TyVisitor &vis)
{
- SubstitutionArg arg = SubstitutionArg::error ();
- bool found = mappings.get_argument_for_symbol (this, &arg);
- if (found && !arg.is_error ())
- {
- TyTy::BaseType *subst = arg.get_tyty ();
- rust_assert (subst->is<TyTy::ConstType> ());
- return static_cast<TyTy::ConstType *> (subst);
- }
+ vis.visit (*this);
+}
+
+void
+ConstErrorType::accept_vis (TyConstVisitor &vis) const
+{
+ vis.visit (*this);
+}
+
+std::string
+ConstErrorType::as_string () const
+{
+ return "<const_error>";
+}
+
+BaseType *
+ConstErrorType::clone () const
+{
+ return new ConstErrorType (specified_type, get_ref (), get_ty_ref (),
+ get_combined_refs ());
+}
+
+std::string
+ConstErrorType::get_name () const
+{
+ return as_string ();
+}
+
+bool
+ConstErrorType::is_equal (const BaseType &other) const
+{
+ if (get_kind () != other.get_kind ())
+ return false;
- return this;
+ auto other_const = other.as_const_type ();
+ return other_const->const_kind () == BaseConstType::ConstKind::Error;
}
// OpaqueType
@@ -3787,13 +3936,6 @@ 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
{
@@ -3815,7 +3957,24 @@ OpaqueType::is_equal (const BaseType &other) const
if (can_resolve () != other2.can_resolve ())
return false;
- return bounds_compatible (other, UNDEF_LOCATION, false);
+ if (num_specified_bounds () != other.num_specified_bounds ())
+ return false;
+
+ for (const auto &pred : specified_bounds)
+ {
+ bool found = false;
+ for (const auto &opred : other.get_specified_bounds ())
+ {
+ found = pred.is_equal (opred);
+ if (found)
+ break;
+ }
+
+ if (!found)
+ return false;
+ }
+
+ return true;
}
// StrType
@@ -3863,13 +4022,6 @@ StrType::as_string () const
}
bool
-StrType::can_eq (const BaseType *other, bool emit_errors) const
-{
- StrCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
-bool
StrType::is_equal (const BaseType &other) const
{
return get_kind () == other.get_kind ();
@@ -3913,13 +4065,6 @@ NeverType::as_string () const
return "!";
}
-bool
-NeverType::can_eq (const BaseType *other, bool emit_errors) const
-{
- NeverCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
NeverType::clone () const
{
@@ -3975,13 +4120,6 @@ PlaceholderType::as_string () const
+ ">";
}
-bool
-PlaceholderType::can_eq (const BaseType *other, bool emit_errors) const
-{
- PlaceholderCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
PlaceholderType::clone () const
{
@@ -4118,12 +4256,6 @@ ProjectionType::as_string () const
return "<Projection=" + subst_as_string () + "::" + base->as_string () + ">";
}
-bool
-ProjectionType::can_eq (const BaseType *other, bool emit_errors) const
-{
- return base->can_eq (other, emit_errors);
-}
-
BaseType *
ProjectionType::clone () const
{
@@ -4237,13 +4369,6 @@ DynamicObjectType::as_string () const
return "dyn [" + raw_bounds_as_string () + "]";
}
-bool
-DynamicObjectType::can_eq (const BaseType *other, bool emit_errors) const
-{
- DynamicCmp r (this, emit_errors);
- return r.can_eq (other);
-}
-
BaseType *
DynamicObjectType::clone () const
{
@@ -4266,7 +4391,21 @@ DynamicObjectType::is_equal (const BaseType &other) const
if (num_specified_bounds () != other.num_specified_bounds ())
return false;
- return bounds_compatible (other, UNDEF_LOCATION, false);
+ for (const auto &pred : specified_bounds)
+ {
+ bool found = false;
+ for (const auto &opred : other.get_specified_bounds ())
+ {
+ found = pred.is_equal (opred);
+ if (found)
+ break;
+ }
+
+ if (!found)
+ return false;
+ }
+
+ return true;
}
const std::vector<
@@ -4287,7 +4426,7 @@ DynamicObjectType::get_object_items () const
if (item->get_trait_item_type ()
== Resolver::TraitItemReference::TraitItemType::FN
&& item->is_object_safe ())
- items.push_back ({item, &bound});
+ items.emplace_back (item, &bound);
}
}
return items;
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 49415ea..3236bf3 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -91,6 +91,7 @@ public:
class TyVisitor;
class TyConstVisitor;
+class BaseConstType;
class BaseType : public TypeBoundsMappings
{
public:
@@ -110,29 +111,15 @@ public:
virtual std::string as_string () const = 0;
virtual std::string get_name () const = 0;
- // similar to unify but does not actually perform type unification but
- // determines whether they are compatible. Consider the following
- //
- // fn foo<T>() -> T { ... }
- // fn foo() -> i32 { ... }
- //
- // when the function has been substituted they can be considered equal.
- //
- // It can also be used to optional emit errors for trait item compatibility
- // checks
- virtual bool can_eq (const BaseType *other, bool emit_errors) const = 0;
-
// Check value equality between two ty. Type inference rules are ignored. Two
// ty are considered equal if they're of the same kind, and
// 1. (For ADTs, arrays, tuples, refs) have the same underlying ty
// 2. (For functions) have the same signature
virtual bool is_equal (const BaseType &other) const;
- bool satisfies_bound (const TypeBoundPredicate &predicate,
- bool emit_error) const;
+ bool satisfies_bound (const TypeBoundPredicate &predicate, bool emit_error);
- bool bounds_compatible (const BaseType &other, location_t locus,
- bool emit_error) const;
+ bool bounds_compatible (BaseType &other, location_t locus, bool emit_error);
void inherit_bounds (const BaseType &other);
@@ -240,6 +227,11 @@ public:
return static_cast<T *> (this);
}
+ // Helper to get BaseConstType interface for CONST types
+ // Overridden by const types that also inherit from BaseConstType
+ virtual BaseConstType *as_const_type () { return nullptr; }
+ virtual const BaseConstType *as_const_type () const { return nullptr; }
+
protected:
BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
std::set<HirId> refs = std::set<HirId> ());
@@ -327,8 +319,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
InferTypeKind get_infer_kind () const;
@@ -359,8 +349,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
std::string get_name () const override final;
@@ -402,8 +390,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
std::string get_symbol () const override final;
@@ -426,7 +412,7 @@ private:
std::string symbol;
};
-class ConstType : public BaseGeneric
+class BaseConstType
{
public:
static constexpr auto KIND = TypeKind::CONST;
@@ -439,25 +425,30 @@ public:
Error
};
- ConstType (ConstKind kind, std::string symbol, TyTy::BaseType *ty, tree value,
- std::vector<TypeBoundPredicate> specified_bounds, location_t locus,
- HirId ref, HirId ty_ref,
- std::set<HirId> refs = std::set<HirId> ());
+ virtual ConstKind const_kind () const = 0;
- void accept_vis (TyVisitor &vis) override;
- void accept_vis (TyConstVisitor &vis) const override;
+ BaseType *get_specified_type () const { return specified_type; }
- ConstKind get_const_kind () const { return const_kind; }
- TyTy::BaseType *get_ty () const { return ty; }
- tree get_value () const { return value; }
+ // Helper to get BaseType interface (all const types also inherit BaseType)
+ // This must be implemented by concrete classes since BaseConstType doesn't
+ // inherit from BaseType, but all concrete const types do.
+ virtual BaseType *as_base_type () = 0;
+ virtual const BaseType *as_base_type () const = 0;
- void set_value (tree value);
+protected:
+ BaseConstType (BaseType *type) : specified_type (type) {}
- std::string as_string () const override;
+ BaseType *specified_type;
+};
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
+class ConstParamType : public BaseConstType, public BaseGeneric
+{
+public:
+ ConstParamType (std::string symbol, location_t locus, BaseType *type,
+ HirId ref, HirId ty_ref,
+ std::set<HirId> refs = std::set<HirId> ());
- BaseType *clone () const final override;
+ ConstKind const_kind () const override final;
std::string get_symbol () const override final;
@@ -465,19 +456,126 @@ public:
BaseType *resolve () const override final;
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ BaseType *clone () const final override;
std::string get_name () const override final;
bool is_equal (const BaseType &other) const override;
- ConstType *handle_substitions (SubstitutionArgumentMappings &mappings);
+ BaseType *handle_substitions (SubstitutionArgumentMappings &mappings);
+
+ BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
+ const BaseType *as_base_type () const override
+ {
+ return static_cast<const BaseType *> (this);
+ }
+
+ BaseConstType *as_const_type () override { return this; }
+ const BaseConstType *as_const_type () const override { return this; }
private:
- ConstKind const_kind;
- TyTy::BaseType *ty;
- tree value;
std::string symbol;
};
+class ConstValueType : public BaseType, public BaseConstType
+{
+public:
+ static constexpr auto KIND = TypeKind::CONST;
+
+ ConstValueType (tree value, BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ ConstKind const_kind () const override final;
+
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ BaseType *clone () const final override;
+ std::string get_name () const override final;
+
+ bool is_equal (const BaseType &other) const override;
+
+ tree get_value () const;
+
+ BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
+ const BaseType *as_base_type () const override
+ {
+ return static_cast<const BaseType *> (this);
+ }
+
+ BaseConstType *as_const_type () override { return this; }
+ const BaseConstType *as_const_type () const override { return this; }
+
+private:
+ tree folded_val;
+};
+
+class ConstInferType : public BaseType, public BaseConstType
+{
+public:
+ static constexpr auto KIND = TypeKind::CONST;
+
+ ConstInferType (BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ ConstKind const_kind () const override final;
+
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ BaseType *clone () const final override;
+ std::string get_name () const override final;
+
+ bool is_equal (const BaseType &other) const override;
+
+ BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
+ const BaseType *as_base_type () const override
+ {
+ return static_cast<const BaseType *> (this);
+ }
+
+ BaseConstType *as_const_type () override { return this; }
+ const BaseConstType *as_const_type () const override { return this; }
+};
+
+class ConstErrorType : public BaseType, public BaseConstType
+{
+public:
+ static constexpr auto KIND = TypeKind::CONST;
+
+ ConstErrorType (BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ ConstKind const_kind () const override final;
+
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ BaseType *clone () const final override;
+ std::string get_name () const override final;
+
+ bool is_equal (const BaseType &other) const override;
+
+ BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
+ const BaseType *as_base_type () const override
+ {
+ return static_cast<const BaseType *> (this);
+ }
+
+ BaseConstType *as_const_type () override { return this; }
+ const BaseConstType *as_const_type () const override { return this; }
+};
+
class OpaqueType : public BaseType
{
public:
@@ -496,8 +594,6 @@ public:
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;
@@ -557,8 +653,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
size_t num_fields () const;
@@ -589,7 +683,7 @@ public:
TypeBoundPredicate (const TypeBoundPredicate &other);
- virtual ~TypeBoundPredicate (){};
+ virtual ~TypeBoundPredicate () {}
TypeBoundPredicate &operator= (const TypeBoundPredicate &other);
@@ -617,10 +711,10 @@ public:
bool contains_item (const std::string &search) const;
- TypeBoundPredicateItem
+ tl::optional<TypeBoundPredicateItem>
lookup_associated_item (const std::string &search) const;
- TypeBoundPredicateItem
+ tl::optional<TypeBoundPredicateItem>
lookup_associated_item (const Resolver::TraitItemReference *ref) const;
// WARNING THIS WILL ALWAYS RETURN NULLPTR
@@ -851,8 +945,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
std::string get_identifier () const { return identifier; }
@@ -1003,8 +1095,6 @@ public:
std::string get_identifier () const { return identifier; }
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
size_t num_params () const { return params.size (); }
@@ -1076,19 +1166,22 @@ public:
static constexpr auto KIND = TypeKind::FNPTR;
FnPtr (HirId ref, location_t locus, std::vector<TyVar> params,
- TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
+ TyVar result_type, ABI abi, Unsafety unsafety,
+ std::set<HirId> refs = std::set<HirId> ())
: CallableTypeInterface (ref, ref, TypeKind::FNPTR,
{Resolver::CanonicalPath::create_empty (), locus},
refs),
- params (std::move (params)), result_type (result_type)
+ params (std::move (params)), result_type (result_type), abi (abi),
+ unsafety (unsafety)
{}
FnPtr (HirId ref, HirId ty_ref, location_t locus, std::vector<TyVar> params,
- TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
+ TyVar result_type, ABI abi, Unsafety unsafety,
+ std::set<HirId> refs = std::set<HirId> ())
: CallableTypeInterface (ref, ty_ref, TypeKind::FNPTR,
{Resolver::CanonicalPath::create_empty (), locus},
refs),
- params (params), result_type (result_type)
+ params (params), result_type (result_type), abi (abi), unsafety (unsafety)
{}
std::string get_name () const override final { return as_string (); }
@@ -1117,8 +1210,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
BaseType *clone () const final override;
@@ -1126,9 +1217,17 @@ public:
std::vector<TyVar> &get_params () { return params; }
const std::vector<TyVar> &get_params () const { return params; }
+ ABI get_abi () const { return abi; }
+
+ Unsafety get_unsafety () const { return unsafety; }
+
+ FnPtr *handle_substitions (SubstitutionArgumentMappings &mappings);
+
private:
std::vector<TyVar> params;
TyVar result_type;
+ ABI abi;
+ Unsafety unsafety;
};
class ClosureType : public CallableTypeInterface, public SubstitutionRef
@@ -1194,8 +1293,6 @@ public:
std::string as_string () const override;
std::string get_name () const override final { return as_string (); }
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
BaseType *clone () const final override;
@@ -1224,14 +1321,14 @@ class ArrayType : public BaseType
public:
static constexpr auto KIND = TypeKind::ARRAY;
- ArrayType (HirId ref, location_t locus, ConstType *capacity, TyVar base,
+ ArrayType (HirId ref, location_t locus, TyVar capacity, TyVar base,
std::set<HirId> refs = std::set<HirId> ())
: BaseType (ref, ref, TypeKind::ARRAY,
{Resolver::CanonicalPath::create_empty (), locus}, refs),
element_type (base), capacity (capacity)
{}
- ArrayType (HirId ref, HirId ty_ref, location_t locus, ConstType *capacity,
+ ArrayType (HirId ref, HirId ty_ref, location_t locus, TyVar capacity,
TyVar base, std::set<HirId> refs = std::set<HirId> ())
: BaseType (ref, ty_ref, TypeKind::ARRAY,
{Resolver::CanonicalPath::create_empty (), locus}, refs),
@@ -1245,8 +1342,6 @@ public:
std::string get_name () const override final { return as_string (); }
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
BaseType *get_element_type () const;
@@ -1254,13 +1349,14 @@ public:
BaseType *clone () const final override;
- ConstType *get_capacity () const { return capacity; }
+ BaseType *get_capacity () const;
+ const TyVar &get_capacity_var () const { return capacity; }
ArrayType *handle_substitions (SubstitutionArgumentMappings &mappings);
private:
TyVar element_type;
- ConstType *capacity;
+ TyVar capacity;
};
class SliceType : public BaseType
@@ -1289,8 +1385,6 @@ public:
std::string get_name () const override final { return as_string (); }
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
BaseType *get_element_type () const;
@@ -1319,8 +1413,6 @@ public:
std::string get_name () const override final;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
};
@@ -1349,8 +1441,6 @@ public:
std::string get_name () const override final;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
IntKind get_int_kind () const;
BaseType *clone () const final override;
@@ -1387,8 +1477,6 @@ public:
std::string get_name () const override final;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
UintKind get_uint_kind () const;
BaseType *clone () const final override;
@@ -1421,8 +1509,6 @@ public:
std::string as_string () const override;
std::string get_name () const override final;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
FloatKind get_float_kind () const;
BaseType *clone () const final override;
@@ -1448,8 +1534,6 @@ public:
std::string as_string () const override;
std::string get_name () const override final;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
};
@@ -1468,8 +1552,6 @@ public:
std::string as_string () const override;
std::string get_name () const override final;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
};
@@ -1487,8 +1569,6 @@ public:
std::string as_string () const override;
std::string get_name () const override final;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
};
@@ -1507,8 +1587,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
BaseType *clone () const final override;
@@ -1532,8 +1610,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
BaseType *clone () const final override;
@@ -1568,8 +1644,6 @@ public:
std::string get_name () const override final;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
BaseType *clone () const final override;
@@ -1612,8 +1686,6 @@ public:
std::string as_string () const override;
std::string get_name () const override final;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
bool is_equal (const BaseType &other) const override;
BaseType *clone () const final override;
@@ -1659,8 +1731,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
std::string get_name () const override final;
@@ -1683,8 +1753,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
std::string get_name () const override final;
@@ -1734,8 +1802,6 @@ public:
std::string as_string () const override;
- bool can_eq (const BaseType *other, bool emit_errors) const override final;
-
BaseType *clone () const final override;
std::string get_name () const override final;
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 30ead5b..43dd6dc 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -24,31 +24,46 @@
namespace Rust {
namespace Resolver {
+static TyTy::BaseType *
+unify_error_type_node ()
+{
+ static TyTy::BaseType *error = nullptr;
+ if (error == nullptr)
+ error = new TyTy::ErrorType (0);
+ return error;
+}
+
UnifyRules::UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
location_t locus, bool commit_flag, bool emit_error,
- bool infer, std::vector<CommitSite> &commits,
+ bool check_bounds, bool infer,
+ std::vector<CommitSite> &commits,
std::vector<InferenceSite> &infers)
: lhs (lhs), rhs (rhs), locus (locus), commit_flag (commit_flag),
- emit_error (emit_error), infer_flag (infer), commits (commits),
- infers (infers), mappings (Analysis::Mappings::get ()),
- context (*TypeCheckContext::get ())
+ emit_error (emit_error), infer_flag (infer),
+ check_bounds_flag (check_bounds), commits (commits), infers (infers),
+ mappings (Analysis::Mappings::get ()), context (*TypeCheckContext::get ())
{}
TyTy::BaseType *
UnifyRules::Resolve (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
location_t locus, bool commit_flag, bool emit_error,
- bool infer, std::vector<CommitSite> &commits,
+ bool check_bounds, bool infer,
+ std::vector<CommitSite> &commits,
std::vector<InferenceSite> &infers)
{
- UnifyRules r (lhs, rhs, locus, commit_flag, emit_error, infer, commits,
- infers);
+ UnifyRules r (lhs, rhs, locus, commit_flag, emit_error, infer, check_bounds,
+ commits, infers);
TyTy::BaseType *result = r.go ();
- commits.push_back ({lhs.get_ty (), rhs.get_ty (), result});
- if (r.commit_flag)
- UnifyRules::commit (lhs.get_ty (), rhs.get_ty (), result);
-
bool failed = result->get_kind () == TyTy::TypeKind::ERROR;
+
+ commits.emplace_back (lhs.get_ty (), rhs.get_ty (), result);
+ if (r.commit_flag && !failed)
+ {
+ result = result->clone ();
+ UnifyRules::commit (lhs.get_ty (), rhs.get_ty (), result);
+ }
+
if (failed && r.emit_error)
r.emit_type_mismatch ();
@@ -60,7 +75,7 @@ UnifyRules::resolve_subtype (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs)
{
TyTy::BaseType *result
= UnifyRules::Resolve (lhs, rhs, locus, commit_flag, emit_error, infer_flag,
- commits, infers);
+ check_bounds_flag, commits, infers);
// If the recursive call resulted in an error and would have emitted an error
// message, disable error emission for the current level to avoid duplicate
@@ -104,24 +119,59 @@ UnifyRules::commit (TyTy::BaseType *base, TyTy::BaseType *other,
b->append_reference (resolved->get_ref ());
b->append_reference (o->get_ref ());
- bool result_resolved = resolved->get_kind () != TyTy::TypeKind::INFER;
- bool result_is_infer_var = resolved->get_kind () == TyTy::TypeKind::INFER;
- bool results_is_non_general_infer_var
- = (result_is_infer_var
- && (static_cast<TyTy::InferType *> (resolved))->get_infer_kind ()
- != TyTy::InferType::GENERAL);
- if (result_resolved || results_is_non_general_infer_var)
+ if (resolved->get_kind () != TyTy::TypeKind::CONST)
{
- for (auto &ref : resolved->get_combined_refs ())
+ bool result_resolved = resolved->get_kind () != TyTy::TypeKind::INFER;
+ bool result_is_infer_var = resolved->get_kind () == TyTy::TypeKind::INFER;
+ bool results_is_non_general_infer_var
+ = (result_is_infer_var
+ && (static_cast<TyTy::InferType *> (resolved))->get_infer_kind ()
+ != TyTy::InferType::GENERAL);
+ if (result_resolved || results_is_non_general_infer_var)
{
- TyTy::BaseType *ref_tyty = nullptr;
- bool ok = context.lookup_type (ref, &ref_tyty);
- if (!ok)
- continue;
-
- // if any of the types are inference variables lets fix them
- if (ref_tyty->is<TyTy::InferType> ())
- context.insert_implicit_type (ref, resolved);
+ for (auto &ref : resolved->get_combined_refs ())
+ {
+ TyTy::BaseType *ref_tyty = nullptr;
+ bool ok = context.lookup_type (ref, &ref_tyty);
+ if (!ok)
+ continue;
+
+ // if any of the types are inference variables lets fix them
+ if (ref_tyty->is<TyTy::InferType> ())
+ context.insert_implicit_type (ref, resolved);
+ }
+ }
+ }
+ else
+ {
+ auto base_const = resolved->as_const_type ();
+ if (base_const->const_kind () == TyTy::BaseConstType::ConstKind::Value)
+ {
+ rust_debug ("UnifyRules::commit const value, resolved_ref=%u "
+ "resolved_ty_ref=%u combined_refs.size=%zu",
+ resolved->get_ref (), resolved->get_ty_ref (),
+ resolved->get_combined_refs ().size ());
+
+ for (auto &ref : resolved->get_combined_refs ())
+ {
+ TyTy::BaseType *ref_tyty = nullptr;
+ bool ok = context.lookup_type (ref, &ref_tyty);
+ if (!ok)
+ continue;
+ if (ref_tyty->get_kind () != TyTy::TypeKind::CONST)
+ continue;
+
+ auto ref_base_const = ref_tyty->as_const_type ();
+ if (ref_base_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Infer
+ || ref_base_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Decl)
+ {
+ rust_debug (" committing to ref=%u kind=%d", ref,
+ (int) ref_base_const->const_kind ());
+ context.insert_implicit_type (ref, resolved);
+ }
+ }
}
}
}
@@ -155,39 +205,40 @@ UnifyRules::emit_abi_mismatch (const TyTy::FnType &expected,
TyTy::BaseType *
UnifyRules::go ()
{
- TyTy::BaseType *ltype = lhs.get_ty ();
- TyTy::BaseType *rtype = rhs.get_ty ();
-
- ltype = lhs.get_ty ()->destructure ();
- rtype = rhs.get_ty ()->destructure ();
+ TyTy::BaseType *ltype = lhs.get_ty ()->destructure ();
+ TyTy::BaseType *rtype = rhs.get_ty ()->destructure ();
rust_debug ("unify::go ltype={%s} rtype={%s}", ltype->debug_str ().c_str (),
rtype->debug_str ().c_str ());
- // check bounds
- bool ltype_is_placeholder = ltype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
- bool rtype_is_placeholder = rtype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
- bool types_equal = ltype->is_equal (*rtype);
- bool should_check_bounds
- = !types_equal && !(ltype_is_placeholder || rtype_is_placeholder);
- if (should_check_bounds)
+ if (check_bounds_flag)
{
- if (ltype->num_specified_bounds () > 0)
+ bool ltype_is_placeholder
+ = ltype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
+ bool rtype_is_placeholder
+ = rtype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
+ bool types_equal = ltype->is_equal (*rtype);
+ bool should_check_bounds
+ = !types_equal && !(ltype_is_placeholder || rtype_is_placeholder);
+ if (should_check_bounds)
{
- if (!ltype->bounds_compatible (*rtype, locus, emit_error))
+ if (ltype->num_specified_bounds () > 0)
{
- // already emitted an error
- emit_error = false;
- return new TyTy::ErrorType (0);
+ if (!ltype->bounds_compatible (*rtype, locus, emit_error))
+ {
+ // already emitted an error
+ emit_error = false;
+ return unify_error_type_node ();
+ }
}
- }
- else if (rtype->num_specified_bounds () > 0)
- {
- if (!rtype->bounds_compatible (*ltype, locus, emit_error))
+ else if (rtype->num_specified_bounds () > 0)
{
- // already emitted an error
- emit_error = false;
- return new TyTy::ErrorType (0);
+ if (!rtype->bounds_compatible (*ltype, locus, emit_error))
+ {
+ // already emitted an error
+ emit_error = false;
+ return unify_error_type_node ();
+ }
}
}
}
@@ -222,7 +273,7 @@ UnifyRules::go ()
rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER);
TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ());
- infers.push_back ({p->get_ref (), p->get_ty_ref (), p, i});
+ infers.emplace_back (p->get_ref (), p->get_ty_ref (), p, i);
// FIXME
// this is hacky to set the implicit param lets make this a function
@@ -239,7 +290,7 @@ UnifyRules::go ()
rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER);
TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ());
- infers.push_back ({p->get_ref (), p->get_ty_ref (), p, i});
+ infers.emplace_back (p->get_ref (), p->get_ty_ref (), p, i);
// FIXME
// this is hacky to set the implicit param lets make this a function
@@ -248,6 +299,36 @@ UnifyRules::go ()
// set the rtype now to the new inference var
ltype = i;
}
+ else if (ltype->get_kind () == TyTy::TypeKind::CONST
+ && rtype->get_kind () == TyTy::TypeKind::CONST)
+ {
+ const auto &lhs = *ltype->as_const_type ();
+ const auto &rhs = *rtype->as_const_type ();
+
+ bool both_are_decls
+ = lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ && rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl;
+ bool have_decls
+ = lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ || rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl;
+
+ if (have_decls && !both_are_decls)
+ {
+ if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
+ {
+ TyTy::TyVar iv = TyTy::TyVar::get_implicit_const_infer_var (
+ lhs.as_base_type ()->get_locus ());
+ ltype = iv.get_tyty ();
+ }
+ else if (rhs.const_kind ()
+ == TyTy::BaseConstType::ConstKind::Decl)
+ {
+ TyTy::TyVar iv = TyTy::TyVar::get_implicit_const_infer_var (
+ rhs.as_base_type ()->get_locus ());
+ rtype = iv.get_tyty ();
+ }
+ }
+ }
}
switch (ltype->get_kind ())
@@ -329,13 +410,13 @@ UnifyRules::go ()
return expect_opaque (static_cast<TyTy::OpaqueType *> (ltype), rtype);
case TyTy::CONST:
- return expect_const (static_cast<TyTy::ConstType *> (ltype), rtype);
+ return expect_const (ltype->as_const_type (), rtype);
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -350,7 +431,7 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
switch (ltype->get_infer_kind ())
{
case TyTy::InferType::InferTypeKind::GENERAL:
- return rtype->clone ();
+ return rtype;
case TyTy::InferType::InferTypeKind::INTEGRAL:
{
@@ -388,7 +469,8 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
== TyTy::InferType::InferTypeKind::INTEGRAL);
if (is_valid)
{
- ltype->apply_primitive_type_hint (*rtype);
+ if (commit_flag)
+ ltype->apply_primitive_type_hint (*rtype);
return rtype;
}
}
@@ -402,7 +484,8 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
== TyTy::InferType::InferTypeKind::FLOAT);
if (is_valid)
{
- ltype->apply_primitive_type_hint (*rtype);
+ if (commit_flag)
+ ltype->apply_primitive_type_hint (*rtype);
return rtype;
}
}
@@ -431,15 +514,15 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
bool is_valid = (ltype->get_infer_kind ()
== TyTy::InferType::InferTypeKind::GENERAL);
if (is_valid)
- return rtype->clone ();
+ return rtype;
}
break;
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -453,7 +536,7 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -462,17 +545,17 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
TyTy::ADTType &type = *static_cast<TyTy::ADTType *> (rtype);
if (ltype->get_adt_kind () != type.get_adt_kind ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
if (ltype->get_identifier ().compare (type.get_identifier ()) != 0)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
if (ltype->number_of_variants () != type.number_of_variants ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
for (size_t i = 0; i < type.number_of_variants (); ++i)
@@ -482,7 +565,7 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
if (a->num_fields () != b->num_fields ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
for (size_t j = 0; j < a->num_fields (); j++)
@@ -498,7 +581,7 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (other_field_ty));
if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
}
}
@@ -521,12 +604,12 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (pb));
if (res->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
}
}
- return type.clone ();
+ return ltype;
}
break;
@@ -554,9 +637,9 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -570,12 +653,12 @@ UnifyRules::expect_str (TyTy::StrType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
case TyTy::STR:
- return rtype->clone ();
+ return rtype;
case TyTy::ADT:
case TyTy::REF:
@@ -601,9 +684,9 @@ UnifyRules::expect_str (TyTy::StrType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -617,7 +700,7 @@ UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -632,7 +715,7 @@ UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (other_base_type));
if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
// rust is permissive about mutablity here you can always go from
@@ -640,12 +723,10 @@ UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
bool mutability_ok = ltype->is_mutable () ? type.is_mutable () : true;
if (!mutability_ok)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ReferenceType (ltype->get_ref (), ltype->get_ty_ref (),
- TyTy::TyVar (base_resolved->get_ref ()),
- ltype->mutability ());
+ return ltype;
}
break;
@@ -673,9 +754,9 @@ UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -689,7 +770,7 @@ UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -704,7 +785,7 @@ UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (other_base_type));
if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
// rust is permissive about mutablity here you can always go from
@@ -712,12 +793,10 @@ UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
bool mutability_ok = ltype->is_mutable () ? type.is_mutable () : true;
if (!mutability_ok)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::PointerType (ltype->get_ref (), ltype->get_ty_ref (),
- TyTy::TyVar (base_resolved->get_ref ()),
- ltype->mutability ());
+ return ltype;
}
break;
@@ -745,9 +824,9 @@ UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -761,7 +840,7 @@ UnifyRules::expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -810,9 +889,9 @@ UnifyRules::expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -826,7 +905,7 @@ UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -838,24 +917,35 @@ UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (type.get_element_type ()));
if (element_unify->get_kind () == TyTy::TypeKind::ERROR)
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
+
+ auto ltype_cap = ltype->get_capacity ();
+ auto rtype_cap = type.get_capacity ();
+
+ // If either capacity is not a const type, return error
+ if (ltype_cap->get_kind () != TyTy::TypeKind::CONST
+ || rtype_cap->get_kind () != TyTy::TypeKind::CONST)
+ return unify_error_type_node ();
bool save_emit_error = emit_error;
emit_error = false;
TyTy::BaseType *capacity_unify
- = resolve_subtype (TyTy::TyWithLocation (ltype->get_capacity ()),
- TyTy::TyWithLocation (type.get_capacity ()));
+ = resolve_subtype (TyTy::TyWithLocation (ltype_cap),
+ TyTy::TyWithLocation (rtype_cap));
emit_error = save_emit_error;
if (capacity_unify->get_kind () != TyTy::TypeKind::CONST)
- return new TyTy::ErrorType (0);
-
- TyTy::ConstType *capacity_type_unify
- = static_cast<TyTy::ConstType *> (capacity_unify);
- return new TyTy::ArrayType (type.get_ref (), type.get_ty_ref (),
- type.get_ident ().locus,
- capacity_type_unify,
- TyTy::TyVar (element_unify->get_ref ()));
+ return unify_error_type_node ();
+
+ auto capacity_type_unify = capacity_unify->as_const_type ();
+ if (capacity_type_unify->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Error)
+ return unify_error_type_node ();
+
+ return new TyTy::ArrayType (
+ type.get_ref (), type.get_ty_ref (), type.get_ident ().locus,
+ TyTy::TyVar (capacity_type_unify->as_base_type ()->get_ref ()),
+ TyTy::TyVar (element_unify->get_ref ()));
}
break;
@@ -883,9 +973,9 @@ UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -899,7 +989,7 @@ UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -911,12 +1001,7 @@ UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (type.get_element_type ()));
if (element_unify->get_kind () != TyTy::TypeKind::ERROR)
- {
- return new TyTy::SliceType (type.get_ref (), type.get_ty_ref (),
- type.get_ident ().locus,
- TyTy::TyVar (
- element_unify->get_ref ()));
- }
+ return ltype;
}
break;
@@ -944,9 +1029,9 @@ UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -960,7 +1045,7 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -969,7 +1054,7 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
TyTy::FnType &type = *static_cast<TyTy::FnType *> (rtype);
if (ltype->num_params () != type.num_params ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
for (size_t i = 0; i < ltype->num_params (); i++)
@@ -981,7 +1066,7 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (b));
if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
}
@@ -990,7 +1075,7 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (type.get_return_type ()));
if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
// ABI match? see
@@ -1001,12 +1086,12 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
{
emit_abi_mismatch (*ltype, type);
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
// DEF Id match? see https://github.com/Rust-GCC/gccrs/issues/2053
- return ltype->clone ();
+ return ltype;
}
break;
@@ -1034,9 +1119,9 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1050,7 +1135,7 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -1059,7 +1144,7 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
TyTy::FnPtr &type = *static_cast<TyTy::FnPtr *> (rtype);
if (ltype->num_params () != type.num_params ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
for (size_t i = 0; i < ltype->num_params (); i++)
@@ -1071,7 +1156,7 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (b));
if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
}
@@ -1080,10 +1165,20 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (type.get_return_type ()));
if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return ltype->clone ();
+ if (ltype->get_abi () != type.get_abi ())
+ {
+ return unify_error_type_node ();
+ }
+
+ if (ltype->get_unsafety () != type.get_unsafety ())
+ {
+ return unify_error_type_node ();
+ }
+
+ return ltype;
}
break;
@@ -1098,12 +1193,12 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (other_ret_type));
if (unified_result->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
if (ltype->num_params () != type.num_params ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
for (size_t i = 0; i < ltype->num_params (); i++)
@@ -1116,11 +1211,30 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (other_param));
if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
}
- return ltype->clone ();
+ // FIXME
+ //
+ // there is a bug in:
+ // testsuite/rust/compile/try-catch-unwind-{new,old}.rs I think the test
+ //
+ // case is wrong because it should be taking an FnOnce which probably
+ // didnt exist at the time in gccrs
+ //
+ // if (ltype->get_abi () != type.get_abi ())
+ // {
+ // return unify_error_type_node ();
+ // }
+
+ // FIXME fntype needs to track unsafe or not
+ // if (ltype->get_unsafety () != type.get_unsafety ())
+ // {
+ // return unify_error_type_node ();
+ // }
+
+ return ltype;
}
break;
@@ -1135,12 +1249,12 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (other_ret_type));
if (unified_result->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
if (ltype->num_params () != type.get_num_params ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
for (size_t i = 0; i < ltype->num_params (); i++)
@@ -1153,11 +1267,11 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (other_param));
if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
}
- return ltype->clone ();
+ return ltype;
}
break;
@@ -1183,9 +1297,9 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1199,7 +1313,7 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -1208,7 +1322,7 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
TyTy::TupleType &type = *static_cast<TyTy::TupleType *> (rtype);
if (ltype->num_fields () != type.num_fields ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
std::vector<TyTy::TyVar> fields;
@@ -1221,13 +1335,12 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
= resolve_subtype (TyTy::TyWithLocation (bo),
TyTy::TyWithLocation (fo));
if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
- fields.push_back (TyTy::TyVar (unified_ty->get_ref ()));
+ fields.emplace_back (unified_ty->get_ref ());
}
- return new TyTy::TupleType (type.get_ref (), type.get_ty_ref (),
- type.get_ident ().locus, fields);
+ return ltype;
}
break;
@@ -1255,9 +1368,9 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1272,14 +1385,15 @@ UnifyRules::expect_bool (TyTy::BoolType *ltype, TyTy::BaseType *rtype)
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
{
- r->apply_primitive_type_hint (*ltype);
- return ltype->clone ();
+ if (commit_flag)
+ r->apply_primitive_type_hint (*ltype);
+ return ltype;
}
}
break;
case TyTy::BOOL:
- return rtype->clone ();
+ return rtype;
case TyTy::CHAR:
case TyTy::INT:
@@ -1305,9 +1419,9 @@ UnifyRules::expect_bool (TyTy::BoolType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1322,14 +1436,15 @@ UnifyRules::expect_char (TyTy::CharType *ltype, TyTy::BaseType *rtype)
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
{
- r->apply_primitive_type_hint (*ltype);
- return ltype->clone ();
+ if (commit_flag)
+ r->apply_primitive_type_hint (*ltype);
+ return ltype;
}
}
break;
case TyTy::CHAR:
- return rtype->clone ();
+ return rtype;
case TyTy::INT:
case TyTy::FLOAT:
@@ -1355,9 +1470,9 @@ UnifyRules::expect_char (TyTy::CharType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1373,8 +1488,9 @@ UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype)
|| r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
if (is_valid)
{
- r->apply_primitive_type_hint (*ltype);
- return ltype->clone ();
+ if (commit_flag)
+ r->apply_primitive_type_hint (*ltype);
+ return ltype;
}
}
break;
@@ -1384,8 +1500,7 @@ UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype)
TyTy::IntType &type = *static_cast<TyTy::IntType *> (rtype);
bool is_valid = ltype->get_int_kind () == type.get_int_kind ();
if (is_valid)
- return new TyTy::IntType (type.get_ref (), type.get_ty_ref (),
- type.get_int_kind ());
+ return ltype;
}
break;
@@ -1413,9 +1528,9 @@ UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1431,8 +1546,9 @@ UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype)
|| r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
if (is_valid)
{
- r->apply_primitive_type_hint (*ltype);
- return ltype->clone ();
+ if (commit_flag)
+ r->apply_primitive_type_hint (*ltype);
+ return ltype;
}
}
break;
@@ -1442,8 +1558,7 @@ UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype)
TyTy::UintType &type = *static_cast<TyTy::UintType *> (rtype);
bool is_valid = ltype->get_uint_kind () == type.get_uint_kind ();
if (is_valid)
- return new TyTy::UintType (type.get_ref (), type.get_ty_ref (),
- type.get_uint_kind ());
+ return ltype;
}
break;
@@ -1471,9 +1586,9 @@ UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1489,8 +1604,9 @@ UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype)
|| r->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT;
if (is_valid)
{
- r->apply_primitive_type_hint (*ltype);
- return ltype->clone ();
+ if (commit_flag)
+ r->apply_primitive_type_hint (*ltype);
+ return ltype;
}
}
break;
@@ -1500,8 +1616,7 @@ UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype)
TyTy::FloatType &type = *static_cast<TyTy::FloatType *> (rtype);
bool is_valid = ltype->get_float_kind () == type.get_float_kind ();
if (is_valid)
- return new TyTy::FloatType (type.get_ref (), type.get_ty_ref (),
- type.get_float_kind ());
+ return ltype;
}
break;
@@ -1529,9 +1644,9 @@ UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1546,14 +1661,15 @@ UnifyRules::expect_isize (TyTy::ISizeType *ltype, TyTy::BaseType *rtype)
= r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
if (is_valid)
{
- r->apply_primitive_type_hint (*ltype);
- return ltype->clone ();
+ if (commit_flag)
+ r->apply_primitive_type_hint (*ltype);
+ return ltype;
}
}
break;
case TyTy::ISIZE:
- return rtype->clone ();
+ return rtype;
case TyTy::ADT:
case TyTy::STR:
@@ -1579,9 +1695,9 @@ UnifyRules::expect_isize (TyTy::ISizeType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1596,14 +1712,15 @@ UnifyRules::expect_usize (TyTy::USizeType *ltype, TyTy::BaseType *rtype)
= r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
if (is_valid)
{
- r->apply_primitive_type_hint (*ltype);
- return ltype->clone ();
+ if (commit_flag)
+ r->apply_primitive_type_hint (*ltype);
+ return ltype;
}
}
break;
case TyTy::USIZE:
- return rtype->clone ();
+ return rtype;
case TyTy::ADT:
case TyTy::STR:
@@ -1629,9 +1746,9 @@ UnifyRules::expect_usize (TyTy::USizeType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1645,14 +1762,14 @@ UnifyRules::expect_never (TyTy::NeverType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
default:
- return rtype->clone ();
+ return rtype;
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1667,12 +1784,12 @@ UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype,
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
case TyTy::PLACEHOLDER:
- return ltype->clone ();
+ return ltype;
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
@@ -1697,14 +1814,14 @@ UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype,
case TyTy::NEVER:
case TyTy::OPAQUE:
if (infer_flag)
- return rtype->clone ();
+ return rtype;
gcc_fallthrough ();
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1719,7 +1836,7 @@ UnifyRules::expect_projection (TyTy::ProjectionType *ltype,
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -1752,9 +1869,9 @@ UnifyRules::expect_projection (TyTy::ProjectionType *ltype,
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1768,7 +1885,7 @@ UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -1778,15 +1895,15 @@ UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype)
= *static_cast<TyTy::DynamicObjectType *> (rtype);
if (ltype->num_specified_bounds () != type.num_specified_bounds ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
if (!ltype->bounds_compatible (type, locus, true))
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return ltype->clone ();
+ return ltype;
}
break;
@@ -1814,9 +1931,9 @@ UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1830,7 +1947,7 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ return ltype;
}
break;
@@ -1839,7 +1956,7 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
TyTy::ClosureType &type = *static_cast<TyTy::ClosureType *> (rtype);
if (ltype->get_def_id () != type.get_def_id ())
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *args_res
@@ -1847,7 +1964,7 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (&type.get_parameters ()));
if (args_res->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *res
@@ -1855,10 +1972,10 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
TyTy::TyWithLocation (&type.get_result_type ()));
if (res == nullptr || res->get_kind () == TyTy::TypeKind::ERROR)
{
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return ltype->clone ();
+ return ltype;
}
break;
@@ -1886,9 +2003,9 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
case TyTy::OPAQUE:
case TyTy::CONST:
case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
TyTy::BaseType *
@@ -1898,7 +2015,7 @@ UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype)
{
TyTy::OpaqueType *ro = rtype->as<TyTy::OpaqueType> ();
if (!ltype->is_equal (*ro))
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
if (ltype->can_resolve () && ro->can_resolve ())
{
@@ -1908,7 +2025,7 @@ UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype)
auto res = resolve_subtype (TyTy::TyWithLocation (lr),
TyTy::TyWithLocation (rr));
if (res->get_kind () == TyTy::TypeKind::ERROR)
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
else if (ltype->can_resolve ())
{
@@ -1927,7 +2044,7 @@ UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype)
auto res = resolve_subtype (TyTy::TyWithLocation (underly),
TyTy::TyWithLocation (rtype));
if (res->get_kind () == TyTy::TypeKind::ERROR)
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
else
{
@@ -1938,70 +2055,108 @@ UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype)
}
TyTy::BaseType *
-UnifyRules::expect_const (TyTy::ConstType *ltype, TyTy::BaseType *rtype)
+UnifyRules::expect_const (TyTy::BaseConstType *ltype, TyTy::BaseType *rtype)
{
if (rtype->get_kind () != TyTy::TypeKind::CONST)
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
- TyTy::ConstType &lhs = *ltype;
- TyTy::ConstType &rhs = *static_cast<TyTy::ConstType *> (rtype);
+ auto &lhs = *ltype;
+ auto &rhs = *rtype->as_const_type ();
- auto res = resolve_subtype (TyTy::TyWithLocation (lhs.get_ty ()),
- TyTy::TyWithLocation (rhs.get_ty ()));
- if (res->get_kind () == TyTy::TypeKind::ERROR)
- return new TyTy::ErrorType (0);
+ // Handle error types early
+ if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Error
+ || rhs.const_kind () == TyTy::BaseConstType::ConstKind::Error)
+ {
+ auto lhs_base = ltype->as_base_type ();
+ return new TyTy::ConstErrorType (lhs.get_specified_type (),
+ lhs_base->get_ref (),
+ lhs_base->get_ty_ref (),
+ lhs_base->get_combined_refs ());
+ }
- tree lv = lhs.get_value ();
- tree rv = rhs.get_value ();
+ // Try to resolve Decl types (ConstParamType)
+ TyTy::BaseConstType *resolved_lhs = &lhs;
+ TyTy::BaseConstType *resolved_rhs = &rhs;
- if (error_operand_p (lv) && error_operand_p (rv))
+ if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
{
- // this is only allowed for some silly senarios like:
- // gcc/testsuite/rust/compile/issue-const_generics_5.rs
- if (lhs.get_const_kind () == rhs.get_const_kind ())
+ auto *param = static_cast<TyTy::ConstParamType *> (&lhs);
+ if (param->can_resolve ())
{
- return new TyTy::ConstType (lhs.get_const_kind (), lhs.get_symbol (),
- res, error_mark_node,
- lhs.get_specified_bounds (),
- lhs.get_locus (), lhs.get_ref (),
- lhs.get_ty_ref (),
- lhs.get_combined_refs ());
+ auto *resolved = param->resolve ();
+ if (resolved->get_kind () == TyTy::TypeKind::CONST)
+ resolved_lhs = resolved->as_const_type ();
}
-
- return new TyTy::ErrorType (0);
}
- bool equal = operand_equal_p (lv, rv, 0);
- if (equal)
+ if (rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
{
- return new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
- lhs.get_symbol (), res, lv,
- lhs.get_specified_bounds (), lhs.get_locus (),
- lhs.get_ref (), lhs.get_ty_ref (),
- lhs.get_combined_refs ());
+ auto *param = static_cast<TyTy::ConstParamType *> (&rhs);
+ if (param->can_resolve ())
+ {
+ auto *resolved = param->resolve ();
+ if (resolved->get_kind () == TyTy::TypeKind::CONST)
+ resolved_rhs = resolved->as_const_type ();
+ }
}
- if (lhs.get_const_kind () == TyTy::ConstType::Infer && !error_operand_p (rv))
+ auto res = resolve_subtype (
+ TyTy::TyWithLocation (resolved_lhs->get_specified_type ()),
+ TyTy::TyWithLocation (resolved_rhs->get_specified_type ()));
+ if (res->get_kind () == TyTy::TypeKind::ERROR)
+ return unify_error_type_node ();
+
+ if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Value
+ && resolved_rhs->const_kind () == TyTy::BaseConstType::ConstKind::Value)
{
- lhs.set_value (rv);
- return new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
- lhs.get_symbol (), res, rv,
- lhs.get_specified_bounds (), lhs.get_locus (),
- lhs.get_ref (), lhs.get_ty_ref (),
- lhs.get_combined_refs ());
+ auto vlhs = static_cast<TyTy::ConstValueType &> (*resolved_lhs);
+ auto vrhs = static_cast<TyTy::ConstValueType &> (*resolved_rhs);
+ tree lv = vlhs.get_value ();
+ tree rv = vrhs.get_value ();
+
+ bool ok = operand_equal_p (lv, rv, 0);
+ if (!ok)
+ return unify_error_type_node ();
+ else
+ {
+ auto lhs_base = resolved_lhs->as_base_type ();
+ return new TyTy::ConstValueType (lv, res, lhs_base->get_ref (),
+ lhs_base->get_ty_ref (),
+ lhs_base->get_combined_refs ());
+ }
}
- else if (rhs.get_const_kind () == TyTy::ConstType::Infer
- && !error_operand_p (lv))
+ else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
+ && resolved_rhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value)
+ return resolved_rhs->as_base_type ();
+ else if (resolved_rhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
+ && resolved_lhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value)
+ return resolved_lhs->as_base_type ();
+ else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
+ && resolved_rhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Infer)
+ return resolved_lhs->as_base_type ();
+ else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ || resolved_rhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Decl)
{
- rhs.set_value (lv);
- return new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
- rhs.get_symbol (), res, lv,
- rhs.get_specified_bounds (), rhs.get_locus (),
- rhs.get_ref (), rhs.get_ty_ref (),
- rhs.get_combined_refs ());
+ // If we still have unresolved Decl after trying to resolve, unify with it
+ // This allows const inference to work
+ if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ && resolved_rhs->const_kind ()
+ != TyTy::BaseConstType::ConstKind::Decl)
+ return resolved_rhs->as_base_type ();
+ else if (resolved_rhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Decl
+ && resolved_lhs->const_kind ()
+ != TyTy::BaseConstType::ConstKind::Decl)
+ return resolved_lhs->as_base_type ();
+ // Both are Decl - return lhs
+ return resolved_lhs->as_base_type ();
}
- return new TyTy::ErrorType (0);
+ return unify_error_type_node ();
}
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-unify.h b/gcc/rust/typecheck/rust-unify.h
index b8c9cbc..4bed24c 100644
--- a/gcc/rust/typecheck/rust-unify.h
+++ b/gcc/rust/typecheck/rust-unify.h
@@ -30,6 +30,11 @@ class UnifyRules
public:
struct InferenceSite
{
+ InferenceSite (HirId pref, HirId ptyref, TyTy::ParamType *param,
+ TyTy::InferType *infer)
+ : pref (pref), ptyref (ptyref), param (param), infer (infer)
+ {}
+
HirId pref;
HirId ptyref;
TyTy::ParamType *param;
@@ -37,6 +42,11 @@ public:
};
struct CommitSite
{
+ CommitSite (TyTy::BaseType *lhs, TyTy::BaseType *rhs,
+ TyTy::BaseType *resolved)
+ : lhs (lhs), rhs (rhs), resolved (resolved)
+ {}
+
TyTy::BaseType *lhs;
TyTy::BaseType *rhs;
TyTy::BaseType *resolved;
@@ -45,6 +55,7 @@ public:
static TyTy::BaseType *Resolve (TyTy::TyWithLocation lhs,
TyTy::TyWithLocation rhs, location_t locus,
bool commit_flag, bool emit_error, bool infer,
+ bool check_bounds,
std::vector<CommitSite> &commits,
std::vector<InferenceSite> &infers);
@@ -84,12 +95,13 @@ protected:
TyTy::BaseType *rtype);
TyTy::BaseType *expect_opaque (TyTy::OpaqueType *ltype,
TyTy::BaseType *rtype);
- TyTy::BaseType *expect_const (TyTy::ConstType *ltype, TyTy::BaseType *rtype);
+ TyTy::BaseType *expect_const (TyTy::BaseConstType *ltype,
+ TyTy::BaseType *rtype);
private:
UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
location_t locus, bool commit_flag, bool emit_error, bool infer,
- std::vector<CommitSite> &commits,
+ bool check_bounds, std::vector<CommitSite> &commits,
std::vector<InferenceSite> &infers);
TyTy::BaseType *resolve_subtype (TyTy::TyWithLocation lhs,
@@ -110,6 +122,7 @@ private:
bool commit_flag;
bool emit_error;
bool infer_flag;
+ bool check_bounds_flag;
std::vector<CommitSite> &commits;
std::vector<InferenceSite> &infers;
diff --git a/gcc/rust/util/bi-map.h b/gcc/rust/util/bi-map.h
index 54870f7..4af157f 100644
--- a/gcc/rust/util/bi-map.h
+++ b/gcc/rust/util/bi-map.h
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-system.h"
+#include "optional.h"
#ifndef BIMAP_H
#define BIMAP_H
diff --git a/gcc/rust/util/fnv-hash.h b/gcc/rust/util/fnv-hash.h
index 6d2ec01..e51b66a 100644
--- a/gcc/rust/util/fnv-hash.h
+++ b/gcc/rust/util/fnv-hash.h
@@ -15,6 +15,7 @@
// 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-system.h"
#ifndef RUST_FNV_HASH_H
#define RUST_FNV_HASH_H
diff --git a/gcc/rust/util/rust-attribute-values.h b/gcc/rust/util/rust-attribute-values.h
index 367044a..a22664a 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -36,6 +36,7 @@ public:
static constexpr auto &DOC = "doc";
static constexpr auto &MUST_USE = "must_use";
static constexpr auto &LANG = "lang";
+ static constexpr auto &LINK_NAME = "link_name";
static constexpr auto &LINK_SECTION = "link_section";
static constexpr auto &NO_MANGLE = "no_mangle";
static constexpr auto &REPR = "repr";
@@ -48,6 +49,8 @@ public:
static constexpr auto &PROC_MACRO_DERIVE = "proc_macro_derive";
static constexpr auto &PROC_MACRO_ATTRIBUTE = "proc_macro_attribute";
+ static constexpr auto &DERIVE = "derive";
+
static constexpr auto &TARGET_FEATURE = "target_feature";
// From now on, these are reserved by the compiler and gated through
// #![feature(rustc_attrs)]
@@ -60,6 +63,8 @@ public:
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_ALLOW_CONST_FN_UNSTABLE
+ = "rustc_allow_const_fn_unstable";
static constexpr auto &RUSTC_SPECIALIZATION_TRAIT
= "rustc_specialization_trait";
@@ -88,8 +93,6 @@ public:
static constexpr auto &TEST = "test";
- static constexpr auto &SIMD_TEST = "simd_test";
-
static constexpr auto &RUSTC_ARGS_REQUIRED_CONST
= "rustc_args_required_const";
};
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index c846c2d..9621100 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -38,6 +38,31 @@ Attributes::is_known (const std::string &attribute_path)
return !lookup.is_error ();
}
+tl::optional<std::string>
+Attributes::extract_string_literal (const AST::Attribute &attr)
+{
+ if (!attr.has_attr_input ())
+ return tl::nullopt;
+
+ auto &attr_input = attr.get_attr_input ();
+
+ if (attr_input.get_attr_input_type ()
+ != AST::AttrInput::AttrInputType::LITERAL)
+ return tl::nullopt;
+
+ auto &literal_expr
+ = static_cast<AST::AttrInputLiteral &> (attr_input).get_literal ();
+
+ auto lit_type = literal_expr.get_lit_type ();
+
+ // TODO: bring escape sequence handling out of lexing?
+ if (lit_type != AST::Literal::LitType::STRING
+ && lit_type != AST::Literal::LitType::RAW_STRING)
+ return tl::nullopt;
+
+ return literal_expr.as_string ();
+}
+
using Attrs = Values::Attributes;
// https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
@@ -53,6 +78,7 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::DOC, HIR_LOWERING},
{Attrs::MUST_USE, STATIC_ANALYSIS},
{Attrs::LANG, HIR_LOWERING},
+ {Attrs::LINK_NAME, CODE_GENERATION},
{Attrs::LINK_SECTION, CODE_GENERATION},
{Attrs::NO_MANGLE, CODE_GENERATION},
{Attrs::REPR, CODE_GENERATION},
@@ -64,6 +90,8 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::PROC_MACRO, EXPANSION},
{Attrs::PROC_MACRO_DERIVE, EXPANSION},
{Attrs::PROC_MACRO_ATTRIBUTE, EXPANSION},
+
+ {Attrs::DERIVE, EXPANSION},
// FIXME: This is not implemented yet, see
// https://github.com/Rust-GCC/gccrs/issues/1475
{Attrs::TARGET_FEATURE, CODE_GENERATION},
@@ -78,6 +106,7 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::RUSTC_PROMOTABLE, CODE_GENERATION},
{Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
{Attrs::RUSTC_CONST_UNSTABLE, STATIC_ANALYSIS},
+ {Attrs::RUSTC_ALLOW_CONST_FN_UNSTABLE, STATIC_ANALYSIS},
{Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
{Attrs::TRACK_CALLER, CODE_GENERATION},
{Attrs::RUSTC_SPECIALIZATION_TRAIT, TYPE_CHECK},
@@ -100,8 +129,7 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::NON_EXHAUSTIVE, TYPE_CHECK},
{Attrs::RUSTFMT, EXTERNAL},
- {Attrs::TEST, CODE_GENERATION},
- {Attrs::SIMD_TEST, CODE_GENERATION}};
+ {Attrs::TEST, CODE_GENERATION}};
BuiltinAttributeMappings *
BuiltinAttributeMappings::get ()
@@ -144,6 +172,7 @@ AttributeChecker::go (AST::Crate &crate)
void
AttributeChecker::visit (AST::Crate &crate)
{
+ check_inner_attributes (crate.get_inner_attrs ());
check_attributes (crate.get_inner_attrs ());
for (auto &item : crate.items)
@@ -214,8 +243,8 @@ check_doc_attribute (const AST::Attribute &attribute)
{
rust_error_at (
attribute.get_locus (),
- // FIXME: Improve error message here. Rustc has a very good one
- "%<#[doc]%> cannot be an empty attribute");
+ "valid forms for the attribute are "
+ "%<#[doc(hidden|inline|...)]%> and %<#[doc = \" string \"]%>");
return;
}
@@ -300,6 +329,20 @@ check_proc_macro_non_root (AST::AttrVec attributes, location_t loc)
void
AttributeChecker::check_attribute (const AST::Attribute &attribute)
{
+ if (!attribute.empty_input ())
+ {
+ const auto &attr_input = attribute.get_attr_input ();
+ auto type = attr_input.get_attr_input_type ();
+ if (type == AST::AttrInput::AttrInputType::TOKEN_TREE)
+ {
+ const auto &option = static_cast<const AST::DelimTokenTree &> (
+ attribute.get_attr_input ());
+ std::unique_ptr<AST::AttrInputMetaItemContainer> meta_item (
+ option.parse_to_meta_item ());
+ AST::DefaultASTVisitor::visit (meta_item);
+ }
+ }
+
BuiltinAttrDefinition result;
// This checker does not check non-builtin attributes
@@ -314,6 +357,15 @@ AttributeChecker::check_attribute (const AST::Attribute &attribute)
}
void
+AttributeChecker::check_inner_attributes (const AST::AttrVec &attributes)
+{
+ for (auto &attr : attributes)
+ if (attr.is_derive ())
+ rust_error_at (attr.get_locus (),
+ "derive attribute cannot be used at crate level");
+}
+
+void
AttributeChecker::check_attributes (const AST::AttrVec &attributes)
{
for (auto &attr : attributes)
@@ -329,10 +381,6 @@ AttributeChecker::visit (AST::DelimTokenTree &)
{}
void
-AttributeChecker::visit (AST::AttrInputMetaItemContainer &)
-{}
-
-void
AttributeChecker::visit (AST::IdentifierExpr &)
{}
@@ -395,8 +443,16 @@ AttributeChecker::visit (AST::MetaItemLitExpr &)
{}
void
-AttributeChecker::visit (AST::MetaItemPathExpr &)
-{}
+AttributeChecker::visit (AST::MetaItemPathExpr &attribute)
+{
+ if (!attribute.get_expr ().is_literal ())
+ {
+ rust_error_at (attribute.get_expr ().get_locus (),
+ "malformed %<path%> attribute input");
+ rust_inform (attribute.get_expr ().get_locus (),
+ "must be of the form: %<#[path = \"file\"]%>");
+ }
+}
void
AttributeChecker::visit (AST::BorrowExpr &)
@@ -622,6 +678,7 @@ AttributeChecker::visit (AST::TypeBoundWhereClauseItem &)
void
AttributeChecker::visit (AST::Module &module)
{
+ check_attributes (module.get_outer_attrs ());
check_proc_macro_non_function (module.get_outer_attrs ());
for (auto &item : module.get_items ())
{
@@ -774,10 +831,6 @@ AttributeChecker::visit (AST::StaticItem &item)
}
void
-AttributeChecker::visit (AST::TraitItemConst &)
-{}
-
-void
AttributeChecker::visit (AST::TraitItemType &)
{}
@@ -785,6 +838,7 @@ void
AttributeChecker::visit (AST::Trait &trait)
{
check_proc_macro_non_function (trait.get_outer_attrs ());
+ check_attributes (trait.get_outer_attrs ());
}
void
@@ -841,10 +895,6 @@ AttributeChecker::visit (AST::MetaItemPath &)
{}
void
-AttributeChecker::visit (AST::MetaItemSeq &)
-{}
-
-void
AttributeChecker::visit (AST::MetaWord &)
{}
@@ -920,11 +970,11 @@ AttributeChecker::visit (AST::StructPattern &)
// void AttributeChecker::visit(TupleStructItems& ){}
void
-AttributeChecker::visit (AST::TupleStructItemsNoRange &)
+AttributeChecker::visit (AST::TupleStructItemsNoRest &)
{}
void
-AttributeChecker::visit (AST::TupleStructItemsRange &)
+AttributeChecker::visit (AST::TupleStructItemsHasRest &)
{}
void
@@ -934,11 +984,11 @@ AttributeChecker::visit (AST::TupleStructPattern &)
// void AttributeChecker::visit(TuplePatternItems& ){}
void
-AttributeChecker::visit (AST::TuplePatternItemsMultiple &)
+AttributeChecker::visit (AST::TuplePatternItemsNoRest &)
{}
void
-AttributeChecker::visit (AST::TuplePatternItemsRanged &)
+AttributeChecker::visit (AST::TuplePatternItemsHasRest &)
{}
void
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index db8fe23..b10a080 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -29,6 +29,8 @@ class Attributes
{
public:
static bool is_known (const std::string &attribute_path);
+ static tl::optional<std::string>
+ extract_string_literal (const AST::Attribute &attr);
};
enum CompilerPass
@@ -104,13 +106,14 @@ private:
void check_attribute (const AST::Attribute &attribute);
/* Check the validity of all given attributes */
+
+ void check_inner_attributes (const AST::AttrVec &attributes);
void check_attributes (const AST::AttrVec &attributes);
// rust-ast.h
void visit (AST::Crate &crate) override;
void visit (AST::Token &tok) override;
void visit (AST::DelimTokenTree &delim_tok_tree) override;
- void visit (AST::AttrInputMetaItemContainer &input) override;
void visit (AST::IdentifierExpr &ident_expr) override;
void visit (AST::Lifetime &lifetime) override;
void visit (AST::LifetimeParam &lifetime_param) override;
@@ -203,7 +206,6 @@ private:
void visit (AST::Union &union_item) override;
void visit (AST::ConstantItem &const_item) override;
void visit (AST::StaticItem &static_item) override;
- void visit (AST::TraitItemConst &item) override;
void visit (AST::TraitItemType &item) override;
void visit (AST::Trait &trait) override;
void visit (AST::InherentImpl &impl) override;
@@ -219,7 +221,6 @@ private:
void visit (AST::MacroRulesDefinition &rules_def) override;
void visit (AST::MacroInvocation &macro_invoc) override;
void visit (AST::MetaItemPath &meta_item) override;
- void visit (AST::MetaItemSeq &meta_item) override;
void visit (AST::MetaWord &meta_item) override;
void visit (AST::MetaNameValueStr &meta_item) override;
void visit (AST::MetaListPaths &meta_item) override;
@@ -242,12 +243,12 @@ private:
void visit (AST::StructPatternFieldIdent &field) override;
void visit (AST::StructPattern &pattern) override;
// void visit(TupleStructItems& tuple_items) override;
- void visit (AST::TupleStructItemsNoRange &tuple_items) override;
- void visit (AST::TupleStructItemsRange &tuple_items) override;
+ void visit (AST::TupleStructItemsNoRest &tuple_items) override;
+ void visit (AST::TupleStructItemsHasRest &tuple_items) override;
void visit (AST::TupleStructPattern &pattern) override;
// void visit(TuplePatternItems& tuple_items) override;
- void visit (AST::TuplePatternItemsMultiple &tuple_items) override;
- void visit (AST::TuplePatternItemsRanged &tuple_items) override;
+ void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
+ void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
void visit (AST::TuplePattern &pattern) override;
void visit (AST::GroupedPattern &pattern) override;
void visit (AST::SlicePattern &pattern) override;
diff --git a/gcc/rust/util/rust-canonical-path.h b/gcc/rust/util/rust-canonical-path.h
index 079ae76..4c4d9df 100644
--- a/gcc/rust/util/rust-canonical-path.h
+++ b/gcc/rust/util/rust-canonical-path.h
@@ -114,6 +114,8 @@ public:
return CanonicalPath (other.segs, crate_num);
std::vector<std::pair<NodeId, std::string>> copy (segs);
+ copy.reserve (other.segs.size ());
+
for (auto &s : other.segs)
copy.push_back (s);
diff --git a/gcc/rust/util/rust-dump.h b/gcc/rust/util/rust-dump.h
index c2d9c4d..111174b 100644
--- a/gcc/rust/util/rust-dump.h
+++ b/gcc/rust/util/rust-dump.h
@@ -16,6 +16,8 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "rust-system.h"
+
// Common definitions useful for textual dump of IRs (AST and HIR).
#ifndef RUST_DUMP_H
diff --git a/gcc/rust/util/rust-ggc.cc b/gcc/rust/util/rust-ggc.cc
index 0722af2..46220a2 100644
--- a/gcc/rust/util/rust-ggc.cc
+++ b/gcc/rust/util/rust-ggc.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-ggc.h"
+#include "rust-ast.h"
#include "stringpool.h"
namespace Rust {
@@ -29,6 +30,8 @@ Ident::Ident (const std::string &str)
: inner (get_identifier_with_length (str.c_str (), str.length ()))
{}
+Ident::Ident (const Rust::Identifier &ident) : Ident (ident.as_string ()) {}
+
bool
Ident::operator== (const std::string &other) const
{
diff --git a/gcc/rust/util/rust-ggc.h b/gcc/rust/util/rust-ggc.h
index da28ede..da4ede1 100644
--- a/gcc/rust/util/rust-ggc.h
+++ b/gcc/rust/util/rust-ggc.h
@@ -24,6 +24,9 @@
namespace Rust {
+// forward declare
+class Identifier;
+
namespace GGC {
class Ident
@@ -33,6 +36,7 @@ class Ident
public:
Ident (const char *str);
Ident (const std::string &str);
+ Ident (const Rust::Identifier &ident);
bool operator== (const Ident &other) const { return inner == other.inner; }
bool operator== (const std::string &other) const;
diff --git a/gcc/rust/util/rust-inline-visitor.h b/gcc/rust/util/rust-inline-visitor.h
index 2a35aa6..a00cd2c 100644
--- a/gcc/rust/util/rust-inline-visitor.h
+++ b/gcc/rust/util/rust-inline-visitor.h
@@ -15,6 +15,7 @@
// 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-system.h"
// An improved implementation of the inline visitor.
// Original idea from https://members.accu.org/index.php/articles/2021
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 67a5d9c..7b9f498 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -21,6 +21,9 @@
#include "optional.h"
#include "bi-map.h"
+#ifndef RUST_LANG_ITEM_H
+#define RUST_LANG_ITEM_H
+
namespace Rust {
class LangItem
@@ -185,3 +188,5 @@ template <> struct hash<Rust::LangItem::Kind>
}
};
} // namespace std
+
+#endif // RUST_LANG_ITEM_H
diff --git a/gcc/rust/util/rust-token-converter.cc b/gcc/rust/util/rust-token-converter.cc
index 52172f4..0865bf9 100644
--- a/gcc/rust/util/rust-token-converter.cc
+++ b/gcc/rust/util/rust-token-converter.cc
@@ -102,7 +102,9 @@ ProcMacro::TokenStream
convert (const std::vector<const_TokenPtr> &tokens)
{
std::vector<ProcMacro::TokenStream> trees;
- trees.push_back (ProcMacro::TokenStream::make_tokenstream ());
+ trees.reserve (tokens.size ());
+
+ trees.emplace_back (ProcMacro::TokenStream::make_tokenstream ());
for (auto &token : tokens)
{
auto loc = convert (token->get_locus ());
diff --git a/gcc/rust/util/rust-unwrap-segment.h b/gcc/rust/util/rust-unwrap-segment.h
index af3a237..ccc1e61 100644
--- a/gcc/rust/util/rust-unwrap-segment.h
+++ b/gcc/rust/util/rust-unwrap-segment.h
@@ -16,6 +16,10 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "rust-system.h"
+#include "optional.h"
+#include "rust-lang-item.h"
+#include "rust-mapping-common.h"
#include <ast/rust-ast-full-decls.h>
namespace Rust {
@@ -115,4 +119,20 @@ unwrap_segment_get_lang_item (const std::unique_ptr<T> &ptr)
return unwrap_segment_get_lang_item (*ptr);
}
+/**
+ * Used to output a path in error messages
+ */
+
+inline static std::string
+unwrap_segment_error_string (const AST::TypePath &path)
+{
+ return path.make_debug_string ();
+}
+
+inline static std::string
+unwrap_segment_error_string (const AST::PathInExpression &path)
+{
+ return path.as_simple_path ().as_string ();
+}
+
} // namespace Rust