2016-12-10 92 views
2

在與黑客的通用功能的限制試驗,我編造了以下內容:Hacklang - 是否可以使用類型常量的類型約束?

<?hh // strict 
class Base {} 
class Derived extends Base {} 
abstract class ImplBase { 
    abstract const type T as Base; 
    public function foo<Tf as this::T>(Tf $v): void {} 
} 
class ImplDerived extends ImplBase { 
    const type T = Derived; 
} 
function foo(ImplDerived $v): void { 
    bar($v); 
} 
function bar(ImplBase $v): void { 
    $v->foo(new Base()); 
    $v->foo(new Derived()); 
} 

原理是基本夠用:向上轉型從具體ImplDerived,請問typechecker治療ImplBase::T爲一個抽象類型bar能按約束投射到Base,還是保留對T = Derived的引用?奇怪的是,答案既不是。在bar每行一個不同的原因而失敗:

  • $v->foo(new Base());因爲Tf是「約束爲一個依賴型<expr#1>::T [...]參照new Base()」失敗。
  • $v->foo(new Derived());失敗,因爲poof! Tf突然變成了Base! 「[this::T]是類型Base的一個對象,由於擴展類型常量ImplBase::T而產生」。

我問不可能,或者這可能還沒有完全實現嗎?

回答

2

有趣的是,你是今天第二個提到我的人;第一個是正在研究改進類型常量和約束之間交互的Hack團隊開發人員之一。

所以是的,我們正在研究它。沒有任何時間表上的承諾來整理它。