mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-14 14:24:10 +02:00
Fixed nullable null coalescing short circuiting
This commit is contained in:
parent
0bedd77f0a
commit
e6352571c1
3 changed files with 34 additions and 30 deletions
|
@ -420,31 +420,6 @@ namespace System
|
||||||
return Nullable<TResult>(lhs.mValue | rhs.mValue);
|
return Nullable<TResult>(lhs.mValue | rhs.mValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
public static T operator??(Nullable<T> lhs, T rhs)
|
|
||||||
{
|
|
||||||
return (lhs.mHasValue) ? lhs.mValue : rhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TResult? operator??<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther ?? T where TResult : struct
|
|
||||||
{
|
|
||||||
if (!rhs.mHasValue) return null;
|
|
||||||
return Nullable<TResult>(lhs ?? rhs.mValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TResult? operator??<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T ?? TOther where TResult : struct
|
|
||||||
{
|
|
||||||
if (!lhs.mHasValue) return null;
|
|
||||||
return Nullable<TResult>(lhs.mValue ?? rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TResult? operator??<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T ?? TOther where TResult : struct
|
|
||||||
{
|
|
||||||
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
|
|
||||||
return Nullable<TResult>(lhs.mValue ?? rhs.mValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
public static TResult? operator<< <TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther << T where TResult : struct
|
public static TResult? operator<< <TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther << T where TResult : struct
|
||||||
|
|
|
@ -22925,17 +22925,21 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
||||||
|
|
||||||
bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, BfExpression* leftExpression, BfExpression* rightExpression, BfTypedValue leftValue, BfType* wantType, BfTypedValue* assignTo)
|
bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, BfExpression* leftExpression, BfExpression* rightExpression, BfTypedValue leftValue, BfType* wantType, BfTypedValue* assignTo)
|
||||||
{
|
{
|
||||||
if ((leftValue) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject())) /* || (leftValue.mType->IsNullable())*/)
|
if ((leftValue) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject())) || (leftValue.mType->IsNullable()))
|
||||||
{
|
{
|
||||||
leftValue = mModule->LoadValue(leftValue);
|
leftValue = mModule->LoadValue(leftValue);
|
||||||
|
|
||||||
|
BfType* nullableElementType = NULL;
|
||||||
BfIRValue nullableHasValue;
|
BfIRValue nullableHasValue;
|
||||||
|
BfTypedValue nullableExtractedLeftValue;
|
||||||
if (leftValue.mType->IsNullable())
|
if (leftValue.mType->IsNullable())
|
||||||
{
|
{
|
||||||
if (wantType == leftValue.mType)
|
nullableElementType = leftValue.mType->GetUnderlyingType();
|
||||||
wantType = leftValue.mType->GetUnderlyingType();
|
nullableHasValue = mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, nullableElementType->IsValuelessType() ? 1 : 2); // has_value
|
||||||
nullableHasValue = mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, 1);
|
if (!nullableElementType->IsValuelessType())
|
||||||
leftValue = BfTypedValue(mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, 0), leftValue.mType->GetUnderlyingType());
|
nullableExtractedLeftValue = BfTypedValue(mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, 1), nullableElementType); // value
|
||||||
|
else
|
||||||
|
nullableExtractedLeftValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), nullableElementType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leftValue.mValue.IsConst())
|
if (leftValue.mValue.IsConst())
|
||||||
|
@ -22984,6 +22988,14 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken,
|
||||||
mModule->AssertErrorState();
|
mModule->AssertErrorState();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((assignTo == NULL) && (leftValue.mType->IsNullable()) && (!rightValue.mType->IsNullable()))
|
||||||
|
{
|
||||||
|
if (wantType == leftValue.mType)
|
||||||
|
wantType = nullableElementType;
|
||||||
|
leftValue = nullableExtractedLeftValue;
|
||||||
|
}
|
||||||
|
|
||||||
rightValue = mModule->LoadValue(rightValue);
|
rightValue = mModule->LoadValue(rightValue);
|
||||||
|
|
||||||
if (assignTo == NULL)
|
if (assignTo == NULL)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma warning disable 168
|
#pragma warning disable 168
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace Tests
|
namespace Tests
|
||||||
{
|
{
|
||||||
|
@ -97,6 +98,22 @@ namespace Tests
|
||||||
|
|
||||||
String str = "Abc";
|
String str = "Abc";
|
||||||
StringView? svn = str;
|
StringView? svn = str;
|
||||||
|
|
||||||
|
iNull = null;
|
||||||
|
int? iNull2 = 123;
|
||||||
|
List<int> l = null;
|
||||||
|
List<int> l2 = scope .();
|
||||||
|
|
||||||
|
int a = iNull2 ?? l.Count;
|
||||||
|
int b = iNull ?? l2.Count;
|
||||||
|
var c = iNull ?? iNull2;
|
||||||
|
|
||||||
|
Test.Assert(a == 123);
|
||||||
|
Test.Assert(b == 0);
|
||||||
|
Test.Assert(typeof(decltype(c)) == typeof(int?));
|
||||||
|
|
||||||
|
iNull ??= iNull2;
|
||||||
|
Test.Assert(iNull == 123);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue