1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00

Added comptype

This commit is contained in:
Brian Fiete 2021-01-15 14:28:21 -08:00
parent bb12a4ec20
commit 4890303508
27 changed files with 382 additions and 157 deletions

View file

@ -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;

View file

@ -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)

View file

@ -710,6 +710,7 @@ void BeIRCodeGen::Read(BeValue*& beValue)
}
else
beValue = GetBeValue(streamId);
beValue->mRefCount++;
BE_MEM_END("ParamType_Const_GlobalVar");
return;
}

View file

@ -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:

View file

@ -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;
@ -473,8 +474,8 @@ public:
virtual void Visit(BfArrayTypeRef* typeRef);
virtual void Visit(BfGenericInstanceTypeRef* typeRef);
virtual void Visit(BfTupleTypeRef* typeRef);
virtual void Visit(BfDelegateTypeRef* typeRef);
virtual void Visit(BfDeclTypeRef* declTypeRef);
virtual void Visit(BfDelegateTypeRef* typeRef);
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
{

View file

@ -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())
{

View file

@ -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();

View file

@ -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);
}
@ -203,7 +203,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
{
auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
if ((constant->mConstType == BfConstType_GlobalVar) && ((mBfEvalExprFlags & BfConstResolveFlag_AllowGlobalVariable) != 0))
isConst = false;
isConst = false;
}
if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0))
@ -232,6 +232,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
}*/
mModule->FixIntUnknown(mResult);
mModule->FixValueActualization(mResult);
return mResult;
}

View file

@ -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;
}

View file

@ -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();

View file

@ -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());

View file

@ -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);

View file

@ -588,54 +588,41 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
return true;
}
bool BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstance, int srcGenericIdx)
{
auto& srcGenericArg = (*mCheckMethodGenericArguments)[srcGenericIdx];
if (srcGenericArg == NULL)
return false;
int startInferCount = mInferredCount;
auto srcGenericParam = methodInstance->mMethodInfoEx->mGenericParams[srcGenericIdx];
for (auto ifaceConstraint : srcGenericParam->mInterfaceConstraints)
{
if ((ifaceConstraint->IsUnspecializedTypeVariation()) && (ifaceConstraint->IsGenericTypeInstance()))
{
InferGenericArgument(methodInstance, srcGenericArg, ifaceConstraint, BfIRValue());
auto typeInstance = srcGenericArg->ToTypeInstance();
if (typeInstance != NULL)
{
for (auto ifaceEntry : typeInstance->mInterfaces)
InferGenericArgument(methodInstance, ifaceEntry.mInterfaceType, ifaceConstraint, BfIRValue());
}
}
}
return mInferredCount != startInferCount;
}
void BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstance)
{
// Attempt to infer from other generic args
for (int srcGenericIdx = 0; srcGenericIdx < (int)mCheckMethodGenericArguments->size(); srcGenericIdx++)
{
auto& srcGenericArg = (*mCheckMethodGenericArguments)[srcGenericIdx];
if (srcGenericArg == NULL)
continue;
auto srcGenericParam = methodInstance->mMethodInfoEx->mGenericParams[srcGenericIdx];
for (auto ifaceConstraint : srcGenericParam->mInterfaceConstraints)
{
if ((ifaceConstraint->IsUnspecializedTypeVariation()) && (ifaceConstraint->IsGenericTypeInstance()))
{
InferGenericArgument(methodInstance, srcGenericArg, ifaceConstraint, BfIRValue());
auto typeInstance = srcGenericArg->ToTypeInstance();
if (typeInstance != NULL)
{
for (auto ifaceEntry : typeInstance->mInterfaces)
InferGenericArgument(methodInstance, ifaceEntry.mInterfaceType, ifaceConstraint, BfIRValue());
}
}
}
InferGenericArguments(methodInstance, srcGenericIdx);
}
}
// 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())
// {
//
//
// }
// }
int BfMethodMatcher::GetMostSpecificType(BfType* lhs, BfType* rhs)
{
if ((lhs->IsRef()) && (rhs->IsRef()))
@ -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())
@ -1857,23 +1872,55 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
}
paramIdx++;
}
}
//
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);
if (genericArg != NULL)
continue;
if (!allowEmptyGenericSet.Contains(genericArgIdx))
goto NoMatch;
}
}
// 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(methodInstance, genericParam, &mCheckMethodGenericArguments);
if (genericArg != NULL)
{
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)
@ -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())
@ -5241,19 +5299,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
if (wantQuickEval)
{
// 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());
}
}
// 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 ((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;
}
@ -7594,8 +7650,7 @@ bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfR
{
mModule->Fail(StrFormat("Must add 'where %s : struct' constraint to generic parameter to instantiate type without allocator", genericConstraint->GetGenericParamDef()->mName.c_str()), targetSrc);
success = false;
}
}
return success;
}
@ -7618,9 +7673,12 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
BF_ASSERT(!mFunctionBindResult->mOrigTarget);
mFunctionBindResult->mOrigTarget = origTarget;
}
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;

View file

@ -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);

View file

@ -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))
@ -7280,9 +7280,16 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar
else
{
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)
{
Fail("Primitive constraints are not allowed unless preceded with 'const'", constraintTypeRef);
@ -7336,7 +7343,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar
{
auto constraintTypeInst = constraintType->ToTypeInstance();
if (genericParamInstance->mTypeConstraint != NULL)
{
{
if ((constraintTypeInst != NULL) && (TypeIsSubTypeOf(constraintTypeInst, genericParamInstance->mTypeConstraint->ToTypeInstance(), false)))
{
// Allow more specific type
@ -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()))
@ -8098,7 +8107,7 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator,
if (!allowRef)
typedVal = RemoveRef(typedVal);
}
}
}
if ((!typedVal.mType->IsComposite()) && (!typedVal.mType->IsGenericParam())) // Load non-structs by default
{
@ -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);
}
@ -13252,9 +13258,9 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
// if ((flags & BfGetMethodInstanceFlag_NoReference) != 0)
// addToWorkList = false;
declareModule->DoMethodDeclaration(methodDef->GetMethodDeclaration(), false, addToWorkList);
declareModule->DoMethodDeclaration(methodDef->GetMethodDeclaration(), false, addToWorkList);
if (processNow)
{
SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
@ -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;
@ -13882,7 +13898,7 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli
if (isByAddr)
localVarDef->mDbgDeclareInst = mBfIRBuilder->DbgInsertDeclare(diValue, diVariable, declareBefore);
else if (diValue)
{
{
localVarDef->mDbgDeclareInst = mBfIRBuilder->DbgInsertValueIntrinsic(diValue, diVariable);
}
else if (mCompiler->mOptions.mToolsetType != BfToolsetType_GNU) // DWARF chokes on this:
@ -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();
}
}
@ -21169,7 +21185,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
// We could trigger a DoMethodDeclaration from a const resolver or other location, so we reset it here
// to effectively make mIgnoreWrites method-scoped
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mWantsIRIgnoreWrites || mCurMethodInstance->mIsUnspecialized || mCurTypeInstance->mResolvingVarField);
SetAndRestoreValue<bool> prevIsCapturingMethodMatchInfo;
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,28 +21331,18 @@ 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();
if (autoComplete != NULL)
autoComplete->CheckTypeRef(externConstraintDef->mTypeRef, false);
if (autoComplete != NULL)
autoComplete->CheckTypeRef(externConstraintDef->mTypeRef, false);
if (genericParam->mExternType != NULL)
{
//
}
else
genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
if (genericParam->mExternType != NULL)
{
//
}
else
genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
}
ResolveGenericParamConstraints(genericParam, methodInstance->mIsUnspecialized);
@ -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);

View file

@ -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);

View file

@ -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);
@ -9334,10 +9355,12 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
lookupCtx.mRootTypeDef = typeDef;
lookupCtx.mModule = this;
BfResolvedTypeSet::Entry* resolvedEntry = NULL;
auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry);
auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry);
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);

View file

@ -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;

View file

@ -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))
{

View file

@ -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;

View file

@ -3408,12 +3408,12 @@ 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,9 +3427,34 @@ 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);
}
ctx->mResolvedType = result.mType;
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;

View file

@ -1104,6 +1104,7 @@ public:
BfType* mExternType;
Array<BfTypeInstance*> mInterfaceConstraints;
Array<BfGenericOperatorConstraintInstance> mOperatorConstraints;
Array<BfTypeReference*> mComptypeConstraint;
BfType* mTypeConstraint;
int mRefCount;
@ -2428,7 +2429,7 @@ public:
{
BfHashFlag_None = 0,
BfHashFlag_AllowRef = 1,
BfHashFlag_AllowGenericParamConstValue = 2
BfHashFlag_AllowGenericParamConstValue = 2
};
class LookupContext
@ -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,10 +2491,10 @@ public:
int tryCount = 0;
ctx->mFailed = false;
int hashVal = Hash(findType, ctx, BfHashFlag_AllowRef);
if (ctx->mFailed)
if ((ctx->mFailed) || (ctx->mHadVar))
{
return false;
}
}
int bucket = (hashVal & 0x7FFFFFFF) % mHashSize;
auto checkEntry = mHashHeads[bucket];
while (checkEntry != NULL)

View file

@ -3420,8 +3420,8 @@ 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);

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);
}
}
}