Skip to content

Commit 2d4c129

Browse files
committed
Merge branch 'master' into 'topic/sbt1'
2 parents 7a99074 + 14187e2 commit 2d4c129

File tree

84 files changed

+1256
-439
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1256
-439
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class Compiler {
6767
new NormalizeFlags, // Rewrite some definition flags
6868
new ExtensionMethods, // Expand methods of value classes with extension methods
6969
new ExpandSAMs, // Expand single abstract method closures to anonymous classes
70+
new ShortcutImplicits, // Allow implicit functions without creating closures
7071
new TailRec, // Rewrite tail recursion to loops
7172
new ByNameClosures, // Expand arguments to by-name parameters to closures
7273
new LiftTry, // Put try expressions that might execute on non-empty stacks into their own methods
@@ -77,7 +78,6 @@ class Compiler {
7778
new PatternMatcher, // Compile pattern matches
7879
new ExplicitOuter, // Add accessors to outer classes from nested ones.
7980
new ExplicitSelf, // Make references to non-trivial self types explicit as casts
80-
new ShortcutImplicits, // Allow implicit functions without creating closures
8181
new CrossCastAnd, // Normalize selections involving intersection types.
8282
new Splitter) :: // Expand selections involving union types into conditionals
8383
List(new ErasedDecls, // Removes all erased defs and vals decls (except for parameters)

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ object desugar {
5050
*/
5151
class DerivedFromParamTree(suffix: String) extends DerivedTypeTree {
5252

53-
/** Make sure that for all enclosing module classes their companion lasses
53+
/** Make sure that for all enclosing module classes their companion classes
5454
* are completed. Reason: We need the constructor of such companion classes to
5555
* be completed so that OriginalSymbol attachments are pushed to DerivedTypeTrees
5656
* in apply/unapply methods.

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
6060
class NonEmptyFunction(args: List[Tree], body: Tree, val mods: Modifiers) extends Function(args, body)
6161

6262
/** A function created from a wildcard expression
63-
* @param placeHolderParams a list of definitions of synthetic parameters
63+
* @param placeholderParams a list of definitions of synthetic parameters.
6464
* @param body the function body where wildcards are replaced by
6565
* references to synthetic parameters.
6666
*/

compiler/src/dotty/tools/dotc/core/CheckRealizable.scala

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ object CheckRealizable {
3030
class NotFinal(sym: Symbol)(implicit ctx: Context)
3131
extends Realizability(i" refers to nonfinal $sym")
3232

33-
class HasProblemBounds(typ: SingleDenotation)(implicit ctx: Context)
34-
extends Realizability(i" has a member $typ with possibly conflicting bounds ${typ.info.bounds.lo} <: ... <: ${typ.info.bounds.hi}")
33+
class HasProblemBounds(name: Name, info: Type)(implicit ctx: Context)
34+
extends Realizability(i" has a member $name with possibly conflicting bounds ${info.bounds.lo} <: ... <: ${info.bounds.hi}")
3535

3636
class HasProblemBaseArg(typ: Type, argBounds: TypeBounds)(implicit ctx: Context)
3737
extends Realizability(i" has a base type $typ with possibly conflicting parameter bounds ${argBounds.lo} <: ... <: ${argBounds.hi}")
@@ -96,6 +96,14 @@ class CheckRealizable(implicit ctx: Context) {
9696
else boundsRealizability(tp).andAlso(memberRealizability(tp))
9797
}
9898

99+
private def refinedNames(tp: Type): Set[Name] = tp.dealias match {
100+
case tp: RefinedType => refinedNames(tp.parent) + tp.refinedName
101+
case tp: AndType => refinedNames(tp.tp1) ++ refinedNames(tp.tp2)
102+
case tp: OrType => refinedNames(tp.tp1) ++ refinedNames(tp.tp2)
103+
case tp: TypeProxy => refinedNames(tp.underlying)
104+
case _ => Set.empty
105+
}
106+
99107
/** `Realizable` if `tp` has good bounds, a `HasProblem...` instance
100108
* pointing to a bad bounds member otherwise. "Has good bounds" means:
101109
*
@@ -107,12 +115,22 @@ class CheckRealizable(implicit ctx: Context) {
107115
* also lead to base types with bad bounds).
108116
*/
109117
private def boundsRealizability(tp: Type) = {
110-
val mbrProblems =
118+
119+
val memberProblems =
111120
for {
112121
mbr <- tp.nonClassTypeMembers
113122
if !(mbr.info.loBound <:< mbr.info.hiBound)
114123
}
115-
yield new HasProblemBounds(mbr)
124+
yield new HasProblemBounds(mbr.name, mbr.info)
125+
126+
val refinementProblems =
127+
for {
128+
name <- refinedNames(tp)
129+
if (name.isTypeName)
130+
mbr <- tp.member(name).alternatives
131+
if !(mbr.info.loBound <:< mbr.info.hiBound)
132+
}
133+
yield new HasProblemBounds(name, mbr.info)
116134

117135
def baseTypeProblems(base: Type) = base match {
118136
case AndType(base1, base2) =>
@@ -126,12 +144,13 @@ class CheckRealizable(implicit ctx: Context) {
126144
val baseProblems =
127145
tp.baseClasses.map(_.baseTypeOf(tp)).flatMap(baseTypeProblems)
128146

129-
(((Realizable: Realizability)
130-
/: mbrProblems)(_ andAlso _)
147+
((((Realizable: Realizability)
148+
/: memberProblems)(_ andAlso _)
149+
/: refinementProblems)(_ andAlso _)
131150
/: baseProblems)(_ andAlso _)
132151
}
133152

134-
/** `Realizable` if all of `tp`'s non-struct fields have realizable types,
153+
/** `Realizable` if all of `tp`'s non-strict fields have realizable types,
135154
* a `HasProblemField` instance pointing to a bad field otherwise.
136155
*/
137156
private def memberRealizability(tp: Type) = {

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,12 +1020,6 @@ object Denotations {
10201020
interval
10211021
}
10221022

1023-
/** For ClassDenotations only:
1024-
* If caches influenced by parent classes are still valid, the denotation
1025-
* itself, otherwise a freshly initialized copy.
1026-
*/
1027-
def syncWithParents(implicit ctx: Context): SingleDenotation = this
1028-
10291023
/** Show declaration string; useful for showing declarations
10301024
* as seen from subclasses.
10311025
*/

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,8 @@ object Types {
16481648
}
16491649

16501650
final def symbol(implicit ctx: Context): Symbol =
1651+
// We can rely on checkedPeriod (unlike in the definition of `denot` below)
1652+
// because SymDenotation#installAfter never changes the symbol
16511653
if (checkedPeriod == ctx.period) lastSymbol else computeSymbol
16521654

16531655
private def computeSymbol(implicit ctx: Context): Symbol =
@@ -1692,17 +1694,11 @@ object Types {
16921694
/** The denotation currently denoted by this type */
16931695
final def denot(implicit ctx: Context): Denotation = {
16941696
val now = ctx.period
1695-
val lastd = lastDenotation
1696-
if (checkedPeriod == now) lastd else denotAt(lastd, now)
1697-
}
1698-
1699-
/** A first fall back to do a somewhat more expensive calculation in case the first
1700-
* attempt in `denot` does not yield a denotation.
1701-
*/
1702-
private def denotAt(lastd: Denotation, now: Period)(implicit ctx: Context): Denotation = {
1703-
if (checkedPeriod != Nowhere && lastd.validFor.contains(now)) {
1697+
// Even if checkedPeriod == now we still need to recheck lastDenotation.validFor
1698+
// as it may have been mutated by SymDenotation#installAfter
1699+
if (checkedPeriod != Nowhere && lastDenotation.validFor.contains(now)) {
17041700
checkedPeriod = now
1705-
lastd
1701+
lastDenotation
17061702
}
17071703
else computeDenot
17081704
}
@@ -3485,10 +3481,9 @@ object Types {
34853481
}
34863482

34873483
def appliedRef(implicit ctx: Context): Type = {
3488-
def clsDenot = if (prefix eq cls.owner.thisType) cls.denot else cls.denot.copySymDenotation(info = this)
34893484
if (appliedRefCache == null)
34903485
appliedRefCache =
3491-
TypeRef(prefix, cls.name, clsDenot).appliedTo(cls.typeParams.map(_.typeRef))
3486+
TypeRef(prefix, cls).appliedTo(cls.typeParams.map(_.typeRef))
34923487
appliedRefCache
34933488
}
34943489

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import dotty.tools.dotc.core.Flags._
1010
import dotty.tools.dotc.core.StdNames._
1111
import dotty.tools.dotc.core.NameKinds
1212
import dotty.tools.dotc.core.Symbols._
13+
import dotty.tools.dotc.core.Types.Type
14+
import dotty.tools.dotc.core.tasty.TreePickler.Hole
1315
import dotty.tools.dotc.core.tasty.{TastyPickler, TastyPrinter, TastyString}
1416

1517
import scala.quoted.Types._
@@ -24,16 +26,21 @@ object PickledQuotes {
2426
def pickleQuote(tree: Tree)(implicit ctx: Context): scala.runtime.quoted.Unpickler.Pickled = {
2527
if (ctx.reporter.hasErrors) Nil
2628
else {
29+
assert(!tree.isInstanceOf[Hole]) // Should not be pickled as it represents `'(~x)` which should be optimized to `x`
2730
val encapsulated = encapsulateQuote(tree)
2831
val pickled = pickle(encapsulated)
2932
TastyString.pickle(pickled)
3033
}
3134
}
3235

3336
/** Transform the expression into its fully spliced Tree */
34-
def quotedExprToTree(expr: quoted.Expr[_])(implicit ctx: Context): Tree = expr match {
37+
def quotedExprToTree[T](expr: quoted.Expr[T])(implicit ctx: Context): Tree = expr match {
3538
case expr: TastyExpr[_] => unpickleExpr(expr)
36-
case expr: LiftedExpr[_] => Literal(Constant(expr.value))
39+
case expr: LiftedExpr[T] =>
40+
expr.value match {
41+
case value: Class[_] => ref(defn.Predef_classOf).appliedToType(classToType(value))
42+
case value=> Literal(Constant(value))
43+
}
3744
case expr: TreeExpr[Tree] @unchecked => expr.tree
3845
case expr: FunctionAppliedTo[_, _] =>
3946
functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x))
@@ -154,4 +161,27 @@ object PickledQuotes {
154161
}
155162
Block(x1 :: Nil, rec(f))
156163
}
164+
165+
private def classToType(clazz: Class[_])(implicit ctx: Context): Type = {
166+
if (clazz.isPrimitive) {
167+
if (clazz == classOf[Boolean]) defn.BooleanType
168+
else if (clazz == classOf[Byte]) defn.ByteType
169+
else if (clazz == classOf[Char]) defn.CharType
170+
else if (clazz == classOf[Short]) defn.ShortType
171+
else if (clazz == classOf[Int]) defn.IntType
172+
else if (clazz == classOf[Long]) defn.LongType
173+
else if (clazz == classOf[Float]) defn.FloatType
174+
else if (clazz == classOf[Double]) defn.DoubleType
175+
else defn.UnitType
176+
} else if (clazz.isArray) {
177+
defn.ArrayType.appliedTo(classToType(clazz.getComponentType))
178+
} else if (clazz.isMemberClass) {
179+
val name = clazz.getSimpleName.toTypeName
180+
val enclosing = classToType(clazz.getEnclosingClass)
181+
if (enclosing.member(name).exists) enclosing.select(name)
182+
else {
183+
enclosing.classSymbol.companionModule.termRef.select(name)
184+
}
185+
} else ctx.getClassIfDefined(clazz.getCanonicalName).typeRef
186+
}
157187
}

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ Standard-Section: "ASTs" TopLevelStat*
198198
SCALA2X // Imported from Scala2.x
199199
DEFAULTparameterized // Method with default parameters
200200
STABLE // Method that is assumed to be stable
201+
PARAMsetter // A setter without a body named `x_=` where `x` is pickled as a PARAM
201202
Annotation
202203
203204
Annotation = ANNOTATION Length tycon_Type fullAnnotation_Term
@@ -226,8 +227,8 @@ Standard Section: "Positions" Assoc*
226227
object TastyFormat {
227228

228229
final val header = Array(0x5C, 0xA1, 0xAB, 0x1F)
229-
val MajorVersion = 5
230-
val MinorVersion = 1
230+
val MajorVersion = 6
231+
val MinorVersion = 0
231232

232233
/** Tags used to serialize names */
233234
class NameTags {
@@ -268,6 +269,7 @@ object TastyFormat {
268269
// AST tags
269270
// Cat. 1: tag
270271

272+
final val firstSimpleTreeTag = UNITconst
271273
final val UNITconst = 2
272274
final val FALSEconst = 3
273275
final val TRUEconst = 4
@@ -300,6 +302,7 @@ object TastyFormat {
300302
final val STABLE = 31
301303
final val MACRO = 32
302304
final val ERASED = 33
305+
final val PARAMsetter = 34
303306

304307
// Cat. 2: tag Nat
305308

@@ -417,15 +420,14 @@ object TastyFormat {
417420

418421
final val HOLE = 255
419422

420-
final val firstSimpleTreeTag = UNITconst
421423
final val firstNatTreeTag = SHAREDterm
422424
final val firstASTTreeTag = THIS
423425
final val firstNatASTTreeTag = IDENT
424426
final val firstLengthTreeTag = PACKAGE
425427

426428
/** Useful for debugging */
427429
def isLegalTag(tag: Int) =
428-
firstSimpleTreeTag <= tag && tag <= ERASED ||
430+
firstSimpleTreeTag <= tag && tag <= PARAMsetter ||
429431
firstNatTreeTag <= tag && tag <= SYMBOLconst ||
430432
firstASTTreeTag <= tag && tag <= SINGLETONtpt ||
431433
firstNatASTTreeTag <= tag && tag <= NAMEDARG ||
@@ -463,6 +465,7 @@ object TastyFormat {
463465
| SCALA2X
464466
| DEFAULTparameterized
465467
| STABLE
468+
| PARAMsetter
466469
| ANNOTATION
467470
| PRIVATEqualified
468471
| PROTECTEDqualified => true
@@ -518,6 +521,7 @@ object TastyFormat {
518521
case SCALA2X => "SCALA2X"
519522
case DEFAULTparameterized => "DEFAULTparameterized"
520523
case STABLE => "STABLE"
524+
case PARAMsetter => "PARAMsetter"
521525

522526
case SHAREDterm => "SHAREDterm"
523527
case SHAREDtype => "SHAREDtype"

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,7 @@ class TreePickler(pickler: TastyPickler) {
601601
if (flags is CaseAccessor) writeByte(CASEaccessor)
602602
if (flags is DefaultParameterized) writeByte(DEFAULTparameterized)
603603
if (flags is Stable) writeByte(STABLE)
604+
if ((flags is ParamAccessor) && sym.isSetter) writeByte(PARAMsetter)
604605
} else {
605606
if (flags is Sealed) writeByte(SEALED)
606607
if (flags is Abstract) writeByte(ABSTRACT)

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -251,17 +251,17 @@ class TreeUnpickler(reader: TastyReader,
251251
val space = readType()
252252
sname match {
253253
case SignedName(name, sig) =>
254-
TermRef(prefix, name, space.decl(name).atSignature(sig))
254+
TermRef(prefix, name, space.decl(name).asSeenFrom(prefix).atSignature(sig))
255255
case name =>
256-
TermRef(prefix, name, space.decl(name))
256+
TermRef(prefix, name, space.decl(name).asSeenFrom(prefix))
257257
}
258258
case TYPEREFin =>
259259
val name = readName().toTypeName
260260
val prefix = readType()
261261
val space = readType()
262262
space.decl(name) match {
263263
case symd: SymDenotation if prefix.isArgPrefixOf(symd.symbol) => TypeRef(prefix, symd.symbol)
264-
case _ => TypeRef(prefix, name, space.decl(name))
264+
case _ => TypeRef(prefix, name, space.decl(name).asSeenFrom(prefix))
265265
}
266266
case REFINEDtype =>
267267
var name: Name = readName()
@@ -424,7 +424,11 @@ class TreeUnpickler(reader: TastyReader,
424424
flags = flags | (if (tag == VALDEF) ModuleValCreationFlags else ModuleClassCreationFlags)
425425
if (ctx.owner.isClass) {
426426
if (tag == TYPEPARAM) flags |= Param
427-
else if (tag == PARAM) flags |= ParamAccessor
427+
else if (tag == PARAM) {
428+
flags |= ParamAccessor
429+
if (!rhsIsEmpty) // param alias
430+
flags |= Method
431+
}
428432
}
429433
else if (isParamTag(tag)) flags |= Param
430434
flags
@@ -585,6 +589,8 @@ class TreeUnpickler(reader: TastyReader,
585589
case SCALA2X => addFlag(Scala2x)
586590
case DEFAULTparameterized => addFlag(DefaultParameterized)
587591
case STABLE => addFlag(Stable)
592+
case PARAMsetter =>
593+
addFlag(ParamAccessor)
588594
case PRIVATEqualified =>
589595
readByte()
590596
privateWithin = readType().typeSymbol
@@ -728,11 +734,6 @@ class TreeUnpickler(reader: TastyReader,
728734
vparamss.nestedMap(_.symbol), name == nme.CONSTRUCTOR)
729735
val resType = ctx.effectiveResultType(sym, typeParams, tpt.tpe)
730736
sym.info = ctx.methodType(typeParams, valueParamss, resType)
731-
if (sym.isSetter && sym.accessedFieldOrGetter.is(ParamAccessor)) {
732-
// reconstitute ParamAccessor flag of setters for var parameters, which is not pickled
733-
sym.setFlag(ParamAccessor)
734-
sym.resetFlag(Deferred)
735-
}
736737
DefDef(tparams, vparamss, tpt)
737738
case VALDEF =>
738739
val tpt = readTpt()(localCtx)
@@ -775,7 +776,6 @@ class TreeUnpickler(reader: TastyReader,
775776
ValDef(tpt)
776777
}
777778
else {
778-
sym.setFlag(Method)
779779
sym.info = ExprType(tpt.tpe)
780780
pickling.println(i"reading param alias $name -> $currentAddr")
781781
DefDef(Nil, Nil, tpt)
@@ -1142,10 +1142,14 @@ class TreeUnpickler(reader: TastyReader,
11421142
val splice = splices(idx)
11431143
val reifiedArgs = args.map(arg => if (arg.isTerm) new TreeExpr(arg) else new TreeType(arg))
11441144
if (isType) {
1145-
val quotedType = splice.asInstanceOf[Seq[Any] => quoted.Type[_]](reifiedArgs)
1145+
val quotedType =
1146+
if (reifiedArgs.isEmpty) splice.asInstanceOf[quoted.Type[_]]
1147+
else splice.asInstanceOf[Seq[Any] => quoted.Type[_]](reifiedArgs)
11461148
PickledQuotes.quotedTypeToTree(quotedType)
11471149
} else {
1148-
val quotedExpr = splice.asInstanceOf[Seq[Any] => quoted.Expr[_]](reifiedArgs)
1150+
val quotedExpr =
1151+
if (reifiedArgs.isEmpty) splice.asInstanceOf[quoted.Expr[_]]
1152+
else splice.asInstanceOf[Seq[Any] => quoted.Expr[_]](reifiedArgs)
11491153
PickledQuotes.quotedExprToTree(quotedExpr)
11501154
}
11511155
}

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -567,12 +567,6 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
567567
// we need the checkNonCyclic call to insert LazyRefs for F-bounded cycles
568568
else if (!denot.is(Param)) tp1.underlyingIfRepeated(isJava = false)
569569
else tp1
570-
571-
if (!denot.isType) { // Only terms might have leaky aliases, see the documentation of `checkNoPrivateLeaks`
572-
val sym = denot.symbol
573-
denot.info = ctx.typeAssigner.avoidPrivateLeaks(sym, sym.pos)
574-
}
575-
576570
if (denot.isConstructor) addConstructorTypeParams(denot)
577571
if (atEnd) {
578572
assert(!denot.isSuperAccessor, denot)

0 commit comments

Comments
 (0)