Skip to content

Commit 599dae5

Browse files
csyongheArielG-NV
andauthored
Open existential on arguments after overload resolution. (#4982)
* Open existential on arguments after overload resolution. * Fix. * Update source/slang/slang-check-overload.cpp Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> --------- Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com>
1 parent ddd2905 commit 599dae5

File tree

3 files changed

+84
-22
lines changed

3 files changed

+84
-22
lines changed

source/slang/slang-check-decl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -4226,7 +4226,7 @@ namespace Slang
42264226
//
42274227
DiagnosticSink tempSink(getSourceManager(), nullptr);
42284228
ExprLocalScope localScope;
4229-
SemanticsVisitor subVisitor(withSink(&tempSink).withExprLocalScope(&localScope));
4229+
SemanticsVisitor subVisitor(withSink(&tempSink).withParentFunc(synFuncDecl).withExprLocalScope(&localScope));
42304230

42314231
// With our temporary diagnostic sink soaking up any messages
42324232
// from overload resolution, we can now try to resolve

source/slang/slang-check-overload.cpp

+40-21
Original file line numberDiff line numberDiff line change
@@ -2266,7 +2266,6 @@ namespace Slang
22662266

22672267
// Look at the base expression for the call, and figure out how to invoke it.
22682268
auto funcExpr = expr->functionExpr;
2269-
auto funcExprType = funcExpr->type;
22702269

22712270
// If we are trying to apply an erroneous expression, then just bail out now.
22722271
if(IsErrorExpr(funcExpr))
@@ -2295,25 +2294,6 @@ namespace Slang
22952294
for (auto& arg : expr->arguments)
22962295
{
22972296
arg = maybeOpenRef(arg);
2298-
}
2299-
2300-
auto funcType = as<FuncType>(funcExprType);
2301-
for (Index i = 0; i < expr->arguments.getCount(); i++)
2302-
{
2303-
auto& arg = expr->arguments[i];
2304-
if (funcType && i < funcType->getParamCount())
2305-
{
2306-
switch (funcType->getParamDirection(i))
2307-
{
2308-
case kParameterDirection_Out:
2309-
case kParameterDirection_InOut:
2310-
case kParameterDirection_Ref:
2311-
case kParameterDirection_ConstRef:
2312-
continue;
2313-
default:
2314-
break;
2315-
}
2316-
}
23172297
arg = maybeOpenExistential(arg);
23182298
}
23192299

@@ -2443,6 +2423,45 @@ namespace Slang
24432423
// the user the most help we can.
24442424
if (shouldAddToCache)
24452425
typeCheckingCache->resolvedOperatorOverloadCache[key] = *context.bestCandidate;
2426+
2427+
// Now that we have resolved the overload candidate, we need to undo an `openExistential`
2428+
// operation that was applied to `out` arguments.
2429+
//
2430+
auto funcType = context.bestCandidate->funcType;
2431+
ShortList<ParameterDirection> paramDirections;
2432+
if (funcType)
2433+
{
2434+
for (Index i = 0; i < funcType->getParamCount(); i++)
2435+
{
2436+
paramDirections.add(funcType->getParamDirection(i));
2437+
}
2438+
}
2439+
else if (auto callableDeclRef = context.bestCandidate->item.declRef.as<CallableDecl>())
2440+
{
2441+
for (auto param : callableDeclRef.getDecl()->getParameters())
2442+
{
2443+
paramDirections.add(getParameterDirection(param));
2444+
}
2445+
}
2446+
for (Index i = 0; i < expr->arguments.getCount(); i++)
2447+
{
2448+
auto& arg = expr->arguments[i];
2449+
if (i < paramDirections.getCount())
2450+
{
2451+
switch (paramDirections[i])
2452+
{
2453+
case kParameterDirection_Out:
2454+
case kParameterDirection_InOut:
2455+
case kParameterDirection_Ref:
2456+
case kParameterDirection_ConstRef:
2457+
break;
2458+
default:
2459+
continue;
2460+
}
2461+
}
2462+
if (auto extractExistentialExpr = as<ExtractExistentialValueExpr>(arg))
2463+
arg = extractExistentialExpr->originalExpr;
2464+
}
24462465
return CompleteOverloadCandidate(context, *context.bestCandidate);
24472466
}
24482467

@@ -2475,7 +2494,7 @@ namespace Slang
24752494

24762495
// Nothing at all was found that we could even consider invoking.
24772496
// In all other cases, this is an error.
2478-
getSink()->diagnose(expr->functionExpr, Diagnostics::expectedFunction, funcExprType);
2497+
getSink()->diagnose(expr->functionExpr, Diagnostics::expectedFunction, funcExpr->type);
24792498
expr->type = QualType(m_astBuilder->getErrorType());
24802499
return expr;
24812500
}

tests/bugs/gh-4467.slang

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHK): -d3d12 -compute -shaderobj -output-using-type
2+
//TEST(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=CHK): -vk -compute -shaderobj -output-using-type
3+
4+
5+
// Test that we can synthesize a [mutating] interface requirement from a nonmutating implementation,
6+
// and the interface requirement signature contains an output interface-typed parameter.
7+
8+
//TEST_INPUT: ubuffer(data=[0 0], stride=4):out,name outputBuffer
9+
RWStructuredBuffer<int> outputBuffer;
10+
11+
interface IFoo
12+
{
13+
int getVal();
14+
};
15+
16+
interface IBar
17+
{
18+
[mutating] void method(out IFoo o);
19+
};
20+
21+
struct FooImpl : IFoo
22+
{
23+
int x;
24+
int getVal() { return x; }
25+
}
26+
27+
struct BarImpl : IBar
28+
{
29+
void method(out IFoo o)
30+
{
31+
o = FooImpl(1);
32+
}
33+
};
34+
35+
[numthreads(1,1,1)]
36+
void computeMain()
37+
{
38+
BarImpl bar;
39+
IFoo foo;
40+
bar.method(foo);
41+
// CHK: 1
42+
outputBuffer[0] = foo.getVal();
43+
}

0 commit comments

Comments
 (0)