aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-04-21 14:32:21 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-04-21 16:06:18 +0100
commitdd9e4c1e0ca0b14388a3cd43f18a4e1a7aebe6e5 (patch)
tree234a6e1ecdbb1b0a185bf94c50121959926e90cc
parentfe10ca37aba8f3cb9bfaa9dd01bdb1329317cf21 (diff)
downloadgcc-dd9e4c1e0ca0b14388a3cd43f18a4e1a7aebe6e5.zip
gcc-dd9e4c1e0ca0b14388a3cd43f18a4e1a7aebe6e5.tar.gz
gcc-dd9e4c1e0ca0b14388a3cd43f18a4e1a7aebe6e5.tar.bz2
Add name and type resolution for TuplePatterns
This adds the relevant pattern resolution steps to match up the TuplePattern. This patch leaves out type resolution on TupleRange Patterns for now. Some thought is needed to figure out how do have a canonical algorithm for code-generation here so splitting this up makes sense for now. This patch extracts the type-resolution handling for HIR::LiteralExpr to have a generic function to resolve the HIR::Literal which is used within HIR::LiteralExpr and HIR::LiteralPattern. Addresses #1081
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc9
-rw-r--r--gcc/rust/hir/tree/rust-hir-pattern.h41
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc30
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc172
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h168
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.cc41
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.h10
9 files changed, 293 insertions, 183 deletions
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index a996228..a53210b 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -2589,14 +2589,7 @@ StructPattern::as_string () const
std::string
LiteralPattern::as_string () const
{
- std::string str;
-
- if (has_minus)
- {
- str += "-";
- }
-
- return str + lit.as_string ();
+ return lit.as_string ();
}
std::string
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index de4a83e..880fc3e 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -29,7 +29,6 @@ namespace HIR {
class LiteralPattern : public Pattern
{
Literal lit;
- bool has_minus;
Location locus;
Analysis::NodeMapping mappings;
@@ -37,16 +36,14 @@ public:
std::string as_string () const override;
// Constructor for a literal pattern
- LiteralPattern (Analysis::NodeMapping mappings, Literal lit, Location locus,
- bool has_minus = false)
- : lit (std::move (lit)), has_minus (has_minus), locus (locus),
- mappings (mappings)
+ LiteralPattern (Analysis::NodeMapping mappings, Literal lit, Location locus)
+ : lit (std::move (lit)), locus (locus), mappings (mappings)
{}
LiteralPattern (Analysis::NodeMapping mappings, std::string val,
- Literal::LitType type, Location locus, bool has_minus = false)
+ Literal::LitType type, Location locus)
: lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
- has_minus (has_minus), locus (locus), mappings (mappings)
+ locus (locus), mappings (mappings)
{}
Location get_locus () const override { return locus; }
@@ -64,6 +61,9 @@ public:
return PatternType::LITERAL;
}
+ Literal &get_literal () { return lit; }
+ const Literal &get_literal () const { return lit; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -962,6 +962,12 @@ protected:
class TuplePatternItems
{
public:
+ enum TuplePatternItemType
+ {
+ MULTIPLE,
+ RANGED,
+ };
+
virtual ~TuplePatternItems () {}
// TODO: should this store location data?
@@ -977,6 +983,8 @@ public:
virtual void accept_vis (HIRFullVisitor &vis) = 0;
+ virtual TuplePatternItemType get_pattern_type () const = 0;
+
protected:
// pure virtual clone implementation
virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
@@ -1019,6 +1027,17 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
+ TuplePatternItemType get_pattern_type () const override
+ {
+ return TuplePatternItemType::MULTIPLE;
+ }
+
+ std::vector<std::unique_ptr<Pattern> > &get_patterns () { return patterns; }
+ const std::vector<std::unique_ptr<Pattern> > &get_patterns () const
+ {
+ return patterns;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1077,6 +1096,11 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
+ TuplePatternItemType get_pattern_type () const override
+ {
+ return TuplePatternItemType::RANGED;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1135,6 +1159,9 @@ public:
return PatternType::TUPLE;
}
+ std::unique_ptr<TuplePatternItems> &get_items () { return items; }
+ const std::unique_ptr<TuplePatternItems> &get_items () const { return items; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
index 0c7c8f3..24cd171 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -100,5 +100,35 @@ PatternDeclaration::visit (AST::StructPattern &pattern)
rust_assert (!struct_pattern_elems.has_etc ());
}
+void
+PatternDeclaration::visit (AST::TuplePattern &pattern)
+{
+ std::unique_ptr<AST::TuplePatternItems> &items = pattern.get_items ();
+ switch (items->get_pattern_type ())
+ {
+ case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
+ AST::TuplePatternItemsMultiple &ref
+ = *static_cast<AST::TuplePatternItemsMultiple *> (
+ pattern.get_items ().get ());
+
+ for (auto &p : ref.get_patterns ())
+ p->accept_vis (*this);
+ }
+ break;
+
+ case AST::TuplePatternItems::TuplePatternItemType::RANGED: {
+ AST::TuplePatternItemsRanged &ref
+ = *static_cast<AST::TuplePatternItemsRanged *> (
+ pattern.get_items ().get ());
+
+ for (auto &p : ref.get_lower_patterns ())
+ p->accept_vis (*this);
+ for (auto &p : ref.get_upper_patterns ())
+ p->accept_vis (*this);
+ }
+ break;
+ }
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h
index dca8258..464e362 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.h
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h
@@ -101,6 +101,8 @@ public:
void visit (AST::TupleStructPattern &pattern) override;
+ void visit (AST::TuplePattern &pattern) override;
+
private:
PatternDeclaration (NodeId parent) : ResolverBase (parent) {}
};
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 32c5881..a924866 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -80,5 +80,177 @@ TypeCheckBase::check_for_unconstrained (
return unconstrained;
}
+TyTy::BaseType *
+TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
+ HIR::Literal &literal, Location locus)
+{
+ TyTy::BaseType *infered = nullptr;
+ switch (literal.get_lit_type ())
+ {
+ case HIR::Literal::LitType::INT: {
+ bool ok = false;
+
+ switch (literal.get_type_hint ())
+ {
+ case CORETYPE_I8:
+ ok = context->lookup_builtin ("i8", &infered);
+ break;
+ case CORETYPE_I16:
+ ok = context->lookup_builtin ("i16", &infered);
+ break;
+ case CORETYPE_I32:
+ ok = context->lookup_builtin ("i32", &infered);
+ break;
+ case CORETYPE_I64:
+ ok = context->lookup_builtin ("i64", &infered);
+ break;
+ case CORETYPE_I128:
+ ok = context->lookup_builtin ("i128", &infered);
+ break;
+
+ case CORETYPE_U8:
+ ok = context->lookup_builtin ("u8", &infered);
+ break;
+ case CORETYPE_U16:
+ ok = context->lookup_builtin ("u16", &infered);
+ break;
+ case CORETYPE_U32:
+ ok = context->lookup_builtin ("u32", &infered);
+ break;
+ case CORETYPE_U64:
+ ok = context->lookup_builtin ("u64", &infered);
+ break;
+ case CORETYPE_U128:
+ ok = context->lookup_builtin ("u128", &infered);
+ break;
+
+ case CORETYPE_F32:
+ literal.set_lit_type (HIR::Literal::LitType::FLOAT);
+ ok = context->lookup_builtin ("f32", &infered);
+ break;
+ case CORETYPE_F64:
+ literal.set_lit_type (HIR::Literal::LitType::FLOAT);
+ ok = context->lookup_builtin ("f64", &infered);
+ break;
+
+ default:
+ ok = true;
+ infered
+ = new TyTy::InferType (expr_mappings.get_hirid (),
+ TyTy::InferType::InferTypeKind::INTEGRAL,
+ locus);
+ break;
+ }
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::FLOAT: {
+ bool ok = false;
+
+ switch (literal.get_type_hint ())
+ {
+ case CORETYPE_F32:
+ ok = context->lookup_builtin ("f32", &infered);
+ break;
+ case CORETYPE_F64:
+ ok = context->lookup_builtin ("f64", &infered);
+ break;
+
+ default:
+ ok = true;
+ infered
+ = new TyTy::InferType (expr_mappings.get_hirid (),
+ TyTy::InferType::InferTypeKind::FLOAT,
+ locus);
+ break;
+ }
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::BOOL: {
+ auto ok = context->lookup_builtin ("bool", &infered);
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::CHAR: {
+ auto ok = context->lookup_builtin ("char", &infered);
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::BYTE: {
+ auto ok = context->lookup_builtin ("u8", &infered);
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::STRING: {
+ TyTy::BaseType *base = nullptr;
+ auto ok = context->lookup_builtin ("str", &base);
+ rust_assert (ok);
+
+ infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
+ TyTy::TyVar (base->get_ref ()),
+ Mutability::Imm);
+ }
+ break;
+
+ case HIR::Literal::LitType::BYTE_STRING: {
+ /* This is an arraytype of u8 reference (&[u8;size]). It isn't in
+ UTF-8, but really just a byte array. Code to construct the array
+ reference copied from ArrayElemsValues and ArrayType. */
+ TyTy::BaseType *u8;
+ auto ok = context->lookup_builtin ("u8", &u8);
+ rust_assert (ok);
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping capacity_mapping (crate_num, UNKNOWN_NODEID,
+ mappings->get_next_hir_id (
+ crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ /* Capacity is the size of the string (number of chars).
+ It is a constant, but for fold it to get a tree. */
+ std::string capacity_str
+ = std::to_string (literal.as_string ().size ());
+ HIR::LiteralExpr *literal_capacity
+ = new HIR::LiteralExpr (capacity_mapping, capacity_str,
+ HIR::Literal::LitType::INT,
+ PrimitiveCoreType::CORETYPE_USIZE, locus, {});
+
+ // mark the type for this implicit node
+ TyTy::BaseType *expected_ty = nullptr;
+ ok = context->lookup_builtin ("usize", &expected_ty);
+ rust_assert (ok);
+ context->insert_type (capacity_mapping, expected_ty);
+
+ Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
+ mappings->get_next_hir_id (
+ crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ TyTy::ArrayType *array
+ = new TyTy::ArrayType (array_mapping.get_hirid (), locus,
+ *literal_capacity,
+ TyTy::TyVar (u8->get_ref ()));
+ context->insert_type (array_mapping, array);
+
+ infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
+ TyTy::TyVar (array->get_ref ()),
+ Mutability::Imm);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ return infered;
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index 5a3f553..159f826 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -55,6 +55,9 @@ protected:
const TyTy::SubstitutionArgumentMappings &constraint_b,
const TyTy::BaseType *reference);
+ TyTy::BaseType *resolve_literal (const Analysis::NodeMapping &mappings,
+ HIR::Literal &literal, Location locus);
+
Analysis::Mappings *mappings;
Resolver *resolver;
TypeCheckContext *context;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index b24ad8b..5db00a4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -535,172 +535,8 @@ public:
void visit (HIR::LiteralExpr &expr) override
{
- switch (expr.get_lit_type ())
- {
- case HIR::Literal::LitType::INT: {
- bool ok = false;
-
- switch (expr.get_literal ().get_type_hint ())
- {
- case CORETYPE_I8:
- ok = context->lookup_builtin ("i8", &infered);
- break;
- case CORETYPE_I16:
- ok = context->lookup_builtin ("i16", &infered);
- break;
- case CORETYPE_I32:
- ok = context->lookup_builtin ("i32", &infered);
- break;
- case CORETYPE_I64:
- ok = context->lookup_builtin ("i64", &infered);
- break;
- case CORETYPE_I128:
- ok = context->lookup_builtin ("i128", &infered);
- break;
-
- case CORETYPE_U8:
- ok = context->lookup_builtin ("u8", &infered);
- break;
- case CORETYPE_U16:
- ok = context->lookup_builtin ("u16", &infered);
- break;
- case CORETYPE_U32:
- ok = context->lookup_builtin ("u32", &infered);
- break;
- case CORETYPE_U64:
- ok = context->lookup_builtin ("u64", &infered);
- break;
- case CORETYPE_U128:
- ok = context->lookup_builtin ("u128", &infered);
- break;
-
- case CORETYPE_F32:
- expr.get_literal ().set_lit_type (HIR::Literal::LitType::FLOAT);
- ok = context->lookup_builtin ("f32", &infered);
- break;
- case CORETYPE_F64:
- expr.get_literal ().set_lit_type (HIR::Literal::LitType::FLOAT);
- ok = context->lookup_builtin ("f64", &infered);
- break;
-
- default:
- ok = true;
- infered
- = new TyTy::InferType (expr.get_mappings ().get_hirid (),
- TyTy::InferType::InferTypeKind::INTEGRAL,
- expr.get_locus ());
- break;
- }
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::FLOAT: {
- bool ok = false;
-
- switch (expr.get_literal ().get_type_hint ())
- {
- case CORETYPE_F32:
- ok = context->lookup_builtin ("f32", &infered);
- break;
- case CORETYPE_F64:
- ok = context->lookup_builtin ("f64", &infered);
- break;
-
- default:
- ok = true;
- infered
- = new TyTy::InferType (expr.get_mappings ().get_hirid (),
- TyTy::InferType::InferTypeKind::FLOAT,
- expr.get_locus ());
- break;
- }
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::BOOL: {
- auto ok = context->lookup_builtin ("bool", &infered);
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::CHAR: {
- auto ok = context->lookup_builtin ("char", &infered);
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::BYTE: {
- auto ok = context->lookup_builtin ("u8", &infered);
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::STRING: {
- TyTy::BaseType *base = nullptr;
- auto ok = context->lookup_builtin ("str", &base);
- rust_assert (ok);
-
- infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
- TyTy::TyVar (base->get_ref ()),
- Mutability::Imm);
- }
- break;
-
- case HIR::Literal::LitType::BYTE_STRING: {
- /* This is an arraytype of u8 reference (&[u8;size]). It isn't in
- UTF-8, but really just a byte array. Code to construct the array
- reference copied from ArrayElemsValues and ArrayType. */
- TyTy::BaseType *u8;
- auto ok = context->lookup_builtin ("u8", &u8);
- rust_assert (ok);
-
- auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping capacity_mapping (crate_num, UNKNOWN_NODEID,
- mappings->get_next_hir_id (
- crate_num),
- UNKNOWN_LOCAL_DEFID);
-
- /* Capacity is the size of the string (number of chars).
- It is a constant, but for fold it to get a tree. */
- std::string capacity_str
- = std::to_string (expr.get_literal ().as_string ().size ());
- HIR::LiteralExpr *literal_capacity
- = new HIR::LiteralExpr (capacity_mapping, capacity_str,
- HIR::Literal::LitType::INT,
- PrimitiveCoreType::CORETYPE_USIZE,
- expr.get_locus (), expr.get_outer_attrs ());
-
- // mark the type for this implicit node
- TyTy::BaseType *expected_ty = nullptr;
- ok = context->lookup_builtin ("usize", &expected_ty);
- rust_assert (ok);
- context->insert_type (capacity_mapping, expected_ty);
-
- Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
- mappings->get_next_hir_id (
- crate_num),
- UNKNOWN_LOCAL_DEFID);
-
- TyTy::ArrayType *array
- = new TyTy::ArrayType (array_mapping.get_hirid (),
- expr.get_locus (), *literal_capacity,
- TyTy::TyVar (u8->get_ref ()));
- context->insert_type (array_mapping, array);
-
- infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
- TyTy::TyVar (array->get_ref ()),
- Mutability::Imm);
- }
- break;
-
- default:
- gcc_unreachable ();
- break;
- }
-
- infered = infered->clone ();
+ infered = resolve_literal (expr.get_mappings (), expr.get_literal (),
+ expr.get_locus ());
}
void visit (HIR::ArithmeticOrLogicalExpr &expr) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index feedbc5..52d0d47 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -232,5 +232,46 @@ TypeCheckPattern::visit (HIR::WildcardPattern &pattern)
infered->set_ref (pattern.get_pattern_mappings ().get_hirid ());
}
+void
+TypeCheckPattern::visit (HIR::TuplePattern &pattern)
+{
+ std::unique_ptr<HIR::TuplePatternItems> items;
+ switch (pattern.get_items ()->get_pattern_type ())
+ {
+ case HIR::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
+ HIR::TuplePatternItemsMultiple &ref
+ = *static_cast<HIR::TuplePatternItemsMultiple *> (
+ pattern.get_items ().get ());
+
+ std::vector<TyTy::TyVar> pattern_elems;
+ for (auto &p : ref.get_patterns ())
+ {
+ TyTy::BaseType *elem = TypeCheckPattern::Resolve (p.get (), parent);
+ pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
+ }
+ infered
+ = new TyTy::TupleType (pattern.get_pattern_mappings ().get_hirid (),
+ pattern.get_locus (), pattern_elems);
+ }
+ break;
+
+ case HIR::TuplePatternItems::TuplePatternItemType::RANGED: {
+ // HIR::TuplePatternItemsRanged &ref
+ // = *static_cast<HIR::TuplePatternItemsRanged *> (
+ // pattern.get_items ().get ());
+ // TODO
+ gcc_unreachable ();
+ }
+ break;
+ }
+}
+
+void
+TypeCheckPattern::visit (HIR::LiteralPattern &pattern)
+{
+ infered = resolve_literal (pattern.get_pattern_mappings (),
+ pattern.get_literal (), pattern.get_locus ());
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.h b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
index ef530b3..b76c7ba 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
@@ -39,6 +39,8 @@ public:
return new TyTy::ErrorType (
pattern->get_pattern_mappings ().get_hirid ());
+ resolver.context->insert_type (pattern->get_pattern_mappings (),
+ resolver.infered);
return resolver.infered;
}
@@ -50,13 +52,17 @@ public:
void visit (HIR::WildcardPattern &pattern) override;
+ void visit (HIR::TuplePattern &pattern) override;
+
+ void visit (HIR::LiteralPattern &pattern) override;
+
private:
TypeCheckPattern (TyTy::BaseType *parent)
- : TypeCheckBase (), infered (nullptr), parent (parent)
+ : TypeCheckBase (), parent (parent), infered (nullptr)
{}
- TyTy::BaseType *infered;
TyTy::BaseType *parent;
+ TyTy::BaseType *infered;
};
} // namespace Resolver