diff options
author | Yizhe <yizhe@pku.edu.cn> | 2021-02-16 12:34:03 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-02-19 10:34:59 +0000 |
commit | 3f2906e5e4fccc2bc6d848a43be7e569036641e6 (patch) | |
tree | bb1b4465a446dffbbfb91707fce4325e7d673fea /gcc | |
parent | 59ce2a981b15c22ab8311aa241cf5d80eada9fbd (diff) | |
download | gcc-3f2906e5e4fccc2bc6d848a43be7e569036641e6.zip gcc-3f2906e5e4fccc2bc6d848a43be7e569036641e6.tar.gz gcc-3f2906e5e4fccc2bc6d848a43be7e569036641e6.tar.bz2 |
Added some doc for BaseRules and BaseType
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-rules.h | 28 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 11 |
2 files changed, 37 insertions, 2 deletions
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index 5593371..be13f0d 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -28,11 +28,33 @@ namespace Rust { namespace TyTy { +/* Rules specify how to unify two Ty. For example, the result of unifying the + two tuples (u64, A) and (B, i64) would be (u64, i64). + + Performing a unification requires a double dispatch. To illustrate, suppose + we want to unify `ty1` and `ty2`. Here's what it looks like: + 1. The caller calls `ty1.unify(ty2)`. This is the first dispatch. + 2. `ty1` creates a rule specific to its type(e.g. TupleRules). + 3. The rule calls `ty2.accept_vis(rule)`. This is the second dispatch. + 4. `ty2` calls `rule.visit(*this)`, which will method-overload to the + correct implementation at compile time. + + The nice thing about Rules is that they seperate unification logic from the + representation of Ty. To support unifying a new Ty, implement its + `accept_vis` and `unify` method to pass the unification request to Rules. + Then, create a new `XXXRules` class and implement one `visit` method for + every Ty it can unify with. */ class BaseRules : public TyVisitor { public: virtual ~BaseRules () {} + /* Unify two ty. Returns a pointer to the newly-created unified ty, or nullptr + if the two types cannot be unified. The caller is responsible for releasing + the memory of the returned ty. + + This method is meant to be used internally by Ty. If you're trying to unify + two ty, you can simply call `unify` on ty themselves. */ BaseType *unify (BaseType *other) { other->accept_vis (*this); @@ -194,7 +216,13 @@ protected: Analysis::Mappings *mappings; Resolver::TypeCheckContext *context; + /* Pointer to the Ty that created this rule. */ BaseType *base; + + /* Temporary storage for the result of a unification. + We could return the result directly instead of storing it in the rule + object, but that involves modifying the visitor pattern to accommodate + the return value, which is too complex. */ BaseType *resolved; }; diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index df39d04..4b0ac86 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -63,16 +63,22 @@ public: void set_ty_ref (HirId id) { ty_ref = id; } + /* Visitor pattern for double dispatch. BaseRules implements TyVisitor. */ virtual void accept_vis (TyVisitor &vis) = 0; virtual std::string as_string () const = 0; + /* Unify two types. Returns a pointer to the newly-created unified ty, or + nullptr if the two ty cannot be unified. The caller is responsible for + releasing the memory of the returned ty. */ virtual BaseType *unify (BaseType *other) = 0; virtual bool is_unit () const { return kind == TypeKind::UNIT; } TypeKind get_kind () const { return kind; } + /* Returns a pointer to a clone of this. The caller is responsible for + * releasing the memory of the returned ty. */ virtual BaseType *clone () = 0; std::set<HirId> get_combined_refs () { return combined; } @@ -81,7 +87,7 @@ public: protected: BaseType (HirId ref, HirId ty_ref, TypeKind kind, - std::set<HirId> refs = std::set<HirId> ()) + std::set<HirId> refs = std::set<HirId> ()) : kind (kind), ref (ref), ty_ref (ty_ref), combined (refs) {} @@ -323,7 +329,8 @@ public: FnType (HirId ref, HirId ty_ref, std::vector<std::pair<HIR::Pattern *, BaseType *> > params, BaseType *type, std::set<HirId> refs = std::set<HirId> ()) - : BaseType (ref, ty_ref, TypeKind::FNDEF, refs), params (params), type (type) + : BaseType (ref, ty_ref, TypeKind::FNDEF, refs), params (params), + type (type) {} void accept_vis (TyVisitor &vis) override; |