diff options
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-base.h | 3 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 27 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.cc | 49 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-full-test.cc | 4 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-path.h | 72 |
5 files changed, 115 insertions, 40 deletions
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h index b1d0df3..07489f8 100644 --- a/gcc/rust/hir/rust-ast-lower-base.h +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -284,6 +284,9 @@ protected: HIR::Type *lower_type_no_bounds (AST::TypeNoBounds *type); HIR::TypeParamBound *lower_bound (AST::TypeParamBound *bound); + + HIR::QualifiedPathType + lower_qual_path_type (AST::QualifiedPathType &qual_path_type); }; } // namespace HIR diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index 1c48651..3415567 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -48,6 +48,28 @@ private: HIR::PathInExpression *translated; }; +class ASTLowerQualPathInExpression : public ASTLoweringBase +{ + using Rust::HIR::ASTLoweringBase::visit; + +public: + static HIR::QualifiedPathInExpression * + translate (AST::QualifiedPathInExpression *expr) + { + ASTLowerQualPathInExpression compiler; + expr->accept_vis (compiler); + rust_assert (compiler.translated); + return compiler.translated; + } + + void visit (AST::QualifiedPathInExpression &expr) override; + +private: + ASTLowerQualPathInExpression () : translated (nullptr) {} + + HIR::QualifiedPathInExpression *translated; +}; + class ASTLoweringExpr : public ASTLoweringBase { using Rust::HIR::ASTLoweringBase::visit; @@ -145,6 +167,11 @@ public: translated = ASTLowerPathInExpression::translate (&expr); } + void visit (AST::QualifiedPathInExpression &expr) override + { + translated = ASTLowerQualPathInExpression::translate (&expr); + } + void visit (AST::ReturnExpr &expr) override { terminated = true; diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index ed59777..e693799 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -282,6 +282,55 @@ ASTLowerPathInExpression::visit (AST::PathInExpression &expr) expr.opening_scope_resolution ()); } +HIR::QualifiedPathType +ASTLoweringBase::lower_qual_path_type (AST::QualifiedPathType &qualified_type) +{ + HIR::Type *type + = ASTLoweringType::translate (qualified_type.get_type ().get ()); + HIR::TypePath *trait + = qualified_type.has_as_clause () + ? ASTLowerTypePath::translate (qualified_type.get_as_type_path ()) + : nullptr; + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, qualified_type.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + return HIR::QualifiedPathType (mapping, std::unique_ptr<HIR::Type> (type), + std::unique_ptr<HIR::TypePath> (trait), + qualified_type.get_locus ()); +} + +void +ASTLowerQualPathInExpression::visit (AST::QualifiedPathInExpression &expr) +{ + HIR::QualifiedPathType qual_path_type + = lower_qual_path_type (expr.get_qualified_path_type ()); + + std::vector<HIR::PathExprSegment> path_segments; + expr.iterate_path_segments ([&] (AST::PathExprSegment &s) mutable -> bool { + path_segments.push_back (lower_path_expr_seg (s)); + + // insert the mappings for the segment + HIR::PathExprSegment *lowered_seg = &path_segments.back (); + mappings->insert_hir_path_expr_seg ( + lowered_seg->get_mappings ().get_crate_num (), + lowered_seg->get_mappings ().get_hirid (), lowered_seg); + return true; + }); + + 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::QualifiedPathInExpression (mapping, qual_path_type, + std::move (path_segments), + expr.get_locus (), + expr.get_outer_attrs ()); +} + // rust-ast-lower-base.h std::vector<std::unique_ptr<HIR::GenericParam> > diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc index dee2827..62262a2 100644 --- a/gcc/rust/hir/tree/rust-hir-full-test.cc +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -1192,11 +1192,11 @@ std::string QualifiedPathType::as_string () const { std::string str ("<"); - str += type_to_invoke_on->as_string (); + str += type->as_string (); if (has_as_clause ()) { - str += " as " + trait_path.as_string (); + str += " as " + trait->as_string (); } return str + ">"; diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index 5d9f965..a8bbbb6 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -709,26 +709,26 @@ public: struct QualifiedPathType { private: - std::unique_ptr<Type> type_to_invoke_on; - - // bool has_as_clause; - TypePath trait_path; - + std::unique_ptr<Type> type; + std::unique_ptr<TypePath> trait; Location locus; + Analysis::NodeMapping mappings; public: // Constructor - QualifiedPathType (std::unique_ptr<Type> invoke_on_type, - Location locus = Location (), - TypePath trait_path = TypePath::create_error ()) - : type_to_invoke_on (std::move (invoke_on_type)), - trait_path (std::move (trait_path)), locus (locus) + QualifiedPathType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type, + std::unique_ptr<TypePath> trait, Location locus) + : type (std::move (type)), trait (std::move (trait)), locus (locus), + mappings (mappings) {} // Copy constructor uses custom deep copy for Type to preserve polymorphism QualifiedPathType (QualifiedPathType const &other) - : type_to_invoke_on (other.type_to_invoke_on->clone_type ()), - trait_path (other.trait_path), locus (other.locus) + : type (other.type->clone_type ()), + trait (other.has_as_clause () ? std::unique_ptr<HIR::TypePath> ( + new HIR::TypePath (*other.trait)) + : nullptr), + locus (other.locus), mappings (other.mappings) {} // default destructor @@ -737,9 +737,14 @@ public: // overload assignment operator to use custom clone method QualifiedPathType &operator= (QualifiedPathType const &other) { - type_to_invoke_on = other.type_to_invoke_on->clone_type (); - trait_path = other.trait_path; + type = other.type->clone_type (); locus = other.locus; + mappings = other.mappings; + trait + = other.has_as_clause () + ? std::unique_ptr<HIR::TypePath> (new HIR::TypePath (*other.trait)) + : nullptr; + return *this; } @@ -748,20 +753,21 @@ public: QualifiedPathType &operator= (QualifiedPathType &&other) = default; // Returns whether the qualified path type has a rebind as clause. - bool has_as_clause () const { return !trait_path.is_error (); } - - // Returns whether the qualified path type is in an error state. - bool is_error () const { return type_to_invoke_on == nullptr; } - - // Creates an error state qualified path type. - static QualifiedPathType create_error () - { - return QualifiedPathType (nullptr); - } + bool has_as_clause () const { return trait != nullptr; } std::string as_string () const; Location get_locus () const { return locus; } + + Analysis::NodeMapping get_mappings () const { return mappings; } + + std::unique_ptr<Type> &get_type () { return type; } + + std::unique_ptr<TypePath> &get_trait () + { + rust_assert (has_as_clause ()); + return trait; + } }; /* HIR node representing a qualified path-in-expression pattern (path that @@ -785,25 +791,15 @@ public: path_type (std::move (qual_path_type)), locus (locus) {} - /* TODO: maybe make a shortcut constructor that has QualifiedPathType elements - * as params */ - - // Returns whether qualified path in expression is in an error state. - bool is_error () const { return path_type.is_error (); } - - // Creates an error qualified path in expression. - static QualifiedPathInExpression create_error () - { - return QualifiedPathInExpression (Analysis::NodeMapping::get_error (), - QualifiedPathType::create_error (), - std::vector<PathExprSegment> ()); - } - Location get_locus () const { return locus; } Location get_locus_slow () const override { return get_locus (); } void accept_vis (HIRVisitor &vis) override; + QualifiedPathType &get_path_type () { return path_type; } + + Location get_locus () { return locus; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ |