diff --git a/compiler/src/dotty/tools/dotc/core/TyperState.scala b/compiler/src/dotty/tools/dotc/core/TyperState.scala index 2c41fc8f0231..b8eff35275a7 100644 --- a/compiler/src/dotty/tools/dotc/core/TyperState.scala +++ b/compiler/src/dotty/tools/dotc/core/TyperState.scala @@ -143,7 +143,15 @@ class TyperState() { reporter.flush() setCommittable(false) val targetState = ctx.typerState - assert(!targetState.isCommitted, s"Attempt to commit $this into already committed $targetState") + + // Committing into an already committed TyperState usually doesn't make + // sense since it means the constraints we're committing won't be propagated + // further, but it can happen if the targetState gets captured in a reported + // Message, because forcing that Message might involve creating and + // committing new TyperStates into the captured one after its been committed. + assert(!targetState.isCommitted || targetState.reporter.hasErrors || targetState.reporter.hasWarnings, + s"Attempt to commit $this into already committed $targetState") + if constraint ne targetState.constraint then Stats.record("typerState.commit.new constraint") constr.println(i"committing $this to $targetState, fromConstr = $constraint, toConstr = ${targetState.constraint}") diff --git a/tests/neg/i13101.scala b/tests/neg/i13101.scala new file mode 100644 index 000000000000..f32ba35ef2c8 --- /dev/null +++ b/tests/neg/i13101.scala @@ -0,0 +1,24 @@ +trait Vehicle +trait Car extends Vehicle + +trait Encoder[A] +object Encoder { + implicit val encodeVehicle: Encoder[Vehicle] = ??? + implicit val encodeCar: Encoder[Car] = ??? +} + +trait Route +trait Printer +trait Marshaller[-A] // must be contravariant + +object Test { + implicit def marshaller[A: Encoder](implicit p: Printer = ???): Marshaller[A] = ??? + // the `Printer` implicit arg seems to be necessary, either with default value, or no implicit in scope + + def foo[A](v: A)(implicit m: Marshaller[A]): Route = ??? + + val route: Route = identity { + val f: (Car => Route) => Route = ??? // ok if s/Car/Vehicle/ + f(vehicle => foo(vehicle)) // error: ambiguous implicit + } +}