diff options
| author | Yong He <yonghe@outlook.com> | 2025-09-09 22:14:05 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-10 05:14:05 +0000 |
| commit | 43dffcde78227113a0e62b02857eaf4ed6ea6e7e (patch) | |
| tree | 5cf38f83d37188651b938aa73d5e07fadd107a26 /source | |
| parent | 7026dec790ab0c239c58ebf72b17633e9e8765c3 (diff) | |
Fix language server auto-complete regression in debug build. (#8416)
Fixes this regression:
```slang
struct MyType
{
// Regression Condition 1: there must be more than one member in the lookup scope.
float v;
int getSum() { return 0; }
}
void m(MyType t)
{
// Regression condition 2: the completion must be in an init expression.
// Regression condition 3: none of the candidate members can coerce to the expected type.
// Regression behavior: no completion candidates are shown, because
// SemanticsVisitor::resolveOverloadedLookup throws an error when there are 0 applicable candidates
// after type coercion filtering.
Texture2D x = t.; // completion request after . here
}
```
The root cause is that we shouldn't be applying candidate filtering on
the candidate list when in completion checking mode.
Closes #8417.
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index ec249f56d..8994eb783 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -1139,13 +1139,20 @@ LookupResult SemanticsVisitor::resolveOverloadedLookup( if (!inResult.isOverloaded()) return inResult; + // If this is a lookup for a completion request token (to generate completion candidate list), + // don't apply expected-type filtering on the lookup result so we can report the entire + // candidate list in the language server. + bool shouldSkipCoercionFilter = + getLinkage()->contentAssistInfo.checkingMode == ContentAssistCheckingMode::Completion && + inResult.getName() == getSession()->getCompletionRequestTokenName(); + // We are going to build up a list of items to return. List<LookupResultItem> items; for (auto item : inResult.items) { // First we check if the item is coercible to targetType. // And skip if it doesn't. - if (targetType) + if (targetType && !shouldSkipCoercionFilter) { auto declType = GetTypeForDeclRef(item.declRef, SourceLoc()); if (!canCoerce(targetType, declType, nullptr, nullptr)) @@ -1186,9 +1193,12 @@ LookupResult SemanticsVisitor::resolveOverloadedLookup( // The resulting `items` list should be all those items // that were neither better nor worse than one another. // - // There should always be at least one such item. + // If no candidates are passing coercion check, return unresolved lookup result + // and leave downstream logic to diagnose and error. // - SLANG_ASSERT(items.getCount() != 0); + + if (items.getCount() == 0) + return inResult; LookupResult result; for (auto item : items) |
