summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-check-conversion.cpp19
-rw-r--r--source/slang/slang-check-expr.cpp3
-rw-r--r--source/slang/slang-check-impl.h1
-rw-r--r--source/slang/slang-check-overload.cpp4
-rw-r--r--tests/language-feature/properties/property-in-interface.slang11
-rw-r--r--tests/language-feature/properties/property-in-interface.slang.expected.txt6
6 files changed, 32 insertions, 12 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index ba4a9b8d9..0a0990ede 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -85,7 +85,7 @@ namespace Slang
// we want to check for is whether a direct initialization
// is possible (a type conversion exists).
//
- return canCoerce(toType, fromExpr->type);
+ return canCoerce(toType, fromExpr->type, fromExpr);
}
bool SemanticsVisitor::_readValueFromInitializerList(
@@ -484,6 +484,18 @@ namespace Slang
Expr* fromExpr,
ConversionCost* outCost)
{
+ // If we are about to try and coerce an overloaded expression,
+ // then we should start by trying to resolve the ambiguous reference
+ // based on prioritization of the different candidates.
+ //
+ if( auto fromOverloadedExpr = as<OverloadedExpr>(fromExpr) )
+ {
+ auto resolvedExpr = maybeResolveOverloadedExpr(fromOverloadedExpr, LookupMask::Default, nullptr);
+
+ fromExpr = resolvedExpr;
+ fromType = resolvedExpr->type;
+ }
+
// An important and easy case is when the "to" and "from" types are equal.
//
if( toType->equals(fromType) )
@@ -756,6 +768,7 @@ namespace Slang
bool SemanticsVisitor::canCoerce(
Type* toType,
Type* fromType,
+ Expr* fromExpr,
ConversionCost* outCost)
{
// As an optimization, we will maintain a cache of conversion results
@@ -795,7 +808,7 @@ namespace Slang
toType,
nullptr,
fromType,
- nullptr,
+ fromExpr,
&cost);
if (outCost)
@@ -877,7 +890,7 @@ namespace Slang
{
// Can we convert at all?
ConversionCost conversionCost;
- if(!canCoerce(toType, fromType, &conversionCost))
+ if(!canCoerce(toType, fromType, nullptr, &conversionCost))
return false;
// Is the conversion cheap enough to be done implicitly?
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 4268ad99e..63367fa97 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -1963,9 +1963,6 @@ namespace Slang
return lookupMemberResultFailure(expr, baseType);
}
- // TODO: need to filter for declarations that are valid to refer
- // to in this context...
-
return createLookupResultExpr(
expr->name,
lookupResult,
diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h
index 7907ef23b..cdd319408 100644
--- a/source/slang/slang-check-impl.h
+++ b/source/slang/slang-check-impl.h
@@ -670,6 +670,7 @@ namespace Slang
bool canCoerce(
Type* toType,
Type* fromType,
+ Expr* fromExpr,
ConversionCost* outCost = 0);
TypeCastExpr* createImplicitCastExpr();
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp
index 0a1294965..94638e473 100644
--- a/source/slang/slang-check-overload.cpp
+++ b/source/slang/slang-check-overload.cpp
@@ -255,7 +255,7 @@ namespace Slang
if (context.mode == OverloadResolveContext::Mode::JustTrying)
{
ConversionCost cost = kConversionCost_None;
- if (!canCoerce(getType(m_astBuilder, valParamRef), arg->type, &cost))
+ if (!canCoerce(getType(m_astBuilder, valParamRef), arg->type, arg, &cost))
{
success = false;
}
@@ -344,7 +344,7 @@ namespace Slang
if(!getType(m_astBuilder, param)->equals(argType))
return false;
}
- else if (!canCoerce(getType(m_astBuilder, param), argType, &cost))
+ else if (!canCoerce(getType(m_astBuilder, param), argType, arg, &cost))
{
return false;
}
diff --git a/tests/language-feature/properties/property-in-interface.slang b/tests/language-feature/properties/property-in-interface.slang
index ba6d5eaa9..3622861e0 100644
--- a/tests/language-feature/properties/property-in-interface.slang
+++ b/tests/language-feature/properties/property-in-interface.slang
@@ -19,6 +19,8 @@ struct MyCell : ICell
struct YourCell : ICell
{
int value;
+
+ int getValue() { return value; }
}
int helper<C : ICell>(C cell)
@@ -31,7 +33,14 @@ int test(int value)
{
MyCell myCell = { value+1 };
YourCell yourCell = { value };
- return helper(myCell)*16 + helper(yourCell);
+
+ // Note: fetching `value` directly from `YourCell`
+ // to confirm that member lookup is prioritizing
+ // the concrete `YourCell::value` member of the inherited
+ // abstract member `ICell::value`.
+ //
+ int f = (yourCell.value + yourCell.getValue()) / 2;
+ return helper(myCell)*16 + helper(yourCell) + f;
}
//TEST_INPUT:ubuffer(data=[0 1 2 3], stride=4):out,name=outputBuffer
diff --git a/tests/language-feature/properties/property-in-interface.slang.expected.txt b/tests/language-feature/properties/property-in-interface.slang.expected.txt
index ba2ec282d..e9c86b523 100644
--- a/tests/language-feature/properties/property-in-interface.slang.expected.txt
+++ b/tests/language-feature/properties/property-in-interface.slang.expected.txt
@@ -1,4 +1,4 @@
21
-32
-43
-54
+33
+45
+57