diff options
| -rw-r--r-- | source/slang/slang-check-conversion.cpp | 19 | ||||
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-check-impl.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-check-overload.cpp | 4 | ||||
| -rw-r--r-- | tests/language-feature/properties/property-in-interface.slang | 11 | ||||
| -rw-r--r-- | tests/language-feature/properties/property-in-interface.slang.expected.txt | 6 |
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 |
