From a035a175012bf53ee96bca7e431bd9f72974618d Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 17 Jul 2025 13:09:59 -0700 Subject: [PATCH] Reset typer state on issueErrors --- .../src/dotty/tools/dotc/typer/Typer.scala | 12 ++++++------ tests/pos/i23555.scala | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 tests/pos/i23555.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index b0156883261a..974905a5d946 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -4406,6 +4406,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer /** Reports errors for arguments of `appTree` that have a `SearchFailureType`. */ def issueErrors(fun: Tree, args: List[Tree], failureType: Type): Tree = + // If there are several arguments, some arguments might already + // have influenced the context, binding variables, but later ones + // might fail. In that case the constraint and instantiated variables + // need to be reset. + ctx.typerState.resetTo(saved) + val errorType = failureType match case ai: AmbiguousImplicits => ai.asNested case tp => tp @@ -4426,12 +4432,6 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val args = implicitArgs(wtp.paramInfos, 0, pt) val failureType = propagatedFailure(args) if failureType.exists then - // If there are several arguments, some arguments might already - // have influenced the context, binding variables, but later ones - // might fail. In that case the constraint and instantiated variables - // need to be reset. - ctx.typerState.resetTo(saved) - // If method has default params, fall back to regular application // where all inferred implicits are passed as named args. if hasDefaultParams && !failureType.isInstanceOf[AmbiguousImplicits] then diff --git a/tests/pos/i23555.scala b/tests/pos/i23555.scala new file mode 100644 index 000000000000..5e02d04db05c --- /dev/null +++ b/tests/pos/i23555.scala @@ -0,0 +1,19 @@ +trait Behavior[A] + +object Behavior: + //implicit def mapBehavior[A: Behavior]: Behavior[List[A]] = new Behavior[List[A]] {} + given [A: Behavior] => Behavior[List[A]] + +object Model: + case class Foo(i: Int) + object Foo: + given Behavior[Foo] = new Behavior[Foo] {} + //implicit def dummy[A: Behavior](using s: String = "hello"): Option[A] = None + //implicit def dummy[A: Behavior](using s: String = "hello")(using DummyImplicit): Option[A] = None + given [A: Behavior] => (s: String = "hello") => Option[A] = None + +@main def Test = + import Model.Foo + //implicitly[Option[List[Foo]]] + //Foo.dummy[List[Foo]](using s = "bye") + summon[Option[List[Foo]]]