diff options
Diffstat (limited to 'gcc')
51 files changed, 3072 insertions, 639 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 9de93fe..b43f0f3 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -75,6 +75,7 @@ GRS_OBJS = \ rust/rust-compile-resolve-path.o \ rust/rust-macro-expand.o \ rust/rust-macro-invoc-lexer.o \ + rust/rust-macro-substitute-ctx.o \ rust/rust-macro-builtins.o \ rust/rust-hir-full-test.o \ rust/rust-hir-map.o \ @@ -95,6 +96,7 @@ GRS_OBJS = \ rust/rust-hir-type-check-type.o \ rust/rust-hir-type-check-struct.o \ rust/rust-hir-type-check-pattern.o \ + rust/rust-hir-type-check-expr.o \ rust/rust-hir-dot-operator.o \ rust/rust-autoderef.o \ rust/rust-substitution-mapper.o \ diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index 5d27f7b..b434168 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -1,3 +1,5 @@ +// Copyright (C) 2020-2022 Free Software Foundation, Inc. + // This file is part of GCC. // GCC is free software; you can redistribute it and/or modify it under @@ -25,7 +27,7 @@ namespace Rust { namespace Compile { -class HIRCompileBase : public HIR::HIRFullVisitorBase +class HIRCompileBase { public: virtual ~HIRCompileBase () {} diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h index a5a5896..4a3c6f5 100644 --- a/gcc/rust/backend/rust-compile-block.h +++ b/gcc/rust/backend/rust-compile-block.h @@ -25,10 +25,8 @@ namespace Rust { namespace Compile { -class CompileBlock : public HIRCompileBase +class CompileBlock : public HIRCompileBase, public HIR::HIRExpressionVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static tree compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result) { @@ -39,6 +37,62 @@ public: void visit (HIR::BlockExpr &expr) override; + // Empty visit for unused Expression HIR nodes. + void visit (HIR::PathInExpression &) override {} + void visit (HIR::QualifiedPathInExpression &) override {} + void visit (HIR::ClosureExprInner &) override {} + void visit (HIR::ClosureExprInnerTyped &) override {} + void visit (HIR::StructExprFieldIdentifier &) override {} + void visit (HIR::StructExprFieldIdentifierValue &) override {} + void visit (HIR::StructExprFieldIndexValue &) override {} + void visit (HIR::StructExprStruct &) override {} + void visit (HIR::StructExprStructFields &) override {} + void visit (HIR::IdentifierExpr &) override {} + void visit (HIR::LiteralExpr &) override {} + void visit (HIR::BorrowExpr &) override {} + void visit (HIR::DereferenceExpr &) override {} + void visit (HIR::ErrorPropagationExpr &) override {} + void visit (HIR::NegationExpr &) override {} + void visit (HIR::ArithmeticOrLogicalExpr &) override {} + void visit (HIR::ComparisonExpr &) override {} + void visit (HIR::LazyBooleanExpr &) override {} + void visit (HIR::TypeCastExpr &) override {} + void visit (HIR::AssignmentExpr &) override {} + void visit (HIR::CompoundAssignmentExpr &) override {} + void visit (HIR::GroupedExpr &) override {} + void visit (HIR::ArrayExpr &) override {} + void visit (HIR::ArrayIndexExpr &) override {} + void visit (HIR::TupleExpr &) override {} + void visit (HIR::TupleIndexExpr &) override {} + void visit (HIR::CallExpr &) override {} + void visit (HIR::MethodCallExpr &) override {} + void visit (HIR::FieldAccessExpr &) override {} + void visit (HIR::ContinueExpr &) override {} + void visit (HIR::BreakExpr &) override {} + void visit (HIR::RangeFromToExpr &) override {} + void visit (HIR::RangeFromExpr &) override {} + void visit (HIR::RangeToExpr &) override {} + void visit (HIR::RangeFullExpr &) override {} + void visit (HIR::RangeFromToInclExpr &) override {} + void visit (HIR::RangeToInclExpr &) override {} + void visit (HIR::ReturnExpr &) override {} + void visit (HIR::UnsafeBlockExpr &) override {} + void visit (HIR::LoopExpr &) override {} + void visit (HIR::WhileLoopExpr &) override {} + void visit (HIR::WhileLetLoopExpr &) override {} + void visit (HIR::ForLoopExpr &) override {} + void visit (HIR::IfExpr &) override {} + void visit (HIR::IfExprConseqElse &) override {} + void visit (HIR::IfExprConseqIf &) override {} + void visit (HIR::IfExprConseqIfLet &) override {} + void visit (HIR::IfLetExpr &) override {} + void visit (HIR::IfLetExprConseqElse &) override {} + void visit (HIR::IfLetExprConseqIf &) override {} + void visit (HIR::IfLetExprConseqIfLet &) override {} + void visit (HIR::MatchExpr &) override {} + void visit (HIR::AwaitExpr &) override {} + void visit (HIR::AsyncBlockExpr &) override {} + private: CompileBlock (Context *ctx, Bvariable *result) : HIRCompileBase (ctx), translated (nullptr), result (result) @@ -48,10 +102,9 @@ private: Bvariable *result; }; -class CompileConditionalBlocks : public HIRCompileBase +class CompileConditionalBlocks : public HIRCompileBase, + public HIR::HIRExpressionVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static tree compile (HIR::IfExpr *expr, Context *ctx, Bvariable *result) { @@ -61,11 +114,63 @@ public: } void visit (HIR::IfExpr &expr) override; - void visit (HIR::IfExprConseqElse &expr) override; - void visit (HIR::IfExprConseqIf &expr) override; + // Empty visit for unused Expression HIR nodes. + void visit (HIR::PathInExpression &) override {} + void visit (HIR::QualifiedPathInExpression &) override {} + void visit (HIR::ClosureExprInner &) override {} + void visit (HIR::ClosureExprInnerTyped &) override {} + void visit (HIR::StructExprFieldIdentifier &) override {} + void visit (HIR::StructExprFieldIdentifierValue &) override {} + void visit (HIR::StructExprFieldIndexValue &) override {} + void visit (HIR::StructExprStruct &) override {} + void visit (HIR::StructExprStructFields &) override {} + void visit (HIR::IdentifierExpr &) override {} + void visit (HIR::LiteralExpr &) override {} + void visit (HIR::BorrowExpr &) override {} + void visit (HIR::DereferenceExpr &) override {} + void visit (HIR::ErrorPropagationExpr &) override {} + void visit (HIR::NegationExpr &) override {} + void visit (HIR::ArithmeticOrLogicalExpr &) override {} + void visit (HIR::ComparisonExpr &) override {} + void visit (HIR::LazyBooleanExpr &) override {} + void visit (HIR::TypeCastExpr &) override {} + void visit (HIR::AssignmentExpr &) override {} + void visit (HIR::CompoundAssignmentExpr &) override {} + void visit (HIR::GroupedExpr &) override {} + void visit (HIR::ArrayExpr &) override {} + void visit (HIR::ArrayIndexExpr &) override {} + void visit (HIR::TupleExpr &) override {} + void visit (HIR::TupleIndexExpr &) override {} + void visit (HIR::CallExpr &) override {} + void visit (HIR::MethodCallExpr &) override {} + void visit (HIR::FieldAccessExpr &) override {} + void visit (HIR::BlockExpr &) override {} + void visit (HIR::ContinueExpr &) override {} + void visit (HIR::BreakExpr &) override {} + void visit (HIR::RangeFromToExpr &) override {} + void visit (HIR::RangeFromExpr &) override {} + void visit (HIR::RangeToExpr &) override {} + void visit (HIR::RangeFullExpr &) override {} + void visit (HIR::RangeFromToInclExpr &) override {} + void visit (HIR::RangeToInclExpr &) override {} + void visit (HIR::ReturnExpr &) override {} + void visit (HIR::UnsafeBlockExpr &) override {} + void visit (HIR::LoopExpr &) override {} + void visit (HIR::WhileLoopExpr &) override {} + void visit (HIR::WhileLetLoopExpr &) override {} + void visit (HIR::ForLoopExpr &) override {} + void visit (HIR::IfExprConseqIfLet &) override {} + void visit (HIR::IfLetExpr &) override {} + void visit (HIR::IfLetExprConseqElse &) override {} + void visit (HIR::IfLetExprConseqIf &) override {} + void visit (HIR::IfLetExprConseqIfLet &) override {} + void visit (HIR::MatchExpr &) override {} + void visit (HIR::AwaitExpr &) override {} + void visit (HIR::AsyncBlockExpr &) override {} + private: CompileConditionalBlocks (Context *ctx, Bvariable *result) : HIRCompileBase (ctx), translated (nullptr), result (result) @@ -75,10 +180,9 @@ private: Bvariable *result; }; -class CompileExprWithBlock : public HIRCompileBase +class CompileExprWithBlock : public HIRCompileBase, + public HIR::HIRExpressionVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static tree compile (HIR::ExprWithBlock *expr, Context *ctx, Bvariable *result) @@ -103,6 +207,60 @@ public: translated = CompileConditionalBlocks::compile (&expr, ctx, result); } + // Empty visit for unused Expression HIR nodes. + void visit (HIR::PathInExpression &) override {} + void visit (HIR::QualifiedPathInExpression &) override {} + void visit (HIR::ClosureExprInner &) override {} + void visit (HIR::ClosureExprInnerTyped &) override {} + void visit (HIR::StructExprFieldIdentifier &) override {} + void visit (HIR::StructExprFieldIdentifierValue &) override {} + void visit (HIR::StructExprFieldIndexValue &) override {} + void visit (HIR::StructExprStruct &) override {} + void visit (HIR::StructExprStructFields &) override {} + void visit (HIR::IdentifierExpr &) override {} + void visit (HIR::LiteralExpr &) override {} + void visit (HIR::BorrowExpr &) override {} + void visit (HIR::DereferenceExpr &) override {} + void visit (HIR::ErrorPropagationExpr &) override {} + void visit (HIR::NegationExpr &) override {} + void visit (HIR::ArithmeticOrLogicalExpr &) override {} + void visit (HIR::ComparisonExpr &) override {} + void visit (HIR::LazyBooleanExpr &) override {} + void visit (HIR::TypeCastExpr &) override {} + void visit (HIR::AssignmentExpr &) override {} + void visit (HIR::CompoundAssignmentExpr &) override {} + void visit (HIR::GroupedExpr &) override {} + void visit (HIR::ArrayExpr &) override {} + void visit (HIR::ArrayIndexExpr &) override {} + void visit (HIR::TupleExpr &) override {} + void visit (HIR::TupleIndexExpr &) override {} + void visit (HIR::CallExpr &) override {} + void visit (HIR::MethodCallExpr &) override {} + void visit (HIR::FieldAccessExpr &) override {} + void visit (HIR::BlockExpr &) override {} + void visit (HIR::ContinueExpr &) override {} + void visit (HIR::BreakExpr &) override {} + void visit (HIR::RangeFromToExpr &) override {} + void visit (HIR::RangeFromExpr &) override {} + void visit (HIR::RangeToExpr &) override {} + void visit (HIR::RangeFullExpr &) override {} + void visit (HIR::RangeFromToInclExpr &) override {} + void visit (HIR::RangeToInclExpr &) override {} + void visit (HIR::ReturnExpr &) override {} + void visit (HIR::UnsafeBlockExpr &) override {} + void visit (HIR::LoopExpr &) override {} + void visit (HIR::WhileLoopExpr &) override {} + void visit (HIR::WhileLetLoopExpr &) override {} + void visit (HIR::ForLoopExpr &) override {} + void visit (HIR::IfExprConseqIfLet &) override {} + void visit (HIR::IfLetExpr &) override {} + void visit (HIR::IfLetExprConseqElse &) override {} + void visit (HIR::IfLetExprConseqIf &) override {} + void visit (HIR::IfLetExprConseqIfLet &) override {} + void visit (HIR::MatchExpr &) override {} + void visit (HIR::AwaitExpr &) override {} + void visit (HIR::AsyncBlockExpr &) override {} + private: CompileExprWithBlock (Context *ctx, Bvariable *result) : HIRCompileBase (ctx), translated (nullptr), result (result) diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 65f159e..bf47661 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -790,7 +790,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref, tree CompileExpr::resolve_operator_overload ( - Analysis::RustLangItem::ItemType lang_item_type, HIR::OperatorExpr &expr, + Analysis::RustLangItem::ItemType lang_item_type, HIR::OperatorExprMeta expr, tree lhs, tree rhs, HIR::Expr *lhs_expr, HIR::Expr *rhs_expr) { TyTy::FnType *fntype; @@ -1377,5 +1377,172 @@ CompileExpr::visit (HIR::IdentifierExpr &expr) } } +void +CompileExpr::visit (HIR::RangeFromToExpr &expr) +{ + tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx); + tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx); + if (from == error_mark_node || to == error_mark_node) + { + translated = error_mark_node; + return; + } + + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + + // make the constructor + translated + = ctx->get_backend ()->constructor_expression (adt, false, {from, to}, -1, + expr.get_locus ()); +} + +void +CompileExpr::visit (HIR::RangeFromExpr &expr) +{ + tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx); + if (from == error_mark_node) + { + translated = error_mark_node; + return; + } + + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + + // make the constructor + translated + = ctx->get_backend ()->constructor_expression (adt, false, {from}, -1, + expr.get_locus ()); +} + +void +CompileExpr::visit (HIR::RangeToExpr &expr) +{ + tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx); + if (to == error_mark_node) + { + translated = error_mark_node; + return; + } + + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + + // make the constructor + translated + = ctx->get_backend ()->constructor_expression (adt, false, {to}, -1, + expr.get_locus ()); +} + +void +CompileExpr::visit (HIR::RangeFullExpr &expr) +{ + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + translated = ctx->get_backend ()->constructor_expression (adt, false, {}, -1, + expr.get_locus ()); +} + +void +CompileExpr::visit (HIR::RangeFromToInclExpr &expr) +{ + tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx); + tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx); + if (from == error_mark_node || to == error_mark_node) + { + translated = error_mark_node; + return; + } + + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + + // make the constructor + translated + = ctx->get_backend ()->constructor_expression (adt, false, {from, to}, -1, + expr.get_locus ()); +} + +void +CompileExpr::visit (HIR::ArrayIndexExpr &expr) +{ + tree array_reference = CompileExpr::Compile (expr.get_array_expr (), ctx); + tree index = CompileExpr::Compile (expr.get_index_expr (), ctx); + + // this might be an core::ops::index lang item situation + TyTy::FnType *fntype; + bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload ( + expr.get_mappings ().get_hirid (), &fntype); + if (is_op_overload) + { + auto lang_item_type = Analysis::RustLangItem::ItemType::INDEX; + tree operator_overload_call + = resolve_operator_overload (lang_item_type, expr, array_reference, + index, expr.get_array_expr (), + expr.get_index_expr ()); + + // lookup the expected type for this expression + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), + &tyty); + rust_assert (ok); + tree expected_type = TyTyResolveCompile::compile (ctx, tyty); + + // rust deref always returns a reference from this overload then we can + // actually do the indirection + translated + = ctx->get_backend ()->indirect_expression (expected_type, + operator_overload_call, + true, expr.get_locus ()); + return; + } + + // lets check if the array is a reference type then we can add an + // indirection if required + TyTy::BaseType *array_expr_ty = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type ( + expr.get_array_expr ()->get_mappings ().get_hirid (), &array_expr_ty); + rust_assert (ok); + + // do we need to add an indirect reference + if (array_expr_ty->get_kind () == TyTy::TypeKind::REF) + { + TyTy::ReferenceType *r + = static_cast<TyTy::ReferenceType *> (array_expr_ty); + TyTy::BaseType *tuple_type = r->get_base (); + tree array_tyty = TyTyResolveCompile::compile (ctx, tuple_type); + + array_reference + = ctx->get_backend ()->indirect_expression (array_tyty, array_reference, + true, expr.get_locus ()); + } + + translated + = ctx->get_backend ()->array_index_expression (array_reference, index, + expr.get_locus ()); +} + } // namespace Compile } // namespace Rust diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 2fee3be..3cc51d4 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -29,10 +29,8 @@ namespace Rust { namespace Compile { -class CompileExpr : public HIRCompileBase +class CompileExpr : public HIRCompileBase, public HIR::HIRExpressionVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static tree Compile (HIR::Expr *expr, Context *ctx) { @@ -201,36 +199,7 @@ public: void visit (HIR::CompoundAssignmentExpr &expr) override; - void visit (HIR::ArrayIndexExpr &expr) override - { - tree array_reference = CompileExpr::Compile (expr.get_array_expr (), ctx); - tree index = CompileExpr::Compile (expr.get_index_expr (), ctx); - - // lets check if the array is a reference type then we can add an - // indirection if required - TyTy::BaseType *array_expr_ty = nullptr; - bool ok = ctx->get_tyctx ()->lookup_type ( - expr.get_array_expr ()->get_mappings ().get_hirid (), &array_expr_ty); - rust_assert (ok); - - // do we need to add an indirect reference - if (array_expr_ty->get_kind () == TyTy::TypeKind::REF) - { - TyTy::ReferenceType *r - = static_cast<TyTy::ReferenceType *> (array_expr_ty); - TyTy::BaseType *tuple_type = r->get_base (); - tree array_tyty = TyTyResolveCompile::compile (ctx, tuple_type); - - array_reference - = ctx->get_backend ()->indirect_expression (array_tyty, - array_reference, true, - expr.get_locus ()); - } - - translated - = ctx->get_backend ()->array_index_expression (array_reference, index, - expr.get_locus ()); - } + void visit (HIR::ArrayIndexExpr &expr) override; void visit (HIR::ArrayExpr &expr) override; @@ -798,11 +767,37 @@ public: } void visit (HIR::BorrowExpr &expr) override; - void visit (HIR::DereferenceExpr &expr) override; - void visit (HIR::MatchExpr &expr) override; + void visit (HIR::RangeFromToExpr &expr) override; + + void visit (HIR::RangeFromExpr &expr) override; + + void visit (HIR::RangeToExpr &expr) override; + + void visit (HIR::RangeFullExpr &expr) override; + + void visit (HIR::RangeFromToInclExpr &expr) override; + + // Empty visit for unused Expression HIR nodes. + void visit (HIR::ClosureExprInner &) override {} + void visit (HIR::ClosureExprInnerTyped &) override {} + void visit (HIR::StructExprFieldIdentifier &) override {} + void visit (HIR::StructExprFieldIdentifierValue &) override {} + void visit (HIR::StructExprFieldIndexValue &) override {} + void visit (HIR::ErrorPropagationExpr &) override {} + void visit (HIR::RangeToInclExpr &) override {} + void visit (HIR::WhileLetLoopExpr &) override {} + void visit (HIR::ForLoopExpr &) override {} + void visit (HIR::IfExprConseqIfLet &) override {} + void visit (HIR::IfLetExpr &) override {} + void visit (HIR::IfLetExprConseqElse &) override {} + void visit (HIR::IfLetExprConseqIf &) override {} + void visit (HIR::IfLetExprConseqIfLet &) override {} + void visit (HIR::AwaitExpr &) override {} + void visit (HIR::AsyncBlockExpr &) override {} + protected: tree compile_dyn_dispatch_call (const TyTy::DynamicObjectType *dyn, TyTy::BaseType *receiver, @@ -818,7 +813,7 @@ protected: tree resolve_operator_overload (Analysis::RustLangItem::ItemType lang_item_type, - HIR::OperatorExpr &expr, tree lhs, tree rhs, + HIR::OperatorExprMeta expr, tree lhs, tree rhs, HIR::Expr *lhs_expr, HIR::Expr *rhs_expr); tree compile_bool_literal (const HIR::LiteralExpr &expr, diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h index 1412e7a..1987805 100644 --- a/gcc/rust/backend/rust-compile-extern.h +++ b/gcc/rust/backend/rust-compile-extern.h @@ -25,10 +25,9 @@ namespace Rust { namespace Compile { -class CompileExternItem : public HIRCompileBase +class CompileExternItem : public HIRCompileBase, + public HIR::HIRExternalItemVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static void compile (HIR::ExternalItem *item, Context *ctx, TyTy::BaseType *concrete = nullptr) diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h index 4ca26ec..74df725 100644 --- a/gcc/rust/backend/rust-compile-fnparam.h +++ b/gcc/rust/backend/rust-compile-fnparam.h @@ -24,10 +24,8 @@ namespace Rust { namespace Compile { -class CompileFnParam : public HIRCompileBase +class CompileFnParam : public HIRCompileBase, public HIR::HIRPatternVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static Bvariable *compile (Context *ctx, tree fndecl, HIR::FunctionParam *param, tree decl_type, @@ -57,6 +55,18 @@ public: = ctx->get_backend ()->parameter_variable (fndecl, "_", decl_type, locus); } + // Empty visit for unused Pattern HIR nodes. + void visit (HIR::GroupedPattern &) override {} + void visit (HIR::LiteralPattern &) override {} + void visit (HIR::PathInExpression &) override {} + void visit (HIR::QualifiedPathInExpression &) override {} + void visit (HIR::RangePattern &) override {} + void visit (HIR::ReferencePattern &) override {} + void visit (HIR::SlicePattern &) override {} + void visit (HIR::StructPattern &) override {} + void visit (HIR::TuplePattern &) override {} + void visit (HIR::TupleStructPattern &) override {} + private: CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus) : HIRCompileBase (ctx), fndecl (fndecl), decl_type (decl_type), @@ -69,7 +79,7 @@ private: Bvariable *compiled_param; }; -class CompileSelfParam : public HIRCompileBase +class CompileSelfParam : public HIRCompileBase, public HIR::HIRStmtVisitor { public: static Bvariable *compile (Context *ctx, tree fndecl, HIR::SelfParam &self, diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h index 4d49c0b..ac9478a 100644 --- a/gcc/rust/backend/rust-compile-implitem.h +++ b/gcc/rust/backend/rust-compile-implitem.h @@ -29,8 +29,6 @@ namespace Compile { // this is a proxy for HIR::ImplItem's back to use the normel HIR::Item path class CompileInherentImplItem : public CompileItem { - using Rust::Compile::CompileItem::visit; - public: static tree Compile (HIR::ImplItem *item, Context *ctx, TyTy::BaseType *concrete = nullptr, @@ -54,10 +52,8 @@ private: {} }; -class CompileTraitItem : public HIRCompileBase +class CompileTraitItem : public HIRCompileBase, public HIR::HIRTraitItemVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static tree Compile (HIR::TraitItem *item, Context *ctx, TyTy::BaseType *concrete, bool is_query_mode = false, @@ -74,9 +70,10 @@ public: } void visit (HIR::TraitItemConst &constant) override; - void visit (HIR::TraitItemFunc &func) override; + void visit (HIR::TraitItemType &typ) override {} + private: CompileTraitItem (Context *ctx, TyTy::BaseType *concrete, Location ref_locus) : HIRCompileBase (ctx), concrete (concrete), reference (error_mark_node), diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index 897fe85..63316b9 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -24,11 +24,9 @@ namespace Rust { namespace Compile { -class CompileItem : public HIRCompileBase +class CompileItem : public HIRCompileBase, public HIR::HIRStmtVisitor { protected: - using Rust::Compile::HIRCompileBase::visit; - public: static tree compile (HIR::Item *item, Context *ctx, TyTy::BaseType *concrete = nullptr, @@ -46,17 +44,33 @@ public: } void visit (HIR::StaticItem &var) override; - void visit (HIR::ConstantItem &constant) override; - void visit (HIR::Function &function) override; - void visit (HIR::ImplBlock &impl_block) override; - void visit (HIR::ExternBlock &extern_block) override; - void visit (HIR::Module &module) override; + // Empty visit for unused Stmt HIR nodes. + void visit (HIR::TupleStruct &) override {} + void visit (HIR::EnumItem &) override {} + void visit (HIR::EnumItemTuple &) override {} + void visit (HIR::EnumItemStruct &) override {} + void visit (HIR::EnumItemDiscriminant &) override {} + void visit (HIR::TypePathSegmentFunction &) override {} + void visit (HIR::TypePath &) override {} + void visit (HIR::QualifiedPathInType &) override {} + void visit (HIR::ExternCrate &) override {} + void visit (HIR::UseDeclaration &) override {} + void visit (HIR::TypeAlias &) override {} + void visit (HIR::StructStruct &) override {} + void visit (HIR::Enum &) override {} + void visit (HIR::Union &) override {} + void visit (HIR::Trait &) override {} + void visit (HIR::EmptyStmt &) override {} + void visit (HIR::LetStmt &) override {} + void visit (HIR::ExprStmtWithoutBlock &) override {} + void visit (HIR::ExprStmtWithBlock &) override {} + protected: CompileItem (Context *ctx, TyTy::BaseType *concrete, Location ref_locus) : HIRCompileBase (ctx), concrete (concrete), reference (error_mark_node), diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h index 535cf36..36e4ef3 100644 --- a/gcc/rust/backend/rust-compile-pattern.h +++ b/gcc/rust/backend/rust-compile-pattern.h @@ -21,10 +21,9 @@ namespace Rust { namespace Compile { -class CompilePatternCaseLabelExpr : public HIRCompileBase +class CompilePatternCaseLabelExpr : public HIRCompileBase, + public HIR::HIRPatternVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static tree Compile (HIR::Pattern *pattern, tree associated_case_label, Context *ctx) @@ -35,14 +34,20 @@ public: } void visit (HIR::PathInExpression &pattern) override; - void visit (HIR::StructPattern &pattern) override; - void visit (HIR::TupleStructPattern &pattern) override; - void visit (HIR::WildcardPattern &pattern) override; -private: + // Empty visit for unused Pattern HIR nodes. + void visit (HIR::GroupedPattern &) override {} + void visit (HIR::IdentifierPattern &) override {} + void visit (HIR::LiteralPattern &) override {} + void visit (HIR::QualifiedPathInExpression &) override {} + void visit (HIR::RangePattern &) override {} + void visit (HIR::ReferencePattern &) override {} + void visit (HIR::SlicePattern &) override {} + void visit (HIR::TuplePattern &) override {} + CompilePatternCaseLabelExpr (Context *ctx, tree associated_case_label) : HIRCompileBase (ctx), case_label_expr (error_mark_node), associated_case_label (associated_case_label) @@ -52,10 +57,9 @@ private: tree associated_case_label; }; -class CompilePatternBindings : public HIRCompileBase +class CompilePatternBindings : public HIRCompileBase, + public HIR::HIRPatternVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static void Compile (HIR::Pattern *pattern, tree match_scrutinee_expr, Context *ctx) @@ -65,9 +69,20 @@ public: } void visit (HIR::StructPattern &pattern) override; - void visit (HIR::TupleStructPattern &pattern) override; + // Empty visit for unused Pattern HIR nodes. + void visit (HIR::GroupedPattern &) override {} + void visit (HIR::IdentifierPattern &) override {} + void visit (HIR::LiteralPattern &) override {} + void visit (HIR::PathInExpression &) override {} + void visit (HIR::QualifiedPathInExpression &) override {} + void visit (HIR::RangePattern &) override {} + void visit (HIR::ReferencePattern &) override {} + void visit (HIR::SlicePattern &) override {} + void visit (HIR::TuplePattern &) override {} + void visit (HIR::WildcardPattern &) override {} + private: CompilePatternBindings (Context *ctx, tree match_scrutinee_expr) : HIRCompileBase (ctx), match_scrutinee_expr (match_scrutinee_expr) diff --git a/gcc/rust/backend/rust-compile-resolve-path.h b/gcc/rust/backend/rust-compile-resolve-path.h index 9c9d7c5..37dec0b 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.h +++ b/gcc/rust/backend/rust-compile-resolve-path.h @@ -25,10 +25,8 @@ namespace Rust { namespace Compile { -class ResolvePathRef : public HIRCompileBase +class ResolvePathRef : public HIRCompileBase, public HIR::HIRPatternVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static tree Compile (HIR::QualifiedPathInExpression &expr, Context *ctx) { @@ -45,10 +43,20 @@ public: } void visit (HIR::PathInExpression &expr) override; - void visit (HIR::QualifiedPathInExpression &expr) override; -private: + // Empty visit for unused Pattern HIR nodes. + void visit (HIR::GroupedPattern &) override {} + void visit (HIR::IdentifierPattern &) override {} + void visit (HIR::LiteralPattern &) override {} + void visit (HIR::RangePattern &) override {} + void visit (HIR::ReferencePattern &) override {} + void visit (HIR::SlicePattern &) override {} + void visit (HIR::StructPattern &) override {} + void visit (HIR::TuplePattern &) override {} + void visit (HIR::TupleStructPattern &) override {} + void visit (HIR::WildcardPattern &) override {} + ResolvePathRef (Context *ctx) : HIRCompileBase (ctx), resolved (error_mark_node) {} diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h index 24a2084..2dfb520 100644 --- a/gcc/rust/backend/rust-compile-stmt.h +++ b/gcc/rust/backend/rust-compile-stmt.h @@ -26,10 +26,8 @@ namespace Rust { namespace Compile { -class CompileStmt : public HIRCompileBase +class CompileStmt : public HIRCompileBase, public HIR::HIRStmtVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static tree Compile (HIR::Stmt *stmt, Context *ctx) { @@ -103,6 +101,30 @@ public: } } + // Empty visit for unused Stmt HIR nodes. + void visit (HIR::TupleStruct &) override {} + void visit (HIR::EnumItem &) override {} + void visit (HIR::EnumItemTuple &) override {} + void visit (HIR::EnumItemStruct &) override {} + void visit (HIR::EnumItemDiscriminant &) override {} + void visit (HIR::TypePathSegmentFunction &) override {} + void visit (HIR::TypePath &) override {} + void visit (HIR::QualifiedPathInType &) override {} + void visit (HIR::Module &) override {} + void visit (HIR::ExternCrate &) override {} + void visit (HIR::UseDeclaration &) override {} + void visit (HIR::Function &) override {} + void visit (HIR::TypeAlias &) override {} + void visit (HIR::StructStruct &) override {} + void visit (HIR::Enum &) override {} + void visit (HIR::Union &) override {} + void visit (HIR::ConstantItem &) override {} + void visit (HIR::StaticItem &) override {} + void visit (HIR::Trait &) override {} + void visit (HIR::ImplBlock &) override {} + void visit (HIR::ExternBlock &) override {} + void visit (HIR::EmptyStmt &) override {} + private: CompileStmt (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {} diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.h b/gcc/rust/backend/rust-compile-struct-field-expr.h index 0570973..c5e986e 100644 --- a/gcc/rust/backend/rust-compile-struct-field-expr.h +++ b/gcc/rust/backend/rust-compile-struct-field-expr.h @@ -25,10 +25,9 @@ namespace Rust { namespace Compile { -class CompileStructExprField : public HIRCompileBase +class CompileStructExprField : public HIRCompileBase, + public HIR::HIRExpressionVisitor { - using Rust::Compile::HIRCompileBase::visit; - public: static tree Compile (HIR::StructExprField *field, Context *ctx) { @@ -39,11 +38,63 @@ public: } void visit (HIR::StructExprFieldIdentifierValue &field) override; - void visit (HIR::StructExprFieldIndexValue &field) override; - void visit (HIR::StructExprFieldIdentifier &field) override; + // Empty visit for unused Expression HIR nodes. + void visit (HIR::PathInExpression &) override {} + void visit (HIR::QualifiedPathInExpression &) override {} + void visit (HIR::ClosureExprInner &) override {} + void visit (HIR::ClosureExprInnerTyped &) override {} + void visit (HIR::StructExprStruct &) override {} + void visit (HIR::StructExprStructFields &) override {} + void visit (HIR::IdentifierExpr &) override {} + void visit (HIR::LiteralExpr &) override {} + void visit (HIR::BorrowExpr &) override {} + void visit (HIR::DereferenceExpr &) override {} + void visit (HIR::ErrorPropagationExpr &) override {} + void visit (HIR::NegationExpr &) override {} + void visit (HIR::ArithmeticOrLogicalExpr &) override {} + void visit (HIR::ComparisonExpr &) override {} + void visit (HIR::LazyBooleanExpr &) override {} + void visit (HIR::TypeCastExpr &) override {} + void visit (HIR::AssignmentExpr &) override {} + void visit (HIR::CompoundAssignmentExpr &) override {} + void visit (HIR::GroupedExpr &) override {} + void visit (HIR::ArrayExpr &) override {} + void visit (HIR::ArrayIndexExpr &) override {} + void visit (HIR::TupleExpr &) override {} + void visit (HIR::TupleIndexExpr &) override {} + void visit (HIR::CallExpr &) override {} + void visit (HIR::MethodCallExpr &) override {} + void visit (HIR::FieldAccessExpr &) override {} + void visit (HIR::BlockExpr &) override {} + void visit (HIR::ContinueExpr &) override {} + void visit (HIR::BreakExpr &) override {} + void visit (HIR::RangeFromToExpr &) override {} + void visit (HIR::RangeFromExpr &) override {} + void visit (HIR::RangeToExpr &) override {} + void visit (HIR::RangeFullExpr &) override {} + void visit (HIR::RangeFromToInclExpr &) override {} + void visit (HIR::RangeToInclExpr &) override {} + void visit (HIR::ReturnExpr &) override {} + void visit (HIR::UnsafeBlockExpr &) override {} + void visit (HIR::LoopExpr &) override {} + void visit (HIR::WhileLoopExpr &) override {} + void visit (HIR::WhileLetLoopExpr &) override {} + void visit (HIR::ForLoopExpr &) override {} + void visit (HIR::IfExpr &) override {} + void visit (HIR::IfExprConseqElse &) override {} + void visit (HIR::IfExprConseqIf &) override {} + void visit (HIR::IfExprConseqIfLet &) override {} + void visit (HIR::IfLetExpr &) override {} + void visit (HIR::IfLetExprConseqElse &) override {} + void visit (HIR::IfLetExprConseqIf &) override {} + void visit (HIR::IfLetExprConseqIfLet &) override {} + void visit (HIR::MatchExpr &) override {} + void visit (HIR::AwaitExpr &) override {} + void visit (HIR::AsyncBlockExpr &) override {} + private: CompileStructExprField (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc index 6de063b..21da9af 100644 --- a/gcc/rust/backend/rust-compile-type.cc +++ b/gcc/rust/backend/rust-compile-type.cc @@ -345,6 +345,13 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type) } void +TyTyResolveCompile::visit (const TyTy::SliceType &type) +{ + // TODO + gcc_unreachable (); +} + +void TyTyResolveCompile::visit (const TyTy::BoolType &type) { tree compiled_type = nullptr; diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h index 50598de..4f9c403 100644 --- a/gcc/rust/backend/rust-compile-type.h +++ b/gcc/rust/backend/rust-compile-type.h @@ -43,6 +43,7 @@ public: void visit (const TyTy::FnType &) override; void visit (const TyTy::FnPtr &) override; void visit (const TyTy::ArrayType &) override; + void visit (const TyTy::SliceType &) override; void visit (const TyTy::BoolType &) override; void visit (const TyTy::IntType &) override; void visit (const TyTy::UintType &) override; diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index 2e5a769..a3720f8 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -62,6 +62,8 @@ public: void visit (TyTy::ArrayType &) override { gcc_unreachable (); } + void visit (TyTy::SliceType &) override { gcc_unreachable (); } + void visit (TyTy::ReferenceType &) override { gcc_unreachable (); } void visit (TyTy::PointerType &) override { gcc_unreachable (); } diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h index c431edd..2dab39e 100644 --- a/gcc/rust/backend/rust-compile-var-decl.h +++ b/gcc/rust/backend/rust-compile-var-decl.h @@ -20,13 +20,17 @@ #define RUST_COMPILE_VAR_DECL #include "rust-compile-base.h" +#include "rust-hir-visitor.h" namespace Rust { namespace Compile { -class CompileVarDecl : public HIRCompileBase +class CompileVarDecl : public HIRCompileBase, + public HIR::HIRPatternVisitor, + public HIR::HIRStmtVisitor { - using Rust::Compile::HIRCompileBase::visit; + using HIR::HIRPatternVisitor::visit; + using HIR::HIRStmtVisitor::visit; public: static ::Bvariable *compile (tree fndecl, HIR::Stmt *stmt, Context *ctx) @@ -47,7 +51,8 @@ public: rust_assert (ok); translated_type = TyTyResolveCompile::compile (ctx, resolved_type); - stmt.get_pattern ()->accept_vis (*this); + stmt.get_pattern ()->accept_vis ( + static_cast<HIR::HIRPatternVisitor &> (*this)); } void visit (HIR::IdentifierPattern &pattern) override @@ -70,6 +75,44 @@ public: NULL /*decl_var*/, locus); } + // Empty visit for unused Pattern HIR nodes. + void visit (HIR::GroupedPattern &) override {} + void visit (HIR::LiteralPattern &) override {} + void visit (HIR::PathInExpression &) override {} + void visit (HIR::QualifiedPathInExpression &) override {} + void visit (HIR::RangePattern &) override {} + void visit (HIR::ReferencePattern &) override {} + void visit (HIR::SlicePattern &) override {} + void visit (HIR::StructPattern &) override {} + void visit (HIR::TuplePattern &) override {} + void visit (HIR::TupleStructPattern &) override {} + + // Empty visit for unused Stmt HIR nodes. + void visit (HIR::EnumItemTuple &) override {} + void visit (HIR::EnumItemStruct &) override {} + void visit (HIR::EnumItem &item) override {} + void visit (HIR::TupleStruct &tuple_struct) override {} + void visit (HIR::EnumItemDiscriminant &) override {} + void visit (HIR::TypePathSegmentFunction &segment) override {} + void visit (HIR::TypePath &path) override {} + void visit (HIR::QualifiedPathInType &path) override {} + void visit (HIR::Module &module) override {} + void visit (HIR::ExternCrate &crate) override {} + void visit (HIR::UseDeclaration &use_decl) override {} + void visit (HIR::Function &function) override {} + void visit (HIR::TypeAlias &type_alias) override {} + void visit (HIR::StructStruct &struct_item) override {} + void visit (HIR::Enum &enum_item) override {} + void visit (HIR::Union &union_item) override {} + void visit (HIR::ConstantItem &const_item) override {} + void visit (HIR::StaticItem &static_item) override {} + void visit (HIR::Trait &trait) override {} + void visit (HIR::ImplBlock &impl) override {} + void visit (HIR::ExternBlock &block) override {} + void visit (HIR::EmptyStmt &stmt) override {} + void visit (HIR::ExprStmtWithoutBlock &stmt) override {} + void visit (HIR::ExprStmtWithBlock &stmt) override {} + private: CompileVarDecl (Context *ctx, tree fndecl) : HIRCompileBase (ctx), fndecl (fndecl), translated_type (error_mark_node), diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index b7bbd32..ce0be92 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -18,8 +18,20 @@ #include "rust-macro-builtins.h" #include "rust-diagnostics.h" +#include "rust-expr.h" +#include "rust-session-manager.h" namespace Rust { +namespace { +std::unique_ptr<AST::Expr> +make_string (Location locus, std::string value) +{ + return std::unique_ptr<AST::Expr> ( + new AST::LiteralExpr (value, AST::Literal::STRING, + PrimitiveCoreType::CORETYPE_STR, {}, locus)); +} +} // namespace + AST::ASTFragment MacroBuiltin::assert (Location invoc_locus, AST::MacroInvocData &invoc) { @@ -27,4 +39,14 @@ MacroBuiltin::assert (Location invoc_locus, AST::MacroInvocData &invoc) return AST::ASTFragment::create_empty (); } + +AST::ASTFragment +MacroBuiltin::file (Location invoc_locus, AST::MacroInvocData &invoc) +{ + auto current_file + = Session::get_instance ().linemap->location_file (invoc_locus); + auto file_str = AST::SingleASTNode (make_string (invoc_locus, current_file)); + + return AST::ASTFragment ({file_str}); +} } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h index f279d39..ee42fe1 100644 --- a/gcc/rust/expand/rust-macro-builtins.h +++ b/gcc/rust/expand/rust-macro-builtins.h @@ -28,6 +28,9 @@ class MacroBuiltin public: static AST::ASTFragment assert (Location invoc_locus, AST::MacroInvocData &invoc); + + static AST::ASTFragment file (Location invoc_locus, + AST::MacroInvocData &invoc); }; } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 7552e82..a4ed36b 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -17,6 +17,7 @@ // <http://www.gnu.org/licenses/>. #include "rust-macro-expand.h" +#include "rust-macro-substitute-ctx.h" #include "rust-ast-full.h" #include "rust-ast-visitor.h" #include "rust-diagnostics.h" @@ -3773,8 +3774,10 @@ MacroExpander::transcribe_rule ( auto invoc_stream = invoc_token_tree.to_token_stream (); auto macro_rule_tokens = transcribe_tree.to_token_stream (); + auto substitute_context + = SubstituteCtx (invoc_stream, macro_rule_tokens, matched_fragments); std::vector<std::unique_ptr<AST::Token>> substituted_tokens - = substitute_tokens (invoc_stream, macro_rule_tokens, matched_fragments); + = substitute_context.substitute_tokens (); // // handy for debugging // for (auto &tok : substituted_tokens) @@ -3896,220 +3899,4 @@ MacroExpander::transcribe_rule ( return AST::ASTFragment (std::move (nodes)); } - -std::vector<std::unique_ptr<AST::Token>> -MacroExpander::substitute_metavar ( - std::vector<std::unique_ptr<AST::Token>> &input, - std::map<std::string, std::vector<MatchedFragment>> &fragments, - std::unique_ptr<AST::Token> &metavar) -{ - auto metavar_name = metavar->get_str (); - - std::vector<std::unique_ptr<AST::Token>> expanded; - auto it = fragments.find (metavar_name); - if (it == fragments.end ()) - { - // Return a copy of the original token - expanded.push_back (metavar->clone_token ()); - } - else - { - // Replace - // We only care about the vector when expanding repetitions. Just access - // the first element of the vector. - // FIXME: Clean this up so it makes more sense - auto &frag = it->second[0]; - for (size_t offs = frag.token_offset_begin; offs < frag.token_offset_end; - offs++) - { - auto &tok = input.at (offs); - expanded.push_back (tok->clone_token ()); - } - } - - return expanded; -} - -std::vector<std::unique_ptr<AST::Token>> -MacroExpander::substitute_repetition ( - std::vector<std::unique_ptr<AST::Token>> &input, - std::vector<std::unique_ptr<AST::Token>> ¯o, - std::map<std::string, std::vector<MatchedFragment>> &fragments, - size_t pattern_start, size_t pattern_end) -{ - rust_assert (pattern_end < macro.size ()); - - rust_debug ("pattern start: %lu", pattern_start); - rust_debug ("pattern end: %lu", pattern_end); - - std::vector<std::unique_ptr<AST::Token>> expanded; - - // Find the first fragment and get the amount of repetitions that we should - // perform - size_t repeat_amount = 0; - for (size_t i = pattern_start; i < pattern_end; i++) - { - if (macro.at (i)->get_id () == DOLLAR_SIGN) - { - auto &frag_token = macro.at (i + 1); - if (frag_token->get_id () == IDENTIFIER) - { - auto it = fragments.find (frag_token->get_str ()); - if (it == fragments.end ()) - { - // If the repetition is not anything we know (ie no declared - // metavars, or metavars which aren't present in the - // fragment), we can just error out. No need to paste the - // tokens as if nothing had happened. - rust_error_at (frag_token->get_locus (), - "metavar %s used in repetition does not exist", - frag_token->get_str ().c_str ()); - // FIXME: - return expanded; - } - - // FIXME: Refactor, ugly - repeat_amount = it->second[0].match_amount; - } - } - } - - rust_debug ("repetition amount to use: %lu", repeat_amount); - std::vector<std::unique_ptr<AST::Token>> new_macro; - - // We want to generate a "new macro" to substitute with. This new macro - // should contain only the tokens inside the pattern - for (size_t tok_idx = pattern_start; tok_idx < pattern_end; tok_idx++) - new_macro.emplace_back (macro.at (tok_idx)->clone_token ()); - - // Then, we want to create a subset of the matches so that - // `substitute_tokens()` can only see one fragment per metavar. Let's say we - // have the following user input: (1 145 'h') - // on the following match arm: ($($lit:literal)*) - // which causes the following matches: { "lit": [1, 145, 'h'] } - // - // The pattern (new_macro) is `$lit:literal` - // The first time we expand it, we want $lit to have the following token: 1 - // The second time, 145 - // The third and final time, 'h' - // - // In order to do so we must create "sub maps", which only contain parts of - // the original matches - // sub-maps: [ { "lit": 1 }, { "lit": 145 }, { "lit": 'h' } ] - // - // and give them to `substitute_tokens` one by one. - - for (size_t i = 0; i < repeat_amount; i++) - { - std::map<std::string, std::vector<MatchedFragment>> sub_map; - for (auto &kv_match : fragments) - { - std::vector<MatchedFragment> sub_vec; - sub_vec.emplace_back (kv_match.second[i]); - - sub_map.insert ({kv_match.first, sub_vec}); - } - - auto new_tokens = substitute_tokens (input, new_macro, sub_map); - - for (auto &new_token : new_tokens) - expanded.emplace_back (new_token->clone_token ()); - } - - // FIXME: We also need to make sure that all subsequent fragments - // contain the same amount of repetitions as the first one - - return expanded; -} - -std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t> -MacroExpander::substitute_token ( - std::vector<std::unique_ptr<AST::Token>> &input, - std::vector<std::unique_ptr<AST::Token>> ¯o, - std::map<std::string, std::vector<MatchedFragment>> &fragments, - size_t token_idx) -{ - auto &token = macro.at (token_idx); - switch (token->get_id ()) - { - case IDENTIFIER: - rust_debug ("expanding metavar: %s", token->get_str ().c_str ()); - return {substitute_metavar (input, fragments, token), 1}; - case LEFT_PAREN: { - // We need to parse up until the closing delimiter and expand this - // fragment->n times. - rust_debug ("expanding repetition"); - std::vector<std::unique_ptr<AST::Token>> repetition_pattern; - size_t pattern_start = token_idx + 1; - size_t pattern_end = pattern_start; - for (; pattern_end < macro.size () - && macro.at (pattern_end)->get_id () != RIGHT_PAREN; - pattern_end++) - ; - - // FIXME: This skips whitespaces... Is that okay?? - // FIXME: Is there any existing parsing function that allows us to parse - // a macro pattern? - - // FIXME: Add error handling in the case we haven't found a matching - // closing delimiter - - // FIXME: We need to parse the repetition token now - - return { - substitute_repetition (input, macro, fragments, pattern_start, - pattern_end), - // + 2 for the opening and closing parentheses which are mandatory - // + 1 for the repetitor (+, *, ?) - pattern_end - pattern_start + 3}; - } - // TODO: We need to check if the $ was alone. In that case, do - // not error out: Simply act as if there was an empty identifier - // with no associated fragment and paste the dollar sign in the - // transcription. Unsure how to do that since we always have at - // least the closing curly brace after an empty $... - default: - rust_error_at (token->get_locus (), - "unexpected token in macro transcribe: expected " - "%<(%> or identifier after %<$%>, got %<%s%>", - get_token_description (token->get_id ())); - } - - // FIXME: gcc_unreachable() error case? - return {std::vector<std::unique_ptr<AST::Token>> (), 0}; -} - -std::vector<std::unique_ptr<AST::Token>> -MacroExpander::substitute_tokens ( - std::vector<std::unique_ptr<AST::Token>> &input, - std::vector<std::unique_ptr<AST::Token>> ¯o, - std::map<std::string, std::vector<MatchedFragment>> &fragments) -{ - std::vector<std::unique_ptr<AST::Token>> replaced_tokens; - - for (size_t i = 0; i < macro.size (); i++) - { - auto &tok = macro.at (i); - if (tok->get_id () == DOLLAR_SIGN) - { - // Aaaaah, if only we had C++17 :) - // auto [expanded, tok_to_skip] = ... - auto p = substitute_token (input, macro, fragments, i + 1); - auto expanded = std::move (p.first); - auto tok_to_skip = p.second; - - i += tok_to_skip; - - for (auto &token : expanded) - replaced_tokens.emplace_back (token->clone_token ()); - } - else - { - replaced_tokens.emplace_back (tok->clone_token ()); - } - } - - return replaced_tokens; -} - } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h index eeafdb8..9309323 100644 --- a/gcc/rust/expand/rust-macro-expand.h +++ b/gcc/rust/expand/rust-macro-expand.h @@ -213,64 +213,6 @@ struct MacroExpander size_t &match_amount, size_t lo_bound = 0, size_t hi_bound = 0); - /** - * Substitute a metavariable by its given fragment in a transcribing context, - * i.e. replacing $var with the associated fragment. - * - * @param input Tokens given to the transcribing context - * @param fragments Fragments given to the macro substitution - * @param metavar Metavariable to try and replace - * - * @return A token containing the associated fragment expanded into tokens if - * any, or the cloned token if no fragment was associated - */ - static std::vector<std::unique_ptr<AST::Token>> substitute_metavar ( - std::vector<std::unique_ptr<AST::Token>> &input, - std::map<std::string, std::vector<MatchedFragment>> &fragments, - std::unique_ptr<AST::Token> &metavar); - - /** - * Substitute a macro repetition by its given fragments - * - * @param input Tokens given to the transcribing context - * @param fragments Fragments given to the macro substitution - * @param pattern_start Start index of the pattern tokens - * @param pattern_end Index Amount of tokens in the pattern - * - * @return A vector containing the repeated pattern - */ - static std::vector<std::unique_ptr<AST::Token>> substitute_repetition ( - std::vector<std::unique_ptr<AST::Token>> &input, - std::vector<std::unique_ptr<AST::Token>> ¯o, - std::map<std::string, std::vector<MatchedFragment>> &fragments, - size_t pattern_start, size_t pattern_end); - - /** - * Substitute a given token by its appropriate representation - * - * @param macro Tokens used in the macro declaration - * @param input Tokens given to the transcribing context - * @param fragments Fragments given to the macro substitution - * @param token Current token to try and substitute - * - * @return A token containing the associated fragment expanded into tokens if - * any, or the cloned token if no fragment was associated, as well as the - * amount of tokens that should be skipped before the next invocation. Since - * this function may consume more than just one token, it is important to skip - * ahead of the input to avoid mis-substitutions - */ - static std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t> - substitute_token ( - std::vector<std::unique_ptr<AST::Token>> &input, - std::vector<std::unique_ptr<AST::Token>> ¯o, - std::map<std::string, std::vector<MatchedFragment>> &fragments, - size_t token_idx); - - static std::vector<std::unique_ptr<AST::Token>> substitute_tokens ( - std::vector<std::unique_ptr<AST::Token>> &input, - std::vector<std::unique_ptr<AST::Token>> ¯o, - std::map<std::string, std::vector<MatchedFragment>> &fragments); - void push_context (ContextType t) { context.push_back (t); } ContextType pop_context () diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc new file mode 100644 index 0000000..8542614 --- /dev/null +++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc @@ -0,0 +1,206 @@ +#include "rust-macro-substitute-ctx.h" + +namespace Rust { + +std::vector<std::unique_ptr<AST::Token>> +SubstituteCtx::substitute_metavar (std::unique_ptr<AST::Token> &metavar) +{ + auto metavar_name = metavar->get_str (); + + std::vector<std::unique_ptr<AST::Token>> expanded; + auto it = fragments.find (metavar_name); + if (it == fragments.end ()) + { + // Return a copy of the original token + expanded.push_back (metavar->clone_token ()); + } + else + { + // Replace + // We only care about the vector when expanding repetitions. Just access + // the first element of the vector. + // FIXME: Clean this up so it makes more sense + auto &frag = it->second[0]; + for (size_t offs = frag.token_offset_begin; offs < frag.token_offset_end; + offs++) + { + auto &tok = input.at (offs); + expanded.push_back (tok->clone_token ()); + } + } + + return expanded; +} + +std::vector<std::unique_ptr<AST::Token>> +SubstituteCtx::substitute_repetition (size_t pattern_start, size_t pattern_end) +{ + rust_assert (pattern_end < macro.size ()); + + rust_debug ("pattern start: %lu", pattern_start); + rust_debug ("pattern end: %lu", pattern_end); + + std::vector<std::unique_ptr<AST::Token>> expanded; + + // Find the first fragment and get the amount of repetitions that we should + // perform + size_t repeat_amount = 0; + for (size_t i = pattern_start; i < pattern_end; i++) + { + if (macro.at (i)->get_id () == DOLLAR_SIGN) + { + auto &frag_token = macro.at (i + 1); + if (frag_token->get_id () == IDENTIFIER) + { + auto it = fragments.find (frag_token->get_str ()); + if (it == fragments.end ()) + { + // If the repetition is not anything we know (ie no declared + // metavars, or metavars which aren't present in the + // fragment), we can just error out. No need to paste the + // tokens as if nothing had happened. + rust_error_at (frag_token->get_locus (), + "metavar %s used in repetition does not exist", + frag_token->get_str ().c_str ()); + // FIXME: + return expanded; + } + + // FIXME: Refactor, ugly + repeat_amount = it->second[0].match_amount; + } + } + } + + rust_debug ("repetition amount to use: %lu", repeat_amount); + std::vector<std::unique_ptr<AST::Token>> new_macro; + + // We want to generate a "new macro" to substitute with. This new macro + // should contain only the tokens inside the pattern + for (size_t tok_idx = pattern_start; tok_idx < pattern_end; tok_idx++) + new_macro.emplace_back (macro.at (tok_idx)->clone_token ()); + + // Then, we want to create a subset of the matches so that + // `substitute_tokens()` can only see one fragment per metavar. Let's say we + // have the following user input: (1 145 'h') + // on the following match arm: ($($lit:literal)*) + // which causes the following matches: { "lit": [1, 145, 'h'] } + // + // The pattern (new_macro) is `$lit:literal` + // The first time we expand it, we want $lit to have the following token: 1 + // The second time, 145 + // The third and final time, 'h' + // + // In order to do so we must create "sub maps", which only contain parts of + // the original matches + // sub-maps: [ { "lit": 1 }, { "lit": 145 }, { "lit": 'h' } ] + // + // and give them to `substitute_tokens` one by one. + + for (size_t i = 0; i < repeat_amount; i++) + { + std::map<std::string, std::vector<MatchedFragment>> sub_map; + for (auto &kv_match : fragments) + { + std::vector<MatchedFragment> sub_vec; + sub_vec.emplace_back (kv_match.second[i]); + + sub_map.insert ({kv_match.first, sub_vec}); + } + + auto substitute_context = SubstituteCtx (input, new_macro, sub_map); + auto new_tokens = substitute_context.substitute_tokens (); + + for (auto &new_token : new_tokens) + expanded.emplace_back (new_token->clone_token ()); + } + + // FIXME: We also need to make sure that all subsequent fragments + // contain the same amount of repetitions as the first one + + return expanded; +} + +std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t> +SubstituteCtx::substitute_token (size_t token_idx) +{ + auto &token = macro.at (token_idx); + switch (token->get_id ()) + { + case IDENTIFIER: + rust_debug ("expanding metavar: %s", token->get_str ().c_str ()); + return {substitute_metavar (token), 1}; + case LEFT_PAREN: { + // We need to parse up until the closing delimiter and expand this + // fragment->n times. + rust_debug ("expanding repetition"); + std::vector<std::unique_ptr<AST::Token>> repetition_pattern; + size_t pattern_start = token_idx + 1; + size_t pattern_end = pattern_start; + for (; pattern_end < macro.size () + && macro.at (pattern_end)->get_id () != RIGHT_PAREN; + pattern_end++) + ; + + // FIXME: This skips whitespaces... Is that okay?? + // FIXME: Is there any existing parsing function that allows us to parse + // a macro pattern? + + // FIXME: Add error handling in the case we haven't found a matching + // closing delimiter + + // FIXME: We need to parse the repetition token now + + return { + substitute_repetition (pattern_start, pattern_end), + // + 2 for the opening and closing parentheses which are mandatory + // + 1 for the repetitor (+, *, ?) + pattern_end - pattern_start + 3}; + } + // TODO: We need to check if the $ was alone. In that case, do + // not error out: Simply act as if there was an empty identifier + // with no associated fragment and paste the dollar sign in the + // transcription. Unsure how to do that since we always have at + // least the closing curly brace after an empty $... + default: + rust_error_at (token->get_locus (), + "unexpected token in macro transcribe: expected " + "%<(%> or identifier after %<$%>, got %<%s%>", + get_token_description (token->get_id ())); + } + + // FIXME: gcc_unreachable() error case? + return {std::vector<std::unique_ptr<AST::Token>> (), 0}; +} + +std::vector<std::unique_ptr<AST::Token>> +SubstituteCtx::substitute_tokens () +{ + std::vector<std::unique_ptr<AST::Token>> replaced_tokens; + + for (size_t i = 0; i < macro.size (); i++) + { + auto &tok = macro.at (i); + if (tok->get_id () == DOLLAR_SIGN) + { + // Aaaaah, if only we had C++17 :) + // auto [expanded, tok_to_skip] = ... + auto p = substitute_token (i + 1); + auto expanded = std::move (p.first); + auto tok_to_skip = p.second; + + i += tok_to_skip; + + for (auto &token : expanded) + replaced_tokens.emplace_back (token->clone_token ()); + } + else + { + replaced_tokens.emplace_back (tok->clone_token ()); + } + } + + return replaced_tokens; +} + +} // namespace Rust diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.h b/gcc/rust/expand/rust-macro-substitute-ctx.h new file mode 100644 index 0000000..d51fb81 --- /dev/null +++ b/gcc/rust/expand/rust-macro-substitute-ctx.h @@ -0,0 +1,80 @@ +// Copyright (C) 2020-2022 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include "rust-ast.h" +#include "rust-macro-expand.h" + +namespace Rust { +class SubstituteCtx +{ + std::vector<std::unique_ptr<AST::Token>> &input; + std::vector<std::unique_ptr<AST::Token>> ¯o; + std::map<std::string, std::vector<MatchedFragment>> &fragments; + +public: + SubstituteCtx (std::vector<std::unique_ptr<AST::Token>> &input, + std::vector<std::unique_ptr<AST::Token>> ¯o, + std::map<std::string, std::vector<MatchedFragment>> &fragments) + : input (input), macro (macro), fragments (fragments) + {} + + /** + * Substitute a metavariable by its given fragment in a transcribing context, + * i.e. replacing $var with the associated fragment. + * + * @param metavar Metavariable to try and replace + * + * @return A token containing the associated fragment expanded into tokens if + * any, or the cloned token if no fragment was associated + */ + std::vector<std::unique_ptr<AST::Token>> + substitute_metavar (std::unique_ptr<AST::Token> &metavar); + + /** + * Substitute a macro repetition by its given fragments + * + * @param pattern_start Start index of the pattern tokens + * @param pattern_end Index Amount of tokens in the pattern + * + * @return A vector containing the repeated pattern + */ + std::vector<std::unique_ptr<AST::Token>> + substitute_repetition (size_t pattern_start, size_t pattern_end); + + /** + * Substitute a given token by its appropriate representation + * + * @param token_idx Current token to try and substitute + * + * @return A token containing the associated fragment expanded into tokens if + * any, or the cloned token if no fragment was associated, as well as the + * amount of tokens that should be skipped before the next invocation. Since + * this function may consume more than just one token, it is important to skip + * ahead of the input to avoid mis-substitutions + */ + std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t> + substitute_token (size_t token_idx); + + /** + * Substitute all tokens by their appropriate representation + * + * @return A vector containing the substituted tokens + */ + std::vector<std::unique_ptr<AST::Token>> substitute_tokens (); +}; +} // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index a8048bb..df836fc 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -728,6 +728,85 @@ public: expr.get_outer_attrs (), expr.get_locus ()); } + void visit (AST::RangeFromToExpr &expr) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + HIR::Expr *range_from + = ASTLoweringExpr::translate (expr.get_from_expr ().get ()); + HIR::Expr *range_to + = ASTLoweringExpr::translate (expr.get_to_expr ().get ()); + + translated + = new HIR::RangeFromToExpr (mapping, + std::unique_ptr<HIR::Expr> (range_from), + std::unique_ptr<HIR::Expr> (range_to), + expr.get_locus ()); + } + + void visit (AST::RangeFromExpr &expr) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + HIR::Expr *range_from + = ASTLoweringExpr::translate (expr.get_from_expr ().get ()); + + translated + = new HIR::RangeFromExpr (mapping, + std::unique_ptr<HIR::Expr> (range_from), + expr.get_locus ()); + } + + void visit (AST::RangeToExpr &expr) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + HIR::Expr *range_to + = ASTLoweringExpr::translate (expr.get_to_expr ().get ()); + + translated + = new HIR::RangeToExpr (mapping, std::unique_ptr<HIR::Expr> (range_to), + expr.get_locus ()); + } + + void visit (AST::RangeFullExpr &expr) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated = new HIR::RangeFullExpr (mapping, expr.get_locus ()); + } + + void visit (AST::RangeFromToInclExpr &expr) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + HIR::Expr *range_from + = ASTLoweringExpr::translate (expr.get_from_expr ().get ()); + HIR::Expr *range_to + = ASTLoweringExpr::translate (expr.get_to_expr ().get ()); + + translated + = new HIR::RangeFromToInclExpr (mapping, + std::unique_ptr<HIR::Expr> (range_from), + std::unique_ptr<HIR::Expr> (range_to), + expr.get_locus ()); + } + private: ASTLoweringExpr () : ASTLoweringBase (), translated (nullptr), diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index b8d3354..40c9fef 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -97,6 +97,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Literal &get_literal () { return literal; } const Literal &get_literal () const { return literal; } @@ -198,6 +199,7 @@ public: {} void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Mutability get_mut () const { return mut; } bool is_mut () const { return mut == Mutability::Mut; } @@ -234,6 +236,7 @@ public: {} void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -266,6 +269,7 @@ public: {} void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -310,6 +314,7 @@ public: {} void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -378,6 +383,7 @@ public: = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); } void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); } @@ -452,6 +458,7 @@ public: ComparisonExpr &operator= (ComparisonExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Expr *get_lhs () { return main_or_left_expr.get (); } Expr *get_rhs () { return right_expr.get (); } @@ -525,6 +532,7 @@ public: ExprType get_expr_type () const { return expr_type; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Expr *get_lhs () { return main_or_left_expr.get (); } @@ -586,6 +594,7 @@ public: TypeCastExpr &operator= (TypeCastExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_casted_expr () { @@ -654,6 +663,7 @@ public: AssignmentExpr &operator= (AssignmentExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); } void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); } @@ -726,6 +736,7 @@ public: CompoundAssignmentExpr &operator= (CompoundAssignmentExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_left_expr () { @@ -798,6 +809,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_expr_in_parens () { @@ -1018,6 +1030,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; ArrayElems *get_internal_elements () { return internal_elements.get (); }; @@ -1083,6 +1096,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Expr *get_array_expr () { return array_expr.get (); } Expr *get_index_expr () { return index_expr.get (); } @@ -1166,6 +1180,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; const std::vector<std::unique_ptr<Expr> > &get_tuple_elems () const { @@ -1239,6 +1254,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_tuple_expr () { @@ -1315,6 +1331,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -1395,6 +1412,7 @@ public: virtual std::string as_string () const = 0; virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRExpressionVisitor &vis) = 0; Analysis::NodeMapping &get_mappings () { return mappings; } @@ -1429,6 +1447,7 @@ public: std::string as_string () const override { return field_name; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Identifier get_field_name () const { return field_name; } @@ -1498,6 +1517,7 @@ public: std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -1525,10 +1545,11 @@ public: std::string as_string () const override; - void accept_vis (HIRFullVisitor &vis) override; - TupleIndex get_tuple_index () const { return index; }; + void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -1598,6 +1619,7 @@ public: StructExprStructFields &operator= (StructExprStructFields &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::vector<std::unique_ptr<StructExprField> > &get_fields () { @@ -1654,6 +1676,8 @@ public: {} void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + StructBase *get_struct_base () { return &struct_base; } protected: @@ -1726,6 +1750,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Expr *get_fnexpr () { return function.get (); } @@ -1812,6 +1837,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_receiver () { return receiver; } @@ -1893,6 +1919,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_receiver_expr () { @@ -2044,6 +2071,7 @@ public: ClosureExprInner &operator= (ClosureExprInner &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -2144,6 +2172,7 @@ public: Location get_end_locus () const { return end_locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; } @@ -2226,6 +2255,7 @@ public: ClosureExprInnerTyped &operator= (ClosureExprInnerTyped &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -2265,6 +2295,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Lifetime &get_label () { return label; } @@ -2348,6 +2379,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Lifetime &get_label () { return label; } @@ -2429,6 +2461,10 @@ public: RangeFromToExpr &operator= (RangeFromToExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + + std::unique_ptr<Expr> &get_from_expr () { return from; } + std::unique_ptr<Expr> &get_to_expr () { return to; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2479,6 +2515,9 @@ public: RangeFromExpr &operator= (RangeFromExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + + std::unique_ptr<Expr> &get_from_expr () { return from; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2530,6 +2569,9 @@ public: RangeToExpr &operator= (RangeToExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + + std::unique_ptr<Expr> &get_to_expr () { return to; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2560,6 +2602,7 @@ public: // outer attributes not allowed void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -2616,6 +2659,10 @@ public: RangeFromToInclExpr &operator= (RangeFromToInclExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + + std::unique_ptr<Expr> &get_from_expr () { return from; } + std::unique_ptr<Expr> &get_to_expr () { return to; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2667,6 +2714,7 @@ public: RangeToInclExpr &operator= (RangeToInclExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -2733,6 +2781,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; Expr *get_expr () { return return_expr.get (); } @@ -2798,6 +2847,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<BlockExpr> &get_block_expr () { return expr; } @@ -2922,6 +2972,7 @@ public: {} void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -2977,6 +3028,7 @@ public: WhileLoopExpr &operator= (WhileLoopExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_predicate_expr () { return condition; } @@ -3052,6 +3104,7 @@ public: WhileLetLoopExpr &operator= (WhileLetLoopExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_cond () { return condition; } @@ -3117,6 +3170,7 @@ public: ForLoopExpr &operator= (ForLoopExpr &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_iterator_expr () { return iterator_expr; } @@ -3192,6 +3246,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; void vis_if_condition (HIRFullVisitor &vis) { condition->accept_vis (vis); } void vis_if_block (HIRFullVisitor &vis) { if_block->accept_vis (vis); } @@ -3256,6 +3311,7 @@ public: IfExprConseqElse &operator= (IfExprConseqElse &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); } @@ -3323,6 +3379,7 @@ public: IfExprConseqIf &operator= (IfExprConseqIf &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; void vis_conseq_if_expr (HIRFullVisitor &vis) { @@ -3418,6 +3475,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; ExprType get_expression_type () const final override { @@ -3483,6 +3541,7 @@ public: IfExprConseqIfLet &operator= (IfExprConseqIfLet &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -3550,6 +3609,7 @@ public: IfLetExprConseqElse &operator= (IfLetExprConseqElse &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -3616,6 +3676,7 @@ public: IfLetExprConseqIf &operator= (IfLetExprConseqIf &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -3682,6 +3743,7 @@ public: IfLetExprConseqIfLet &operator= (IfLetExprConseqIfLet &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -3882,6 +3944,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; std::unique_ptr<Expr> &get_scrutinee_expr () { @@ -3949,6 +4012,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; ExprType get_expression_type () const final override { @@ -4005,6 +4069,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; ExprType get_expression_type () const final override { @@ -4019,6 +4084,40 @@ protected: return new AsyncBlockExpr (*this); } }; + +// this is a utility helper class for type-checking and code-generation +class OperatorExprMeta +{ +public: + OperatorExprMeta (HIR::CompoundAssignmentExpr &expr) + : node_mappings (expr.get_mappings ()), locus (expr.get_locus ()) + {} + + OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr) + : node_mappings (expr.get_mappings ()), locus (expr.get_locus ()) + {} + + OperatorExprMeta (HIR::NegationExpr &expr) + : node_mappings (expr.get_mappings ()), locus (expr.get_locus ()) + {} + + OperatorExprMeta (HIR::DereferenceExpr &expr) + : node_mappings (expr.get_mappings ()), locus (expr.get_locus ()) + {} + + OperatorExprMeta (HIR::ArrayIndexExpr &expr) + : node_mappings (expr.get_mappings ()), locus (expr.get_locus ()) + {} + + const Analysis::NodeMapping &get_mappings () const { return node_mappings; } + + Location get_locus () const { return locus; } + +private: + const Analysis::NodeMapping node_mappings; + Location locus; +}; + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc index 9314c1d..3f3f484 100644 --- a/gcc/rust/hir/tree/rust-hir-full-test.cc +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -3749,6 +3749,8 @@ Module::add_crate_name (std::vector<std::string> &names) const item->add_crate_name (names); } +/* All accept_vis method below */ + void IdentifierExpr::accept_vis (HIRFullVisitor &vis) { @@ -3756,6 +3758,12 @@ IdentifierExpr::accept_vis (HIRFullVisitor &vis) } void +IdentifierExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void Lifetime::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); @@ -3772,6 +3780,11 @@ PathInExpression::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } +void +PathInExpression::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} void TypePathSegment::accept_vis (HIRFullVisitor &vis) @@ -3802,6 +3815,11 @@ QualifiedPathInExpression::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } +void +QualifiedPathInExpression::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} void QualifiedPathInType::accept_vis (HIRFullVisitor &vis) @@ -3816,121 +3834,181 @@ LiteralExpr::accept_vis (HIRFullVisitor &vis) } void +LiteralExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void BorrowExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void +BorrowExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void DereferenceExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void +DereferenceExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void ErrorPropagationExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void +ErrorPropagationExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void NegationExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void +NegationExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void ArithmeticOrLogicalExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void +ArithmeticOrLogicalExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void ComparisonExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void +ComparisonExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void LazyBooleanExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void +LazyBooleanExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void TypeCastExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void +TypeCastExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void AssignmentExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void +AssignmentExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void CompoundAssignmentExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -GroupedExpr::accept_vis (HIRFullVisitor &vis) +CompoundAssignmentExpr::accept_vis (HIRExpressionVisitor &vis) { vis.visit (*this); } void -ArrayElemsValues::accept_vis (HIRFullVisitor &vis) +GroupedExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -ArrayElemsCopied::accept_vis (HIRFullVisitor &vis) +GroupedExpr::accept_vis (HIRExpressionVisitor &vis) { vis.visit (*this); } void -ArrayExpr::accept_vis (HIRFullVisitor &vis) +ArrayElemsValues::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -ArrayIndexExpr::accept_vis (HIRFullVisitor &vis) +ArrayElemsCopied::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -TupleExpr::accept_vis (HIRFullVisitor &vis) +ArrayExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -TupleIndexExpr::accept_vis (HIRFullVisitor &vis) +ArrayIndexExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -StructExprStruct::accept_vis (HIRFullVisitor &vis) +TupleExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -StructExprFieldIdentifier::accept_vis (HIRFullVisitor &vis) +TupleIndexExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -StructExprFieldIdentifierValue::accept_vis (HIRFullVisitor &vis) +StructExprStruct::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } @@ -4121,56 +4199,56 @@ IfLetExprConseqIfLet::accept_vis (HIRFullVisitor &vis) vis.visit (*this); } -/*void -MatchCaseBlockExpr::accept_vis (HIRFullVisitor &vis) +void +MatchExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -MatchCaseExpr::accept_vis (HIRFullVisitor &vis) +AwaitExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); -}*/ +} void -MatchExpr::accept_vis (HIRFullVisitor &vis) +AsyncBlockExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -AwaitExpr::accept_vis (HIRFullVisitor &vis) +TypeParam::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -AsyncBlockExpr::accept_vis (HIRFullVisitor &vis) +LifetimeWhereClauseItem::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -TypeParam::accept_vis (HIRFullVisitor &vis) +TypeBoundWhereClauseItem::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -LifetimeWhereClauseItem::accept_vis (HIRFullVisitor &vis) +Module::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); } void -TypeBoundWhereClauseItem::accept_vis (HIRFullVisitor &vis) +Module::accept_vis (HIRStmtVisitor &vis) { vis.visit (*this); } void -Module::accept_vis (HIRFullVisitor &vis) +Module::accept_vis (HIRVisItemVisitor &vis) { vis.visit (*this); } @@ -4547,5 +4625,665 @@ BareFunctionType::accept_vis (HIRFullVisitor &vis) vis.visit (*this); } +void +NeverType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ParenthesisedType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +EmptyStmt::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +GroupedPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +WildcardPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitItemType::accept_vis (HIRTraitItemVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitItemConst::accept_vis (HIRTraitItemVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitItemFunc::accept_vis (HIRTraitItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternalFunctionItem::accept_vis (HIRExternalItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternalStaticItem::accept_vis (HIRExternalItemVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItemDiscriminant::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItemStruct::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItemTuple::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItem::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprStructFields::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIndexValue::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIdentifierValue::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIdentifierValue::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIdentifier::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIdentifier::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprStruct::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +SliceType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplTraitTypeOneBound::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +BareFunctionType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitObjectType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +RawPointerType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ReferenceType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplTraitType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +InferredType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +LetStmt::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStructPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +IdentifierPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +ReferencePattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +LiteralPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +StructPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +TuplePattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +SlicePattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +RangePattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +ForLoopExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePath::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +QualifiedPathInType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ExprStmtWithoutBlock::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +MatchExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +BreakExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +AwaitExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +LoopExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +WhileLetLoopExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +WhileLoopExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +CallExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFromToInclExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExprConseqIfLet::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExprConseqIf::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExprConseqElse::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExprConseqIfLet::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExprConseqIf::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExprConseqElse::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ClosureExprInner::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +UnsafeBlockExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeToInclExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFromToExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +FieldAccessExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleIndexExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +MethodCallExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +AsyncBlockExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayIndexExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFullExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFromExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ContinueExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeToExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ReturnExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +QualifiedPathInExpression::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +ClosureExprInnerTyped::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ExprStmtWithBlock::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +PathInExpression::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternBlock::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternBlock::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeAlias::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeAlias::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeAlias::accept_vis (HIRImplVisitor &vis) +{ + vis.visit (*this); +} + +void +BlockExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +Function::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +Function::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +Function::accept_vis (HIRImplVisitor &vis) +{ + vis.visit (*this); +} + +void +Union::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +Union::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +Trait::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +Trait::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +Enum::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +Enum::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +UseDeclaration::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +UseDeclaration::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +StructStruct::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +StructStruct::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplBlock::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplBlock::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstantItem::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstantItem::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstantItem::accept_vis (HIRImplVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStruct::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStruct::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternCrate::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternCrate::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +StaticItem::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +StaticItem::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index ffde1ca..54ba7d5 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -677,10 +677,14 @@ protected: VisItem &operator= (VisItem &&other) = default; public: + using HIR::Stmt::accept_vis; + /* Does the item have some kind of public visibility (non-default * visibility)? */ bool has_visibility () const { return !visibility.is_error (); } + virtual void accept_vis (HIRVisItemVisitor &vis) = 0; + Visibility &get_visibility () { return visibility; } std::string as_string () const override; @@ -744,6 +748,8 @@ public: Module &operator= (Module &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; std::vector<std::unique_ptr<Item>> &get_items () { return items; }; @@ -804,6 +810,8 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; // Override that adds extern crate name in decl to passed list of names. void add_crate_name (std::vector<std::string> &names) const override @@ -1069,6 +1077,8 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object @@ -1181,6 +1191,9 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRImplVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; Analysis::NodeMapping get_impl_mappings () const override { @@ -1318,6 +1331,9 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRImplVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; std::vector<std::unique_ptr<GenericParam>> &get_generic_params () { @@ -1541,6 +1557,8 @@ public: bool is_unit_struct () const { return is_unit; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; std::vector<StructField> &get_fields () { return fields; } @@ -1649,6 +1667,8 @@ public: {} void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; std::vector<TupleField> &get_fields () { return fields; } const std::vector<TupleField> &get_fields () const { return fields; } @@ -1696,7 +1716,9 @@ public: virtual std::string as_string () const override; // not pure virtual as not abstract - virtual void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + // void accept_vis (HIRVisItemVisitor &vis) override; Location get_locus () const override { return locus; } @@ -1727,6 +1749,7 @@ public: std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; std::vector<TupleField> &get_tuple_fields () { return tuple_fields; } @@ -1759,6 +1782,7 @@ public: std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; std::vector<StructField> &get_struct_fields () { return struct_fields; } @@ -1807,6 +1831,7 @@ public: std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; std::unique_ptr<Expr> &get_discriminant_expression () { return expression; } @@ -1901,6 +1926,8 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; Identifier get_identifier () const { return enum_name; } @@ -2003,6 +2030,8 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; std::vector<StructField> &get_variants () { return variants; } @@ -2062,6 +2091,9 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRImplVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; Type *get_type () { return type.get (); } @@ -2143,6 +2175,8 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; Identifier get_identifier () const { return name; } @@ -2311,6 +2345,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTraitItemVisitor &vis) override; TraitFunctionDecl &get_decl () { return decl; } @@ -2396,6 +2431,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTraitItemVisitor &vis) override; Identifier get_name () const { return name; } @@ -2481,6 +2517,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTraitItemVisitor &vis) override; Identifier get_name () const { return name; } @@ -2601,6 +2638,8 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; std::vector<std::unique_ptr<GenericParam>> &get_generic_params () { @@ -2699,6 +2738,8 @@ public: bool has_impl_items () const { return !impl_items.empty (); } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; std::vector<std::unique_ptr<ImplItem>> &get_impl_items () { @@ -2774,6 +2815,7 @@ public: Location get_locus () const { return locus; } virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRExternalItemVisitor &vis) = 0; Analysis::NodeMapping get_mappings () const { return mappings; } @@ -2852,6 +2894,7 @@ public: std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExternalItemVisitor &vis) override; bool is_mut () const { return mut == Mutability::Mut; } @@ -2994,6 +3037,7 @@ public: std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExternalItemVisitor &vis) override; std::vector<std::unique_ptr<GenericParam>> &get_generic_params () { @@ -3087,6 +3131,8 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; + void accept_vis (HIRVisItemVisitor &vis) override; std::vector<std::unique_ptr<ExternalItem>> &get_extern_items () { diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index cbbf93c..9858ba3 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -323,6 +323,8 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; bool opening_scope_resolution () { return has_opening_scope_resolution; } @@ -706,6 +708,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; size_t get_num_segments () const { return segments.size (); } @@ -829,6 +832,8 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; QualifiedPathType &get_path_type () { return path_type; } @@ -927,6 +932,7 @@ public: std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; QualifiedPathType &get_path_type () { return path_type; } diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h index 2d9c5fb..de4a83e 100644 --- a/gcc/rust/hir/tree/rust-hir-pattern.h +++ b/gcc/rust/hir/tree/rust-hir-pattern.h @@ -52,6 +52,7 @@ public: Location get_locus () const override { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; Analysis::NodeMapping get_pattern_mappings () const override final { @@ -132,6 +133,7 @@ public: bool is_mut () const { return mut == Mutability::Mut; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; Analysis::NodeMapping get_pattern_mappings () const override final { @@ -170,6 +172,7 @@ public: Location get_locus () const override { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; Analysis::NodeMapping get_pattern_mappings () const override final { @@ -353,6 +356,7 @@ public: Location get_locus () const override { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; Analysis::NodeMapping get_pattern_mappings () const override final { @@ -418,6 +422,7 @@ public: bool is_mut () const { return mut == Mutability::Mut; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; Analysis::NodeMapping get_pattern_mappings () const override final { @@ -699,6 +704,7 @@ public: Location get_locus () const override { return path.get_locus (); } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; PathInExpression &get_path () { return path; } StructPatternElements &get_struct_pattern_elems () { return elems; } @@ -927,6 +933,7 @@ public: Location get_locus () const override { return path.get_locus (); } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; PathInExpression &get_path () { return path; } @@ -1116,6 +1123,7 @@ public: Location get_locus () const override { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; Analysis::NodeMapping get_pattern_mappings () const override final { @@ -1178,6 +1186,7 @@ public: Location get_locus () const override { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; Analysis::NodeMapping get_pattern_mappings () const override final { @@ -1242,6 +1251,7 @@ public: Location get_locus () const override { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRPatternVisitor &vis) override; Analysis::NodeMapping get_pattern_mappings () const override final { diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h index 43be744..54d3e21 100644 --- a/gcc/rust/hir/tree/rust-hir-stmt.h +++ b/gcc/rust/hir/tree/rust-hir-stmt.h @@ -40,6 +40,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; bool is_item () const override final { return false; } @@ -114,6 +115,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; HIR::Type *get_type () { return type.get (); } @@ -181,6 +183,7 @@ public: ExprStmtWithoutBlock &operator= (ExprStmtWithoutBlock &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; Expr *get_expr () { return expr.get (); } @@ -228,6 +231,7 @@ public: ExprStmtWithBlock &operator= (ExprStmtWithBlock &&other) = default; void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRStmtVisitor &vis) override; ExprWithBlock *get_expr () { return expr.get (); } diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h index 6e5e221..8692dfd 100644 --- a/gcc/rust/hir/tree/rust-hir-type.h +++ b/gcc/rust/hir/tree/rust-hir-type.h @@ -139,6 +139,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; }; // An opaque value of another type that implements a set of traits @@ -196,6 +197,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () { @@ -275,6 +277,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; }; // Impl trait with a single bound? Poor reference material here. @@ -311,6 +314,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; }; class TypePath; // definition moved to "rust-path.h" @@ -362,6 +366,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; std::vector<std::unique_ptr<Type> > &get_elems () { return elems; } const std::vector<std::unique_ptr<Type> > &get_elems () const @@ -411,6 +416,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; }; // A type consisting of a pointer without safety or liveness guarantees @@ -453,6 +459,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; std::unique_ptr<Type> &get_type () { return type; } @@ -532,6 +539,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; Lifetime &get_lifetime () { return lifetime; } @@ -598,6 +606,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; Type *get_element_type () { return elem_type.get (); } @@ -657,6 +666,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object rather @@ -703,6 +713,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; }; class QualifiedPathInType; // definition moved to "rust-path.h" @@ -845,6 +856,7 @@ public: Location get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRTypeVisitor &vis) override; std::vector<MaybeNamedParam> &get_function_params () { return params; } const std::vector<MaybeNamedParam> &get_function_params () const diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h index 4ac7c63..42cc1ab 100644 --- a/gcc/rust/hir/tree/rust-hir-visitor.h +++ b/gcc/rust/hir/tree/rust-hir-visitor.h @@ -315,6 +315,179 @@ public: virtual void visit (BareFunctionType &) override {} }; +class HIRExternalItemVisitor +{ +public: + virtual void visit (ExternalStaticItem &item) = 0; + virtual void visit (ExternalFunctionItem &item) = 0; +}; + +class HIRTraitItemVisitor +{ +public: + virtual void visit (TraitItemFunc &item) = 0; + virtual void visit (TraitItemConst &item) = 0; + virtual void visit (TraitItemType &item) = 0; +}; + +class HIRVisItemVisitor +{ +public: + virtual void visit (Module &module) = 0; + virtual void visit (ExternCrate &crate) = 0; + virtual void visit (UseDeclaration &use_decl) = 0; + virtual void visit (Function &function) = 0; + virtual void visit (TypeAlias &type_alias) = 0; + virtual void visit (StructStruct &struct_item) = 0; + virtual void visit (TupleStruct &tuple_struct) = 0; + virtual void visit (Enum &enum_item) = 0; + virtual void visit (Union &union_item) = 0; + virtual void visit (ConstantItem &const_item) = 0; + virtual void visit (StaticItem &static_item) = 0; + virtual void visit (Trait &trait) = 0; + virtual void visit (ImplBlock &impl) = 0; + virtual void visit (ExternBlock &block) = 0; +}; + +class HIRImplVisitor +{ +public: + virtual void visit (Function &function) = 0; + virtual void visit (ConstantItem &const_item) = 0; + virtual void visit (TypeAlias &type_alias) = 0; +}; + +class HIRTypeVisitor +{ +public: + virtual void visit (TypePathSegmentFunction &segment) = 0; + virtual void visit (TypePath &path) = 0; + virtual void visit (QualifiedPathInType &path) = 0; + virtual void visit (TraitBound &bound) = 0; + virtual void visit (ImplTraitType &type) = 0; + virtual void visit (TraitObjectType &type) = 0; + virtual void visit (ParenthesisedType &type) = 0; + virtual void visit (ImplTraitTypeOneBound &type) = 0; + virtual void visit (TupleType &type) = 0; + virtual void visit (NeverType &type) = 0; + virtual void visit (RawPointerType &type) = 0; + virtual void visit (ReferenceType &type) = 0; + virtual void visit (ArrayType &type) = 0; + virtual void visit (SliceType &type) = 0; + virtual void visit (InferredType &type) = 0; + virtual void visit (BareFunctionType &type) = 0; +}; + +class HIRStmtVisitor +{ +public: + virtual void visit (EnumItemTuple &) = 0; + virtual void visit (EnumItemStruct &) = 0; + virtual void visit (EnumItem &item) = 0; + virtual void visit (TupleStruct &tuple_struct) = 0; + virtual void visit (EnumItemDiscriminant &) = 0; + virtual void visit (TypePathSegmentFunction &segment) = 0; + virtual void visit (TypePath &path) = 0; + virtual void visit (QualifiedPathInType &path) = 0; + virtual void visit (Module &module) = 0; + virtual void visit (ExternCrate &crate) = 0; + virtual void visit (UseDeclaration &use_decl) = 0; + virtual void visit (Function &function) = 0; + virtual void visit (TypeAlias &type_alias) = 0; + virtual void visit (StructStruct &struct_item) = 0; + virtual void visit (Enum &enum_item) = 0; + virtual void visit (Union &union_item) = 0; + virtual void visit (ConstantItem &const_item) = 0; + virtual void visit (StaticItem &static_item) = 0; + virtual void visit (Trait &trait) = 0; + virtual void visit (ImplBlock &impl) = 0; + virtual void visit (ExternBlock &block) = 0; + virtual void visit (EmptyStmt &stmt) = 0; + virtual void visit (LetStmt &stmt) = 0; + virtual void visit (ExprStmtWithoutBlock &stmt) = 0; + virtual void visit (ExprStmtWithBlock &stmt) = 0; +}; + +class HIRExpressionVisitor +{ +public: + // These are StructExprField + // Added because of CompileStructExprField + virtual void visit (StructExprFieldIdentifier &field) = 0; + virtual void visit (StructExprFieldIdentifierValue &field) = 0; + virtual void visit (StructExprFieldIndexValue &field) = 0; + + virtual void visit (HIR::QualifiedPathInExpression &expr) = 0; + virtual void visit (HIR::PathInExpression &expr) = 0; + virtual void visit (ClosureExprInnerTyped &) = 0; + virtual void visit (ClosureExprInner &expr) = 0; + virtual void visit (StructExprStructFields &) = 0; + virtual void visit (StructExprStruct &) = 0; + virtual void visit (IdentifierExpr &ident_expr) = 0; + virtual void visit (LiteralExpr &expr) = 0; + virtual void visit (BorrowExpr &expr) = 0; + virtual void visit (DereferenceExpr &expr) = 0; + virtual void visit (ErrorPropagationExpr &expr) = 0; + virtual void visit (NegationExpr &expr) = 0; + virtual void visit (ArithmeticOrLogicalExpr &expr) = 0; + virtual void visit (ComparisonExpr &expr) = 0; + virtual void visit (LazyBooleanExpr &expr) = 0; + virtual void visit (TypeCastExpr &expr) = 0; + virtual void visit (AssignmentExpr &expr) = 0; + virtual void visit (CompoundAssignmentExpr &expr) = 0; + virtual void visit (GroupedExpr &expr) = 0; + virtual void visit (ArrayExpr &expr) = 0; + virtual void visit (ArrayIndexExpr &expr) = 0; + virtual void visit (TupleExpr &expr) = 0; + virtual void visit (TupleIndexExpr &expr) = 0; + virtual void visit (CallExpr &expr) = 0; + virtual void visit (MethodCallExpr &expr) = 0; + virtual void visit (FieldAccessExpr &expr) = 0; + virtual void visit (BlockExpr &expr) = 0; + virtual void visit (ContinueExpr &expr) = 0; + virtual void visit (BreakExpr &expr) = 0; + virtual void visit (RangeFromToExpr &expr) = 0; + virtual void visit (RangeFromExpr &expr) = 0; + virtual void visit (RangeToExpr &expr) = 0; + virtual void visit (RangeFullExpr &expr) = 0; + virtual void visit (RangeFromToInclExpr &expr) = 0; + virtual void visit (RangeToInclExpr &expr) = 0; + virtual void visit (ReturnExpr &expr) = 0; + virtual void visit (UnsafeBlockExpr &expr) = 0; + virtual void visit (LoopExpr &expr) = 0; + virtual void visit (WhileLoopExpr &expr) = 0; + virtual void visit (WhileLetLoopExpr &expr) = 0; + virtual void visit (ForLoopExpr &expr) = 0; + virtual void visit (IfExpr &expr) = 0; + virtual void visit (IfExprConseqElse &expr) = 0; + virtual void visit (IfExprConseqIf &expr) = 0; + virtual void visit (IfExprConseqIfLet &expr) = 0; + virtual void visit (IfLetExpr &expr) = 0; + virtual void visit (IfLetExprConseqElse &expr) = 0; + virtual void visit (IfLetExprConseqIf &expr) = 0; + virtual void visit (IfLetExprConseqIfLet &expr) = 0; + virtual void visit (MatchExpr &expr) = 0; + virtual void visit (AwaitExpr &expr) = 0; + virtual void visit (AsyncBlockExpr &expr) = 0; +}; + +class HIRPatternVisitor +{ +public: + virtual void visit (GroupedPattern &) = 0; + virtual void visit (IdentifierPattern &) = 0; + virtual void visit (LiteralPattern &) = 0; + virtual void visit (PathInExpression &) = 0; + virtual void visit (QualifiedPathInExpression &) = 0; + virtual void visit (RangePattern &) = 0; + virtual void visit (ReferencePattern &) = 0; + virtual void visit (SlicePattern &) = 0; + virtual void visit (StructPattern &) = 0; + virtual void visit (TuplePattern &) = 0; + virtual void visit (TupleStructPattern &) = 0; + virtual void visit (WildcardPattern &) = 0; +}; + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h index 1f82f37..760904b 100644 --- a/gcc/rust/hir/tree/rust-hir.h +++ b/gcc/rust/hir/tree/rust-hir.h @@ -33,6 +33,14 @@ typedef int TupleIndex; namespace HIR { // foward decl: ast visitor class HIRFullVisitor; +class HIRStmtVisitor; +class HIRTraitItemVisitor; +class HIRExternalItemVisitor; +class HIRVisItemVisitor; +class HIRExpressionVisitor; +class HIRPatternVisitor; +class HIRImplVisitor; +class HIRTypeVisitor; // forward decl for use in token tree method class Token; @@ -97,6 +105,7 @@ public: virtual std::string as_string () const = 0; virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRStmtVisitor &vis) = 0; virtual Location get_locus () const = 0; @@ -137,8 +146,6 @@ public: add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const {} - virtual void accept_vis (HIRFullVisitor &vis ATTRIBUTE_UNUSED) {} - AST::AttrVec &get_outer_attrs () { return outer_attrs; } const AST::AttrVec &get_outer_attrs () const { return outer_attrs; } @@ -225,8 +232,6 @@ public: virtual Location get_locus () const = 0; - virtual void accept_vis (HIRFullVisitor &vis) = 0; - const Analysis::NodeMapping &get_mappings () const { return mappings; } // Clone function implementation as pure virtual method @@ -236,6 +241,9 @@ public: virtual ExprType get_expression_type () const = 0; + virtual void accept_vis (HIRExpressionVisitor &vis) = 0; + virtual void accept_vis (HIRFullVisitor &vis) = 0; + protected: // Constructor Expr (Analysis::NodeMapping mappings, @@ -318,6 +326,7 @@ public: Location get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; // Clones this object. std::unique_ptr<IdentifierExpr> clone_identifier_expr () const @@ -380,6 +389,7 @@ public: virtual std::string as_string () const = 0; virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRPatternVisitor &vis) = 0; virtual Analysis::NodeMapping get_pattern_mappings () const = 0; @@ -420,6 +430,7 @@ public: * declaration. */ virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRTypeVisitor &vis) = 0; virtual Analysis::NodeMapping get_mappings () const { return mappings; } @@ -704,6 +715,7 @@ public: virtual std::string as_string () const = 0; + virtual void accept_vis (HIRTraitItemVisitor &vis) = 0; virtual void accept_vis (HIRFullVisitor &vis) = 0; virtual const std::string trait_identifier () const = 0; @@ -733,7 +745,9 @@ public: virtual std::string as_string () const = 0; + virtual void accept_vis (HIRImplVisitor &vis) = 0; virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRStmtVisitor &vis) = 0; virtual Analysis::NodeMapping get_impl_mappings () const = 0; diff --git a/gcc/rust/lint/rust-lint-scan-deadcode.h b/gcc/rust/lint/rust-lint-scan-deadcode.h index 86fd7af..7bb166a 100644 --- a/gcc/rust/lint/rust-lint-scan-deadcode.h +++ b/gcc/rust/lint/rust-lint-scan-deadcode.h @@ -144,4 +144,4 @@ private: } // namespace Analysis } // namespace Rust -#endif
\ No newline at end of file +#endif diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc new file mode 100644 index 0000000..539a3fe --- /dev/null +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -0,0 +1,490 @@ +// Copyright (C) 2020-2022 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-type-check-expr.h" + +namespace Rust { +namespace Resolver { + +void +TypeCheckExpr::visit (HIR::RangeFromToExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->get_kind () == TyTy::TypeKind::ADT); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (item_type); + + // this is a single generic item lets assert that + rust_assert (adt->get_num_substitutions () == 1); + + // resolve the range expressions and these types must unify then we use that + // type to substitute into the ADT + TyTy::BaseType *from_ty + = TypeCheckExpr::Resolve (expr.get_from_expr ().get (), false); + TyTy::BaseType *to_ty + = TypeCheckExpr::Resolve (expr.get_to_expr ().get (), false); + TyTy::BaseType *unified = from_ty->unify (to_ty); + + // substitute it in + std::vector<TyTy::SubstitutionArg> subst_mappings; + const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); + subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified)); + + TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + infered = SubstMapperInternal::Resolve (adt, subst); +} + +void +TypeCheckExpr::visit (HIR::RangeFromExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE_FROM; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->get_kind () == TyTy::TypeKind::ADT); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (item_type); + + // this is a single generic item lets assert that + rust_assert (adt->get_num_substitutions () == 1); + + // resolve the range expressions and these types must unify then we use that + // type to substitute into the ADT + TyTy::BaseType *from_ty + = TypeCheckExpr::Resolve (expr.get_from_expr ().get (), false); + + // substitute it in + std::vector<TyTy::SubstitutionArg> subst_mappings; + const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); + subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty)); + + TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + infered = SubstMapperInternal::Resolve (adt, subst); +} + +void +TypeCheckExpr::visit (HIR::RangeToExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE_TO; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->get_kind () == TyTy::TypeKind::ADT); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (item_type); + + // this is a single generic item lets assert that + rust_assert (adt->get_num_substitutions () == 1); + + // resolve the range expressions and these types must unify then we use that + // type to substitute into the ADT + TyTy::BaseType *from_ty + = TypeCheckExpr::Resolve (expr.get_to_expr ().get (), false); + + // substitute it in + std::vector<TyTy::SubstitutionArg> subst_mappings; + const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); + subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty)); + + TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + infered = SubstMapperInternal::Resolve (adt, subst); +} + +void +TypeCheckExpr::visit (HIR::RangeFullExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE_FULL; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->is_unit ()); + + infered = item_type; +} + +void +TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE_INCLUSIVE; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->get_kind () == TyTy::TypeKind::ADT); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (item_type); + + // this is a single generic item lets assert that + rust_assert (adt->get_num_substitutions () == 1); + + // resolve the range expressions and these types must unify then we use that + // type to substitute into the ADT + TyTy::BaseType *from_ty + = TypeCheckExpr::Resolve (expr.get_from_expr ().get (), false); + TyTy::BaseType *to_ty + = TypeCheckExpr::Resolve (expr.get_to_expr ().get (), false); + TyTy::BaseType *unified = from_ty->unify (to_ty); + + // substitute it in + std::vector<TyTy::SubstitutionArg> subst_mappings; + const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); + subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified)); + + TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + infered = SubstMapperInternal::Resolve (adt, subst); +} + +void +TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr) +{ + auto array_expr_ty + = TypeCheckExpr::Resolve (expr.get_array_expr (), inside_loop); + if (array_expr_ty->get_kind () == TyTy::TypeKind::ERROR) + return; + + auto index_expr_ty = TypeCheckExpr::Resolve (expr.get_index_expr (), false); + if (index_expr_ty->get_kind () == TyTy::TypeKind::ERROR) + return; + + // is this a case of core::ops::index? + auto lang_item_type = Analysis::RustLangItem::ItemType::INDEX; + bool operator_overloaded + = resolve_operator_overload (lang_item_type, expr, array_expr_ty, + index_expr_ty); + if (operator_overloaded) + { + // index and index mut always return a reference to the element + TyTy::BaseType *resolved = infered; + rust_assert (resolved->get_kind () == TyTy::TypeKind::REF); + TyTy::ReferenceType *ref = static_cast<TyTy::ReferenceType *> (resolved); + + infered = ref->get_base ()->clone (); + return; + } + + if (array_expr_ty->get_kind () == TyTy::TypeKind::REF) + { + // lets try and deref it since rust allows this + auto ref = static_cast<TyTy::ReferenceType *> (array_expr_ty); + auto base = ref->get_base (); + if (base->get_kind () == TyTy::TypeKind::ARRAY) + array_expr_ty = base; + } + + if (array_expr_ty->get_kind () != TyTy::TypeKind::ARRAY) + { + rust_error_at (expr.get_index_expr ()->get_locus (), + "expected an ArrayType got [%s]", + array_expr_ty->as_string ().c_str ()); + return; + } + + TyTy::BaseType *size_ty; + bool ok = context->lookup_builtin ("usize", &size_ty); + rust_assert (ok); + + auto resolved_index_expr + = size_ty->unify (TypeCheckExpr::Resolve (expr.get_index_expr (), false)); + if (resolved_index_expr->get_kind () == TyTy::TypeKind::ERROR) + return; + + TyTy::ArrayType *array_type = static_cast<TyTy::ArrayType *> (array_expr_ty); + infered = array_type->get_element_type ()->clone (); +} + +bool +TypeCheckExpr::resolve_operator_overload ( + Analysis::RustLangItem::ItemType lang_item_type, HIR::OperatorExprMeta expr, + TyTy::BaseType *lhs, TyTy::BaseType *rhs) +{ + // look up lang item for arithmetic type + std::string associated_item_name + = Analysis::RustLangItem::ToString (lang_item_type); + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // probe for the lang-item + if (!lang_item_defined) + return false; + + auto segment = HIR::PathIdentSegment (associated_item_name); + auto candidate + = MethodResolver::Probe (lhs, HIR::PathIdentSegment (associated_item_name)); + + bool have_implementation_for_lang_item = !candidate.is_error (); + if (!have_implementation_for_lang_item) + return false; + + // Get the adjusted self + Adjuster adj (lhs); + TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments); + + // is this the case we are recursive + // handle the case where we are within the impl block for this lang_item + // otherwise we end up with a recursive operator overload such as the i32 + // operator overload trait + TypeCheckContextItem &fn_context = context->peek_context (); + if (fn_context.get_type () == TypeCheckContextItem::ItemType::IMPL_ITEM) + { + auto &impl_item = fn_context.get_impl_item (); + HIR::ImplBlock *parent = impl_item.first; + HIR::Function *fn = impl_item.second; + + if (parent->has_trait_ref () + && fn->get_function_name ().compare (associated_item_name) == 0) + { + TraitReference *trait_reference + = TraitResolver::Lookup (*parent->get_trait_ref ().get ()); + if (!trait_reference->is_error ()) + { + TyTy::BaseType *lookup = nullptr; + bool ok = context->lookup_type (fn->get_mappings ().get_hirid (), + &lookup); + rust_assert (ok); + rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF); + + TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup); + rust_assert (fntype->is_method ()); + + bool is_lang_item_impl + = trait_reference->get_mappings ().get_defid () + == respective_lang_item_id; + bool self_is_lang_item_self + = fntype->get_self_type ()->is_equal (*adjusted_self); + bool recursive_operator_overload + = is_lang_item_impl && self_is_lang_item_self; + + if (recursive_operator_overload) + return false; + } + } + } + + // store the adjustments for code-generation to know what to do + context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (), + std::move (candidate.adjustments)); + + // now its just like a method-call-expr + context->insert_receiver (expr.get_mappings ().get_hirid (), lhs); + + PathProbeCandidate &resolved_candidate = candidate.candidate; + TyTy::BaseType *lookup_tyty = candidate.candidate.ty; + NodeId resolved_node_id + = resolved_candidate.is_impl_candidate () + ? resolved_candidate.item.impl.impl_item->get_impl_mappings () + .get_nodeid () + : resolved_candidate.item.trait.item_ref->get_mappings ().get_nodeid (); + + rust_assert (lookup_tyty->get_kind () == TyTy::TypeKind::FNDEF); + TyTy::BaseType *lookup = lookup_tyty; + TyTy::FnType *fn = static_cast<TyTy::FnType *> (lookup); + rust_assert (fn->is_method ()); + + auto root = lhs->get_root (); + bool receiver_is_type_param = root->get_kind () == TyTy::TypeKind::PARAM; + if (root->get_kind () == TyTy::TypeKind::ADT) + { + const TyTy::ADTType *adt = static_cast<const TyTy::ADTType *> (root); + if (adt->has_substitutions () && fn->needs_substitution ()) + { + // consider the case where we have: + // + // struct Foo<X,Y>(X,Y); + // + // impl<T> Foo<T, i32> { + // fn test<X>(self, a:X) -> (T,X) { (self.0, a) } + // } + // + // In this case we end up with an fn type of: + // + // fn <T,X> test(self:Foo<T,i32>, a:X) -> (T,X) + // + // This means the instance or self we are calling this method for + // will be substituted such that we can get the inherited type + // arguments but then need to use the turbo fish if available or + // infer the remaining arguments. Luckily rust does not allow for + // default types GenericParams on impl blocks since these must + // always be at the end of the list + + auto s = fn->get_self_type ()->get_root (); + rust_assert (s->can_eq (adt, false)); + rust_assert (s->get_kind () == TyTy::TypeKind::ADT); + const TyTy::ADTType *self_adt + = static_cast<const TyTy::ADTType *> (s); + + // we need to grab the Self substitutions as the inherit type + // parameters for this + if (self_adt->needs_substitution ()) + { + rust_assert (adt->was_substituted ()); + + TyTy::SubstitutionArgumentMappings used_args_in_prev_segment + = GetUsedSubstArgs::From (adt); + + TyTy::SubstitutionArgumentMappings inherit_type_args + = self_adt->solve_mappings_from_receiver_for_self ( + used_args_in_prev_segment); + + // there may or may not be inherited type arguments + if (!inherit_type_args.is_error ()) + { + // need to apply the inherited type arguments to the + // function + lookup = fn->handle_substitions (inherit_type_args); + } + } + } + } + + // handle generics + if (!receiver_is_type_param) + { + if (lookup->needs_generic_substitutions ()) + { + lookup = SubstMapper::InferSubst (lookup, expr.get_locus ()); + } + } + + // type check the arguments if required + TyTy::FnType *type = static_cast<TyTy::FnType *> (lookup); + rust_assert (type->num_params () > 0); + auto fnparam = type->param_at (0); + fnparam.second->unify (adjusted_self); // typecheck the self + if (rhs == nullptr) + { + rust_assert (type->num_params () == 1); + } + else + { + rust_assert (type->num_params () == 2); + auto fnparam = type->param_at (1); + fnparam.second->unify (rhs); // typecheck the rhs + } + + // get the return type + TyTy::BaseType *function_ret_tyty = type->get_return_type ()->clone (); + + // store the expected fntype + context->insert_operator_overload (expr.get_mappings ().get_hirid (), type); + + // set up the resolved name on the path + resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (), + resolved_node_id); + + // return the result of the function back + infered = function_ret_tyty; + + return true; +} + +} // namespace Resolver +} // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index a4b8f0a..93aa868 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -879,52 +879,7 @@ public: = TypeCheckExpr::Resolve (expr.get_block_expr ().get (), inside_loop); } - void visit (HIR::ArrayIndexExpr &expr) override - { - TyTy::BaseType *size_ty; - if (!context->lookup_builtin ("usize", &size_ty)) - { - rust_error_at ( - expr.get_locus (), - "Failure looking up size type for index in ArrayIndexExpr"); - return; - } - - auto resolved_index_expr - = size_ty->unify (TypeCheckExpr::Resolve (expr.get_index_expr (), false)); - if (resolved_index_expr->get_kind () != TyTy::TypeKind::ERROR) - { - // allow the index expr to fail lets just continue on - context->insert_type (expr.get_index_expr ()->get_mappings (), - resolved_index_expr); - } - - auto array_expr_ty - = TypeCheckExpr::Resolve (expr.get_array_expr (), inside_loop); - if (array_expr_ty->get_kind () == TyTy::TypeKind::ERROR) - return; - else if (array_expr_ty->get_kind () == TyTy::TypeKind::REF) - { - // lets try and deref it since rust allows this - auto ref = static_cast<TyTy::ReferenceType *> (array_expr_ty); - auto base = ref->get_base (); - if (base->get_kind () == TyTy::TypeKind::ARRAY) - array_expr_ty = base; - } - - if (array_expr_ty->get_kind () != TyTy::TypeKind::ARRAY) - { - rust_error_at (expr.get_index_expr ()->get_locus (), - "expected an ArrayType got [%s]", - infered->as_string ().c_str ()); - infered = nullptr; - return; - } - - TyTy::ArrayType *array_type - = static_cast<TyTy::ArrayType *> (array_expr_ty); - infered = array_type->get_element_type ()->clone (); - } + void visit (HIR::ArrayIndexExpr &expr) override; void visit (HIR::ArrayExpr &expr) override { @@ -1271,195 +1226,21 @@ public: } } -protected: - bool - resolve_operator_overload (Analysis::RustLangItem::ItemType lang_item_type, - HIR::OperatorExpr &expr, TyTy::BaseType *lhs, - TyTy::BaseType *rhs) - { - // look up lang item for arithmetic type - std::string associated_item_name - = Analysis::RustLangItem::ToString (lang_item_type); - DefId respective_lang_item_id = UNKNOWN_DEFID; - bool lang_item_defined - = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); - - // probe for the lang-item - if (!lang_item_defined) - return false; - - auto segment = HIR::PathIdentSegment (associated_item_name); - auto candidate - = MethodResolver::Probe (lhs, - HIR::PathIdentSegment (associated_item_name)); + void visit (HIR::RangeFromToExpr &expr) override; - bool have_implementation_for_lang_item = !candidate.is_error (); - if (!have_implementation_for_lang_item) - return false; + void visit (HIR::RangeFromExpr &expr) override; - // Get the adjusted self - Adjuster adj (lhs); - TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments); + void visit (HIR::RangeToExpr &expr) override; - // is this the case we are recursive - // handle the case where we are within the impl block for this lang_item - // otherwise we end up with a recursive operator overload such as the i32 - // operator overload trait - TypeCheckContextItem &fn_context = context->peek_context (); - if (fn_context.get_type () == TypeCheckContextItem::ItemType::IMPL_ITEM) - { - auto &impl_item = fn_context.get_impl_item (); - HIR::ImplBlock *parent = impl_item.first; - HIR::Function *fn = impl_item.second; + void visit (HIR::RangeFullExpr &expr) override; - if (parent->has_trait_ref () - && fn->get_function_name ().compare (associated_item_name) == 0) - { - TraitReference *trait_reference - = TraitResolver::Lookup (*parent->get_trait_ref ().get ()); - if (!trait_reference->is_error ()) - { - TyTy::BaseType *lookup = nullptr; - bool ok - = context->lookup_type (fn->get_mappings ().get_hirid (), - &lookup); - rust_assert (ok); - rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF); - - TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup); - rust_assert (fntype->is_method ()); - - bool is_lang_item_impl - = trait_reference->get_mappings ().get_defid () - == respective_lang_item_id; - bool self_is_lang_item_self - = fntype->get_self_type ()->is_equal (*adjusted_self); - bool recursive_operator_overload - = is_lang_item_impl && self_is_lang_item_self; - - if (recursive_operator_overload) - return false; - } - } - } + void visit (HIR::RangeFromToInclExpr &expr) override; - // store the adjustments for code-generation to know what to do - context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (), - std::move (candidate.adjustments)); - - // now its just like a method-call-expr - context->insert_receiver (expr.get_mappings ().get_hirid (), lhs); - - PathProbeCandidate &resolved_candidate = candidate.candidate; - TyTy::BaseType *lookup_tyty = candidate.candidate.ty; - NodeId resolved_node_id - = resolved_candidate.is_impl_candidate () - ? resolved_candidate.item.impl.impl_item->get_impl_mappings () - .get_nodeid () - : resolved_candidate.item.trait.item_ref->get_mappings () - .get_nodeid (); - - rust_assert (lookup_tyty->get_kind () == TyTy::TypeKind::FNDEF); - TyTy::BaseType *lookup = lookup_tyty; - TyTy::FnType *fn = static_cast<TyTy::FnType *> (lookup); - rust_assert (fn->is_method ()); - - auto root = lhs->get_root (); - bool receiver_is_type_param = root->get_kind () == TyTy::TypeKind::PARAM; - if (root->get_kind () == TyTy::TypeKind::ADT) - { - const TyTy::ADTType *adt = static_cast<const TyTy::ADTType *> (root); - if (adt->has_substitutions () && fn->needs_substitution ()) - { - // consider the case where we have: - // - // struct Foo<X,Y>(X,Y); - // - // impl<T> Foo<T, i32> { - // fn test<X>(self, a:X) -> (T,X) { (self.0, a) } - // } - // - // In this case we end up with an fn type of: - // - // fn <T,X> test(self:Foo<T,i32>, a:X) -> (T,X) - // - // This means the instance or self we are calling this method for - // will be substituted such that we can get the inherited type - // arguments but then need to use the turbo fish if available or - // infer the remaining arguments. Luckily rust does not allow for - // default types GenericParams on impl blocks since these must - // always be at the end of the list - - auto s = fn->get_self_type ()->get_root (); - rust_assert (s->can_eq (adt, false)); - rust_assert (s->get_kind () == TyTy::TypeKind::ADT); - const TyTy::ADTType *self_adt - = static_cast<const TyTy::ADTType *> (s); - - // we need to grab the Self substitutions as the inherit type - // parameters for this - if (self_adt->needs_substitution ()) - { - rust_assert (adt->was_substituted ()); - - TyTy::SubstitutionArgumentMappings used_args_in_prev_segment - = GetUsedSubstArgs::From (adt); - - TyTy::SubstitutionArgumentMappings inherit_type_args - = self_adt->solve_mappings_from_receiver_for_self ( - used_args_in_prev_segment); - - // there may or may not be inherited type arguments - if (!inherit_type_args.is_error ()) - { - // need to apply the inherited type arguments to the - // function - lookup = fn->handle_substitions (inherit_type_args); - } - } - } - } - - // handle generics - if (!receiver_is_type_param) - { - if (lookup->needs_generic_substitutions ()) - { - lookup = SubstMapper::InferSubst (lookup, expr.get_locus ()); - } - } - - // type check the arguments if required - TyTy::FnType *type = static_cast<TyTy::FnType *> (lookup); - rust_assert (type->num_params () > 0); - auto fnparam = type->param_at (0); - fnparam.second->unify (adjusted_self); // typecheck the self - if (rhs == nullptr) - { - rust_assert (type->num_params () == 1); - } - else - { - rust_assert (type->num_params () == 2); - auto fnparam = type->param_at (1); - fnparam.second->unify (rhs); // typecheck the rhs - } - - // get the return type - TyTy::BaseType *function_ret_tyty = type->get_return_type ()->clone (); - - // store the expected fntype - context->insert_operator_overload (expr.get_mappings ().get_hirid (), type); - - // set up the resolved name on the path - resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (), - resolved_node_id); - - // return the result of the function back - infered = function_ret_tyty; - - return true; - } +protected: + bool + resolve_operator_overload (Analysis::RustLangItem::ItemType lang_item_type, + HIR::OperatorExprMeta expr, TyTy::BaseType *lhs, + TyTy::BaseType *rhs); private: TypeCheckExpr (bool inside_loop) diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index 4ea4762..0d48bd2 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -124,6 +124,7 @@ public: void visit (TyTy::TupleType &) override { gcc_unreachable (); } void visit (TyTy::FnPtr &) override { gcc_unreachable (); } void visit (TyTy::ArrayType &) override { gcc_unreachable (); } + void visit (TyTy::SliceType &) override { gcc_unreachable (); } void visit (TyTy::BoolType &) override { gcc_unreachable (); } void visit (TyTy::IntType &) override { gcc_unreachable (); } void visit (TyTy::UintType &) override { gcc_unreachable (); } @@ -224,6 +225,7 @@ public: void visit (TyTy::InferType &) override { gcc_unreachable (); } void visit (TyTy::FnPtr &) override { gcc_unreachable (); } void visit (TyTy::ArrayType &) override { gcc_unreachable (); } + void visit (TyTy::SliceType &) override { gcc_unreachable (); } void visit (TyTy::BoolType &) override { gcc_unreachable (); } void visit (TyTy::IntType &) override { gcc_unreachable (); } void visit (TyTy::UintType &) override { gcc_unreachable (); } @@ -286,6 +288,7 @@ public: void visit (TyTy::TupleType &) override { gcc_unreachable (); } void visit (TyTy::FnPtr &) override { gcc_unreachable (); } void visit (TyTy::ArrayType &) override { gcc_unreachable (); } + void visit (TyTy::SliceType &) override { gcc_unreachable (); } void visit (TyTy::BoolType &) override { gcc_unreachable (); } void visit (TyTy::IntType &) override { gcc_unreachable (); } void visit (TyTy::UintType &) override { gcc_unreachable (); } @@ -343,6 +346,7 @@ public: void visit (const TyTy::TupleType &) override {} void visit (const TyTy::FnPtr &) override {} void visit (const TyTy::ArrayType &) override {} + void visit (const TyTy::SliceType &) override {} void visit (const TyTy::BoolType &) override {} void visit (const TyTy::IntType &) override {} void visit (const TyTy::UintType &) override {} diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h index b238d476f..51817e6 100644 --- a/gcc/rust/typecheck/rust-tyty-call.h +++ b/gcc/rust/typecheck/rust-tyty-call.h @@ -43,6 +43,7 @@ public: void visit (InferType &) override { gcc_unreachable (); } void visit (TupleType &) override { gcc_unreachable (); } void visit (ArrayType &) override { gcc_unreachable (); } + void visit (SliceType &) override { gcc_unreachable (); } void visit (BoolType &) override { gcc_unreachable (); } void visit (IntType &) override { gcc_unreachable (); } void visit (UintType &) override { gcc_unreachable (); } @@ -99,6 +100,7 @@ public: void visit (InferType &) override { gcc_unreachable (); } void visit (TupleType &) override { gcc_unreachable (); } void visit (ArrayType &) override { gcc_unreachable (); } + void visit (SliceType &) override { gcc_unreachable (); } void visit (BoolType &) override { gcc_unreachable (); } void visit (IntType &) override { gcc_unreachable (); } void visit (UintType &) override { gcc_unreachable (); } diff --git a/gcc/rust/typecheck/rust-tyty-cast.h b/gcc/rust/typecheck/rust-tyty-cast.h index b9f4e14..0e0e7b0 100644 --- a/gcc/rust/typecheck/rust-tyty-cast.h +++ b/gcc/rust/typecheck/rust-tyty-cast.h @@ -153,6 +153,17 @@ public: type.as_string ().c_str ()); } + virtual void visit (SliceType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "invalid cast [%s] to [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + virtual void visit (BoolType &type) override { Location ref_locus = mappings->lookup_location (type.get_ref ()); @@ -468,6 +479,19 @@ public: BaseCastRules::visit (type); } + void visit (SliceType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + + BaseCastRules::visit (type); + } + void visit (ADTType &type) override { bool is_valid @@ -818,6 +842,35 @@ private: ArrayType *base; }; +class SliceCastRules : public BaseCastRules +{ + using Rust::TyTy::BaseCastRules::visit; + +public: + SliceCastRules (SliceType *base) : BaseCastRules (base), base (base) {} + + void visit (SliceType &type) override + { + // check base type + auto base_resolved + = base->get_element_type ()->unify (type.get_element_type ()); + if (base_resolved == nullptr) + { + BaseCastRules::visit (type); + return; + } + + resolved = new SliceType (type.get_ref (), type.get_ty_ref (), + type.get_ident ().locus, + TyVar (base_resolved->get_ref ())); + } + +private: + BaseType *get_base () override { return base; } + + SliceType *base; +}; + class BoolCastRules : public BaseCastRules { using Rust::TyTy::BaseCastRules::visit; diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h index bd568be..436bde9 100644 --- a/gcc/rust/typecheck/rust-tyty-cmp.h +++ b/gcc/rust/typecheck/rust-tyty-cmp.h @@ -155,6 +155,22 @@ public: } } + virtual void visit (const SliceType &type) override + { + ok = false; + if (emit_error_flag) + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus + = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "expected [%s] got [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + } + virtual void visit (const BoolType &type) override { ok = false; @@ -544,6 +560,19 @@ public: BaseCmp::visit (type); } + void visit (const SliceType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + ok = true; + return; + } + + BaseCmp::visit (type); + } + void visit (const ADTType &type) override { bool is_valid @@ -864,6 +893,36 @@ private: const ArrayType *base; }; +class SliceCmp : public BaseCmp +{ + using Rust::TyTy::BaseCmp::visit; + +public: + SliceCmp (const SliceType *base, bool emit_errors) + : BaseCmp (base, emit_errors), base (base) + {} + + void visit (const SliceType &type) override + { + // check base type + const BaseType *base_element = base->get_element_type (); + const BaseType *other_element = type.get_element_type (); + if (!base_element->can_eq (other_element, emit_error_flag)) + { + BaseCmp::visit (type); + return; + } + + ok = true; + } + + void visit (const ParamType &type) override { ok = true; } + +private: + const BaseType *get_base () const override { return base; } + const SliceType *base; +}; + class BoolCmp : public BaseCmp { using Rust::TyTy::BaseCmp::visit; @@ -1258,6 +1317,8 @@ public: void visit (const ArrayType &) override { ok = true; } + void visit (const SliceType &) override { ok = true; } + void visit (const BoolType &) override { ok = true; } void visit (const IntType &) override { ok = true; } diff --git a/gcc/rust/typecheck/rust-tyty-coercion.h b/gcc/rust/typecheck/rust-tyty-coercion.h index 75913f0..4deed55 100644 --- a/gcc/rust/typecheck/rust-tyty-coercion.h +++ b/gcc/rust/typecheck/rust-tyty-coercion.h @@ -167,6 +167,17 @@ public: type.as_string ().c_str ()); } + virtual void visit (SliceType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "expected [%s] got [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + virtual void visit (BoolType &type) override { Location ref_locus = mappings->lookup_location (type.get_ref ()); @@ -483,6 +494,19 @@ public: BaseCoercionRules::visit (type); } + void visit (SliceType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + + BaseCoercionRules::visit (type); + } + void visit (ADTType &type) override { bool is_valid @@ -836,6 +860,36 @@ private: ArrayType *base; }; +class SliceCoercionRules : public BaseCoercionRules +{ + using Rust::TyTy::BaseCoercionRules::visit; + +public: + SliceCoercionRules (SliceType *base) : BaseCoercionRules (base), base (base) + {} + + void visit (SliceType &type) override + { + // check base type + auto base_resolved + = base->get_element_type ()->unify (type.get_element_type ()); + if (base_resolved == nullptr) + { + BaseCoercionRules::visit (type); + return; + } + + resolved = new SliceType (type.get_ref (), type.get_ty_ref (), + type.get_ident ().locus, + TyVar (base_resolved->get_ref ())); + } + +private: + BaseType *get_base () override { return base; } + + SliceType *base; +}; + class BoolCoercionRules : public BaseCoercionRules { using Rust::TyTy::BaseCoercionRules::visit; diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index 906e33d..c1fc2cd 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -185,6 +185,17 @@ public: type.as_string ().c_str ()); } + virtual void visit (SliceType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "expected [%s] got [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + virtual void visit (BoolType &type) override { Location ref_locus = mappings->lookup_location (type.get_ref ()); @@ -500,6 +511,19 @@ public: BaseRules::visit (type); } + void visit (SliceType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + + BaseRules::visit (type); + } + void visit (ADTType &type) override { bool is_valid @@ -850,6 +874,35 @@ private: ArrayType *base; }; +class SliceRules : public BaseRules +{ + using Rust::TyTy::BaseRules::visit; + +public: + SliceRules (SliceType *base) : BaseRules (base), base (base) {} + + void visit (SliceType &type) override + { + // check base type + auto base_resolved + = base->get_element_type ()->unify (type.get_element_type ()); + if (base_resolved == nullptr) + { + BaseRules::visit (type); + return; + } + + resolved = new SliceType (type.get_ref (), type.get_ty_ref (), + type.get_ident ().locus, + TyVar (base_resolved->get_ref ())); + } + +private: + BaseType *get_base () override { return base; } + + SliceType *base; +}; + class BoolRules : public BaseRules { using Rust::TyTy::BaseRules::visit; diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h index fa01a71..464e70d 100644 --- a/gcc/rust/typecheck/rust-tyty-visitor.h +++ b/gcc/rust/typecheck/rust-tyty-visitor.h @@ -33,6 +33,7 @@ public: virtual void visit (FnType &type) = 0; virtual void visit (FnPtr &type) = 0; virtual void visit (ArrayType &type) = 0; + virtual void visit (SliceType &type) = 0; virtual void visit (BoolType &type) = 0; virtual void visit (IntType &type) = 0; virtual void visit (UintType &type) = 0; @@ -61,6 +62,7 @@ public: virtual void visit (const FnType &type) = 0; virtual void visit (const FnPtr &type) = 0; virtual void visit (const ArrayType &type) = 0; + virtual void visit (const SliceType &type) = 0; virtual void visit (const BoolType &type) = 0; virtual void visit (const IntType &type) = 0; virtual void visit (const UintType &type) = 0; diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 0dde299..fa5dcfb 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -59,6 +59,9 @@ TypeKindFormat::to_string (TypeKind kind) case TypeKind::ARRAY: return "ARRAY"; + case TypeKind::SLICE: + return "SLICE"; + case TypeKind::FNDEF: return "FnDef"; @@ -840,16 +843,14 @@ ADTType::is_equal (const BaseType &other) const return false; } } - else + + for (size_t i = 0; i < number_of_variants (); i++) { - 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 *a = get_variants ().at (i); + const TyTy::VariantDef *b = other2.get_variants ().at (i); - if (!a->is_equal (*b)) - return false; - } + if (!a->is_equal (*b)) + return false; } return true; @@ -1505,6 +1506,79 @@ ArrayType::clone () const } void +SliceType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +void +SliceType::accept_vis (TyConstVisitor &vis) const +{ + vis.visit (*this); +} + +std::string +SliceType::as_string () const +{ + return "[" + get_element_type ()->as_string () + "]"; +} + +BaseType * +SliceType::unify (BaseType *other) +{ + SliceRules r (this); + return r.unify (other); +} + +BaseType * +SliceType::coerce (BaseType *other) +{ + SliceCoercionRules r (this); + return r.coerce (other); +} + +BaseType * +SliceType::cast (BaseType *other) +{ + SliceCastRules r (this); + return r.cast (other); +} + +bool +SliceType::can_eq (const BaseType *other, bool emit_errors) const +{ + SliceCmp r (this, emit_errors); + return r.can_eq (other); +} + +bool +SliceType::is_equal (const BaseType &other) const +{ + if (get_kind () != other.get_kind ()) + return false; + + auto other2 = static_cast<const SliceType &> (other); + + auto this_element_type = get_element_type (); + auto other_element_type = other2.get_element_type (); + + return this_element_type->is_equal (*other_element_type); +} + +BaseType * +SliceType::get_element_type () const +{ + return element_type.get_tyty (); +} + +BaseType * +SliceType::clone () const +{ + return new SliceType (get_ref (), get_ty_ref (), ident.locus, element_type, + get_combined_refs ()); +} + +void BoolType::accept_vis (TyVisitor &vis) { vis.visit (*this); diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 036d772..85948b2 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -47,6 +47,7 @@ enum TypeKind POINTER, PARAM, ARRAY, + SLICE, FNDEF, FNPTR, TUPLE, @@ -1666,6 +1667,50 @@ private: HIR::Expr &capacity_expr; }; +class SliceType : public BaseType +{ +public: + SliceType (HirId ref, Location locus, TyVar base, + std::set<HirId> refs = std::set<HirId> ()) + : BaseType (ref, ref, TypeKind::SLICE, + {Resolver::CanonicalPath::create_empty (), locus}, refs), + element_type (base) + {} + + SliceType (HirId ref, HirId ty_ref, Location locus, TyVar base, + std::set<HirId> refs = std::set<HirId> ()) + : BaseType (ref, ty_ref, TypeKind::SLICE, + {Resolver::CanonicalPath::create_empty (), locus}, refs), + element_type (base) + {} + + void accept_vis (TyVisitor &vis) override; + void accept_vis (TyConstVisitor &vis) const override; + + std::string as_string () const override; + + std::string get_name () const override final { return as_string (); } + + BaseType *unify (BaseType *other) override; + bool can_eq (const BaseType *other, bool emit_errors) const override final; + BaseType *coerce (BaseType *other) override; + BaseType *cast (BaseType *other) override; + + bool is_equal (const BaseType &other) const override; + + BaseType *get_element_type () const; + + BaseType *clone () const final override; + + bool is_concrete () const final override + { + return get_element_type ()->is_concrete (); + } + +private: + TyVar element_type; +}; + class BoolType : public BaseType { public: diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index da0db00..9190bd9 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -749,6 +749,7 @@ Mappings::insert_macro_def (AST::MacroRulesDefinition *macro) Location, AST::MacroInvocData &)>> builtin_macros = { {"assert", MacroBuiltin::assert}, + {"file", MacroBuiltin::file}, }; auto builtin = builtin_macros.find (macro->get_rule_name ()); diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h index da200e7..cade09d 100644 --- a/gcc/rust/util/rust-lang-item.h +++ b/gcc/rust/util/rust-lang-item.h @@ -56,6 +56,10 @@ public: DEREF, DEREF_MUT, + // https://github.com/rust-lang/rust/blob/master/library/core/src/ops/index.rs + INDEX, + INDEX_MUT, + // https://github.com/rust-lang/rust/blob/master/library/core/src/ops/range.rs RANGE_FULL, RANGE, @@ -165,6 +169,18 @@ public: { return ItemType::DEREF_MUT; } + else if (item.compare ("index") == 0) + { + return ItemType::INDEX; + } + else if (item.compare ("index_mut") == 0) + { + return ItemType::INDEX_MUT; + } + else if (item.compare ("RangeFull") == 0) + { + return ItemType::RANGE_FULL; + } else if (item.compare ("Range") == 0) { return ItemType::RANGE; @@ -241,6 +257,10 @@ public: return "deref"; case DEREF_MUT: return "deref_mut"; + case INDEX: + return "index"; + case INDEX_MUT: + return "index_mut"; case RANGE_FULL: return "RangeFull"; case RANGE: diff --git a/gcc/testsuite/rust/compile/torture/range-lang-item1.rs b/gcc/testsuite/rust/compile/torture/range-lang-item1.rs new file mode 100644 index 0000000..8694616 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/range-lang-item1.rs @@ -0,0 +1,32 @@ +// { dg-additional-options "-w" } +#[lang = "RangeFull"] +pub struct RangeFull; + +#[lang = "Range"] +pub struct Range<Idx> { + pub start: Idx, + pub end: Idx, +} + +#[lang = "RangeFrom"] +pub struct RangeFrom<Idx> { + pub start: Idx, +} + +#[lang = "RangeTo"] +pub struct RangeTo<Idx> { + pub end: Idx, +} + +#[lang = "RangeInclusive"] +pub struct RangeInclusive<Idx> { + pub start: Idx, + pub end: Idx, +} + +fn test() { + let a = 1..2; // range + let b = 1..; // range from + let c = ..3; // range to + let d = 0..=2; // range inclusive +} diff --git a/gcc/testsuite/rust/compile/usize1.rs b/gcc/testsuite/rust/compile/usize1.rs index 8c12789..c7e746b 100644 --- a/gcc/testsuite/rust/compile/usize1.rs +++ b/gcc/testsuite/rust/compile/usize1.rs @@ -2,4 +2,5 @@ fn main() { let a = [1, 2, 3]; let b: u32 = 1; let c = a[b]; // { dg-error "expected .usize. got .u32." } + // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 } } diff --git a/gcc/testsuite/rust/execute/torture/builtin_macros1.rs b/gcc/testsuite/rust/execute/torture/builtin_macros1.rs new file mode 100644 index 0000000..d68f62f --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macros1.rs @@ -0,0 +1,18 @@ +// { dg-output "rust/execute/torture/builtin_macros1.rs" } +macro_rules! file { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: &str) { + printf("%s\n\0" as *const str as *const i8, s); +} + +fn main() -> i32 { + print(file!()); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/index1.rs b/gcc/testsuite/rust/execute/torture/index1.rs new file mode 100644 index 0000000..4682978 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/index1.rs @@ -0,0 +1,28 @@ +// { dg-additional-options "-w" } +#[lang = "index"] +trait Index<Idx> { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +struct Foo(i32, i32); +impl Index<isize> for Foo { + type Output = i32; + + fn index(&self, index: isize) -> &i32 { + if index == 0 { + &self.0 + } else { + &self.1 + } + } +} + +fn main() -> i32 { + let a = Foo(1, 2); + let b = a[0]; + let c = a[1]; + + c - b - 1 +} |