diff options
| author | Yong He <yonghe@outlook.com> | 2024-10-20 09:28:13 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-20 09:28:13 -0700 |
| commit | 307315a7305e76529837fd1cdb677f534d5f539b (patch) | |
| tree | ba39e96ba2e9b3d62d1213aab2f1cc54febe451a /source/slang/slang-check-overload.cpp | |
| parent | 9936178dd3efb026bfa142512a2bf061d7a75ab5 (diff) | |
Properly check switch case. (#5341)
Diffstat (limited to 'source/slang/slang-check-overload.cpp')
| -rw-r--r-- | source/slang/slang-check-overload.cpp | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp index d0441397d..41bac4bb0 100644 --- a/source/slang/slang-check-overload.cpp +++ b/source/slang/slang-check-overload.cpp @@ -2097,7 +2097,7 @@ namespace Slang // by doing so we could weed out cases where a type is "constructed" // from a value of the same type. There is no need in Slang for // "copy constructors" but the stdlib currently has to define - // some just to make code that does, e.g., `float(1.0f)` work. + // some just to make code that does, e.g., `float(1.0f)` work.) LookupResult initializers = lookUpMember( m_astBuilder, @@ -2404,7 +2404,7 @@ namespace Slang return argsListBuilder.produceString(); } - Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr * expr) + Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr) { OverloadResolveContext context; // check if this is a stdlib operator call, if so we want to use cached results @@ -2470,7 +2470,7 @@ namespace Slang context.sourceScope = m_outerScope; context.baseExpr = GetBaseExpr(funcExpr); - // TODO: We should have a special case here where an `InvokeExpr` + // We run a special case here where an `InvokeExpr` // with a single argument where the base/func expression names // a type should always be treated as an explicit type coercion // (and hence bottleneck through `coerce()`) instead of just @@ -2484,8 +2484,33 @@ namespace Slang // that `(T) expr` and `T(expr)` continue to be semantically // `visitTypeCastExpr`) would allow us to continue to ensure // equivalent in (almost) all cases. + // If callee is a type, and we are calling with one argument, then treat it as a + // type coercion. + bool typeOverloadChecked = false; - if (!context.bestCandidate) + if (expr->arguments.getCount() == 1) + { + if (const auto typeType = as<TypeType>(funcExpr->type)) + { + if (isDeclRefTypeOf<AggTypeDeclBase>(typeType->getType())) + { + Expr* resultExpr = nullptr; + DiagnosticSink tempSink(getSourceManager(), nullptr); + ConversionCost conversionCost = kConversionCost_None; + auto coerceResult = SemanticsVisitor(withSink(&tempSink))._coerce( + CoercionSite::ExplicitCoercion, + typeType->getType(), + &resultExpr, + expr->arguments[0]->type, + expr->arguments[0], + &conversionCost); + if (coerceResult) + return resultExpr; + typeOverloadChecked = true; + } + } + } + if (!context.bestCandidate && !typeOverloadChecked) { AddOverloadCandidates(funcExpr, context); } |
