diff --git a/hphp/runtime/vm/type_constraint.cpp b/hphp/runtime/vm/type_constraint.cpp index 39133fcbf..1906d888c 100644 --- a/hphp/runtime/vm/type_constraint.cpp +++ b/hphp/runtime/vm/type_constraint.cpp @@ -182,9 +182,14 @@ TypeConstraint::check(const TypedValue* tv, const Func* func) const { return true; } - return isObjectOrTypedef() && !isCallable() - ? checkTypedefNonObj(tv) - : equivDataTypes(m_type.m_dt, tv->m_type); + if (isObjectOrTypedef()) { + if (isCallable()) { + return f_is_callable(tvAsCVarRef(tv)); + } + return checkTypedefNonObj(tv); + } + + return equivDataTypes(m_type.m_dt, tv->m_type); } bool diff --git a/hphp/test/quick/callable.php b/hphp/test/quick/callable.php index 0f68d189b..bd26a3311 100644 --- a/hphp/test/quick/callable.php +++ b/hphp/test/quick/callable.php @@ -5,9 +5,19 @@ function check($f) { var_dump(is_callable($f)); } +function typehint(callable $a) { + var_dump('worked'); +} + +function id() {} + function main() { check(''); - check('main'); + check('id'); check('blarblah'); + + $cl = function() { return 'closure'; }; + typehint($cl); + typehint('id'); } main(); diff --git a/hphp/test/quick/callable.php.expect b/hphp/test/quick/callable.php.expect index 3eafbf522..bc342550b 100644 --- a/hphp/test/quick/callable.php.expect +++ b/hphp/test/quick/callable.php.expect @@ -1,6 +1,8 @@ string(0) "" bool(false) -string(4) "main" +string(2) "id" bool(true) string(8) "blarblah" bool(false) +string(6) "worked" +string(6) "worked"