summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-overload.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-07-22 08:47:50 -0700
committerGitHub <noreply@github.com>2025-07-22 15:47:50 +0000
commit52a45890b5ab71d7dbfdd01955afce129728d67e (patch)
tree141491e9c36cfa6a1a890765682d69ac4bfd2270 /source/slang/slang-check-overload.cpp
parent0d26dbaad90f5eac604e148971d14e552bf9d5b8 (diff)
Fix crash when private ctor is used for coercion. (#7858)
* Fix crash when private ctor is used for coercion. * Fix tests. * Fix. * Fix test error.
Diffstat (limited to 'source/slang/slang-check-overload.cpp')
-rw-r--r--source/slang/slang-check-overload.cpp43
1 files changed, 35 insertions, 8 deletions
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp
index 18fb9798b..8a8da3eb2 100644
--- a/source/slang/slang-check-overload.cpp
+++ b/source/slang/slang-check-overload.cpp
@@ -245,13 +245,6 @@ bool SemanticsVisitor::TryCheckOverloadCandidateVisibility(
OverloadResolveContext& context,
OverloadCandidate const& candidate)
{
- // Always succeeds when we are trying out constructors.
- if (context.mode == OverloadResolveContext::Mode::JustTrying)
- {
- if (as<ConstructorDecl>(candidate.item.declRef))
- return true;
- }
-
if (!context.sourceScope)
return true;
@@ -1280,6 +1273,21 @@ error:
if (context.originalExpr)
{
+ // Even when there is an error, we still want to update
+ // the expr we return to refer to the candidate we found so far
+ // so language server can still provide info on the potential callee.
+ if (candidate.flavor == OverloadCandidate::Flavor::Func)
+ {
+ if (auto invokeExpr = as<InvokeExpr>(context.originalExpr))
+ {
+ invokeExpr->functionExpr = ConstructLookupResultExpr(
+ candidate.item,
+ context.baseExpr,
+ candidate.item.declRef.getName(),
+ context.funcLoc,
+ context.originalExpr);
+ }
+ }
return CreateErrorExpr(context.originalExpr);
}
else
@@ -2711,9 +2719,15 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr)
// equivalent in (almost) all cases.
// If callee is a type, and we are calling with one argument, then treat it as a
// type coercion.
+ //
+ // Exception: if the argument is an initializer list, such as
+ // Foo({1,2,3}), we should not coerce {1,2,3} to Foo, but rather
+ // treat it as a ctor call with {1,2,3} as the first argument.
+ //
bool typeOverloadChecked = false;
- if (expr->arguments.getCount() == 1 && !as<ExplicitCtorInvokeExpr>(expr))
+ if (expr->arguments.getCount() == 1 && !as<ExplicitCtorInvokeExpr>(expr) &&
+ !as<InitializerListExpr>(expr->arguments[0]))
{
if (const auto typeType = as<TypeType>(funcExpr->type))
{
@@ -2943,7 +2957,20 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr)
initListExpr->type = m_astBuilder->getInitializerListType();
Expr* outExpr = nullptr;
if (_coerceInitializerList(typetype->getType(), &outExpr, initListExpr))
+ {
+ // If there is a coercion error, make sure we return a valid original expr
+ // for language server to use.
+ if (IsErrorExpr(outExpr))
+ {
+ if (auto invokeExpr = as<InvokeExpr>(outExpr))
+ {
+ invokeExpr->originalFunctionExpr = typeExpr;
+ return CreateErrorExpr(invokeExpr);
+ }
+ return CreateErrorExpr(typeExpr);
+ }
return outExpr;
+ }
}
// Nothing at all was found that we could even consider invoking.