diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index aa1e31baaffc..865bbcd48e21 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -9,12 +9,17 @@ on: branches: [ master ] merge_group: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: build-and-check-ubuntu-64bit: env: # Force locale, in particular for reproducible results re '.github/bors_log_expected_warnings' (see below). LC_ALL: C.UTF-8 + SCCACHE_GHA_ENABLED: "true" runs-on: ubuntu-22.04 @@ -39,11 +44,14 @@ jobs: g++-multilib \ dejagnu + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.3 + - name: Configure run: | mkdir -p gccrs-build; cd gccrs-build; - ../configure \ + ../configure CC="sccache gcc" CXX="sccache g++" \ --enable-languages=rust \ --disable-bootstrap \ --enable-multilib @@ -54,6 +62,10 @@ jobs: cd gccrs-build; \ make -Otarget -j $(nproc) 2>&1 | tee log + - name: Show sccache stats + shell: bash + run: ${SCCACHE_PATH} --show-stats + - name: Check for new warnings run: | cd gccrs-build diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index b630cfa53920..e2d3eea6c583 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -85,8 +85,9 @@ std::unique_ptr AstBuilder::block (std::vector> &&stmts, std::unique_ptr &&tail_expr) { - return std::unique_ptr ( - new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {}, loc, loc)); + return std::unique_ptr (new BlockExpr (std::move (stmts), + std::move (tail_expr), {}, {}, + LoopLabel::error (), loc, loc)); } std::unique_ptr diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index db55f011faac..e5cadb673148 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -1194,7 +1194,7 @@ class Pattern : public Visitable virtual bool is_marked_for_strip () const { return false; } virtual location_t get_locus () const = 0; - virtual NodeId get_pattern_node_id () const = 0; + virtual NodeId get_node_id () const = 0; protected: // Clone pattern implementation as pure virtual method @@ -1446,8 +1446,30 @@ class LifetimeParam : public GenericParam } }; +class AssociatedItem : public Visitable +{ +protected: + // Clone function implementation as pure virtual method + virtual AssociatedItem *clone_associated_item_impl () const = 0; + +public: + virtual ~AssociatedItem () {} + + std::unique_ptr clone_associated_item () const + { + return std::unique_ptr (clone_associated_item_impl ()); + } + + virtual std::string as_string () const = 0; + + virtual void mark_for_strip () = 0; + virtual bool is_marked_for_strip () const = 0; + + virtual location_t get_locus () const = 0; +}; + // Item used in trait declarations - abstract base class -class TraitItem : public Visitable +class TraitItem : virtual public AssociatedItem { protected: TraitItem (location_t locus) @@ -1455,73 +1477,50 @@ class TraitItem : public Visitable {} // Clone function implementation as pure virtual method - virtual TraitItem *clone_trait_item_impl () const = 0; + virtual TraitItem *clone_associated_item_impl () const override = 0; NodeId node_id; location_t locus; public: - virtual ~TraitItem () {} - // Unique pointer custom clone function std::unique_ptr clone_trait_item () const { - return std::unique_ptr (clone_trait_item_impl ()); + return std::unique_ptr (clone_associated_item_impl ()); } - virtual std::string as_string () const = 0; - - virtual void mark_for_strip () = 0; - virtual bool is_marked_for_strip () const = 0; - NodeId get_node_id () const { return node_id; } location_t get_locus () const { return locus; } }; /* Abstract base class for items used within an inherent impl block (the impl * name {} one) */ -class InherentImplItem : public Visitable +class InherentImplItem : virtual public AssociatedItem { protected: // Clone function implementation as pure virtual method - virtual InherentImplItem *clone_inherent_impl_item_impl () const = 0; + virtual InherentImplItem *clone_associated_item_impl () const override = 0; public: - virtual ~InherentImplItem () {} - // Unique pointer custom clone function std::unique_ptr clone_inherent_impl_item () const { - return std::unique_ptr (clone_inherent_impl_item_impl ()); + return std::unique_ptr (clone_associated_item_impl ()); } - - virtual std::string as_string () const = 0; - - virtual void mark_for_strip () = 0; - virtual bool is_marked_for_strip () const = 0; - - virtual location_t get_locus () const = 0; }; // Abstract base class for items used in a trait impl -class TraitImplItem : public Visitable +class TraitImplItem : virtual public AssociatedItem { protected: - virtual TraitImplItem *clone_trait_impl_item_impl () const = 0; + virtual TraitImplItem *clone_associated_item_impl () const override = 0; public: - virtual ~TraitImplItem (){}; - // Unique pointer custom clone function std::unique_ptr clone_trait_impl_item () const { - return std::unique_ptr (clone_trait_impl_item_impl ()); + return std::unique_ptr (clone_associated_item_impl ()); } - - virtual std::string as_string () const = 0; - - virtual void mark_for_strip () = 0; - virtual bool is_marked_for_strip () const = 0; }; // Abstract base class for an item used inside an extern block diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 012b05578236..bd59f81b562f 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -11,6 +11,36 @@ namespace AST { * "has_whatever" pairs with * optional types (std::optional or boost::optional)? */ +// Loop label expression AST node used with break and continue expressions +// TODO: inline? +class LoopLabel /*: public Node*/ +{ + Lifetime label; // or type LIFETIME_OR_LABEL + location_t locus; + + NodeId node_id; + +public: + std::string as_string () const; + + LoopLabel (Lifetime loop_label, location_t locus = UNDEF_LOCATION) + : label (std::move (loop_label)), locus (locus), + node_id (Analysis::Mappings::get ()->get_next_node_id ()) + {} + + // 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; } + + NodeId get_node_id () const { return node_id; } +}; + // AST node for an expression with an accompanying block - abstract class ExprWithBlock : public Expr { @@ -2396,6 +2426,7 @@ class BlockExpr : public ExprWithBlock std::vector inner_attrs; std::vector > statements; std::unique_ptr expr; + LoopLabel label; location_t start_locus; location_t end_locus; bool marked_for_strip = false; @@ -2412,19 +2443,21 @@ class BlockExpr : public ExprWithBlock BlockExpr (std::vector > block_statements, std::unique_ptr block_expr, std::vector inner_attribs, - std::vector outer_attribs, location_t start_locus, - location_t end_locus) + std::vector outer_attribs, 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)), - start_locus (start_locus), end_locus (end_locus) + label (std::move (label)), start_locus (start_locus), + end_locus (end_locus) {} // Copy constructor with clone BlockExpr (BlockExpr const &other) : ExprWithBlock (other), outer_attrs (other.outer_attrs), - inner_attrs (other.inner_attrs), start_locus (other.start_locus), - end_locus (other.end_locus), marked_for_strip (other.marked_for_strip) + inner_attrs (other.inner_attrs), label (other.label), + start_locus (other.start_locus), end_locus (other.end_locus), + marked_for_strip (other.marked_for_strip) { // guard to protect from null pointer dereference if (other.expr != nullptr) @@ -2524,6 +2557,9 @@ class BlockExpr : public ExprWithBlock outer_attrs = std::move (new_attrs); } + bool has_label () { return !label.is_error (); } + LoopLabel &get_label () { return label; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3352,36 +3388,6 @@ class UnsafeBlockExpr : public ExprWithBlock } }; -// Loop label expression AST node used with break and continue expressions -// TODO: inline? -class LoopLabel /*: public Node*/ -{ - Lifetime label; // or type LIFETIME_OR_LABEL - location_t locus; - - NodeId node_id; - -public: - std::string as_string () const; - - LoopLabel (Lifetime loop_label, location_t locus = UNDEF_LOCATION) - : label (std::move (loop_label)), locus (locus), - node_id (Analysis::Mappings::get ()->get_next_node_id ()) - {} - - // 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; } - - NodeId get_node_id () const { return node_id; } -}; - // Base loop expression AST node - aka LoopExpr class BaseLoopExpr : public ExprWithBlock { diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index aae054969633..99cb908e8049 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -923,14 +923,7 @@ class Method : public InherentImplItem, public TraitImplItem protected: /* Use covariance to implement clone function as returning this object * rather than base */ - Method *clone_inherent_impl_item_impl () const final override - { - return clone_method_impl (); - } - - /* Use covariance to implement clone function as returning this object - * rather than base */ - Method *clone_trait_impl_item_impl () const final override + Method *clone_associated_item_impl () const final override { return clone_method_impl (); } @@ -1703,14 +1696,7 @@ class Function : public VisItem, public InherentImplItem, public TraitImplItem /* Use covariance to implement clone function as returning this object * rather than base */ - Function *clone_inherent_impl_item_impl () const override - { - return new Function (*this); - } - - /* Use covariance to implement clone function as returning this object - * rather than base */ - Function *clone_trait_impl_item_impl () const override + Function *clone_associated_item_impl () const override { return new Function (*this); } @@ -1834,7 +1820,7 @@ class TypeAlias : public VisItem, public TraitImplItem /* Use covariance to implement clone function as returning this object * rather than base */ - TypeAlias *clone_trait_impl_item_impl () const override + TypeAlias *clone_associated_item_impl () const override { return new TypeAlias (*this); } @@ -2618,6 +2604,13 @@ class ConstantItem : public VisItem, const_expr (std::move (const_expr)), locus (locus) {} + ConstantItem (std::string ident, Visibility vis, std::unique_ptr type, + std::vector outer_attrs, location_t locus) + : VisItem (std::move (vis), std::move (outer_attrs)), + identifier (std::move (ident)), type (std::move (type)), + const_expr (nullptr), locus (locus) + {} + ConstantItem (ConstantItem const &other) : VisItem (other), identifier (other.identifier), locus (other.locus) { @@ -2699,14 +2692,7 @@ class ConstantItem : public VisItem, /* Use covariance to implement clone function as returning this object * rather than base */ - ConstantItem *clone_inherent_impl_item_impl () const override - { - return new ConstantItem (*this); - } - - /* Use covariance to implement clone function as returning this object - * rather than base */ - ConstantItem *clone_trait_impl_item_impl () const override + ConstantItem *clone_associated_item_impl () const override { return new ConstantItem (*this); } @@ -3016,7 +3002,7 @@ class TraitItemFunc : public TraitItem protected: // Clone function implementation as (not pure) virtual method - TraitItemFunc *clone_trait_item_impl () const override + TraitItemFunc *clone_associated_item_impl () const override { return new TraitItemFunc (*this); } @@ -3232,7 +3218,7 @@ class TraitItemMethod : public TraitItem protected: // Clone function implementation as (not pure) virtual method - TraitItemMethod *clone_trait_item_impl () const override + TraitItemMethod *clone_associated_item_impl () const override { return new TraitItemMethod (*this); } @@ -3337,7 +3323,7 @@ class TraitItemConst : public TraitItem protected: // Clone function implementation as (not pure) virtual method - TraitItemConst *clone_trait_item_impl () const override + TraitItemConst *clone_associated_item_impl () const override { return new TraitItemConst (*this); } @@ -3424,7 +3410,7 @@ class TraitItemType : public TraitItem protected: // Clone function implementation as (not pure) virtual method - TraitItemType *clone_trait_item_impl () const override + TraitItemType *clone_associated_item_impl () const override { return new TraitItemType (*this); } diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index 27d3134ec2a1..07991649a936 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -149,6 +149,7 @@ class MacroFragSpec { switch (kind) { + case PATH: case PAT: case TY: case VIS: @@ -668,7 +669,7 @@ class MacroInvocation : public TypeNoBounds, outer_attrs = std::move (new_attrs); } - NodeId get_pattern_node_id () const override final + NodeId get_node_id () const override final { return ExprWithoutBlock::get_node_id (); } @@ -803,20 +804,10 @@ class MacroInvocation : public TypeNoBounds, bool is_item () const override { return !has_semicolon (); } - TraitItem *clone_trait_item_impl () const override - { - return clone_macro_invocation_impl (); - }; - - TraitImplItem *clone_trait_impl_item_impl () const override + MacroInvocation *clone_associated_item_impl () const override { return clone_macro_invocation_impl (); }; - - InherentImplItem *clone_inherent_impl_item_impl () const override - { - return clone_macro_invocation_impl (); - } }; // more generic meta item path-only form diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index 912a64183857..7ac9cddeaf83 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -644,8 +644,6 @@ class PathInExpression : public PathPattern, public PathExpr outer_attrs = std::move (new_attrs); } - NodeId get_pattern_node_id () const override final { return get_node_id (); } - protected: /* Use covariance to implement clone function as returning this object * rather than base */ @@ -1244,8 +1242,6 @@ class QualifiedPathInExpression : public PathPattern, public PathExpr NodeId get_node_id () const override { return _node_id; } - NodeId get_pattern_node_id () const override final { return get_node_id (); } - protected: /* Use covariance to implement clone function as returning this object * rather than base */ diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h index 85ab627697cd..68fee92bde5d 100644 --- a/gcc/rust/ast/rust-pattern.h +++ b/gcc/rust/ast/rust-pattern.h @@ -49,9 +49,7 @@ class LiteralPattern : public Pattern void accept_vis (ASTVisitor &vis) override; - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } Literal &get_literal () { return lit; } @@ -149,9 +147,7 @@ class IdentifierPattern : public Pattern bool get_is_mut () const { return is_mut; } bool get_is_ref () const { return is_ref; } - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather @@ -179,9 +175,7 @@ class WildcardPattern : public Pattern void accept_vis (ASTVisitor &vis) override; - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather @@ -208,7 +202,7 @@ class RestPattern : public Pattern void accept_vis (ASTVisitor &vis) override; - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override final { return node_id; } protected: RestPattern *clone_pattern_impl () const override @@ -435,9 +429,7 @@ class RangePattern : public Pattern return upper; } - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather @@ -505,9 +497,7 @@ class ReferencePattern : public Pattern bool get_is_mut () const { return is_mut; } - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather @@ -942,9 +932,7 @@ class StructPattern : public Pattern PathInExpression &get_path () { return path; } const PathInExpression &get_path () const { return path; } - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather @@ -1181,9 +1169,7 @@ class TupleStructPattern : public Pattern PathInExpression &get_path () { return path; } const PathInExpression &get_path () const { return path; } - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather @@ -1423,9 +1409,7 @@ class TuplePattern : public Pattern return items; } - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather @@ -1485,9 +1469,7 @@ class GroupedPattern : public Pattern return pattern_in_parens; } - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather @@ -1551,9 +1533,7 @@ class SlicePattern : public Pattern return items; } - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather @@ -1618,9 +1598,7 @@ class AltPattern : public Pattern return alts; } - NodeId get_node_id () const { return node_id; } - - NodeId get_pattern_node_id () const override final { return node_id; } + NodeId get_node_id () const override { return node_id; } protected: /* Use covariance to implement clone function as returning this object rather diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index 9a51c4752047..7aab59baefec 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -615,7 +615,7 @@ HIRCompileBase::compile_function ( param_vars.push_back (compiled_param_var); const HIR::Pattern ¶m_pattern = *referenced_param.get_param_name (); - ctx->insert_var_decl (param_pattern.get_pattern_mappings ().get_hirid (), + ctx->insert_var_decl (param_pattern.get_mappings ().get_hirid (), compiled_param_var); } diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 24d6eba957e8..e60d32ca9411 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -340,9 +340,9 @@ class Context bool const_context_p (void) { return (const_context > 0); } std::string mangle_item (const TyTy::BaseType *ty, - const Resolver::CanonicalPath &path) const + const Resolver::CanonicalPath &path) { - return mangler.mangle_item (ty, path); + return mangler.mangle_item (this, ty, path); } void push_closure_context (HirId id); diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index bd91c91c9390..5f4ce5411cee 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -184,8 +184,8 @@ void CompileExpr::visit (HIR::CompoundAssignmentExpr &expr) { auto op = expr.get_expr_type (); - auto lhs = CompileExpr::Compile (expr.get_left_expr ().get (), ctx); - auto rhs = CompileExpr::Compile (expr.get_right_expr ().get (), ctx); + auto lhs = CompileExpr::Compile (expr.get_lhs ().get (), ctx); + auto rhs = CompileExpr::Compile (expr.get_rhs ().get (), ctx); // this might be an operator overload situation lets check TyTy::FnType *fntype; @@ -198,8 +198,8 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr) expr.get_expr_type ()); auto compound_assignment = resolve_operator_overload (lang_item_type, expr, lhs, rhs, - expr.get_left_expr ().get (), - expr.get_right_expr ().get ()); + expr.get_lhs ().get (), + expr.get_rhs ().get ()); ctx->add_statement (compound_assignment); return; @@ -352,6 +352,12 @@ CompileExpr::visit (HIR::IfExprConseqElse &expr) void CompileExpr::visit (HIR::BlockExpr &expr) { + if (expr.has_label ()) + { + rust_error_at (expr.get_locus (), "labeled blocks are not supported"); + return; + } + TyTy::BaseType *block_tyty = nullptr; if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &block_tyty)) @@ -1038,7 +1044,7 @@ sort_tuple_patterns (HIR::MatchExpr &expr) auto items = HIR::TuplePattern (ref).get_items ()->clone_tuple_pattern_items (); - if (items->get_pattern_type () + if (items->get_item_type () == HIR::TuplePatternItems::TuplePatternItemType::MULTIPLE) { auto items_ref @@ -1066,7 +1072,7 @@ sort_tuple_patterns (HIR::MatchExpr &expr) // Construct a TuplePattern from the rest of the patterns result_pattern = std::unique_ptr ( - new HIR::TuplePattern (ref.get_pattern_mappings (), + new HIR::TuplePattern (ref.get_mappings (), std::move (new_items), ref.get_locus ())); } @@ -1635,17 +1641,13 @@ CompileExpr::visit (HIR::CallExpr &expr) return; bool is_variadic = false; - if (tyty->get_kind () == TyTy::TypeKind::FNDEF) - { - const TyTy::FnType *fn = static_cast (tyty); - is_variadic = fn->is_variadic (); - } - size_t required_num_args = expr.get_arguments ().size (); + if (tyty->get_kind () == TyTy::TypeKind::FNDEF) { const TyTy::FnType *fn = static_cast (tyty); required_num_args = fn->num_params (); + is_variadic = fn->is_variadic (); } else if (tyty->get_kind () == TyTy::TypeKind::FNPTR) { diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h index be92529a1acc..1df3875541a3 100644 --- a/gcc/rust/backend/rust-compile-extern.h +++ b/gcc/rust/backend/rust-compile-extern.h @@ -115,10 +115,8 @@ class CompileExternItem : public HIRCompileBase, } if (fntype->has_substitutions_defined ()) - { - // override the Hir Lookups for the substituions in this context - fntype->override_context (); - } + // override the HIR lookups for the substitutions in this context + fntype->override_context (); if (fntype->get_abi () == ABI::INTRINSIC) { diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index 05bd94d360b3..5358c8a6dc4e 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -85,8 +85,8 @@ CompilePatternCaseLabelExpr::visit (HIR::LiteralPattern &pattern) { // Compile the literal HIR::LiteralExpr *litexpr - = new HIR::LiteralExpr (pattern.get_pattern_mappings (), - pattern.get_literal (), pattern.get_locus (), + = new HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (), + pattern.get_locus (), std::vector ()); // Note: Floating point literals are currently accepted but will likely be @@ -164,10 +164,10 @@ void CompilePatternCaseLabelExpr::visit (HIR::RangePattern &pattern) { tree upper = compile_range_pattern_bound (pattern.get_upper_bound ().get (), - pattern.get_pattern_mappings (), + pattern.get_mappings (), pattern.get_locus (), ctx); tree lower = compile_range_pattern_bound (pattern.get_lower_bound ().get (), - pattern.get_pattern_mappings (), + pattern.get_mappings (), pattern.get_locus (), ctx); case_label_expr = build_case_label (lower, upper, associated_case_label); @@ -239,7 +239,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern) pattern->get_locus ()); ctx->insert_pattern_binding ( - pattern->get_pattern_mappings ().get_hirid (), binding); + pattern->get_mappings ().get_hirid (), binding); } } else @@ -255,7 +255,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern) pattern->get_locus ()); ctx->insert_pattern_binding ( - pattern->get_pattern_mappings ().get_hirid (), binding); + pattern->get_mappings ().get_hirid (), binding); } } } @@ -362,7 +362,7 @@ CompilePatternBindings::visit (HIR::ReferencePattern &pattern) void CompilePatternBindings::visit (HIR::IdentifierPattern &pattern) { - ctx->insert_pattern_binding (pattern.get_pattern_mappings ().get_hirid (), + ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (), match_scrutinee_expr); } @@ -371,7 +371,7 @@ CompilePatternLet::visit (HIR::IdentifierPattern &pattern) { Bvariable *var = nullptr; rust_assert ( - ctx->lookup_var_decl (pattern.get_pattern_mappings ().get_hirid (), &var)); + ctx->lookup_var_decl (pattern.get_mappings ().get_hirid (), &var)); auto fnctx = ctx->peek_fn (); if (ty->is_unit ()) @@ -416,7 +416,7 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern) tree access_expr = Backend::var_expression (tmp_var, pattern.get_locus ()); ctx->add_statement (init_stmt); - switch (pattern.get_items ()->get_pattern_type ()) + switch (pattern.get_items ()->get_item_type ()) { case HIR::TuplePatternItems::TuplePatternItemType::RANGED: { size_t tuple_idx = 0; @@ -429,7 +429,7 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern) for (auto &sub : items_lower) { TyTy::BaseType *ty_sub = nullptr; - HirId pattern_id = pattern.get_pattern_mappings ().get_hirid (); + HirId pattern_id = pattern.get_mappings ().get_hirid (); bool ok = ctx->get_tyctx ()->lookup_type (pattern_id, &ty_sub); rust_assert (ok); @@ -448,7 +448,7 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern) for (auto &sub : items_upper) { TyTy::BaseType *ty_sub = nullptr; - HirId pattern_id = pattern.get_pattern_mappings ().get_hirid (); + HirId pattern_id = pattern.get_mappings ().get_hirid (); bool ok = ctx->get_tyctx ()->lookup_type (pattern_id, &ty_sub); rust_assert (ok); @@ -470,7 +470,7 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern) for (auto &sub : items.get_patterns ()) { TyTy::BaseType *ty_sub = nullptr; - HirId pattern_id = pattern.get_pattern_mappings ().get_hirid (); + HirId pattern_id = pattern.get_mappings ().get_hirid (); bool ok = ctx->get_tyctx ()->lookup_type (pattern_id, &ty_sub); rust_assert (ok); diff --git a/gcc/rust/backend/rust-compile-stmt.cc b/gcc/rust/backend/rust-compile-stmt.cc index 5c1170b1c242..839fa0cf5abf 100644 --- a/gcc/rust/backend/rust-compile-stmt.cc +++ b/gcc/rust/backend/rust-compile-stmt.cc @@ -49,7 +49,7 @@ CompileStmt::visit (HIR::LetStmt &stmt) return; HIR::Pattern &stmt_pattern = *stmt.get_pattern (); - HirId stmt_id = stmt_pattern.get_pattern_mappings ().get_hirid (); + HirId stmt_id = stmt_pattern.get_mappings ().get_hirid (); TyTy::BaseType *ty = nullptr; if (!ctx->get_tyctx ()->lookup_type (stmt_id, &ty)) diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h index 91c55eec68dc..eb7977b58fd6 100644 --- a/gcc/rust/backend/rust-compile-var-decl.h +++ b/gcc/rust/backend/rust-compile-var-decl.h @@ -47,7 +47,7 @@ class CompileVarDecl : public HIRCompileBase, public HIR::HIRPatternVisitor translated_type, NULL /*decl_var*/, pattern.get_locus ()); - HirId stmt_id = pattern.get_pattern_mappings ().get_hirid (); + HirId stmt_id = pattern.get_mappings ().get_hirid (); ctx->insert_var_decl (stmt_id, var); locals.push_back (var); diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 27991994b844..404b90aa01ac 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -115,8 +115,8 @@ HIRCompileBase::coercion_site1 (tree rvalue, TyTy::BaseType *rval, if (!valid_coercion) return error_mark_node; - const TyTy::ReferenceType *exp - = static_cast (expected); + const TyTy::PointerType *exp + = static_cast (expected); TyTy::BaseType *actual_base = nullptr; if (actual->get_kind () == TyTy::TypeKind::REF) diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc index 6ca7e917f84b..8d104846b847 100644 --- a/gcc/rust/backend/rust-mangle.cc +++ b/gcc/rust/backend/rust-mangle.cc @@ -4,8 +4,17 @@ #include "rust-base62.h" #include "rust-unicode.h" #include "rust-diagnostics.h" +#include "rust-hir-full-decls.h" +#include "rust-hir-item.h" +#include "rust-hir-type-bounds.h" +#include "rust-system.h" +#include "rust-tyty-subst.h" +#include "rust-tyty.h" #include "rust-unicode.h" #include "rust-punycode.h" +#include "rust-hir.h" +#include "rust-compile-type.h" +#include // FIXME: Rename those to legacy_* static const std::string kMangledSymbolPrefix = "_ZN"; @@ -28,6 +37,43 @@ namespace Compile { Mangler::MangleVersion Mangler::version = MangleVersion::LEGACY; +struct V0Path +{ + std::string prefix = ""; + // Used for "N" + std::string ns = ""; + std::string path = ""; + // Used for "N" and "C" + std::string ident = ""; + // Used for "C" + std::string crate_disambiguator = ""; + // Used for "M" and "X" + std::string impl_path = ""; + std::string impl_type = ""; + std::string trait_type = ""; + // Used for generic types + std::string generic_postfix = ""; + std::string generic_prefix = ""; + + std::string as_string () const + { + if (prefix == "N") + return generic_prefix + prefix + ns + path + ident + generic_postfix; + else if (prefix == "M") + return prefix + impl_path + impl_type; + else if (prefix == "X") + return prefix + impl_type + trait_type; + else if (prefix == "C") + return prefix + crate_disambiguator + ident; + else + rust_unreachable (); + } +}; + +static std::string +v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty, + const Resolver::CanonicalPath &path); + static std::string legacy_mangle_name (const std::string &name) { @@ -52,8 +98,7 @@ legacy_mangle_name (const std::string &name) // _ZN74_$LT$example..Identity$u20$as$u20$example..FnLike$LT$$RF$T$C$$RF$T$GT$$GT$4call17ha9ee58935895acb3E tl::optional utf8_name = Utf8String::make_utf8_string (name); - if (!utf8_name.has_value ()) - rust_unreachable (); + rust_assert (utf8_name.has_value ()); std::vector chars = utf8_name.value ().get_chars (); std::string buffer; for (size_t i = 0; i < chars.size (); i++) @@ -151,9 +196,9 @@ static std::string v0_numeric_prefix (const TyTy::BaseType *ty) { static const std::map num_prefixes = { - {"[i8]", "a"}, {"[u8]", "h"}, {"[i16]", "s"}, {"[u16]", "t"}, - {"[i32]", "l"}, {"[u32]", "m"}, {"[i64]", "x"}, {"[u64]", "y"}, - {"[isize]", "i"}, {"[usize]", "j"}, {"[f32]", "f"}, {"[f64]", "d"}, + {"i8", "a"}, {"u8", "h"}, {"i16", "s"}, {"u16", "t"}, + {"i32", "l"}, {"u32", "m"}, {"i64", "x"}, {"u64", "y"}, + {"isize", "i"}, {"usize", "j"}, {"f32", "f"}, {"f64", "d"}, }; auto ty_kind = ty->get_kind (); @@ -170,7 +215,7 @@ v0_numeric_prefix (const TyTy::BaseType *ty) if (numeric_iter != num_prefixes.end ()) return numeric_iter->second; - return ""; + rust_unreachable (); } static std::string @@ -212,50 +257,104 @@ v0_simple_type_prefix (const TyTy::BaseType *ty) rust_unreachable (); } -// Add an underscore-terminated base62 integer to the mangling string. +static std::string +v0_complex_type_prefix (Context *ctx, const TyTy::BaseType *ty) +{ + // FIXME: ref, slice, dyn, etc. + // TODO: generics + switch (ty->get_kind ()) + { + case TyTy::TypeKind::ADT: { + const TyTy::ADTType *adt = static_cast (ty); + return v0_path (ctx, ty, adt->get_ident ().path); + } + break; + default: + return ""; + } +} + +// Returns an underscore-terminated base62 integer. // This corresponds to the `` grammar in the v0 mangling RFC: // - 0 is encoded as "_" // - any other value is encoded as itself minus one in base 62, followed by // "_" -static void -v0_add_integer_62 (std::string &mangled, uint64_t x) +static std::string +v0_integer_62 (uint64_t x) { + std::stringstream s; if (x > 0) - mangled.append (base62_integer (x - 1)); + s << base62_integer (x - 1); - mangled.append ("_"); + s << "_"; + return s.str (); } -// Add a tag-prefixed base62 integer to the mangling string when the +// Returns a tag-prefixed base62 integer when the // integer is greater than 0: // - 0 is encoded as "" (nothing) -// - any other value is encoded as + v0_add_integer_62(itself), that is +// - any other value is encoded as + v0_integer_62(itself), that is // + base62(itself - 1) + '_' -static void -v0_add_opt_integer_62 (std::string &mangled, std::string tag, uint64_t x) +static std::string +v0_opt_integer_62 (std::string tag, uint64_t x) { if (x > 0) { - mangled.append (tag); - v0_add_integer_62 (mangled, x); + return tag + v0_integer_62 (x); } + return ""; +} + +static std::string +v0_disambiguator (uint64_t dis) +{ + return v0_opt_integer_62 ("s", dis); +} + +static std::string +v0_type_prefix (Context *ctx, const TyTy::BaseType *ty) +{ + std::string ty_prefix; + + ty_prefix = v0_simple_type_prefix (ty); + if (!ty_prefix.empty ()) + return ty_prefix; + + ty_prefix = v0_complex_type_prefix (ctx, ty); + if (!ty_prefix.empty ()) + return ty_prefix; + + rust_unreachable (); } -static void -v0_add_disambiguator (std::string &mangled, uint64_t dis) +static std::string +v0_generic_args (Context *ctx, const TyTy::BaseType *ty) { - v0_add_opt_integer_62 (mangled, "s", dis); + std::stringstream ss; + const TyTy::FnType *fnty = static_cast (ty); + TyTy::SubstitutionArgumentMappings &subst_ref + = const_cast (fnty)->get_substitution_arguments (); + for (TyTy::SubstitutionArg &map : subst_ref.get_mappings ()) + { + ss << v0_type_prefix (ctx, map.get_tyty ()); + } + return ss.str (); } -// Add an identifier to the mangled string. This corresponds to the +// Returns an mangled identifier. This corresponds to the // `` grammar in the v0 mangling RFC. -static void -v0_add_identifier (std::string &mangled, const std::string &identifier) +static std::string +v0_identifier (const std::string &identifier) { + std::stringstream mangled; // The grammar for unicode identifier is contained in // , right under the one. If the // identifier contains unicode values, then an extra "u" needs to be added to // the mangling string and `punycode` must be used to encode the characters. + + if (!is_ascii_only (identifier)) + mangled << "u"; + tl::optional uident_opt = Utf8String::make_utf8_string (identifier); rust_assert (uident_opt.has_value ()); @@ -263,42 +362,228 @@ v0_add_identifier (std::string &mangled, const std::string &identifier) = encode_punycode (uident_opt.value ()); rust_assert (punycode_opt.has_value ()); - bool is_ascii_ident = true; - for (auto c : uident_opt.value ().get_chars ()) - if (c.value > 127) - { - is_ascii_ident = false; - break; - } - std::string punycode = punycode_opt.value (); - // remove tailing hyphen + + // remove a tailing hyphen if (punycode.back () == '-') punycode.pop_back (); - // replace hyphens in punycode with underscores + + // replace a hyphen in punycode with a underscore std::replace (punycode.begin (), punycode.end (), '-', '_'); - if (!is_ascii_ident) - mangled.append ("u"); + mangled << std::to_string (punycode.size ()); - mangled += std::to_string (punycode.size ()); - // If the first character of the identifier is a digit or an underscore, we - // add an extra underscore - if (punycode[0] == '_') - mangled += "_"; + // Add extra '_' + if (punycode[0] == '_' || ('0' <= punycode[0] && punycode[0] <= '9')) + mangled << "_"; - mangled += punycode; + mangled << punycode; + return mangled.str (); +} + +static V0Path +v0_type_path (V0Path path, std::string ident) +{ + V0Path v0path; + v0path.prefix = "N"; + v0path.ns = "t"; + v0path.path = path.as_string (); + v0path.ident = ident; + // TODO: Need ? + return v0path; +} + +static V0Path +v0_function_path (V0Path path, Rust::Compile::Context *ctx, + const TyTy::BaseType *ty, HIR::Function *fn, + std::string ident) +{ + V0Path v0path; + v0path.prefix = "N"; + v0path.ns = "v"; + v0path.path = path.as_string (); + v0path.ident = ident; + if (!fn->get_generic_params ().empty ()) + { + v0path.generic_prefix = "I"; + v0path.generic_postfix = v0_generic_args (ctx, ty) + "E"; + } + return v0path; +} + +static V0Path +v0_scope_path (V0Path path, std::string ident, std::string ns) +{ + V0Path v0path; + v0path.prefix = "N"; + v0path.ns = ns; + v0path.path = path.as_string (); + v0path.ident = ident; + return v0path; +} + +static V0Path +v0_crate_path (CrateNum crate_num, std::string ident) +{ + V0Path v0path; + v0path.prefix = "C"; + v0path.crate_disambiguator = v0_disambiguator (crate_num); + v0path.ident = ident; + return v0path; +} + +static V0Path +v0_inherent_or_trait_impl_path (Rust::Compile::Context *ctx, + HIR::ImplBlock *impl_block) +{ + V0Path v0path; + bool ok; + + // lookup impl type + TyTy::BaseType *impl_ty = nullptr; + ok = ctx->get_tyctx ()->lookup_type ( + impl_block->get_type ()->get_mappings ().get_hirid (), &impl_ty); + rust_assert (ok); + + // FIXME: dummy value for now + v0path.impl_path = "C5crate"; + v0path.impl_type = v0_type_prefix (ctx, impl_ty); + + if (impl_block->has_trait_ref ()) + { + // trait impl: X + v0path.prefix = "X"; + + TyTy::BaseType *trait_ty = nullptr; + ok = ctx->get_tyctx ()->lookup_type ( + impl_block->get_trait_ref ()->get_mappings ().get_hirid (), &trait_ty); + rust_assert (ok); + + v0path.trait_type = v0_type_prefix (ctx, trait_ty); + } + else + // inherent impl: M + v0path.prefix = "M"; + + return v0path; } static std::string -v0_type_prefix (const TyTy::BaseType *ty) +v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty, + const Resolver::CanonicalPath &cpath) { - auto ty_prefix = v0_simple_type_prefix (ty); - if (!ty_prefix.empty ()) - return ty_prefix; + auto mappings = Analysis::Mappings::get (); - // FIXME: We need to fetch more type prefixes - rust_unreachable (); + V0Path v0path = {}; + + cpath.iterate_segs ([&] (const Resolver::CanonicalPath &seg) { + HirId hir_id; + bool ok = mappings->lookup_node_to_hir (seg.get_node_id (), &hir_id); + if (!ok) + { + // FIXME: generic arg in canonical path? (e.g. in crate::S) + rust_unreachable (); + } + + HirId parent_impl_id = UNKNOWN_HIRID; + HIR::ImplItem *impl_item + = mappings->lookup_hir_implitem (hir_id, &parent_impl_id); + HIR::TraitItem *trait_item = mappings->lookup_hir_trait_item (hir_id); + HIR::Item *item = mappings->lookup_hir_item (hir_id); + + if (impl_item != nullptr) + { + switch (impl_item->get_impl_item_type ()) + { + case HIR::ImplItem::FUNCTION: { + HIR::Function *fn = static_cast (impl_item); + v0path = v0_function_path (v0path, ctx, ty, fn, + v0_identifier (seg.get ())); + } + break; + case HIR::ImplItem::CONSTANT: + v0path = v0_scope_path (v0path, v0_identifier (seg.get ()), "v"); + break; + default: + rust_internal_error_at (UNDEF_LOCATION, "Attempt to mangle '%s'", + cpath.get ().c_str ()); + break; + } + } + else if (trait_item != nullptr) + { + switch (trait_item->get_item_kind ()) + { + case HIR::TraitItem::FUNC: { + HIR::Function *fn = static_cast (impl_item); + v0path = v0_function_path (v0path, ctx, ty, fn, + v0_identifier (seg.get ())); + } + break; + case HIR::TraitItem::CONST: + v0path = v0_scope_path (v0path, v0_identifier (seg.get ()), "v"); + break; + default: + rust_internal_error_at (UNDEF_LOCATION, "Attempt to mangle '%s'", + cpath.get ().c_str ()); + break; + } + } + else if (item != nullptr) + switch (item->get_item_kind ()) + { + case HIR::Item::ItemKind::Function: { + HIR::Function *fn = static_cast (item); + v0path = v0_function_path (v0path, ctx, ty, fn, + v0_identifier (seg.get ())); + } + break; + case HIR::Item::ItemKind::Module: + v0path = v0_scope_path (v0path, v0_identifier (seg.get ()), "t"); + break; + case HIR::Item::ItemKind::Trait: // FIXME: correct? + case HIR::Item::ItemKind::Static: + case HIR::Item::ItemKind::Constant: + v0path = v0_scope_path (v0path, v0_identifier (seg.get ()), "v"); + break; + case HIR::Item::ItemKind::Struct: + case HIR::Item::ItemKind::Enum: + case HIR::Item::ItemKind::Union: + v0path = v0_type_path (v0path, v0_identifier (seg.get ())); + break; + case HIR::Item::ItemKind::Impl: + // Trait impl or inherent impl. + { + HIR::ImplBlock *impl_block = static_cast (item); + v0path = v0_inherent_or_trait_impl_path (ctx, impl_block); + } + break; + case HIR::Item::ItemKind::ExternBlock: + case HIR::Item::ItemKind::ExternCrate: + case HIR::Item::ItemKind::UseDeclaration: + case HIR::Item::ItemKind::TypeAlias: + case HIR::Item::ItemKind::EnumItem: // FIXME: correct? + rust_internal_error_at (UNDEF_LOCATION, "Attempt to mangle '%s'", + cpath.get ().c_str ()); + break; + } + else + { + // Not HIR item, impl item, nor trait impl item. Assume a crate. + // FIXME: Do closures get here? + + // std::string crate_name; + // bool ok = mappings->get_crate_name (path.get_crate_num (), + // crate_name); rust_assert (ok); rust_assert (crate_name == seg.get()); + + v0path + = v0_crate_path (cpath.get_crate_num (), v0_identifier (seg.get ())); + } + + return true; + }); + + return v0path.as_string (); } static std::string @@ -313,25 +598,27 @@ legacy_mangle_item (const TyTy::BaseType *ty, } static std::string -v0_mangle_item (const TyTy::BaseType *ty, const Resolver::CanonicalPath &path) +v0_mangle_item (Rust::Compile::Context *ctx, const TyTy::BaseType *ty, + const Resolver::CanonicalPath &path) { - // we can get this from the canonical_path - auto mappings = Analysis::Mappings::get (); - std::string crate_name; - bool ok = mappings->get_crate_name (path.get_crate_num (), crate_name); - rust_assert (ok); + rust_debug ("Start mangling: %s", path.get ().c_str ()); - std::string mangled; - // FIXME: Add real algorithm once all pieces are implemented - v0_add_identifier (mangled, crate_name); - v0_add_disambiguator (mangled, 62); - auto ty_prefix = v0_type_prefix (ty); + // auto mappings = Analysis::Mappings::get (); + // std::string crate_name; + // bool ok = mappings->get_crate_name (path.get_crate_num (), crate_name); + // rust_assert (ok); - rust_unreachable (); + std::stringstream mangled; + mangled << "_R"; + mangled << v0_path (ctx, ty, path); + + rust_debug ("=> %s", mangled.str ().c_str ()); + + return mangled.str (); } std::string -Mangler::mangle_item (const TyTy::BaseType *ty, +Mangler::mangle_item (Rust::Compile::Context *ctx, const TyTy::BaseType *ty, const Resolver::CanonicalPath &path) const { switch (version) @@ -339,7 +626,7 @@ Mangler::mangle_item (const TyTy::BaseType *ty, case Mangler::MangleVersion::LEGACY: return legacy_mangle_item (ty, path); case Mangler::MangleVersion::V0: - return v0_mangle_item (ty, path); + return v0_mangle_item (ctx, ty, path); default: rust_unreachable (); } diff --git a/gcc/rust/backend/rust-mangle.h b/gcc/rust/backend/rust-mangle.h index 6d5a64f8bce0..09329bb99234 100644 --- a/gcc/rust/backend/rust-mangle.h +++ b/gcc/rust/backend/rust-mangle.h @@ -23,6 +23,8 @@ namespace Rust { namespace Compile { +class Context; + class Mangler { public: @@ -34,7 +36,8 @@ class Mangler }; // this needs to support Legacy and V0 see github #429 or #305 - std::string mangle_item (const TyTy::BaseType *ty, + std::string mangle_item (Rust::Compile::Context *ctx, + const TyTy::BaseType *ty, const Resolver::CanonicalPath &path) const; static void set_mangling (int frust_mangling_value) @@ -48,5 +51,4 @@ class Mangler } // namespace Compile } // namespace Rust - #endif // RUST_MANGLE_H diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc index 6bdc2fa17a70..81f678dabaaa 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc +++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc @@ -375,8 +375,8 @@ PrivacyReporter::visit (HIR::AssignmentExpr &expr) void PrivacyReporter::visit (HIR::CompoundAssignmentExpr &expr) { - expr.get_left_expr ()->accept_vis (*this); - expr.get_right_expr ()->accept_vis (*this); + expr.get_lhs ()->accept_vis (*this); + expr.get_rhs ()->accept_vis (*this); } void diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc index 22668d5d7bb7..032a8ec9f3aa 100644 --- a/gcc/rust/checks/errors/rust-const-checker.cc +++ b/gcc/rust/checks/errors/rust-const-checker.cc @@ -214,8 +214,8 @@ ConstChecker::visit (AssignmentExpr &expr) void ConstChecker::visit (CompoundAssignmentExpr &expr) { - expr.get_left_expr ()->accept_vis (*this); - expr.get_right_expr ()->accept_vis (*this); + expr.get_lhs ()->accept_vis (*this); + expr.get_rhs ()->accept_vis (*this); } void diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc index d5b772b2063d..bee446f57060 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.cc +++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc @@ -327,8 +327,8 @@ UnsafeChecker::visit (AssignmentExpr &expr) void UnsafeChecker::visit (CompoundAssignmentExpr &expr) { - expr.get_left_expr ()->accept_vis (*this); - expr.get_right_expr ()->accept_vis (*this); + expr.get_lhs ()->accept_vis (*this); + expr.get_rhs ()->accept_vis (*this); } void diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc index 964602b98b9e..cac309946576 100644 --- a/gcc/rust/expand/rust-derive-clone.cc +++ b/gcc/rust/expand/rust-derive-clone.cc @@ -46,7 +46,8 @@ std::unique_ptr DeriveClone::clone_fn (std::unique_ptr &&clone_expr) { auto block = std::unique_ptr ( - new BlockExpr ({}, std::move (clone_expr), {}, {}, loc, loc)); + new BlockExpr ({}, std::move (clone_expr), {}, {}, AST::LoopLabel::error (), + loc, loc)); auto big_self_type = builder.single_type_path ("Self"); return std::unique_ptr ( diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index f00b64c3bc07..d0b19d95caa6 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -583,7 +583,6 @@ MacroBuiltin::include_str_handler (location_t invoc_locus, auto node = AST::SingleASTNode (make_string (invoc_locus, str)); auto str_tok = make_token (Token::make_string (invoc_locus, std::move (str))); - // FIXME: Do not return an empty token vector here return AST::Fragment ({node}, std::move (str_tok)); } @@ -785,7 +784,6 @@ MacroBuiltin::env_handler (location_t invoc_locus, AST::MacroInvocData &invoc) auto tok = make_token (Token::make_string (invoc_locus, std::move (env_value))); - // FIXME: Do not return an empty token vector here return AST::Fragment ({node}, std::move (tok)); } @@ -824,7 +822,6 @@ MacroBuiltin::cfg_handler (location_t invoc_locus, AST::MacroInvocData &invoc) auto tok = make_token ( Token::make (result ? TRUE_LITERAL : FALSE_LITERAL, invoc_locus)); - // FIXME: Do not return an empty token vector here return AST::Fragment ({literal_exp}, std::move (tok)); } @@ -912,7 +909,6 @@ MacroBuiltin::line_handler (location_t invoc_locus, AST::MacroInvocData &) auto tok = make_token (Token::make_int (invoc_locus, std::to_string (current_line))); - // FIXME: Do not return an empty token vector here return AST::Fragment ({line_no}, std::move (tok)); } diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h index c8f64402c2f1..abb0227426a1 100644 --- a/gcc/rust/hir/rust-ast-lower-implitem.h +++ b/gcc/rust/hir/rust-ast-lower-implitem.h @@ -32,31 +32,7 @@ class ASTLowerImplItem : public ASTLoweringBase using Rust::HIR::ASTLoweringBase::visit; public: - static HIR::ImplItem *translate (AST::InherentImplItem *item, - HirId parent_impl_id) - { - ASTLowerImplItem resolver; - item->accept_vis (resolver); - - if (resolver.translated != nullptr) - { - rust_assert (resolver.item_cast != nullptr); - - auto id = resolver.translated->get_impl_mappings ().get_hirid (); - auto defid = resolver.translated->get_impl_mappings ().get_defid (); - auto locus = resolver.translated->get_locus (); - - resolver.handle_outer_attributes (*resolver.item_cast); - resolver.mappings->insert_hir_implitem (parent_impl_id, - resolver.translated); - resolver.mappings->insert_location (id, locus); - resolver.mappings->insert_defid_mapping (defid, resolver.item_cast); - } - - return resolver.translated; - } - - static HIR::ImplItem *translate (AST::TraitImplItem *item, + static HIR::ImplItem *translate (AST::AssociatedItem *item, HirId parent_impl_id) { ASTLowerImplItem resolver; @@ -312,7 +288,7 @@ class ASTLowerTraitItem : public ASTLoweringBase using Rust::HIR::ASTLoweringBase::visit; public: - static HIR::TraitItem *translate (AST::TraitItem *item) + static HIR::TraitItem *translate (AST::AssociatedItem *item) { ASTLowerTraitItem resolver; item->accept_vis (resolver); diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc index bac79ef907b4..f0f94f688f29 100644 --- a/gcc/rust/hir/rust-ast-lower-pattern.cc +++ b/gcc/rust/hir/rust-ast-lower-pattern.cc @@ -35,8 +35,7 @@ ASTLoweringPattern::translate (AST::Pattern *pattern, bool is_let_top_level) resolver.mappings->insert_hir_pattern (resolver.translated); resolver.mappings->insert_location ( - resolver.translated->get_pattern_mappings ().get_hirid (), - pattern->get_locus ()); + resolver.translated->get_mappings ().get_hirid (), pattern->get_locus ()); return resolver.translated; } @@ -122,8 +121,23 @@ ASTLoweringPattern::visit (AST::StructPattern &pattern) switch (field->get_item_type ()) { case AST::StructPatternField::ItemType::TUPLE_PAT: { - // TODO - rust_unreachable (); + AST::StructPatternFieldTuplePat &tuple + = static_cast (*field); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, tuple.get_node_id (), + mappings->get_next_hir_id ( + crate_num), + UNKNOWN_LOCAL_DEFID); + + std::unique_ptr pat (ASTLoweringPattern::translate ( + tuple.get_index_pattern ().get ())); + + f = new HIR::StructPatternFieldTuplePat (mapping, + tuple.get_index (), + std::move (pat), + tuple.get_outer_attrs (), + tuple.get_locus ()); } break; diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index c3e12688b81f..8323894b887d 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -95,6 +95,8 @@ ASTLowering::go () void ASTLoweringBlock::visit (AST::BlockExpr &expr) { + auto label = lower_loop_label (expr.get_label ()); + std::vector> block_stmts; bool block_did_terminate = false; @@ -143,8 +145,8 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr) = new HIR::BlockExpr (mapping, std::move (block_stmts), std::unique_ptr (tail_expr), tail_reachable, expr.get_inner_attrs (), - expr.get_outer_attrs (), expr.get_start_locus (), - expr.get_end_locus ()); + expr.get_outer_attrs (), label, + expr.get_start_locus (), expr.get_end_locus ()); terminated = block_did_terminate; } diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc index 342c62e58a1b..8e31f2774382 100644 --- a/gcc/rust/hir/rust-hir-dump.cc +++ b/gcc/rust/hir/rust-hir-dump.cc @@ -983,7 +983,7 @@ Dump::visit (CompoundAssignmentExpr &e) begin ("CompoundAssignmentExpr"); do_operatorexpr (e); - visit_field ("right_expr", *e.get_right_expr ()); + visit_field ("right_expr", *e.get_rhs ()); std::string str; @@ -2019,7 +2019,7 @@ Dump::visit (LiteralPattern &e) { begin ("LiteralPattern"); put_field ("lit", e.get_literal ().as_string ()); - do_mappings (e.get_pattern_mappings ()); + do_mappings (e.get_mappings ()); end ("LiteralPattern"); } @@ -2042,7 +2042,7 @@ void Dump::visit (WildcardPattern &e) { begin ("WildcardPattern"); - do_mappings (e.get_pattern_mappings ()); + do_mappings (e.get_mappings ()); end ("WildcardPattern"); } @@ -2075,7 +2075,7 @@ void Dump::visit (RangePattern &e) { begin ("RangePattern"); - do_mappings (e.get_pattern_mappings ()); + do_mappings (e.get_mappings ()); put_field ("lower", e.get_lower_bound ()->as_string ()); put_field ("upper", e.get_upper_bound ()->as_string ()); put_field ("has_ellipsis_syntax", @@ -2087,7 +2087,7 @@ void Dump::visit (ReferencePattern &e) { begin ("ReferencePattern"); - do_mappings (e.get_pattern_mappings ()); + do_mappings (e.get_mappings ()); put_field ("mut", std::to_string (e.is_mut ())); put_field ("pattern", e.get_referenced_pattern ()->as_string ()); end ("ReferencePattern"); @@ -2161,7 +2161,7 @@ void Dump::visit (TupleStructPattern &e) { begin ("TupleStructPattern"); - do_mappings (e.get_pattern_mappings ()); + do_mappings (e.get_mappings ()); put_field ("path", e.get_path ().as_string ()); @@ -2191,7 +2191,7 @@ void Dump::visit (TuplePattern &e) { begin ("TuplePattern"); - do_mappings (e.get_pattern_mappings ()); + do_mappings (e.get_mappings ()); visit_field ("items", e.get_items ()); end ("TuplePattern"); } @@ -2200,7 +2200,7 @@ void Dump::visit (SlicePattern &e) { begin ("SlicePattern"); - do_mappings (e.get_pattern_mappings ()); + do_mappings (e.get_mappings ()); visit_collection ("items", e.get_items ()); end ("SlicePattern"); } @@ -2209,7 +2209,7 @@ void Dump::visit (AltPattern &e) { begin ("AltPattern"); - do_mappings (e.get_pattern_mappings ()); + do_mappings (e.get_mappings ()); visit_collection ("alts", e.get_alts ()); end ("AltPattern"); } diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 1a917fd11cb5..c5abeaa23a05 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -28,6 +28,34 @@ namespace Rust { namespace HIR { +// Loop label expression HIR node used with break and continue expressions +// TODO: inline? +class LoopLabel /*: public Node*/ +{ + Lifetime label; // or type LIFETIME_OR_LABEL + + location_t locus; + + Analysis::NodeMapping mappings; + +public: + std::string as_string () const; + + LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label, + location_t locus) + : label (std::move (loop_label)), locus (locus), mappings (mapping) + {} + + // Returns whether the LoopLabel is in an error state. + bool is_error () const { return label.is_error (); } + + location_t get_locus () const { return locus; } + + Analysis::NodeMapping &get_mappings () { return mappings; } + + Lifetime &get_lifetime () { return label; } +}; + // HIR node for an expression with an accompanying block - abstract class ExprWithBlock : public Expr { @@ -734,9 +762,9 @@ class CompoundAssignmentExpr : public OperatorExpr void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr &get_left_expr () { return main_or_left_expr; } + std::unique_ptr &get_lhs () { return main_or_left_expr; } - std::unique_ptr &get_right_expr () { return right_expr; } + std::unique_ptr &get_rhs () { return right_expr; } void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); } void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); } @@ -1510,6 +1538,8 @@ class StructExprFieldIdentifierValue : public StructExprFieldWithVal void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; + Identifier get_field_name () const { return field_name; } + StructExprFieldKind get_kind () const override { return StructExprFieldKind::IDENTIFIER_VALUE; @@ -2121,6 +2151,7 @@ class BlockExpr : public ExprWithBlock, public WithInnerAttrs std::vector > statements; std::unique_ptr expr; bool tail_reachable; + LoopLabel label; location_t start_locus; location_t end_locus; @@ -2140,19 +2171,19 @@ class BlockExpr : public ExprWithBlock, public WithInnerAttrs std::vector > block_statements, std::unique_ptr block_expr, bool tail_reachable, AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, - location_t start_locus, location_t end_locus) + LoopLabel label, location_t start_locus, location_t end_locus) : ExprWithBlock (std::move (mappings), std::move (outer_attribs)), WithInnerAttrs (std::move (inner_attribs)), statements (std::move (block_statements)), expr (std::move (block_expr)), - tail_reachable (tail_reachable), start_locus (start_locus), - end_locus (end_locus) + tail_reachable (tail_reachable), label (std::move (label)), + start_locus (start_locus), end_locus (end_locus) {} // Copy constructor with clone BlockExpr (BlockExpr const &other) : ExprWithBlock (other), /*statements(other.statements),*/ - WithInnerAttrs (other.inner_attrs), start_locus (other.start_locus), - end_locus (other.end_locus) + WithInnerAttrs (other.inner_attrs), label (other.label), + start_locus (other.start_locus), end_locus (other.end_locus) { // guard to protect from null pointer dereference if (other.expr != nullptr) @@ -2211,6 +2242,9 @@ class BlockExpr : public ExprWithBlock, public WithInnerAttrs return ExprType::Block; } + bool has_label () const { return !label.is_error (); } + LoopLabel &get_label () { return label; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -2835,34 +2869,6 @@ class UnsafeBlockExpr : public ExprWithBlock } }; -// Loop label expression HIR node used with break and continue expressions -// TODO: inline? -class LoopLabel /*: public Node*/ -{ - Lifetime label; // or type LIFETIME_OR_LABEL - - location_t locus; - - Analysis::NodeMapping mappings; - -public: - std::string as_string () const; - - LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label, - location_t locus) - : label (std::move (loop_label)), locus (locus), mappings (mapping) - {} - - // Returns whether the LoopLabel is in an error state. - bool is_error () const { return label.is_error (); } - - location_t get_locus () const { return locus; } - - Analysis::NodeMapping &get_mappings () { return mappings; } - - Lifetime &get_lifetime () { return label; } -}; - // Base loop expression HIR node - aka LoopExpr class BaseLoopExpr : public ExprWithBlock { diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index e5709211d837..002dd1da75c9 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -22,6 +22,7 @@ #include "rust-abi.h" #include "rust-ast-full-decls.h" #include "rust-common.h" +#include "rust-hir-expr.h" #include "rust-hir.h" #include "rust-hir-path.h" diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index 3f61e4585cca..c07448060431 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -321,7 +321,7 @@ class PathPattern : public Pattern PathExprSegment &get_root_seg () { return segments.at (0); } - PathExprSegment get_final_segment () const { return segments.back (); } + const PathExprSegment &get_final_segment () const { return segments.back (); } PatternType get_pattern_type () const override final { @@ -390,9 +390,9 @@ class PathInExpression : public PathPattern, public PathExpr == 0; } - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { - return get_mappings (); + return mappings; } protected: @@ -864,9 +864,9 @@ class QualifiedPathInExpression : public PathPattern, public PathExpr location_t get_locus () { return locus; } - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { - return get_mappings (); + return mappings; } protected: diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h index b3dc56a88c6b..65dc53a4ca6d 100644 --- a/gcc/rust/hir/tree/rust-hir-pattern.h +++ b/gcc/rust/hir/tree/rust-hir-pattern.h @@ -51,7 +51,7 @@ class LiteralPattern : public Pattern void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRPatternVisitor &vis) override; - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } @@ -137,7 +137,7 @@ class IdentifierPattern : public Pattern void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRPatternVisitor &vis) override; - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } @@ -176,7 +176,7 @@ class WildcardPattern : public Pattern void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRPatternVisitor &vis) override; - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } @@ -395,7 +395,7 @@ class RangePattern : public Pattern bool get_has_ellipsis_syntax () { return has_ellipsis_syntax; }; - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } @@ -464,7 +464,7 @@ class ReferencePattern : public Pattern void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRPatternVisitor &vis) override; - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } @@ -758,7 +758,7 @@ class StructPattern : public Pattern PathInExpression &get_path () { return path; } StructPatternElements &get_struct_pattern_elems () { return elems; } - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } @@ -794,7 +794,7 @@ class TupleStructItems : public FullVisitable // Unique pointer custom clone function std::unique_ptr clone_tuple_struct_items () const { - return std::unique_ptr (clone_tuple_struct_items_impl ()); + return std::unique_ptr (clone_tuple_items_impl ()); } virtual std::string as_string () const = 0; @@ -805,7 +805,7 @@ class TupleStructItems : public FullVisitable protected: // pure virtual clone implementation - virtual TupleStructItems *clone_tuple_struct_items_impl () const = 0; + virtual TupleStructItems *clone_tuple_items_impl () const = 0; }; // Class for non-ranged tuple struct pattern patterns @@ -857,7 +857,7 @@ class TupleStructItemsNoRange : public TupleStructItems protected: /* Use covariance to implement clone function as returning this object rather * than base */ - TupleStructItemsNoRange *clone_tuple_struct_items_impl () const override + TupleStructItemsNoRange *clone_tuple_items_impl () const override { return new TupleStructItemsNoRange (*this); } @@ -936,7 +936,7 @@ class TupleStructItemsRange : public TupleStructItems protected: /* Use covariance to implement clone function as returning this object rather * than base */ - TupleStructItemsRange *clone_tuple_struct_items_impl () const override + TupleStructItemsRange *clone_tuple_items_impl () const override { return new TupleStructItemsRange (*this); } @@ -991,7 +991,7 @@ class TupleStructPattern : public Pattern std::unique_ptr &get_items () { return items; } - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } @@ -1027,17 +1027,16 @@ class TuplePatternItems : public FullVisitable // Unique pointer custom clone function std::unique_ptr clone_tuple_pattern_items () const { - return std::unique_ptr ( - clone_tuple_pattern_items_impl ()); + return std::unique_ptr (clone_tuple_items_impl ()); } virtual std::string as_string () const = 0; - virtual TuplePatternItemType get_pattern_type () const = 0; + virtual TuplePatternItemType get_item_type () const = 0; protected: // pure virtual clone implementation - virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0; + virtual TuplePatternItems *clone_tuple_items_impl () const = 0; }; // Class representing TuplePattern patterns where there are multiple patterns @@ -1078,7 +1077,7 @@ class TuplePatternItemsMultiple : public TuplePatternItems void accept_vis (HIRFullVisitor &vis) override; - TuplePatternItemType get_pattern_type () const override + TuplePatternItemType get_item_type () const override { return TuplePatternItemType::MULTIPLE; } @@ -1092,7 +1091,7 @@ class TuplePatternItemsMultiple : public TuplePatternItems protected: /* Use covariance to implement clone function as returning this object rather * than base */ - TuplePatternItemsMultiple *clone_tuple_pattern_items_impl () const override + TuplePatternItemsMultiple *clone_tuple_items_impl () const override { return new TuplePatternItemsMultiple (*this); } @@ -1148,7 +1147,7 @@ class TuplePatternItemsRanged : public TuplePatternItems void accept_vis (HIRFullVisitor &vis) override; - TuplePatternItemType get_pattern_type () const override + TuplePatternItemType get_item_type () const override { return TuplePatternItemType::RANGED; } @@ -1174,7 +1173,7 @@ class TuplePatternItemsRanged : public TuplePatternItems protected: /* Use covariance to implement clone function as returning this object rather * than base */ - TuplePatternItemsRanged *clone_tuple_pattern_items_impl () const override + TuplePatternItemsRanged *clone_tuple_items_impl () const override { return new TuplePatternItemsRanged (*this); } @@ -1219,7 +1218,7 @@ class TuplePattern : public Pattern void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRPatternVisitor &vis) override; - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } @@ -1294,7 +1293,7 @@ class SlicePattern : public Pattern void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRPatternVisitor &vis) override; - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } @@ -1366,7 +1365,7 @@ class AltPattern : public Pattern void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRPatternVisitor &vis) override; - Analysis::NodeMapping get_pattern_mappings () const override final + const Analysis::NodeMapping &get_mappings () const override final { return mappings; } diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h index abbc2a09d053..81baa500d0cf 100644 --- a/gcc/rust/hir/tree/rust-hir.h +++ b/gcc/rust/hir/tree/rust-hir.h @@ -420,7 +420,7 @@ class Pattern : public Node, virtual public FullVisitable virtual void accept_vis (HIRPatternVisitor &vis) = 0; - virtual Analysis::NodeMapping get_pattern_mappings () const = 0; + virtual const Analysis::NodeMapping &get_mappings () const = 0; virtual location_t get_locus () const = 0; diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc index 9a1132f6a727..75967f239cbc 100644 --- a/gcc/rust/lex/rust-token.cc +++ b/gcc/rust/lex/rust-token.cc @@ -245,6 +245,8 @@ Token::as_string () const return "b'" + escape_special_chars (get_str (), Context::Char) + "'"; case LIFETIME: return "'" + get_str (); + case SCOPE_RESOLUTION: + return "::"; case INT_LITERAL: if (get_type_hint () == CORETYPE_UNKNOWN) return get_str (); diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index be3a7b8f3fbf..7b5fb83de2af 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -22,6 +22,7 @@ /* DO NOT INCLUDE ANYWHERE - this is automatically included with rust-parse.h * This is also the reason why there are no include guards. */ +#include "rust-token.h" #define INCLUDE_ALGORITHM #include "rust-diagnostics.h" #include "rust-make-unique.h" @@ -1070,6 +1071,18 @@ Parser::parse_token_tree () } } +template +bool +Parser::is_macro_rules_def (const_TokenPtr t) +{ + auto macro_name = lexer.peek_token (2)->get_id (); + + bool allowed_macro_name = (macro_name == IDENTIFIER || macro_name == TRY); + + return t->get_str () == "macro_rules" + && lexer.peek_token (1)->get_id () == EXCLAM && allowed_macro_name; +} + // Parses a single item template std::unique_ptr @@ -1133,14 +1146,15 @@ Parser::parse_item (bool called_from_statement) return parse_vis_item (std::move (outer_attrs)); // or should this go straight to parsing union? } - else if (t->get_str () == "default") + else if (t->get_str () == "default" + && lexer.peek_token (1)->get_id () != EXCLAM) { add_error (Error (t->get_locus (), "%qs is only allowed on items within %qs blocks", "default", "impl")); return nullptr; } - else if (t->get_str () == "macro_rules") + else if (is_macro_rules_def (t)) { // macro_rules! macro item return parse_macro_rules_def (std::move (outer_attrs)); @@ -2296,8 +2310,11 @@ Parser::parse_visibility () auto vis_loc = lexer.peek_token ()->get_locus (); lexer.skip_token (); - // create simple pub visibility if no parentheses - if (lexer.peek_token ()->get_id () != LEFT_PAREN) + // create simple pub visibility if + // - found no parentheses + // - found unit type `()` + if (lexer.peek_token ()->get_id () != LEFT_PAREN + || lexer.peek_token (1)->get_id () == RIGHT_PAREN) { return AST::Visibility::create_public (vis_loc); // or whatever @@ -3093,7 +3110,7 @@ Parser::parse_generic_param (EndTokenPred is_end_token) // FIXME: Can we clean this last call with a method call? rust_error_at (token->get_locus (), "unexpected token when parsing generic parameters: %qs", - token->get_str ().c_str ()); + token->as_string ().c_str ()); return nullptr; } @@ -3886,6 +3903,7 @@ Parser::parse_type_param_bound () case SELF_ALIAS: case CRATE: case DOLLAR_SIGN: + case SCOPE_RESOLUTION: return parse_trait_bound (); default: // don't error - assume this is fine TODO @@ -4765,6 +4783,16 @@ Parser::parse_const_item (AST::Visibility vis, // parse constant type (required) std::unique_ptr type = parse_type (); + // A const with no given expression value + if (lexer.peek_token ()->get_id () == SEMICOLON) + { + lexer.skip_token (); + return std::unique_ptr ( + new AST::ConstantItem (std::move (ident), std::move (vis), + std::move (type), std::move (outer_attrs), + locus)); + } + if (!skip_token (EQUAL)) { skip_after_semicolon (); @@ -6227,8 +6255,7 @@ Parser::parse_stmt (ParseRestrictions restrictions) return parse_vis_item (std::move (outer_attrs)); // or should this go straight to parsing union? } - else if (t->get_str () == "macro_rules" - && lexer.peek_token (1)->get_id () == EXCLAM) + else if (is_macro_rules_def (t)) { // macro_rules! macro item return parse_macro_rules_def (std::move (outer_attrs)); @@ -6804,11 +6831,13 @@ Parser::parse_path_expr_segment () /* use lookahead to determine if they actually exist (don't want to * accidently parse over next ident segment) */ if (lexer.peek_token ()->get_id () == SCOPE_RESOLUTION - && lexer.peek_token (1)->get_id () == LEFT_ANGLE) + && (lexer.peek_token (1)->get_id () == LEFT_ANGLE + || lexer.peek_token (1)->get_id () == LEFT_SHIFT)) { // skip scope resolution lexer.skip_token (); + // Let parse_path_generic_args split "<<" tokens AST::GenericArgs generic_args = parse_path_generic_args (); return AST::PathExprSegment (std::move (ident), locus, @@ -7340,6 +7369,7 @@ Parser::parse_expr_stmt (AST::AttrVec outer_attrs, template std::unique_ptr Parser::parse_block_expr (AST::AttrVec outer_attrs, + AST::LoopLabel label, location_t pratt_parsed_loc) { location_t locus = pratt_parsed_loc; @@ -7406,8 +7436,8 @@ Parser::parse_block_expr (AST::AttrVec outer_attrs, return std::unique_ptr ( new AST::BlockExpr (std::move (stmts), std::move (expr), - std::move (inner_attrs), std::move (outer_attrs), locus, - end_locus)); + std::move (inner_attrs), std::move (outer_attrs), + std::move (label), locus, end_locus)); } /* Parses a "grouped" expression (expression in parentheses), used to control @@ -8348,7 +8378,7 @@ Parser::parse_for_loop_expr (AST::AttrVec outer_attrs, // Parses a loop expression with label (any kind of loop - disambiguates). template -std::unique_ptr +std::unique_ptr Parser::parse_labelled_loop_expr (const_TokenPtr tok, AST::AttrVec outer_attrs) { @@ -8400,6 +8430,8 @@ Parser::parse_labelled_loop_expr (const_TokenPtr tok, return parse_while_loop_expr (std::move (outer_attrs), std::move (label)); } + case LEFT_CURLY: + return parse_block_expr (std::move (outer_attrs), std::move (label)); default: // error add_error (Error (t->get_locus (), @@ -11452,6 +11484,8 @@ Parser::parse_struct_pattern_field_partial ( std::string index_str = t->get_str (); int index = atoi (index_str.c_str ()); + lexer.skip_token (); + if (!skip_token (COLON)) { return nullptr; @@ -12080,7 +12114,7 @@ Parser::parse_expr (int right_binding_power, { TokenId id = current_token->get_id (); if (id == SEMICOLON || id == RIGHT_PAREN || id == RIGHT_CURLY - || id == RIGHT_SQUARE) + || id == RIGHT_SQUARE || id == COMMA || id == LEFT_CURLY) return nullptr; } @@ -12516,7 +12550,8 @@ Parser::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), tok->get_locus ()); + return parse_block_expr (std::move (outer_attrs), + AST::LoopLabel::error (), tok->get_locus ()); case IF: // if or if let, so more lookahead to find out if (lexer.peek_token ()->get_id () == LET) @@ -14443,12 +14478,17 @@ Parser::parse_closure_expr_pratt (const_TokenPtr tok, if (lexer.peek_token ()->get_id () != COMMA) { + if (lexer.peek_token ()->get_id () == OR) + lexer.split_current_token (PIPE, PIPE); // not an error but means param list is done break; } // skip comma lexer.skip_token (); + if (lexer.peek_token ()->get_id () == OR) + lexer.split_current_token (PIPE, PIPE); + t = lexer.peek_token (); } diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 904b5028a755..6a69533b3f2b 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -139,8 +139,10 @@ template class Parser std::unique_ptr parse_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (), + AST::LoopLabel label = AST::LoopLabel::error (), location_t pratt_parsed_loc = UNKNOWN_LOCATION); + bool is_macro_rules_def (const_TokenPtr t); std::unique_ptr parse_item (bool called_from_statement); std::unique_ptr parse_pattern (); std::unique_ptr parse_pattern_no_alt (); @@ -589,9 +591,9 @@ template class Parser AST::MatchArm parse_match_arm (); std::vector > parse_match_arm_patterns (TokenId end_token_id); - std::unique_ptr - parse_labelled_loop_expr (const_TokenPtr tok, - AST::AttrVec outer_attrs = AST::AttrVec ()); + std::unique_ptr parse_labelled_loop_expr (const_TokenPtr tok, + AST::AttrVec outer_attrs + = AST::AttrVec ()); AST::LoopLabel parse_loop_label (const_TokenPtr tok); std::unique_ptr parse_async_block_expr (AST::AttrVec outer_attrs = AST::AttrVec ()); diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc index 92466ed35338..65abf1906682 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.cc +++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc @@ -303,6 +303,28 @@ ResolveExpr::visit (AST::BlockExpr &expr) resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); resolver->push_new_label_rib (resolver->get_type_scope ().peek ()); + if (expr.has_label ()) + { + auto label = expr.get_label (); + if (label.get_lifetime ().get_lifetime_type () + != AST::Lifetime::LifetimeType::NAMED) + { + rust_error_at (label.get_locus (), + "Labels must be a named lifetime value"); + return; + } + + auto label_name = label.get_lifetime ().get_lifetime_name (); + auto label_lifetime_node_id = label.get_lifetime ().get_node_id (); + resolver->get_label_scope ().insert ( + CanonicalPath::new_seg (label.get_node_id (), label_name), + label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label, + [&] (const CanonicalPath &, NodeId, location_t locus) -> void { + rust_error_at (label.get_locus (), "label redefined multiple times"); + rust_error_at (locus, "was defined here"); + }); + } + for (auto &s : expr.get_statements ()) { if (s->is_item ()) diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h index 9a34aa83889c..aa7ffe3d796b 100644 --- a/gcc/rust/resolve/rust-ast-resolve-implitem.h +++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h @@ -31,16 +31,7 @@ class ResolveToplevelImplItem : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::InherentImplItem *item, const CanonicalPath &prefix) - { - if (item->is_marked_for_strip ()) - return; - - ResolveToplevelImplItem resolver (prefix); - item->accept_vis (resolver); - } - - static void go (AST::TraitImplItem *item, const CanonicalPath &prefix) + static void go (AST::AssociatedItem *item, const CanonicalPath &prefix) { if (item->is_marked_for_strip ()) return; @@ -128,7 +119,7 @@ class ResolveTopLevelTraitItems : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::TraitItem *item, const CanonicalPath &prefix, + static void go (AST::AssociatedItem *item, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix) { ResolveTopLevelTraitItems resolver (prefix, canonical_prefix); diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc index baab62209994..3b730924c277 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.cc +++ b/gcc/rust/resolve/rust-ast-resolve-item.cc @@ -33,7 +33,7 @@ ResolveTraitItems::ResolveTraitItems (const CanonicalPath &prefix, {} void -ResolveTraitItems::go (AST::TraitItem *item, const CanonicalPath &prefix, +ResolveTraitItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix) { if (item->is_marked_for_strip ()) @@ -881,15 +881,7 @@ ResolveItem::visit (AST::ExternBlock &extern_block) } void -ResolveItem::resolve_impl_item (AST::TraitImplItem *item, - const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - ResolveImplItems::go (item, prefix, canonical_prefix); -} - -void -ResolveItem::resolve_impl_item (AST::InherentImplItem *item, +ResolveItem::resolve_impl_item (AST::AssociatedItem *item, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix) { @@ -1062,18 +1054,7 @@ ResolveImplItems::ResolveImplItems (const CanonicalPath &prefix, {} void -ResolveImplItems::go (AST::InherentImplItem *item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - if (item->is_marked_for_strip ()) - return; - - ResolveImplItems resolver (prefix, canonical_prefix); - item->accept_vis (resolver); -} - -void -ResolveImplItems::go (AST::TraitImplItem *item, const CanonicalPath &prefix, +ResolveImplItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix) { if (item->is_marked_for_strip ()) diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index db47df5713a5..273d5c1c9efd 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -32,7 +32,7 @@ class ResolveTraitItems : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::TraitItem *item, const CanonicalPath &prefix, + static void go (AST::AssociatedItem *item, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix); void visit (AST::TraitItemType &type) override; @@ -78,9 +78,7 @@ class ResolveItem : public ResolverBase void visit (AST::UseDeclaration &) override; protected: - void resolve_impl_item (AST::TraitImplItem *item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - void resolve_impl_item (AST::InherentImplItem *item, + void resolve_impl_item (AST::AssociatedItem *item, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix); void resolve_extern_item (AST::ExternalItem *item); @@ -97,9 +95,7 @@ class ResolveImplItems : public ResolveItem using Rust::Resolver::ResolveItem::visit; public: - static void go (AST::InherentImplItem *item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - static void go (AST::TraitImplItem *item, const CanonicalPath &prefix, + static void go (AST::AssociatedItem *item, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix); void visit (AST::TypeAlias &alias) override; diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc index fbdf6c428a61..bded3678031d 100644 --- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc +++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc @@ -124,8 +124,10 @@ PatternDeclaration::visit (AST::StructPattern &pattern) switch (field->get_item_type ()) { case AST::StructPatternField::ItemType::TUPLE_PAT: { - // TODO - rust_unreachable (); + AST::StructPatternFieldTuplePat &tuple + = static_cast (*field); + + tuple.get_index_pattern ()->accept_vis (*this); } break; @@ -151,9 +153,6 @@ PatternDeclaration::visit (AST::StructPattern &pattern) break; } } - - // TODO - rust_assert (!struct_pattern_elems.has_etc ()); } void diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc b/gcc/rust/resolve/rust-early-name-resolver.cc index dc7ad16039fd..32522d52cac0 100644 --- a/gcc/rust/resolve/rust-early-name-resolver.cc +++ b/gcc/rust/resolve/rust-early-name-resolver.cc @@ -953,7 +953,7 @@ EarlyNameResolver::visit (AST::MacroInvocation &invoc) if (has_semicolon) source_node = invoc.get_macro_node_id (); else - source_node = invoc.get_pattern_node_id (); + source_node = invoc.get_node_id (); auto seg = CanonicalPath::new_seg (source_node, invoc_data.get_path ().as_string ()); diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 805c4bb5175c..9f1ee012851a 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -249,16 +249,14 @@ TypeCheckExpr::visit (HIR::CompoundAssignmentExpr &expr) { infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ()); - auto lhs = TypeCheckExpr::Resolve (expr.get_left_expr ().get ()); - auto rhs = TypeCheckExpr::Resolve (expr.get_right_expr ().get ()); + auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ()); + auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ()); // we dont care about the result of the unify from a compound assignment // since this is a unit-type expr coercion_site (expr.get_mappings ().get_hirid (), - TyTy::TyWithLocation (lhs, - expr.get_left_expr ()->get_locus ()), - TyTy::TyWithLocation (rhs, - expr.get_right_expr ()->get_locus ()), + TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()), + TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()), expr.get_locus ()); auto lang_item_type @@ -566,6 +564,10 @@ TypeCheckExpr::visit (HIR::UnsafeBlockExpr &expr) void TypeCheckExpr::visit (HIR::BlockExpr &expr) { + if (expr.has_label ()) + context->push_new_loop_context (expr.get_mappings ().get_hirid (), + expr.get_locus ()); + for (auto &s : expr.get_statements ()) { if (!s->is_item ()) @@ -602,6 +604,20 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr) else if (expr.is_tail_reachable ()) infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ()); + else if (expr.has_label ()) + { + TyTy::BaseType *loop_context_type = context->pop_loop_context (); + + bool loop_context_type_infered + = (loop_context_type->get_kind () != TyTy::TypeKind::INFER) + || ((loop_context_type->get_kind () == TyTy::TypeKind::INFER) + && (((TyTy::InferType *) loop_context_type)->get_infer_kind () + != TyTy::InferType::GENERAL)); + + infered = loop_context_type_infered ? loop_context_type + : TyTy::TupleType::get_unit_type ( + expr.get_mappings ().get_hirid ()); + } else { // FIXME this seems wrong diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc index 0786f89e4071..a5bceae039e7 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc @@ -34,10 +34,9 @@ TypeCheckPattern::Resolve (HIR::Pattern *pattern, TyTy::BaseType *parent) pattern->accept_vis (resolver); if (resolver.infered == nullptr) - return new TyTy::ErrorType (pattern->get_pattern_mappings ().get_hirid ()); + return new TyTy::ErrorType (pattern->get_mappings ().get_hirid ()); - resolver.context->insert_type (pattern->get_pattern_mappings (), - resolver.infered); + resolver.context->insert_type (pattern->get_mappings (), resolver.infered); return resolver.infered; } @@ -135,7 +134,7 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern) TyTy::BaseType *fty = field->get_field_type (); // setup the type on this pattern type - context->insert_type (pattern->get_pattern_mappings (), fty); + context->insert_type (pattern->get_mappings (), fty); } } break; @@ -289,14 +288,14 @@ TypeCheckPattern::visit (HIR::WildcardPattern &pattern) // wildcard patterns within the MatchArm's are simply just the same type as // the parent infered = parent->clone (); - infered->set_ref (pattern.get_pattern_mappings ().get_hirid ()); + infered->set_ref (pattern.get_mappings ().get_hirid ()); } void TypeCheckPattern::visit (HIR::TuplePattern &pattern) { std::unique_ptr items; - switch (pattern.get_items ()->get_pattern_type ()) + switch (pattern.get_items ()->get_item_type ()) { case HIR::TuplePatternItems::TuplePatternItemType::MULTIPLE: { HIR::TuplePatternItemsMultiple &ref @@ -332,9 +331,8 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern) = TypeCheckPattern::Resolve (p.get (), par_type); pattern_elems.push_back (TyTy::TyVar (elem->get_ref ())); } - infered - = new TyTy::TupleType (pattern.get_pattern_mappings ().get_hirid (), - pattern.get_locus (), pattern_elems); + infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (), + pattern.get_locus (), pattern_elems); } break; @@ -352,8 +350,8 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern) void TypeCheckPattern::visit (HIR::LiteralPattern &pattern) { - infered = resolve_literal (pattern.get_pattern_mappings (), - pattern.get_literal (), pattern.get_locus ()); + infered = resolve_literal (pattern.get_mappings (), pattern.get_literal (), + pattern.get_locus ()); } void @@ -363,14 +361,14 @@ TypeCheckPattern::visit (HIR::RangePattern &pattern) TyTy::BaseType *upper = nullptr, *lower = nullptr; upper = typecheck_range_pattern_bound (pattern.get_upper_bound (), - pattern.get_pattern_mappings (), + pattern.get_mappings (), pattern.get_locus ()); lower = typecheck_range_pattern_bound (pattern.get_lower_bound (), - pattern.get_pattern_mappings (), + pattern.get_mappings (), pattern.get_locus ()); - infered = unify_site (pattern.get_pattern_mappings ().get_hirid (), + infered = unify_site (pattern.get_mappings ().get_hirid (), TyTy::TyWithLocation (upper), TyTy::TyWithLocation (lower), pattern.get_locus ()); } @@ -402,11 +400,10 @@ TypeCheckPattern::visit (HIR::ReferencePattern &pattern) TyTy::BaseType *infered_base = TypeCheckPattern::Resolve (pattern.get_referenced_pattern ().get (), ref_ty_ty->get_base ()); - infered - = new TyTy::ReferenceType (pattern.get_pattern_mappings ().get_hirid (), - TyTy::TyVar (infered_base->get_ref ()), - pattern.is_mut () ? Mutability::Mut - : Mutability::Imm); + infered = new TyTy::ReferenceType (pattern.get_mappings ().get_hirid (), + TyTy::TyVar (infered_base->get_ref ()), + pattern.is_mut () ? Mutability::Mut + : Mutability::Imm); } void @@ -488,7 +485,7 @@ TypeCheckPattern::visit (HIR::AltPattern &pattern) for (auto &type : types) { alt_pattern_type - = unify_site (pattern.get_pattern_mappings ().get_hirid (), + = unify_site (pattern.get_mappings ().get_hirid (), TyTy::TyWithLocation (alt_pattern_type), TyTy::TyWithLocation (type, type->get_locus ()), pattern.get_locus ()); @@ -519,7 +516,7 @@ ClosureParamInfer::ClosureParamInfer () void ClosureParamInfer::visit (HIR::WildcardPattern &pattern) { - HirId id = pattern.get_pattern_mappings ().get_hirid (); + HirId id = pattern.get_mappings ().get_hirid (); infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL, TyTy::InferType::TypeHint::Default (), pattern.get_locus ()); @@ -528,7 +525,7 @@ ClosureParamInfer::visit (HIR::WildcardPattern &pattern) void ClosureParamInfer::visit (HIR::IdentifierPattern &pattern) { - HirId id = pattern.get_pattern_mappings ().get_hirid (); + HirId id = pattern.get_mappings ().get_hirid (); infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL, TyTy::InferType::TypeHint::Default (), pattern.get_locus ()); @@ -540,7 +537,7 @@ ClosureParamInfer::visit (HIR::ReferencePattern &pattern) TyTy::BaseType *element = ClosureParamInfer::Resolve (pattern.get_referenced_pattern ().get ()); - HirId id = pattern.get_pattern_mappings ().get_hirid (); + HirId id = pattern.get_mappings ().get_hirid (); infered = new TyTy::ReferenceType (id, TyTy::TyVar (element->get_ref ()), pattern.get_mutability ()); } diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc index 680e3236fa51..219dd156ee15 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc @@ -87,7 +87,7 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt) return; init_expr_ty->append_reference ( - stmt_pattern.get_pattern_mappings ().get_hirid ()); + stmt_pattern.get_mappings ().get_hirid ()); } TyTy::BaseType *specified_ty = nullptr; @@ -122,10 +122,11 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt) // let x; else { - auto infer = new TyTy::InferType ( - stmt_pattern.get_pattern_mappings ().get_hirid (), - TyTy::InferType::InferTypeKind::GENERAL, - TyTy::InferType::TypeHint::Default (), stmt.get_locus ()); + auto infer + = new TyTy::InferType (stmt_pattern.get_mappings ().get_hirid (), + TyTy::InferType::InferTypeKind::GENERAL, + TyTy::InferType::TypeHint::Default (), + stmt.get_locus ()); TypeCheckPattern::Resolve (&stmt_pattern, infer); } } diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 6136fa62f948..64db06dd0785 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -220,16 +220,15 @@ BaseType::is_unit () const return true; case TUPLE: { - const TupleType &tuple = *static_cast (x); - return tuple.num_fields () == 0; + return x->as ()->num_fields () == 0; } case ADT: { - const ADTType &adt = *static_cast (x); - if (adt.is_enum ()) + auto adt = x->as (); + if (adt->is_enum ()) return false; - for (const auto &variant : adt.get_variants ()) + for (const auto &variant : adt->get_variants ()) { if (variant->num_fields () > 0) return false; @@ -276,8 +275,6 @@ bool BaseType::satisfies_bound (const TypeBoundPredicate &predicate, bool emit_error) const { - bool is_infer_var = destructure ()->get_kind () == TyTy::TypeKind::INFER; - const Resolver::TraitReference *query = predicate.get (); for (const auto &bound : specified_bounds) { @@ -286,7 +283,7 @@ BaseType::satisfies_bound (const TypeBoundPredicate &predicate, return true; } - if (is_infer_var) + if (destructure ()->is ()) return true; bool satisfied = false; @@ -435,28 +432,24 @@ BaseType::get_root () const { // FIXME this needs to be it its own visitor class with a vector adjustments const TyTy::BaseType *root = this; - if (get_kind () == TyTy::REF) + + if (const auto r = root->try_as ()) { - const ReferenceType *r = static_cast (root); root = r->get_base ()->get_root (); } - else if (get_kind () == TyTy::POINTER) + else if (const auto r = root->try_as ()) { - const PointerType *r = static_cast (root); root = r->get_base ()->get_root (); } - // these are an unsize - else if (get_kind () == TyTy::SLICE) + else if (const auto r = root->try_as ()) { - const SliceType *r = static_cast (root); root = r->get_element_type ()->get_root (); } - // else if (get_kind () == TyTy::ARRAY) - // { - // const ArrayType *r = static_cast (root); - // root = r->get_element_type ()->get_root (); - // } + // else if (const auto r = root->try_as ()) + // { + // root = r->get_element_type ()->get_root (); + // } return root; } @@ -478,34 +471,27 @@ BaseType::destructure () return new ErrorType (get_ref ()); } - switch (x->get_kind ()) + if (auto p = x->try_as ()) { - case TyTy::TypeKind::PARAM: { - TyTy::ParamType *p = static_cast (x); - TyTy::BaseType *pr = p->resolve (); - if (pr == x) - return pr; - - x = pr; - } - break; + auto pr = p->resolve (); + if (pr == x) + return pr; - case TyTy::TypeKind::PLACEHOLDER: { - TyTy::PlaceholderType *p = static_cast (x); - if (!p->can_resolve ()) - return p; - - x = p->resolve (); - } - break; - - case TyTy::TypeKind::PROJECTION: { - TyTy::ProjectionType *p = static_cast (x); - x = p->get (); - } - break; + x = pr; + } + else if (auto p = x->try_as ()) + { + if (!p->can_resolve ()) + return p; - default: + x = p->resolve (); + } + else if (auto p = x->try_as ()) + { + x = p->get (); + } + else + { return x; } } @@ -530,36 +516,27 @@ BaseType::destructure () const return new ErrorType (get_ref ()); } - switch (x->get_kind ()) + if (auto p = x->try_as ()) { - case TyTy::TypeKind::PARAM: { - const TyTy::ParamType *p = static_cast (x); - const TyTy::BaseType *pr = p->resolve (); - if (pr == x) - return pr; - - x = pr; - } - break; - - case TyTy::TypeKind::PLACEHOLDER: { - const TyTy::PlaceholderType *p - = static_cast (x); - if (!p->can_resolve ()) - return p; - - x = p->resolve (); - } - break; + auto pr = p->resolve (); + if (pr == x) + return pr; - case TyTy::TypeKind::PROJECTION: { - const TyTy::ProjectionType *p - = static_cast (x); - x = p->get (); - } - break; + x = pr; + } + else if (auto p = x->try_as ()) + { + if (!p->can_resolve ()) + return p; - default: + x = p->resolve (); + } + else if (auto p = x->try_as ()) + { + x = p->get (); + } + else + { return x; } } @@ -571,112 +548,81 @@ BaseType * BaseType::monomorphized_clone () const { const TyTy::BaseType *x = destructure (); - switch (x->get_kind ()) - { - case PARAM: - case PROJECTION: - case PLACEHOLDER: - case INFER: - case BOOL: - case CHAR: - case INT: - case UINT: - case FLOAT: - case USIZE: - case ISIZE: - case NEVER: - case STR: - case DYNAMIC: - case CLOSURE: - case ERROR: - return x->clone (); - - case ARRAY: { - const ArrayType &arr = *static_cast (x); - TyVar elm = arr.get_var_element_type ().monomorphized_clone (); - return new ArrayType (arr.get_ref (), arr.get_ty_ref (), ident.locus, - arr.get_capacity_expr (), elm, - arr.get_combined_refs ()); - } - break; - - case SLICE: { - const SliceType &slice = *static_cast (x); - TyVar elm = slice.get_var_element_type ().monomorphized_clone (); - return new SliceType (slice.get_ref (), slice.get_ty_ref (), - ident.locus, elm, slice.get_combined_refs ()); - } - break; - - case POINTER: { - const PointerType &ptr = *static_cast (x); - TyVar elm = ptr.get_var_element_type ().monomorphized_clone (); - return new PointerType (ptr.get_ref (), ptr.get_ty_ref (), elm, - ptr.mutability (), ptr.get_combined_refs ()); - } - break; - - case REF: { - const ReferenceType &ref = *static_cast (x); - TyVar elm = ref.get_var_element_type ().monomorphized_clone (); - return new ReferenceType (ref.get_ref (), ref.get_ty_ref (), elm, - ref.mutability (), ref.get_combined_refs ()); - } - break; - - case TUPLE: { - const TupleType &tuple = *static_cast (x); - std::vector cloned_fields; - for (const auto &f : tuple.get_fields ()) - cloned_fields.push_back (f.monomorphized_clone ()); - - return new TupleType (tuple.get_ref (), tuple.get_ty_ref (), - tuple.get_ident ().locus, cloned_fields, - tuple.get_combined_refs ()); - } - break; - - case FNDEF: { - const FnType &fn = *static_cast (x); - std::vector> cloned_params; - for (auto &p : fn.get_params ()) - cloned_params.push_back ({p.first, p.second->monomorphized_clone ()}); - - BaseType *retty = fn.get_return_type ()->monomorphized_clone (); - return new FnType (fn.get_ref (), fn.get_ty_ref (), fn.get_id (), - fn.get_identifier (), fn.ident, fn.get_flags (), - fn.get_abi (), std::move (cloned_params), retty, - fn.clone_substs (), fn.get_combined_refs ()); - } - break; - - case FNPTR: { - const FnPtr &fn = *static_cast (x); - std::vector cloned_params; - for (auto &p : fn.get_params ()) - cloned_params.push_back (p.monomorphized_clone ()); - TyVar retty = fn.get_var_return_type ().monomorphized_clone (); - return new FnPtr (fn.get_ref (), fn.get_ty_ref (), fn.ident.locus, - std::move (cloned_params), retty, - fn.get_combined_refs ()); - } - break; + if (auto arr = x->try_as ()) + { + TyVar elm = arr->get_var_element_type ().monomorphized_clone (); + return new ArrayType (arr->get_ref (), arr->get_ty_ref (), ident.locus, + arr->get_capacity_expr (), elm, + arr->get_combined_refs ()); + } + else if (auto slice = x->try_as ()) + { + TyVar elm = slice->get_var_element_type ().monomorphized_clone (); + return new SliceType (slice->get_ref (), slice->get_ty_ref (), + ident.locus, elm, slice->get_combined_refs ()); + } + else if (auto ptr = x->try_as ()) + { + TyVar elm = ptr->get_var_element_type ().monomorphized_clone (); + return new PointerType (ptr->get_ref (), ptr->get_ty_ref (), elm, + ptr->mutability (), ptr->get_combined_refs ()); + } + else if (auto ref = x->try_as ()) + { + TyVar elm = ref->get_var_element_type ().monomorphized_clone (); + return new ReferenceType (ref->get_ref (), ref->get_ty_ref (), elm, + ref->mutability (), ref->get_combined_refs ()); + } + else if (auto tuple = x->try_as ()) + { + std::vector cloned_fields; + for (const auto &f : tuple->get_fields ()) + cloned_fields.push_back (f.monomorphized_clone ()); - case ADT: { - const ADTType &adt = *static_cast (x); - std::vector cloned_variants; - for (auto &variant : adt.get_variants ()) - cloned_variants.push_back (variant->monomorphized_clone ()); - - return new ADTType (adt.get_ref (), adt.get_ty_ref (), - adt.get_identifier (), adt.ident, - adt.get_adt_kind (), cloned_variants, - adt.clone_substs (), adt.get_repr_options (), - adt.get_used_arguments (), - adt.get_combined_refs ()); - } - break; + return new TupleType (tuple->get_ref (), tuple->get_ty_ref (), + ident.locus, cloned_fields, + tuple->get_combined_refs ()); + } + else if (auto fn = x->try_as ()) + { + std::vector> cloned_params; + for (auto &p : fn->get_params ()) + cloned_params.push_back ({p.first, p.second->monomorphized_clone ()}); + + BaseType *retty = fn->get_return_type ()->monomorphized_clone (); + return new FnType (fn->get_ref (), fn->get_ty_ref (), fn->get_id (), + fn->get_identifier (), fn->ident, fn->get_flags (), + fn->get_abi (), std::move (cloned_params), retty, + fn->clone_substs (), fn->get_combined_refs ()); + } + else if (auto fn = x->try_as ()) + { + std::vector cloned_params; + for (auto &p : fn->get_params ()) + cloned_params.push_back (p.monomorphized_clone ()); + + TyVar retty = fn->get_var_return_type ().monomorphized_clone (); + return new FnPtr (fn->get_ref (), fn->get_ty_ref (), ident.locus, + std::move (cloned_params), retty, + fn->get_combined_refs ()); + } + else if (auto adt = x->try_as ()) + { + std::vector cloned_variants; + for (auto &variant : adt->get_variants ()) + cloned_variants.push_back (variant->monomorphized_clone ()); + + return new ADTType (adt->get_ref (), adt->get_ty_ref (), + adt->get_identifier (), adt->ident, + adt->get_adt_kind (), cloned_variants, + adt->clone_substs (), adt->get_repr_options (), + adt->get_used_arguments (), + adt->get_combined_refs ()); + } + else + { + return x->clone (); } rust_unreachable (); @@ -714,122 +660,94 @@ bool BaseType::is_concrete () const { const TyTy::BaseType *x = destructure (); - switch (x->get_kind ()) + + if (x->is () || x->is ()) { - case PARAM: - case PROJECTION: return false; - - // placeholder is a special case for this case when it is not resolvable - // it means we its just an empty placeholder associated type which is - // concrete - case PLACEHOLDER: + } + // placeholder is a special case for this case when it is not resolvable + // it means we its just an empty placeholder associated type which is + // concrete + else if (x->is ()) + { return true; + } + else if (auto fn = x->try_as ()) + { + for (const auto ¶m : fn->get_params ()) + { + if (!param.second->is_concrete ()) + return false; + } + return fn->get_return_type ()->is_concrete (); + } + else if (auto fn = x->try_as ()) + { + for (const auto ¶m : fn->get_params ()) + { + if (!param.get_tyty ()->is_concrete ()) + return false; + } + return fn->get_return_type ()->is_concrete (); + } + else if (auto adt = x->try_as ()) + { + if (adt->is_unit ()) + return !adt->needs_substitution (); - case FNDEF: { - const FnType &fn = *static_cast (x); - for (const auto ¶m : fn.get_params ()) - { - const BaseType *p = param.second; - if (!p->is_concrete ()) - return false; - } - return fn.get_return_type ()->is_concrete (); - } - break; - - case FNPTR: { - const FnPtr &fn = *static_cast (x); - for (const auto ¶m : fn.get_params ()) - { - const BaseType *p = param.get_tyty (); - if (!p->is_concrete ()) - return false; - } - return fn.get_return_type ()->is_concrete (); - } - break; - - case ADT: { - const ADTType &adt = *static_cast (x); - if (adt.is_unit ()) - { - return !adt.needs_substitution (); - } - - for (auto &variant : adt.get_variants ()) - { - bool is_num_variant - = variant->get_variant_type () == VariantDef::VariantType::NUM; - if (is_num_variant) - continue; - - for (auto &field : variant->get_fields ()) - { - const BaseType *field_type = field->get_field_type (); - if (!field_type->is_concrete ()) - return false; - } - } - return true; - } - break; - - case ARRAY: { - const ArrayType &arr = *static_cast (x); - return arr.get_element_type ()->is_concrete (); - } - break; - - case SLICE: { - const SliceType &slice = *static_cast (x); - return slice.get_element_type ()->is_concrete (); - } - break; - - case POINTER: { - const PointerType &ptr = *static_cast (x); - return ptr.get_base ()->is_concrete (); - } - break; - - case REF: { - const ReferenceType &ref = *static_cast (x); - return ref.get_base ()->is_concrete (); - } - break; - - case TUPLE: { - const TupleType &tuple = *static_cast (x); - for (size_t i = 0; i < tuple.num_fields (); i++) - { - if (!tuple.get_field (i)->is_concrete ()) - return false; - } - return true; - } - break; - - case CLOSURE: { - const ClosureType &closure = *static_cast (x); - if (closure.get_parameters ().is_concrete ()) - return false; - return closure.get_result_type ().is_concrete (); - } - break; + for (auto &variant : adt->get_variants ()) + { + bool is_num_variant + = variant->get_variant_type () == VariantDef::VariantType::NUM; + if (is_num_variant) + continue; - case INFER: - case BOOL: - case CHAR: - case INT: - case UINT: - case FLOAT: - case USIZE: - case ISIZE: - case NEVER: - case STR: - case DYNAMIC: - case ERROR: + for (auto &field : variant->get_fields ()) + { + const BaseType *field_type = field->get_field_type (); + if (!field_type->is_concrete ()) + return false; + } + } + return true; + } + else if (auto arr = x->try_as ()) + { + return arr->get_element_type ()->is_concrete (); + } + else if (auto slice = x->try_as ()) + { + return slice->get_element_type ()->is_concrete (); + } + else if (auto ptr = x->try_as ()) + { + return ptr->get_base ()->is_concrete (); + } + else if (auto ref = x->try_as ()) + { + return ref->get_base ()->is_concrete (); + } + else if (auto tuple = x->try_as ()) + { + for (size_t i = 0; i < tuple->num_fields (); i++) + { + if (!tuple->get_field (i)->is_concrete ()) + return false; + } + return true; + } + else if (auto closure = x->try_as ()) + { + if (closure->get_parameters ().is_concrete ()) + return false; + return closure->get_result_type ().is_concrete (); + } + else if (x->is () || x->is () || x->is () + || x->is () || x->is () || x->is () + || x->is () || x->is () || x->is () + || x->is () || x->is () + || x->is ()) + { return true; } @@ -962,14 +880,14 @@ BaseType::needs_generic_substitutions () const InferType::InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint, location_t locus, std::set refs) - : BaseType (ref, ref, TypeKind::INFER, - {Resolver::CanonicalPath::create_empty (), locus}, refs), + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), locus}, + refs), infer_kind (infer_kind), default_hint (hint) {} InferType::InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind, TypeHint hint, location_t locus, std::set refs) - : BaseType (ref, ty_ref, TypeKind::INFER, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), locus}, refs), infer_kind (infer_kind), default_hint (hint) {} @@ -1197,10 +1115,9 @@ InferType::apply_primitive_type_hint (const BaseType &hint) case INT: { infer_kind = INTEGRAL; - const IntType &i = static_cast (hint); default_hint.kind = hint.get_kind (); default_hint.shint = TypeHint::SignedHint::SIGNED; - switch (i.get_int_kind ()) + switch (hint.as ()->get_int_kind ()) { case IntType::I8: default_hint.szhint = TypeHint::SizeHint::S8; @@ -1223,10 +1140,9 @@ InferType::apply_primitive_type_hint (const BaseType &hint) case UINT: { infer_kind = INTEGRAL; - const UintType &i = static_cast (hint); default_hint.kind = hint.get_kind (); default_hint.shint = TypeHint::SignedHint::UNSIGNED; - switch (i.get_uint_kind ()) + switch (hint.as ()->get_uint_kind ()) { case UintType::U8: default_hint.szhint = TypeHint::SizeHint::S8; @@ -1251,8 +1167,7 @@ InferType::apply_primitive_type_hint (const BaseType &hint) infer_kind = FLOAT; default_hint.shint = TypeHint::SignedHint::SIGNED; default_hint.kind = hint.get_kind (); - const FloatType &i = static_cast (hint); - switch (i.get_float_kind ()) + switch (hint.as ()->get_float_kind ()) { case FloatType::F32: default_hint.szhint = TypeHint::SizeHint::S32; @@ -1274,12 +1189,12 @@ InferType::apply_primitive_type_hint (const BaseType &hint) // ErrorType ErrorType::ErrorType (HirId ref, std::set refs) - : BaseType (ref, ref, TypeKind::ERROR, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), UNDEF_LOCATION}, refs) {} ErrorType::ErrorType (HirId ref, HirId ty_ref, std::set refs) - : BaseType (ref, ty_ref, TypeKind::ERROR, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), UNDEF_LOCATION}, refs) {} @@ -1371,14 +1286,11 @@ StructFieldType::as_string () const bool StructFieldType::is_equal (const StructFieldType &other) const { - bool names_eq = get_name ().compare (other.get_name ()) == 0; + bool names_eq = get_name () == other.get_name (); TyTy::BaseType *o = other.get_field_type (); - if (o->get_kind () == TypeKind::PARAM) - { - ParamType *op = static_cast (o); - o = op->resolve (); - } + if (auto op = o->try_as ()) + o = op->resolve (); bool types_eq = get_field_type ()->is_equal (*o); @@ -1673,25 +1585,25 @@ ADTType::is_equal (const BaseType &other) const if (get_kind () != other.get_kind ()) return false; - auto other2 = static_cast (other); - if (get_adt_kind () != other2.get_adt_kind ()) + auto other2 = other.as (); + if (get_adt_kind () != other2->get_adt_kind ()) return false; - if (number_of_variants () != other2.number_of_variants ()) + if (number_of_variants () != other2->number_of_variants ()) return false; - if (has_substitutions_defined () != other2.has_substitutions_defined ()) + if (has_substitutions_defined () != other2->has_substitutions_defined ()) return false; if (has_substitutions_defined ()) { - if (get_num_substitutions () != other2.get_num_substitutions ()) + if (get_num_substitutions () != other2->get_num_substitutions ()) return false; for (size_t i = 0; i < get_num_substitutions (); i++) { const SubstitutionParamMapping &a = substitutions.at (i); - const SubstitutionParamMapping &b = other2.substitutions.at (i); + const SubstitutionParamMapping &b = other2->substitutions.at (i); const ParamType *aa = a.get_param_ty (); const ParamType *bb = b.get_param_ty (); @@ -1705,7 +1617,7 @@ ADTType::is_equal (const BaseType &other) const for (size_t i = 0; i < number_of_variants (); i++) { const TyTy::VariantDef *a = get_variants ().at (i); - const TyTy::VariantDef *b = other2.get_variants ().at (i); + const TyTy::VariantDef *b = other2->get_variants ().at (i); if (!a->is_equal (*b)) return false; @@ -1732,11 +1644,8 @@ handle_substitions (SubstitutionArgumentMappings &subst_mappings, StructFieldType *field) { auto fty = field->get_field_type (); - bool is_param_ty = fty->get_kind () == TypeKind::PARAM; - if (is_param_ty) + if (auto p = fty->try_as ()) { - ParamType *p = static_cast (fty); - SubstitutionArg arg = SubstitutionArg::error (); bool ok = subst_mappings.get_argument_for_symbol (p, &arg); if (ok) @@ -1781,7 +1690,7 @@ handle_substitions (SubstitutionArgumentMappings &subst_mappings, ADTType * ADTType::handle_substitions (SubstitutionArgumentMappings &subst_mappings) { - ADTType *adt = static_cast (clone ()); + auto adt = clone ()->as (); adt->set_ty_ref (mappings->get_next_hir_id ()); adt->used_arguments = subst_mappings; @@ -1814,14 +1723,14 @@ ADTType::handle_substitions (SubstitutionArgumentMappings &subst_mappings) TupleType::TupleType (HirId ref, location_t locus, std::vector fields, std::set refs) - : BaseType (ref, ref, TypeKind::TUPLE, - {Resolver::CanonicalPath::create_empty (), locus}, refs), + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), locus}, + refs), fields (fields) {} TupleType::TupleType (HirId ref, HirId ty_ref, location_t locus, std::vector fields, std::set refs) - : BaseType (ref, ty_ref, TypeKind::TUPLE, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), locus}, refs), fields (fields) {} @@ -1905,13 +1814,13 @@ TupleType::is_equal (const BaseType &other) const if (get_kind () != other.get_kind ()) return false; - auto other2 = static_cast (other); - if (num_fields () != other2.num_fields ()) + auto other2 = other.as (); + if (num_fields () != other2->num_fields ()) return false; for (size_t i = 0; i < num_fields (); i++) { - if (!get_field (i)->is_equal (*other2.get_field (i))) + if (!get_field (i)->is_equal (*other2->get_field (i))) return false; } return true; @@ -1933,7 +1842,7 @@ TupleType::handle_substitions (SubstitutionArgumentMappings &mappings) { auto mappings_table = Analysis::Mappings::get (); - TupleType *tuple = static_cast (clone ()); + auto tuple = clone ()->as (); tuple->set_ref (mappings_table->get_next_hir_id ()); tuple->set_ty_ref (mappings_table->get_next_hir_id ()); @@ -2487,13 +2396,13 @@ SliceType::handle_substitions (SubstitutionArgumentMappings &mappings) // BoolType BoolType::BoolType (HirId ref, std::set refs) - : BaseType (ref, ref, TypeKind::BOOL, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} BoolType::BoolType (HirId ref, HirId ty_ref, std::set refs) - : BaseType (ref, ty_ref, TypeKind::BOOL, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} @@ -2538,14 +2447,14 @@ BoolType::clone () const // IntType IntType::IntType (HirId ref, IntKind kind, std::set refs) - : BaseType (ref, ref, TypeKind::INT, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), int_kind (kind) {} IntType::IntType (HirId ref, HirId ty_ref, IntKind kind, std::set refs) - : BaseType (ref, ty_ref, TypeKind::INT, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), int_kind (kind) @@ -2622,7 +2531,7 @@ IntType::is_equal (const BaseType &other) const // UintType UintType::UintType (HirId ref, UintKind kind, std::set refs) - : BaseType (ref, ref, TypeKind::UINT, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), uint_kind (kind) @@ -2630,7 +2539,7 @@ UintType::UintType (HirId ref, UintKind kind, std::set refs) UintType::UintType (HirId ref, HirId ty_ref, UintKind kind, std::set refs) - : BaseType (ref, ty_ref, TypeKind::UINT, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), uint_kind (kind) @@ -2707,7 +2616,7 @@ UintType::is_equal (const BaseType &other) const // FloatType FloatType::FloatType (HirId ref, FloatKind kind, std::set refs) - : BaseType (ref, ref, TypeKind::FLOAT, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), float_kind (kind) @@ -2715,7 +2624,7 @@ FloatType::FloatType (HirId ref, FloatKind kind, std::set refs) FloatType::FloatType (HirId ref, HirId ty_ref, FloatKind kind, std::set refs) - : BaseType (ref, ty_ref, TypeKind::FLOAT, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), float_kind (kind) @@ -2786,13 +2695,13 @@ FloatType::is_equal (const BaseType &other) const // UsizeType USizeType::USizeType (HirId ref, std::set refs) - : BaseType (ref, ref, TypeKind::USIZE, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} USizeType::USizeType (HirId ref, HirId ty_ref, std::set refs) - : BaseType (ref, ty_ref, TypeKind::USIZE, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} @@ -2837,13 +2746,13 @@ USizeType::clone () const // ISizeType ISizeType::ISizeType (HirId ref, std::set refs) - : BaseType (ref, ref, TypeKind::ISIZE, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} ISizeType::ISizeType (HirId ref, HirId ty_ref, std::set refs) - : BaseType (ref, ty_ref, TypeKind::ISIZE, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} @@ -2888,13 +2797,13 @@ ISizeType::clone () const // Char Type CharType::CharType (HirId ref, std::set refs) - : BaseType (ref, ref, TypeKind::CHAR, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} CharType::CharType (HirId ref, HirId ty_ref, std::set refs) - : BaseType (ref, ty_ref, TypeKind::CHAR, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} @@ -2940,7 +2849,7 @@ CharType::clone () const ReferenceType::ReferenceType (HirId ref, TyVar base, Mutability mut, std::set refs) - : BaseType (ref, ref, TypeKind::REF, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), base (base), mut (mut) @@ -2948,7 +2857,7 @@ ReferenceType::ReferenceType (HirId ref, TyVar base, Mutability mut, ReferenceType::ReferenceType (HirId ref, HirId ty_ref, TyVar base, Mutability mut, std::set refs) - : BaseType (ref, ty_ref, TypeKind::REF, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), base (base), mut (mut) @@ -3096,7 +3005,7 @@ ReferenceType::handle_substitions (SubstitutionArgumentMappings &mappings) PointerType::PointerType (HirId ref, TyVar base, Mutability mut, std::set refs) - : BaseType (ref, ref, TypeKind::POINTER, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), base (base), mut (mut) @@ -3104,7 +3013,7 @@ PointerType::PointerType (HirId ref, TyVar base, Mutability mut, PointerType::PointerType (HirId ref, HirId ty_ref, TyVar base, Mutability mut, std::set refs) - : BaseType (ref, ty_ref, TypeKind::POINTER, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), base (base), mut (mut) @@ -3260,7 +3169,7 @@ ParamType::ParamType (std::string symbol, location_t locus, HirId ref, HIR::GenericParam ¶m, std::vector specified_bounds, std::set refs) - : BaseType (ref, ref, TypeKind::PARAM, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol), locus}, specified_bounds, refs), @@ -3271,7 +3180,7 @@ ParamType::ParamType (bool is_trait_self, std::string symbol, location_t locus, HirId ref, HirId ty_ref, HIR::GenericParam ¶m, std::vector specified_bounds, std::set refs) - : BaseType (ref, ty_ref, TypeKind::PARAM, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol), locus}, specified_bounds, refs), @@ -3434,13 +3343,13 @@ ParamType::is_implicit_self_trait () const // StrType StrType::StrType (HirId ref, std::set refs) - : BaseType (ref, ref, TypeKind::STR, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} StrType::StrType (HirId ref, HirId ty_ref, std::set refs) - : BaseType (ref, ty_ref, TypeKind::STR, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} @@ -3491,13 +3400,13 @@ StrType::is_equal (const BaseType &other) const // Never Type NeverType::NeverType (HirId ref, std::set refs) - : BaseType (ref, ref, TypeKind::NEVER, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} NeverType::NeverType (HirId ref, HirId ty_ref, std::set refs) - : BaseType (ref, ty_ref, TypeKind::NEVER, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs) {} @@ -3543,7 +3452,7 @@ NeverType::clone () const PlaceholderType::PlaceholderType (std::string symbol, HirId ref, std::set refs) - : BaseType (ref, ref, TypeKind::PLACEHOLDER, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), symbol (symbol) @@ -3551,7 +3460,7 @@ PlaceholderType::PlaceholderType (std::string symbol, HirId ref, PlaceholderType::PlaceholderType (std::string symbol, HirId ref, HirId ty_ref, std::set refs) - : BaseType (ref, ty_ref, TypeKind::PLACEHOLDER, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), symbol (symbol) @@ -3656,7 +3565,7 @@ ProjectionType::ProjectionType ( HirId ref, BaseType *base, const Resolver::TraitReference *trait, DefId item, std::vector subst_refs, SubstitutionArgumentMappings generic_arguments, std::set refs) - : BaseType (ref, ref, TypeKind::PROJECTION, + : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)), @@ -3668,7 +3577,7 @@ ProjectionType::ProjectionType ( const Resolver::TraitReference *trait, DefId item, std::vector subst_refs, SubstitutionArgumentMappings generic_arguments, std::set refs) - : BaseType (ref, ty_ref, TypeKind::PROJECTION, + : BaseType (ref, ty_ref, KIND, {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION}, refs), SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)), @@ -3730,7 +3639,8 @@ ProjectionType::handle_substitions ( SubstitutionArgumentMappings &subst_mappings) { // // do we really need to substitute this? - // if (base->needs_generic_substitutions () || base->contains_type_parameters + // if (base->needs_generic_substitutions () || + // base->contains_type_parameters // ()) // { // return this; @@ -3802,13 +3712,13 @@ ProjectionType::handle_substitions ( DynamicObjectType::DynamicObjectType ( HirId ref, RustIdent ident, std::vector specified_bounds, std::set refs) - : BaseType (ref, ref, TypeKind::DYNAMIC, ident, specified_bounds, refs) + : BaseType (ref, ref, KIND, ident, specified_bounds, refs) {} DynamicObjectType::DynamicObjectType ( HirId ref, HirId ty_ref, RustIdent ident, std::vector specified_bounds, std::set refs) - : BaseType (ref, ty_ref, TypeKind::DYNAMIC, ident, specified_bounds, refs) + : BaseType (ref, ty_ref, KIND, ident, specified_bounds, refs) {} void diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index f146b6b8e3fb..212ebc975704 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -31,7 +31,9 @@ namespace Rust { namespace Resolver { class TraitReference; + class TraitItemReference; + class AssociatedImplTrait; } // namespace Resolver @@ -116,9 +118,12 @@ class BaseType : public TypeBoundsMappings bool satisfies_bound (const TypeBoundPredicate &predicate, bool emit_error) const; + bool bounds_compatible (const BaseType &other, location_t locus, bool emit_error) const; + void inherit_bounds (const BaseType &other); + void inherit_bounds ( const std::vector &specified_bounds); @@ -138,10 +143,13 @@ class BaseType : public TypeBoundsMappings // get_combined_refs returns the chain of node refs involved in unification std::set get_combined_refs () const; + void append_reference (HirId id); std::string mappings_str () const; + std::string debug_str () const; + void debug () const; // FIXME this will eventually go away @@ -168,6 +176,55 @@ class BaseType : public TypeBoundsMappings * releasing the memory of the returned ty. */ virtual BaseType *clone () const = 0; + // Check if TyTy::BaseType is of a specific type. + template [[nodiscard]] bool is () const + { + static_assert (std::is_base_of::value, + "Can only safely cast to TyTy types."); + return this->get_kind () == T::KIND; + } + + template T *as () const + { + static_assert (std::is_base_of::value, + "Can only safely cast to TyTy types."); + rust_assert (this->is ()); + return static_cast (this); + } + + template T *as () + { + static_assert (std::is_base_of::value, + "Can only safely cast to TyTy types."); + rust_assert (this->is ()); + return static_cast (this); + } + + // Check if TyTy::BaseType is of a specific type and convert it to that type + // if so. + // Returns nullptr otherwise. Works as a dynamic_cast, but without compiler + // RTTI. + template T *try_as () const + { + static_assert (std::is_base_of::value, + "Can only safely cast to TyTy types."); + if (!this->is ()) + return nullptr; + + return static_cast (this); + } + + // See above. + template T *try_as () + { + static_assert (std::is_base_of::value, + "Can only safely cast to TyTy types."); + if (!this->is ()) + return nullptr; + + return static_cast (this); + } + protected: BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident, std::set refs = std::set ()); @@ -188,6 +245,8 @@ class BaseType : public TypeBoundsMappings class InferType : public BaseType { public: + static constexpr auto KIND = TypeKind::INFER; + enum InferTypeKind { GENERAL, @@ -231,6 +290,7 @@ class InferType : public BaseType location_t locus, std::set refs = std::set ()); void accept_vis (TyVisitor &vis) override; + void accept_vis (TyConstVisitor &vis) const override; std::string as_string () const override; @@ -255,6 +315,8 @@ class InferType : public BaseType class ErrorType : public BaseType { public: + static constexpr auto KIND = TypeKind::ERROR; + ErrorType (HirId ref, std::set refs = std::set ()); ErrorType (HirId ref, HirId ty_ref, @@ -275,6 +337,8 @@ class ErrorType : public BaseType class ParamType : public BaseType { public: + static constexpr auto KIND = TypeKind::PARAM; + ParamType (std::string symbol, location_t locus, HirId ref, HIR::GenericParam ¶m, std::vector specified_bounds, @@ -348,6 +412,8 @@ class StructFieldType class TupleType : public BaseType { public: + static constexpr auto KIND = TypeKind::TUPLE; + TupleType (HirId ref, location_t locus, std::vector fields = std::vector (), std::set refs = std::set ()); @@ -511,7 +577,9 @@ class VariantDef std::string as_string () const; bool is_equal (const VariantDef &other) const; + VariantDef *clone () const; + VariantDef *monomorphized_clone () const; const RustIdent &get_ident () const; @@ -530,6 +598,8 @@ class VariantDef class ADTType : public BaseType, public SubstitutionRef { public: + static constexpr auto KIND = TypeKind::ADT; + enum ADTKind { STRUCT_STRUCT, @@ -587,14 +657,19 @@ class ADTType : public BaseType, public SubstitutionRef {} ADTKind get_adt_kind () const { return adt_kind; } + ReprOptions get_repr_options () const { return repr; } bool is_struct_struct () const { return adt_kind == STRUCT_STRUCT; } + bool is_tuple_struct () const { return adt_kind == TUPLE_STRUCT; } + bool is_union () const { return adt_kind == UNION; } + bool is_enum () const { return adt_kind == ENUM; } void accept_vis (TyVisitor &vis) override; + void accept_vis (TyConstVisitor &vis) const override; std::string as_string () const override; @@ -615,6 +690,7 @@ class ADTType : public BaseType, public SubstitutionRef size_t number_of_variants () const { return variants.size (); } std::vector &get_variants () { return variants; } + const std::vector &get_variants () const { return variants; } bool lookup_variant (const std::string &lookup, @@ -663,6 +739,8 @@ class ADTType : public BaseType, public SubstitutionRef class FnType : public BaseType, public SubstitutionRef { public: + static constexpr auto KIND = TypeKind::FNDEF; + static const uint8_t FNTYPE_DEFAULT_FLAGS = 0x00; static const uint8_t FNTYPE_IS_METHOD_FLAG = 0x01; static const uint8_t FNTYPE_IS_EXTERN_FLAG = 0x02; @@ -776,6 +854,8 @@ class FnType : public BaseType, public SubstitutionRef class FnPtr : public BaseType { public: + static constexpr auto KIND = TypeKind::FNPTR; + FnPtr (HirId ref, location_t locus, std::vector params, TyVar result_type, std::set refs = std::set ()) : BaseType (ref, ref, TypeKind::FNPTR, @@ -821,6 +901,8 @@ class FnPtr : public BaseType class ClosureType : public BaseType, public SubstitutionRef { public: + static constexpr auto KIND = TypeKind::CLOSURE; + ClosureType (HirId ref, DefId id, RustIdent ident, TyTy::TupleType *parameters, TyVar result_type, std::vector subst_refs, @@ -891,6 +973,8 @@ class ClosureType : public BaseType, public SubstitutionRef class ArrayType : public BaseType { public: + static constexpr auto KIND = TypeKind::ARRAY; + ArrayType (HirId ref, location_t locus, HIR::Expr &capacity_expr, TyVar base, std::set refs = std::set ()) : BaseType (ref, ref, TypeKind::ARRAY, @@ -928,12 +1012,16 @@ class ArrayType : public BaseType private: TyVar element_type; + // FIXME: I dont think this should be in tyty - tyty should already be const + // evaluated HIR::Expr &capacity_expr; }; class SliceType : public BaseType { public: + static constexpr auto KIND = TypeKind::SLICE; + SliceType (HirId ref, location_t locus, TyVar base, std::set refs = std::set ()) : BaseType (ref, ref, TypeKind::SLICE, @@ -973,6 +1061,8 @@ class SliceType : public BaseType class BoolType : public BaseType { public: + static constexpr auto KIND = TypeKind::BOOL; + BoolType (HirId ref, std::set refs = std::set ()); BoolType (HirId ref, HirId ty_ref, std::set refs = std::set ()); @@ -1000,6 +1090,8 @@ class IntType : public BaseType I128 }; + static constexpr auto KIND = TypeKind::INT; + IntType (HirId ref, IntKind kind, std::set refs = std::set ()); IntType (HirId ref, HirId ty_ref, IntKind kind, std::set refs = std::set ()); @@ -1026,6 +1118,8 @@ class IntType : public BaseType class UintType : public BaseType { public: + static constexpr auto KIND = TypeKind::UINT; + enum UintKind { U8, @@ -1062,6 +1156,8 @@ class UintType : public BaseType class FloatType : public BaseType { public: + static constexpr auto KIND = TypeKind::FLOAT; + enum FloatKind { F32, @@ -1094,6 +1190,8 @@ class FloatType : public BaseType class USizeType : public BaseType { public: + static constexpr auto KIND = TypeKind::USIZE; + USizeType (HirId ref, std::set refs = std::set ()); USizeType (HirId ref, HirId ty_ref, std::set refs = std::set ()); @@ -1112,6 +1210,8 @@ class USizeType : public BaseType class ISizeType : public BaseType { public: + static constexpr auto KIND = TypeKind::ISIZE; + ISizeType (HirId ref, std::set refs = std::set ()); ISizeType (HirId ref, HirId ty_ref, std::set refs = std::set ()); @@ -1130,6 +1230,8 @@ class ISizeType : public BaseType class CharType : public BaseType { public: + static constexpr auto KIND = TypeKind::CHAR; + CharType (HirId ref, std::set refs = std::set ()); CharType (HirId ref, HirId ty_ref, std::set refs = std::set ()); @@ -1147,6 +1249,8 @@ class CharType : public BaseType class StrType : public BaseType { public: + static constexpr auto KIND = TypeKind::STR; + StrType (HirId ref, std::set refs = std::set ()); StrType (HirId ref, HirId ty_ref, std::set refs = std::set ()); @@ -1167,6 +1271,8 @@ class StrType : public BaseType class DynamicObjectType : public BaseType { public: + static constexpr auto KIND = TypeKind::DYNAMIC; + DynamicObjectType (HirId ref, RustIdent ident, std::vector specified_bounds, std::set refs = std::set ()); @@ -1197,6 +1303,8 @@ class DynamicObjectType : public BaseType class ReferenceType : public BaseType { public: + static constexpr auto KIND = TypeKind::REF; + ReferenceType (HirId ref, TyVar base, Mutability mut, std::set refs = std::set ()); ReferenceType (HirId ref, HirId ty_ref, TyVar base, Mutability mut, @@ -1236,6 +1344,8 @@ class ReferenceType : public BaseType class PointerType : public BaseType { public: + static constexpr auto KIND = TypeKind::POINTER; + PointerType (HirId ref, TyVar base, Mutability mut, std::set refs = std::set ()); PointerType (HirId ref, HirId ty_ref, TyVar base, Mutability mut, @@ -1284,11 +1394,15 @@ class PointerType : public BaseType class NeverType : public BaseType { public: + static constexpr auto KIND = TypeKind::NEVER; + NeverType (HirId ref, std::set refs = std::set ()); + NeverType (HirId ref, HirId ty_ref, std::set refs = std::set ()); void accept_vis (TyVisitor &vis) override; + void accept_vis (TyConstVisitor &vis) const override; std::string as_string () const override; @@ -1305,6 +1419,8 @@ class NeverType : public BaseType class PlaceholderType : public BaseType { public: + static constexpr auto KIND = TypeKind::PLACEHOLDER; + PlaceholderType (std::string symbol, HirId ref, std::set refs = std::set ()); PlaceholderType (std::string symbol, HirId ref, HirId ty_ref, @@ -1340,6 +1456,8 @@ class PlaceholderType : public BaseType class ProjectionType : public BaseType, public SubstitutionRef { public: + static constexpr auto KIND = TypeKind::PROJECTION; + ProjectionType (HirId ref, BaseType *base, const Resolver::TraitReference *trait, DefId item, std::vector subst_refs, diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index a15d310ce6d2..55e22f637dd4 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -709,11 +709,11 @@ Mappings::lookup_hir_struct_field (HirId id) void Mappings::insert_hir_pattern (HIR::Pattern *pattern) { - auto id = pattern->get_pattern_mappings ().get_hirid (); + auto id = pattern->get_mappings ().get_hirid (); rust_assert (lookup_hir_pattern (id) == nullptr); hirPatternMappings[id] = pattern; - insert_node_to_hir (pattern->get_pattern_mappings ().get_nodeid (), id); + insert_node_to_hir (pattern->get_mappings ().get_nodeid (), id); } HIR::Pattern * diff --git a/gcc/testsuite/rust/compile/closure_in_closure.rs b/gcc/testsuite/rust/compile/closure_in_closure.rs new file mode 100644 index 000000000000..1a003070f6a7 --- /dev/null +++ b/gcc/testsuite/rust/compile/closure_in_closure.rs @@ -0,0 +1,8 @@ +// { dg-additional-options "-frust-compile-until=ast" } +// +// Do not reformat this test! The default rust format settings will insert a +// space between closure parameter lists. +fn main() { + let f = |_||x, y| x+y; + assert_eq!(f(())(1, 2), 3); +} diff --git a/gcc/testsuite/rust/compile/issue-2645.rs b/gcc/testsuite/rust/compile/issue-2645.rs new file mode 100644 index 000000000000..ef1403de1a78 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2645.rs @@ -0,0 +1,4 @@ +// { dg-additional-options "-frust-compile-until=ast" } +pub fn struct_tuple(A { 0: a, 1: ref b }: A) -> i32 { + a +} diff --git a/gcc/testsuite/rust/compile/issue-2665.rs b/gcc/testsuite/rust/compile/issue-2665.rs new file mode 100644 index 000000000000..3ee8e7b22ca0 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2665.rs @@ -0,0 +1,6 @@ +fn main() {} + +#[cfg(FALSE)] +impl X { + const Y: u8; +} diff --git a/gcc/testsuite/rust/compile/macro-issue2653.rs b/gcc/testsuite/rust/compile/macro-issue2653.rs new file mode 100644 index 000000000000..dc2972f4e0d4 --- /dev/null +++ b/gcc/testsuite/rust/compile/macro-issue2653.rs @@ -0,0 +1,5 @@ +macro_rules! foo { + ($p:path $b:block) => {}; +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/macro57.rs b/gcc/testsuite/rust/compile/macro57.rs new file mode 100644 index 000000000000..0640d2f83052 --- /dev/null +++ b/gcc/testsuite/rust/compile/macro57.rs @@ -0,0 +1,13 @@ +macro_rules! macro_rules { + () => {}; +} + +macro_rules! foo { + () => {}; +} + +foo!(); + +fn main() {} + +macro_rules!(); diff --git a/gcc/testsuite/rust/compile/macro_rules_macro_rules.rs b/gcc/testsuite/rust/compile/macro_rules_macro_rules.rs new file mode 100644 index 000000000000..ecd1712c94ae --- /dev/null +++ b/gcc/testsuite/rust/compile/macro_rules_macro_rules.rs @@ -0,0 +1,10 @@ +macro_rules! macro_rules { + () => { + struct S; + }; +} +macro_rules! {} // calls the macro defined above + +fn main() { + let _s = S; +} diff --git a/gcc/testsuite/rust/compile/match_break.rs b/gcc/testsuite/rust/compile/match_break.rs new file mode 100644 index 000000000000..d5aca86e8a4f --- /dev/null +++ b/gcc/testsuite/rust/compile/match_break.rs @@ -0,0 +1,14 @@ +// { dg-additional-options "-frust-compile-until=ast" } +enum Nat { + S(Box), + Z, +} +fn test(x: &mut Nat) { + let mut p = &mut *x; + loop { + match p { + &mut Nat::Z => break, + &mut Nat::S(ref mut n) => p = &mut *n, + } + } +} diff --git a/gcc/testsuite/rust/compile/parse_generic_path_expr.rs b/gcc/testsuite/rust/compile/parse_generic_path_expr.rs new file mode 100644 index 000000000000..a340067e9ea5 --- /dev/null +++ b/gcc/testsuite/rust/compile/parse_generic_path_expr.rs @@ -0,0 +1,4 @@ +// { dg-additional-options "-frust-compile-until=ast" } +fn main() { + only_foo::<::Item>(); +} diff --git a/gcc/testsuite/rust/compile/parse_global_path_generic.rs b/gcc/testsuite/rust/compile/parse_global_path_generic.rs new file mode 100644 index 000000000000..eb083a8bed2f --- /dev/null +++ b/gcc/testsuite/rust/compile/parse_global_path_generic.rs @@ -0,0 +1,4 @@ +// { dg-additional-options "-frust-compile-until=ast" } +pub fn foo(_d: D) -> u32 { + 0 +} diff --git a/gcc/testsuite/rust/compile/parse_item_default_macro.rs b/gcc/testsuite/rust/compile/parse_item_default_macro.rs new file mode 100644 index 000000000000..3e632695c12d --- /dev/null +++ b/gcc/testsuite/rust/compile/parse_item_default_macro.rs @@ -0,0 +1,8 @@ +// { dg-additional-options "-frust-compile-until=ast" } +macro_rules! default { + ($($x:tt)*) => { $($x)* } +} + +default! { + struct A; +} diff --git a/gcc/testsuite/rust/compile/parse_pub_unit_type.rs b/gcc/testsuite/rust/compile/parse_pub_unit_type.rs new file mode 100644 index 000000000000..c79f1990ccb4 --- /dev/null +++ b/gcc/testsuite/rust/compile/parse_pub_unit_type.rs @@ -0,0 +1 @@ +pub struct Foo(pub ()); diff --git a/gcc/testsuite/rust/compile/range_from_expr_for_loop.rs b/gcc/testsuite/rust/compile/range_from_expr_for_loop.rs new file mode 100644 index 000000000000..69b4b0c12c21 --- /dev/null +++ b/gcc/testsuite/rust/compile/range_from_expr_for_loop.rs @@ -0,0 +1,7 @@ +// { dg-additional-options "-frust-compile-until=ast" } +fn main() { + for _ in 1.. { + break; + } + let i = 2; +} diff --git a/gcc/testsuite/rust/compile/tupple_struct_pattern_tuple.rs b/gcc/testsuite/rust/compile/tupple_struct_pattern_tuple.rs new file mode 100644 index 000000000000..053b9ce7e27e --- /dev/null +++ b/gcc/testsuite/rust/compile/tupple_struct_pattern_tuple.rs @@ -0,0 +1,4 @@ +// { dg-additional-options "-frust-compile-until=typecheck" } +struct Struct(i32); + +fn struct_pattern(Struct { 0: a }: Struct) {} diff --git a/gcc/testsuite/rust/compile/v0-mangle1.rs b/gcc/testsuite/rust/compile/v0-mangle1.rs new file mode 100644 index 000000000000..a34f1a70112a --- /dev/null +++ b/gcc/testsuite/rust/compile/v0-mangle1.rs @@ -0,0 +1,70 @@ +// { dg-additional-options -frust-mangling=v0 } +#[lang = "sized"] +pub trait Sized {} + +pub fn foo() {} + +pub mod module_a { + pub fn bar() {} + + pub mod module_b { + pub fn baz() {} + } +} + +struct S; // { dg-warning "struct is never constructed" } + +// name starting with underscore. +pub fn _uc() {} + +pub fn generic1() {} + +pub fn generic2() {} + +pub fn 初音ミク() {} + +pub fn іржа() {} + +pub fn あ1() {} + +fn main() { + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle13foo" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle13foo + foo(); + + // { dg-final { scan-assembler "_R.*NvNtC.*10v0_mangle18module_a3bar" } } + // cf. rustc 1.72.0: _RNvNtCshIBIgX6Bzox_10v0_mangle18module_a3bar + module_a::bar(); + + // { dg-final { scan-assembler "_R.*NvNtNtC10v0_mangle18module_a8module_b3baz" } } + // cf. rustc 1.72.0: _RNvNtNtCshIBIgX6Bzox_10v0_mangle18module_a8module_b3baz + module_a::module_b::baz(); + + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle13__uc" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle13__uc + _uc(); + + // { dg-final { scan-assembler "_R.*INvC.*10v0_mangle18generic1lE.*" } } + // cf. rustc 1.72.0: _RINvCshIBIgX6Bzox_10v0_mangle18generic1lEB2_ + generic1::(); + + // { dg-final { scan-assembler "_R.*INvC.*10v0_mangle18generic1NtC.*10v0_mangle11SE.*" } } + // cf. rustc 1.72.0: _RINvCshIBIgX6Bzox_10v0_mangle18generic1NtB2_1SEB2_ + generic1::(); + + // { dg-final { scan-assembler "_R.*INvC.*10v0_mangle18generic2hfjE.*" } } + // cf. rustc 1.72.0: _RINvCshIBIgX6Bzox_10v0_mangle18generic2hfjEB2_ + generic2::(); + + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle1u13pck1ew32ihn2d" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle1u13pck1ew32ihn2d + 初音ミク(); + + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle1u8_80al3a6f" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle1u8_80al3a6f + іржа(); + + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle1u5_1_w7t" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle1u5_1_w7t + あ1(); +} diff --git a/gcc/testsuite/rust/compile/while_break_expr.rs b/gcc/testsuite/rust/compile/while_break_expr.rs new file mode 100644 index 000000000000..099683e45de6 --- /dev/null +++ b/gcc/testsuite/rust/compile/while_break_expr.rs @@ -0,0 +1,3 @@ +fn main() { + let _ = 'l: while break 'l {}; +}