From e71e75ab96fab6897f445c96a1de67e528676955 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 24 Mar 2020 14:04:30 -0700 Subject: Fix some bad behavior around static methods (#1289) These are steps towards a fix for the problem of not being able to call a static method as follows: SomeType::someMethod(); One problem in the above is that the parser gets confused and parses an (anonynmous!) function declaration. This change doesn't address that problem, but *does* fix the problem that when checking fails to coerce `SomeType::someMethod` into a type it was triggering an unimplemented-feature exception rather than a real error message. Another problem was that if the above is re-written to try to avoid the parser bug: (SomeType::someMethod)(); we end up with a call where the base expression (the callee) is a `ParenExpr` and the code for handling calls wasn't expecting that. Instead, it sent the overload resolution logic into an unimplemented case that was bailing by throwing an arbitrary C++ exception instead of emitting a diagnostic. This latter issue was fixed in two ways. First, the code path that failed to emit a diagnostic now emits a reasonable one for the unimplemented feature (this still ends up being a fatal compiler error). Second, we properly handle the case of trying to call a `ParenExpr` by unwrapping it and using the base expression instead, so that `()()` is always treated the same as `()`. --- source/slang/slang-check-overload.cpp | 36 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'source/slang/slang-check-overload.cpp') diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp index 92d390bf0..0cad2875a 100644 --- a/source/slang/slang-check-overload.cpp +++ b/source/slang/slang-check-overload.cpp @@ -849,25 +849,11 @@ namespace Slang } void SemanticsVisitor::AddFuncOverloadCandidate( - RefPtr /*funcType*/, - OverloadResolveContext& /*context*/) + RefPtr funcType, + OverloadResolveContext& context) { -#if 0 - if (funcType->decl) - { - AddFuncOverloadCandidate(funcType->decl, context); - } - else if (funcType->Func) - { - AddFuncOverloadCandidate(funcType->Func->SyntaxNode, context); - } - else if (funcType->Component) - { - AddComponentFuncOverloadCandidate(funcType->Component, context); - } -#else - throw "unimplemented"; -#endif + SLANG_UNUSED(funcType); + getSink()->diagnose(context.loc, Diagnostics::unimplemented, "call on expression of function type"); } void SemanticsVisitor::AddCtorOverloadCandidate( @@ -1093,9 +1079,19 @@ namespace Slang } void SemanticsVisitor::AddOverloadCandidates( - RefPtr funcExpr, - OverloadResolveContext& context) + RefPtr funcExpr, + OverloadResolveContext& context) { + // A call of the form `()()` should be + // resolved as if the user wrote `()`, + // so that we avoid introducing intermediate expressions + // of function type in cases where they are not needed. + // + while(auto parenExpr = as(funcExpr)) + { + funcExpr = parenExpr->base; + } + auto funcExprType = funcExpr->type; if (auto declRefExpr = as(funcExpr)) -- cgit v1.2.3