diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index ae435e33..0582f52a 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -1941,13 +1941,13 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst } } -// while (true) -// { -// -// } - - // - + if ((mCheckReturnType != NULL) && (methodInstance->mReturnType->IsUnspecializedType())) + { + genericInferContext.mCheckedTypeSet.Clear(); + if (!genericInferContext.InferGenericArgument(methodInstance, mCheckReturnType, methodInstance->mReturnType, BfIRValue())) + return ResultKind_Failed; + } + bool failed = false; bool inferredAllGenericArguments = false; for (int pass = 0; true; pass++) @@ -2172,20 +2172,20 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst if (mCheckReturnType != NULL) { - auto wantType = mCheckReturnType; - if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType())) + auto returnType = methodInstance->mReturnType; + if ((genericArgumentsSubstitute != NULL) && (returnType->IsUnspecializedType())) { - auto resolvedType = mModule->ResolveGenericType(wantType, typeGenericArguments, genericArgumentsSubstitute, false); + auto resolvedType = mModule->ResolveGenericType(returnType, typeGenericArguments, genericArgumentsSubstitute, false); if (resolvedType == NULL) goto NoMatch; - wantType = resolvedType; + returnType = resolvedType; } - wantType = mModule->ResolveSelfType(wantType, typeInstance); + returnType = mModule->ResolveSelfType(returnType, typeInstance); BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None; if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0) castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit); - if (!mModule->CanCast(mModule->GetFakeTypedValue(methodInstance->mReturnType), wantType, castFlags)) + if (!mModule->CanCast(mModule->GetFakeTypedValue(returnType), mCheckReturnType, castFlags)) goto NoMatch; } @@ -2206,7 +2206,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst goto NoMatch; if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, NULL, genericParams[checkGenericIdx], genericArgumentsSubstitute, NULL)) - goto NoMatch; + goto NoMatch; } } diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index a42af100..9bea6f34 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -19195,7 +19195,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, refNode = operatorDef->mOperatorDeclaration->mCommas[0]; Fail("Conversion operators must declare one parameter", refNode); } - else + else if ((methodInstance->mIsUnspecialized) && (!methodInstance->mIsUnspecializedVariation)) { auto checkParam0 = mCurMethodInstance->GetParamType(0); if ((checkParam0->IsRef()) && (!checkParam0->IsOut())) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 3f910880..ab5187a9 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -12805,7 +12805,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if ((explicitCast) && (typedVal.mType->IsTypedPrimitive())) { auto underlyingType = typedVal.mType->GetUnderlyingType(); - if ((returnType != underlyingType) && (CanCast(GetFakeTypedValue(underlyingType), toType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator)))) + if ((returnType == underlyingType) && (explicitCast)) + { + doCall = false; + } + else if ((CanCast(GetFakeTypedValue(underlyingType), toType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator)))) { float underlyingCanCast = CanCast(GetFakeTypedValue(underlyingType), toType, implicitCastFlags); float returnCanCast = CanCast(GetFakeTypedValue(returnType), toType, implicitCastFlags); @@ -12834,8 +12838,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if ((explicitCast) && (toType->IsTypedPrimitive())) { auto underlyingType = toType->GetUnderlyingType(); - if ((paramType != underlyingType) && - (CanCast(typedVal, underlyingType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator)))) + if ((paramType == underlyingType) && (explicitCast)) + { + doCall = false; + } + else if (CanCast(typedVal, underlyingType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator))) { float underlyingCanCast = CanCast(typedVal, underlyingType, implicitCastFlags); float paramCanCast = CanCast(typedVal, paramType, implicitCastFlags); diff --git a/IDEHelper/Tests/src/Operators.bf b/IDEHelper/Tests/src/Operators.bf index 4b81e578..a66a478a 100644 --- a/IDEHelper/Tests/src/Operators.bf +++ b/IDEHelper/Tests/src/Operators.bf @@ -336,6 +336,15 @@ namespace Tests } } + struct StructK : uint64 + { + public static T operator implicit(Self self) + where T : operator explicit uint64 + { + return (.)(uint64)self; + } + } + /*struct OuterOp { public struct InnerOp @@ -644,6 +653,10 @@ namespace Tests Test.Assert(sji8i.mVal == 56); Test.Assert(sji8e.mVal == 45); } + + StructK sk = (.)123; + uint64 sku32 = sk; + Test.Assert(sku32 == 123); } struct IntStruct