diff --git a/compiler/src/dotty/tools/dotc/Bench.scala b/compiler/src/dotty/tools/dotc/Bench.scala index ee7789c32f9f..a5fe890b8119 100644 --- a/compiler/src/dotty/tools/dotc/Bench.scala +++ b/compiler/src/dotty/tools/dotc/Bench.scala @@ -1,7 +1,3 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Martin Odersky - */ package dotty.tools package dotc @@ -24,6 +20,11 @@ object Bench extends Driver { val start = System.nanoTime() val r = super.doCompile(compiler, fileNames) println(s"time elapsed: ${(System.nanoTime - start) / 1000000}ms") + if (ctx.settings.prompt.value) { + print("hit to continue >") + System.in.read() + println() + } r } diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index e81628c21639..247c028ae221 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -476,6 +476,7 @@ object Contexts { def setRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this } def setDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this } def setGadt(gadt: GADTMap): this.type = { this.gadt = gadt; this } + def setFreshGADTBounds: this.type = setGadt(new GADTMap(gadt.bounds)) def setTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this } def setSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this } def setFreshNames(freshNames: FreshNameCreator): this.type = { this.freshNames = freshNames; this } @@ -493,7 +494,6 @@ object Contexts { def setSetting[T](setting: Setting[T], value: T): this.type = setSettings(setting.updateIn(sstate, value)) - def setFreshGADTBounds: this.type = { this.gadt = new GADTMap(gadt.bounds); this } def setDebug = setSetting(base.settings.debug, true) } @@ -532,7 +532,7 @@ object Contexts { moreProperties = Map.empty typeComparer = new TypeComparer(this) searchHistory = new SearchHistory(0, Map()) - gadt = new GADTMap(SimpleMap.Empty) + gadt = EmptyGADTMap } @sharable object NoContext extends Context { @@ -694,10 +694,14 @@ object Contexts { implicit val ctx: Context = initctx } - class GADTMap(initBounds: SimpleMap[Symbol, TypeBounds]) { + class GADTMap(initBounds: SimpleMap[Symbol, TypeBounds]) extends util.DotClass { private var myBounds = initBounds def setBounds(sym: Symbol, b: TypeBounds): Unit = myBounds = myBounds.updated(sym, b) def bounds = myBounds } + + @sharable object EmptyGADTMap extends GADTMap(SimpleMap.Empty) { + override def setBounds(sym: Symbol, b: TypeBounds) = unsupported("EmptyGADTMap.setBounds") + } } diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index 530c11a3b7e7..0625242adbc0 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -54,17 +54,9 @@ import reporting.diagnostic.messages.SuperCallsNotAllowedInline * mini-phase or subfunction of a macro phase equally well. But taken by themselves * they do not warrant their own group of miniphases before pickling. */ -class PostTyper extends MacroTransform with SymTransformer { thisTransformer => - - +class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTransformer => import tpd._ - def transformSym(ref: SymDenotation)(implicit ctx: Context): SymDenotation = { - if (ref.is(BindDefinedType) && ctx.gadt.bounds.contains(ref.symbol)) { - ref.copySymDenotation(info = ctx.gadt.bounds.apply(ref.symbol) & ref.info) - } else ref - } - /** the following two members override abstract members in Transform */ override def phaseName: String = "posttyper" @@ -264,7 +256,7 @@ class PostTyper extends MacroTransform with SymTransformer { thisTransformer => case tree @ Annotated(annotated, annot) => cpy.Annotated(tree)(transform(annotated), transformAnnot(annot)) case tree: AppliedTypeTree => - Checking.checkAppliedType(tree) + Checking.checkAppliedType(tree, boundsCheck = !ctx.mode.is(Mode.Pattern)) super.transform(tree) case SingletonTypeTree(ref) => Checking.checkRealizable(ref.tpe, ref.pos.focus) @@ -289,6 +281,15 @@ class PostTyper extends MacroTransform with SymTransformer { thisTransformer => case _ => } super.transform(tree) + case Typed(Ident(nme.WILDCARD), _) => + super.transform(tree)(ctx.addMode(Mode.Pattern)) + // The added mode signals that bounds in a pattern need not + // conform to selector bounds. I.e. assume + // type Tree[T >: Null <: Type] + // One is still allowed to write + // case x: Tree[_] + // (which translates to) + // case x: (_: Tree[_]) case tree => super.transform(tree) } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 3c60db0e0ec1..27b685a19299 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -68,7 +68,7 @@ object Checking { * Unreducible applications correspond to general existentials, and we * cannot handle those. */ - def checkAppliedType(tree: AppliedTypeTree)(implicit ctx: Context) = { + def checkAppliedType(tree: AppliedTypeTree, boundsCheck: Boolean)(implicit ctx: Context) = { val AppliedTypeTree(tycon, args) = tree // If `args` is a list of named arguments, return corresponding type parameters, // otherwise return type parameters unchanged @@ -81,7 +81,7 @@ object Checking { val bounds = tparams.map(_.paramInfoAsSeenFrom(tycon.tpe).bounds) def instantiate(bound: Type, args: List[Type]) = HKTypeLambda.fromParams(tparams, bound).appliedTo(args) - checkBounds(orderedArgs, bounds, instantiate) + if (boundsCheck) checkBounds(orderedArgs, bounds, instantiate) def checkWildcardApply(tp: Type, pos: Position): Unit = tp match { case tp @ AppliedType(tycon, args) if args.exists(_.isInstanceOf[TypeBounds]) => diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index a937aa418d3d..9cececffd041 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -491,7 +491,10 @@ trait ImplicitRunInfo { self: RunInfo => override def default(key: TermRef) = 0 } - def clear() = implicitScopeCache.clear() + def clear() = { + implicitScopeCache.clear() + useCount.clear() + } } /** The implicit resolution part of type checking */ diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 9d7fe3e4486e..e93aea790f7a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -921,16 +921,21 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def typedCase(tree: untpd.CaseDef, pt: Type, selType: Type, gadtSyms: Set[Symbol])(implicit ctx: Context): CaseDef = track("typedCase") { val originalCtx = ctx + val gadtCtx = ctx.fresh.setFreshGADTBounds + for (sym <- gadtSyms) + if (!gadtCtx.gadt.bounds.contains(sym)) + gadtCtx.gadt.setBounds(sym, TypeBounds.empty) + /** - replace all references to symbols associated with wildcards by their GADT bounds * - enter all symbols introduced by a Bind in current scope */ val indexPattern = new TreeMap { val elimWildcardSym = new TypeMap { def apply(t: Type) = t match { - case ref: TypeRef if ref.name == tpnme.WILDCARD && ctx.gadt.bounds.contains(ref.symbol) => - ctx.gadt.bounds(ref.symbol) - case TypeAlias(ref: TypeRef) if ref.name == tpnme.WILDCARD && ctx.gadt.bounds.contains(ref.symbol) => - ctx.gadt.bounds(ref.symbol) + case ref: TypeRef if ref.name == tpnme.WILDCARD && gadtCtx.gadt.bounds.contains(ref.symbol) => + gadtCtx.gadt.bounds(ref.symbol) + case TypeAlias(ref: TypeRef) if ref.name == tpnme.WILDCARD && gadtCtx.gadt.bounds.contains(ref.symbol) => + gadtCtx.gadt.bounds(ref.symbol) case _ => mapOver(t) } @@ -955,15 +960,6 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit assignType(cpy.CaseDef(tree)(pat1, guard1, body1), body1) } - val gadtCtx = - if (gadtSyms.isEmpty) ctx - else { - val c = ctx.fresh.setFreshGADTBounds - for (sym <- gadtSyms) - if (!c.gadt.bounds.contains(sym)) - c.gadt.setBounds(sym, TypeBounds.empty) - c - } val pat1 = typedPattern(tree.pat, selType)(gadtCtx) caseRest(pat1)(gadtCtx.fresh.setNewScope) }