aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.h3
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h27
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc49
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc4
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.h72
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 */