diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-04-21 14:32:21 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-04-21 16:06:18 +0100 |
commit | dd9e4c1e0ca0b14388a3cd43f18a4e1a7aebe6e5 (patch) | |
tree | 234a6e1ecdbb1b0a185bf94c50121959926e90cc | |
parent | fe10ca37aba8f3cb9bfaa9dd01bdb1329317cf21 (diff) | |
download | gcc-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.cc | 9 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-pattern.h | 41 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-pattern.cc | 30 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-pattern.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-base.cc | 172 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-base.h | 3 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 168 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 41 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-pattern.h | 10 |
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 |