diff options
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 77 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-pattern.h | 7 |
2 files changed, 84 insertions, 0 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc index 52d0d47..bceafde 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc @@ -273,5 +273,82 @@ TypeCheckPattern::visit (HIR::LiteralPattern &pattern) pattern.get_literal (), pattern.get_locus ()); } +void +TypeCheckPattern::visit (HIR::RangePattern &pattern) +{ + // Resolve the upper and lower bounds, and ensure they are compatible types + TyTy::BaseType *upper = nullptr, *lower = nullptr; + + // TODO: It would be nice to factor this out into a helper since the logic for + // both bounds is exactly the same... + switch (pattern.get_upper_bound ()->get_bound_type ()) + { + case HIR::RangePatternBound::RangePatternBoundType::LITERAL: { + HIR::RangePatternBoundLiteral &ref + = *static_cast<HIR::RangePatternBoundLiteral *> ( + pattern.get_upper_bound ().get ()); + + HIR::Literal lit = ref.get_literal (); + + upper = resolve_literal (pattern.get_pattern_mappings (), lit, + pattern.get_locus ()); + } + break; + + case HIR::RangePatternBound::RangePatternBoundType::PATH: { + HIR::RangePatternBoundPath &ref + = *static_cast<HIR::RangePatternBoundPath *> ( + pattern.get_upper_bound ().get ()); + + upper = TypeCheckExpr::Resolve (&ref.get_path (), false); + } + break; + + case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: { + HIR::RangePatternBoundQualPath &ref + = *static_cast<HIR::RangePatternBoundQualPath *> ( + pattern.get_upper_bound ().get ()); + + upper = TypeCheckExpr::Resolve (&ref.get_qualified_path (), false); + } + break; + } + + switch (pattern.get_lower_bound ()->get_bound_type ()) + { + case HIR::RangePatternBound::RangePatternBoundType::LITERAL: { + HIR::RangePatternBoundLiteral &ref + = *static_cast<HIR::RangePatternBoundLiteral *> ( + pattern.get_lower_bound ().get ()); + + HIR::Literal lit = ref.get_literal (); + + lower = resolve_literal (pattern.get_pattern_mappings (), lit, + pattern.get_locus ()); + } + break; + + case HIR::RangePatternBound::RangePatternBoundType::PATH: { + HIR::RangePatternBoundPath &ref + = *static_cast<HIR::RangePatternBoundPath *> ( + pattern.get_lower_bound ().get ()); + + lower = TypeCheckExpr::Resolve (&ref.get_path (), false); + } + break; + + case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: { + HIR::RangePatternBoundQualPath &ref + = *static_cast<HIR::RangePatternBoundQualPath *> ( + pattern.get_lower_bound ().get ()); + + lower = TypeCheckExpr::Resolve (&ref.get_qualified_path (), false); + } + break; + } + + infered = upper->unify (lower); +} + } // 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 b76c7ba..03c4977 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-pattern.h +++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.h @@ -56,11 +56,18 @@ public: void visit (HIR::LiteralPattern &pattern) override; + void visit (HIR::RangePattern &pattern) override; + private: TypeCheckPattern (TyTy::BaseType *parent) : TypeCheckBase (), parent (parent), infered (nullptr) {} + static TyTy::BaseType * + typecheck_range_pattern_bound (HIR::RangePatternBound *bound, + Analysis::NodeMapping mappings, + Location locus); + TyTy::BaseType *parent; TyTy::BaseType *infered; }; |