Type native_function_return_type(const php::Func* f, bool include_coercion_failures) { assert(f->nativeInfo); // If the function returns by ref, we can't say much about it. It can be a ref // or null. if (f->attrs & AttrReference) { return union_of(TRef, TInitNull); } // Infer the type from the HNI declaration auto t = [&]{ auto const hni = f->nativeInfo->returnType; return hni ? from_DataType(*hni) : TInitCell; }(); if (t.subtypeOf(BArr)) { if (f->retTypeConstraint.isVArray()) { assertx(!RuntimeOption::EvalHackArrDVArrs); t = TVArr; } else if (f->retTypeConstraint.isDArray()) { assertx(!RuntimeOption::EvalHackArrDVArrs); t = TDArr; } else if (f->retTypeConstraint.isArray()) { t = TPArr; } } // Non-simple types (ones that are represented by pointers) can always // possibly be null. if (t.subtypeOfAny(TStr, TArr, TVec, TDict, TKeyset, TObj, TRes)) { t |= TInitNull; } else { // Otherwise it should be a simple type or possibly everything. assert(t == TInitCell || t.subtypeOfAny(TBool, TInt, TDbl, TNull)); } if (include_coercion_failures) { // If parameter coercion fails, we can also get null or false depending on // the function. if (f->attrs & AttrParamCoerceModeNull) { t |= TInitNull; } if (f->attrs & AttrParamCoerceModeFalse) { t |= TFalse; } } return remove_uninit(t); }
Type native_function_return_type(borrowed_ptr<const php::Func> f, bool include_coercion_failures) { assert(f->nativeInfo); // If the function returns by ref, we can't say much about it. It can be a ref // or null. if (f->attrs & AttrReference) { return union_of(TRef, TInitNull); } // Infer the type from the HNI declaration auto const hni = f->nativeInfo->returnType; auto t = hni ? from_DataType(*hni) : TInitCell; // Non-simple types (ones that are represented by pointers) can always // possibly be null. if (t.subtypeOfAny(TStr, TArr, TVec, TDict, TKeyset, TObj, TRes)) { t = union_of(t, TInitNull); } else { // Otherwise it should be a simple type or possibly everything. assert(t == TInitCell || t.subtypeOfAny(TBool, TInt, TDbl, TNull)); } if (include_coercion_failures) { // If parameter coercion fails, we can also get null or false depending on // the function. if (f->attrs & AttrParamCoerceModeNull) { t = union_of(t, TInitNull); } if (f->attrs & AttrParamCoerceModeFalse) { t = union_of(t, TFalse); } } return remove_uninit(t); }