mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Added comptype
This commit is contained in:
parent
bb12a4ec20
commit
4890303508
27 changed files with 382 additions and 157 deletions
|
@ -4947,7 +4947,7 @@ namespace IDE.ui
|
|||
{
|
||||
if (mHoverResolveTask == null)
|
||||
{
|
||||
if ((!handlingHoverResolveTask) && (!ResolveCompiler.mThreadWorkerHi.mThreadRunning))
|
||||
if ((!handlingHoverResolveTask) && (!ResolveCompiler.mThreadWorkerHi.mThreadRunning) && (gApp.mSettings.mEditorSettings.mHiliteCursorReferences))
|
||||
{
|
||||
ResolveParams resolveParams = new .();
|
||||
resolveParams.mOverrideCursorPos = (int32)textIdx;
|
||||
|
|
|
@ -1986,6 +1986,12 @@ void BeCOFFObject::Generate(BeModule* module)
|
|||
{
|
||||
auto globalVar = module->mGlobalVariables[globalVarIdx];
|
||||
|
||||
if ((globalVar->mRefCount == 0) && (globalVar->mInitializer == NULL))
|
||||
{
|
||||
globalVarSyms.push_back(NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
BeMCSymbol* sym = mSymbols.Alloc();
|
||||
sym->mType = globalVar->mType;
|
||||
sym->mName = globalVar->mName;
|
||||
|
@ -2001,6 +2007,10 @@ void BeCOFFObject::Generate(BeModule* module)
|
|||
for (int globalVarIdx = 0; globalVarIdx < (int)module->mGlobalVariables.size(); globalVarIdx++)
|
||||
{
|
||||
auto globalVar = module->mGlobalVariables[globalVarIdx];
|
||||
|
||||
if ((globalVar->mRefCount == 0) && (globalVar->mInitializer == NULL))
|
||||
continue;
|
||||
|
||||
auto sym = globalVarSyms[globalVarIdx];
|
||||
|
||||
if (globalVar->mInitializer != NULL)
|
||||
|
|
|
@ -710,6 +710,7 @@ void BeIRCodeGen::Read(BeValue*& beValue)
|
|||
}
|
||||
else
|
||||
beValue = GetBeValue(streamId);
|
||||
beValue->mRefCount++;
|
||||
BE_MEM_END("ParamType_Const_GlobalVar");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -291,7 +291,7 @@ void BfStructuralVisitor::Visit(BfDelegateTypeRef* typeRef)
|
|||
Visit(typeRef->ToBase());
|
||||
}
|
||||
|
||||
void BfStructuralVisitor::Visit(BfDeclTypeRef* declTypeRef)
|
||||
void BfStructuralVisitor::Visit(BfExprModTypeRef* declTypeRef)
|
||||
{
|
||||
Visit(declTypeRef->ToBase());
|
||||
}
|
||||
|
@ -1307,6 +1307,8 @@ const char* Beefy::BfTokenToString(BfToken token)
|
|||
return "checked";
|
||||
case BfToken_Class:
|
||||
return "class";
|
||||
case BfToken_Comptype:
|
||||
return "comptype";
|
||||
case BfToken_Concrete:
|
||||
return "concrete";
|
||||
case BfToken_Const:
|
||||
|
|
|
@ -122,6 +122,7 @@ enum BfToken : uint8
|
|||
BfToken_Catch,
|
||||
BfToken_Checked,
|
||||
BfToken_Class,
|
||||
BfToken_Comptype,
|
||||
BfToken_Concrete,
|
||||
BfToken_Const,
|
||||
BfToken_Continue,
|
||||
|
@ -308,7 +309,7 @@ class BfLetTypeReference;
|
|||
class BfGenericInstanceTypeRef;
|
||||
class BfTupleTypeRef;
|
||||
class BfDelegateTypeRef;
|
||||
class BfDeclTypeRef;
|
||||
class BfExprModTypeRef;
|
||||
class BfCommentNode;
|
||||
class BfIfStatement;
|
||||
class BfParenthesizedExpression;
|
||||
|
@ -474,7 +475,7 @@ public:
|
|||
virtual void Visit(BfGenericInstanceTypeRef* typeRef);
|
||||
virtual void Visit(BfTupleTypeRef* typeRef);
|
||||
virtual void Visit(BfDelegateTypeRef* typeRef);
|
||||
virtual void Visit(BfDeclTypeRef* declTypeRef);
|
||||
virtual void Visit(BfExprModTypeRef* declTypeRef);
|
||||
virtual void Visit(BfPointerTypeRef* typeRef);
|
||||
virtual void Visit(BfNullableTypeRef* typeRef);
|
||||
virtual void Visit(BfVariableDeclaration* varDecl);
|
||||
|
@ -2543,16 +2544,16 @@ public:
|
|||
BfAstNode* mCloseParen;
|
||||
}; BF_AST_DECL(BfDelegateTypeRef, BfTypeReference);
|
||||
|
||||
class BfDeclTypeRef : public BfTypeReference
|
||||
class BfExprModTypeRef : public BfTypeReference
|
||||
{
|
||||
public:
|
||||
BF_AST_TYPE(BfDeclTypeRef, BfTypeReference);
|
||||
BF_AST_TYPE(BfExprModTypeRef, BfTypeReference);
|
||||
|
||||
BfTokenNode* mToken;
|
||||
BfTokenNode* mOpenParen;
|
||||
BfExpression* mTarget;
|
||||
BfTokenNode* mCloseParen;
|
||||
}; BF_AST_DECL(BfDeclTypeRef, BfTypeReference);
|
||||
}; BF_AST_DECL(BfExprModTypeRef, BfTypeReference);
|
||||
|
||||
enum BfGenericParamKind
|
||||
{
|
||||
|
|
|
@ -1708,6 +1708,8 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken
|
|||
// Statics, inner types
|
||||
|
||||
auto checkType = targetValue.mType;
|
||||
if (checkType->IsConcreteInterfaceType())
|
||||
checkType = checkType->GetUnderlyingType();
|
||||
|
||||
if (checkType->IsGenericParam())
|
||||
{
|
||||
|
|
|
@ -7296,7 +7296,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
|
||||
if ((mCEMachine != NULL) && (!mIsResolveOnly) && (mCEMachine->mRevisionExecuteTime > 0))
|
||||
{
|
||||
mPassInstance->OutputLine(StrFormat(":med Const evaluation time: %0.2fs", mCEMachine->mRevisionExecuteTime / 1000.0f));
|
||||
mPassInstance->OutputLine(StrFormat(":med Comptime execution time: %0.2fs", mCEMachine->mRevisionExecuteTime / 1000.0f));
|
||||
}
|
||||
|
||||
BpLeave();
|
||||
|
|
|
@ -103,7 +103,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
|||
wantIgnoreWrites = true;
|
||||
}
|
||||
|
||||
SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, wantIgnoreWrites);
|
||||
SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, wantIgnoreWrites);
|
||||
|
||||
auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
|
||||
|
||||
|
@ -139,7 +139,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
|||
{
|
||||
if ((flags & BfConstResolveFlag_RemapFromStringId) != 0)
|
||||
{
|
||||
ignoreWrites.Restore();
|
||||
prevIgnoreWrites.Restore();
|
||||
mModule->mBfIRBuilder->PopulateType(mResult.mType);
|
||||
return BfTypedValue(mModule->GetStringObjectValue(stringId), mResult.mType);
|
||||
}
|
||||
|
@ -232,6 +232,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
|||
}*/
|
||||
|
||||
mModule->FixIntUnknown(mResult);
|
||||
mModule->FixValueActualization(mResult);
|
||||
|
||||
return mResult;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ BfContext::BfContext(BfCompiler* compiler) :
|
|||
mMappedObjectRevision = 0;
|
||||
mDeleting = false;
|
||||
mLockModules = false;
|
||||
mAllowLockYield = true;
|
||||
|
||||
mCurTypeState = NULL;
|
||||
mCurConstraintState = NULL;
|
||||
|
@ -255,9 +256,15 @@ void BfContext::EnsureHotMangledVirtualMethodNames()
|
|||
}
|
||||
}
|
||||
|
||||
void BfContext::CheckLockYield()
|
||||
{
|
||||
if (mAllowLockYield)
|
||||
mSystem->CheckLockYield();
|
||||
}
|
||||
|
||||
bool BfContext::IsCancellingAndYield()
|
||||
{
|
||||
mSystem->CheckLockYield();
|
||||
CheckLockYield();
|
||||
return mCompiler->mCanceling;
|
||||
}
|
||||
|
||||
|
|
|
@ -309,6 +309,8 @@ public:
|
|||
BfType* mLeftType;
|
||||
BfType* mRightType;
|
||||
BfConstraintState* mPrevState;
|
||||
BfMethodInstance* mMethodInstance;
|
||||
BfTypeVector* mMethodGenericArgsOverride;
|
||||
|
||||
public:
|
||||
BfConstraintState()
|
||||
|
@ -316,6 +318,8 @@ public:
|
|||
mGenericParamInstance = NULL;
|
||||
mLeftType = NULL;
|
||||
mRightType = NULL;
|
||||
mMethodInstance = NULL;
|
||||
mMethodGenericArgsOverride = NULL;
|
||||
mPrevState = NULL;
|
||||
}
|
||||
|
||||
|
@ -343,6 +347,7 @@ public:
|
|||
BfSystem* mSystem;
|
||||
BfCompiler* mCompiler;
|
||||
|
||||
bool mAllowLockYield;
|
||||
bool mLockModules;
|
||||
BfModule* mScratchModule;
|
||||
BfModule* mUnreifiedModule;
|
||||
|
@ -433,6 +438,7 @@ public:
|
|||
void ReportMemory(MemReporter* memReporter);
|
||||
void ProcessMethod(BfMethodInstance* methodInstance);
|
||||
int GetStringLiteralId(const StringImpl& str);
|
||||
void CheckLockYield();
|
||||
bool IsCancellingAndYield();
|
||||
void QueueFinishModule(BfModule * module);
|
||||
void CancelWorkItems();
|
||||
|
|
|
@ -414,7 +414,7 @@ void BfElementVisitor::Visit(BfTupleTypeRef* typeRef)
|
|||
VisitChild(typeRef->mCloseParen);
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfDeclTypeRef* typeRef)
|
||||
void BfElementVisitor::Visit(BfExprModTypeRef* typeRef)
|
||||
{
|
||||
Visit(typeRef->ToBase());
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
virtual void Visit(BfArrayTypeRef* typeRef);
|
||||
virtual void Visit(BfGenericInstanceTypeRef* typeRef);
|
||||
virtual void Visit(BfTupleTypeRef* typeRef);
|
||||
virtual void Visit(BfDeclTypeRef* typeRef);
|
||||
virtual void Visit(BfExprModTypeRef* typeRef);
|
||||
virtual void Visit(BfDelegateTypeRef* typeRef);
|
||||
virtual void Visit(BfPointerTypeRef* typeRef);
|
||||
virtual void Visit(BfNullableTypeRef* typeRef);
|
||||
|
|
|
@ -588,14 +588,13 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
|
|||
return true;
|
||||
}
|
||||
|
||||
void BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstance)
|
||||
{
|
||||
// Attempt to infer from other generic args
|
||||
for (int srcGenericIdx = 0; srcGenericIdx < (int)mCheckMethodGenericArguments->size(); srcGenericIdx++)
|
||||
bool BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstance, int srcGenericIdx)
|
||||
{
|
||||
auto& srcGenericArg = (*mCheckMethodGenericArguments)[srcGenericIdx];
|
||||
if (srcGenericArg == NULL)
|
||||
continue;
|
||||
return false;
|
||||
|
||||
int startInferCount = mInferredCount;
|
||||
|
||||
auto srcGenericParam = methodInstance->mMethodInfoEx->mGenericParams[srcGenericIdx];
|
||||
for (auto ifaceConstraint : srcGenericParam->mInterfaceConstraints)
|
||||
|
@ -611,30 +610,18 @@ void BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstan
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mInferredCount != startInferCount;
|
||||
}
|
||||
|
||||
// void BfGenericInferContext::PropogateInference(BfType* resolvedType, BfType* unresovledType)
|
||||
// {
|
||||
// if (!unresovledType->IsUnspecializedTypeVariation())
|
||||
// return;
|
||||
//
|
||||
// auto resolvedTypeInstance = resolvedType->ToTypeInstance();
|
||||
// auto unresolvedTypeInstance = unresovledType->ToTypeInstance();
|
||||
//
|
||||
// if ((resolvedTypeInstance == NULL) || (unresolvedTypeInstance == NULL))
|
||||
// return;
|
||||
// if (resolvedTypeInstance->mTypeDef != unresolvedTypeInstance->mTypeDef)
|
||||
// return;
|
||||
//
|
||||
// if (unres)
|
||||
//
|
||||
// if (resolvedType->IsGenericTypeInstance())
|
||||
// {
|
||||
//
|
||||
//
|
||||
// }
|
||||
// }
|
||||
void BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstance)
|
||||
{
|
||||
// Attempt to infer from other generic args
|
||||
for (int srcGenericIdx = 0; srcGenericIdx < (int)mCheckMethodGenericArguments->size(); srcGenericIdx++)
|
||||
{
|
||||
InferGenericArguments(methodInstance, srcGenericIdx);
|
||||
}
|
||||
}
|
||||
|
||||
int BfMethodMatcher::GetMostSpecificType(BfType* lhs, BfType* rhs)
|
||||
{
|
||||
|
@ -1440,10 +1427,10 @@ bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInst
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BfMethodMatcher::InferFromGenericConstraints(BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs)
|
||||
bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs)
|
||||
{
|
||||
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Equals) == 0)
|
||||
return false;
|
||||
// if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Equals) == 0)
|
||||
// return false;
|
||||
|
||||
if (!genericParamInst->mExternType->IsGenericParam())
|
||||
return false;
|
||||
|
@ -1490,6 +1477,9 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfGenericParamInstance* generi
|
|||
|
||||
if (checkOpConstraint.mBinaryOp != BfBinaryOp_None)
|
||||
{
|
||||
if ((leftType == NULL) || (rightType == NULL))
|
||||
continue;
|
||||
|
||||
BfExprEvaluator exprEvaluator(mModule);
|
||||
|
||||
BfTypedValue leftValue(mModule->mBfIRBuilder->GetFakeVal(), leftType);
|
||||
|
@ -1507,6 +1497,9 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfGenericParamInstance* generi
|
|||
}
|
||||
else
|
||||
{
|
||||
if (rightType == NULL)
|
||||
continue;
|
||||
|
||||
BfTypedValue rightValue(mModule->mBfIRBuilder->GetFakeVal(), rightType);
|
||||
|
||||
StringT<128> failedOpName;
|
||||
|
@ -1537,6 +1530,28 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfGenericParamInstance* generi
|
|||
}
|
||||
}
|
||||
|
||||
if ((checkArgType == NULL) && ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_ComptypeExpr) != 0))
|
||||
{
|
||||
for (auto comptypeConstraint : genericParamInst->mComptypeConstraint)
|
||||
{
|
||||
BfConstraintState constraintSet;
|
||||
constraintSet.mPrevState = mModule->mContext->mCurConstraintState;
|
||||
constraintSet.mGenericParamInstance = genericParamInst;
|
||||
constraintSet.mMethodInstance = methodInstance;
|
||||
constraintSet.mMethodGenericArgsOverride = methodGenericArgs;
|
||||
|
||||
SetAndRestoreValue<BfConstraintState*> prevConstraintSet(mModule->mContext->mCurConstraintState, &constraintSet);
|
||||
if (!mModule->CheckConstraintState(NULL))
|
||||
return false;
|
||||
|
||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mModule->mCurMethodInstance, methodInstance);
|
||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mModule->mCurTypeInstance, methodInstance->GetOwner());
|
||||
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
||||
|
||||
checkArgType = mModule->ResolveTypeRef(comptypeConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
if (checkArgType == NULL)
|
||||
return false;
|
||||
if (checkArgType->IsVar())
|
||||
|
@ -1860,21 +1875,53 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
|||
}
|
||||
}
|
||||
|
||||
// while (true)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
|
||||
//
|
||||
|
||||
bool failed = false;
|
||||
bool inferredAllGenericArguments = false;
|
||||
for (int pass = 0; true; pass++)
|
||||
{
|
||||
bool madeProgress = false;
|
||||
bool hasUninferred = false;
|
||||
failed = false;
|
||||
|
||||
for (int genericArgIdx = uniqueGenericStartIdx; genericArgIdx < (int)checkMethod->mGenericParams.size(); genericArgIdx++)
|
||||
{
|
||||
auto& genericArg = mCheckMethodGenericArguments[genericArgIdx];
|
||||
if (genericArg == NULL)
|
||||
{
|
||||
auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericArgIdx];
|
||||
InferFromGenericConstraints(genericParam, &mCheckMethodGenericArguments);
|
||||
InferFromGenericConstraints(methodInstance, genericParam, &mCheckMethodGenericArguments);
|
||||
if (genericArg != NULL)
|
||||
continue;
|
||||
{
|
||||
if (inferredAllGenericArguments)
|
||||
genericInferContext.InferGenericArguments(methodInstance, genericArgIdx);
|
||||
madeProgress = true;
|
||||
}
|
||||
hasUninferred = true;
|
||||
if (!allowEmptyGenericSet.Contains(genericArgIdx))
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasUninferred)
|
||||
break;
|
||||
if (inferredAllGenericArguments)
|
||||
{
|
||||
if (!madeProgress)
|
||||
break;
|
||||
}
|
||||
genericInferContext.InferGenericArguments(methodInstance);
|
||||
inferredAllGenericArguments = true;
|
||||
}
|
||||
if (failed)
|
||||
goto NoMatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (checkMethod->mMethodType == BfMethodType_Extension)
|
||||
argIdx--;
|
||||
|
@ -2538,7 +2585,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori
|
|||
if ((mModule->mCompiler->IsAutocomplete()) || (mModule->mContext->mResolvingVarField))
|
||||
return;
|
||||
|
||||
if (mModule->mBfIRBuilder->mIgnoreWrites)
|
||||
if ((mModule->mBfIRBuilder->mIgnoreWrites) && (!mBestMethodDef->mIsConcrete))
|
||||
return;
|
||||
|
||||
if (mBestMethodTypeInstance->IsInterface())
|
||||
|
@ -5169,6 +5216,17 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
|
||||
auto _GetDefaultReturnValue = [&]()
|
||||
{
|
||||
if (methodInstance->mVirtualTableIdx == -1)
|
||||
{
|
||||
if (methodInstance->GetOwner()->IsInterface())
|
||||
{
|
||||
// We're attempting to directly invoke a non-virtual interface method, if we're return an interface then
|
||||
// it is a concrete interface
|
||||
if (returnType->IsInterface())
|
||||
returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
|
||||
}
|
||||
}
|
||||
|
||||
if ((returnType->IsVar()) && (mExpectingType != NULL))
|
||||
returnType = mExpectingType;
|
||||
if (returnType->IsRef())
|
||||
|
@ -5243,17 +5301,6 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
// In an autocomplete pass we may have stale method references that need to be resolved
|
||||
// in the full classify pass, and in the full classify pass while just refreshing internals, we
|
||||
// may have NULL funcs temporarily. We simply skip generating the method call here.
|
||||
if (methodInstance->mVirtualTableIdx == -1)
|
||||
{
|
||||
if (methodInstance->GetOwner()->IsInterface())
|
||||
{
|
||||
// We're attempting to directly invoke a non-virtual interface method, if we're return an interface then
|
||||
// it is a concrete interface
|
||||
if (returnType->IsInterface())
|
||||
returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
|
||||
}
|
||||
}
|
||||
|
||||
if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
|
||||
{
|
||||
if (methodInstance->mReturnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
|
||||
|
@ -5348,6 +5395,15 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
}
|
||||
else
|
||||
{
|
||||
if (returnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
|
||||
{
|
||||
if (mExpectingType->IsUndefSizedArray())
|
||||
{
|
||||
if (returnType->GetUnderlyingType() == mExpectingType->GetUnderlyingType())
|
||||
return mModule->GetDefaultTypedValue(mExpectingType, true, BfDefaultValueKind_Undef);
|
||||
}
|
||||
}
|
||||
|
||||
return mModule->GetDefaultTypedValue(returnType, true, BfDefaultValueKind_Undef);
|
||||
}
|
||||
|
||||
|
@ -6148,7 +6204,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
if (!mModule->mCompiler->mIsResolveOnly)
|
||||
sCallIdx++;
|
||||
int callIdx = sCallIdx;
|
||||
if (callIdx == 1177)
|
||||
if (callIdx == 0x000020F9)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
@ -7596,7 +7652,6 @@ bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfR
|
|||
success = false;
|
||||
}
|
||||
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -7621,6 +7676,9 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
|
||||
if (target)
|
||||
{
|
||||
if (target.mType->IsConcreteInterfaceType())
|
||||
target.mType = target.mType->GetUnderlyingType();
|
||||
|
||||
// Turn T* into a T, if we can
|
||||
if ((target.mType->IsPointer()) && (target.mType->GetUnderlyingType()->IsGenericParam()))
|
||||
{
|
||||
|
@ -9790,7 +9848,6 @@ void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr)
|
|||
}
|
||||
|
||||
mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
|
||||
|
||||
mResult = BfTypedValue(mModule->CreateTypeDataRef(type), typeType);
|
||||
}
|
||||
|
||||
|
@ -15580,6 +15637,11 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (expectingType->IsVar())
|
||||
{
|
||||
// Silently allow
|
||||
gaveUnqualifiedDotError = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
gaveUnqualifiedDotError = true;
|
||||
|
|
|
@ -142,6 +142,7 @@ public:
|
|||
{
|
||||
return (int)mCheckMethodGenericArguments->size() - mInferredCount;
|
||||
}
|
||||
bool InferGenericArguments(BfMethodInstance* methodInstance, int srcGenericIdx);
|
||||
void InferGenericArguments(BfMethodInstance* methodInstance);
|
||||
};
|
||||
|
||||
|
@ -212,7 +213,7 @@ public:
|
|||
|
||||
public:
|
||||
BfTypedValue ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute, BfType *origCheckType = NULL, BfResolveArgFlags flags = BfResolveArgFlag_None);
|
||||
bool InferFromGenericConstraints(BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs);
|
||||
bool InferFromGenericConstraints(BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs);
|
||||
void CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute,
|
||||
BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
|
||||
bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail);
|
||||
|
|
|
@ -3962,7 +3962,7 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
|
|||
|
||||
BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfFieldDef* field)
|
||||
{
|
||||
bool isDeclType = (field->mFieldDeclaration != NULL) && BfNodeDynCastExact<BfDeclTypeRef>(field->mFieldDeclaration->mTypeRef) != NULL;
|
||||
bool isDeclType = (field->mFieldDeclaration != NULL) && BfNodeDynCastExact<BfExprModTypeRef>(field->mFieldDeclaration->mTypeRef) != NULL;
|
||||
|
||||
auto fieldType = fieldInstance->GetResolvedType();
|
||||
if ((field->mIsConst) && (!isDeclType))
|
||||
|
@ -7281,7 +7281,14 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar
|
|||
{
|
||||
bool checkEquality = false;
|
||||
|
||||
if (constraintType->IsPrimitiveType())
|
||||
if (constraintType->IsVar())
|
||||
{
|
||||
// From a `comptype` generic undef resolution. Ignore.
|
||||
genericParamInstance->mGenericParamFlags |= BfGenericParamFlag_ComptypeExpr;
|
||||
genericParamInstance->mComptypeConstraint.Add(constraintTypeRef);
|
||||
continue;
|
||||
}
|
||||
else if (constraintType->IsPrimitiveType())
|
||||
{
|
||||
if (isUnspecialized)
|
||||
{
|
||||
|
@ -8079,6 +8086,8 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator,
|
|||
|
||||
if ((flags & BfEvalExprFlags_AllowIntUnknown) == 0)
|
||||
FixIntUnknown(typedVal);
|
||||
if (!mBfIRBuilder->mIgnoreWrites)
|
||||
FixValueActualization(typedVal);
|
||||
exprEvaluator.CheckResultForReading(typedVal);
|
||||
|
||||
if ((wantTypeRef == NULL) || (!wantTypeRef->IsRef()))
|
||||
|
@ -8115,7 +8124,7 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator,
|
|||
if (outOrigType != NULL)
|
||||
*outOrigType = typedVal.mType;
|
||||
|
||||
if ((flags & BfEvalExprFlags_NoCast) == 0)
|
||||
if (((flags & BfEvalExprFlags_NoCast) == 0) && (!wantTypeRef->IsVar()))
|
||||
{
|
||||
BfCastFlags castFlags = ((flags & BfEvalExprFlags_ExplicitCast) != 0) ? BfCastFlags_Explicit : BfCastFlags_None;
|
||||
if ((flags & BfEvalExprFlags_FieldInitializer) != 0)
|
||||
|
@ -8125,9 +8134,6 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator,
|
|||
return typedVal;
|
||||
}
|
||||
|
||||
//WTF- why did we have this?
|
||||
/*if ((flags & BfEvalExprFlags_ExplicitCast) == 0)
|
||||
typedVal = LoadValue(typedVal, 0, exprEvaluator.mIsVolatileReference);*/
|
||||
if (exprEvaluator.mIsVolatileReference)
|
||||
typedVal = LoadValue(typedVal, 0, exprEvaluator.mIsVolatileReference);
|
||||
}
|
||||
|
@ -13805,6 +13811,16 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli
|
|||
isByAddr = true;
|
||||
}
|
||||
|
||||
if (diValue.IsConst())
|
||||
{
|
||||
auto constant = mBfIRBuilder->GetConstant(diValue);
|
||||
if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData))
|
||||
{
|
||||
// Ignore for now
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto diType = mBfIRBuilder->DbgGetType(localVarDef->mResolvedType);
|
||||
bool didConstToMem = false;
|
||||
|
||||
|
@ -17390,7 +17406,7 @@ void BfModule::ProcessMethod_ProcessDeferredLocals(int startIdx)
|
|||
}
|
||||
delete deferredLocalMethod;
|
||||
|
||||
mSystem->CheckLockYield();
|
||||
mContext->CheckLockYield();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17455,7 +17471,7 @@ void BfModule::ProcessMethod_ProcessDeferredLocals(int startIdx)
|
|||
}
|
||||
}
|
||||
|
||||
mSystem->CheckLockYield();
|
||||
mContext->CheckLockYield();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21170,6 +21186,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
// to effectively make mIgnoreWrites method-scoped
|
||||
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mWantsIRIgnoreWrites || mCurMethodInstance->mIsUnspecialized || mCurTypeInstance->mResolvingVarField);
|
||||
SetAndRestoreValue<bool> prevIsCapturingMethodMatchInfo;
|
||||
SetAndRestoreValue<bool> prevAllowLockYield(mContext->mAllowLockYield, false);
|
||||
SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
|
||||
if (mCompiler->IsAutocomplete())
|
||||
prevIsCapturingMethodMatchInfo.Init(mCompiler->mResolvePassData->mAutoComplete->mIsCapturingMethodMatchInfo, false);
|
||||
|
@ -21314,16 +21331,6 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
else
|
||||
{
|
||||
auto externConstraintDef = genericParam->GetExternConstraintDef();
|
||||
|
||||
// if (unspecializedTypeInstance == NULL)
|
||||
// unspecializedTypeInstance = GetUnspecializedTypeInstance(mCurTypeInstance);
|
||||
//
|
||||
// // 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();
|
||||
|
@ -21486,7 +21493,8 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
|
|||
|
||||
BfResolveTypeRefFlags flags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric);
|
||||
|
||||
if (((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0) && (methodDef->mReturnTypeRef->IsA<BfVarTypeReference>()))
|
||||
if ((((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0) || (methodInstance->mIsAutocompleteMethod))
|
||||
&& (methodDef->mReturnTypeRef->IsA<BfVarTypeReference>()))
|
||||
resolvedReturnType = GetPrimitiveType(BfTypeCode_Var);
|
||||
else
|
||||
resolvedReturnType = ResolveTypeRef(methodDef->mReturnTypeRef, BfPopulateType_Declaration, flags);
|
||||
|
|
|
@ -1762,6 +1762,7 @@ public:
|
|||
BfType* FixIntUnknown(BfType* type);
|
||||
void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL);
|
||||
void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs);
|
||||
void FixValueActualization(BfTypedValue& typedVal);
|
||||
bool TypeEquals(BfTypedValue& val, BfType* type);
|
||||
BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
||||
BfType* ResolveType(BfType* lookupType, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
||||
|
|
|
@ -3515,7 +3515,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
fieldInstance->mIsEnumPayloadCase = true;
|
||||
}
|
||||
}
|
||||
else if ((field->mTypeRef != NULL) && ((field->mTypeRef->IsExact<BfVarTypeReference>()) || (field->mTypeRef->IsExact<BfLetTypeReference>()) || (field->mTypeRef->IsExact<BfDeclTypeRef>())))
|
||||
else if ((field->mTypeRef != NULL) && ((field->mTypeRef->IsExact<BfVarTypeReference>()) || (field->mTypeRef->IsExact<BfLetTypeReference>()) || (field->mTypeRef->IsExact<BfExprModTypeRef>())))
|
||||
{
|
||||
resolvedFieldType = GetPrimitiveType(BfTypeCode_Var);
|
||||
|
||||
|
@ -5153,7 +5153,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
if ((mContext->mFieldResolveReentrys.size() == 0) && (!mContext->mResolvingVarField))
|
||||
{
|
||||
disableYield.Release();
|
||||
mSystem->CheckLockYield();
|
||||
mContext->CheckLockYield();
|
||||
disableYield.Acquire();
|
||||
}
|
||||
}
|
||||
|
@ -6258,6 +6258,21 @@ void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs)
|
|||
FixIntUnknown(rhs);
|
||||
}
|
||||
|
||||
void BfModule::FixValueActualization(BfTypedValue& typedVal)
|
||||
{
|
||||
if (!typedVal.mValue.IsConst())
|
||||
return;
|
||||
if (mBfIRBuilder->mIgnoreWrites)
|
||||
return;
|
||||
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
||||
if (constant->mConstType == BfConstType_TypeOf)
|
||||
{
|
||||
auto constTypeOf = (BfTypeOf_Const*)constant;
|
||||
AddDependency(constTypeOf->mType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
|
||||
typedVal.mValue = CreateTypeDataRef(constTypeOf->mType);
|
||||
}
|
||||
}
|
||||
|
||||
BfTypeInstance* BfModule::GetPrimitiveStructType(BfTypeCode typeCode)
|
||||
{
|
||||
BfTypeInstance* typeInst = NULL;
|
||||
|
@ -7858,7 +7873,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
|||
{
|
||||
baseNode = qualifiedNameNode->mRight;
|
||||
}
|
||||
else if (auto declTypeRef = BfNodeDynCast<BfDeclTypeRef>(baseNode))
|
||||
else if (auto declTypeRef = BfNodeDynCast<BfExprModTypeRef>(baseNode))
|
||||
{
|
||||
baseNode = NULL;
|
||||
break;
|
||||
|
@ -8868,6 +8883,12 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
return GetGenericParamType(BfGenericParamKind_Method, genericParamIdx);
|
||||
else
|
||||
{
|
||||
if ((mContext->mCurConstraintState != NULL) && (mContext->mCurConstraintState->mMethodInstance == checkMethodInstance) &&
|
||||
(mContext->mCurConstraintState->mMethodGenericArgsOverride != NULL))
|
||||
{
|
||||
return ResolveTypeResult(typeRef, (*mContext->mCurConstraintState->mMethodGenericArgsOverride)[genericParamIdx], populateType, resolveFlags);
|
||||
}
|
||||
|
||||
SetAndRestoreValue<BfGetSymbolReferenceKind> prevSymbolRefKind;
|
||||
if (mCompiler->mResolvePassData != NULL) // Don't add these typeRefs, they are indirect
|
||||
prevSymbolRefKind.Init(mCompiler->mResolvePassData->mGetSymbolReferenceKind, BfGetSymbolReferenceKind_None);
|
||||
|
@ -9338,6 +9359,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
|
||||
if (resolvedEntry == NULL)
|
||||
{
|
||||
if (lookupCtx.mHadVar)
|
||||
return ResolveTypeResult(typeRef, GetPrimitiveType(BfTypeCode_Var), populateType, resolveFlags);
|
||||
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
||||
}
|
||||
|
||||
|
@ -9620,7 +9643,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
for (auto genericArgRef : genericArguments)
|
||||
{
|
||||
auto genericArg = ResolveTypeRef(genericArgRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowGenericTypeParamConstValue | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue));
|
||||
if (genericArg == NULL)
|
||||
if ((genericArg == NULL) || (genericArg->IsVar()))
|
||||
{
|
||||
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
||||
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
||||
|
|
|
@ -2889,6 +2889,10 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
|
|||
if (SrcPtrHasToken("class"))
|
||||
mToken = BfToken_Class;
|
||||
break;
|
||||
case TOKEN_HASH('c', 'o', 'm', 'p'):
|
||||
if ((!mCompatMode) && (SrcPtrHasToken("comptype")))
|
||||
mToken = BfToken_Comptype;
|
||||
break;
|
||||
case TOKEN_HASH('c', 'o', 'n', 'c'):
|
||||
if ((!mCompatMode) && (SrcPtrHasToken("concrete")))
|
||||
mToken = BfToken_Concrete;
|
||||
|
|
|
@ -270,7 +270,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int*
|
|||
{
|
||||
// Tuple start
|
||||
}
|
||||
else if ((checkToken == BfToken_Decltype) || (checkToken == BfToken_AllocType) || (checkToken == BfToken_RetType) || (checkToken == BfToken_Nullable))
|
||||
else if ((checkToken == BfToken_Comptype) || (checkToken == BfToken_Decltype) || (checkToken == BfToken_AllocType) || (checkToken == BfToken_RetType) || (checkToken == BfToken_Nullable))
|
||||
{
|
||||
// Decltype start
|
||||
}
|
||||
|
@ -777,7 +777,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int*
|
|||
checkIdx = funcEndNode;
|
||||
continue;
|
||||
}
|
||||
else if ((checkToken == BfToken_Decltype) || (checkToken == BfToken_AllocType) || (checkToken == BfToken_RetType) || (checkToken == BfToken_Nullable))
|
||||
else if ((checkToken == BfToken_Comptype) || (checkToken == BfToken_Decltype) || (checkToken == BfToken_AllocType) || (checkToken == BfToken_RetType) || (checkToken == BfToken_Nullable))
|
||||
{
|
||||
int endNodeIdx = checkIdx + 1;
|
||||
|
||||
|
@ -2231,7 +2231,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (tokenNode->GetToken() == BfToken_Decltype)
|
||||
else if ((tokenNode->GetToken() == BfToken_Comptype) || (tokenNode->GetToken() == BfToken_Decltype))
|
||||
{
|
||||
auto typeRef = CreateTypeRef(tokenNode, CreateTypeRefFlags_EarlyExit);
|
||||
if (typeRef != NULL)
|
||||
|
@ -4755,9 +4755,9 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
|||
if ((createTypeRefFlags & CreateTypeRefFlags_EarlyExit) != 0)
|
||||
return delegateTypeRef;
|
||||
}
|
||||
else if (token == BfToken_Decltype)
|
||||
else if ((token == BfToken_Comptype) || (token == BfToken_Decltype))
|
||||
{
|
||||
auto declTypeRef = mAlloc->Alloc<BfDeclTypeRef>();
|
||||
auto declTypeRef = mAlloc->Alloc<BfExprModTypeRef>();
|
||||
ReplaceNode(tokenNode, declTypeRef);
|
||||
declTypeRef->mToken = tokenNode;
|
||||
tokenNode = ExpectTokenAfter(declTypeRef, BfToken_LParen);
|
||||
|
@ -5064,6 +5064,7 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
|||
(token == BfToken_LParen) ||
|
||||
(token == BfToken_Delegate) ||
|
||||
(token == BfToken_Function) ||
|
||||
(token == BfToken_Comptype) ||
|
||||
(token == BfToken_Decltype) ||
|
||||
((token == BfToken_Star) && (mAllowTypeWildcard))))
|
||||
doAddType = true;
|
||||
|
@ -6521,6 +6522,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, int depth, BfAstNode* defe
|
|||
(token == BfToken_AllocType) ||
|
||||
(token == BfToken_RetType) ||
|
||||
(token == BfToken_Nullable) ||
|
||||
(token == BfToken_Comptype) ||
|
||||
(token == BfToken_Decltype) ||
|
||||
(token == BfToken_LParen))
|
||||
{
|
||||
|
|
|
@ -126,7 +126,7 @@ BfAstNode* BfResolvePassData::FindBaseNode(BfAstNode* node)
|
|||
{
|
||||
baseNode = qualifiedNameNode->mRight;
|
||||
}
|
||||
else if (auto declTypeRef = BfNodeDynCast<BfDeclTypeRef>(baseNode))
|
||||
else if (auto declTypeRef = BfNodeDynCast<BfExprModTypeRef>(baseNode))
|
||||
{
|
||||
baseNode = NULL;
|
||||
break;
|
||||
|
|
|
@ -3409,11 +3409,11 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
|
||||
return hashVal;
|
||||
}
|
||||
else if (auto declTypeRef = BfNodeDynCastExact<BfDeclTypeRef>(typeRef))
|
||||
else if (auto exprModTypeRef = BfNodeDynCastExact<BfExprModTypeRef>(typeRef))
|
||||
{
|
||||
if (ctx->mResolvedType == NULL)
|
||||
{
|
||||
if (declTypeRef->mTarget != NULL)
|
||||
if (exprModTypeRef->mTarget != NULL)
|
||||
{
|
||||
BfTypedValue result;
|
||||
//
|
||||
|
@ -3427,8 +3427,33 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
SetAndRestoreValue<bool> ignoreWrites(ctx->mModule->mBfIRBuilder->mIgnoreWrites, true);
|
||||
SetAndRestoreValue<bool> allowUninitReads(ctx->mModule->mCurMethodState->mAllowUinitReads, true);
|
||||
|
||||
result = ctx->mModule->CreateValueFromExpression(declTypeRef->mTarget);
|
||||
if (exprModTypeRef->mToken->mToken == BfToken_Comptype)
|
||||
result = ctx->mModule->CreateValueFromExpression(exprModTypeRef->mTarget, ctx->mModule->ResolveTypeDef(ctx->mModule->mCompiler->mTypeTypeDef), BfEvalExprFlags_Comptime);
|
||||
else
|
||||
result = ctx->mModule->CreateValueFromExpression(exprModTypeRef->mTarget);
|
||||
}
|
||||
|
||||
if ((result) && (exprModTypeRef->mToken->mToken == BfToken_Comptype))
|
||||
{
|
||||
auto constant = ctx->mModule->mBfIRBuilder->GetConstant(result.mValue);
|
||||
if (constant != NULL)
|
||||
{
|
||||
if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData))
|
||||
{
|
||||
auto typeOf = (BfTypeOf_Const*)constant;
|
||||
ctx->mResolvedType = typeOf->mType;
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_Undef)
|
||||
{
|
||||
ctx->mHadVar = true;
|
||||
ctx->mResolvedType = ctx->mModule->GetPrimitiveType(BfTypeCode_Var);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->mResolvedType == NULL)
|
||||
ctx->mModule->Fail("Constant System.Type value required", exprModTypeRef->mTarget);
|
||||
}
|
||||
else
|
||||
ctx->mResolvedType = result.mType;
|
||||
}
|
||||
}
|
||||
|
@ -3875,7 +3900,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
|||
}
|
||||
}
|
||||
|
||||
if (auto declTypeRef = BfNodeDynCastExact<BfDeclTypeRef>(rhs))
|
||||
if (auto declTypeRef = BfNodeDynCastExact<BfExprModTypeRef>(rhs))
|
||||
{
|
||||
BF_ASSERT(ctx->mResolvedType != NULL);
|
||||
return lhs == ctx->mResolvedType;
|
||||
|
|
|
@ -1104,6 +1104,7 @@ public:
|
|||
BfType* mExternType;
|
||||
Array<BfTypeInstance*> mInterfaceConstraints;
|
||||
Array<BfGenericOperatorConstraintInstance> mOperatorConstraints;
|
||||
Array<BfTypeReference*> mComptypeConstraint;
|
||||
BfType* mTypeConstraint;
|
||||
int mRefCount;
|
||||
|
||||
|
@ -2440,6 +2441,7 @@ public:
|
|||
BfTypeInstance* mRootOuterTypeInstance;
|
||||
BfType* mResolvedType;
|
||||
BfResolveTypeRefFlags mResolveFlags;
|
||||
bool mHadVar;
|
||||
bool mFailed;
|
||||
|
||||
public:
|
||||
|
@ -2451,6 +2453,7 @@ public:
|
|||
mModule = NULL;
|
||||
mResolvedType = NULL;
|
||||
mFailed = false;
|
||||
mHadVar = false;
|
||||
mResolveFlags = BfResolveTypeRefFlag_None;
|
||||
}
|
||||
|
||||
|
@ -2488,7 +2491,7 @@ public:
|
|||
int tryCount = 0;
|
||||
ctx->mFailed = false;
|
||||
int hashVal = Hash(findType, ctx, BfHashFlag_AllowRef);
|
||||
if (ctx->mFailed)
|
||||
if ((ctx->mFailed) || (ctx->mHadVar))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -3421,7 +3421,7 @@ void BfModule::VisitCodeBlock(BfBlock* block)
|
|||
else
|
||||
child->Accept(this);
|
||||
|
||||
mSystem->CheckLockYield();
|
||||
mContext->CheckLockYield();
|
||||
|
||||
++itr;
|
||||
}
|
||||
|
@ -3437,7 +3437,7 @@ void BfModule::VisitCodeBlock(BfBlock* block)
|
|||
//??
|
||||
auto moduleMethodInstance = GetLocalMethodInstance(localMethod, BfTypeVector(), NULL, true);
|
||||
}
|
||||
mSystem->CheckLockYield();
|
||||
mContext->CheckLockYield();
|
||||
}
|
||||
|
||||
while ((int)mCurMethodState->mLocalMethods.size() > startLocalMethod)
|
||||
|
@ -4967,7 +4967,11 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
|
|||
|
||||
BfType* expectingReturnType = retType;
|
||||
if ((expectingReturnType != NULL) && (expectingReturnType->IsVar()))
|
||||
expectingReturnType = NULL;
|
||||
{
|
||||
NOP;
|
||||
// expectingReturnType = NULL;
|
||||
}
|
||||
|
||||
|
||||
BfType* origType;
|
||||
BfExprEvaluator exprEvaluator(this);
|
||||
|
|
|
@ -637,7 +637,8 @@ enum BfGenericParamFlags : uint16
|
|||
BfGenericParamFlag_Equals = 0x400,
|
||||
BfGenericParamFlag_Equals_Op = 0x800,
|
||||
BfGenericParamFlag_Equals_Type = 0x1000,
|
||||
BfGenericParamFlag_Equals_IFace = 0x2000
|
||||
BfGenericParamFlag_Equals_IFace = 0x2000,
|
||||
BfGenericParamFlag_ComptypeExpr = 0x4000
|
||||
};
|
||||
|
||||
class BfConstraintDef
|
||||
|
|
|
@ -3480,6 +3480,19 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
return BfIRValue();
|
||||
}
|
||||
|
||||
if (typeInst->IsInstanceOf(ceModule->mCompiler->mTypeTypeDef))
|
||||
{
|
||||
addr_ce addr = *(addr_ce*)(instData);
|
||||
int typeId = GetTypeIdFromType(addr);
|
||||
if (typeId <= 0)
|
||||
{
|
||||
Fail("Unable to locate return type type");
|
||||
return BfIRValue();
|
||||
}
|
||||
|
||||
return module->CreateTypeDataRef(module->mContext->mTypes[typeId]);
|
||||
}
|
||||
|
||||
if (typeInst->IsObjectOrInterface())
|
||||
{
|
||||
Fail(StrFormat("Reference type '%s' return value not allowed", module->TypeToString(typeInst).c_str()));
|
||||
|
@ -3846,7 +3859,12 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
memStart = &mMemory[0];
|
||||
|
||||
addr_ce retInstAddr = retAddr;
|
||||
if ((returnType->IsObject()) || (returnType->IsPointer()))
|
||||
|
||||
if (returnType->IsInstanceOf(mCeMachine->mCompiler->mTypeTypeDef))
|
||||
{
|
||||
// Allow
|
||||
}
|
||||
else if ((returnType->IsObject()) || (returnType->IsPointer()))
|
||||
{
|
||||
// Or pointer?
|
||||
retInstAddr = *(addr_ce*)(memStart + retAddr);
|
||||
|
|
|
@ -955,7 +955,7 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef)
|
|||
}
|
||||
}
|
||||
|
||||
if (auto declTypeRef = BfNodeDynCastExact<BfDeclTypeRef>(typeRef))
|
||||
if (auto declTypeRef = BfNodeDynCastExact<BfExprModTypeRef>(typeRef))
|
||||
{
|
||||
mResult = DbgTypedValue();
|
||||
VisitChild(declTypeRef->mTarget);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
|
@ -73,6 +74,40 @@ namespace Tests
|
|||
|
||||
}
|
||||
|
||||
struct DoublingEnumerator<TElem, TEnum> : IEnumerator<TElem>
|
||||
where TElem : operator TElem + TElem
|
||||
where TEnum : concrete, IEnumerator<TElem>
|
||||
{
|
||||
TEnum mEnum;
|
||||
|
||||
public this(TEnum e)
|
||||
{
|
||||
mEnum = e;
|
||||
}
|
||||
|
||||
public Result<TElem> GetNext() mut
|
||||
{
|
||||
switch (mEnum.GetNext())
|
||||
{
|
||||
case .Ok(let val): return .Ok(val + val);
|
||||
case .Err: return .Err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Type GetConcreteEnumerator<TCollection, TElem>() where TCollection : IEnumerable<TElem>
|
||||
{
|
||||
TCollection col = ?;
|
||||
return col.GetEnumerator().GetType();
|
||||
}
|
||||
|
||||
public static DoublingEnumerator<TElem, comptype(GetConcreteEnumerator<TCollection, TElem>())> GetDoublingEnumerator<TCollection, TElem>(this TCollection it)
|
||||
where TCollection: concrete, IEnumerable<TElem>
|
||||
where TElem : operator TElem + TElem
|
||||
{
|
||||
return .(it.GetEnumerator());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
|
@ -88,6 +123,14 @@ namespace Tests
|
|||
|
||||
MethodA(34, 45);
|
||||
Debug.Assert(LogAttribute.gLog == "Called Tests.Comptime.MethodA(int a, int b) 34 45");
|
||||
|
||||
List<float> fList = scope .() { 1, 2, 3 };
|
||||
var e = fList.GetDoublingEnumerator();
|
||||
Test.Assert(e.GetNext().Value == 2);
|
||||
Test.Assert(e.GetNext().Value == 4);
|
||||
Test.Assert(e.GetNext().Value == 6);
|
||||
|
||||
//Test.Assert(fList.DoubleVals() == 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue