public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Thomas Schwinge <tschwinge@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Add name and type resolution for TuplePatterns Date: Wed, 8 Jun 2022 12:34:14 +0000 (GMT) [thread overview] Message-ID: <20220608123414.8118C38207C0@sourceware.org> (raw) https://gcc.gnu.org/g:dd9e4c1e0ca0b14388a3cd43f18a4e1a7aebe6e5 commit dd9e4c1e0ca0b14388a3cd43f18a4e1a7aebe6e5 Author: Philip Herron <philip.herron@embecosm.com> Date: Thu Apr 21 14:32:21 2022 +0100 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 Diff: --- gcc/rust/hir/tree/rust-hir-full-test.cc | 9 +- gcc/rust/hir/tree/rust-hir-pattern.h | 41 +++++- gcc/rust/resolve/rust-ast-resolve-pattern.cc | 30 ++++ gcc/rust/resolve/rust-ast-resolve-pattern.h | 2 + gcc/rust/typecheck/rust-hir-type-check-base.cc | 172 ++++++++++++++++++++++ gcc/rust/typecheck/rust-hir-type-check-base.h | 3 + gcc/rust/typecheck/rust-hir-type-check-expr.h | 168 +-------------------- gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 41 ++++++ 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 a996228ce31..a53210ba768 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 de4a83e297c..880fc3e2e48 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 0c7c8f37a3a..24cd171384d 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 dca82580e5b..464e3628768 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 32c58816582..a9248669979 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 5a3f553367f..159f8261c9e 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 b24ad8b5e99..5db00a43832 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 feedbc5b899..52d0d479d29 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 ef530b3af77..b76c7baa6c3 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
reply other threads:[~2022-06-08 12:34 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220608123414.8118C38207C0@sourceware.org \ --to=tschwinge@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).