diff --git a/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala b/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala index 9fa11c8bf80d..85add107119d 100644 --- a/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala +++ b/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala @@ -70,6 +70,7 @@ object NavigateAST { */ def pathTo(span: Span, from: Positioned, skipZeroExtent: Boolean = false)(implicit ctx: Context): List[Positioned] = { def childPath(it: Iterator[Any], path: List[Positioned]): List[Positioned] = { + var bestFit: List[Positioned] = path while (it.hasNext) { val path1 = it.next() match { case p: Positioned => singlePath(p, path) @@ -77,9 +78,13 @@ object NavigateAST { case xs: List[_] => childPath(xs.iterator, path) case _ => path } - if (path1 ne path) return path1 + if ((path1 ne path) && + ((bestFit eq path) || + bestFit.head.span != path1.head.span && + bestFit.head.span.contains(path1.head.span))) + bestFit = path1 } - path + bestFit } def singlePath(p: Positioned, path: List[Positioned]): List[Positioned] = if (p.span.exists && !(skipZeroExtent && p.span.isZeroExtent) && p.span.contains(span)) { diff --git a/compiler/src/dotty/tools/dotc/ast/Positioned.scala b/compiler/src/dotty/tools/dotc/ast/Positioned.scala index a8e91ca2076c..7ee0f4798164 100644 --- a/compiler/src/dotty/tools/dotc/ast/Positioned.scala +++ b/compiler/src/dotty/tools/dotc/ast/Positioned.scala @@ -147,6 +147,11 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro } } + /** A hook that can be overridden if overlap checking in `checkPos` should be + * disabled for this node. + */ + def disableOverlapChecks = false + /** Check that all positioned items in this tree satisfy the following conditions: * - Parent spans contain child spans * - If item is a non-empty tree, it has a position @@ -169,7 +174,7 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro s"position error: position not set for $tree # ${tree.uniqueId}") case _ => } - if (nonOverlapping) { + if (nonOverlapping && !disableOverlapChecks) { this match { case _: XMLBlock => // FIXME: Trees generated by the XML parser do not satisfy `checkPos` diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 2e9ca19b7b19..a74dc2e4c069 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -746,6 +746,10 @@ object Trees { assert(tpt != genericEmptyTree) def unforced: LazyTree = preRhs protected def force(x: AnyRef): Unit = preRhs = x + + override def disableOverlapChecks = rawMods.is(Flags.Implied) + // disable order checks for implicit aliases since their given clause follows + // their for clause, but the two appear swapped in the DefDef. } class BackquotedDefDef[-T >: Untyped] private[ast] (name: TermName, tparams: List[TypeDef[T]], @@ -783,6 +787,10 @@ object Trees { def parents: List[Tree[T]] = parentsOrDerived // overridden by DerivingTemplate def derived: List[untpd.Tree] = Nil // overridden by DerivingTemplate + + override def disableOverlapChecks = true + // disable overlaps checks since templates of instance definitions have their + // `given` clause come last, which means that the constructor span can contain the parent spans. } diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index 94ca12203539..74e831d36b96 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -415,9 +415,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { vdef.withMods(mods | Param) } - def makeSyntheticParameter(n: Int = 1, tpt: Tree = null, flags: FlagSet = EmptyFlags)(implicit ctx: Context): ValDef = + def makeSyntheticParameter(n: Int = 1, tpt: Tree = null, flags: FlagSet = SyntheticTermParam)(implicit ctx: Context): ValDef = ValDef(nme.syntheticParamName(n), if (tpt == null) TypeTree() else tpt, EmptyTree) - .withFlags(flags | SyntheticTermParam) + .withFlags(flags) def lambdaAbstract(tparams: List[TypeDef], tpt: Tree)(implicit ctx: Context): Tree = if (tparams.isEmpty) tpt else LambdaTypeTree(tparams, tpt) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index ab5484380d37..cfd880e32977 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -575,22 +575,26 @@ object Parsers { } else recur(operand()) } - else if (in.token == GIVEN) { + else if (in.token == GIVEN && !isType) { val top1 = reduceStack(base, top, minInfixPrec, leftAssoc = true, nme.WITHkw, isType) assert(opStack `eq` base) - val app = atSpan(startOffset(top1), in.offset) { - in.nextToken() - val args = if (in.token == LPAREN) parArgumentExprs() else operand() :: Nil - Apply(top, args) - } - app.pushAttachment(ApplyGiven, ()) - recur(app) + recur(applyGiven(top1, operand)) } else reduceStack(base, top, minPrec, leftAssoc = true, in.name, isType) recur(first) } + def applyGiven(t: Tree, operand: () => Tree): Tree = { + val app = atSpan(startOffset(t), in.offset) { + in.nextToken() + val args = if (in.token == LPAREN) parArgumentExprs() else operand() :: Nil + Apply(t, args) + } + app.pushAttachment(ApplyGiven, ()) + app + } + /* -------- IDENTIFIERS AND LITERALS ------------------------------------------- */ /** Accept identifier and return its name as a term name. */ @@ -2247,7 +2251,8 @@ object Parsers { val tps = commaSeparated(() => annotType()) var counter = nparams def nextIdx = { counter += 1; counter } - val params = tps.map(makeSyntheticParameter(nextIdx, _, Given | Implicit)) + val paramFlags = if (ofClass) Private | Local | ParamAccessor else Param + val params = tps.map(makeSyntheticParameter(nextIdx, _, paramFlags | Synthetic | Given | Implicit)) params :: recur(firstClause = false, nparams + params.length) } else Nil @@ -2673,22 +2678,22 @@ object Parsers { Template(constr, parents, Nil, EmptyValDef, Nil) } - /** InstanceDef ::= [id] InstanceParams InstanceBody + /** InstanceDef ::= [id] [DefTypeParamClause] InstanceBody * InstanceParams ::= [DefTypeParamClause] {GivenParamClause} - * InstanceBody ::= [‘for’ ConstrApp {‘,’ ConstrApp }] [TemplateBody] - * | ‘for’ Type ‘=’ Expr + * InstanceBody ::= [‘for’ ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody] + * | ‘for’ Type {GivenParamClause} ‘=’ Expr */ def instanceDef(start: Offset, mods: Modifiers, instanceMod: Mod) = atSpan(start, nameStart) { var mods1 = addMod(mods, instanceMod) val name = if (isIdent) ident() else EmptyTermName val tparams = typeParamClauseOpt(ParamOwner.Def) - val vparamss = paramClauses(ofInstance = true) val parents = if (in.token == FOR) { in.nextToken() tokenSeparated(COMMA, constrApp) } else Nil + val vparamss = paramClauses(ofInstance = true) val instDef = if (in.token == EQUALS && parents.length == 1 && parents.head.isType) { in.nextToken() @@ -2709,13 +2714,43 @@ object Parsers { /* -------- TEMPLATES ------------------------------------------- */ - /** ConstrApp ::= SimpleType {ParArgumentExprs} + /** SimpleConstrApp ::= AnnotType {ParArgumentExprs} + * ConstrApp ::= SimpleConstrApp + * | ‘(’ SimpleConstrApp {‘given’ (PrefixExpr | ParArgumentExprs)} ‘)’ */ val constrApp: () => Tree = () => { - // Using Ident(nme.ERROR) to avoid causing cascade errors on non-user-written code - val t = rejectWildcardType(annotType(), fallbackTree = Ident(nme.ERROR)) - if (in.token == LPAREN) parArgumentExprss(wrapNew(t)) - else t + + def isAnnotType(t: Tree) = t match { + case _: Ident + | _: Select + | _: AppliedTypeTree + | _: Tuple + | _: Parens + | _: RefinedTypeTree + | _: SingletonTypeTree + | _: TypSplice + | _: Annotated => true + case _ => false + } + + def givenArgs(t: Tree): Tree = { + if (in.token == GIVEN) givenArgs(applyGiven(t, prefixExpr)) else t + } + + if (in.token == LPAREN) + inParens { + val t = toplevelTyp() + if (isAnnotType(t)) + if (in.token == LPAREN) givenArgs(parArgumentExprss(wrapNew(t))) + else if (in.token == GIVEN) givenArgs(wrapNew(t)) + else t + else Parens(t) + } + else { + val t = rejectWildcardType(annotType(), fallbackTree = Ident(nme.ERROR)) + // Using Ident(nme.ERROR) to avoid causing cascade errors on non-user-written code + if (in.token == LPAREN) parArgumentExprss(wrapNew(t)) else t + } } /** ConstrApps ::= ConstrApp {‘with’ ConstrApp} (to be deprecated in 3.1) diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index c8ba4f862774..4274013cbd32 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -350,6 +350,11 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { keywordStr("'{") ~ toTextGlobal(args, ", ") ~ keywordStr("}") else if (!ctx.settings.YprintDebug.value && fun.hasType && fun.symbol == defn.InternalQuoted_exprSplice) keywordStr("${") ~ toTextGlobal(args, ", ") ~ keywordStr("}") + else if (tree.getAttachment(untpd.ApplyGiven).isDefined && !homogenizedView) + changePrec(InfixPrec) { + toTextLocal(fun) ~ " given " ~ + (if (args.length == 1) toTextLocal(args.head) else "(" ~ toTextGlobal(args, ", ") ~ ")") + } else toTextLocal(fun) ~ "(" ~ toTextGlobal(args, ", ") ~ ")" case tree: TypeApply => diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 841651128888..55d7969ebe60 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2591,6 +2591,8 @@ class Typer extends Namer tree else if (wtp.isContextual) adaptNoArgs(wtp) // insert arguments implicitly + else if (tree.symbol.isPrimaryConstructor && tree.symbol.info.firstParamTypes.isEmpty) + readapt(tree.appliedToNone) // insert () to primary constructors else errorTree(tree, em"Missing arguments for $methodStr") case _ => tryInsertApplyOrImplicit(tree, pt, locked) { diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 7c071a2c9169..416bc00d45d4 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -378,16 +378,17 @@ ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses ConstrMods ::= {Annotation} [AccessModifier] ObjectDef ::= id [Template] ModuleDef(mods, name, template) // no constructor EnumDef ::= id ClassConstr InheritClauses EnumBody EnumDef(mods, name, tparams, template) -InstanceDef ::= [id] InstanceParams InstanceBody +InstanceDef ::= [id] [DefTypeParamClause] InstanceBody InstanceParams ::= [DefTypeParamClause] {GivenParamClause} -InstanceBody ::= [‘for’ ConstrApp {‘,’ ConstrApp }] [TemplateBody] - | ‘for’ Type ‘=’ Expr +InstanceBody ::= [‘for’ ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody] + | ‘for’ Type {GivenParamClause} ‘=’ Expr Template ::= InheritClauses [TemplateBody] Template(constr, parents, self, stats) InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}] ConstrApps ::= ConstrApp {‘with’ ConstrApp} | ConstrApp {‘,’ ConstrApp} -ConstrApp ::= AnnotType {ArgumentExprs} Apply(tp, args) - | ‘(’ ConstrApp {‘given’ (InfixExpr | ParArgumentExprs)} ‘)’ +ConstrApp ::= SimpleConstrApp + | ‘(’ SimpleConstrApp {‘given’ (PrefixExpr | ParArgumentExprs)} ‘)’ +SimpleConstrApp ::= AnnotType {ArgumentExprs} Apply(tp, args) ConstrExpr ::= SelfInvocation | ConstrBlock SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} diff --git a/docs/docs/reference/contextual-implicit/instance-defs.md b/docs/docs/reference/contextual-implicit/instance-defs.md index 690f0b9b30a4..412cc227fc53 100644 --- a/docs/docs/reference/contextual-implicit/instance-defs.md +++ b/docs/docs/reference/contextual-implicit/instance-defs.md @@ -71,12 +71,13 @@ An implicit instance without type parameters or given clause is created on-deman Here is the new syntax of implicit instances, seen as a delta from the [standard context free syntax of Scala 3](http://dotty.epfl.ch/docs/internals/syntax.html). ``` TmplDef ::= ... - | ‘implicit’ InstanceDef + | ‘implicit’ InstanceDef InstanceDef ::= [id] [DefTypeParamClause] InstanceBody -InstanceBody ::= [‘of’ ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody] - | ‘of’ Type {GivenParamClause} ‘=’ Expr -ConstrApp ::= AnnotType {ArgumentExprs} - | ‘(’ ConstrApp {‘given’ (InfixExpr | ParArgumentExprs)} ‘)’ +InstanceBody ::= [‘for’ ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody] + | ‘for’ Type {GivenParamClause} ‘=’ Expr +ConstrApp ::= SimpleConstrApp + | ‘(’ SimpleConstrApp {‘given’ (PrefixExpr | ParArgumentExprs)} ‘)’ +SimpleConstrApp ::= AnnotType {ArgumentExprs} GivenParamClause ::= ‘given’ (‘(’ [DefParams] ‘)’ | GivenTypes) GivenTypes ::= AnnotType {‘,’ AnnotType} ``` diff --git a/docs/docs/reference/contextual/instance-defs.md b/docs/docs/reference/contextual/instance-defs.md index 79fddb295b52..10b4c949aa58 100644 --- a/docs/docs/reference/contextual/instance-defs.md +++ b/docs/docs/reference/contextual/instance-defs.md @@ -72,6 +72,8 @@ GivenParamClause ::= ‘given’ (‘(’ [DefParams] ‘)’ | GivenTypes) InstanceBody ::= [‘for’ ConstrApp {‘,’ ConstrApp }] [TemplateBody] | ‘for’ Type ‘=’ Expr GivenTypes ::= AnnotType {‘,’ AnnotType} +ConstrApp ::= SimpleConstrApp + | ‘(’ SimpleConstrApp {‘given’ (PrefixExpr | ParArgumentExprs)} ‘)’ ``` The identifier `id` can be omitted only if either the `for` part or the template body is present. If the `for` part is missing, the template body must define at least one extension method. diff --git a/tests/neg/i5978.scala b/tests/neg/i5978.scala index 33fceb941082..7543ae141cd7 100644 --- a/tests/neg/i5978.scala +++ b/tests/neg/i5978.scala @@ -7,8 +7,8 @@ trait TokenParser[Token, R] object TextParser { implied TP for TokenParser[Char, Position[CharSequence]] {} - implied FromCharToken - given (T: TokenParser[Char, Position[CharSequence]]) for Conversion[Char, Position[CharSequence]] = ??? + implied FromCharToken for Conversion[Char, Position[CharSequence]] + given (T: TokenParser[Char, Position[CharSequence]]) = ??? } diff --git a/tests/neg/parser-stability-25.scala b/tests/neg/parser-stability-25.scala index 23db4498af0e..68fa28a9d9e1 100644 --- a/tests/neg/parser-stability-25.scala +++ b/tests/neg/parser-stability-25.scala @@ -11,5 +11,5 @@ class D extends (Int => 1) { } class Wrap(x: Int) -class E extends (Wrap)( // error +class E extends (Wrap)( // error // error // error \ No newline at end of file diff --git a/tests/pos/given-constrapps.scala b/tests/pos/given-constrapps.scala new file mode 100644 index 000000000000..020aa6231ebc --- /dev/null +++ b/tests/pos/given-constrapps.scala @@ -0,0 +1,29 @@ +class TC +val tc = TC() +class C given (x: TC) { + assert(x eq tc) +} +class C2(n: Int) given (x: TC) given List[TC] { + assert(x eq tc) + the[List[TC]].foreach(t => assert(t eq tc)) + + def this() given TC given List[TC] = this(1) +} + +class D extends (C given tc) +class D2 extends (C2(1) given tc given Nil) + +class Foo given TC { + assert(the[TC] != null) +} + +object Test extends App { + new (C given tc) + new (C() given tc) + new (C given tc) {} + new (C2(1) given tc given List(tc)) + new (C2(1) given tc given List(tc)) {} + new (C2() given tc given List(tc)) + def foo given TC = () + foo given tc +} \ No newline at end of file diff --git a/tests/pos/i5978.scala b/tests/pos/i5978.scala index 705c2a226346..4daf73e09fd1 100644 --- a/tests/pos/i5978.scala +++ b/tests/pos/i5978.scala @@ -9,8 +9,8 @@ package p1 { object TextParser { implied TP for TokenParser[Char, Position[CharSequence]] {} - implied FromCharToken - given (T: TokenParser[Char, Position[CharSequence]]) for Conversion[Char, Position[CharSequence]] = ??? + implied FromCharToken for Conversion[Char, Position[CharSequence]] + given (T: TokenParser[Char, Position[CharSequence]])= ??? } diff --git a/tests/pos/multiversal.scala b/tests/pos/multiversal.scala index 27197dbc6e2d..cbe295ff1ed4 100644 --- a/tests/pos/multiversal.scala +++ b/tests/pos/multiversal.scala @@ -1,7 +1,7 @@ object Test { import scala.Eql - implied [X, Y] given Eql[X, Y] for Eql[List[X], List[Y]] = Eql.derived + implied [X, Y] for Eql[List[X], List[Y]] given Eql[X, Y] = Eql.derived val b: Byte = 1 val c: Char = 2 diff --git a/tests/pos/reference/instances.scala b/tests/pos/reference/instances.scala index cb9631fb8d90..23f99bc207ee 100644 --- a/tests/pos/reference/instances.scala +++ b/tests/pos/reference/instances.scala @@ -37,7 +37,7 @@ object Instances extends Common { if (x < y) -1 else if (x > y) +1 else 0 } - implied ListOrd[T] given Ord[T] for Ord[List[T]] { + implied ListOrd[T] for Ord[List[T]] given Ord[T] { def (xs: List[T]) compareTo (ys: List[T]): Int = (xs, ys) match { case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -132,7 +132,7 @@ object Instances extends Common { println(the[D[Int]]) } locally { - implied given Context for D[Int] + implied for D[Int] given Context println(the[D[Int]]) } } @@ -195,7 +195,7 @@ object AnonymousInstances extends Common { def (xs: List[T]) second[T] = xs.tail.head } - implied [From, To] given (c: Convertible[From, To]) for Convertible[List[From], List[To]] { + implied [From, To] for Convertible[List[From], List[To]] given (c: Convertible[From, To]) { def (x: List[From]) convert: List[To] = x.map(c.convert) } diff --git a/tests/run/implicit-specifity.scala b/tests/run/implicit-specifity.scala index d21462d74f77..cc833cdc24d2 100644 --- a/tests/run/implicit-specifity.scala +++ b/tests/run/implicit-specifity.scala @@ -9,7 +9,7 @@ object Show { class Generic object Generic { implied gen for Generic = new Generic - implied showGen[T] given Generic for Show[T] = new Show[T](2) + implied showGen[T] for Show[T] given Generic = new Show[T](2) } class Generic2 @@ -25,9 +25,9 @@ object SubGen { object Contextual { trait Context implied ctx for Context - implied showGen[T] given Generic for Show[T] = new Show[T](2) - implied showGen[T] given Generic, Context for Show[T] = new Show[T](3) - implied showGen[T] given SubGen for Show[T] = new Show[T](4) + implied showGen[T] for Show[T] given Generic = new Show[T](2) + implied showGen[T] for Show[T] given Generic, Context = new Show[T](3) + implied showGen[T] for Show[T] given SubGen = new Show[T](4) } object Test extends App { diff --git a/tests/run/implied-divergence.scala b/tests/run/implied-divergence.scala index 739791581176..2557a7433816 100644 --- a/tests/run/implied-divergence.scala +++ b/tests/run/implied-divergence.scala @@ -6,7 +6,7 @@ implied e for E(null) object Test extends App { - implied f given (e: E) for E(e) + implied f for E(e) given (e: E) assert(the[E].toString == "E(E(null))") diff --git a/tests/run/implied-priority.scala b/tests/run/implied-priority.scala index cdd89d78631a..9e3a32b31b96 100644 --- a/tests/run/implied-priority.scala +++ b/tests/run/implied-priority.scala @@ -15,7 +15,7 @@ class LowPriorityImplicits { } object NormalImplicits extends LowPriorityImplicits { - implied t2[T] given Arg[T] for E[T]("norm") + implied t2[T]for E[T]("norm") given Arg[T] } def test1 = { @@ -38,8 +38,8 @@ object Priority { } object Impl2 { - implied t1[T] given Priority.Low for E[T]("low") - implied t2[T] given Priority.High given Arg[T] for E[T]("norm") + implied t1[T] for E[T]("low") given Priority.Low + implied t2[T] for E[T]("norm") given Priority.High given Arg[T] } def test2 = { @@ -102,7 +102,7 @@ def test3 = { */ object Impl4 { implied t1 for E[String]("string") - implied t2[T] given Arg[T] for E[T]("generic") + implied t2[T] for E[T]("generic") given Arg[T] } object fallback4 { @@ -133,7 +133,7 @@ object HigherPriority { } object fallback5 { - implied [T] given (ev: E[T] = new E[T]("fallback")) for (E[T] & HigherPriority) = HigherPriority.inject(ev) + implied [T] for (E[T] & HigherPriority) given (ev: E[T] = new E[T]("fallback")) = HigherPriority.inject(ev) } def test5 = { diff --git a/tests/run/implied-specifity-2.scala b/tests/run/implied-specifity-2.scala index 8818eb56c2fd..536a307fa271 100644 --- a/tests/run/implied-specifity-2.scala +++ b/tests/run/implied-specifity-2.scala @@ -15,36 +15,36 @@ class Foo[T](val i: Int) object Foo { def apply[T] given (fooT: Foo[T]): Int = fooT.i - implied foo[T] given Low for Foo[T](0) - implied foobar[T] given Low for Foo[Bar[T]](1) - implied foobarbaz given Low for Foo[Bar[Baz]](2) + implied foo[T] for Foo[T](0) given Low + implied foobar[T] for Foo[Bar[T]](1) given Low + implied foobarbaz for Foo[Bar[Baz]](2) given Low } class Bar[T] object Bar { - implied foobar[T] given Medium for Foo[Bar[T]](3) - implied foobarbaz given Medium for Foo[Bar[Baz]](4) + implied foobar[T] for Foo[Bar[T]](3) given Medium + implied foobarbaz for Foo[Bar[Baz]](4) given Medium } class Baz object Baz { - implied baz given High for Foo[Bar[Baz]](5) + implied baz for Foo[Bar[Baz]](5) given High } class Arg implied for Arg class Bam(val str: String) -implied lo given Low for Bam("lo") -implied hi given High given Arg for Bam("hi") +implied lo for Bam("lo") given Low +implied hi for Bam("hi") given High given Arg class Bam2(val str: String) -implied lo2 given Low for Bam2("lo") -implied mid2 given High given Arg for Bam2("mid") +implied lo2 for Bam2("lo") given Low +implied mid2 for Bam2("mid") given High given Arg implied hi2 for Bam2("hi") class Arg2 class Red(val str: String) -implied normal given Arg2 for Red("normal") -implied reduced given (ev: Arg2 | Low) for Red("reduced") +implied normal for Red("normal") given Arg2 +implied reduced for Red("reduced") given (ev: Arg2 | Low) object Test extends App { assert(Foo[Int] == 0) diff --git a/tests/run/tagless.scala b/tests/run/tagless.scala index e14a0c12b25e..8d199a762fd0 100644 --- a/tests/run/tagless.scala +++ b/tests/run/tagless.scala @@ -196,7 +196,7 @@ object Test extends App { // Added operation: negation pushdown enum NCtx { case Pos, Neg } - implied [T] given (e: Exp[T]) for Exp[NCtx => T] { + implied [T] for Exp[NCtx => T] given (e: Exp[T]) { import NCtx._ def lit(i: Int) = { case Pos => e.lit(i) @@ -216,7 +216,7 @@ object Test extends App { println(pushNeg(tf1[NCtx => String])) println(pushNeg(pushNeg(pushNeg(tf1))): String) - implied [T] given (e: Mult[T]) for Mult[NCtx => T] { + implied [T] for Mult[NCtx => T] given (e: Mult[T]) { import NCtx._ def mul(l: NCtx => T, r: NCtx => T): NCtx => T = { case Pos => e.mul(l(Pos), r(Pos))