aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorYizhe <yizhe@pku.edu.cn>2021-02-16 12:34:03 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-02-19 10:34:59 +0000
commit3f2906e5e4fccc2bc6d848a43be7e569036641e6 (patch)
treebb1b4465a446dffbbfb91707fce4325e7d673fea /gcc
parent59ce2a981b15c22ab8311aa241cf5d80eada9fbd (diff)
downloadgcc-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.h28
-rw-r--r--gcc/rust/typecheck/rust-tyty.h11
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;