| 395 | } |
| 396 | |
| 397 | bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* genericTypeInst, bool ignoreErrors) |
| 398 | { |
| 399 | if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsTypeAlias()) && (mCurTypeInstance->IsGenericTypeInstance())) |
| 400 | { |
| 401 | // Don't validate constraints during the population of a concrete generic type alias instance, we want to |
| 402 | // throw those errors at the usage sites |
| 403 | return true; |
| 404 | } |
| 405 | |
| 406 | // We don't validate constraints for things like Tuples/Delegates |
| 407 | if (genericTypeInst->IsOnDemand()) |
| 408 | return true; |
| 409 | |
| 410 | SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, mIgnoreErrors || ignoreErrors); |
| 411 | genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints = true; |
| 412 | if (!genericTypeInst->mGenericTypeInfo->mFinishedGenericParams) |
| 413 | mContext->mUnreifiedModule->PopulateType(genericTypeInst, BfPopulateType_Interfaces_All); |
| 414 | |
| 415 | if (genericTypeInst->IsTypeAlias()) |
| 416 | { |
| 417 | auto underlyingType = genericTypeInst->GetUnderlyingType(); |
| 418 | if ((underlyingType != NULL) && (underlyingType->IsGenericTypeInstance())) |
| 419 | { |
| 420 | auto underlyingGenericType = underlyingType->ToGenericTypeInstance(); |
| 421 | mContext->mUnreifiedModule->PopulateType(underlyingType, BfPopulateType_Declaration); |
| 422 | bool result = ValidateGenericConstraints(typeRef, underlyingGenericType, ignoreErrors); |
| 423 | if (underlyingGenericType->mGenericTypeInfo->mHadValidateErrors) |
| 424 | genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true; |
| 425 | return result; |
| 426 | } |
| 427 | return true; |
| 428 | } |
| 429 | |
| 430 | for (auto typeArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments) |
| 431 | { |
| 432 | auto genericArg = typeArg->ToGenericTypeInstance(); |
| 433 | if (genericArg != NULL) |
| 434 | genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->mGenericTypeInfo->mMaxGenericDepth + 1); |
| 435 | } |
| 436 | |
| 437 | auto typeDef = genericTypeInst->mTypeDef; |
| 438 | |
| 439 | int startGenericParamIdx = 0; |
| 440 | if (typeDef->mOuterType != NULL) |
| 441 | { |
| 442 | startGenericParamIdx = typeDef->mOuterType->mGenericParamDefs.mSize + typeDef->mOuterType->mExternalConstraints.mSize; |
| 443 | auto outerType = GetOuterType(genericTypeInst); |
| 444 | mContext->mUnreifiedModule->PopulateType(outerType, BfPopulateType_Declaration); |
| 445 | if ((outerType->mGenericTypeInfo != NULL) && (outerType->mGenericTypeInfo->mHadValidateErrors)) |
| 446 | genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true; |
| 447 | } |
| 448 | |
| 449 | for (int paramIdx = startGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++) |
| 450 | { |
| 451 | auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx]; |
| 452 | |
| 453 | BfType* genericArg; |
| 454 | if (paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size()) |
nothing calls this directly
no test coverage detected