1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Fixed invalid generic inference from generic constraints

This commit is contained in:
Brian Fiete 2021-06-25 06:04:48 -07:00
parent 4189d10f41
commit 03e28f3add
4 changed files with 35 additions and 3 deletions

View file

@ -85,5 +85,23 @@ namespace IDETest
{ {
} }
public static void TestGen<T, TItem>(T val)
where T : IEnumerator<TItem>
where TItem : var
{
Console.WriteLine(typeof(decltype(val)).ToString(.. scope .()));
}
public static void TestPreGen<T>()
{
T a = default;
TestGen(a); //FAIL Unable to determine generic argument 'TItem'
}
public static void TestGenBug()
{
TestPreGen<List<int>>();
}
} }
} }

View file

@ -243,6 +243,16 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
if (argType == NULL) if (argType == NULL)
return false; return false;
if (mIgnoreMethodGenericParam)
{
if (argType->IsGenericParam())
{
auto genericParamType = (BfGenericParamType*)argType;
if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
return false;
}
}
if (!wantType->IsUnspecializedType()) if (!wantType->IsUnspecializedType())
return true; return true;
@ -623,6 +633,8 @@ bool BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstan
else else
genericParam = mModule->GetGenericParamInstance(genericParamType); genericParam = mModule->GetGenericParamInstance(genericParamType);
// Generic arg references in constraints refer to the caller, not the callee -- so ignore those
SetAndRestoreValue<bool> prevIgnoreMethodGenericArg(mIgnoreMethodGenericParam, true);
if (genericParam->mTypeConstraint != NULL) if (genericParam->mTypeConstraint != NULL)
InferGenericArgument(methodInstance, genericParam->mTypeConstraint, ifaceConstraint, BfIRValue()); InferGenericArgument(methodInstance, genericParam->mTypeConstraint, ifaceConstraint, BfIRValue());
for (auto argIfaceConstraint : genericParam->mInterfaceConstraints) for (auto argIfaceConstraint : genericParam->mInterfaceConstraints)

View file

@ -138,12 +138,14 @@ public:
BfTypeVector* mCheckMethodGenericArguments; BfTypeVector* mCheckMethodGenericArguments;
SizedArray<BfIRValue, 4> mPrevArgValues; SizedArray<BfIRValue, 4> mPrevArgValues;
int mInferredCount; int mInferredCount;
bool mIgnoreMethodGenericParam;
public: public:
BfGenericInferContext() BfGenericInferContext()
{ {
mModule = NULL; mModule = NULL;
mInferredCount = 0; mInferredCount = 0;
mIgnoreMethodGenericParam = false;
} }
bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue); bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue);
int GetUnresolvedCount() int GetUnresolvedCount()

View file

@ -7483,8 +7483,8 @@ String BfModule::GenericParamSourceToString(const BfGenericParamSource & generic
{ {
if (genericParamSource.mMethodInstance != NULL) if (genericParamSource.mMethodInstance != NULL)
{ {
auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance, false); //auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance, false);
SetAndRestoreValue<BfMethodInstance*> prevMethodInst(methodInst, NULL); //SetAndRestoreValue<BfMethodInstance*> prevMethodInst(mCurMethodInstance, methodInst);
return MethodToString(genericParamSource.mMethodInstance); return MethodToString(genericParamSource.mMethodInstance);
} }
else else