diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 2ecab983b1d7..10974daf0571 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -479,11 +479,11 @@ object ProtoTypes { * for each parameter. * @return The added type lambda, and the list of created type variables. */ - def constrained(tl: TypeLambda, owningTree: untpd.Tree, alwaysAddTypeVars: Boolean = false)(implicit ctx: Context): (TypeLambda, List[TypeTree]) = { + def constrained(tl: TypeLambda, owningTree: untpd.Tree, alwaysAddTypeVars: Boolean)(implicit ctx: Context): (TypeLambda, List[TypeTree]) = { val state = ctx.typerState val addTypeVars = alwaysAddTypeVars || !owningTree.isEmpty if (tl.isInstanceOf[PolyType]) - assert(!(ctx.typerState.isCommittable && !addTypeVars), + assert(!ctx.typerState.isCommittable || addTypeVars, s"inconsistent: no typevars were added to committable constraint ${state.constraint}") // hk type lambdas can be added to constraints without typevars during match reduction @@ -502,8 +502,13 @@ object ProtoTypes { (added, tvars) } + def constrained(tl: TypeLambda, owningTree: untpd.Tree)(implicit ctx: Context): (TypeLambda, List[TypeTree]) = + constrained(tl, owningTree, + alwaysAddTypeVars = tl.isInstanceOf[PolyType] && ctx.typerState.isCommittable) + /** Same as `constrained(tl, EmptyTree)`, but returns just the created type lambda */ - def constrained(tl: TypeLambda)(implicit ctx: Context): TypeLambda = constrained(tl, EmptyTree)._1 + def constrained(tl: TypeLambda)(implicit ctx: Context): TypeLambda = + constrained(tl, EmptyTree)._1 def newTypeVar(bounds: TypeBounds)(implicit ctx: Context): TypeVar = { val poly = PolyType(DepParamName.fresh().toTypeName :: Nil)( diff --git a/tests/neg/i7060.scala b/tests/neg/i7060.scala new file mode 100644 index 000000000000..93ada152f811 --- /dev/null +++ b/tests/neg/i7060.scala @@ -0,0 +1,19 @@ +object PostConditions1 { + + import PostConditions.{ensure, res, Box} + + val v = List(1, 2, 4).sum.ensure(Box(10) => res == 10) // error: not a legal formal parameter + println(v) +} + +object PostConditions { + + class Box[T](val t: T) + + def res[T] given (b: Box[T]): T = b.t + + def (e: T) ensure[T](cond: given Box[T] => Boolean): T = { + if (cond given Box(e)) e + else throw new AssertionError("condition not fulfilled") + } +} \ No newline at end of file