mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Fixed constraint checks for inner types
This commit is contained in:
parent
439b34f7c2
commit
bca82c231f
3 changed files with 76 additions and 6 deletions
|
@ -119,6 +119,38 @@ namespace IDETest
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TestExt<T> where T : struct
|
||||||
|
{
|
||||||
|
public struct InnerA
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct InnerB<T2> where T2 : struct
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TestExt<T>
|
||||||
|
where T : Int
|
||||||
|
{
|
||||||
|
public int a = 0;
|
||||||
|
|
||||||
|
public struct InnerC
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TestExtMethod()
|
||||||
|
{
|
||||||
|
TestExt<String>.InnerA a; //FAIL
|
||||||
|
TestExt<String>.InnerB<int> b; //FAIL
|
||||||
|
TestExt<int>.InnerB<int> c;
|
||||||
|
TestExt<int>.InnerC d;
|
||||||
|
TestExt<float>.InnerC e; //FAIL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -719,6 +719,18 @@ void BfAutoComplete::AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& f
|
||||||
|
|
||||||
for (auto innerType : typeInst->mTypeDef->mNestedTypes)
|
for (auto innerType : typeInst->mTypeDef->mNestedTypes)
|
||||||
{
|
{
|
||||||
|
if (innerType->mOuterType->mTypeCode == BfTypeCode_Extension)
|
||||||
|
{
|
||||||
|
if (typeInst->mDefineState < BfTypeDefineState_Defined)
|
||||||
|
mModule->PopulateType(typeInst);
|
||||||
|
|
||||||
|
if ((typeInst->mGenericTypeInfo != NULL) && (typeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL))
|
||||||
|
{
|
||||||
|
if (!typeInst->mGenericTypeInfo->mGenericExtensionInfo->mConstraintsPassedSet.IsSet(innerType->mOuterType->mPartialIdx))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (CheckProtection(innerType->mProtection, innerType, allowProtected, allowPrivate))
|
if (CheckProtection(innerType->mProtection, innerType, allowProtected, allowPrivate))
|
||||||
AddTypeDef(innerType, filter);
|
AddTypeDef(innerType, filter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9429,8 +9429,25 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
Fail(StrFormat("'%s' is inaccessible due to its protection level", TypeToString(typeInstance).c_str()), typeRef); // CS0122
|
Fail(StrFormat("'%s' is inaccessible due to its protection level", TypeToString(typeInstance).c_str()), typeRef); // CS0122
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((populateType > BfPopulateType_IdentityNoRemapAlias) && (!ResolveTypeResult_Validate(typeRef, resolvedTypeRef)))
|
// If the inner type is definted in an extension then we need to make sure the constraints are good
|
||||||
|
if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL) && (typeInstance->mTypeDef->mOuterType != NULL) &&
|
||||||
|
(typeInstance->mTypeDef->mOuterType->mTypeCode == BfTypeCode_Extension))
|
||||||
|
{
|
||||||
|
auto outerType = GetOuterType(typeInstance);
|
||||||
|
if ((outerType->mGenericTypeInfo != NULL) && (outerType->mGenericTypeInfo->mGenericExtensionInfo != NULL))
|
||||||
|
{
|
||||||
|
if (!outerType->mGenericTypeInfo->mGenericExtensionInfo->mConstraintsPassedSet.IsSet(typeInstance->mTypeDef->mOuterType->mPartialIdx))
|
||||||
|
{
|
||||||
|
Fail(StrFormat("'%s' is declared inside a type extension whose constraints were not met", TypeToString(typeInstance).c_str()), typeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (populateType > BfPopulateType_IdentityNoRemapAlias)
|
||||||
|
{
|
||||||
|
if (!ResolveTypeResult_Validate(typeRef, resolvedTypeRef))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((populateType != BfPopulateType_TypeDef) && (populateType != BfPopulateType_IdentityNoRemapAlias))
|
if ((populateType != BfPopulateType_TypeDef) && (populateType != BfPopulateType_IdentityNoRemapAlias))
|
||||||
{
|
{
|
||||||
|
@ -10827,7 +10844,16 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
if (leftType == NULL)
|
if (leftType == NULL)
|
||||||
{
|
{
|
||||||
BfAutoParentNodeEntry autoParentNodeEntry(this, qualifiedTypeRef);
|
BfAutoParentNodeEntry autoParentNodeEntry(this, qualifiedTypeRef);
|
||||||
leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Identity, (BfResolveTypeRefFlags)((resolveFlags | BfResolveTypeRefFlag_IgnoreLookupError) & ~BfResolveTypeRefFlag_Attribute)); // We throw an error below if we can't find the type
|
|
||||||
|
auto leftPopulateType = BfPopulateType_Identity;
|
||||||
|
if ((resolveFlags & BfResolveTypeRefFlag_AllowUnboundGeneric) == 0)
|
||||||
|
{
|
||||||
|
// We can't just pass 'Identity' here because it won't validate a generic type ref on the left
|
||||||
|
leftPopulateType = BfPopulateType_Declaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, leftPopulateType,
|
||||||
|
(BfResolveTypeRefFlags)((resolveFlags | BfResolveTypeRefFlag_IgnoreLookupError) & ~BfResolveTypeRefFlag_Attribute)); // We throw an error below if we can't find the type
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leftType == NULL)
|
if (leftType == NULL)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue