summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-09-09 22:14:05 -0700
committerGitHub <noreply@github.com>2025-09-10 05:14:05 +0000
commit43dffcde78227113a0e62b02857eaf4ed6ea6e7e (patch)
tree5cf38f83d37188651b938aa73d5e07fadd107a26
parent7026dec790ab0c239c58ebf72b17633e9e8765c3 (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.
-rw-r--r--source/slang/slang-check-expr.cpp16
-rw-r--r--tests/language-server/completion-in-initexpr.slang20
2 files changed, 33 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)
diff --git a/tests/language-server/completion-in-initexpr.slang b/tests/language-server/completion-in-initexpr.slang
new file mode 100644
index 000000000..8eec82991
--- /dev/null
+++ b/tests/language-server/completion-in-initexpr.slang
@@ -0,0 +1,20 @@
+//TEST:LANG_SERVER(filecheck=CHECK):
+//COMPLETE:17,21
+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.;
+}
+
+// CHECK: getSum