aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/ChangeLog478
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc8
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc4
-rw-r--r--gcc/rust/ast/rust-ast-visitor.cc16
-rw-r--r--gcc/rust/ast/rust-ast.cc23
-rw-r--r--gcc/rust/ast/rust-ast.h21
-rw-r--r--gcc/rust/ast/rust-desugar-for-loops.cc4
-rw-r--r--gcc/rust/ast/rust-expr.h72
-rw-r--r--gcc/rust/ast/rust-item.h23
-rw-r--r--gcc/rust/ast/rust-type.h10
-rw-r--r--gcc/rust/backend/rust-compile-base.cc22
-rw-r--r--gcc/rust/backend/rust-compile-base.h6
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc3
-rw-r--r--gcc/rust/backend/rust-compile-extern.h6
-rw-r--r--gcc/rust/backend/rust-compile-implitem.cc2
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h6
-rw-r--r--gcc/rust/backend/rust-compile-item.cc6
-rw-r--r--gcc/rust/backend/rust-compile-item.h4
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc15
-rw-r--r--gcc/rust/backend/rust-compile.cc2
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.cc3
-rw-r--r--gcc/rust/checks/errors/rust-feature-gate.cc7
-rw-r--r--gcc/rust/checks/errors/rust-feature.cc4
-rw-r--r--gcc/rust/checks/errors/rust-feature.h1
-rw-r--r--gcc/rust/expand/rust-derive-clone.cc5
-rw-r--r--gcc/rust/expand/rust-derive-debug.cc3
-rw-r--r--gcc/rust/expand/rust-derive-default.cc3
-rw-r--r--gcc/rust/expand/rust-derive-eq.cc3
-rw-r--r--gcc/rust/expand/rust-macro-builtins-format-args.cc7
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc2
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc21
-rw-r--r--gcc/rust/expand/rust-token-tree-desugar.cc72
-rw-r--r--gcc/rust/expand/rust-token-tree-desugar.h55
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc8
-rw-r--r--gcc/rust/hir/rust-ast-lower-block.h4
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.cc21
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.cc29
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.cc5
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc11
-rw-r--r--gcc/rust/hir/rust-hir-dump.cc6
-rw-r--r--gcc/rust/hir/tree/rust-hir-bound.h12
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.cc24
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h51
-rw-r--r--gcc/rust/hir/tree/rust-hir-generic-param.h3
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.cc28
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h61
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.cc2
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.h9
-rw-r--r--gcc/rust/hir/tree/rust-hir.cc106
-rw-r--r--gcc/rust/parse/rust-parse-impl.h189
-rw-r--r--gcc/rust/parse/rust-parse.h45
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h5
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.cc14
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h19
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.cc2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h20
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h32
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc2
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc7
-rw-r--r--gcc/rust/resolve/rust-forever-stack.h7
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx79
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc53
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.h4
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h41
-rw-r--r--gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc12
-rw-r--r--gcc/rust/rust-gcc.cc260
-rw-r--r--gcc/rust/rust-session-manager.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc12
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc44
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h8
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc138
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.cc205
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.cc21
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc44
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h11
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc35
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.cc27
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h2
-rw-r--r--gcc/rust/typecheck/rust-type-util.cc37
-rw-r--r--gcc/rust/typecheck/rust-typecheck-context.cc11
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.cc8
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.h6
-rw-r--r--gcc/rust/typecheck/rust-tyty-variance-analysis.cc2
-rw-r--r--gcc/rust/util/expected.h4
-rw-r--r--gcc/rust/util/rust-attribute-values.h27
-rw-r--r--gcc/rust/util/rust-attributes.cc22
-rw-r--r--gcc/rust/util/rust-attributes.h7
-rw-r--r--gcc/rust/util/rust-lang-item.cc1
-rw-r--r--gcc/rust/util/rust-lang-item.h2
92 files changed, 1836 insertions, 933 deletions
diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog
index 31c731b..453b9f7 100644
--- a/gcc/rust/ChangeLog
+++ b/gcc/rust/ChangeLog
@@ -1,3 +1,481 @@
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-lang-item.h: Add new manually_drop lang item.
+ * util/rust-lang-item.cc: Likewise.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-attribute-values.h: Add RUSTFMT value.
+ * util/rust-attributes.cc: Define the attribute.
+ * util/rust-attributes.h (enum CompilerPass): Add EXTERNAL variant.
+ * expand/rust-macro-builtins.cc: Fix formatting.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-early-name-resolver-2.0.cc (Early::visit_attributes): Remove assertion.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-attribute-values.h: Add missing attributes.
+ * util/rust-attributes.cc: Likewise.
+ * util/rust-attributes.h (enum CompilerPass): Mention adding something for const
+ functions.
+
+2025-04-14 beamandala <mandalapubhavesh@gmail.com>
+
+ * expand/rust-macro-builtins.cc (MacroBuiltin::builtin_transcribers):
+ Add entry for track_caller.
+ * util/rust-attribute-values.h: add `TRACK_CALLER` attribute.
+ * util/rust-attributes.cc: add `track_caller` attribute definition.
+
+2025-04-14 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/rust-const-checker.cc
+ (ConstChecker::visit): Visit the enum items of enums.
+ * resolve/rust-ast-resolve-item.cc
+ (ResolveItem::visit): Resolve enum discriminants during nr1.0.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-macro-builtins-format-args.cc (format_args_parse_arguments): Improve safety,
+ allow extra commas after end of argument list.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-macro-expand.cc (MacroExpander::expand_decl_macro): Call into
+ TokenTreeDesugar.
+ * expand/rust-token-tree-desugar.cc: New file.
+ * expand/rust-token-tree-desugar.h: New file.
+ * Make-lang.in: Compile them.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * expand/rust-macro-expand.cc (MacroExpander::match_n_matches): Do not
+ insert fragments and substack fragments if the matcher failed.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * rust-session-manager.cc (Session::compile_crate): Call the visitor later in the pipeline.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast.h (DelimTokenTree::get_locus): New function.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-expr.h (class RangeExpr): Add empty outer attributes and allow getting them
+ and setting them.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Return if module
+ is unloaded.
+
+2025-04-14 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * typecheck/rust-hir-type-check-expr.cc (is_default_fn): New.
+ (emit_ambiguous_resolution_error): New.
+ (handle_multiple_candidates): Properly handle multiple candidates in
+ the case of specialization.
+ (TypeCheckExpr::visit): Call `handle_multiple_candidates`.
+
+2025-04-14 Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR rust/119342
+ * rust-gcc.cc (block): Add comment on why chaining
+ the variables of the scope toether.
+
+2025-04-14 Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR rust/119341
+ * rust-gcc.cc (function_type): Use range fors.
+ (function_type_variadic): Likewise.
+ (fill_in_fields): Likewise.
+ (statement_list): Likewise.
+ (block): Likewise.
+ (block_add_statements): Likewise.
+ (function_set_parameters): Likewise.
+ (write_global_definitions): Likewise.
+
+2025-04-14 Andrew Pinski <quic_apinski@quicinc.com>
+
+ * rust-gcc.cc (Bvariable::get_tree): Use error_operand_p.
+ (pointer_type): Likewise.
+ (reference_type): Likewise.
+ (immutable_type): Likewise.
+ (function_type): Likewise.
+ (function_type_variadic): Likewise.
+ Cleanup the check for receiver.type first.
+ (function_ptr_type): Use error_operand_p.
+ (fill_in_fields): Likewise.
+ (fill_in_array): Likewise.
+ (named_type): Likewise.
+ (type_size): Likewise.
+ (type_alignment): Likewise.
+ (type_field_alignment): Likewise.
+ (type_field_offset): Likewise.
+ (zero_expression): Likewise.
+ (float_constant_expression): Likewise.
+ (convert_expression): Likewise.
+ (struct_field_expression): Likewise.
+ (compound_expression): Likewise.
+ (conditional_expression): Likewise.
+ (negation_expression): Likewise.
+ (arithmetic_or_logical_expression): Likewise.
+ (arithmetic_or_logical_expression_checked): Likewise.
+ (comparison_expression): Likewise.
+ (lazy_boolean_expression): Likewise.
+ (constructor_expression): Likewise.
+ (array_constructor_expression): Likewise.
+ (array_index_expression): Likewise.
+ (call_expression): Likewise.
+ (init_statement): Likewise.
+ (assignment_statement): Likewise.
+ (return_statement): Likewise.
+ (exception_handler_statement): Likewise.
+ (if_statement): Likewise.
+ (compound_statement): Likewise.
+ Tighten up the code, removing t variable.
+ (statement_list): Use error_operand_p.
+ (block): Likewise.
+ (block_add_statements): Likewise.
+ (convert_tree): Likewise.
+ (global_variable): Likewise.
+ (global_variable_set_init): Likewise.
+ (local_variable): Likewise.
+ (parameter_variable): Likewise.
+ (static_chain_variable): Likewise.
+ (temporary_variable): Likewise.
+ (function): Likewise. Tighten up the code.
+ (function_defer_statement): Use error_operand_p.
+ (function_set_parameters): Use error_operand_p.
+ (write_global_definitions): Use error_operand_p.
+ Tighten up the code around the loop.
+
+2025-04-14 Andrew Pinski <quic_apinski@quicinc.com>
+
+ * rust-gcc.cc (is_floating_point): Use FLOAT_TYPE_P
+ instead of manually checking the type.
+
+2025-04-08 Matty Kuhn <matty.kuhn.1@gmail.com>
+
+ * ast/rust-ast.h: (AST::Attribute): add empty_input function
+ * checks/errors/rust-feature-gate.cc: (FeatureGate::visit): check for empty feature gate
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit): Update label
+ getter call.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
+ * ast/rust-ast.cc (BreakExpr::as_string): Likewise.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
+ * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Likewise.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise.
+ * ast/rust-expr.h: Add optional getter and rename label getter to
+ get_label_unchecked.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-collector.cc (TokenCollector::visit):
+ Call unchecked getter.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit):
+ Likewise.
+ * ast/rust-ast.cc (ContinueExpr::as_string): Likewise.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
+ * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Likewise.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise.
+ * ast/rust-expr.h: Add new getter for the optional and rename getter
+ to get_label_unchecked.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_loop_label): Change function
+ return type to expected.
+ (Parser::parse_labelled_loop_expr): Adapt call location to new return
+ type.
+ * parse/rust-parse.h (enum class): Update function prototype.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add call
+ to label resolution if there is one label.
+ (Late::resolve_label): Look for labels and emit an error message on
+ failure.
+ * resolve/rust-late-name-resolver-2.0.h: Add function prototypes.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit):
+ Change error message to match rustc.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::self_ref_param): Remove error state
+ and use optional.
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Check label
+ before visiting.
+ * ast/rust-ast.cc (ContinueExpr::as_string): Retrieve label value.
+ (Lifetime::as_string): Retrieve lifetime value.
+ (ReferenceType::as_string): Likewise.
+ (SelfParam::as_string): Likewise.
+ * ast/rust-ast.h: Remove lifetime and LifetimeParam error state.
+ * ast/rust-desugar-for-loops.cc (DesugarForLoops::DesugarCtx::make_break_arm):
+ Use optional instead of error state.
+ * ast/rust-expr.h (class ContinueExpr): Make label optional.
+ * ast/rust-item.h (class SelfParam): Make lifetime optional.
+ * ast/rust-type.h (class ReferenceType): Likewise.
+ * backend/rust-compile-base.cc: Use optional for self param instead
+ of error state.
+ * backend/rust-compile-base.h: Update function prototype.
+ * expand/rust-derive-clone.cc (DeriveClone::clone_fn): Use optional.
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_self): Lower
+ lifetime only if it exists.
+ * hir/rust-ast-lower-block.h: Lower loop label only if it exists.
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
+ * hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): Remove
+ references to error state.
+ (ASTLowerTraitItem::visit): Lower self param only if it exists.
+ * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Use nullopt
+ for default value instead of SelfParam error state.
+ * hir/rust-ast-lower.cc (ASTLoweringExprWithBlock::visit): Lower label
+ only if it exists.
+ * hir/rust-hir-dump.cc (Dump::do_traitfunctiondecl): Print self only if
+ it exists.
+ (Dump::visit): Liewise.
+ * hir/tree/rust-hir-bound.h: Remove error state.
+ * hir/tree/rust-hir-expr.cc (ContinueExpr::ContinueExpr): Use optional
+ in constructor for loop label.
+ (BreakExpr::BreakExpr): Likewise.
+ * hir/tree/rust-hir-expr.h (class ContinueExpr): Remove error state
+ implementation.
+ (class BreakExpr): Likewise.
+ * hir/tree/rust-hir-generic-param.h: Likewise.
+ * hir/tree/rust-hir-item.cc (SelfParam::SelfParam): Make lifetime
+ optional.
+ (Function::Function): Make self param optional.
+ * hir/tree/rust-hir-item.h (class Function): Likewise.
+ * hir/tree/rust-hir-type.cc (ReferenceType::ReferenceType): Make
+ lifetime optional.
+ * hir/tree/rust-hir-type.h (class ReferenceType): Likewise.
+ * hir/tree/rust-hir.cc (ContinueExpr::as_string): Use new getter.
+ (BreakExpr::as_string): Likewise.
+ (Lifetime::as_string): Likewise.
+ (ReferenceType::as_string): Likewise.
+ (TraitFunctionDecl::as_string): Likewise.
+ (SelfParam::as_string): Remove error state checking.
+ * parse/rust-parse-impl.h (Parser::parse_generic_param): Adapt to
+ optional.
+ (Parser::parse_lifetime_params): Likewise.
+ (Parser::parse_lifetime_params_objs): Likewise.
+ (Parser::parse_lifetime_param): Likewise.
+ (Parser::parse_lifetime_where_clause_item): Likewise.
+ (Parser::parse_type_param_bound): Likewise.
+ (Parser::parse_lifetime_bounds): Likewise.
+ (Parser::parse_path_generic_args): Likewise.
+ (Parser::parse_self_param): Likewise.
+ (Parser::parse_break_expr): Likewise.
+ (Parser::parse_continue_expr): Likewise.
+ (Parser::parse_reference_type_inner): Likewise.
+ * parse/rust-parse.h (class ParseLifetimeParamError): Add new class for
+ lifetime param parsing errors.
+ (class ParseLifetimeError): Add new class for lifetime parsing errors.
+ (enum ParseSelfError): Add new class for self param parsing errors.
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItem::visit):
+ Use unchecked getter in checked context. And make anonymous region.
+ * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn):
+ Likewise.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Add
+ check for loop label before visiting it.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-expr.h: Remove error getter and constructor.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-builder.cc (Builder::block): Call with a nullopt instead
+ of an error loop label.
+ (WhileLetLoopExpr::as_string): Use getter function and adapt to
+ newtype.
+ * ast/rust-ast.cc (WhileLoopExpr::as_string): Likewise.
+ (LoopExpr::as_string): Likewise.
+ (BreakExpr::as_string): Likewise.
+ (ForLoopExpr::as_string): Likewise.
+ * ast/rust-expr.h (class BlockExpr): Make loop label optional.
+ (class BreakExpr): Likewise.
+ * expand/rust-derive-clone.cc (DeriveClone::clone_fn): Use nullopt.
+ * expand/rust-derive-debug.cc (DeriveDebug::stub_debug_fn): Likewise.
+ * expand/rust-derive-default.cc (DeriveDefault::default_fn): Likewise.
+ * expand/rust-derive-eq.cc: Likewise.
+ * parse/rust-parse-impl.h (Parser::parse_block_expr): Use optional
+ for arguments.
+ (Parser::parse_loop_expr): Likewise.
+ (Parser::parse_while_loop_expr): Likewise.
+ (Parser::parse_while_let_loop_expr): Likewise.
+ (Parser::parse_for_loop_expr): Likewise.
+ (Parser::parse_labelled_loop_expr): Likewise.
+ (Parser::parse_loop_label): Return an optional.
+ * parse/rust-parse.h: Update function prototype and use nullopt for
+ default values.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Change default
+ visit order.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Visit loop label
+ only if it exists.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * hir/rust-ast-lower.cc (ASTLoweringBlock::visit): Lower label only if
+ it exists.
+ * hir/tree/rust-hir-expr.cc (BlockExpr::BlockExpr): Make loop label
+ optional.
+ (BaseLoopExpr::BaseLoopExpr): Likewise.
+ (LoopExpr::LoopExpr): Likewise.
+ (WhileLoopExpr::WhileLoopExpr): Likewise.
+ * hir/tree/rust-hir-expr.h: Use optional for lifetime and labels.
+ * hir/tree/rust-hir.cc (WhileLoopExpr::as_string): Use getter.
+ (WhileLetLoopExpr::as_string): Likewise.
+ (LoopExpr::as_string): Likewise.
+ * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Resolve labels.
+ * resolve/rust-late-name-resolver-2.0.h: Add visit function prototype
+ for loop labels.
+
+2025-04-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * util/expected.h: Use gcc_unreachable within gcc context.
+
+2025-04-08 Sri Ganesh Thota <sriganeshthota12345@gmail.com>
+
+ * resolve/rust-ast-resolve-base.h (redefined_error): created a function for
+ rust_error_at for redefined at multiple times.
+ * resolve/rust-ast-resolve-implitem.h: changed rust_error_at to redefined_error.
+ * resolve/rust-ast-resolve-stmt.cc (ResolveStmt::visit): changed rust_error_at to
+ redefined_error.
+ * resolve/rust-ast-resolve-stmt.h: changed rust_error_at to redefined_error.
+ * resolve/rust-ast-resolve-toplevel.h: changed rust_error_at to redefined_error.
+
+2025-04-08 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-ast-visitor.cc
+ (DefaultASTVisitor::visit): Remove explicit visitation of a
+ function's self parameter, as if it exists it'll be visited as
+ one of the function parameters.
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-typecheck-context.cc (TypeCheckContext::lookup_lifetime): emit error
+
+2025-04-08 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast.cc (Function::Function): Rename is_default -> has_default.
+ (Function::operator=): Likewise.
+ * ast/rust-item.h (class Function): Add `is_default` method.
+ * hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): Lower default qualifier.
+ * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Likewise.
+ * hir/tree/rust-hir-item.cc (Function::Function): Add `is_default` member.
+ (Function::operator=): Likewise.
+ * hir/tree/rust-hir-item.h (enum class Defaultness): New enum.
+ (class Function): Use it.
+
+2025-04-08 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * checks/errors/rust-feature.cc (Feature::create): Handle `#![feature(min_specialization)]`.
+ * checks/errors/rust-feature.h: Likewise.
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): fix error msg
+ * typecheck/rust-substitution-mapper.cc (SubstMapper::Resolve): add validation
+ (SubstMapper::valid_type): new check
+ (SubstMapper::visit): check if can resolve
+ * typecheck/rust-substitution-mapper.h: new prototype
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-base.cc (HIRCompileBase::address_expression): allow optional type
+ * backend/rust-compile-base.h: update prototype
+ * backend/rust-compile-expr.cc (CompileExpr::visit): update borrow expr
+ * backend/rust-compile-extern.h: remove unused debug
+ * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): update usage
+ * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): lower raw ref
+ * hir/tree/rust-hir-expr.cc (BorrowExpr::BorrowExpr): add flag for raw ref
+ * hir/tree/rust-hir-expr.h (class BorrowExpr): add new raw ref field
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): add handle for raw ref
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): emit error
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): new argument
+ * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::TypeCheckBase): new helper
+ * typecheck/rust-hir-type-check-base.h: new helper prototype
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit):
+ remove comment out code
+ * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_root_path): check for null
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path): likewise
+ (TypeResolveGenericParam::Resolve): new args
+ (TypeResolveGenericParam::ApplyAnyTraitBounds): new helper
+ (TypeResolveGenericParam::apply_trait_bounds): new field
+ (TypeResolveGenericParam::visit): update
+ * typecheck/rust-hir-type-check-type.h: new args
+ * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn): reuse helper
+ * typecheck/rust-type-util.cc (query_type): check for recursive query
+ * typecheck/rust-tyty-subst.cc (SubstitutionParamMapping::SubstitutionParamMapping):
+ remove const
+ (SubstitutionParamMapping::get_generic_param): likewise
+ * typecheck/rust-tyty-subst.h: likewise
+ * typecheck/rust-tyty-variance-analysis.cc (GenericTyVisitorCtx::process_type): likewise
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-base.cc: new flag is_root_item
+ * backend/rust-compile-base.h: update prototype
+ * backend/rust-compile-implitem.cc (CompileTraitItem::visit): update call
+ * backend/rust-compile-implitem.h: remove old debug internal error
+ * backend/rust-compile-item.cc (CompileItem::visit): update call
+ * backend/rust-compile-item.h: remove old debug
+ * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): update calls
+ * backend/rust-compile.cc: likewise
+ * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_path_to_trait):
+ remove assertion and error
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-base.cc: remove assertion
+
+2025-04-08 Philip Herron <herron.philip@googlemail.com>
+
+ * rust-gcc.cc (arithmetic_or_logical_expression): unwrap const decls
+
+2025-04-08 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * resolve/rust-forever-stack.h
+ (ForeverStack::ForeverStack): Initialize extern_prelude.
+ (ForeverStack::resolve_path): Add parameter
+ has_opening_scope_resolution.
+ (ForeverStack::extern_prelude): Add field.
+ * resolve/rust-forever-stack.hxx: Include rust-edition.h.
+ (ForeverStacl::resolve_path): Handle global paths (paths with an
+ opening scope resolution operator).
+ * resolve/rust-late-name-resolver-2.0.cc
+ (Late::visit): Handle global paths.
+ * resolve/rust-name-resolution-context.h
+ (NameResolutionContext::resolve_path): Handle global paths.
+
+2025-04-08 Ryutaro Okada <1015ryu88@gmail.com>
+
+ * backend/rust-compile-resolve-path.cc: Evaluate the enum's discriminant in a const context
+
2025-03-31 Philip Herron <herron.philip@googlemail.com>
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path):
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 4028b47..835e113 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -115,6 +115,7 @@ GRS_OBJS = \
rust/rust-macro-builtins-format-args.o \
rust/rust-macro-builtins-location.o \
rust/rust-macro-builtins-include.o \
+ rust/rust-token-tree-desugar.o \
rust/rust-fmt.o \
rust/rust-hir.o \
rust/rust-hir-map.o \
diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index cdc6eec..08c52b1 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -137,7 +137,7 @@ Builder::tuple (std::vector<std::unique_ptr<Expr>> &&values) const
std::unique_ptr<Param>
Builder::self_ref_param (bool mutability) const
{
- return std::make_unique<SelfParam> (Lifetime::error (), mutability, loc);
+ return std::make_unique<SelfParam> (tl::nullopt, mutability, loc);
}
std::unique_ptr<Param>
@@ -335,9 +335,9 @@ std::unique_ptr<BlockExpr>
Builder::block (std::vector<std::unique_ptr<Stmt>> &&stmts,
std::unique_ptr<Expr> &&tail_expr) const
{
- return std::unique_ptr<BlockExpr> (
- new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {},
- LoopLabel::error (), loc, loc));
+ return std::unique_ptr<BlockExpr> (new BlockExpr (std::move (stmts),
+ std::move (tail_expr), {},
+ {}, tl::nullopt, loc, loc));
}
std::unique_ptr<Expr>
diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index 3297407..8ee6375 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1279,7 +1279,7 @@ TokenCollector::visit (ContinueExpr &expr)
{
push (Rust::Token::make (CONTINUE, expr.get_locus ()));
if (expr.has_label ())
- visit (expr.get_label ());
+ visit (expr.get_label_unchecked ());
}
void
@@ -1287,7 +1287,7 @@ TokenCollector::visit (BreakExpr &expr)
{
push (Rust::Token::make (BREAK, expr.get_locus ()));
if (expr.has_label ())
- visit (expr.get_label ());
+ visit (expr.get_label_unchecked ());
if (expr.has_break_expr ())
visit (expr.get_break_expr ());
}
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index ba5f87b..9d524c3 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -477,7 +477,8 @@ void
DefaultASTVisitor::visit (AST::ContinueExpr &expr)
{
visit_outer_attrs (expr);
- visit (expr.get_label ());
+ if (expr.has_label ())
+ visit (expr.get_label_unchecked ());
}
void
@@ -485,7 +486,7 @@ DefaultASTVisitor::visit (AST::BreakExpr &expr)
{
visit_outer_attrs (expr);
if (expr.has_label ())
- visit (expr.get_label ());
+ visit (expr.get_label_unchecked ());
if (expr.has_break_expr ())
visit (expr.get_break_expr ());
@@ -559,7 +560,8 @@ void
DefaultASTVisitor::visit (AST::LoopExpr &expr)
{
visit_outer_attrs (expr);
- visit (expr.get_loop_label ());
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
visit (expr.get_loop_block ());
}
@@ -567,8 +569,9 @@ void
DefaultASTVisitor::visit (AST::WhileLoopExpr &expr)
{
visit_outer_attrs (expr);
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
visit (expr.get_predicate_expr ());
- visit (expr.get_loop_label ());
visit (expr.get_loop_block ());
}
@@ -589,7 +592,8 @@ DefaultASTVisitor::visit (AST::ForLoopExpr &expr)
visit_outer_attrs (expr);
visit (expr.get_pattern ());
visit (expr.get_iterator_expr ());
- visit (expr.get_loop_label ());
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
visit (expr.get_loop_block ());
}
@@ -824,8 +828,6 @@ DefaultASTVisitor::visit (AST::Function &function)
visit (function.get_qualifiers ());
for (auto &generic : function.get_generic_params ())
visit (generic);
- if (function.has_self_param ())
- visit (function.get_self_param ());
for (auto &param : function.get_function_params ())
visit (param);
if (function.has_return_type ())
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index ab82303..06e0e7b 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -1068,7 +1068,7 @@ Function::Function (Function const &other)
: VisItem (other), ExternalItem (other.get_node_id ()),
qualifiers (other.qualifiers), function_name (other.function_name),
where_clause (other.where_clause), locus (other.locus),
- is_default (other.is_default),
+ has_default (other.has_default),
is_external_function (other.is_external_function)
{
// guard to prevent null dereference (always required)
@@ -1100,7 +1100,7 @@ Function::operator= (Function const &other)
// visibility = other.visibility->clone_visibility();
// outer_attrs = other.outer_attrs;
locus = other.locus;
- is_default = other.is_default;
+ has_default = other.has_default;
is_external_function = other.is_external_function;
// guard to prevent null dereference (always required)
@@ -1631,7 +1631,7 @@ ContinueExpr::as_string () const
std::string str ("continue ");
if (has_label ())
- str += label.as_string ();
+ str += get_label_unchecked ().as_string ();
return str;
}
@@ -2095,7 +2095,7 @@ WhileLoopExpr::as_string () const
if (!has_loop_label ())
str += "none";
else
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
str += "\n Conditional expr: " + condition->as_string ();
@@ -2115,7 +2115,7 @@ WhileLetLoopExpr::as_string () const
if (!has_loop_label ())
str += "none";
else
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
str += "\n Match arm patterns: ";
if (match_arm_patterns.empty ())
@@ -2146,7 +2146,7 @@ LoopExpr::as_string () const
if (!has_loop_label ())
str += "none";
else
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
str += "\n Loop block: " + loop_block->as_string ();
@@ -2183,7 +2183,7 @@ BreakExpr::as_string () const
std::string str ("break ");
if (has_label ())
- str += label.as_string () + " ";
+ str += get_label_unchecked ().as_string () + " ";
if (has_break_expr ())
str += break_expr->as_string ();
@@ -2485,9 +2485,6 @@ MacroMatchRepetition::as_string () const
std::string
Lifetime::as_string () const
{
- if (is_error ())
- return "error lifetime";
-
switch (lifetime_type)
{
case NAMED:
@@ -2545,7 +2542,7 @@ ForLoopExpr::as_string () const
if (!has_loop_label ())
str += "none";
else
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
str += "\n Pattern: " + pattern->as_string ();
@@ -2612,7 +2609,7 @@ ReferenceType::as_string () const
std::string str ("&");
if (has_lifetime ())
- str += lifetime.as_string () + " ";
+ str += get_lifetime ().as_string () + " ";
if (has_mut)
str += "mut ";
@@ -3070,7 +3067,7 @@ SelfParam::as_string () const
else if (has_lifetime ())
{
// ref and lifetime
- std::string str = "&" + lifetime.as_string () + " ";
+ std::string str = "&" + get_lifetime ().as_string () + " ";
if (is_mut)
str += "mut ";
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 4d7d23d..91611ec 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -657,6 +657,9 @@ public:
// Returns whether the attribute is considered an "empty" attribute.
bool is_empty () const { return attr_input == nullptr && path.is_empty (); }
+ // Returns whether the attribute has no input
+ bool empty_input () const { return !attr_input; }
+
location_t get_locus () const { return locus; }
AttrInput &get_attr_input () const { return *attr_input; }
@@ -1015,6 +1018,7 @@ public:
}
DelimType get_delim_type () const { return delim_type; }
+ location_t get_locus () const { return locus; }
};
/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
@@ -1587,17 +1591,9 @@ public:
lifetime_name (std::move (name)), locus (locus)
{}
- // Creates an "error" lifetime.
- static Lifetime error () { return Lifetime (NAMED, ""); }
-
static Lifetime elided () { return Lifetime (WILDCARD, ""); }
// Returns true if the lifetime is in an error state.
- bool is_error () const
- {
- return lifetime_type == NAMED && lifetime_name.empty ();
- }
-
std::string as_string () const override;
void accept_vis (ASTVisitor &vis) override;
@@ -1688,15 +1684,6 @@ public:
// Returns whether the lifetime param has an outer attribute.
bool has_outer_attribute () const { return !outer_attrs.empty (); }
- // Creates an error state lifetime param.
- static LifetimeParam create_error ()
- {
- return LifetimeParam (Lifetime::error (), {}, {}, UNDEF_LOCATION);
- }
-
- // Returns whether the lifetime param is in an error state.
- bool is_error () const { return lifetime.is_error (); }
-
// Constructor
LifetimeParam (Lifetime lifetime, std::vector<Lifetime> lifetime_bounds,
AST::AttrVec outer_attrs, location_t locus)
diff --git a/gcc/rust/ast/rust-desugar-for-loops.cc b/gcc/rust/ast/rust-desugar-for-loops.cc
index 5e5cbbc..ffc3470 100644
--- a/gcc/rust/ast/rust-desugar-for-loops.cc
+++ b/gcc/rust/ast/rust-desugar-for-loops.cc
@@ -59,8 +59,8 @@ DesugarForLoops::DesugarCtx::make_break_arm ()
auto arm = make_match_arm (std::unique_ptr<Pattern> (new PathInExpression (
builder.path_in_expression (LangItem::Kind::OPTION_NONE))));
- auto break_expr = std::unique_ptr<Expr> (
- new BreakExpr (Lifetime::error (), nullptr, {}, loc));
+ auto break_expr
+ = std::unique_ptr<Expr> (new BreakExpr (tl::nullopt, nullptr, {}, loc));
return MatchCase (std::move (arm), std::move (break_expr));
}
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index cff09fe..69538df 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -31,11 +31,6 @@ public:
{}
// Returns whether the LoopLabel is in an error state.
- bool is_error () const { return label.is_error (); }
-
- // Creates an error state LoopLabel.
- static LoopLabel error () { return LoopLabel (Lifetime::error ()); }
-
location_t get_locus () const { return locus; }
Lifetime &get_lifetime () { return label; }
@@ -2590,7 +2585,7 @@ class BlockExpr : public ExprWithBlock
std::vector<Attribute> inner_attrs;
std::vector<std::unique_ptr<Stmt> > statements;
std::unique_ptr<Expr> expr;
- LoopLabel label;
+ tl::optional<LoopLabel> label;
location_t start_locus;
location_t end_locus;
bool marked_for_strip = false;
@@ -2607,8 +2602,9 @@ public:
BlockExpr (std::vector<std::unique_ptr<Stmt> > block_statements,
std::unique_ptr<Expr> block_expr,
std::vector<Attribute> inner_attribs,
- std::vector<Attribute> outer_attribs, LoopLabel label,
- location_t start_locus, location_t end_locus)
+ std::vector<Attribute> outer_attribs,
+ tl::optional<LoopLabel> label, location_t start_locus,
+ location_t end_locus)
: outer_attrs (std::move (outer_attribs)),
inner_attrs (std::move (inner_attribs)),
statements (std::move (block_statements)), expr (std::move (block_expr)),
@@ -2727,8 +2723,8 @@ public:
outer_attrs = std::move (new_attrs);
}
- bool has_label () { return !label.is_error (); }
- LoopLabel &get_label () { return label; }
+ bool has_label () { return label.has_value (); }
+ LoopLabel &get_label () { return label.value (); }
Expr::Kind get_expr_kind () const override { return Expr::Kind::Block; }
@@ -2848,7 +2844,7 @@ protected:
class ContinueExpr : public ExprWithoutBlock
{
std::vector<Attribute> outer_attrs;
- Lifetime label;
+ tl::optional<Lifetime> label;
location_t locus;
// TODO: find another way to store this to save memory?
@@ -2858,11 +2854,11 @@ public:
std::string as_string () const override;
// Returns true if the continue expr has a label.
- bool has_label () const { return !label.is_error (); }
+ bool has_label () const { return label.has_value (); }
// Constructor for a ContinueExpr with a label.
- ContinueExpr (Lifetime label, std::vector<Attribute> outer_attribs,
- location_t locus)
+ ContinueExpr (tl::optional<Lifetime> label,
+ std::vector<Attribute> outer_attribs, location_t locus)
: outer_attrs (std::move (outer_attribs)), label (std::move (label)),
locus (locus)
{}
@@ -2883,7 +2879,11 @@ public:
outer_attrs = std::move (new_attrs);
}
- Lifetime &get_label () { return label; }
+ Lifetime &get_label_unchecked () { return label.value (); }
+ const Lifetime &get_label_unchecked () const { return label.value (); }
+
+ tl::optional<Lifetime> &get_label () { return label; }
+ const tl::optional<Lifetime> &get_label () const { return label; }
Expr::Kind get_expr_kind () const override { return Expr::Kind::Continue; }
@@ -2901,7 +2901,7 @@ protected:
class BreakExpr : public ExprWithoutBlock
{
std::vector<Attribute> outer_attrs;
- LoopLabel label;
+ tl::optional<LoopLabel> label;
std::unique_ptr<Expr> break_expr;
location_t locus;
@@ -2912,14 +2912,15 @@ public:
std::string as_string () const override;
// Returns whether the break expression has a label or not.
- bool has_label () const { return !label.is_error (); }
+ bool has_label () const { return label.has_value (); }
/* Returns whether the break expression has an expression used in the break or
* not. */
bool has_break_expr () const { return break_expr != nullptr; }
// Constructor for a break expression
- BreakExpr (LoopLabel break_label, std::unique_ptr<Expr> expr_in_break,
+ BreakExpr (tl::optional<LoopLabel> break_label,
+ std::unique_ptr<Expr> expr_in_break,
std::vector<Attribute> outer_attribs, location_t locus)
: outer_attrs (std::move (outer_attribs)), label (std::move (break_label)),
break_expr (std::move (expr_in_break)), locus (locus)
@@ -2981,7 +2982,11 @@ public:
outer_attrs = std::move (new_attrs);
}
- LoopLabel &get_label () { return label; }
+ LoopLabel &get_label_unchecked () { return label.value (); }
+ const LoopLabel &get_label_unchecked () const { return label.value (); }
+
+ tl::optional<LoopLabel> &get_label () { return label; }
+ const tl::optional<LoopLabel> &get_label () const { return label; }
Expr::Kind get_expr_kind () const override { return Expr::Kind::Break; }
@@ -2999,6 +3004,10 @@ class RangeExpr : public ExprWithoutBlock
{
location_t locus;
+ // Some visitors still check for attributes on RangeExprs, and they will need
+ // to be supported in the future - so keep that for now
+ std::vector<Attribute> empty_attributes = {};
+
protected:
// outer attributes not allowed before range expressions
RangeExpr (location_t locus) : locus (locus) {}
@@ -3008,15 +3017,11 @@ public:
std::vector<Attribute> &get_outer_attrs () override final
{
- // RangeExpr cannot have any outer attributes
- rust_assert (false);
+ return empty_attributes;
}
// should never be called - error if called
- void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override
- {
- rust_assert (false);
- }
+ void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override {}
Expr::Kind get_expr_kind () const override { return Expr::Kind::Range; }
};
@@ -3657,7 +3662,7 @@ class BaseLoopExpr : public ExprWithBlock
protected:
// protected to allow subclasses better use of them
std::vector<Attribute> outer_attrs;
- LoopLabel loop_label;
+ tl::optional<LoopLabel> loop_label;
std::unique_ptr<BlockExpr> loop_block;
private:
@@ -3666,7 +3671,7 @@ private:
protected:
// Constructor for BaseLoopExpr
BaseLoopExpr (std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs
= std::vector<Attribute> ())
: outer_attrs (std::move (outer_attribs)),
@@ -3706,9 +3711,10 @@ protected:
BaseLoopExpr &operator= (BaseLoopExpr &&other) = default;
public:
- bool has_loop_label () const { return !loop_label.is_error (); }
+ bool has_loop_label () const { return loop_label.has_value (); }
- LoopLabel &get_loop_label () { return loop_label; }
+ LoopLabel &get_loop_label () { return loop_label.value (); }
+ const LoopLabel &get_loop_label () const { return loop_label.value (); }
location_t get_locus () const override final { return locus; }
@@ -3752,7 +3758,7 @@ public:
// Constructor for LoopExpr
LoopExpr (std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs = std::vector<Attribute> ())
: BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label),
std::move (outer_attribs))
@@ -3785,7 +3791,7 @@ public:
// Constructor for while loop with loop label
WhileLoopExpr (std::unique_ptr<Expr> loop_condition,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs
= std::vector<Attribute> ())
: BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label),
@@ -3851,7 +3857,7 @@ public:
WhileLetLoopExpr (std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
std::unique_ptr<Expr> scrutinee,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs
= std::vector<Attribute> ())
: BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label),
@@ -3938,7 +3944,7 @@ public:
ForLoopExpr (std::unique_ptr<Pattern> loop_pattern,
std::unique_ptr<Expr> iterator_expr,
std::unique_ptr<BlockExpr> loop_body, location_t locus,
- LoopLabel loop_label = LoopLabel::error (),
+ tl::optional<LoopLabel> loop_label = tl::nullopt,
std::vector<Attribute> outer_attribs = std::vector<Attribute> ())
: BaseLoopExpr (std::move (loop_body), locus, std::move (loop_label),
std::move (outer_attribs)),
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 8eb0cc5..062f85d 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -434,13 +434,14 @@ class SelfParam : public Param
bool has_ref;
bool is_mut;
// bool has_lifetime; // only possible if also ref
- Lifetime lifetime;
+ tl::optional<Lifetime> lifetime;
// bool has_type; // only possible if not ref
std::unique_ptr<Type> type;
// Unrestricted constructor used for error state
- SelfParam (Lifetime lifetime, bool has_ref, bool is_mut, Type *type)
+ SelfParam (tl::optional<Lifetime> lifetime, bool has_ref, bool is_mut,
+ Type *type)
: Param ({}, UNDEF_LOCATION), has_ref (has_ref), is_mut (is_mut),
lifetime (std::move (lifetime)), type (type)
{}
@@ -453,7 +454,7 @@ public:
bool has_type () const { return type != nullptr; }
// Returns whether the self-param has a valid lifetime.
- bool has_lifetime () const { return !lifetime.is_error (); }
+ bool has_lifetime () const { return lifetime.has_value (); }
// Returns whether the self-param is in an error state.
bool is_error () const
@@ -472,11 +473,11 @@ public:
// Type-based self parameter (not ref, no lifetime)
SelfParam (std::unique_ptr<Type> type, bool is_mut, location_t locus)
: Param ({}, locus), has_ref (false), is_mut (is_mut),
- lifetime (Lifetime::error ()), type (std::move (type))
+ lifetime (tl::nullopt), type (std::move (type))
{}
// Lifetime-based self parameter (is ref, no type)
- SelfParam (Lifetime lifetime, bool is_mut, location_t locus)
+ SelfParam (tl::optional<Lifetime> lifetime, bool is_mut, location_t locus)
: Param ({}, locus), has_ref (true), is_mut (is_mut),
lifetime (std::move (lifetime))
{}
@@ -522,8 +523,8 @@ public:
bool get_has_ref () const { return has_ref; };
bool get_is_mut () const { return is_mut; }
- Lifetime get_lifetime () const { return lifetime; }
- Lifetime &get_lifetime () { return lifetime; }
+ Lifetime get_lifetime () const { return lifetime.value (); }
+ Lifetime &get_lifetime () { return lifetime.value (); }
NodeId get_node_id () const { return node_id; }
@@ -1330,7 +1331,7 @@ class Function : public VisItem, public AssociatedItem, public ExternalItem
WhereClause where_clause;
tl::optional<std::unique_ptr<BlockExpr>> function_body;
location_t locus;
- bool is_default;
+ bool has_default;
bool is_external_function;
public:
@@ -1355,6 +1356,8 @@ public:
bool has_body () const { return function_body.has_value (); }
+ bool is_default () const { return has_default; }
+
// Mega-constructor with all possible fields
Function (Identifier function_name, FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam>> generic_params,
@@ -1362,7 +1365,7 @@ public:
std::unique_ptr<Type> return_type, WhereClause where_clause,
tl::optional<std::unique_ptr<BlockExpr>> function_body,
Visibility vis, std::vector<Attribute> outer_attrs,
- location_t locus, bool is_default = false,
+ location_t locus, bool has_default = false,
bool is_external_function = false)
: VisItem (std::move (vis), std::move (outer_attrs)),
ExternalItem (Stmt::node_id), qualifiers (std::move (qualifiers)),
@@ -1372,7 +1375,7 @@ public:
return_type (std::move (return_type)),
where_clause (std::move (where_clause)),
function_body (std::move (function_body)), locus (locus),
- is_default (is_default), is_external_function (is_external_function)
+ has_default (has_default), is_external_function (is_external_function)
{}
// TODO: add constructor with less fields
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 20e0232..1bb521d 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -542,7 +542,7 @@ protected:
class ReferenceType : public TypeNoBounds
{
// bool has_lifetime; // TODO: handle in lifetime or something?
- Lifetime lifetime;
+ tl::optional<Lifetime> lifetime;
bool has_mut;
std::unique_ptr<TypeNoBounds> type;
@@ -553,11 +553,12 @@ public:
bool is_mut () const { return has_mut; }
// Returns whether the reference has a lifetime.
- bool has_lifetime () const { return !lifetime.is_error (); }
+ bool has_lifetime () const { return lifetime.has_value (); }
// Constructor
ReferenceType (bool is_mut, std::unique_ptr<TypeNoBounds> type_no_bounds,
- location_t locus, Lifetime lifetime = Lifetime::elided ())
+ location_t locus,
+ tl::optional<Lifetime> lifetime = Lifetime::elided ())
: lifetime (std::move (lifetime)), has_mut (is_mut),
type (std::move (type_no_bounds)), locus (locus)
{}
@@ -598,7 +599,8 @@ public:
bool get_has_mut () const { return has_mut; }
- Lifetime &get_lifetime () { return lifetime; }
+ Lifetime &get_lifetime () { return lifetime.value (); }
+ const Lifetime &get_lifetime () const { return lifetime.value (); }
TypeNoBounds &get_base_type () { return *type; }
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index fdbca7f..12b9561 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -549,7 +549,7 @@ HIRCompileBase::mark_addressable (tree exp, location_t locus)
}
tree
-HIRCompileBase::address_expression (tree expr, location_t location)
+HIRCompileBase::address_expression (tree expr, location_t location, tree ptrty)
{
if (expr == error_mark_node)
return error_mark_node;
@@ -557,7 +557,10 @@ HIRCompileBase::address_expression (tree expr, location_t location)
if (!mark_addressable (expr, location))
return error_mark_node;
- return build_fold_addr_expr_loc (location, expr);
+ if (ptrty == NULL || ptrty == error_mark_node)
+ ptrty = build_pointer_type (TREE_TYPE (expr));
+
+ return build_fold_addr_expr_with_type_loc (location, expr, ptrty);
}
tree
@@ -663,7 +666,8 @@ get_abi (const AST::AttrVec &outer_attrs,
tree
HIRCompileBase::compile_function (
- const std::string &fn_name, HIR::SelfParam &self_param,
+ bool is_root_item, const std::string &fn_name,
+ tl::optional<HIR::SelfParam> &self_param,
std::vector<HIR::FunctionParam> &function_params,
const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility,
AST::AttrVec &outer_attrs, location_t locus, HIR::BlockExpr *function_body,
@@ -674,7 +678,7 @@ HIRCompileBase::compile_function (
= canonical_path.get () + fntype->subst_as_string ();
// we don't mangle the main fn since we haven't implemented the main shim
- bool is_main_fn = fn_name.compare ("main") == 0;
+ bool is_main_fn = fn_name.compare ("main") == 0 && is_root_item;
if (is_main_fn)
{
rust_assert (!main_identifier_node);
@@ -710,24 +714,24 @@ HIRCompileBase::compile_function (
// setup the params
TyTy::BaseType *tyret = fntype->get_return_type ();
std::vector<Bvariable *> param_vars;
- if (!self_param.is_error ())
+ if (self_param)
{
rust_assert (fntype->is_method ());
TyTy::BaseType *self_tyty_lookup = fntype->get_self_type ();
tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
Bvariable *compiled_self_param
- = CompileSelfParam::compile (ctx, fndecl, self_param, self_type,
- self_param.get_locus ());
+ = CompileSelfParam::compile (ctx, fndecl, self_param.value (),
+ self_type, self_param->get_locus ());
param_vars.push_back (compiled_self_param);
- ctx->insert_var_decl (self_param.get_mappings ().get_hirid (),
+ ctx->insert_var_decl (self_param->get_mappings ().get_hirid (),
compiled_self_param);
}
// offset from + 1 for the TyTy::FnType being used when this is a method to
// skip over Self on the FnType
- bool is_method = !self_param.is_error ();
+ bool is_method = self_param.has_value ();
size_t i = is_method ? 1 : 0;
for (auto &referenced_param : function_params)
{
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index 4b4f8b0..6814abc 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -29,7 +29,8 @@ class HIRCompileBase
public:
virtual ~HIRCompileBase () {}
- static tree address_expression (tree expr, location_t locus);
+ static tree address_expression (tree expr, location_t locus,
+ tree ptrty = NULL_TREE);
static tree compile_constant_expr (
Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type,
@@ -102,7 +103,8 @@ protected:
HIR::Expr &const_value_expr, location_t locus,
location_t expr_locus);
- tree compile_function (const std::string &fn_name, HIR::SelfParam &self_param,
+ tree compile_function (bool is_root_item, const std::string &fn_name,
+ tl::optional<HIR::SelfParam> &self_param,
std::vector<HIR::FunctionParam> &function_params,
const HIR::FunctionQualifiers &qualifiers,
HIR::Visibility &visibility, AST::AttrVec &outer_attrs,
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index e4ab9f0..37856a7 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -905,7 +905,8 @@ CompileExpr::visit (HIR::BorrowExpr &expr)
&tyty))
return;
- translated = address_expression (main_expr, expr.get_locus ());
+ tree expected_type = TyTyResolveCompile::compile (ctx, tyty);
+ translated = address_expression (main_expr, expr.get_locus (), expected_type);
}
void
diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index bacd1c0..d6aa589 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -34,16 +34,10 @@ class CompileExternItem : public HIRCompileBase,
public:
static tree compile (HIR::ExternalItem *item, Context *ctx,
TyTy::BaseType *concrete = nullptr,
- bool is_query_mode = false,
location_t ref_locus = UNDEF_LOCATION)
{
CompileExternItem compiler (ctx, concrete, ref_locus);
item->accept_vis (compiler);
-
- if (is_query_mode && compiler.reference == error_mark_node)
- rust_internal_error_at (ref_locus, "failed to compile extern item: %s",
- item->as_string ().c_str ());
-
return compiler.reference;
}
diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc
index 71b3e8d..1230c85 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -117,7 +117,7 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func)
auto vis = HIR::Visibility (HIR::Visibility::VisType::PUBLIC);
HIR::TraitFunctionDecl &function = func.get_decl ();
tree fndecl
- = compile_function (function.get_function_name ().as_string (),
+ = compile_function (false, function.get_function_name ().as_string (),
function.get_self (), function.get_function_params (),
function.get_qualifiers (), vis,
func.get_outer_attrs (), func.get_locus (),
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index d2ef989..2d18dbf 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -30,16 +30,10 @@ class CompileInherentImplItem : public CompileItem
public:
static tree Compile (HIR::ImplItem *item, Context *ctx,
TyTy::BaseType *concrete = nullptr,
- bool is_query_mode = false,
location_t ref_locus = UNDEF_LOCATION)
{
CompileInherentImplItem compiler (ctx, concrete, ref_locus);
item->accept_vis (compiler);
-
- if (is_query_mode && compiler.reference == error_mark_node)
- rust_internal_error_at (ref_locus, "failed to compile impl item: %s",
- item->as_string ().c_str ());
-
return compiler.reference;
}
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index 7ce9848..9666990 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -252,8 +252,12 @@ CompileItem::visit (HIR::Function &function)
if (function.get_qualifiers ().is_const ())
ctx->push_const_context ();
+ auto lookup_root_item = ctx->get_mappings ().lookup_hir_item (
+ function.get_mappings ().get_hirid ());
+ bool is_root_item = lookup_root_item.has_value ();
tree fndecl
- = compile_function (function.get_function_name ().as_string (),
+ = compile_function (is_root_item,
+ function.get_function_name ().as_string (),
function.get_self_param (),
function.get_function_params (),
function.get_qualifiers (), function.get_visibility (),
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index eccb040..d9d946d 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -35,10 +35,6 @@ public:
{
CompileItem compiler (ctx, concrete, ref_locus);
item->accept_vis (compiler);
-
- if (compiler.reference == error_mark_node)
- rust_debug ("failed to compile item: %s", item->as_string ().c_str ());
-
return compiler.reference;
}
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 115dd04..81d2dbb 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -105,7 +105,9 @@ ResolvePathRef::attempt_constructor_expression_lookup (
// make the ctor for the union
HIR::Expr &discrim_expr = variant->get_discriminant ();
+ ctx->push_const_context ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
+ ctx->pop_const_context ();
tree folded_discrim_expr = fold_expr (discrim_expr_node);
tree qualifier = folded_discrim_expr;
@@ -259,10 +261,10 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
HIR::ExternalItem *resolved_extern_item = hir_extern_item->first;
if (!lookup->has_substitutions_defined ())
return CompileExternItem::compile (resolved_extern_item, ctx, nullptr,
- true, expr_locus);
+ expr_locus);
else
return CompileExternItem::compile (resolved_extern_item, ctx, lookup,
- true, expr_locus);
+ expr_locus);
}
else
{
@@ -284,10 +286,10 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
{
if (!lookup->has_substitutions_defined ())
return CompileInherentImplItem::Compile (resolved_item->first, ctx,
- nullptr, true, expr_locus);
+ nullptr, expr_locus);
else
return CompileInherentImplItem::Compile (resolved_item->first, ctx,
- lookup, true, expr_locus);
+ lookup, expr_locus);
}
else if (auto trait_item
= ctx->get_mappings ().lookup_hir_trait_item (ref))
@@ -370,11 +372,10 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
if (!lookup->has_substitutions_defined ())
return CompileInherentImplItem::Compile (impl_item, ctx,
- nullptr, true,
- expr_locus);
+ nullptr, expr_locus);
else
return CompileInherentImplItem::Compile (impl_item, ctx, lookup,
- true, expr_locus);
+ expr_locus);
}
}
}
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 7b00066..dbd8515 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -338,7 +338,7 @@ HIRCompileBase::compute_address_for_trait_item (
}
return CompileInherentImplItem::Compile (associated_function, ctx,
- lookup_fntype, true, locus);
+ lookup_fntype, locus);
}
// we can only compile trait-items with a body
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index 4904322..4c2257a 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -646,6 +646,9 @@ ConstChecker::visit (Enum &enum_item)
{
check_default_const_generics (enum_item.get_generic_params (),
ConstGenericCtx::Enum);
+
+ for (auto &item : enum_item.get_variants ())
+ item->accept_vis (*this);
}
void
diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc b/gcc/rust/checks/errors/rust-feature-gate.cc
index f3daa61..44007f9 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/rust-feature-gate.cc
@@ -40,6 +40,13 @@ FeatureGate::visit (AST::Crate &crate)
{
if (attr.get_path ().as_string () == "feature")
{
+ // check for empty feature, such as `#![feature], this is an error
+ if (attr.empty_input ())
+ {
+ rust_error_at (attr.get_locus (), ErrorCode::E0556,
+ "malformed %<feature%> attribute input");
+ continue;
+ }
const auto &attr_input = attr.get_attr_input ();
auto type = attr_input.get_attr_input_type ();
if (type == AST::AttrInput::AttrInputType::TOKEN_TREE)
diff --git a/gcc/rust/checks/errors/rust-feature.cc b/gcc/rust/checks/errors/rust-feature.cc
index 25af46c..441a1b2 100644
--- a/gcc/rust/checks/errors/rust-feature.cc
+++ b/gcc/rust/checks/errors/rust-feature.cc
@@ -55,6 +55,9 @@ Feature::create (Feature::Name f)
"1.11.0", 37854);
case Feature::Name::PRELUDE_IMPORT:
return Feature (f, Feature::State::ACTIVE, "prelude_import", "1.0.0");
+ case Feature::Name::MIN_SPECIALIZATION:
+ return Feature (f, Feature::State::ACTIVE, "min_specialization",
+ "1.0.0" /* FIXME: What version here? */, 31844);
case Feature::Name::AUTO_TRAITS:
return Feature (f, Feature::State::ACTIVE, "optin_builtin_traits",
"1.0.0", 13231);
@@ -80,6 +83,7 @@ const std::map<std::string, Feature::Name> Feature::name_hash_map = {
{"raw_ref_op", Feature::Name::RAW_REF_OP},
{"exclusive_range_pattern", Feature::Name::EXCLUSIVE_RANGE_PATTERN},
{"prelude_import", Feature::Name::PRELUDE_IMPORT},
+ {"min_specialization", Feature::Name::MIN_SPECIALIZATION},
}; // namespace Rust
tl::optional<Feature::Name>
diff --git a/gcc/rust/checks/errors/rust-feature.h b/gcc/rust/checks/errors/rust-feature.h
index 9edae6d..e7cb0af 100644
--- a/gcc/rust/checks/errors/rust-feature.h
+++ b/gcc/rust/checks/errors/rust-feature.h
@@ -51,6 +51,7 @@ public:
RAW_REF_OP,
EXCLUSIVE_RANGE_PATTERN,
PRELUDE_IMPORT,
+ MIN_SPECIALIZATION,
};
const std::string &as_string () { return m_name_str; }
diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc
index 074ea01..a955b58 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -61,11 +61,10 @@ std::unique_ptr<AssociatedItem>
DeriveClone::clone_fn (std::unique_ptr<Expr> &&clone_expr)
{
auto block = std::unique_ptr<BlockExpr> (
- new BlockExpr ({}, std::move (clone_expr), {}, {}, AST::LoopLabel::error (),
- loc, loc));
+ new BlockExpr ({}, std::move (clone_expr), {}, {}, tl::nullopt, loc, loc));
auto big_self_type = builder.single_type_path ("Self");
- std::unique_ptr<SelfParam> self (new SelfParam (Lifetime::error (),
+ std::unique_ptr<SelfParam> self (new SelfParam (tl::nullopt,
/* is_mut */ false, loc));
std::vector<std::unique_ptr<Param>> params;
diff --git a/gcc/rust/expand/rust-derive-debug.cc b/gcc/rust/expand/rust-derive-debug.cc
index 7ad3908..a0bf9d8 100644
--- a/gcc/rust/expand/rust-derive-debug.cc
+++ b/gcc/rust/expand/rust-derive-debug.cc
@@ -50,8 +50,7 @@ DeriveDebug::stub_debug_fn ()
// we can't use builder.block() here as it returns a unique_ptr<Expr> and
// Function's constructor expects a unique_ptr<BlockExpr>
auto block = std::unique_ptr<BlockExpr> (
- new BlockExpr ({}, std::move (stub_return), {}, {},
- AST::LoopLabel::error (), loc, loc));
+ new BlockExpr ({}, std::move (stub_return), {}, {}, tl::nullopt, loc, loc));
auto self = builder.self_ref_param ();
diff --git a/gcc/rust/expand/rust-derive-default.cc b/gcc/rust/expand/rust-derive-default.cc
index c54f8c3..2e8b456 100644
--- a/gcc/rust/expand/rust-derive-default.cc
+++ b/gcc/rust/expand/rust-derive-default.cc
@@ -58,8 +58,7 @@ DeriveDefault::default_fn (std::unique_ptr<Expr> &&return_expr)
= std::unique_ptr<Type> (new TypePath (builder.type_path ("Self")));
auto block = std::unique_ptr<BlockExpr> (
- new BlockExpr ({}, std::move (return_expr), {}, {},
- AST::LoopLabel::error (), loc, loc));
+ new BlockExpr ({}, std::move (return_expr), {}, {}, tl::nullopt, loc, loc));
return builder.function ("default", {}, std::move (self_ty),
std::move (block));
diff --git a/gcc/rust/expand/rust-derive-eq.cc b/gcc/rust/expand/rust-derive-eq.cc
index dc173de..5e7a894 100644
--- a/gcc/rust/expand/rust-derive-eq.cc
+++ b/gcc/rust/expand/rust-derive-eq.cc
@@ -49,8 +49,7 @@ DeriveEq::assert_receiver_is_total_eq_fn (
stmts.emplace_back (assert_type_is_eq (std::move (type)));
auto block = std::unique_ptr<BlockExpr> (
- new BlockExpr (std::move (stmts), nullptr, {}, {}, AST::LoopLabel::error (),
- loc, loc));
+ new BlockExpr (std::move (stmts), nullptr, {}, {}, tl::nullopt, loc, loc));
auto self = builder.self_ref_param ();
diff --git a/gcc/rust/expand/rust-macro-builtins-format-args.cc b/gcc/rust/expand/rust-macro-builtins-format-args.cc
index 8eb32d5..3e1249d 100644
--- a/gcc/rust/expand/rust-macro-builtins-format-args.cc
+++ b/gcc/rust/expand/rust-macro-builtins-format-args.cc
@@ -55,6 +55,8 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
if (parser.peek_current_token ()->get_id () == STRING_LITERAL)
format_expr = parser.parse_literal_expr ();
+ rust_assert (format_expr);
+
// TODO(Arthur): Clean this up - if we haven't parsed a string literal but a
// macro invocation, what do we do here? return a tl::unexpected?
auto format_str = static_cast<AST::LiteralExpr &> (*format_expr)
@@ -81,6 +83,11 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
{
parser.skip_token (COMMA);
+ // Check in case of an extraneous comma in the args list, which is
+ // allowed - format_args!("fmt", arg, arg2,)
+ if (parser.peek_current_token ()->get_id () == last_token_id)
+ break;
+
if (parser.peek_current_token ()->get_id () == IDENTIFIER
&& parser.peek (1)->get_id () == EQUAL)
{
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 39c4c46..8b406ff 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -83,7 +83,6 @@ const BiMap<std::string, BuiltinMacro> MacroBuiltin::builtins = {{
{"Ord", BuiltinMacro::Ord},
{"PartialOrd", BuiltinMacro::PartialOrd},
{"Hash", BuiltinMacro::Hash},
-
}};
AST::MacroTranscriberFunc
@@ -137,6 +136,7 @@ std::unordered_map<std::string, AST::MacroTranscriberFunc>
{"cfg_accessible", MacroBuiltin::sorry},
{"rustc_const_stable", MacroBuiltin::sorry},
{"rustc_const_unstable", MacroBuiltin::sorry},
+ {"track_caller", MacroBuiltin::sorry},
/* Derive builtins do not need a real transcriber, but still need one. It
should however never be called since builtin derive macros get expanded
differently, and benefit from knowing on what kind of items they are
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index cd17a3f..673b8fb 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -28,6 +28,7 @@
#include "rust-cfg-strip.h"
#include "rust-early-name-resolver.h"
#include "rust-proc-macro.h"
+#include "rust-token-tree-desugar.h"
namespace Rust {
@@ -78,7 +79,10 @@ MacroExpander::expand_decl_macro (location_t invoc_locus,
* trees.
*/
- AST::DelimTokenTree &invoc_token_tree = invoc.get_delim_tok_tree ();
+ AST::DelimTokenTree &invoc_token_tree_sugar = invoc.get_delim_tok_tree ();
+
+ // We must first desugar doc comments into proper attributes
+ auto invoc_token_tree = AST::TokenTreeDesugar ().go (invoc_token_tree_sugar);
// find matching arm
AST::MacroRule *matched_rule = nullptr;
@@ -621,9 +625,10 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
// matched fragment get the offset in the token stream
size_t offs_end = source.get_offs ();
- sub_stack.insert_metavar (
- MatchedFragment (fragment->get_ident ().as_string (),
- offs_begin, offs_end));
+ if (valid_current_match)
+ sub_stack.insert_metavar (
+ MatchedFragment (fragment->get_ident ().as_string (),
+ offs_begin, offs_end));
}
break;
@@ -650,15 +655,15 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
}
auto old_stack = sub_stack.pop ();
- // nest metavars into repetitions
- for (auto &ent : old_stack)
- sub_stack.append_fragment (ent.first, std::move (ent.second));
-
// If we've encountered an error once, stop trying to match more
// repetitions
if (!valid_current_match)
break;
+ // nest metavars into repetitions
+ for (auto &ent : old_stack)
+ sub_stack.append_fragment (ent.first, std::move (ent.second));
+
match_amount++;
// Break early if we notice there's too many expressions already
diff --git a/gcc/rust/expand/rust-token-tree-desugar.cc b/gcc/rust/expand/rust-token-tree-desugar.cc
new file mode 100644
index 0000000..3b47180
--- /dev/null
+++ b/gcc/rust/expand/rust-token-tree-desugar.cc
@@ -0,0 +1,72 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-token-tree-desugar.h"
+#include "rust-ast.h"
+#include "rust-token.h"
+
+namespace Rust {
+namespace AST {
+
+DelimTokenTree
+TokenTreeDesugar::go (DelimTokenTree &tts)
+{
+ tts.accept_vis (*this);
+
+ return DelimTokenTree (tts.get_delim_type (), std::move (desugared),
+ tts.get_locus ());
+}
+
+void
+TokenTreeDesugar::append (TokenPtr &&new_token)
+{
+ desugared.emplace_back (std::make_unique<Token> (std::move (new_token)));
+}
+
+void
+TokenTreeDesugar::append (std::unique_ptr<TokenTree> &&new_token)
+{
+ desugared.emplace_back (std::move (new_token));
+}
+
+void
+TokenTreeDesugar::visit (Token &tts)
+{
+ if (tts.get_id () == TokenId::OUTER_DOC_COMMENT
+ || tts.get_id () == TokenId::INNER_DOC_COMMENT)
+ {
+ append (Rust::Token::make (TokenId::HASH, tts.get_locus ()));
+
+ if (tts.get_id () == TokenId::INNER_DOC_COMMENT)
+ append (Rust::Token::make (EXCLAM, tts.get_locus ()));
+
+ append (Rust::Token::make (TokenId::LEFT_SQUARE, tts.get_locus ()));
+ append (Rust::Token::make_identifier (tts.get_locus (), "doc"));
+ append (Rust::Token::make (TokenId::EQUAL, tts.get_locus ()));
+ append (Rust::Token::make_string (tts.get_locus (),
+ std::string (tts.get_str ())));
+ append (Rust::Token::make (TokenId::RIGHT_SQUARE, tts.get_locus ()));
+ }
+ else
+ {
+ append (tts.clone_token ());
+ }
+}
+
+}; // namespace AST
+}; // namespace Rust
diff --git a/gcc/rust/expand/rust-token-tree-desugar.h b/gcc/rust/expand/rust-token-tree-desugar.h
new file mode 100644
index 0000000..ccba53b
--- /dev/null
+++ b/gcc/rust/expand/rust-token-tree-desugar.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_TOKEN_TREE_DESUGAR_H
+#define RUST_TOKEN_TREE_DESUGAR_H
+
+#include "rust-ast-visitor.h"
+#include "rust-system.h"
+#include "rust-ast.h"
+
+namespace Rust {
+namespace AST {
+
+/**
+ * Desugar a given token-tree before parsing it for a macro invocation. At the
+ * moment, the sole purpose of this desugar is to transform doc-comments into
+ * their attribute form (/// comment -> #[doc = "comment"])
+ */
+class TokenTreeDesugar : public DefaultASTVisitor
+{
+public:
+ TokenTreeDesugar () : desugared (std::vector<std::unique_ptr<TokenTree>> ())
+ {}
+
+ DelimTokenTree go (DelimTokenTree &tts);
+
+private:
+ std::vector<std::unique_ptr<TokenTree>> desugared;
+ void append (TokenPtr &&new_token);
+ void append (std::unique_ptr<TokenTree> &&new_token);
+
+ using DefaultASTVisitor::visit;
+
+ virtual void visit (Token &tts) override;
+};
+
+}; // namespace AST
+}; // namespace Rust
+
+#endif //! RUST_TOKEN_TREE_DESUGAR_H
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index b0d347e..5039798 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -690,8 +690,12 @@ ASTLoweringBase::lower_self (AST::Param &param)
self.get_is_mut (), self.get_locus ());
}
- AST::Lifetime l = self.get_lifetime ();
- return HIR::SelfParam (mapping, lower_lifetime (l), self.get_is_mut (),
+ tl::optional<HIR::Lifetime> lifetime = tl::nullopt;
+
+ if (self.has_lifetime ())
+ lifetime = lower_lifetime (self.get_lifetime ());
+
+ return HIR::SelfParam (mapping, lifetime, self.get_is_mut (),
self.get_locus ());
}
diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h
index a39c010..93cd443 100644
--- a/gcc/rust/hir/rust-ast-lower-block.h
+++ b/gcc/rust/hir/rust-ast-lower-block.h
@@ -195,7 +195,9 @@ public:
HIR::BlockExpr *loop_block
= ASTLoweringBlock::translate (expr.get_loop_block (), &terminated);
- HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ());
+ tl::optional<HIR::LoopLabel> loop_label = tl::nullopt;
+ if (expr.has_loop_label ())
+ loop_label = lower_loop_label (expr.get_loop_label ());
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc
index 9f363c0..3784e74 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -597,8 +597,10 @@ ASTLoweringExpr::visit (AST::ForLoopExpr &expr)
void
ASTLoweringExpr::visit (AST::BreakExpr &expr)
{
- HIR::Lifetime break_label
- = lower_lifetime (expr.get_label ().get_lifetime ());
+ tl::optional<HIR::Lifetime> break_label = tl::nullopt;
+ if (expr.has_label ())
+ break_label = lower_lifetime (expr.get_label_unchecked ().get_lifetime ());
+
HIR::Expr *break_expr
= expr.has_break_expr ()
? ASTLoweringExpr::translate (expr.get_break_expr ())
@@ -618,7 +620,9 @@ ASTLoweringExpr::visit (AST::BreakExpr &expr)
void
ASTLoweringExpr::visit (AST::ContinueExpr &expr)
{
- HIR::Lifetime break_label = lower_lifetime (expr.get_label ());
+ tl::optional<HIR::Lifetime> break_label;
+ if (expr.has_label ())
+ break_label = lower_lifetime (expr.get_label_unchecked ());
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
@@ -633,9 +637,6 @@ ASTLoweringExpr::visit (AST::ContinueExpr &expr)
void
ASTLoweringExpr::visit (AST::BorrowExpr &expr)
{
- if (expr.is_raw_borrow ())
- rust_unreachable ();
-
HIR::Expr *borrow_lvalue
= ASTLoweringExpr::translate (expr.get_borrowed_expr ());
@@ -646,8 +647,8 @@ ASTLoweringExpr::visit (AST::BorrowExpr &expr)
auto *borrow_expr
= new HIR::BorrowExpr (mapping, std::unique_ptr<HIR::Expr> (borrow_lvalue),
- expr.get_mutability (), expr.get_outer_attrs (),
- expr.get_locus ());
+ expr.get_mutability (), expr.is_raw_borrow (),
+ expr.get_outer_attrs (), expr.get_locus ());
if (expr.get_is_double_borrow ())
{
@@ -659,8 +660,8 @@ ASTLoweringExpr::visit (AST::BorrowExpr &expr)
borrow_expr
= new HIR::BorrowExpr (mapping,
std::unique_ptr<HIR::Expr> (borrow_expr),
- expr.get_mutability (), expr.get_outer_attrs (),
- expr.get_locus ());
+ expr.get_mutability (), expr.is_raw_borrow (),
+ expr.get_outer_attrs (), expr.get_locus ());
}
translated = borrow_expr;
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc
index 5380d25..d815a71 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.cc
+++ b/gcc/rust/hir/rust-ast-lower-implitem.cc
@@ -22,6 +22,7 @@
#include "rust-ast-lower-expr.h"
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-block.h"
+#include "rust-hir-item.h"
#include "rust-item.h"
namespace Rust {
@@ -131,7 +132,7 @@ ASTLowerImplItem::visit (AST::Function &function)
Identifier function_name = function.get_function_name ();
location_t locus = function.get_locus ();
- HIR::SelfParam self_param = HIR::SelfParam::error ();
+ tl::optional<HIR::SelfParam> self_param = tl::nullopt;
if (function.has_self_param ())
self_param = lower_self (function.get_self_param ());
@@ -140,6 +141,9 @@ ASTLowerImplItem::visit (AST::Function &function)
ASTLoweringType::translate (function.get_return_type ()))
: nullptr;
+ Defaultness defaultness
+ = function.is_default () ? Defaultness::Default : Defaultness::Final;
+
std::vector<HIR::FunctionParam> function_params;
for (auto &p : function.get_function_params ())
{
@@ -183,15 +187,15 @@ ASTLowerImplItem::visit (AST::Function &function)
std::move (function_params), std::move (return_type),
std::move (where_clause), std::move (function_body),
std::move (vis), function.get_outer_attrs (),
- std::move (self_param), locus);
+ std::move (self_param), defaultness, locus);
- if (!fn->get_self_param ().is_error ())
+ if (fn->is_method ())
{
// insert mappings for self
- mappings.insert_hir_self_param (&fn->get_self_param ());
+ mappings.insert_hir_self_param (&fn->get_self_param_unchecked ());
mappings.insert_location (
- fn->get_self_param ().get_mappings ().get_hirid (),
- fn->get_self_param ().get_locus ());
+ fn->get_self_param_unchecked ().get_mappings ().get_hirid (),
+ fn->get_self_param_unchecked ().get_locus ());
}
// add the mappings for the function params at the end
@@ -245,9 +249,9 @@ ASTLowerTraitItem::visit (AST::Function &func)
// set self parameter to error if this is a method
// else lower to hir
- HIR::SelfParam self_param = func.has_self_param ()
- ? lower_self (func.get_self_param ())
- : HIR::SelfParam::error ();
+ tl::optional<HIR::SelfParam> self_param = tl::nullopt;
+ if (func.has_self_param ())
+ self_param = lower_self (func.get_self_param ());
std::vector<HIR::FunctionParam> function_params;
for (auto &p : func.get_function_params ())
@@ -299,9 +303,10 @@ ASTLowerTraitItem::visit (AST::Function &func)
if (func.has_self_param ())
{
// insert mappings for self
- mappings.insert_hir_self_param (&self_param);
- mappings.insert_location (self_param.get_mappings ().get_hirid (),
- self_param.get_locus ());
+ // TODO: Is this correct ? Looks fishy
+ mappings.insert_hir_self_param (&*self_param);
+ mappings.insert_location (self_param->get_mappings ().get_hirid (),
+ self_param->get_locus ());
}
// add the mappings for the function params at the end
diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc
index 5dbcad5..f4396b5 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -451,13 +451,16 @@ ASTLoweringItem::visit (AST::Function &function)
mappings.insert_location (function_body->get_mappings ().get_hirid (),
function.get_locus ());
+ Defaultness defaultness
+ = function.is_default () ? Defaultness::Default : Defaultness::Final;
+
auto fn
= new HIR::Function (mapping, std::move (function_name),
std::move (qualifiers), std::move (generic_params),
std::move (function_params), std::move (return_type),
std::move (where_clause), std::move (function_body),
std::move (vis), function.get_outer_attrs (),
- HIR::SelfParam::error (), locus);
+ tl::nullopt, defaultness, locus);
// add the mappings for the function params at the end
for (auto &param : fn->get_function_params ())
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index ebdf981..76bd135 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -97,7 +97,11 @@ ASTLowering::go ()
void
ASTLoweringBlock::visit (AST::BlockExpr &expr)
{
- auto label = lower_loop_label (expr.get_label ());
+ tl::optional<HIR::LoopLabel> label;
+ if (expr.has_label ())
+ label = lower_loop_label (expr.get_label ());
+ else
+ label = tl::nullopt;
std::vector<std::unique_ptr<HIR::Stmt>> block_stmts;
bool block_did_terminate = false;
@@ -398,7 +402,10 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr)
HIR::BlockExpr *loop_block
= ASTLoweringBlock::translate (expr.get_loop_block (), &terminated);
- HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ());
+ tl::optional<HIR::LoopLabel> loop_label;
+ if (expr.has_loop_label ())
+ loop_label = lower_loop_label (expr.get_loop_label ());
+
HIR::Expr *loop_condition
= ASTLoweringExpr::translate (expr.get_predicate_expr (), &terminated);
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 89fcc3d..dafa823 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -546,7 +546,8 @@ Dump::do_traitfunctiondecl (TraitFunctionDecl &e)
else
put_field ("where_clause", "none");
- put_field ("self", e.get_self ().as_string ());
+ if (e.is_method ())
+ put_field ("self", e.get_self_unchecked ().as_string ());
end ("TraitFunctionDecl");
}
@@ -1693,7 +1694,8 @@ Dump::visit (Function &e)
put_field ("where clause", e.get_where_clause ().as_string ());
visit_field ("function_body", e.get_definition ());
- put_field ("self", e.get_self_param ().as_string ());
+ if (e.is_method ())
+ put_field ("self", e.get_self_param_unchecked ().as_string ());
end ("Function");
}
diff --git a/gcc/rust/hir/tree/rust-hir-bound.h b/gcc/rust/hir/tree/rust-hir-bound.h
index 78bb133..8fa6a22 100644
--- a/gcc/rust/hir/tree/rust-hir-bound.h
+++ b/gcc/rust/hir/tree/rust-hir-bound.h
@@ -44,18 +44,6 @@ public:
{}
// Returns true if the lifetime is in an error state.
- bool is_error () const
- {
- return lifetime_type == AST::Lifetime::LifetimeType::NAMED
- && lifetime_name.empty ();
- }
-
- static Lifetime error ()
- {
- return Lifetime (Analysis::NodeMapping::get_error (),
- AST::Lifetime::LifetimeType::NAMED, "", UNDEF_LOCATION);
- }
-
std::string as_string () const override;
void accept_vis (HIRFullVisitor &vis) override;
diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc b/gcc/rust/hir/tree/rust-hir-expr.cc
index 2ded789..266c79c 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.cc
+++ b/gcc/rust/hir/tree/rust-hir-expr.cc
@@ -81,10 +81,10 @@ OperatorExpr::operator= (OperatorExpr const &other)
BorrowExpr::BorrowExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> borrow_lvalue, Mutability mut,
- AST::AttrVec outer_attribs, location_t locus)
+ bool raw, AST::AttrVec outer_attribs, location_t locus)
: OperatorExpr (std::move (mappings), std::move (borrow_lvalue),
std::move (outer_attribs), locus),
- mut (mut)
+ mut (mut), raw (raw)
{}
DereferenceExpr::DereferenceExpr (Analysis::NodeMapping mappings,
@@ -749,7 +749,7 @@ BlockExpr::BlockExpr (Analysis::NodeMapping mappings,
std::vector<std::unique_ptr<Stmt>> block_statements,
std::unique_ptr<Expr> block_expr, bool tail_reachable,
AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
- LoopLabel label, location_t start_locus,
+ tl::optional<LoopLabel> label, location_t start_locus,
location_t end_locus)
: ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
WithInnerAttrs (std::move (inner_attribs)),
@@ -791,13 +791,15 @@ BlockExpr::operator= (BlockExpr const &other)
}
ContinueExpr::ContinueExpr (Analysis::NodeMapping mappings, location_t locus,
- Lifetime label, AST::AttrVec outer_attribs)
+ tl::optional<Lifetime> label,
+ AST::AttrVec outer_attribs)
: ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
label (std::move (label)), locus (locus)
{}
BreakExpr::BreakExpr (Analysis::NodeMapping mappings, location_t locus,
- Lifetime break_label, std::unique_ptr<Expr> expr_in_break,
+ tl::optional<Lifetime> break_label,
+ std::unique_ptr<Expr> expr_in_break,
AST::AttrVec outer_attribs)
: ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
label (std::move (break_label)), break_expr (std::move (expr_in_break)),
@@ -985,7 +987,8 @@ UnsafeBlockExpr::operator= (UnsafeBlockExpr const &other)
BaseLoopExpr::BaseLoopExpr (Analysis::NodeMapping mappings,
std::unique_ptr<BlockExpr> loop_block,
- location_t locus, LoopLabel loop_label,
+ location_t locus,
+ tl::optional<LoopLabel> loop_label,
AST::AttrVec outer_attribs)
: ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
loop_label (std::move (loop_label)), loop_block (std::move (loop_block)),
@@ -1011,7 +1014,8 @@ BaseLoopExpr::operator= (BaseLoopExpr const &other)
LoopExpr::LoopExpr (Analysis::NodeMapping mappings,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label, AST::AttrVec outer_attribs)
+ tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs)
: BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
std::move (loop_label), std::move (outer_attribs))
{}
@@ -1019,7 +1023,8 @@ LoopExpr::LoopExpr (Analysis::NodeMapping mappings,
WhileLoopExpr::WhileLoopExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> loop_condition,
std::unique_ptr<BlockExpr> loop_block,
- location_t locus, LoopLabel loop_label,
+ location_t locus,
+ tl::optional<LoopLabel> loop_label,
AST::AttrVec outer_attribs)
: BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
std::move (loop_label), std::move (outer_attribs)),
@@ -1046,7 +1051,8 @@ WhileLetLoopExpr::WhileLetLoopExpr (
Analysis::NodeMapping mappings,
std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> loop_block,
- location_t locus, LoopLabel loop_label, AST::AttrVec outer_attribs)
+ location_t locus, tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs)
: BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
std::move (loop_label), std::move (outer_attribs)),
match_arm_patterns (std::move (match_arm_patterns)),
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index f8f2128..96f0cf6 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -45,9 +45,6 @@ public:
LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label,
location_t locus);
- // Returns whether the LoopLabel is in an error state.
- bool is_error () const { return label.is_error (); }
-
location_t get_locus () const { return locus; }
Analysis::NodeMapping &get_mappings () { return mappings; }
@@ -199,12 +196,13 @@ public:
class BorrowExpr : public OperatorExpr
{
Mutability mut;
+ bool raw;
public:
std::string as_string () const override;
BorrowExpr (Analysis::NodeMapping mappings,
- std::unique_ptr<Expr> borrow_lvalue, Mutability mut,
+ std::unique_ptr<Expr> borrow_lvalue, Mutability mut, bool raw,
AST::AttrVec outer_attribs, location_t locus);
void accept_vis (HIRFullVisitor &vis) override;
@@ -212,6 +210,7 @@ public:
Mutability get_mut () const { return mut; }
bool is_mut () const { return mut == Mutability::Mut; }
+ bool is_raw_borrow () const { return raw; }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -1715,7 +1714,7 @@ public:
std::vector<std::unique_ptr<Stmt>> statements;
std::unique_ptr<Expr> expr;
bool tail_reachable;
- LoopLabel label;
+ tl::optional<LoopLabel> label;
location_t start_locus;
location_t end_locus;
@@ -1735,7 +1734,8 @@ public:
std::vector<std::unique_ptr<Stmt>> block_statements,
std::unique_ptr<Expr> block_expr, bool tail_reachable,
AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
- LoopLabel label, location_t start_locus, location_t end_locus);
+ tl::optional<LoopLabel> label, location_t start_locus,
+ location_t end_locus);
// Copy constructor with clone
BlockExpr (BlockExpr const &other);
@@ -1774,8 +1774,8 @@ public:
return ExprType::Block;
}
- bool has_label () const { return !label.is_error (); }
- LoopLabel &get_label () { return label; }
+ bool has_label () const { return label.has_value (); }
+ LoopLabel &get_label () { return label.value (); }
protected:
/* Use covariance to implement clone function as returning this object rather
@@ -1803,25 +1803,27 @@ protected:
// HIR node representing continue expression within loops
class ContinueExpr : public ExprWithoutBlock
{
- Lifetime label;
+ tl::optional<Lifetime> label;
location_t locus;
public:
std::string as_string () const override;
// Returns true if the continue expr has a label.
- bool has_label () const { return !label.is_error (); }
+ bool has_label () const { return label.has_value (); }
// Constructor for a ContinueExpr with a label.
ContinueExpr (Analysis::NodeMapping mappings, location_t locus,
- Lifetime label, AST::AttrVec outer_attribs = AST::AttrVec ());
+ tl::optional<Lifetime> label,
+ AST::AttrVec outer_attribs = AST::AttrVec ());
location_t get_locus () const override final { return locus; }
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- Lifetime &get_label () { return label; }
+ Lifetime &get_label () { return label.value (); }
+ const Lifetime &get_label () const { return label.value (); }
ExprType get_expression_type () const final override
{
@@ -1848,7 +1850,7 @@ protected:
class BreakExpr : public ExprWithoutBlock
{
// bool has_label;
- Lifetime label;
+ tl::optional<Lifetime> label;
// bool has_break_expr;
std::unique_ptr<Expr> break_expr;
@@ -1859,7 +1861,7 @@ public:
std::string as_string () const override;
// Returns whether the break expression has a label or not.
- bool has_label () const { return !label.is_error (); }
+ bool has_label () const { return label.has_value (); }
/* Returns whether the break expression has an expression used in the break or
* not. */
@@ -1867,7 +1869,7 @@ public:
// Constructor for a break expression
BreakExpr (Analysis::NodeMapping mappings, location_t locus,
- Lifetime break_label,
+ tl::optional<Lifetime> break_label,
std::unique_ptr<Expr> expr_in_break = nullptr,
AST::AttrVec outer_attribs = AST::AttrVec ());
@@ -1886,7 +1888,8 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
- Lifetime &get_label () { return label; }
+ Lifetime &get_label () { return label.value (); }
+ const Lifetime &get_label () const { return label.value (); }
Expr &get_expr () { return *break_expr; }
@@ -2293,7 +2296,7 @@ protected:
class BaseLoopExpr : public ExprWithBlock
{
protected:
- LoopLabel loop_label;
+ tl::optional<LoopLabel> loop_label;
std::unique_ptr<BlockExpr> loop_block;
private:
@@ -2303,7 +2306,7 @@ protected:
// Constructor for BaseLoopExpr
BaseLoopExpr (Analysis::NodeMapping mappings,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label,
+ tl::optional<LoopLabel> loop_label,
AST::AttrVec outer_attribs = AST::AttrVec ());
// Copy constructor for BaseLoopExpr with clone
@@ -2322,13 +2325,14 @@ protected:
}
public:
- bool has_loop_label () const { return !loop_label.is_error (); }
+ bool has_loop_label () const { return loop_label.has_value (); }
location_t get_locus () const override final { return locus; }
HIR::BlockExpr &get_loop_block () { return *loop_block; };
- LoopLabel &get_loop_label () { return loop_label; }
+ LoopLabel &get_loop_label () { return loop_label.value (); }
+ const LoopLabel &get_loop_label () const { return loop_label.value (); }
};
// 'Loop' expression (i.e. the infinite loop) HIR node
@@ -2340,7 +2344,8 @@ public:
// Constructor for LoopExpr
LoopExpr (Analysis::NodeMapping mappings,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label, AST::AttrVec outer_attribs = AST::AttrVec ());
+ tl::optional<LoopLabel> loop_label,
+ AST::AttrVec outer_attribs = AST::AttrVec ());
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRExpressionVisitor &vis) override;
@@ -2370,7 +2375,7 @@ public:
WhileLoopExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> loop_condition,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label,
+ tl::optional<LoopLabel> loop_label,
AST::AttrVec outer_attribs = AST::AttrVec ());
// Copy constructor with clone
@@ -2419,7 +2424,7 @@ public:
std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
std::unique_ptr<Expr> condition,
std::unique_ptr<BlockExpr> loop_block, location_t locus,
- LoopLabel loop_label,
+ tl::optional<LoopLabel> loop_label,
AST::AttrVec outer_attribs = AST::AttrVec ());
// Copy constructor with clone
diff --git a/gcc/rust/hir/tree/rust-hir-generic-param.h b/gcc/rust/hir/tree/rust-hir-generic-param.h
index a1c59bf..960de56 100644
--- a/gcc/rust/hir/tree/rust-hir-generic-param.h
+++ b/gcc/rust/hir/tree/rust-hir-generic-param.h
@@ -97,9 +97,6 @@ public:
AST::AttrVec &get_outer_attrs () override { return outer_attrs; }
- // Returns whether the lifetime param is in an error state.
- bool is_error () const { return lifetime.is_error (); }
-
// Constructor
LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime,
location_t locus = UNDEF_LOCATION,
diff --git a/gcc/rust/hir/tree/rust-hir-item.cc b/gcc/rust/hir/tree/rust-hir-item.cc
index cff06d3..160f710 100644
--- a/gcc/rust/hir/tree/rust-hir-item.cc
+++ b/gcc/rust/hir/tree/rust-hir-item.cc
@@ -123,7 +123,8 @@ TypeBoundWhereClauseItem::get_type_param_bounds ()
}
SelfParam::SelfParam (Analysis::NodeMapping mappings,
- ImplicitSelfKind self_kind, Lifetime lifetime, Type *type)
+ ImplicitSelfKind self_kind,
+ tl::optional<Lifetime> lifetime, Type *type)
: self_kind (self_kind), lifetime (std::move (lifetime)), type (type),
mappings (mappings)
{}
@@ -131,13 +132,13 @@ SelfParam::SelfParam (Analysis::NodeMapping mappings,
SelfParam::SelfParam (Analysis::NodeMapping mappings,
std::unique_ptr<Type> type, bool is_mut, location_t locus)
: self_kind (is_mut ? ImplicitSelfKind::MUT : ImplicitSelfKind::IMM),
- lifetime (
- Lifetime (mappings, AST::Lifetime::LifetimeType::NAMED, "", locus)),
- type (std::move (type)), locus (locus), mappings (mappings)
+ lifetime (tl::nullopt), type (std::move (type)), locus (locus),
+ mappings (mappings)
{}
-SelfParam::SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime,
- bool is_mut, location_t locus)
+SelfParam::SelfParam (Analysis::NodeMapping mappings,
+ tl::optional<Lifetime> lifetime, bool is_mut,
+ location_t locus)
: self_kind (is_mut ? ImplicitSelfKind::MUT_REF : ImplicitSelfKind::IMM_REF),
lifetime (std::move (lifetime)), locus (locus), mappings (mappings)
{}
@@ -263,7 +264,8 @@ Function::Function (Analysis::NodeMapping mappings, Identifier function_name,
std::vector<FunctionParam> function_params,
std::unique_ptr<Type> return_type, WhereClause where_clause,
std::unique_ptr<BlockExpr> function_body, Visibility vis,
- AST::AttrVec outer_attrs, SelfParam self, location_t locus)
+ AST::AttrVec outer_attrs, tl::optional<SelfParam> self,
+ Defaultness defaultness, location_t locus)
: VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
qualifiers (std::move (qualifiers)),
function_name (std::move (function_name)),
@@ -272,7 +274,7 @@ Function::Function (Analysis::NodeMapping mappings, Identifier function_name,
return_type (std::move (return_type)),
where_clause (std::move (where_clause)),
function_body (std::move (function_body)), self (std::move (self)),
- locus (locus)
+ locus (locus), defaultness (defaultness)
{}
Function::Function (Function const &other)
@@ -280,7 +282,7 @@ Function::Function (Function const &other)
function_name (other.function_name),
function_params (other.function_params), where_clause (other.where_clause),
function_body (other.function_body->clone_block_expr ()), self (other.self),
- locus (other.locus)
+ locus (other.locus), defaultness (other.defaultness)
{
// guard to prevent null dereference (always required)
if (other.return_type != nullptr)
@@ -312,6 +314,8 @@ Function::operator= (Function const &other)
locus = other.locus;
self = other.self;
+ defaultness = other.defaultness;
+
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
@@ -609,9 +613,9 @@ StaticItem::operator= (StaticItem const &other)
TraitFunctionDecl::TraitFunctionDecl (
Identifier function_name, FunctionQualifiers qualifiers,
- std::vector<std::unique_ptr<GenericParam>> generic_params, SelfParam self,
- std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type,
- WhereClause where_clause)
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ tl::optional<SelfParam> self, std::vector<FunctionParam> function_params,
+ std::unique_ptr<Type> return_type, WhereClause where_clause)
: qualifiers (std::move (qualifiers)),
function_name (std::move (function_name)),
generic_params (std::move (generic_params)),
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 4744717..b9b105b 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -371,13 +371,13 @@ public:
private:
ImplicitSelfKind self_kind;
- Lifetime lifetime;
+ tl::optional<Lifetime> lifetime;
std::unique_ptr<Type> type;
location_t locus;
Analysis::NodeMapping mappings;
SelfParam (Analysis::NodeMapping mappings, ImplicitSelfKind self_kind,
- Lifetime lifetime, Type *type);
+ tl::optional<Lifetime> lifetime, Type *type);
public:
// Type-based self parameter (not ref, no lifetime)
@@ -385,8 +385,8 @@ public:
bool is_mut, location_t locus);
// Lifetime-based self parameter (is ref, no type)
- SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime, bool is_mut,
- location_t locus);
+ SelfParam (Analysis::NodeMapping mappings, tl::optional<Lifetime> lifetime,
+ bool is_mut, location_t locus);
// Copy constructor requires clone
SelfParam (SelfParam const &other);
@@ -398,22 +398,13 @@ public:
SelfParam (SelfParam &&other) = default;
SelfParam &operator= (SelfParam &&other) = default;
- static SelfParam error ()
- {
- return SelfParam (Analysis::NodeMapping::get_error (),
- ImplicitSelfKind::NONE, Lifetime::error (), nullptr);
- }
-
// Returns whether the self-param has a type field.
bool has_type () const { return type != nullptr; }
// Returns whether the self-param has a valid lifetime.
- bool has_lifetime () const { return !lifetime.is_error (); }
-
- const Lifetime &get_lifetime () const { return lifetime; }
+ bool has_lifetime () const { return lifetime.has_value (); }
- // Returns whether the self-param is in an error state.
- bool is_error () const { return self_kind == ImplicitSelfKind::NONE; }
+ const Lifetime &get_lifetime () const { return lifetime.value (); }
std::string as_string () const;
@@ -945,6 +936,12 @@ protected:
class LetStmt;
+enum class Defaultness
+{
+ Default,
+ Final,
+};
+
// Rust function declaration HIR node
class Function : public VisItem, public ImplItem
{
@@ -955,9 +952,14 @@ class Function : public VisItem, public ImplItem
std::unique_ptr<Type> return_type;
WhereClause where_clause;
std::unique_ptr<BlockExpr> function_body;
- SelfParam self;
+ tl::optional<SelfParam> self;
location_t locus;
+ // NOTE: This should be moved to the trait item base class once we start
+ // implementing specialization for real, instead of just stubbing out the
+ // feature
+ Defaultness defaultness;
+
public:
std::string as_string () const override;
@@ -973,6 +975,9 @@ public:
// Returns whether function has a where clause.
bool has_where_clause () const { return !where_clause.is_empty (); }
+ // Returns whether function has a default qualifier
+ bool is_default () const { return defaultness == Defaultness::Default; }
+
ImplItemType get_impl_item_type () const override final
{
return ImplItem::ImplItemType::FUNCTION;
@@ -987,7 +992,8 @@ public:
std::vector<FunctionParam> function_params,
std::unique_ptr<Type> return_type, WhereClause where_clause,
std::unique_ptr<BlockExpr> function_body, Visibility vis,
- AST::AttrVec outer_attrs, SelfParam self, location_t locus);
+ AST::AttrVec outer_attrs, tl::optional<SelfParam> self,
+ Defaultness defaultness, location_t locus);
// Copy constructor with clone
Function (Function const &other);
@@ -1041,9 +1047,13 @@ public:
// TODO: is this better? Or is a "vis_block" better?
Type &get_return_type () { return *return_type; }
- bool is_method () const { return !self.is_error (); }
+ bool is_method () const { return self.has_value (); }
+
+ tl::optional<SelfParam> &get_self_param () { return self; }
+ const tl::optional<SelfParam> &get_self_param () const { return self; }
- SelfParam &get_self_param () { return self; }
+ SelfParam &get_self_param_unchecked () { return self.value (); }
+ const SelfParam &get_self_param_unchecked () const { return self.value (); }
std::string get_impl_item_name () const override final
{
@@ -1898,13 +1908,14 @@ private:
std::vector<FunctionParam> function_params;
std::unique_ptr<Type> return_type;
WhereClause where_clause;
- SelfParam self;
+ tl::optional<SelfParam> self;
public:
// Mega-constructor
TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam>> generic_params,
- SelfParam self, std::vector<FunctionParam> function_params,
+ tl::optional<SelfParam> self,
+ std::vector<FunctionParam> function_params,
std::unique_ptr<Type> return_type,
WhereClause where_clause);
@@ -1936,9 +1947,13 @@ public:
WhereClause &get_where_clause () { return where_clause; }
- bool is_method () const { return !self.is_error (); }
+ bool is_method () const { return self.has_value (); }
+
+ SelfParam &get_self_unchecked () { return self.value (); }
+ const SelfParam &get_self_unchecked () const { return self.value (); }
- SelfParam &get_self () { return self; }
+ tl::optional<SelfParam> &get_self () { return self; }
+ const tl::optional<SelfParam> &get_self () const { return self; }
Identifier get_function_name () const { return function_name; }
diff --git a/gcc/rust/hir/tree/rust-hir-type.cc b/gcc/rust/hir/tree/rust-hir-type.cc
index 6a6c319..ec48425 100644
--- a/gcc/rust/hir/tree/rust-hir-type.cc
+++ b/gcc/rust/hir/tree/rust-hir-type.cc
@@ -162,7 +162,7 @@ RawPointerType::operator= (RawPointerType const &other)
ReferenceType::ReferenceType (Analysis::NodeMapping mappings, Mutability mut,
std::unique_ptr<Type> type_no_bounds,
- location_t locus, Lifetime lifetime)
+ location_t locus, tl::optional<Lifetime> lifetime)
: TypeNoBounds (mappings, locus), lifetime (std::move (lifetime)), mut (mut),
type (std::move (type_no_bounds))
{}
diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
index bd0f2b6..cbc20ff 100644
--- a/gcc/rust/hir/tree/rust-hir-type.h
+++ b/gcc/rust/hir/tree/rust-hir-type.h
@@ -291,7 +291,7 @@ protected:
class ReferenceType : public TypeNoBounds
{
// bool has_lifetime; // TODO: handle in lifetime or something?
- Lifetime lifetime;
+ tl::optional<Lifetime> lifetime;
Mutability mut;
std::unique_ptr<Type> type;
@@ -301,12 +301,12 @@ public:
bool is_mut () const { return mut == Mutability::Mut; }
// Returns whether the reference has a lifetime.
- bool has_lifetime () const { return !lifetime.is_error (); }
+ bool has_lifetime () const { return lifetime.has_value (); }
// Constructor
ReferenceType (Analysis::NodeMapping mappings, Mutability mut,
std::unique_ptr<Type> type_no_bounds, location_t locus,
- Lifetime lifetime);
+ tl::optional<Lifetime> lifetime);
// Copy constructor with custom clone method
ReferenceType (ReferenceType const &other);
@@ -323,7 +323,8 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRTypeVisitor &vis) override;
- Lifetime &get_lifetime () { return lifetime; }
+ Lifetime &get_lifetime () { return lifetime.value (); }
+ const Lifetime &get_lifetime () const { return lifetime.value (); }
Mutability get_mut () const { return mut; }
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index 822eaff..c8bf9da 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -1314,7 +1314,7 @@ ContinueExpr::as_string () const
if (has_label ())
{
- str += label.as_string ();
+ str += get_label ().as_string ();
}
return str;
@@ -1704,7 +1704,7 @@ WhileLoopExpr::as_string () const
}
else
{
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
}
str += "\n Conditional expr: " + condition->as_string ();
@@ -1726,7 +1726,7 @@ WhileLetLoopExpr::as_string () const
}
else
{
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
}
str += "\n Match arm patterns: ";
@@ -1761,7 +1761,7 @@ LoopExpr::as_string () const
}
else
{
- str += loop_label.as_string ();
+ str += get_loop_label ().as_string ();
}
str += "\n Loop block: " + loop_block->as_string ();
@@ -1816,7 +1816,7 @@ BreakExpr::as_string () const
if (has_label ())
{
- str += label.as_string () + " ";
+ str += get_label ().as_string () + " ";
}
if (has_break_expr ())
@@ -2101,11 +2101,6 @@ QualifiedPathInType::as_string () const
std::string
Lifetime::as_string () const
{
- if (is_error ())
- {
- return "error lifetime";
- }
-
switch (lifetime_type)
{
case AST::Lifetime::LifetimeType::NAMED:
@@ -2760,7 +2755,7 @@ ReferenceType::as_string () const
if (has_lifetime ())
{
- str += lifetime.as_string () + " ";
+ str += get_lifetime ().as_string () + " ";
}
if (is_mut ())
@@ -3411,7 +3406,7 @@ TraitFunctionDecl::as_string () const
str += "\n Function params: ";
if (is_method ())
{
- str += self.as_string () + (has_params () ? ", " : "");
+ str += get_self_unchecked ().as_string () + (has_params () ? ", " : "");
}
if (has_params ())
@@ -3525,70 +3520,63 @@ TraitItemType::as_string () const
std::string
SelfParam::as_string () const
{
- if (is_error ())
- {
- return "error";
- }
- else
+ if (has_type ())
{
- if (has_type ())
+ // type (i.e. not ref, no lifetime)
+ std::string str;
+
+ if (is_mut ())
{
- // type (i.e. not ref, no lifetime)
- std::string str;
+ str += "mut ";
+ }
- if (is_mut ())
- {
- str += "mut ";
- }
+ str += "self : ";
- str += "self : ";
+ str += type->as_string ();
- str += type->as_string ();
+ return str;
+ }
+ else if (has_lifetime ())
+ {
+ // ref and lifetime
+ std::string str = "&" + get_lifetime ().as_string () + " ";
- return str;
- }
- else if (has_lifetime ())
+ if (is_mut ())
{
- // ref and lifetime
- std::string str = "&" + lifetime.as_string () + " ";
+ str += "mut ";
+ }
- if (is_mut ())
- {
- str += "mut ";
- }
+ str += "self";
- str += "self";
+ return str;
+ }
+ else if (is_ref ())
+ {
+ // ref with no lifetime
+ std::string str = "&";
- return str;
- }
- else if (is_ref ())
+ if (is_mut ())
{
- // ref with no lifetime
- std::string str = "&";
+ str += " mut ";
+ }
- if (is_mut ())
- {
- str += " mut ";
- }
+ str += "self";
- str += "self";
+ return str;
+ }
+ else
+ {
+ // no ref, no type
+ std::string str;
- return str;
- }
- else
+ if (is_mut ())
{
- // no ref, no type
- std::string str;
-
- if (is_mut ())
- {
- str += "mut ";
- }
+ str += "mut ";
+ }
- str += "self";
+ str += "self";
- return str;
- }
+ return str;
}
}
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 71d7250..3bb758e 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -3102,7 +3102,7 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token)
{
case LIFETIME: {
auto lifetime = parse_lifetime (false);
- if (lifetime.is_error ())
+ if (!lifetime)
{
rust_error_at (
token->get_locus (),
@@ -3122,7 +3122,7 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token)
}
param = std::unique_ptr<AST::LifetimeParam> (new AST::LifetimeParam (
- std::move (lifetime), std::move (lifetime_bounds),
+ std::move (lifetime.value ()), std::move (lifetime_bounds),
std::move (outer_attrs), token->get_locus ()));
break;
}
@@ -3276,16 +3276,16 @@ Parser<ManagedTokenSource>::parse_lifetime_params ()
while (lexer.peek_token ()->get_id () != END_OF_FILE)
{
- AST::LifetimeParam lifetime_param = parse_lifetime_param ();
+ auto lifetime_param = parse_lifetime_param ();
- if (lifetime_param.is_error ())
+ if (!lifetime_param)
{
// can't treat as error as only way to get out with trailing comma
break;
}
lifetime_params.push_back (std::unique_ptr<AST::LifetimeParam> (
- new AST::LifetimeParam (std::move (lifetime_param))));
+ new AST::LifetimeParam (std::move (lifetime_param.value ()))));
if (lexer.peek_token ()->get_id () != COMMA)
break;
@@ -3311,9 +3311,9 @@ Parser<ManagedTokenSource>::parse_lifetime_params (EndTokenPred is_end_token)
// if end_token is not specified, it defaults to EOF, so should work fine
while (!is_end_token (lexer.peek_token ()->get_id ()))
{
- AST::LifetimeParam lifetime_param = parse_lifetime_param ();
+ auto lifetime_param = parse_lifetime_param ();
- if (lifetime_param.is_error ())
+ if (!lifetime_param)
{
/* TODO: is it worth throwing away all lifetime params just because
* one failed? */
@@ -3351,9 +3351,9 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs ()
// bad control structure as end token cannot be guaranteed
while (true)
{
- AST::LifetimeParam lifetime_param = parse_lifetime_param ();
+ auto lifetime_param = parse_lifetime_param ();
- if (lifetime_param.is_error ())
+ if (!lifetime_param)
{
// not an error as only way to exit if trailing comma
break;
@@ -3386,9 +3386,9 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs (
while (!is_end_token (lexer.peek_token ()->get_id ()))
{
- AST::LifetimeParam lifetime_param = parse_lifetime_param ();
+ auto lifetime_param = parse_lifetime_param ();
- if (lifetime_param.is_error ())
+ if (!lifetime_param)
{
/* TODO: is it worth throwing away all lifetime params just because
* one failed? */
@@ -3399,7 +3399,7 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs (
return {};
}
- lifetime_params.push_back (std::move (lifetime_param));
+ lifetime_params.push_back (std::move (lifetime_param.value ()));
if (lexer.peek_token ()->get_id () != COMMA)
break;
@@ -3458,7 +3458,7 @@ Parser<ManagedTokenSource>::parse_non_ptr_sequence (
/* Parses a single lifetime generic parameter (not including comma). */
template <typename ManagedTokenSource>
-AST::LifetimeParam
+tl::expected<AST::LifetimeParam, ParseLifetimeParamError>
Parser<ManagedTokenSource>::parse_lifetime_param ()
{
// parse outer attributes, which are optional and may not exist
@@ -3468,8 +3468,8 @@ Parser<ManagedTokenSource>::parse_lifetime_param ()
const_TokenPtr lifetime_tok = lexer.peek_token ();
if (lifetime_tok->get_id () != LIFETIME)
{
- // if lifetime is missing, must not be a lifetime param, so return null
- return AST::LifetimeParam::create_error ();
+ // if lifetime is missing, must not be a lifetime param, so return error
+ return tl::make_unexpected<ParseLifetimeParamError> ({});
}
lexer.skip_token ();
AST::Lifetime lifetime (AST::Lifetime::NAMED, lifetime_tok->get_str (),
@@ -3815,12 +3815,13 @@ template <typename ManagedTokenSource>
std::unique_ptr<AST::LifetimeWhereClauseItem>
Parser<ManagedTokenSource>::parse_lifetime_where_clause_item ()
{
- AST::Lifetime lifetime = parse_lifetime (false);
- if (lifetime.is_error ())
+ auto parsed_lifetime = parse_lifetime (false);
+ if (!parsed_lifetime)
{
// TODO: error here?
return nullptr;
}
+ auto lifetime = parsed_lifetime.value ();
if (!skip_token (COLON))
{
@@ -4013,7 +4014,7 @@ Parser<ManagedTokenSource>::parse_type_param_bound ()
{
case LIFETIME:
return std::unique_ptr<AST::Lifetime> (
- new AST::Lifetime (parse_lifetime (false)));
+ new AST::Lifetime (parse_lifetime (false).value ()));
case LEFT_PAREN:
case QUESTION_MARK:
case FOR:
@@ -4086,13 +4087,13 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds ()
while (true)
{
- AST::Lifetime lifetime = parse_lifetime (false);
+ auto lifetime = parse_lifetime (false);
// quick exit for parsing failure
- if (lifetime.is_error ())
+ if (!lifetime)
break;
- lifetime_bounds.push_back (std::move (lifetime));
+ lifetime_bounds.push_back (std::move (lifetime.value ()));
/* plus is maybe not allowed at end - spec defines it weirdly, so
* assuming allowed at end */
@@ -4116,9 +4117,9 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token)
while (!is_end_token (lexer.peek_token ()->get_id ()))
{
- AST::Lifetime lifetime = parse_lifetime (false);
+ auto lifetime = parse_lifetime (false);
- if (lifetime.is_error ())
+ if (!lifetime)
{
/* TODO: is it worth throwing away all lifetime bound info just
* because one failed? */
@@ -4129,7 +4130,7 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token)
return {};
}
- lifetime_bounds.push_back (std::move (lifetime));
+ lifetime_bounds.push_back (std::move (lifetime.value ()));
/* plus is maybe not allowed at end - spec defines it weirdly, so
* assuming allowed at end */
@@ -4146,14 +4147,20 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token)
/* Parses a lifetime token (named, 'static, or '_). Also handles lifetime not
* existing. */
template <typename ManagedTokenSource>
-AST::Lifetime
+tl::expected<AST::Lifetime, ParseLifetimeError>
Parser<ManagedTokenSource>::parse_lifetime (bool allow_elided)
{
const_TokenPtr lifetime_tok = lexer.peek_token ();
if (lifetime_tok->get_id () != LIFETIME)
{
- return (allow_elided) ? AST::Lifetime::elided ()
- : AST::Lifetime::error ();
+ if (allow_elided)
+ {
+ return AST::Lifetime::elided ();
+ }
+ else
+ {
+ return tl::make_unexpected<ParseLifetimeError> ({});
+ }
}
lexer.skip_token ();
@@ -6340,14 +6347,14 @@ Parser<ManagedTokenSource>::parse_path_generic_args ()
location_t locus = t->get_locus ();
while (!is_right_angle_tok (t->get_id ()))
{
- AST::Lifetime lifetime = parse_lifetime (false);
- if (lifetime.is_error ())
+ auto lifetime = parse_lifetime (false);
+ if (!lifetime)
{
// not necessarily an error
break;
}
- lifetime_args.push_back (std::move (lifetime));
+ lifetime_args.push_back (std::move (lifetime.value ()));
// if next token isn't comma, then it must be end of list
if (lexer.peek_token ()->get_id () != COMMA)
@@ -6961,10 +6968,12 @@ Parser<ManagedTokenSource>::parse_self_param ()
// now test whether it has a lifetime
if (lexer.peek_token ()->get_id () == LIFETIME)
{
- lifetime = parse_lifetime (true);
-
// something went wrong somehow
- if (lifetime.is_error ())
+ if (auto parsed_lifetime = parse_lifetime (true))
+ {
+ lifetime = parsed_lifetime.value ();
+ }
+ else
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse lifetime in self param");
@@ -7153,9 +7162,9 @@ Parser<ManagedTokenSource>::parse_expr_stmt (AST::AttrVec outer_attrs,
// Parses a block expression, including the curly braces at start and end.
template <typename ManagedTokenSource>
std::unique_ptr<AST::BlockExpr>
-Parser<ManagedTokenSource>::parse_block_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label,
- location_t pratt_parsed_loc)
+Parser<ManagedTokenSource>::parse_block_expr (
+ AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label,
+ location_t pratt_parsed_loc)
{
location_t locus = pratt_parsed_loc;
if (locus == UNKNOWN_LOCATION)
@@ -7519,12 +7528,10 @@ Parser<ManagedTokenSource>::parse_break_expr (AST::AttrVec outer_attrs,
skip_token (BREAK);
}
- // parse label (lifetime) if it exists - create dummy first
- AST::Lifetime label = AST::Lifetime::error ();
- if (lexer.peek_token ()->get_id () == LIFETIME)
- {
- label = parse_lifetime (false);
- }
+ auto parsed_label = parse_lifetime (false);
+ auto label = (parsed_label)
+ ? tl::optional<AST::Lifetime> (parsed_label.value ())
+ : tl::nullopt;
// parse break return expression if it exists
ParseRestrictions restrictions;
@@ -7550,12 +7557,10 @@ Parser<ManagedTokenSource>::parse_continue_expr (AST::AttrVec outer_attrs,
skip_token (CONTINUE);
}
- // parse label (lifetime) if it exists - create dummy first
- AST::Lifetime label = AST::Lifetime::error ();
- if (lexer.peek_token ()->get_id () == LIFETIME)
- {
- label = parse_lifetime (false);
- }
+ auto parsed_label = parse_lifetime (false);
+ auto label = (parsed_label)
+ ? tl::optional<AST::Lifetime> (parsed_label.value ())
+ : tl::nullopt;
return std::unique_ptr<AST::ContinueExpr> (
new AST::ContinueExpr (std::move (label), std::move (outer_attrs), locus));
@@ -7563,14 +7568,15 @@ Parser<ManagedTokenSource>::parse_continue_expr (AST::AttrVec outer_attrs,
// Parses a loop label used in loop expressions.
template <typename ManagedTokenSource>
-AST::LoopLabel
+tl::expected<AST::LoopLabel, ParseLoopLabelError>
Parser<ManagedTokenSource>::parse_loop_label (const_TokenPtr tok)
{
// parse lifetime - if doesn't exist, assume no label
if (tok->get_id () != LIFETIME)
{
// not necessarily an error
- return AST::LoopLabel::error ();
+ return tl::unexpected<ParseLoopLabelError> (
+ ParseLoopLabelError::NOT_LOOP_LABEL);
}
/* FIXME: check for named lifetime requirement here? or check in semantic
* analysis phase? */
@@ -7579,10 +7585,12 @@ Parser<ManagedTokenSource>::parse_loop_label (const_TokenPtr tok)
if (!skip_token (COLON))
{
// skip somewhere?
- return AST::LoopLabel::error ();
+ return tl::unexpected<ParseLoopLabelError> (
+ ParseLoopLabelError::MISSING_COLON);
}
- return AST::LoopLabel (std::move (label), tok->get_locus ());
+ return tl::expected<AST::LoopLabel, ParseLoopLabelError> (
+ AST::LoopLabel (std::move (label), tok->get_locus ()));
}
/* Parses an if expression of any kind, including with else, else if, else if
@@ -7935,16 +7943,16 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec outer_attrs,
template <typename ManagedTokenSource>
std::unique_ptr<AST::LoopExpr>
Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label,
+ tl::optional<AST::LoopLabel> label,
location_t pratt_parsed_loc)
{
location_t locus = pratt_parsed_loc;
if (locus == UNKNOWN_LOCATION)
{
- if (label.is_error ())
- locus = lexer.peek_token ()->get_locus ();
+ if (label)
+ locus = label->get_locus ();
else
- locus = label.get_locus ();
+ locus = lexer.peek_token ()->get_locus ();
if (!skip_token (LOOP))
{
@@ -7954,8 +7962,8 @@ Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs,
}
else
{
- if (!label.is_error ())
- locus = label.get_locus ();
+ if (label)
+ locus = label->get_locus ();
}
// parse loop body, which is required
@@ -7978,17 +7986,17 @@ Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs,
* via parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
std::unique_ptr<AST::WhileLoopExpr>
-Parser<ManagedTokenSource>::parse_while_loop_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label,
- location_t pratt_parsed_loc)
+Parser<ManagedTokenSource>::parse_while_loop_expr (
+ AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label,
+ location_t pratt_parsed_loc)
{
location_t locus = pratt_parsed_loc;
if (locus == UNKNOWN_LOCATION)
{
- if (label.is_error ())
- locus = lexer.peek_token ()->get_locus ();
+ if (label)
+ locus = label->get_locus ();
else
- locus = label.get_locus ();
+ locus = lexer.peek_token ()->get_locus ();
if (!skip_token (WHILE))
{
@@ -7998,8 +8006,8 @@ Parser<ManagedTokenSource>::parse_while_loop_expr (AST::AttrVec outer_attrs,
}
else
{
- if (!label.is_error ())
- locus = label.get_locus ();
+ if (label)
+ locus = label->get_locus ();
}
// ensure it isn't a while let loop
@@ -8051,14 +8059,14 @@ Parser<ManagedTokenSource>::parse_while_loop_expr (AST::AttrVec outer_attrs,
* parsed via parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
std::unique_ptr<AST::WhileLetLoopExpr>
-Parser<ManagedTokenSource>::parse_while_let_loop_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label)
+Parser<ManagedTokenSource>::parse_while_let_loop_expr (
+ AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label)
{
location_t locus = UNKNOWN_LOCATION;
- if (label.is_error ())
- locus = lexer.peek_token ()->get_locus ();
+ if (label)
+ locus = label->get_locus ();
else
- locus = label.get_locus ();
+ locus = lexer.peek_token ()->get_locus ();
maybe_skip_token (WHILE);
/* check for possible accidental recognition of a while loop as a while let
@@ -8125,14 +8133,14 @@ Parser<ManagedTokenSource>::parse_while_let_loop_expr (AST::AttrVec outer_attrs,
* parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
std::unique_ptr<AST::ForLoopExpr>
-Parser<ManagedTokenSource>::parse_for_loop_expr (AST::AttrVec outer_attrs,
- AST::LoopLabel label)
+Parser<ManagedTokenSource>::parse_for_loop_expr (
+ AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label)
{
location_t locus = UNKNOWN_LOCATION;
- if (label.is_error ())
- locus = lexer.peek_token ()->get_locus ();
+ if (label)
+ locus = label->get_locus ();
else
- locus = label.get_locus ();
+ locus = lexer.peek_token ()->get_locus ();
maybe_skip_token (FOR);
// parse pattern, which is required
@@ -8210,8 +8218,9 @@ Parser<ManagedTokenSource>::parse_labelled_loop_expr (const_TokenPtr tok,
}
// parse loop label (required)
- AST::LoopLabel label = parse_loop_label (tok);
- if (label.is_error ())
+ // TODO: Convert this return type to tl::expected instead of tl::optional
+ auto parsed_label = parse_loop_label (tok);
+ if (!parsed_label)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse loop label in labelled loop expr");
@@ -8221,6 +8230,10 @@ Parser<ManagedTokenSource>::parse_labelled_loop_expr (const_TokenPtr tok,
return nullptr;
}
+ auto label = parsed_label
+ ? tl::optional<AST::LoopLabel> (parsed_label.value ())
+ : tl::nullopt;
+
// branch on next token
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
@@ -9598,8 +9611,12 @@ Parser<ManagedTokenSource>::parse_reference_type_inner (location_t locus)
AST::Lifetime lifetime = AST::Lifetime::elided ();
if (lexer.peek_token ()->get_id () == LIFETIME)
{
- lifetime = parse_lifetime (true);
- if (lifetime.is_error ())
+ auto parsed_lifetime = parse_lifetime (true);
+ if (parsed_lifetime)
+ {
+ lifetime = parsed_lifetime.value ();
+ }
+ else
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse lifetime in reference type");
@@ -12400,8 +12417,8 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
return parse_continue_expr (std::move (outer_attrs), tok->get_locus ());
case LEFT_CURLY:
// ok - this is an expression with block for once.
- return parse_block_expr (std::move (outer_attrs),
- AST::LoopLabel::error (), tok->get_locus ());
+ return parse_block_expr (std::move (outer_attrs), tl::nullopt,
+ tok->get_locus ());
case IF:
// if or if let, so more lookahead to find out
if (lexer.peek_token ()->get_id () == LET)
@@ -12417,7 +12434,7 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
case LIFETIME:
return parse_labelled_loop_expr (tok, std::move (outer_attrs));
case LOOP:
- return parse_loop_expr (std::move (outer_attrs), AST::LoopLabel::error (),
+ return parse_loop_expr (std::move (outer_attrs), tl::nullopt,
tok->get_locus ());
case WHILE:
if (lexer.peek_token ()->get_id () == LET)
@@ -12426,13 +12443,11 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
}
else
{
- return parse_while_loop_expr (std::move (outer_attrs),
- AST::LoopLabel::error (),
+ return parse_while_loop_expr (std::move (outer_attrs), tl::nullopt,
tok->get_locus ());
}
case FOR:
- return parse_for_loop_expr (std::move (outer_attrs),
- AST::LoopLabel::error ());
+ return parse_for_loop_expr (std::move (outer_attrs), tl::nullopt);
case MATCH_KW:
// also an expression with block
return parse_match_expr (std::move (outer_attrs), tok->get_locus ());
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 6c50ba9..ff79879 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -25,6 +25,26 @@ along with GCC; see the file COPYING3. If not see
#include "expected.h"
namespace Rust {
+
+class ParseLifetimeParamError
+{
+};
+
+class ParseLifetimeError
+{
+};
+enum class ParseLoopLabelError
+{
+ NOT_LOOP_LABEL,
+ MISSING_COLON,
+};
+enum ParseSelfError
+{
+ SELF_PTR,
+ PARSING,
+ NOT_SELF,
+};
+
/* HACK: used to resolve the expression-or-statement problem at the end of a
* block by allowing either to be returned (technically). Tagged union would
* probably take up the same amount of space. */
@@ -95,12 +115,6 @@ struct ParseRestrictions
bool allow_close_after_expr_stmt = false;
};
-enum ParseSelfError
-{
- SELF_PTR,
- PARSING,
- NOT_SELF,
-};
// Parser implementation for gccrs.
// TODO: if updated to C++20, ManagedTokenSource would be useful as a concept
template <typename ManagedTokenSource> class Parser
@@ -148,7 +162,7 @@ public:
std::unique_ptr<AST::BlockExpr>
parse_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error (),
+ tl::optional<AST::LoopLabel> = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
bool is_macro_rules_def (const_TokenPtr t);
@@ -277,7 +291,8 @@ private:
ParseFunction parsing_function, EndTokenPred is_end_token,
std::string error_msg = "failed to parse generic param in generic params")
-> std::vector<decltype (parsing_function ())>;
- AST::LifetimeParam parse_lifetime_param ();
+ tl::expected<AST::LifetimeParam, ParseLifetimeParamError>
+ parse_lifetime_param ();
std::vector<std::unique_ptr<AST::TypeParam>> parse_type_params ();
template <typename EndTokenPred>
std::vector<std::unique_ptr<AST::TypeParam>>
@@ -306,7 +321,8 @@ private:
std::vector<AST::Lifetime> parse_lifetime_bounds ();
template <typename EndTokenPred>
std::vector<AST::Lifetime> parse_lifetime_bounds (EndTokenPred is_end_token);
- AST::Lifetime parse_lifetime (bool allow_elided);
+ tl::expected<AST::Lifetime, ParseLifetimeError>
+ parse_lifetime (bool allow_elided);
AST::Lifetime lifetime_from_token (const_TokenPtr tok);
std::unique_ptr<AST::ExternalTypeItem>
parse_external_type_item (AST::Visibility vis, AST::AttrVec outer_attrs);
@@ -588,18 +604,18 @@ private:
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::LoopExpr>
parse_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error (),
+ tl::optional<AST::LoopLabel> label = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::WhileLoopExpr>
parse_while_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error (),
+ tl::optional<AST::LoopLabel> label = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::WhileLetLoopExpr>
parse_while_let_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error ());
+ tl::optional<AST::LoopLabel> label = tl::nullopt);
std::unique_ptr<AST::ForLoopExpr>
parse_for_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
- AST::LoopLabel label = AST::LoopLabel::error ());
+ tl::optional<AST::LoopLabel> label = tl::nullopt);
std::unique_ptr<AST::MatchExpr>
parse_match_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
@@ -609,7 +625,8 @@ private:
std::unique_ptr<AST::Expr> parse_labelled_loop_expr (const_TokenPtr tok,
AST::AttrVec outer_attrs
= AST::AttrVec ());
- AST::LoopLabel parse_loop_label (const_TokenPtr tok);
+ tl::expected<AST::LoopLabel, ParseLoopLabelError>
+ parse_loop_label (const_TokenPtr tok);
std::unique_ptr<AST::AsyncBlockExpr>
parse_async_block_expr (AST::AttrVec outer_attrs = AST::AttrVec ());
std::unique_ptr<AST::GroupedExpr> parse_grouped_expr (AST::AttrVec outer_attrs
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
index 0d497f8..ab74e84 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -27,6 +27,11 @@
namespace Rust {
namespace Resolver {
+inline void
+redefined_error (const rich_location &loc)
+{
+ rust_error_at (loc, "redefined multiple times");
+}
class ResolverBase : public AST::ASTVisitor
{
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index dc7f76d..8070fc1 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -471,7 +471,7 @@ ResolveExpr::visit (AST::BreakExpr &expr)
{
if (expr.has_label ())
{
- auto label = expr.get_label ().get_lifetime ();
+ auto label = expr.get_label_unchecked ().get_lifetime ();
if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED)
{
rust_error_at (label.get_locus (),
@@ -486,8 +486,8 @@ ResolveExpr::visit (AST::BreakExpr &expr)
&resolved_node))
{
rust_error_at (label.get_locus (), ErrorCode::E0426,
- "use of undeclared label %qs in %<break%>",
- label.get_lifetime_name ().c_str ());
+ "use of undeclared label %qs",
+ label.as_string ().c_str ());
return;
}
resolver->insert_resolved_label (label.get_node_id (), resolved_node);
@@ -594,7 +594,7 @@ ResolveExpr::visit (AST::ContinueExpr &expr)
{
if (expr.has_label ())
{
- auto label = expr.get_label ();
+ auto label = expr.get_label_unchecked ();
if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED)
{
rust_error_at (label.get_locus (),
@@ -608,9 +608,9 @@ ResolveExpr::visit (AST::ContinueExpr &expr)
label.get_lifetime_name ()),
&resolved_node))
{
- rust_error_at (expr.get_label ().get_locus (), ErrorCode::E0426,
- "use of undeclared label %qs in %<continue%>",
- label.get_lifetime_name ().c_str ());
+ rust_error_at (expr.get_label_unchecked ().get_locus (),
+ ErrorCode::E0426, "use of undeclared label %qs",
+ label.as_string ().c_str ());
return;
}
resolver->insert_resolved_label (label.get_node_id (), resolved_node);
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index 971bf8f..2081697 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -51,7 +51,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, type.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
}
@@ -67,7 +67,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, constant.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
}
@@ -84,7 +84,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
}
@@ -124,7 +124,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (function.get_node_id (), cpath);
@@ -144,7 +144,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, constant.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (constant.get_node_id (), cpath);
@@ -162,7 +162,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, type.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (type.get_node_id (), cpath);
@@ -202,7 +202,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -221,7 +221,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -239,8 +239,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, type.get_locus ());
r.add_range (locus);
-
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index d584961..30f6d43 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -356,6 +356,8 @@ ResolveItem::visit (AST::EnumItemDiscriminant &item)
auto cpath = canonical_prefix.append (decl);
mappings.insert_canonical_path (item.get_node_id (), cpath);
+
+ ResolveExpr::go (item.get_expr (), path, cpath);
}
void
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.cc b/gcc/rust/resolve/rust-ast-resolve-stmt.cc
index fefb522..bfba302 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.cc
@@ -70,7 +70,7 @@ ResolveStmt::visit (AST::StaticItem &var)
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, var.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
ResolveType::go (var.get_type ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index 6c99d6a..d413a7c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -63,7 +63,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, constant.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
ResolveType::go (constant.get_type ());
@@ -98,7 +98,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, struct_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = struct_decl.get_node_id ();
@@ -129,7 +129,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, enum_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = enum_decl.get_node_id ();
@@ -159,7 +159,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
// Done, no fields.
@@ -179,7 +179,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
for (auto &field : item.get_tuple_fields ())
@@ -205,7 +205,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
for (auto &field : item.get_struct_fields ())
@@ -231,7 +231,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
// Done, no fields.
@@ -252,7 +252,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, struct_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = struct_decl.get_node_id ();
@@ -288,7 +288,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, union_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = union_decl.get_node_id ();
@@ -324,7 +324,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId scope_node_id = function.get_node_id ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 379ccab..f52fb8a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -58,7 +58,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, module.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -88,7 +88,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, alias.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -110,7 +110,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, struct_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -132,7 +132,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, enum_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
resolver->push_new_module_scope (enum_decl.get_node_id ());
@@ -158,7 +158,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (item.get_node_id (), cpath);
@@ -180,7 +180,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (item.get_node_id (), cpath);
@@ -202,7 +202,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (item.get_node_id (), cpath);
@@ -224,7 +224,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, item.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
mappings.insert_canonical_path (item.get_node_id (), cpath);
@@ -246,7 +246,7 @@ public:
= [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, struct_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
};
resolver->get_type_scope ().insert (path, struct_decl.get_node_id (),
@@ -277,7 +277,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, union_decl.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -297,7 +297,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, var.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -318,7 +318,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, constant.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -340,7 +340,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
NodeId current_module = resolver->peek_current_module_scope ();
@@ -388,7 +388,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, impl_block.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
for (auto &impl_item : impl_block.get_impl_items ())
@@ -408,7 +408,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, trait.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
for (auto &item : trait.get_trait_items ())
@@ -480,7 +480,7 @@ public:
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, extern_crate.get_locus ());
r.add_range (locus);
- rust_error_at (r, "defined multiple times");
+ redefined_error (r);
});
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index 5ab0c44..606141c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -357,7 +357,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
{
rust_error_at (segment->get_locus (), ErrorCode::E0412,
"could not resolve type path %qs",
- segment->as_string ().c_str ());
+ segment->get_ident_segment ().as_string ().c_str ());
return false;
}
}
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 afaca1f..36456e1 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -325,10 +325,9 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
auto pm_def = mappings.lookup_derive_proc_macro_def (
definition->get_node_id ());
- rust_assert (pm_def.has_value ());
-
- mappings.insert_derive_proc_macro_invocation (trait,
- pm_def.value ());
+ if (pm_def.has_value ())
+ mappings.insert_derive_proc_macro_invocation (trait,
+ pm_def.value ());
}
}
else if (Analysis::BuiltinAttributeMappings::get ()
diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h
index f390e38..cf02651 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -549,6 +549,7 @@ public:
ForeverStack ()
: root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)),
lang_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)),
+ extern_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID)),
cursor_reference (root)
{
rust_assert (root.is_root ());
@@ -671,7 +672,7 @@ public:
*/
template <typename S>
tl::optional<Rib::Definition> resolve_path (
- const std::vector<S> &segments,
+ const std::vector<S> &segments, bool has_opening_scope_resolution,
std::function<void (const S &, NodeId)> insert_segment_resolution);
// FIXME: Documentation
@@ -768,6 +769,10 @@ private:
* resolution
*/
Node lang_prelude;
+ /*
+ * The extern prelude, used for resolving external crates
+ */
+ Node extern_prelude;
std::reference_wrapper<Node> cursor_reference;
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index 885f282..993e2d4 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -20,6 +20,7 @@
#include "rust-ast.h"
#include "rust-diagnostics.h"
#include "rust-forever-stack.h"
+#include "rust-edition.h"
#include "rust-rib.h"
#include "rust-unwrap-segment.h"
#include "optional.h"
@@ -618,11 +619,24 @@ template <Namespace N>
template <typename S>
tl::optional<Rib::Definition>
ForeverStack<N>::resolve_path (
- const std::vector<S> &segments,
+ const std::vector<S> &segments, bool has_opening_scope_resolution,
std::function<void (const S &, NodeId)> insert_segment_resolution)
{
// TODO: What to do if segments.empty() ?
+ // handle paths with opening scopes
+ std::function<void (void)> cleanup_current = [] () {};
+ if (has_opening_scope_resolution)
+ {
+ Node *last_current = &cursor_reference.get ();
+ if (get_rust_edition () == Edition::E2015)
+ cursor_reference = root;
+ else
+ cursor_reference = extern_prelude;
+ cleanup_current
+ = [this, last_current] () { cursor_reference = *last_current; };
+ }
+
// if there's only one segment, we just use `get`
if (segments.size () == 1)
{
@@ -633,6 +647,7 @@ ForeverStack<N>::resolve_path (
lang_item.value ());
insert_segment_resolution (seg, seg_id);
+ cleanup_current ();
// TODO: does NonShadowable matter?
return Rib::Definition::NonShadowable (seg_id);
}
@@ -646,40 +661,44 @@ ForeverStack<N>::resolve_path (
if (res && !res->is_ambiguous ())
insert_segment_resolution (segments.back (), res->get_node_id ());
+ cleanup_current ();
return res;
}
std::reference_wrapper<Node> starting_point = cursor ();
- return find_starting_point (segments, starting_point,
- insert_segment_resolution)
- .and_then ([this, &segments, &starting_point, &insert_segment_resolution] (
- typename std::vector<S>::const_iterator iterator) {
- return resolve_segments (starting_point.get (), segments, iterator,
- insert_segment_resolution);
- })
- .and_then ([this, &segments, &insert_segment_resolution] (
- Node final_node) -> tl::optional<Rib::Definition> {
- // leave resolution within impl blocks to type checker
- if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
- return tl::nullopt;
-
- auto &seg = unwrap_type_segment (segments.back ());
- std::string seg_name = seg.as_string ();
-
- // assuming this can't be a lang item segment
- tl::optional<Rib::Definition> res
- = resolve_final_segment (final_node, seg_name,
- seg.is_lower_self_seg ());
- // Ok we didn't find it in the rib, Lets try the prelude...
- if (!res)
- res = get_lang_prelude (seg_name);
-
- if (res && !res->is_ambiguous ())
- insert_segment_resolution (segments.back (), res->get_node_id ());
-
- return res;
- });
+ auto res
+ = find_starting_point (segments, starting_point, insert_segment_resolution)
+ .and_then (
+ [this, &segments, &starting_point, &insert_segment_resolution] (
+ typename std::vector<S>::const_iterator iterator) {
+ return resolve_segments (starting_point.get (), segments, iterator,
+ insert_segment_resolution);
+ })
+ .and_then ([this, &segments, &insert_segment_resolution] (
+ Node final_node) -> tl::optional<Rib::Definition> {
+ // leave resolution within impl blocks to type checker
+ if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
+ return tl::nullopt;
+
+ auto &seg = unwrap_type_segment (segments.back ());
+ std::string seg_name = seg.as_string ();
+
+ // assuming this can't be a lang item segment
+ tl::optional<Rib::Definition> res
+ = resolve_final_segment (final_node, seg_name,
+ seg.is_lower_self_seg ());
+ // Ok we didn't find it in the rib, Lets try the prelude...
+ if (!res)
+ res = get_lang_prelude (seg_name);
+
+ if (res && !res->is_ambiguous ())
+ insert_segment_resolution (segments.back (), res->get_node_id ());
+
+ return res;
+ });
+ cleanup_current ();
+ return res;
}
template <Namespace N>
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 7d32374..f743e1e 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -187,6 +187,9 @@ Late::visit (AST::SelfParam &param)
void
Late::visit (AST::BreakExpr &expr)
{
+ if (expr.has_label ())
+ resolve_label (expr.get_label_unchecked ().get_lifetime ());
+
if (expr.has_break_expr ())
{
auto &break_expr = expr.get_break_expr ();
@@ -213,6 +216,38 @@ Late::visit (AST::BreakExpr &expr)
}
void
+Late::visit (AST::LoopLabel &label)
+{
+ auto &lifetime = label.get_lifetime ();
+ ctx.labels.insert (Identifier (lifetime.as_string (), lifetime.get_locus ()),
+ lifetime.get_node_id ());
+}
+
+void
+Late::resolve_label (AST::Lifetime &lifetime)
+{
+ if (auto resolved = ctx.labels.get (lifetime.as_string ()))
+ {
+ if (resolved->get_node_id () != lifetime.get_node_id ())
+ ctx.map_usage (Usage (lifetime.get_node_id ()),
+ Definition (resolved->get_node_id ()));
+ }
+ else
+ rust_error_at (lifetime.get_locus (), ErrorCode::E0426,
+ "use of undeclared label %qs",
+ lifetime.as_string ().c_str ());
+}
+
+void
+Late::visit (AST::ContinueExpr &expr)
+{
+ if (expr.has_label ())
+ resolve_label (expr.get_label_unchecked ());
+
+ DefaultResolver::visit (expr);
+}
+
+void
Late::visit (AST::IdentifierExpr &expr)
{
// TODO: same thing as visit(PathInExpression) here?
@@ -307,8 +342,7 @@ Late::visit (AST::PathInExpression &expr)
return;
}
- auto resolved = ctx.resolve_path (expr.get_segments (), Namespace::Values,
- Namespace::Types);
+ auto resolved = ctx.resolve_path (expr, Namespace::Values, Namespace::Types);
if (!resolved)
{
@@ -340,13 +374,9 @@ Late::visit (AST::TypePath &type)
DefaultResolver::visit (type);
- // take care of only simple cases
- // TODO: remove this?
- rust_assert (!type.has_opening_scope_resolution_op ());
-
// this *should* mostly work
// TODO: make sure typepath-like path resolution (?) is working
- auto resolved = ctx.resolve_path (type.get_segments (), Namespace::Types);
+ auto resolved = ctx.resolve_path (type, Namespace::Types);
if (!resolved.has_value ())
{
@@ -394,8 +424,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 ().get_segments (), Namespace::Types);
+ 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 ()));
@@ -409,8 +438,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 ().get_segments (), Namespace::Types);
+ 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 ()));
@@ -427,8 +455,7 @@ Late::visit (AST::StructExprStructFields &s)
for (auto &field : s.get_fields ())
visit (field);
- auto resolved
- = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
+ 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 ()));
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 ac376b5..5703b15 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -48,6 +48,8 @@ public:
void visit (AST::IdentifierExpr &) override;
void visit (AST::StructExprFieldIdentifier &) override;
void visit (AST::BreakExpr &) override;
+ void visit (AST::ContinueExpr &) override;
+ void visit (AST::LoopLabel &) override;
void visit (AST::PathInExpression &) override;
void visit (AST::TypePath &) override;
void visit (AST::Trait &) override;
@@ -61,6 +63,8 @@ public:
void visit (AST::ClosureExprInnerTyped &) override;
private:
+ void resolve_label (AST::Lifetime &lifetime);
+
/* Setup Rust's builtin types (u8, i32, !...) in the resolver */
void setup_builtin_types ();
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h
index ea81bde..84c0800 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -221,6 +221,7 @@ public:
template <typename S>
tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments,
+ bool has_opening_scope_resolution,
Namespace ns)
{
std::function<void (const S &, NodeId)> insert_segment_resolution
@@ -232,13 +233,17 @@ public:
switch (ns)
{
case Namespace::Values:
- return values.resolve_path (segments, insert_segment_resolution);
+ return values.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution);
case Namespace::Types:
- return types.resolve_path (segments, insert_segment_resolution);
+ return types.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution);
case Namespace::Macros:
- return macros.resolve_path (segments, insert_segment_resolution);
+ return macros.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution);
case Namespace::Labels:
- return labels.resolve_path (segments, insert_segment_resolution);
+ return labels.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution);
default:
rust_unreachable ();
}
@@ -246,19 +251,45 @@ public:
template <typename S, typename... Args>
tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments,
+ bool has_opening_scope_resolution,
Args... ns_args)
{
std::initializer_list<Namespace> namespaces = {ns_args...};
for (auto ns : namespaces)
{
- if (auto ret = resolve_path (segments, ns))
+ if (auto ret
+ = resolve_path (segments, has_opening_scope_resolution, ns))
return ret;
}
return tl::nullopt;
}
+ template <typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const AST::SimplePath &path,
+ Args... ns_args)
+ {
+ return resolve_path (path.get_segments (),
+ path.has_opening_scope_resolution (), ns_args...);
+ }
+
+ template <typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const AST::PathInExpression &path,
+ Args... ns_args)
+ {
+ return resolve_path (path.get_segments (), path.opening_scope_resolution (),
+ ns_args...);
+ }
+
+ template <typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const AST::TypePath &path,
+ Args... ns_args)
+ {
+ return resolve_path (path.get_segments (),
+ path.has_opening_scope_resolution_op (), ns_args...);
+ }
+
private:
/* Map of "usage" nodes which have been resolved to a "definition" node */
std::map<Usage, Definition> resolved_nodes;
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 8863be7..ba37dee 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -113,7 +113,17 @@ TopLevel::visit (AST::Module &module)
// This was copied from the old early resolver method
// 'accumulate_escaped_macros'
if (module.get_kind () == AST::Module::UNLOADED)
- module.load_items ();
+ {
+ module.load_items ();
+
+ // If the module was previously unloaded, then we don't want to visit it
+ // this time around as the CfgStrip hasn't run on its inner items yet.
+ // Skip it for now, mark the visitor as dirty and try again
+
+ dirty = true;
+
+ return;
+ }
DefaultResolver::visit (module);
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index a6e8ea9..234721c 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -61,7 +61,7 @@
tree
Bvariable::get_tree (location_t location) const
{
- if (this->t_ == error_mark_node)
+ if (error_operand_p (this->t_))
return error_mark_node;
TREE_USED (this->t_) = 1;
@@ -431,7 +431,7 @@ float_type (int bits)
tree
pointer_type (tree to_type)
{
- if (to_type == error_mark_node)
+ if (error_operand_p (to_type))
return error_mark_node;
tree type = build_pointer_type (to_type);
return type;
@@ -442,7 +442,7 @@ pointer_type (tree to_type)
tree
reference_type (tree to_type)
{
- if (to_type == error_mark_node)
+ if (error_operand_p (to_type))
return error_mark_node;
tree type = build_reference_type (to_type);
return type;
@@ -453,7 +453,7 @@ reference_type (tree to_type)
tree
immutable_type (tree base)
{
- if (base == error_mark_node)
+ if (error_operand_p (base))
return error_mark_node;
tree constified = build_qualified_type (base, TYPE_QUAL_CONST);
return constified;
@@ -472,17 +472,16 @@ function_type (const typed_identifier &receiver,
if (receiver.type != NULL_TREE)
{
tree t = receiver.type;
- if (t == error_mark_node)
+ if (error_operand_p (t))
return error_mark_node;
*pp = tree_cons (NULL_TREE, t, NULL_TREE);
pp = &TREE_CHAIN (*pp);
}
- for (std::vector<typed_identifier>::const_iterator p = parameters.begin ();
- p != parameters.end (); ++p)
+ for (const auto &p : parameters)
{
- tree t = p->type;
- if (t == error_mark_node)
+ tree t = p.type;
+ if (error_operand_p (t))
return error_mark_node;
*pp = tree_cons (NULL_TREE, t, NULL_TREE);
pp = &TREE_CHAIN (*pp);
@@ -502,11 +501,11 @@ function_type (const typed_identifier &receiver,
gcc_assert (result_struct != NULL);
result = result_struct;
}
- if (result == error_mark_node)
+ if (error_operand_p (result))
return error_mark_node;
tree fntype = build_function_type (result, args);
- if (fntype == error_mark_node)
+ if (error_operand_p (fntype))
return error_mark_node;
return build_pointer_type (fntype);
@@ -521,21 +520,16 @@ function_type_variadic (const typed_identifier &receiver,
size_t n = parameters.size () + (receiver.type != NULL_TREE ? 1 : 0);
tree *args = XALLOCAVEC (tree, n);
size_t offs = 0;
+ if (error_operand_p (receiver.type))
+ return error_mark_node;
if (receiver.type != NULL_TREE)
- {
- tree t = receiver.type;
- if (t == error_mark_node)
- return error_mark_node;
+ args[offs++] = receiver.type;
- args[offs++] = t;
- }
-
- for (std::vector<typed_identifier>::const_iterator p = parameters.begin ();
- p != parameters.end (); ++p)
+ for (const auto &p : parameters)
{
- tree t = p->type;
- if (t == error_mark_node)
+ tree t = p.type;
+ if (error_operand_p (t))
return error_mark_node;
args[offs++] = t;
}
@@ -550,11 +544,11 @@ function_type_variadic (const typed_identifier &receiver,
gcc_assert (result_struct != NULL_TREE);
result = result_struct;
}
- if (result == error_mark_node)
+ if (error_operand_p (result))
return error_mark_node;
tree fntype = build_varargs_function_type_array (result, n, args);
- if (fntype == error_mark_node)
+ if (error_operand_p (fntype))
return error_mark_node;
return build_pointer_type (fntype);
@@ -569,7 +563,7 @@ function_ptr_type (tree result_type, const std::vector<tree> &parameters,
for (auto &param : parameters)
{
- if (param == error_mark_node)
+ if (error_operand_p (param))
return error_mark_node;
*pp = tree_cons (NULL_TREE, param, NULL_TREE);
@@ -583,7 +577,7 @@ function_ptr_type (tree result_type, const std::vector<tree> &parameters,
result = void_type_node;
tree fntype = build_function_type (result, args);
- if (fntype == error_mark_node)
+ if (error_operand_p (fntype))
return error_mark_node;
return build_pointer_type (fntype);
@@ -613,14 +607,13 @@ fill_in_fields (tree fill, const std::vector<typed_identifier> &fields,
{
tree field_trees = NULL_TREE;
tree *pp = &field_trees;
- for (std::vector<typed_identifier>::const_iterator p = fields.begin ();
- p != fields.end (); ++p)
+ for (const auto &p : fields)
{
- tree name_tree = get_identifier_from_string (p->name);
- tree type_tree = p->type;
- if (type_tree == error_mark_node)
+ tree name_tree = get_identifier_from_string (p.name);
+ tree type_tree = p.type;
+ if (error_operand_p (type_tree))
return error_mark_node;
- tree field = build_decl (p->location, FIELD_DECL, name_tree, type_tree);
+ tree field = build_decl (p.location, FIELD_DECL, name_tree, type_tree);
DECL_CONTEXT (field) = fill;
*pp = field;
pp = &DECL_CHAIN (field);
@@ -652,7 +645,7 @@ array_type (tree element_type, tree length)
tree
fill_in_array (tree fill, tree element_type, tree length_tree)
{
- if (element_type == error_mark_node || length_tree == error_mark_node)
+ if (error_operand_p (element_type) || error_operand_p (length_tree))
return error_mark_node;
gcc_assert (TYPE_SIZE (element_type) != NULL_TREE);
@@ -684,7 +677,7 @@ fill_in_array (tree fill, tree element_type, tree length_tree)
tree
named_type (const std::string &name, tree type, location_t location)
{
- if (type == error_mark_node)
+ if (error_operand_p (type))
return error_mark_node;
// The middle-end expects a basic type to have a name. In Rust every
@@ -714,7 +707,7 @@ named_type (const std::string &name, tree type, location_t location)
int64_t
type_size (tree t)
{
- if (t == error_mark_node)
+ if (error_operand_p (t))
return 1;
if (t == void_type_node)
return 0;
@@ -732,7 +725,7 @@ type_size (tree t)
int64_t
type_alignment (tree t)
{
- if (t == error_mark_node)
+ if (error_operand_p (t))
return 1;
return TYPE_ALIGN_UNIT (t);
}
@@ -742,7 +735,7 @@ type_alignment (tree t)
int64_t
type_field_alignment (tree t)
{
- if (t == error_mark_node)
+ if (error_operand_p (t))
return 1;
return rust_field_alignment (t);
}
@@ -752,7 +745,7 @@ type_field_alignment (tree t)
int64_t
type_field_offset (tree struct_tree, size_t index)
{
- if (struct_tree == error_mark_node)
+ if (error_operand_p (struct_tree))
return 0;
gcc_assert (TREE_CODE (struct_tree) == RECORD_TYPE);
tree field = TYPE_FIELDS (struct_tree);
@@ -773,7 +766,7 @@ tree
zero_expression (tree t)
{
tree ret;
- if (t == error_mark_node)
+ if (error_operand_p (t))
ret = error_mark_node;
else
ret = build_zero_cst (t);
@@ -794,7 +787,7 @@ tree
float_constant_expression (tree t, mpfr_t val)
{
tree ret;
- if (t == error_mark_node)
+ if (error_operand_p (t))
return error_mark_node;
REAL_VALUE_TYPE r1;
@@ -845,8 +838,7 @@ boolean_constant_expression (bool val)
tree
convert_expression (tree type_tree, tree expr_tree, location_t location)
{
- if (type_tree == error_mark_node || expr_tree == error_mark_node
- || TREE_TYPE (expr_tree) == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (expr_tree))
return error_mark_node;
tree ret;
@@ -878,8 +870,7 @@ convert_expression (tree type_tree, tree expr_tree, location_t location)
tree
struct_field_expression (tree struct_tree, size_t index, location_t location)
{
- if (struct_tree == error_mark_node
- || TREE_TYPE (struct_tree) == error_mark_node)
+ if (error_operand_p (struct_tree))
return error_mark_node;
gcc_assert (TREE_CODE (TREE_TYPE (struct_tree)) == RECORD_TYPE
|| TREE_CODE (TREE_TYPE (struct_tree)) == UNION_TYPE);
@@ -895,7 +886,7 @@ struct_field_expression (tree struct_tree, size_t index, location_t location)
field = DECL_CHAIN (field);
gcc_assert (field != NULL_TREE);
}
- if (TREE_TYPE (field) == error_mark_node)
+ if (error_operand_p (TREE_TYPE (field)))
return error_mark_node;
tree ret = fold_build3_loc (location, COMPONENT_REF, TREE_TYPE (field),
struct_tree, field, NULL_TREE);
@@ -909,7 +900,7 @@ struct_field_expression (tree struct_tree, size_t index, location_t location)
tree
compound_expression (tree stat, tree expr, location_t location)
{
- if (stat == error_mark_node || expr == error_mark_node)
+ if (error_operand_p (stat) || error_operand_p (expr))
return error_mark_node;
tree ret
= fold_build2_loc (location, COMPOUND_EXPR, TREE_TYPE (expr), stat, expr);
@@ -923,8 +914,8 @@ tree
conditional_expression (tree, tree type_tree, tree cond_expr, tree then_expr,
tree else_expr, location_t location)
{
- if (type_tree == error_mark_node || cond_expr == error_mark_node
- || then_expr == error_mark_node || else_expr == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (cond_expr)
+ || error_operand_p (then_expr) || error_operand_p (else_expr))
return error_mark_node;
tree ret = build3_loc (location, COND_EXPR, type_tree, cond_expr, then_expr,
else_expr);
@@ -1021,12 +1012,12 @@ operator_to_tree_code (LazyBooleanOperator op)
}
}
-/* Helper function for deciding if a tree is a floating point node. */
+/* Returns true if the type of EXP is a floating point type.
+ False otherwise. */
bool
-is_floating_point (tree t)
+is_floating_point (tree exp)
{
- auto tree_type = TREE_CODE (TREE_TYPE (t));
- return tree_type == REAL_TYPE || tree_type == COMPLEX_TYPE;
+ return FLOAT_TYPE_P (TREE_TYPE (exp));
}
// Return an expression for the negation operation OP EXPR.
@@ -1035,7 +1026,7 @@ negation_expression (NegationOperator op, tree expr_tree, location_t location)
{
/* Check if the expression is an error, in which case we return an error
expression. */
- if (expr_tree == error_mark_node || TREE_TYPE (expr_tree) == error_mark_node)
+ if (error_operand_p (expr_tree))
return error_mark_node;
/* For negation operators, the resulting type should be the same as its
@@ -1071,9 +1062,15 @@ arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op, tree left,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left == error_mark_node || right == error_mark_node)
+ if (error_operand_p (left) || error_operand_p (right))
return error_mark_node;
+ // unwrap the const decls if set
+ if (TREE_CODE (left) == CONST_DECL)
+ left = DECL_INITIAL (left);
+ if (TREE_CODE (right) == CONST_DECL)
+ right = DECL_INITIAL (right);
+
/* We need to determine if we're doing floating point arithmetics of integer
arithmetics. */
bool floating_point = is_floating_point (left);
@@ -1176,7 +1173,7 @@ arithmetic_or_logical_expression_checked (ArithmeticOrLogicalOperator op,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left == error_mark_node || right == error_mark_node)
+ if (error_operand_p (left) || error_operand_p (right))
return error_mark_node;
// FIXME: Add `if (!debug_mode)`
@@ -1216,7 +1213,7 @@ comparison_expression (ComparisonOperator op, tree left_tree, tree right_tree,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left_tree == error_mark_node || right_tree == error_mark_node)
+ if (error_operand_p (left_tree) || error_operand_p (right_tree))
return error_mark_node;
/* For comparison operators, the resulting type should be boolean. */
@@ -1236,7 +1233,7 @@ lazy_boolean_expression (LazyBooleanOperator op, tree left_tree,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left_tree == error_mark_node || right_tree == error_mark_node)
+ if (error_operand_p (left_tree) || error_operand_p (right_tree))
return error_mark_node;
/* For lazy boolean operators, the resulting type should be the same as the
@@ -1257,7 +1254,7 @@ constructor_expression (tree type_tree, bool is_variant,
const std::vector<tree> &vals, int union_index,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return error_mark_node;
vec<constructor_elt, va_gc> *init;
@@ -1299,8 +1296,8 @@ constructor_expression (tree type_tree, bool is_variant,
gcc_assert (field != NULL_TREE);
field = DECL_CHAIN (field);
}
- if (TREE_TYPE (field) == error_mark_node || val == error_mark_node
- || TREE_TYPE (val) == error_mark_node)
+
+ if (TREE_TYPE (field) == error_mark_node || error_operand_p (val))
return error_mark_node;
if (int_size_in_bytes (TREE_TYPE (field)) == 0)
@@ -1330,8 +1327,7 @@ constructor_expression (tree type_tree, bool is_variant,
{
gcc_assert (field != NULL_TREE);
tree val = (*p);
- if (TREE_TYPE (field) == error_mark_node || val == error_mark_node
- || TREE_TYPE (val) == error_mark_node)
+ if (TREE_TYPE (field) == error_mark_node || error_operand_p (val))
return error_mark_node;
if (int_size_in_bytes (TREE_TYPE (field)) == 0)
@@ -1370,7 +1366,7 @@ array_constructor_expression (tree type_tree,
const std::vector<tree> &vals,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return error_mark_node;
gcc_assert (indexes.size () == vals.size ());
@@ -1387,7 +1383,7 @@ array_constructor_expression (tree type_tree,
tree index = size_int (indexes[i]);
tree val = vals[i];
- if (index == error_mark_node || val == error_mark_node)
+ if (error_operand_p (index) || error_operand_p (val))
return error_mark_node;
if (element_size == 0)
@@ -1491,8 +1487,7 @@ array_initializer (tree fndecl, tree block, tree array_type, tree length,
tree
array_index_expression (tree array_tree, tree index_tree, location_t location)
{
- if (array_tree == error_mark_node || TREE_TYPE (array_tree) == error_mark_node
- || index_tree == error_mark_node)
+ if (error_operand_p (array_tree) || error_operand_p (index_tree))
return error_mark_node;
// A function call that returns a zero sized object will have been
@@ -1514,7 +1509,7 @@ tree
call_expression (tree fn, const std::vector<tree> &fn_args, tree chain_expr,
location_t location)
{
- if (fn == error_mark_node || TREE_TYPE (fn) == error_mark_node)
+ if (error_operand_p (fn))
return error_mark_node;
gcc_assert (FUNCTION_POINTER_TYPE_P (TREE_TYPE (fn)));
@@ -1594,7 +1589,7 @@ tree
init_statement (tree, Bvariable *var, tree init_tree)
{
tree var_tree = var->get_decl ();
- if (var_tree == error_mark_node || init_tree == error_mark_node)
+ if (error_operand_p (var_tree) || error_operand_p (init_tree))
return error_mark_node;
gcc_assert (TREE_CODE (var_tree) == VAR_DECL);
@@ -1625,7 +1620,7 @@ init_statement (tree, Bvariable *var, tree init_tree)
tree
assignment_statement (tree lhs, tree rhs, location_t location)
{
- if (lhs == error_mark_node || rhs == error_mark_node)
+ if (error_operand_p (lhs) || error_operand_p (rhs))
return error_mark_node;
// To avoid problems with GNU ld, we don't make zero-sized
@@ -1650,14 +1645,14 @@ assignment_statement (tree lhs, tree rhs, location_t location)
tree
return_statement (tree fntree, tree val, location_t location)
{
- if (fntree == error_mark_node)
+ if (error_operand_p (fntree))
return error_mark_node;
tree result = DECL_RESULT (fntree);
- if (result == error_mark_node)
+ if (error_operand_p (result))
return error_mark_node;
- if (val == error_mark_node)
+ if (error_operand_p (val))
return error_mark_node;
tree set
@@ -1675,8 +1670,8 @@ tree
exception_handler_statement (tree try_stmt, tree except_stmt, tree finally_stmt,
location_t location)
{
- if (try_stmt == error_mark_node || except_stmt == error_mark_node
- || finally_stmt == error_mark_node)
+ if (error_operand_p (try_stmt) || error_operand_p (except_stmt)
+ || error_operand_p (finally_stmt))
return error_mark_node;
if (except_stmt != NULL_TREE)
@@ -1695,8 +1690,8 @@ tree
if_statement (tree, tree cond_tree, tree then_tree, tree else_tree,
location_t location)
{
- if (cond_tree == error_mark_node || then_tree == error_mark_node
- || else_tree == error_mark_node)
+ if (error_operand_p (cond_tree) || error_operand_p (then_tree)
+ || error_operand_p (else_tree))
return error_mark_node;
tree ret = build3_loc (location, COND_EXPR, void_type_node, cond_tree,
then_tree, else_tree);
@@ -1722,15 +1717,12 @@ exit_expression (tree cond_tree, location_t locus)
tree
compound_statement (tree s1, tree s2)
{
- tree stmt_list = NULL_TREE;
- tree t = s1;
- if (t == error_mark_node)
- return error_mark_node;
- append_to_statement_list (t, &stmt_list);
- t = s2;
- if (t == error_mark_node)
+ if (error_operand_p (s1) || error_operand_p (s2))
return error_mark_node;
- append_to_statement_list (t, &stmt_list);
+
+ tree stmt_list = NULL_TREE;
+ append_to_statement_list (s1, &stmt_list);
+ append_to_statement_list (s2, &stmt_list);
// If neither statement has any side effects, stmt_list can be NULL
// at this point.
@@ -1746,11 +1738,9 @@ tree
statement_list (const std::vector<tree> &statements)
{
tree stmt_list = NULL_TREE;
- for (std::vector<tree>::const_iterator p = statements.begin ();
- p != statements.end (); ++p)
+ for (tree t : statements)
{
- tree t = (*p);
- if (t == error_mark_node)
+ if (error_operand_p (t))
return error_mark_node;
append_to_statement_list (t, &stmt_list);
}
@@ -1802,12 +1792,13 @@ block (tree fndecl, tree enclosing, const std::vector<Bvariable *> &vars,
*pp = block_tree;
}
+ // Chain the variables of the scope together so they are all connected
+ // to the block.
tree *pp = &BLOCK_VARS (block_tree);
- for (std::vector<Bvariable *>::const_iterator pv = vars.begin ();
- pv != vars.end (); ++pv)
+ for (Bvariable *bv : vars)
{
- *pp = (*pv)->get_decl ();
- if (*pp != error_mark_node)
+ *pp = bv->get_decl ();
+ if (!error_operand_p (*pp))
pp = &DECL_CHAIN (*pp);
}
*pp = NULL_TREE;
@@ -1826,11 +1817,9 @@ void
block_add_statements (tree bind_tree, const std::vector<tree> &statements)
{
tree stmt_list = NULL_TREE;
- for (std::vector<tree>::const_iterator p = statements.begin ();
- p != statements.end (); ++p)
+ for (tree s : statements)
{
- tree s = (*p);
- if (s != error_mark_node)
+ if (!error_operand_p (s))
append_to_statement_list (s, &stmt_list);
}
@@ -1908,8 +1897,7 @@ convert_tree (tree type_tree, tree expr_tree, location_t location)
if (type_tree == TREE_TYPE (expr_tree))
return expr_tree;
- if (type_tree == error_mark_node || expr_tree == error_mark_node
- || TREE_TYPE (expr_tree) == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (expr_tree))
return error_mark_node;
if (POINTER_TYPE_P (type_tree) || INTEGRAL_TYPE_P (type_tree)
@@ -1938,7 +1926,7 @@ global_variable (const std::string &var_name, const std::string &asm_name,
tree type_tree, bool is_external, bool is_hidden,
bool in_unique_section, location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
// The GNU linker does not like dynamic variables with zero size.
@@ -1977,11 +1965,11 @@ global_variable (const std::string &var_name, const std::string &asm_name,
void
global_variable_set_init (Bvariable *var, tree expr_tree)
{
- if (expr_tree == error_mark_node)
+ if (error_operand_p (expr_tree))
return;
gcc_assert (TREE_CONSTANT (expr_tree));
tree var_decl = var->get_decl ();
- if (var_decl == error_mark_node)
+ if (error_operand_p (var_decl))
return;
DECL_INITIAL (var_decl) = expr_tree;
@@ -2002,7 +1990,7 @@ Bvariable *
local_variable (tree function, const std::string &name, tree type_tree,
Bvariable *decl_var, location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
tree decl = build_decl (location, VAR_DECL, get_identifier_from_string (name),
type_tree);
@@ -2023,7 +2011,7 @@ Bvariable *
parameter_variable (tree function, const std::string &name, tree type_tree,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
tree decl = build_decl (location, PARM_DECL,
get_identifier_from_string (name), type_tree);
@@ -2040,7 +2028,7 @@ Bvariable *
static_chain_variable (tree fndecl, const std::string &name, tree type_tree,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
tree decl = build_decl (location, PARM_DECL,
get_identifier_from_string (name), type_tree);
@@ -2074,8 +2062,8 @@ temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree init_tree,
tree *pstatement)
{
gcc_assert (fndecl != NULL_TREE);
- if (type_tree == error_mark_node || init_tree == error_mark_node
- || fndecl == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (init_tree)
+ || error_operand_p (fndecl))
{
*pstatement = error_mark_node;
return Bvariable::error_variable ();
@@ -2192,13 +2180,13 @@ tree
function (tree functype, const std::string &name, const std::string &asm_name,
unsigned int flags, location_t location)
{
- if (functype != error_mark_node)
- {
- gcc_assert (FUNCTION_POINTER_TYPE_P (functype));
- functype = TREE_TYPE (functype);
- }
+ if (error_operand_p (functype))
+ return error_mark_node;
+
+ gcc_assert (FUNCTION_POINTER_TYPE_P (functype));
+ functype = TREE_TYPE (functype);
tree id = get_identifier_from_string (name);
- if (functype == error_mark_node || id == error_mark_node)
+ if (error_operand_p (id))
return error_mark_node;
tree decl = build_decl (location, FUNCTION_DECL, id, functype);
@@ -2236,8 +2224,8 @@ tree
function_defer_statement (tree function, tree undefer_tree, tree defer_tree,
location_t location)
{
- if (undefer_tree == error_mark_node || defer_tree == error_mark_node
- || function == error_mark_node)
+ if (error_operand_p (undefer_tree) || error_operand_p (defer_tree)
+ || error_operand_p (function))
return error_mark_node;
if (DECL_STRUCT_FUNCTION (function) == NULL)
@@ -2269,16 +2257,15 @@ bool
function_set_parameters (tree function,
const std::vector<Bvariable *> &param_vars)
{
- if (function == error_mark_node)
+ if (error_operand_p (function))
return false;
tree params = NULL_TREE;
tree *pp = &params;
- for (std::vector<Bvariable *>::const_iterator pv = param_vars.begin ();
- pv != param_vars.end (); ++pv)
+ for (Bvariable *bv : param_vars)
{
- *pp = (*pv)->get_decl ();
- gcc_assert (*pp != error_mark_node);
+ *pp = bv->get_decl ();
+ gcc_assert (!error_operand_p (*pp));
pp = &DECL_CHAIN (*pp);
}
*pp = NULL_TREE;
@@ -2303,23 +2290,19 @@ write_global_definitions (const std::vector<tree> &type_decls,
// Convert all non-erroneous declarations into Gimple form.
size_t i = 0;
- for (std::vector<Bvariable *>::const_iterator p = variable_decls.begin ();
- p != variable_decls.end (); ++p)
+ for (Bvariable *bv : variable_decls)
{
- tree v = (*p)->get_decl ();
- if (v != error_mark_node)
- {
- defs[i] = v;
- rust_preserve_from_gc (defs[i]);
- ++i;
- }
+ tree v = bv->get_decl ();
+ if (error_operand_p (v))
+ continue;
+ defs[i] = v;
+ rust_preserve_from_gc (defs[i]);
+ ++i;
}
- for (std::vector<tree>::const_iterator p = type_decls.begin ();
- p != type_decls.end (); ++p)
+ for (tree type_tree : type_decls)
{
- tree type_tree = (*p);
- if (type_tree != error_mark_node && IS_TYPE_OR_DECL_P (type_tree))
+ if (!error_operand_p (type_tree) && IS_TYPE_OR_DECL_P (type_tree))
{
defs[i] = TYPE_NAME (type_tree);
gcc_assert (defs[i] != NULL);
@@ -2327,21 +2310,18 @@ write_global_definitions (const std::vector<tree> &type_decls,
++i;
}
}
- for (std::vector<tree>::const_iterator p = constant_decls.begin ();
- p != constant_decls.end (); ++p)
+ for (tree t : constant_decls)
{
- if ((*p) != error_mark_node)
+ if (!error_operand_p (t))
{
- defs[i] = (*p);
+ defs[i] = t;
rust_preserve_from_gc (defs[i]);
++i;
}
}
- for (std::vector<tree>::const_iterator p = function_decls.begin ();
- p != function_decls.end (); ++p)
+ for (tree decl : function_decls)
{
- tree decl = (*p);
- if (decl != error_mark_node)
+ if (!error_operand_p (decl))
{
rust_preserve_from_gc (decl);
if (DECL_STRUCT_FUNCTION (decl) == NULL)
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 15f21ef..48acbf34 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -611,7 +611,6 @@ Session::compile_crate (const char *filename)
return;
AST::CollectLangItems ().go (parsed_crate);
- AST::DesugarQuestionMark ().go (parsed_crate);
auto name_resolution_ctx = Resolver2_0::NameResolutionContext ();
// expansion pipeline stage
@@ -619,6 +618,7 @@ Session::compile_crate (const char *filename)
expansion (parsed_crate, name_resolution_ctx);
AST::DesugarForLoops ().go (parsed_crate);
+ AST::DesugarQuestionMark ().go (parsed_crate);
rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index e4a61bd..e78c192 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -157,7 +157,13 @@ TraitResolver::resolve_path_to_trait (const HIR::TypePath &path,
}
auto resolved_item = mappings.lookup_hir_item (hid.value ());
- rust_assert (resolved_item.has_value ());
+ if (!resolved_item.has_value ())
+ {
+ rust_error_at (path.get_locus (),
+ "Failed to resolve trait by looking up hir node");
+ return false;
+ }
+
if (resolved_item.value ()->get_item_kind () != HIR::Item::ItemKind::Trait)
{
rich_location r (line_table, path.get_locus ());
@@ -228,7 +234,9 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
// The one exception is the implicit Self type of a trait
bool apply_sized = !is_self;
auto param_type
- = TypeResolveGenericParam::Resolve (*generic_param, apply_sized);
+ = TypeResolveGenericParam::Resolve (*generic_param, true,
+ apply_sized);
+
context->insert_type (generic_param->get_mappings (), param_type);
substitutions.push_back (
TyTy::SubstitutionParamMapping (typaram, param_type));
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 34a726c..beee91e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -31,6 +31,16 @@ TypeCheckBase::TypeCheckBase ()
context (TypeCheckContext::get ())
{}
+void
+TypeCheckBase::ResolveGenericParams (
+ const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+ ABI abi)
+{
+ TypeCheckBase ctx;
+ ctx.resolve_generic_params (generic_params, substitutions, is_foreign, abi);
+}
+
static void
walk_types_to_constrain (std::set<HirId> &constrained_symbols,
const TyTy::SubstitutionArgumentMappings &constraints)
@@ -387,7 +397,8 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
void
TypeCheckBase::resolve_generic_params (
const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
- std::vector<TyTy::SubstitutionParamMapping> &substitutions)
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+ ABI abi)
{
for (auto &generic_param : generic_params)
{
@@ -397,15 +408,18 @@ TypeCheckBase::resolve_generic_params (
auto lifetime_param
= static_cast<HIR::LifetimeParam &> (*generic_param);
auto lifetime = lifetime_param.get_lifetime ();
- rust_assert (lifetime.get_lifetime_type ()
- == AST::Lifetime::LifetimeType::NAMED);
context->get_lifetime_resolver ().insert_mapping (
context->intern_lifetime (lifetime));
}
-
break;
case HIR::GenericParam::GenericKind::CONST: {
+ if (is_foreign && abi != Rust::ABI::INTRINSIC)
+ {
+ rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
+ "foreign items may not have const parameters");
+ }
+
auto &param
= static_cast<HIR::ConstGenericParam &> (*generic_param);
auto specified_type = TypeCheckType::Resolve (param.get_type ());
@@ -429,15 +443,31 @@ TypeCheckBase::resolve_generic_params (
break;
case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type = TypeResolveGenericParam::Resolve (*generic_param);
+ if (is_foreign && abi != Rust::ABI::INTRINSIC)
+ {
+ rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
+ "foreign items may not have type parameters");
+ }
+
+ auto param_type = TypeResolveGenericParam::Resolve (
+ *generic_param, false /*resolve_trait_bounds*/);
context->insert_type (generic_param->get_mappings (), param_type);
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
+ auto &param = static_cast<HIR::TypeParam &> (*generic_param);
+ TyTy::SubstitutionParamMapping p (param, param_type);
+ substitutions.push_back (p);
}
break;
}
}
+
+ // now walk them to setup any specified type param bounds
+ for (auto &subst : substitutions)
+ {
+ auto pty = subst.get_param_ty ();
+ TypeResolveGenericParam::ApplyAnyTraitBounds (subst.get_generic_param (),
+ pty);
+ }
}
TyTy::TypeBoundPredicate
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index 8a1bf6f..580082a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -32,6 +32,11 @@ class TypeCheckBase
public:
virtual ~TypeCheckBase () {}
+ static void ResolveGenericParams (
+ const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+ ABI abi);
+
protected:
TypeCheckBase ();
@@ -57,7 +62,8 @@ protected:
void resolve_generic_params (
const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
- std::vector<TyTy::SubstitutionParamMapping> &substitutions);
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions,
+ bool is_foreign = false, ABI abi = ABI::RUST);
TyTy::TypeBoundPredicate get_marker_predicate (LangItem::Kind item_type,
location_t locus);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index b7fdc13..b2bcac0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -16,6 +16,8 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "optional.h"
+#include "rust-hir-expr.h"
#include "rust-system.h"
#include "rust-tyty-call.h"
#include "rust-hir-type-check-struct-field.h"
@@ -1154,6 +1156,94 @@ TypeCheckExpr::visit (HIR::FieldAccessExpr &expr)
infered = lookup->get_field_type ();
}
+bool
+is_default_fn (const MethodCandidate &candidate)
+{
+ if (candidate.candidate.is_impl_candidate ())
+ {
+ auto *item = candidate.candidate.item.impl.impl_item;
+
+ if (item->get_impl_item_type () == HIR::ImplItem::FUNCTION)
+ {
+ auto &fn = static_cast<HIR::Function &> (*item);
+
+ return fn.is_default ();
+ }
+ }
+
+ return false;
+}
+
+void
+emit_ambiguous_resolution_error (HIR::MethodCallExpr &expr,
+ std::set<MethodCandidate> &candidates)
+{
+ rich_location r (line_table, expr.get_method_name ().get_locus ());
+ std::string rich_msg = "multiple "
+ + expr.get_method_name ().get_segment ().as_string ()
+ + " found";
+
+ // We have to filter out default candidates
+ for (auto &c : candidates)
+ if (!is_default_fn (c))
+ r.add_range (c.candidate.locus);
+
+ r.add_fixit_replace (rich_msg.c_str ());
+
+ rust_error_at (r, ErrorCode::E0592, "duplicate definitions with name %qs",
+ expr.get_method_name ().get_segment ().as_string ().c_str ());
+}
+
+// We are allowed to have multiple candidates if they are all specializable
+// functions or if all of them except one are specializable functions.
+// In the later case, we just return a valid candidate without erroring out
+// about ambiguity. If there are two or more specialized functions, then we
+// error out.
+//
+// FIXME: The first case is not handled at the moment, so we error out
+tl::optional<const MethodCandidate &>
+handle_multiple_candidates (HIR::MethodCallExpr &expr,
+ std::set<MethodCandidate> &candidates)
+{
+ auto all_default = true;
+ tl::optional<const MethodCandidate &> found = tl::nullopt;
+
+ for (auto &c : candidates)
+ {
+ if (!is_default_fn (c))
+ {
+ all_default = false;
+
+ // We haven't found a final candidate yet, so we can select
+ // this one. However, if we already have a candidate, then
+ // that means there are multiple non-default candidates - we
+ // must error out
+ if (!found)
+ {
+ found = c;
+ }
+ else
+ {
+ emit_ambiguous_resolution_error (expr, candidates);
+ return tl::nullopt;
+ }
+ }
+ }
+
+ // None of the candidates were a non-default (specialized) function, so we
+ // error out
+ if (all_default)
+ {
+ rust_sorry_at (expr.get_locus (),
+ "cannot resolve method calls to non-specialized methods "
+ "(all function candidates are %qs)",
+ "default");
+ return tl::nullopt;
+ }
+
+ return found;
+}
+
void
TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
{
@@ -1181,34 +1271,25 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
return;
}
+ tl::optional<const MethodCandidate &> candidate = *candidates.begin ();
+
if (candidates.size () > 1)
- {
- rich_location r (line_table, expr.get_method_name ().get_locus ());
- std::string rich_msg
- = "multiple " + expr.get_method_name ().get_segment ().as_string ()
- + " found";
+ candidate = handle_multiple_candidates (expr, candidates);
- for (auto &c : candidates)
- r.add_range (c.candidate.locus);
+ if (!candidate)
+ return;
- r.add_fixit_replace (rich_msg.c_str ());
+ auto found_candidate = *candidate;
- rust_error_at (
- r, ErrorCode::E0592, "duplicate definitions with name %qs",
- expr.get_method_name ().get_segment ().as_string ().c_str ());
- return;
- }
-
- auto candidate = *candidates.begin ();
rust_debug_loc (expr.get_method_name ().get_locus (),
"resolved method to: {%u} {%s} with [%lu] adjustments",
- candidate.candidate.ty->get_ref (),
- candidate.candidate.ty->debug_str ().c_str (),
- (unsigned long) candidate.adjustments.size ());
+ found_candidate.candidate.ty->get_ref (),
+ found_candidate.candidate.ty->debug_str ().c_str (),
+ (unsigned long) found_candidate.adjustments.size ());
// Get the adjusted self
Adjuster adj (receiver_tyty);
- TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments);
+ TyTy::BaseType *adjusted_self = adj.adjust_type (found_candidate.adjustments);
rust_debug ("receiver: %s adjusted self %s",
receiver_tyty->debug_str ().c_str (),
adjusted_self->debug_str ().c_str ());
@@ -1219,10 +1300,10 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
HirId autoderef_mappings_id
= expr.get_receiver ().get_mappings ().get_hirid ();
context->insert_autoderef_mappings (autoderef_mappings_id,
- std::move (candidate.adjustments));
+ std::move (found_candidate.adjustments));
- PathProbeCandidate &resolved_candidate = candidate.candidate;
- TyTy::BaseType *lookup_tyty = candidate.candidate.ty;
+ PathProbeCandidate &resolved_candidate = found_candidate.candidate;
+ TyTy::BaseType *lookup_tyty = found_candidate.candidate.ty;
NodeId resolved_node_id
= resolved_candidate.is_impl_candidate ()
? resolved_candidate.item.impl.impl_item->get_impl_mappings ()
@@ -1249,8 +1330,8 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
fn->prepare_higher_ranked_bounds ();
rust_debug_loc (expr.get_locus (), "resolved method call to: {%u} {%s}",
- candidate.candidate.ty->get_ref (),
- candidate.candidate.ty->debug_str ().c_str ());
+ found_candidate.candidate.ty->get_ref (),
+ found_candidate.candidate.ty->debug_str ().c_str ());
if (resolved_candidate.is_impl_candidate ())
{
@@ -1463,6 +1544,15 @@ TypeCheckExpr::visit (HIR::BorrowExpr &expr)
}
}
+ if (expr.is_raw_borrow ())
+ {
+ infered = new TyTy::PointerType (expr.get_mappings ().get_hirid (),
+ TyTy::TyVar (resolved_base->get_ref ()),
+ expr.get_mut ());
+
+ return;
+ }
+
infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
TyTy::TyVar (resolved_base->get_ref ()),
expr.get_mut ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index a5ae54b..bc7f6dc 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -73,44 +73,8 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
std::vector<TyTy::SubstitutionParamMapping> substitutions;
if (function.has_generics ())
{
- for (auto &generic_param : function.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME:
- context->intern_and_insert_lifetime (
- static_cast<HIR::LifetimeParam &> (*generic_param)
- .get_lifetime ());
- // TODO: handle bounds
- break;
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- if (parent.get_abi () != Rust::ABI::INTRINSIC)
- {
- rust_error_at (function.get_locus (), ErrorCode::E0044,
- "foreign items may not have const parameters");
- }
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- if (parent.get_abi () != Rust::ABI::INTRINSIC)
- {
- rust_error_at (
- function.get_locus (), ErrorCode::E0044,
- "foreign items may not have type parameters");
- }
- auto param_type
- = TypeResolveGenericParam::Resolve (*generic_param);
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
+ resolve_generic_params (function.get_generic_params (), substitutions,
+ true /*is_foreign*/, parent.get_abi ());
}
TyTy::RegionConstraints region_constraints;
@@ -200,128 +164,7 @@ void
TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem &type)
{
rust_sorry_at (type.get_locus (), "extern types are not supported yet");
- // auto binder_pin = context->push_clean_lifetime_resolver ();
-
- // std::vector<TyTy::SubstitutionParamMapping> substitutions;
- // if (function.has_generics ())
- // {
- // for (auto &generic_param : function.get_generic_params ())
- // {
- // switch (generic_param.get ()->get_kind ())
- // {
- // case HIR::GenericParam::GenericKind::LIFETIME:
- // context->intern_and_insert_lifetime (
- // static_cast<HIR::LifetimeParam &> (*generic_param)
- // .get_lifetime ());
- // // TODO: handle bounds
- // break;
- // case HIR::GenericParam::GenericKind::CONST:
- // // FIXME: Skipping Lifetime and Const completely until better
- // // handling.
- // break;
-
- // case HIR::GenericParam::GenericKind::TYPE: {
- // auto param_type
- // = TypeResolveGenericParam::Resolve (generic_param.get ());
- // context->insert_type (generic_param->get_mappings (),
- // param_type);
-
- // substitutions.push_back (TyTy::SubstitutionParamMapping (
- // static_cast<HIR::TypeParam &> (*generic_param), param_type));
- // }
- // break;
- // }
- // }
- // }
-
- // TyTy::RegionConstraints region_constraints;
- // if (function.has_where_clause ())
- // {
- // for (auto &where_clause_item : function.get_where_clause ().get_items
- // ())
- // {
- // ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
- // region_constraints);
- // }
- // }
-
- // TyTy::BaseType *ret_type = nullptr;
- // if (!function.has_return_type ())
- // ret_type
- // = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid
- // ());
- // else
- // {
- // auto resolved
- // = TypeCheckType::Resolve (function.get_return_type ().get ());
- // if (resolved == nullptr)
- // {
- // rust_error_at (function.get_locus (),
- // "failed to resolve return type");
- // return;
- // }
-
- // ret_type = resolved->clone ();
- // ret_type->set_ref (
- // function.get_return_type ()->get_mappings ().get_hirid ());
- // }
-
- // std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
- // for (auto &param : function.get_function_params ())
- // {
- // // get the name as well required for later on
- // auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
-
- // // these are implicit mappings and not used
- // auto crate_num = mappings->get_current_crate ();
- // Analysis::NodeMapping mapping (crate_num, mappings->get_next_node_id
- // (),
- // mappings->get_next_hir_id (crate_num),
- // UNKNOWN_LOCAL_DEFID);
-
- // HIR::IdentifierPattern *param_pattern
- // = new HIR::IdentifierPattern (mapping, param.get_param_name (),
- // UNDEF_LOCATION, false, Mutability::Imm,
- // std::unique_ptr<HIR::Pattern> (nullptr));
-
- // params.push_back (
- // std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern,
- // param_tyty));
-
- // context->insert_type (param.get_mappings (), param_tyty);
-
- // // FIXME do we need error checking for patterns here?
- // // see https://github.com/Rust-GCC/gccrs/issues/995
- // }
-
- // uint8_t flags = TyTy::FnType::FNTYPE_IS_EXTERN_FLAG;
- // if (function.is_variadic ())
- // {
- // flags |= TyTy::FnType::FNTYPE_IS_VARADIC_FLAG;
- // if (parent.get_abi () != Rust::ABI::C)
- // {
- // rust_error_at (
- // function.get_locus (), ErrorCode::E0045,
- // "C-variadic function must have C or cdecl calling convention");
- // }
- // }
-
- // RustIdent ident{
- // CanonicalPath::new_seg (function.get_mappings ().get_nodeid (),
- // function.get_item_name ().as_string ()),
- // function.get_locus ()};
-
- // auto fnType = new TyTy::FnType (
- // function.get_mappings ().get_hirid (),
- // function.get_mappings ().get_defid (),
- // function.get_item_name ().as_string (), ident, flags, parent.get_abi (),
- // std::move (params), ret_type, std::move (substitutions),
- // TyTy::SubstitutionArgumentMappings::empty (
- // context->get_lifetime_resolver ().get_num_bound_regions ()),
- // region_constraints);
-
- // context->insert_type (function.get_mappings (), fnType);
- // resolved = fnType;
+ // TODO
}
TypeCheckImplItem::TypeCheckImplItem (
@@ -399,7 +242,7 @@ TypeCheckImplItem::visit (HIR::Function &function)
// add the synthetic self param at the front, this is a placeholder for
// compilation to know parameter names. The types are ignored but we
// reuse the HIR identifier pattern which requires it
- HIR::SelfParam &self_param = function.get_self_param ();
+ HIR::SelfParam &self_param = function.get_self_param_unchecked ();
// FIXME: which location should be used for Rust::Identifier for `self`?
std::unique_ptr<HIR::Pattern> self_pattern
= std::make_unique<HIR::IdentifierPattern> (
@@ -424,13 +267,21 @@ TypeCheckImplItem::visit (HIR::Function &function)
break;
case HIR::SelfParam::IMM_REF: {
- auto region = context->lookup_and_resolve_lifetime (
- self_param.get_lifetime ());
- if (!region.has_value ())
+ tl::optional<TyTy::Region> region;
+ if (self_param.has_lifetime ())
{
- rust_inform (self_param.get_locus (),
- "failed to resolve lifetime");
- region = TyTy::Region::make_anonymous (); // FIXME
+ region = context->lookup_and_resolve_lifetime (
+ self_param.get_lifetime ());
+ if (!region.has_value ())
+ {
+ rust_inform (self_param.get_locus (),
+ "failed to resolve lifetime");
+ return;
+ }
+ }
+ else
+ {
+ region = TyTy::Region::make_anonymous ();
}
self_type = new TyTy::ReferenceType (
self_param.get_mappings ().get_hirid (),
@@ -440,13 +291,21 @@ TypeCheckImplItem::visit (HIR::Function &function)
break;
case HIR::SelfParam::MUT_REF: {
- auto region = context->lookup_and_resolve_lifetime (
- self_param.get_lifetime ());
- if (!region.has_value ())
+ tl::optional<TyTy::Region> region;
+ if (self_param.has_lifetime ())
+ {
+ region = context->lookup_and_resolve_lifetime (
+ self_param.get_lifetime ());
+ if (!region.has_value ())
+ {
+ rust_error_at (self_param.get_locus (),
+ "failed to resolve lifetime");
+ return;
+ }
+ }
+ else
{
- rust_error_at (self_param.get_locus (),
- "failed to resolve lifetime");
- return;
+ region = TyTy::Region::make_anonymous ();
}
self_type = new TyTy::ReferenceType (
self_param.get_mappings ().get_hirid (),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 1fe39aae..5662da5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -336,7 +336,7 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
TyTy::BaseType *lookup = nullptr;
if (!query_type (ref, &lookup))
{
- if (is_root)
+ if (is_root || root_tyty == nullptr)
{
rust_error_at (expr.get_locus (), ErrorCode::E0425,
"cannot find value %qs in this scope",
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 3f9557a..bd13f7a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -277,7 +277,15 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
infered = pattern_ty;
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
- rust_assert (adt->number_of_variants () > 0);
+ if (adt->number_of_variants () == 0)
+ {
+ HIR::PathInExpression &path = pattern.get_path ();
+ const AST::SimplePath &sp = path.as_simple_path ();
+ rust_error_at (pattern.get_locus (), ErrorCode::E0574,
+ "expected struct, variant or union type, found enum %qs",
+ sp.as_string ().c_str ());
+ return;
+ }
TyTy::VariantDef *variant = adt->get_variants ().at (0);
if (adt->is_enum ())
@@ -285,7 +293,16 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
HirId variant_id = UNKNOWN_HIRID;
bool ok = context->lookup_variant_definition (
pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
- rust_assert (ok);
+ if (!ok)
+ {
+ HIR::PathInExpression &path = pattern.get_path ();
+ const AST::SimplePath &sp = path.as_simple_path ();
+ rust_error_at (
+ pattern.get_locus (), ErrorCode::E0574,
+ "expected struct, variant or union type, found enum %qs",
+ sp.as_string ().c_str ());
+ return;
+ }
ok = adt->lookup_variant_by_id (variant_id, &variant);
rust_assert (ok);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 54f50ec..6919093 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -417,8 +417,13 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
TyTy::BaseType *lookup = nullptr;
if (!query_type (ref, &lookup))
{
- if (is_root)
- return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+ if (is_root || root_tyty == nullptr)
+ {
+ rust_error_at (seg->get_locus (),
+ "failed to resolve type path segment: %qs",
+ seg->as_string ().c_str ());
+ return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+ }
return root_tyty;
}
@@ -573,6 +578,7 @@ TypeCheckType::resolve_segments (
ignore_mandatory_trait_items);
if (candidates.size () == 0)
{
+ prev_segment->debug ();
rust_error_at (
seg->get_locus (),
"failed to resolve path segment using an impl Probe");
@@ -797,9 +803,10 @@ TypeCheckType::visit (HIR::ImplTraitType &type)
}
TyTy::ParamType *
-TypeResolveGenericParam::Resolve (HIR::GenericParam &param, bool apply_sized)
+TypeResolveGenericParam::Resolve (HIR::GenericParam &param,
+ bool resolve_trait_bounds, bool apply_sized)
{
- TypeResolveGenericParam resolver (apply_sized);
+ TypeResolveGenericParam resolver (apply_sized, resolve_trait_bounds);
switch (param.get_kind ())
{
case HIR::GenericParam::GenericKind::TYPE:
@@ -818,6 +825,14 @@ TypeResolveGenericParam::Resolve (HIR::GenericParam &param, bool apply_sized)
}
void
+TypeResolveGenericParam::ApplyAnyTraitBounds (HIR::TypeParam &param,
+ TyTy::ParamType *pty)
+{
+ TypeResolveGenericParam resolver (true, true);
+ resolver.apply_trait_bounds (param, pty);
+}
+
+void
TypeResolveGenericParam::visit (HIR::LifetimeParam &param)
{
// nothing to do
@@ -835,6 +850,19 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
if (param.has_type ())
TypeCheckType::Resolve (param.get_type ());
+ resolved
+ = new TyTy::ParamType (param.get_type_representation ().as_string (),
+ param.get_locus (),
+ param.get_mappings ().get_hirid (), param, {});
+
+ if (resolve_trait_bounds)
+ apply_trait_bounds (param, resolved);
+}
+
+void
+TypeResolveGenericParam::apply_trait_bounds (HIR::TypeParam &param,
+ TyTy::ParamType *pty)
+{
std::unique_ptr<HIR::Type> implicit_self_bound = nullptr;
if (param.has_type_param_bounds ())
{
@@ -865,8 +893,6 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
//
// We can only do this when we are not resolving the implicit Self for Sized
// itself
- rust_debug_loc (param.get_locus (), "apply_sized: %s",
- apply_sized ? "true" : "false");
if (apply_sized)
{
TyTy::TypeBoundPredicate sized_predicate
@@ -941,10 +967,8 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
}
}
- resolved = new TyTy::ParamType (param.get_type_representation ().as_string (),
- param.get_locus (),
- param.get_mappings ().get_hirid (), param,
- specified_bounds);
+ // inherit them
+ pty->inherit_bounds (specified_bounds);
}
void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index fc272e6..cc991b6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -91,20 +91,27 @@ class TypeResolveGenericParam : public TypeCheckBase
{
public:
static TyTy::ParamType *Resolve (HIR::GenericParam &param,
+ bool resolve_trait_bounds = true,
bool apply_sized = true);
+ static void ApplyAnyTraitBounds (HIR::TypeParam &param, TyTy::ParamType *pty);
+
protected:
void visit (HIR::TypeParam &param);
void visit (HIR::LifetimeParam &param);
void visit (HIR::ConstGenericParam &param);
+ void apply_trait_bounds (HIR::TypeParam &param, TyTy::ParamType *pty);
+
private:
- TypeResolveGenericParam (bool apply_sized)
- : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized)
+ TypeResolveGenericParam (bool apply_sized, bool resolve_trait_bounds)
+ : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized),
+ resolve_trait_bounds (resolve_trait_bounds)
{}
TyTy::ParamType *resolved;
bool apply_sized;
+ bool resolve_trait_bounds;
};
class ResolveWhereClauseItem : public TypeCheckBase
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index a198ad3..fbaf323 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -165,36 +165,9 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
HIR::TraitFunctionDecl &function = fn.get_decl ();
if (function.has_generics ())
{
- for (auto &generic_param : function.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME: {
- auto lifetime_param
- = static_cast<HIR::LifetimeParam &> (*generic_param);
-
- context->intern_and_insert_lifetime (
- lifetime_param.get_lifetime ());
- // TODO: Handle lifetime bounds
- }
- break;
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (*generic_param);
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
+ TypeCheckBase::ResolveGenericParams (function.get_generic_params (),
+ substitutions, false /*is_foreign*/,
+ ABI::RUST);
}
if (function.has_where_clause ())
@@ -235,7 +208,7 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
// add the synthetic self param at the front, this is a placeholder
// for compilation to know parameter names. The types are ignored
// but we reuse the HIR identifier pattern which requires it
- HIR::SelfParam &self_param = function.get_self ();
+ HIR::SelfParam &self_param = function.get_self_unchecked ();
std::unique_ptr<HIR::Pattern> self_pattern
= std::make_unique<HIR::IdentifierPattern> (HIR::IdentifierPattern (
mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
index 212ab3f..f0bd1f8 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.cc
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -34,6 +34,15 @@ SubstMapper::Resolve (TyTy::BaseType *base, location_t locus,
HIR::GenericArgs *generics,
const std::vector<TyTy::Region> &regions)
{
+ if (!valid_type (base))
+ {
+ rich_location r (line_table, locus);
+ r.add_fixit_remove (generics->get_locus ());
+ rust_error_at (r, ErrorCode::E0109,
+ "generic arguments are not allowed for this type");
+ return base;
+ }
+
SubstMapper mapper (base->get_ref (), generics, regions, locus);
base->accept_vis (mapper);
rust_assert (mapper.resolved != nullptr);
@@ -47,6 +56,17 @@ SubstMapper::InferSubst (TyTy::BaseType *base, location_t locus)
}
bool
+SubstMapper::valid_type (TyTy::BaseType *base)
+{
+ bool is_fn = base->is<TyTy::FnType> ();
+ bool is_adt = base->is<TyTy::ADTType> ();
+ bool is_placeholder = base->is<TyTy::PlaceholderType> ();
+ bool is_projection = base->is<TyTy::ProjectionType> ();
+
+ return is_fn || is_adt || is_placeholder || is_projection;
+}
+
+bool
SubstMapper::have_generic_args () const
{
return generics != nullptr;
@@ -103,7 +123,12 @@ SubstMapper::visit (TyTy::ADTType &type)
void
SubstMapper::visit (TyTy::PlaceholderType &type)
{
- rust_assert (type.can_resolve ());
+ if (!type.can_resolve ())
+ {
+ resolved = &type;
+ return;
+ }
+
resolved = SubstMapper::Resolve (type.resolve (), locus, generics, regions);
}
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index bc54f56..32ab71c 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -37,6 +37,8 @@ public:
bool have_generic_args () const;
+ static bool valid_type (TyTy::BaseType *base);
+
void visit (TyTy::FnType &type) override;
void visit (TyTy::ADTType &type) override;
void visit (TyTy::PlaceholderType &type) override;
diff --git a/gcc/rust/typecheck/rust-type-util.cc b/gcc/rust/typecheck/rust-type-util.cc
index 4abfbae..c6c5b4b 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -22,10 +22,13 @@
#include "rust-hir-type-check-implitem.h"
#include "rust-hir-type-check-item.h"
#include "rust-hir-type-check.h"
+#include "rust-hir-type-check-type.h"
#include "rust-casts.h"
#include "rust-unify.h"
#include "rust-coercion.h"
#include "rust-hir-type-bounds.h"
+#include "rust-immutable-name-resolution-context.h"
+#include "options.h"
namespace Rust {
namespace Resolver {
@@ -34,6 +37,7 @@ bool
query_type (HirId reference, TyTy::BaseType **result)
{
auto &mappings = Analysis::Mappings::get ();
+ auto &resolver = *Resolver::get ();
TypeCheckContext *context = TypeCheckContext::get ();
if (context->query_in_progress (reference))
@@ -91,6 +95,39 @@ query_type (HirId reference, TyTy::BaseType **result)
HIR::ImplBlock *impl = impl_block_by_type.value ();
rust_debug_loc (impl->get_locus (), "resolved impl block type {%u} to",
reference);
+
+ // this could be recursive to the root type
+ if (impl->has_type ())
+ {
+ HIR::Type &ty = impl->get_type ();
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ NodeId ast_node_id = ty.get_mappings ().get_nodeid ();
+
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx = Resolver2_0::ImmutableNameResolutionContext::get ()
+ .resolver ();
+
+ // assign the ref_node_id if we've found something
+ nr_ctx.lookup (ast_node_id)
+ .map (
+ [&ref_node_id] (NodeId resolved) { ref_node_id = resolved; });
+ }
+ else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ resolver.lookup_resolved_type (ast_node_id, &ref_node_id);
+
+ if (ref_node_id != UNKNOWN_NODEID)
+ {
+ tl::optional<HirId> hid
+ = mappings.lookup_node_to_hir (ref_node_id);
+ if (hid.has_value () && context->query_in_progress (hid.value ()))
+ {
+ context->query_completed (reference);
+ return false;
+ }
+ }
+ }
+
*result = TypeCheckItem::ResolveImplBlockSelf (*impl);
context->query_completed (reference);
return true;
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc
index f02e484..9112b99 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -514,7 +514,16 @@ TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
{
if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
{
- rust_assert (lifetime.get_name () != "static");
+ if (lifetime.get_name () == "static")
+ {
+ rich_location r (line_table, lifetime.get_locus ());
+ r.add_fixit_insert_after (lifetime.get_locus (),
+ "static is a reserved lifetime name");
+ rust_error_at (r, ErrorCode::E0262,
+ "invalid lifetime parameter name: %qs",
+ lifetime.get_name ().c_str ());
+ return tl::nullopt;
+ }
const auto name = lifetime.get_name ();
auto it = lifetime_name_interner.find (name);
if (it == lifetime_name_interner.end ())
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index 95f18b9..bdb6474 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -28,8 +28,8 @@
namespace Rust {
namespace TyTy {
-SubstitutionParamMapping::SubstitutionParamMapping (
- const HIR::TypeParam &generic, ParamType *param)
+SubstitutionParamMapping::SubstitutionParamMapping (HIR::TypeParam &generic,
+ ParamType *param)
: generic (generic), param (param)
{}
@@ -66,8 +66,8 @@ SubstitutionParamMapping::get_param_ty () const
return param;
}
-const HIR::TypeParam &
-SubstitutionParamMapping::get_generic_param () const
+HIR::TypeParam &
+SubstitutionParamMapping::get_generic_param ()
{
return generic;
}
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
index 3f0b912..e6ed1fc 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -44,7 +44,7 @@ class SubstitutionArgumentMappings;
class SubstitutionParamMapping
{
public:
- SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param);
+ SubstitutionParamMapping (HIR::TypeParam &generic, ParamType *param);
SubstitutionParamMapping (const SubstitutionParamMapping &other);
@@ -59,7 +59,7 @@ public:
const ParamType *get_param_ty () const;
- const HIR::TypeParam &get_generic_param () const;
+ HIR::TypeParam &get_generic_param ();
// this is used for the backend to override the HirId ref of the param to
// what the concrete type is for the rest of the context
@@ -76,7 +76,7 @@ public:
bool need_substitution () const;
private:
- const HIR::TypeParam &generic;
+ HIR::TypeParam &generic;
ParamType *param;
};
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
index 1aba576..38f9d52 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
@@ -238,7 +238,7 @@ GenericTyVisitorCtx::process_type (ADTType &ty)
first_lifetime = lookup_or_add_type (ty.get_orig_ref ());
first_type = first_lifetime + ty.get_used_arguments ().get_regions ().size ();
- for (const auto &param : ty.get_substs ())
+ for (auto &param : ty.get_substs ())
param_names.push_back (
param.get_generic_param ().get_type_representation ().as_string ());
diff --git a/gcc/rust/util/expected.h b/gcc/rust/util/expected.h
index a9e3bc2..07ba877 100644
--- a/gcc/rust/util/expected.h
+++ b/gcc/rust/util/expected.h
@@ -212,10 +212,8 @@ template <typename E>
throw std::forward<E>(e);
#else
(void)e;
-#ifdef _MSC_VER
gcc_unreachable();
#endif
-#endif
}
#ifndef TL_TRAITS_MUTEX
@@ -2437,4 +2435,4 @@ void swap(expected<T, E> &lhs,
}
} // namespace tl
-#endif \ No newline at end of file
+#endif
diff --git a/gcc/rust/util/rust-attribute-values.h b/gcc/rust/util/rust-attribute-values.h
index 9ef5cc5..47e6a17 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -40,12 +40,14 @@ public:
static constexpr auto &NO_MANGLE = "no_mangle";
static constexpr auto &REPR = "repr";
static constexpr auto &RUSTC_BUILTIN_MACRO = "rustc_builtin_macro";
+ static constexpr auto &RUSTC_MACRO_TRANSPARENCY = "rustc_macro_transparency";
static constexpr auto &PATH = "path";
static constexpr auto &MACRO_USE = "macro_use";
static constexpr auto &MACRO_EXPORT = "macro_export";
static constexpr auto &PROC_MACRO = "proc_macro";
static constexpr auto &PROC_MACRO_DERIVE = "proc_macro_derive";
static constexpr auto &PROC_MACRO_ATTRIBUTE = "proc_macro_attribute";
+
static constexpr auto &TARGET_FEATURE = "target_feature";
// From now on, these are reserved by the compiler and gated through
// #![feature(rustc_attrs)]
@@ -54,10 +56,35 @@ public:
= "rustc_inherit_overflow_checks";
static constexpr auto &STABLE = "stable";
static constexpr auto &UNSTABLE = "unstable";
+
+ static constexpr auto &RUSTC_PROMOTABLE = "rustc_promotable";
static constexpr auto &RUSTC_CONST_STABLE = "rustc_const_stable";
static constexpr auto &RUSTC_CONST_UNSTABLE = "rustc_const_unstable";
+
+ static constexpr auto &RUSTC_SPECIALIZATION_TRAIT
+ = "rustc_specialization_trait";
+ static constexpr auto &RUSTC_UNSAFE_SPECIALIZATION_MARKER
+ = "rustc_unsafe_specialization_marker";
+ static constexpr auto &RUSTC_RESERVATION_IMPL = "rustc_reservation_impl";
+ static constexpr auto &RUSTC_PAREN_SUGAR = "rustc_paren_sugar";
+ static constexpr auto &RUSTC_NONNULL_OPTIMIZATION_GUARANTEED
+ = "rustc_nonnull_optimization_guaranteed";
+
+ static constexpr auto &RUSTC_LAYOUT_SCALAR_VALID_RANGE_START
+ = "rustc_layout_scalar_valid_range_start";
+
static constexpr auto &MAY_DANGLE = "may_dangle";
static constexpr auto &PRELUDE_IMPORT = "prelude_import";
+ static constexpr auto &TRACK_CALLER = "track_caller";
+
+ static constexpr auto &RUSTC_DIAGNOSTIC_ITEM = "rustc_diagnostic_item";
+ static constexpr auto &RUSTC_ON_UNIMPLEMENTED = "rustc_on_unimplemented";
+
+ static constexpr auto &FUNDAMENTAL = "fundamental";
+
+ static constexpr auto &NON_EXHAUSTIVE = "non_exhaustive";
+
+ static constexpr auto &RUSTFMT = "rustfmt";
};
} // namespace Values
} // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 03452c7..c77e99c 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -57,6 +57,7 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::NO_MANGLE, CODE_GENERATION},
{Attrs::REPR, CODE_GENERATION},
{Attrs::RUSTC_BUILTIN_MACRO, EXPANSION},
+ {Attrs::RUSTC_MACRO_TRANSPARENCY, EXPANSION},
{Attrs::PATH, EXPANSION},
{Attrs::MACRO_USE, NAME_RESOLUTION},
{Attrs::MACRO_EXPORT, NAME_RESOLUTION},
@@ -72,10 +73,29 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION},
{Attrs::STABLE, STATIC_ANALYSIS},
{Attrs::UNSTABLE, STATIC_ANALYSIS},
+
// assuming we keep these for static analysis
+ {Attrs::RUSTC_PROMOTABLE, CODE_GENERATION},
{Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
{Attrs::RUSTC_CONST_UNSTABLE, STATIC_ANALYSIS},
- {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION}};
+ {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
+ {Attrs::TRACK_CALLER, CODE_GENERATION},
+ {Attrs::RUSTC_SPECIALIZATION_TRAIT, TYPE_CHECK},
+ {Attrs::RUSTC_UNSAFE_SPECIALIZATION_MARKER, TYPE_CHECK},
+ {Attrs::RUSTC_RESERVATION_IMPL, TYPE_CHECK},
+ {Attrs::RUSTC_PAREN_SUGAR, TYPE_CHECK},
+ {Attrs::RUSTC_NONNULL_OPTIMIZATION_GUARANTEED, TYPE_CHECK},
+
+ {Attrs::RUSTC_LAYOUT_SCALAR_VALID_RANGE_START, CODE_GENERATION},
+
+ {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
+
+ {Attrs::RUSTC_DIAGNOSTIC_ITEM, STATIC_ANALYSIS},
+ {Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS},
+
+ {Attrs::FUNDAMENTAL, TYPE_CHECK},
+ {Attrs::NON_EXHAUSTIVE, TYPE_CHECK},
+ {Attrs::RUSTFMT, EXTERNAL}};
BuiltinAttributeMappings *
BuiltinAttributeMappings::get ()
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index c928c8e..7c7a1fc 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -40,7 +40,12 @@ enum CompilerPass
HIR_LOWERING,
TYPE_CHECK,
STATIC_ANALYSIS,
- CODE_GENERATION
+ CODE_GENERATION,
+
+ // External Rust tooling attributes, like #[rustfmt::skip]
+ EXTERNAL,
+
+ // Do we need to add something here for const fns?
};
struct BuiltinAttrDefinition
diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index a76cc7f..9aff31b 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -118,6 +118,7 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{
{"discriminant_kind", Kind::DISCRIMINANT_KIND},
{"discriminant_type", Kind::DISCRIMINANT_TYPE},
+ {"manually_drop", Kind::MANUALLY_DROP},
}};
tl::optional<LangItem::Kind>
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 8f3af36..67a5d9c 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -150,6 +150,8 @@ public:
DISCRIMINANT_TYPE,
DISCRIMINANT_KIND,
+
+ MANUALLY_DROP,
};
static const BiMap<std::string, Kind> lang_items;