From ee1eadbe2b3b914a06f2764cd393fe86e2918834 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 2 Jul 2019 16:57:07 +0200 Subject: [PATCH 1/9] Apply refactorings blocked previously Apply refactorings that were not possible before because bootstrap compiler had problems with them. --- .../src/dotty/tools/dotc/core/Flags.scala | 6 +--- .../tools/dotc/core/SymDenotations.scala | 36 +++++++------------ .../tools/dotc/tastyreflect/KernelImpl.scala | 2 -- .../dotty/tools/dotc/typer/Variances.scala | 1 - 4 files changed, 13 insertions(+), 32 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 464807e98a35..3de27b232634 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -20,11 +20,7 @@ object Flags { opaque type Flag <: FlagSet = Long private[Flags] def Flag(bits: Long): Flag = bits } - type FlagSet = opaques.FlagSet - def FlagSet(bits: Long): FlagSet = opaques.FlagSet(bits) - // DOTTY TODO: replace previous 2 lines with - // export opaques.FlagSet - // once 0.17 is released and #6721 is in the bootstrap + export opaques.FlagSet type Flag = opaques.Flag diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 67ee4bd91d0f..df91418e7979 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -187,46 +187,34 @@ object SymDenotations { if (isCurrent(fs)) myFlags else flags /** Has this denotation one of given flag set? */ - final def is(flag: Flag)(implicit ctx: Context): Boolean = { - val toTest = if (isCurrent(flag)) myFlags else flags // TODO: combine these two lines once 0.17 is released and #6706 is in - toTest.is(flag) - } + final def is(flag: Flag)(implicit ctx: Context): Boolean = + (if (isCurrent(flag)) myFlags else flags).is(flag) /** Has this denotation one of the flags in `fs` set? */ - final def isOneOf(fs: FlagSet)(implicit ctx: Context): Boolean = { - val toTest = if (isCurrent(fs)) myFlags else flags // TODO: combine these two lines once 0.17 is released and #6706 is in - toTest.isOneOf(fs) - } + final def isOneOf(fs: FlagSet)(implicit ctx: Context): Boolean = + (if (isCurrent(fs)) myFlags else flags).isOneOf(fs) /** Has this denotation the given flag set, whereas none of the flags * in `butNot` are set? */ - final def is(flag: Flag, butNot: FlagSet)(implicit ctx: Context): Boolean = { - val toTest = if (isCurrent(flag) && isCurrent(butNot)) myFlags else flags // TODO: combine these two lines once 0.17 is released and #6706 is in - toTest.is(flag, butNot) - } + final def is(flag: Flag, butNot: FlagSet)(implicit ctx: Context): Boolean = + (if (isCurrent(flag) && isCurrent(butNot)) myFlags else flags).is(flag, butNot) /** Has this denotation one of the flags in `fs` set, whereas none of the flags * in `butNot` are set? */ - final def isOneOf(fs: FlagSet, butNot: FlagSet)(implicit ctx: Context): Boolean = { - val toTest = if (isCurrent(fs) && isCurrent(butNot)) myFlags else flags // TODO: combine these two lines once 0.17 is released and #6706 is in - toTest.isOneOf(fs, butNot) - } + final def isOneOf(fs: FlagSet, butNot: FlagSet)(implicit ctx: Context): Boolean = + (if (isCurrent(fs) && isCurrent(butNot)) myFlags else flags).isOneOf(fs, butNot) /** Has this denotation all of the flags in `fs` set? */ - final def isAllOf(fs: FlagSet)(implicit ctx: Context): Boolean = { - val toTest = if (isCurrent(fs)) myFlags else flags // TODO: combine these two lines once 0.17 is released and #6706 is in - toTest.isAllOf(fs) - } + final def isAllOf(fs: FlagSet)(implicit ctx: Context): Boolean = + (if (isCurrent(fs)) myFlags else flags).isAllOf(fs) /** Has this denotation all of the flags in `fs` set, whereas none of the flags * in `butNot` are set? */ - final def isAllOf(fs: FlagSet, butNot: FlagSet)(implicit ctx: Context): Boolean = { - val toTest = if (isCurrent(fs) && isCurrent(butNot)) myFlags else flags // TODO: combine these two lines once 0.17 is released and #6706 is in - toTest.isAllOf(fs, butNot) - } + final def isAllOf(fs: FlagSet, butNot: FlagSet)(implicit ctx: Context): Boolean = + (if (isCurrent(fs) && isCurrent(butNot)) myFlags else flags).isAllOf(fs, butNot) /** The type info, or, if symbol is not yet completed, the completer */ final def infoOrCompleter: Type = myInfo diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala index 0e2dddf69555..3d2d674f5730 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala @@ -17,8 +17,6 @@ import dotty.tools.dotc.util.SourceFile import scala.tasty.reflect.Kernel -import delegate Flags.FlagOps // DOTTY problem: this line can be dropped in 0.17 once #6712 is in bootstrap. - class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util.SourcePosition) extends Kernel { private implicit def ctx: core.Contexts.Context = rootContext diff --git a/compiler/src/dotty/tools/dotc/typer/Variances.scala b/compiler/src/dotty/tools/dotc/typer/Variances.scala index 05570bac0bbe..014c23c961ee 100644 --- a/compiler/src/dotty/tools/dotc/typer/Variances.scala +++ b/compiler/src/dotty/tools/dotc/typer/Variances.scala @@ -3,7 +3,6 @@ package typer import core._ import Types._, Contexts._, Flags._, Symbols._, Annotations._ -import delegate Flags.FlagOps // DOTTY problem: this line can be dropped in 0.17 once #6712 is in bootstrap. object Variances { From 5bff0ce2b2e49176eb1835c835908a847e605dd2 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 2 Jul 2019 17:29:07 +0200 Subject: [PATCH 2/9] Make MatchDegree an enum --- compiler/src/dotty/tools/dotc/core/Denotations.scala | 6 +++--- compiler/src/dotty/tools/dotc/core/Signature.scala | 8 ++++---- .../dotty/tools/dotc/reporting/diagnostic/messages.scala | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index 331d593a2644..e15a4ba59025 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -757,8 +757,8 @@ object Denotations { def atSignature(sig: Signature, site: Type, relaxed: Boolean)(implicit ctx: Context): SingleDenotation = { val situated = if (site == NoPrefix) this else asSeenFrom(site) - val matches = sig.matchDegree(situated.signature) >= - (if (relaxed) Signature.ParamMatch else Signature.FullMatch) + val matches = sig.matchDegree(situated.signature).ordinal >= + (if (relaxed) Signature.ParamMatch else Signature.FullMatch).ordinal if (matches) this else NoDenotation } @@ -1096,7 +1096,7 @@ object Denotations { d == Signature.FullMatch && !infoOrCompleter.isInstanceOf[PolyType] && !other.infoOrCompleter.isInstanceOf[PolyType] || - d >= Signature.ParamMatch && info.matches(other.info)) + d != Signature.NoMatch && info.matches(other.info)) } def mapInherited(ownDenots: PreDenotation, prevDenots: PreDenotation, pre: Type)(implicit ctx: Context): SingleDenotation = diff --git a/compiler/src/dotty/tools/dotc/core/Signature.scala b/compiler/src/dotty/tools/dotc/core/Signature.scala index 4999c9eb90be..977bcef3f252 100644 --- a/compiler/src/dotty/tools/dotc/core/Signature.scala +++ b/compiler/src/dotty/tools/dotc/core/Signature.scala @@ -107,10 +107,10 @@ case class Signature(paramsSig: List[TypeName], resSig: TypeName) { object Signature { - type MatchDegree = Int - val NoMatch: Int = 0 - val ParamMatch: Int = 1 - val FullMatch: Int = 2 + enum MatchDegree { + case NoMatch, ParamMatch, FullMatch + } + export MatchDegree._ /** The signature of everything that's not a method, i.e. that has * a type different from PolyType, MethodType, or ExprType. diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 675365864c98..1d37ba7c8edf 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -2154,11 +2154,13 @@ object messages { val details = if (decl.isRealMethod && previousDecl.isRealMethod) { // compare the signatures when both symbols represent methods decl.signature.matchDegree(previousDecl.signature) match { - case Signature.NoMatch => + case Signature.MatchDegree.NoMatch => + // DOTTY problem: Need to qualify MatchDegree enum vals since otherwise exhaustivity fails. + // To fix this, we need to export vals under singleton types. "" // shouldn't be reachable - case Signature.ParamMatch => + case Signature.MatchDegree.ParamMatch => "have matching parameter types." - case Signature.FullMatch => + case Signature.MatchDegree.FullMatch => i"have the same$nameAnd type after erasure." } } else "" From 95aa46e4f98fc9a5f7689e9084b19975143b1c3a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 3 Jul 2019 11:14:07 +0200 Subject: [PATCH 3/9] Allow enum datastructures to be @shared --- compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala b/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala index a573618d90d1..98a3cb12d54e 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala @@ -43,7 +43,10 @@ class CheckReentrant extends MiniPhase { def isIgnored(sym: Symbol)(implicit ctx: Context): Boolean = sym.hasAnnotation(sharableAnnot()) || - sym.hasAnnotation(unsharedAnnot()) + sym.hasAnnotation(unsharedAnnot()) || + sym.owner == defn.EnumValuesClass + // enum values are initialized eagerly before use + // in the long run, we should make them vals def scanning(sym: Symbol)(op: => Unit)(implicit ctx: Context): Unit = { ctx.log(i"${" " * indent}scanning $sym") From 8817b155d25dfca72636755a27e0c276f46766c6 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 3 Jul 2019 13:26:10 +0200 Subject: [PATCH 4/9] Make ErrorMessageID a Scala enum --- .../tools/dotc/reporting/MessageRendering.scala | 2 +- .../{ErrorMessageID.java => ErrorMessageID.scala} | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) rename compiler/src/dotty/tools/dotc/reporting/diagnostic/{ErrorMessageID.java => ErrorMessageID.scala} (95%) diff --git a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala index ce15d818260b..1b28cbc8996a 100644 --- a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala +++ b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala @@ -119,7 +119,7 @@ trait MessageRendering { else s"${pos.source.file.toString}: offset ${pos.start} (missing source file)" val errId = if (message.errorId ne ErrorMessageID.NoExplanationID) { - val errorNumber = message.errorId.errorNumber() + val errorNumber = message.errorId.errorNumber s"[E${"0" * (3 - errorNumber.toString.length) + errorNumber}] " } else "" val kind = diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala similarity index 95% rename from compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java rename to compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala index b84b2cf17af7..0b751d09d404 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala @@ -1,10 +1,10 @@ -package dotty.tools.dotc.reporting.diagnostic; +package dotty.tools.dotc.reporting.diagnostic /** Unique IDs identifying the messages */ -public enum ErrorMessageID { - - // IMPORTANT: Add new IDs only at the end and never remove IDs +enum ErrorMessageID { + // IMPORTANT: Add new IDs only at the end and never remove IDs + case LazyErrorId, // // errorNumber: -2 NoExplanationID, // errorNumber: -1 @@ -146,10 +146,6 @@ public enum ErrorMessageID { StableIdentPatternID, StaticFieldsShouldPrecedeNonStaticID, IllegalSuperAccessorID - ; - - public int errorNumber() { - return ordinal() - 2; - } + def errorNumber = ordinal - 2 } From 1a2682ba53d5323d3481a72735a9cf9c78834a16 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 3 Jul 2019 14:10:58 +0200 Subject: [PATCH 5/9] Let ErrorMessageId extend java.lang.Enum This is necessary so that enum constants come with the class not the companion object which was in turn necessary to let the bootstrapped build pass. Two questions: 1) It seems the bootstrapped build got confused. It seemed it compiled against the previous ErrorMesssageID.java and ran against the ErrorMessageID.scala. 2) In any case, it would be good if enum constants were always generated at the same place, no matter whether we extend java.lang.Enum or not. --- .../dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala index 0b751d09d404..bbfe6c1e505a 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala @@ -1,7 +1,7 @@ package dotty.tools.dotc.reporting.diagnostic /** Unique IDs identifying the messages */ -enum ErrorMessageID { +enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] { // IMPORTANT: Add new IDs only at the end and never remove IDs case From 3ceb51dd0419b686927fe9cd415f83ec948af01c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 3 Jul 2019 13:44:44 +0200 Subject: [PATCH 6/9] Make `reporting` nicer Allow use of `result` instead of having to pass a lambda. --- compiler/src/dotty/tools/dotc/ast/Desugar.scala | 2 +- .../src/dotty/tools/dotc/core/Decorators.scala | 14 ++++++++++---- .../src/dotty/tools/dotc/core/GadtConstraint.scala | 13 ++++++------- .../dotty/tools/dotc/core/OrderingConstraint.scala | 2 +- compiler/src/dotty/tools/dotc/core/Symbols.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Inliner.scala | 2 +- .../src/dotty/tools/dotc/typer/ProtoTypes.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Typer.scala | 2 +- compiler/src/dotty/tools/package.scala | 8 ++++++++ 9 files changed, 30 insertions(+), 17 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index fd09af8a9ee5..bbde5522484b 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -766,7 +766,7 @@ object desugar { } flatTree(cdef1 :: companions ::: implicitWrappers) - }.reporting(res => i"desugared: $res", Printers.desugar) + }.reporting(i"desugared: $result", Printers.desugar) /** Expand * diff --git a/compiler/src/dotty/tools/dotc/core/Decorators.scala b/compiler/src/dotty/tools/dotc/core/Decorators.scala index 37a6e3e10c4f..0ca6b7f86c98 100644 --- a/compiler/src/dotty/tools/dotc/core/Decorators.scala +++ b/compiler/src/dotty/tools/dotc/core/Decorators.scala @@ -1,4 +1,5 @@ -package dotty.tools.dotc +package dotty.tools +package dotc package core import annotation.tailrec @@ -168,11 +169,16 @@ object Decorators { } } - implicit class genericDeco[T](val x: T) extends AnyVal { - def reporting(op: T => String, printer: config.Printers.Printer = config.Printers.default): T = { - printer.println(op(x)) + implicit object reportDeco { + def (x: T) reporting[T]( + op: given WrappedResult[T] => String, + printer: config.Printers.Printer = config.Printers.default): T = { + printer.println(op given WrappedResult(x)) x } + } + + implicit class genericDeco[T](val x: T) extends AnyVal { def assertingErrorsReported(implicit ctx: Context): T = { assert(ctx.reporter.errorsReported) x diff --git a/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala b/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala index 11b869b8f995..e31821e2b5e0 100644 --- a/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala @@ -123,9 +123,8 @@ final class ProperGadtConstraint private( } // The replaced symbols are picked up here. - addToConstraint(poly1, tvars).reporting({ _ => - i"added to constraint: $params%, %\n$debugBoundsDescription" - }, gadts) + addToConstraint(poly1, tvars) + .reporting(i"added to constraint: $params%, %\n$debugBoundsDescription", gadts) } override def addBound(sym: Symbol, bound: Type, isUpper: Boolean)(implicit ctx: Context): Boolean = { @@ -159,7 +158,7 @@ final class ProperGadtConstraint private( val oldUpperBound = bounds(symTvar.origin) // If we have bounds: // F >: [t] => List[t] <: [t] => Any - // and we want to record that: + // and we want to record that: // F <: [+A] => List[A] // we need to adapt the variance and instead record that: // F <: [A] => List[A] @@ -177,10 +176,10 @@ final class ProperGadtConstraint private( if (isUpper) addUpperBound(symTvar.origin, bound1) else addLowerBound(symTvar.origin, bound1) } - ).reporting({ res => + ).reporting({ val descr = if (isUpper) "upper" else "lower" val op = if (isUpper) "<:" else ">:" - i"adding $descr bound $sym $op $bound = $res" + i"adding $descr bound $sym $op $bound = $result" }, gadts) } @@ -206,7 +205,7 @@ final class ProperGadtConstraint private( case tb => tb } retrieveBounds - //.reporting({ res => i"gadt bounds $sym: $res" }, gadts) + //.reporting(i"gadt bounds $sym: $result", gadts) //.ensuring(containsNoInternalTypes(_)) } } diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala index 740882a1cc63..76d5ac88d38c 100644 --- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -548,7 +548,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, merge(this.boundsMap, that.boundsMap, mergeEntries), merge(this.lowerMap, that.lowerMap, mergeParams), merge(this.upperMap, that.upperMap, mergeParams)) - }.reporting(res => i"constraint merge $this with $other = $res", constr) + }.reporting(i"constraint merge $this with $other = $result", constr) def rename(tl: TypeLambda)(implicit ctx: Context): OrderingConstraint = { assert(contains(tl)) diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala index 496eacbdf546..11e57c3f9233 100644 --- a/compiler/src/dotty/tools/dotc/core/Symbols.scala +++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala @@ -782,7 +782,7 @@ object Symbols { } sourceFromTopLevel(ctx.withPhaseNoLater(ctx.flattenPhase)) } - }//.reporting(res => i"source of $this # $id in ${denot.owner} = $res") + }//.reporting(i"source of $this # $id in ${denot.owner} = $result") mySource } diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 4595720091b2..76b669d9c655 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -628,7 +628,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { if (idx >= 0 && idx < args.length) { def finish(arg: Tree) = new TreeTypeMap().transform(arg) // make sure local bindings in argument have fresh symbols - .reporting(res => i"projecting $tree -> $res", inlining) + .reporting(i"projecting $tree -> $result", inlining) val arg = args(idx) if (precomputed) if (isPureExpr(arg)) finish(arg) diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index f96a0c761503..9eafce747966 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -401,7 +401,7 @@ object ProtoTypes { resType match { case SelectionProto(name: TermName, mbrType, _, _) => ctx.typer.hasExtensionMethod(tp, name, argType, mbrType) - //.reporting(res => i"has ext $tp $name $argType $mbrType: $res") + //.reporting(i"has ext $tp $name $argType $mbrType: $result") case _ => false } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 3621d093c897..24f605eb6310 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2565,7 +2565,7 @@ class Typer extends Namer typed(untpd.Select(untpd.New(untpd.TypedSplice(tpt)), nme.CONSTRUCTOR), pt) } recur(tycon, pt) - .reporting(res => i"try new $tree -> $res", typr) + .reporting(i"try new $tree -> $result", typr) } } { (nu, nuState) => if (nu.isEmpty) fallBack diff --git a/compiler/src/dotty/tools/package.scala b/compiler/src/dotty/tools/package.scala index 2a7506da8d52..828cc36af332 100644 --- a/compiler/src/dotty/tools/package.scala +++ b/compiler/src/dotty/tools/package.scala @@ -23,4 +23,12 @@ package object tools { /** Throws an `UnsupportedOperationException` with the given method name. */ def unsupported(methodName: String): Nothing = throw new UnsupportedOperationException(methodName) + + object WrappedResult { + opaque type Type[T] = T + def unwrap[T](x: Type[T]): T = x + def apply[T](x: T): Type[T] = x + } + type WrappedResult[T] = WrappedResult.Type[T] + def result[T] given (x: WrappedResult[T]): T = WrappedResult.unwrap(x) } From 7fcb5b26fd4b79edff03768a6596c893250af351 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 3 Jul 2019 14:06:42 +0200 Subject: [PATCH 7/9] Make WrappedResult a separate object --- compiler/src/dotty/tools/WrappedResult.scala | 7 +++++++ compiler/src/dotty/tools/package.scala | 13 ++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 compiler/src/dotty/tools/WrappedResult.scala diff --git a/compiler/src/dotty/tools/WrappedResult.scala b/compiler/src/dotty/tools/WrappedResult.scala new file mode 100644 index 000000000000..d1ea062c86ef --- /dev/null +++ b/compiler/src/dotty/tools/WrappedResult.scala @@ -0,0 +1,7 @@ +package dotty.tools + +object WrappedResult { + opaque type WrappedResult[T] = T + def result[T] given (x: WrappedResult[T]): T = x + def apply[T](x: T): WrappedResult[T] = x +} diff --git a/compiler/src/dotty/tools/package.scala b/compiler/src/dotty/tools/package.scala index 828cc36af332..f90beab6abe7 100644 --- a/compiler/src/dotty/tools/package.scala +++ b/compiler/src/dotty/tools/package.scala @@ -24,11 +24,10 @@ package object tools { def unsupported(methodName: String): Nothing = throw new UnsupportedOperationException(methodName) - object WrappedResult { - opaque type Type[T] = T - def unwrap[T](x: Type[T]): T = x - def apply[T](x: T): Type[T] = x - } - type WrappedResult[T] = WrappedResult.Type[T] - def result[T] given (x: WrappedResult[T]): T = WrappedResult.unwrap(x) + export WrappedResult.{WrappedResult, result} + // Equivalent to: + // type WrappedResult[T] = WrappedResult.WrappedResult[T] + // def result[T] given WrappedResult[T] = WrappedResult.result[T] + // The export gave a CyclicReference error in some situations + // Investigate if this happens again. } From 510a56b7eb7abcfd28e9be9c93cc440de1963ac0 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 4 Jul 2019 16:31:01 +0200 Subject: [PATCH 8/9] Move WrappedResult to dotty.util We can't have WrappedResult in tools itself, since that gives a CyclicReference error in some situations. Specifically, if tools.WrappedResult is compiled first, we complete its paackage, which means we complete tools/package.scala which means we enter its members which means we process the WrappedResult export which means we complete WrappedResult which gives a CyclicReference An alternative fix would be to avoid the export and use explicit forwarders instead. --- compiler/src/dotty/tools/dotc/core/Decorators.scala | 1 + compiler/src/dotty/tools/package.scala | 7 +------ compiler/src/dotty/{tools => util}/WrappedResult.scala | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) rename compiler/src/dotty/{tools => util}/WrappedResult.scala (88%) diff --git a/compiler/src/dotty/tools/dotc/core/Decorators.scala b/compiler/src/dotty/tools/dotc/core/Decorators.scala index 0ca6b7f86c98..c203844478c9 100644 --- a/compiler/src/dotty/tools/dotc/core/Decorators.scala +++ b/compiler/src/dotty/tools/dotc/core/Decorators.scala @@ -11,6 +11,7 @@ import dotty.tools.dotc.transform.MegaPhase import ast.tpd._ import scala.language.implicitConversions import printing.Formatting._ +import dotty.util.WrappedResult /** This object provides useful implicit decorators for types defined elsewhere */ object Decorators { diff --git a/compiler/src/dotty/tools/package.scala b/compiler/src/dotty/tools/package.scala index f90beab6abe7..f35495ac3c12 100644 --- a/compiler/src/dotty/tools/package.scala +++ b/compiler/src/dotty/tools/package.scala @@ -24,10 +24,5 @@ package object tools { def unsupported(methodName: String): Nothing = throw new UnsupportedOperationException(methodName) - export WrappedResult.{WrappedResult, result} - // Equivalent to: - // type WrappedResult[T] = WrappedResult.WrappedResult[T] - // def result[T] given WrappedResult[T] = WrappedResult.result[T] - // The export gave a CyclicReference error in some situations - // Investigate if this happens again. + export util.WrappedResult.{WrappedResult, result} } diff --git a/compiler/src/dotty/tools/WrappedResult.scala b/compiler/src/dotty/util/WrappedResult.scala similarity index 88% rename from compiler/src/dotty/tools/WrappedResult.scala rename to compiler/src/dotty/util/WrappedResult.scala index d1ea062c86ef..d94e9eabcf07 100644 --- a/compiler/src/dotty/tools/WrappedResult.scala +++ b/compiler/src/dotty/util/WrappedResult.scala @@ -1,4 +1,4 @@ -package dotty.tools +package dotty.util object WrappedResult { opaque type WrappedResult[T] = T From a778f3501b8db28f3f962db1d7e8c0e5f4bd03e4 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 4 Jul 2019 16:43:59 +0200 Subject: [PATCH 9/9] Alternative WrappedResult implementation without exports This allows us to put WrappedResult directly in the tools package object. --- compiler/src/dotty/tools/dotc/core/Decorators.scala | 1 - compiler/src/dotty/tools/package.scala | 9 ++++++++- compiler/src/dotty/util/WrappedResult.scala | 7 ------- 3 files changed, 8 insertions(+), 9 deletions(-) delete mode 100644 compiler/src/dotty/util/WrappedResult.scala diff --git a/compiler/src/dotty/tools/dotc/core/Decorators.scala b/compiler/src/dotty/tools/dotc/core/Decorators.scala index c203844478c9..0ca6b7f86c98 100644 --- a/compiler/src/dotty/tools/dotc/core/Decorators.scala +++ b/compiler/src/dotty/tools/dotc/core/Decorators.scala @@ -11,7 +11,6 @@ import dotty.tools.dotc.transform.MegaPhase import ast.tpd._ import scala.language.implicitConversions import printing.Formatting._ -import dotty.util.WrappedResult /** This object provides useful implicit decorators for types defined elsewhere */ object Decorators { diff --git a/compiler/src/dotty/tools/package.scala b/compiler/src/dotty/tools/package.scala index f35495ac3c12..416504d40aa4 100644 --- a/compiler/src/dotty/tools/package.scala +++ b/compiler/src/dotty/tools/package.scala @@ -24,5 +24,12 @@ package object tools { def unsupported(methodName: String): Nothing = throw new UnsupportedOperationException(methodName) - export util.WrappedResult.{WrappedResult, result} + object resultWrapper { + opaque type WrappedResult[T] = T + private[tools] def unwrap[T](x: WrappedResult[T]): T = x + private[tools] def wrap[T](x: T): WrappedResult[T] = x + } + type WrappedResult[T] = resultWrapper.WrappedResult[T] + def WrappedResult[T](x: T) = resultWrapper.wrap(x) + def result[T] given (x: WrappedResult[T]): T = resultWrapper.unwrap(x) } diff --git a/compiler/src/dotty/util/WrappedResult.scala b/compiler/src/dotty/util/WrappedResult.scala deleted file mode 100644 index d94e9eabcf07..000000000000 --- a/compiler/src/dotty/util/WrappedResult.scala +++ /dev/null @@ -1,7 +0,0 @@ -package dotty.util - -object WrappedResult { - opaque type WrappedResult[T] = T - def result[T] given (x: WrappedResult[T]): T = x - def apply[T](x: T): WrappedResult[T] = x -}