mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
Fixed error messages for methods with extern constraints in variations
This commit is contained in:
parent
c7393865b4
commit
92d3ab6ca9
3 changed files with 64 additions and 10 deletions
|
@ -1,9 +1,24 @@
|
||||||
|
#pragma warning disable 168
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
namespace System
|
||||||
|
{
|
||||||
|
extension Array1<T>
|
||||||
|
{
|
||||||
|
public static bool operator==(Self lhs, Self rhs) where T : IOpEquals
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace IDETest
|
namespace IDETest
|
||||||
{
|
{
|
||||||
class Generics
|
class Generics
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public void Method1<T>(T val) where T : Array
|
public void Method1<T>(T val) where T : Array
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -13,5 +28,15 @@ namespace IDETest
|
||||||
{
|
{
|
||||||
Method1(val2); //FAIL 'T', declared to be 'T2'
|
Method1(val2); //FAIL 'T', declared to be 'T2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Method3<TFoo>(ref TFoo[] val)
|
||||||
|
{
|
||||||
|
bool eq = val == val; //FAIL Generic argument 'T', declared to be 'TFoo' for 'TFoo[].operator==(TFoo[] lhs, TFoo[] rhs)', must implement 'System.IOpEquals'
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Method4()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,12 @@ void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSized
|
||||||
for (BfTypeReference* genericArg : *methodGenericArguments)
|
for (BfTypeReference* genericArg : *methodGenericArguments)
|
||||||
{
|
{
|
||||||
auto genericArgType = mModule->ResolveTypeRef(genericArg);
|
auto genericArgType = mModule->ResolveTypeRef(genericArg);
|
||||||
|
if (genericArgType->IsGenericParam())
|
||||||
|
{
|
||||||
|
auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)genericArgType);
|
||||||
|
if ((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
|
||||||
|
mHasVarArguments = true;
|
||||||
|
}
|
||||||
mExplicitMethodGenericArguments.push_back(genericArgType);
|
mExplicitMethodGenericArguments.push_back(genericArgType);
|
||||||
}
|
}
|
||||||
mHadExplicitGenericArguments = true;
|
mHadExplicitGenericArguments = true;
|
||||||
|
@ -13023,7 +13029,12 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
{
|
{
|
||||||
checkMethodGenericArgs = &methodMatcher.mBestMethodGenericArguments;
|
checkMethodGenericArgs = &methodMatcher.mBestMethodGenericArguments;
|
||||||
genericArg = genericParams->mExternType;
|
genericArg = genericParams->mExternType;
|
||||||
genericArg = mModule->ResolveGenericType(genericArg, NULL, checkMethodGenericArgs);
|
|
||||||
|
auto owner = methodInstance.mMethodInstance->GetOwner();
|
||||||
|
BfTypeVector* typeGenericArguments = NULL;
|
||||||
|
if (owner->mGenericTypeInfo != NULL)
|
||||||
|
typeGenericArguments = &owner->mGenericTypeInfo->mTypeGenericArguments;
|
||||||
|
genericArg = mModule->ResolveGenericType(genericArg, typeGenericArguments, checkMethodGenericArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (genericArg->IsVar())
|
if (genericArg->IsVar())
|
||||||
|
@ -13039,7 +13050,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
|
|
||||||
// Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized
|
// Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized
|
||||||
BfError* error = NULL;
|
BfError* error = NULL;
|
||||||
if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance.mMethodInstance), genericArg, paramSrc, genericParams, checkMethodGenericArgs,
|
if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance.mMethodInstance), genericArg, paramSrc, genericParams, NULL,
|
||||||
failed ? NULL : &error))
|
failed ? NULL : &error))
|
||||||
{
|
{
|
||||||
if (methodInstance.mMethodInstance->IsSpecializedGenericMethod())
|
if (methodInstance.mMethodInstance->IsSpecializedGenericMethod())
|
||||||
|
|
|
@ -6879,7 +6879,6 @@ String BfModule::GenericParamSourceToString(const BfGenericParamSource & generic
|
||||||
if (genericParamSource.mMethodInstance != NULL)
|
if (genericParamSource.mMethodInstance != NULL)
|
||||||
{
|
{
|
||||||
auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance);
|
auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance);
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInst(mCurMethodInstance, methodInst);
|
|
||||||
return MethodToString(methodInst);
|
return MethodToString(methodInst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -9598,6 +9597,8 @@ String BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags
|
||||||
type = ResolveGenericType(type, NULL, methodGenericArgs);
|
type = ResolveGenericType(type, NULL, methodGenericArgs);
|
||||||
if ((type == NULL) || (!type->IsUnspecializedTypeVariation()))
|
if ((type == NULL) || (!type->IsUnspecializedTypeVariation()))
|
||||||
typeNameFlags = BfTypeNameFlag_ResolveGenericParamNames;
|
typeNameFlags = BfTypeNameFlag_ResolveGenericParamNames;
|
||||||
|
if (allowResolveGenericParamNames)
|
||||||
|
typeNameFlags = BfTypeNameFlag_ResolveGenericParamNames;
|
||||||
|
|
||||||
String methodName;
|
String methodName;
|
||||||
if ((methodNameFlags & BfMethodNameFlag_OmitTypeName) == 0)
|
if ((methodNameFlags & BfMethodNameFlag_OmitTypeName) == 0)
|
||||||
|
@ -11290,6 +11291,8 @@ bool BfModule::CompareMethodSignatures(BfMethodInstance* methodA, BfMethodInstan
|
||||||
return false;
|
return false;
|
||||||
if (methodA->mMethodDef->mCheckedKind != methodB->mMethodDef->mCheckedKind)
|
if (methodA->mMethodDef->mCheckedKind != methodB->mMethodDef->mCheckedKind)
|
||||||
return false;
|
return false;
|
||||||
|
if ((methodA->mMethodDef->mMethodType == BfMethodType_Mixin) != (methodB->mMethodDef->mMethodType == BfMethodType_Mixin))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (methodA->mMethodDef->mMethodType == BfMethodType_Ctor)
|
if (methodA->mMethodDef->mMethodType == BfMethodType_Ctor)
|
||||||
{
|
{
|
||||||
|
@ -15501,6 +15504,7 @@ void BfModule::EmitTupleToStringBody()
|
||||||
|
|
||||||
if (fieldValue.mType->IsObjectOrInterface())
|
if (fieldValue.mType->IsObjectOrInterface())
|
||||||
{
|
{
|
||||||
|
fieldValue = LoadValue(fieldValue);
|
||||||
BF_ASSERT(!fieldValue.IsAddr());
|
BF_ASSERT(!fieldValue.IsAddr());
|
||||||
SizedArray<BfIRValue, 2> args;
|
SizedArray<BfIRValue, 2> args;
|
||||||
args.Add(mBfIRBuilder->CreateBitCast(fieldValue.mValue, mBfIRBuilder->MapType(mContext->mBfObjectType)));
|
args.Add(mBfIRBuilder->CreateBitCast(fieldValue.mValue, mBfIRBuilder->MapType(mContext->mBfObjectType)));
|
||||||
|
@ -19839,8 +19843,15 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
if (mCompiler->mResolvePassData != NULL)
|
if (mCompiler->mResolvePassData != NULL)
|
||||||
bfAutocomplete = mCompiler->mResolvePassData->mAutoComplete;
|
bfAutocomplete = mCompiler->mResolvePassData->mAutoComplete;
|
||||||
|
|
||||||
|
if ((methodDeclaration != NULL) && (methodDeclaration->ToString().Contains("//TEST")))
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
if (methodInstance->mMethodInfoEx != NULL)
|
if (methodInstance->mMethodInfoEx != NULL)
|
||||||
{
|
{
|
||||||
|
BfTypeInstance* unspecializedTypeInstance = NULL;
|
||||||
|
|
||||||
for (int genericParamIdx = 0; genericParamIdx < (int)methodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
|
for (int genericParamIdx = 0; genericParamIdx < (int)methodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
|
||||||
{
|
{
|
||||||
auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
|
auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
|
||||||
|
@ -19850,8 +19861,15 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (unspecializedTypeInstance == NULL)
|
||||||
|
unspecializedTypeInstance = GetUnspecializedTypeInstance(mCurTypeInstance);
|
||||||
|
|
||||||
auto externConstraintDef = genericParam->GetExternConstraintDef();
|
auto externConstraintDef = genericParam->GetExternConstraintDef();
|
||||||
|
// Resolve in the unspecialized type, then resolve the generic later. This fixes ambiguity where the type is specialized by a method generic arg
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, unspecializedTypeInstance);
|
||||||
genericParam->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
|
genericParam->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
|
||||||
|
}
|
||||||
|
|
||||||
auto autoComplete = mCompiler->GetAutoComplete();
|
auto autoComplete = mCompiler->GetAutoComplete();
|
||||||
if (autoComplete != NULL)
|
if (autoComplete != NULL)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue