diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 73b00027e733..414d406e870a 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -232,10 +232,8 @@ object Completion { val mappings = collection.mutable.Map.empty[Name, List[ScopedDenotations]].withDefaultValue(List.empty) def addMapping(name: Name, denots: ScopedDenotations) = mappings(name) = mappings(name) :+ denots - var ctx = context - while ctx ne NoContext do - given Context = ctx + ctx.outersIterator.foreach { case ctx @ given Context => if ctx.isImportContext then importedCompletions.foreach { (name, denots) => addMapping(name, ScopedDenotations(denots, ctx)) @@ -251,9 +249,7 @@ object Completion { .groupByName.foreach { (name, denots) => addMapping(name, ScopedDenotations(denots, ctx)) } - - ctx = ctx.outer - end while + } var resultMappings = Map.empty[Name, Seq[SingleDenotation]] diff --git a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala index d0cff4c2e281..6b2237a09b3f 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala @@ -306,7 +306,7 @@ object Interactive { case _ => } contextOfStat(stats, nested, ctx.owner, localCtx) - case tree @ CaseDef(pat, guard, rhs) if nested `eq` rhs => + case tree @ CaseDef(pat, _, _) => val localCtx = outer.fresh.setNewScope pat.foreachSubTree { case bind: Bind => localCtx.enter(bind.symbol) diff --git a/language-server/test/dotty/tools/languageserver/CompletionTest.scala b/language-server/test/dotty/tools/languageserver/CompletionTest.scala index 76749b08796f..b4eeb4b01d71 100644 --- a/language-server/test/dotty/tools/languageserver/CompletionTest.scala +++ b/language-server/test/dotty/tools/languageserver/CompletionTest.scala @@ -1474,4 +1474,48 @@ class CompletionTest { ("xClass", Module, "Foo.xClass"), ("xClass", Class, "Foo.xClass"))) } + + @Test def patternGuardCompletions: Unit = { + code"""object Foo: + | 1 match { case foo if fo${m1} => } + | 1 match { case foo => fo${m2} } + """ + .completion(m1, Set(("foo", Field, "Int"))) + .completion(m2, Set(("foo", Field, "Int"))) + } + + @Test def patternGuardCompletionsUnApply: Unit = { + code"""object Foo: + | Some(1) match { case Some(foo) if fo${m1} => } + | Some(1) match { case Some(foo) => fo${m2} } + """ + .completion(m1, Set(("foo", Field, "Int"))) + .completion(m2, Set(("foo", Field, "Int"))) + } + + @Test def patternGuardCompletionsNested: Unit = { + code"""object Foo: + | ((1, 2), 3) match { case ((foo1, foo2), foo3) if fo${m1} => } + | ((1, 2), 3) match { case ((foo1, foo2), foo3) => fo${m2} } + """ + .completion(m1, Set(("foo1", Field, "Int"), ("foo2", Field, "Int"), ("foo3", Field, "Int"))) + .completion(m2, Set(("foo1", Field, "Int"), ("foo2", Field, "Int"), ("foo3", Field, "Int"))) + } + + @Test def patternGuardCompletionsSeq: Unit = { + code"""object Foo: + | Seq(1, 2) match { case foo1 :: foo2 if fo${m1} => } + | Seq(1, 2) match { case foo1 :: foo2 => fo${m2} } + """ + .completion(m1, Set(("foo1", Field, "Int"), ("foo2", Field, "List[Int]"))) + .completion(m2, Set(("foo1", Field, "Int"), ("foo2", Field, "List[Int]"))) + } + + @Test def noCompletionsInsidePatternBind: Unit = { + code"""object Foo: + | (1, 2) match { case (foo, fo${m1} + """ + .noCompletions() + } + }