Skip to content

Commit 86615f6

Browse files
author
Arnaud ESTEVE
committed
Merge remote-tracking branch 'upstream/master' into doc/rework-typeclasses-new
# Conflicts: # docs/docs/reference/contextual/typeclasses-new.md
2 parents cd501b6 + c228b36 commit 86615f6

File tree

751 files changed

+8366
-8859
lines changed

Some content is hidden

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

751 files changed

+8366
-8859
lines changed

.drone.yml

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,25 +78,6 @@ steps:
7878
- tag
7979
- promote
8080

81-
- name: documentation
82-
pull: default
83-
image: lampepfl/dotty:2020-01-22-2
84-
depends_on:
85-
- test
86-
- test_bootstrapped
87-
- community_build
88-
- test_java11
89-
commands:
90-
- ./project/scripts/genDocs
91-
environment:
92-
BOT_TOKEN:
93-
from_secret: bot_token
94-
when:
95-
branch:
96-
- master
97-
event:
98-
- push
99-
10081
- name: publish_nightly
10182
pull: default
10283
image: lampepfl/dotty:2020-01-22-2

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ object desugar {
252252

253253
if (meth1.mods.is(Inline))
254254
meth1.tpt match {
255-
case TypeBoundsTree(_, tpt1) =>
255+
case TypeBoundsTree(_, tpt1, _) =>
256256
meth1 = cpy.DefDef(meth1)(tpt = tpt1)
257257
case tpt if !tpt.isEmpty && !meth1.rhs.isEmpty =>
258258
meth1 = cpy.DefDef(meth1)(rhs = Typed(meth1.rhs, tpt))
@@ -488,7 +488,7 @@ object desugar {
488488
if (isEnum) {
489489
val (enumCases, enumStats) = stats.partition(DesugarEnums.isEnumCase)
490490
if (enumCases.isEmpty)
491-
ctx.error("Enumerations must contain at least one case", namePos)
491+
ctx.error(EnumerationsShouldNotBeEmpty(cdef), namePos)
492492
val enumCompanionRef = TermRefTree()
493493
val enumImport =
494494
Import(enumCompanionRef, enumCases.flatMap(caseIds).map(ImportSelector(_)))
@@ -684,7 +684,7 @@ object desugar {
684684
val mods = constr1.mods
685685
mods.is(Private) || (!mods.is(Protected) && mods.hasPrivateWithin)
686686
}
687-
687+
688688
/** Does one of the parameter's types (in the first param clause)
689689
* mention a preceding parameter?
690690
*/
@@ -883,12 +883,12 @@ object desugar {
883883
def flagSourcePos(flag: FlagSet) = mods.mods.find(_.flags == flag).fold(mdef.sourcePos)(_.sourcePos)
884884

885885
if (mods.is(Abstract))
886-
ctx.error(em"${hl("abstract")} modifier cannot be used for objects", flagSourcePos(Abstract))
886+
ctx.error(AbstractCannotBeUsedForObjects(mdef), flagSourcePos(Abstract))
887887
if (mods.is(Sealed))
888-
ctx.error(em"${hl("sealed")} modifier is redundant for objects", flagSourcePos(Sealed))
888+
ctx.error(ModifierRedundantForObjects(mdef, "sealed"), flagSourcePos(Sealed))
889889
// Maybe this should be an error; see https://github.com/scala/bug/issues/11094.
890890
if (mods.is(Final) && !mods.is(Synthetic))
891-
ctx.warning(em"${hl("final")} modifier is redundant for objects", flagSourcePos(Final))
891+
ctx.warning(ModifierRedundantForObjects(mdef, "final"), flagSourcePos(Final))
892892

893893
if (mods.is(Package))
894894
packageModuleDef(mdef)
@@ -1156,7 +1156,8 @@ object desugar {
11561156
val legalOpaque: MemberDefTest = {
11571157
case TypeDef(_, rhs) =>
11581158
def rhsOK(tree: Tree): Boolean = tree match {
1159-
case _: TypeBoundsTree | _: Template => false
1159+
case bounds: TypeBoundsTree => !bounds.alias.isEmpty
1160+
case _: Template => false
11601161
case LambdaTypeTree(_, body) => rhsOK(body)
11611162
case _ => true
11621163
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ object DesugarEnums {
4949
val tparams = enumClass.typeParams
5050
def isGround(tp: Type) = tp.subst(tparams, tparams.map(_ => NoType)) eq tp
5151
val targs = tparams map { tparam =>
52-
if (tparam.variance > 0 && isGround(tparam.info.bounds.lo))
52+
if (tparam.is(Covariant) && isGround(tparam.info.bounds.lo))
5353
tparam.info.bounds.lo
54-
else if (tparam.variance < 0 && isGround(tparam.info.bounds.hi))
54+
else if (tparam.is(Contravariant) && isGround(tparam.info.bounds.hi))
5555
tparam.info.bounds.hi
5656
else {
5757
def problem =
58-
if (tparam.variance == 0) "is non variant"
58+
if (!tparam.isOneOf(VarianceFlags)) "is non variant"
5959
else "has bounds that depend on a type parameter in the same parameter list"
6060
errorType(i"""cannot determine type argument for enum parent $enumClass,
6161
|type parameter $tparam $problem""", ctx.source.atSpan(span))

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
298298
def isFunctionWithUnknownParamType(tree: Tree): Boolean =
299299
functionWithUnknownParamType(tree).isDefined
300300

301-
/** Is `tree` an implicit function or closure, possibly nested in a block? */
301+
/** Is `tree` an context function or closure, possibly nested in a block? */
302302
def isContextualClosure(tree: Tree)(implicit ctx: Context): Boolean = unsplice(tree) match {
303303
case tree: FunctionWithMods => tree.mods.is(Given)
304304
case Function((param: untpd.ValDef) :: _, _) => param.mods.is(Given)
@@ -307,7 +307,7 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
307307
case Block(DefDef(nme.ANON_FUN, _, params :: _, _, _) :: Nil, cl: Closure) =>
308308
params match {
309309
case param :: _ => param.mods.is(Given)
310-
case Nil => cl.tpt.eq(untpd.ContextualEmptyTree) || defn.isImplicitFunctionType(cl.tpt.typeOpt)
310+
case Nil => cl.tpt.eq(untpd.ContextualEmptyTree) || defn.isContextFunctionType(cl.tpt.typeOpt)
311311
}
312312
case _ => false
313313
}

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

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ object Trees {
440440
type ThisTree[-T >: Untyped] = Apply[T]
441441

442442
def isGivenApply = hasAttachment(untpd.ApplyGiven)
443-
def setGivenApply() = { pushAttachment(untpd.ApplyGiven, ()); this }
443+
def setGivenApply() = { putAttachment(untpd.ApplyGiven, ()); this }
444444
}
445445

446446
/** fun[args] */
@@ -690,8 +690,10 @@ object Trees {
690690
type ThisTree[-T >: Untyped] = ByNameTypeTree[T]
691691
}
692692

693-
/** >: lo <: hi */
694-
case class TypeBoundsTree[-T >: Untyped] private[ast] (lo: Tree[T], hi: Tree[T])(implicit @constructorOnly src: SourceFile)
693+
/** >: lo <: hi
694+
* >: lo <: hi = alias for RHS of bounded opaque type
695+
*/
696+
case class TypeBoundsTree[-T >: Untyped] private[ast] (lo: Tree[T], hi: Tree[T], alias: Tree[T])(implicit @constructorOnly src: SourceFile)
695697
extends TypTree[T] {
696698
type ThisTree[-T >: Untyped] = TypeBoundsTree[T]
697699
}
@@ -760,7 +762,8 @@ object Trees {
760762
/** mods class name template or
761763
* mods trait name template or
762764
* mods type name = rhs or
763-
* mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi) & (lo ne hi)
765+
* mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi) or
766+
* mods type name >: lo <: hi = rhs if rhs = TypeBoundsTree(lo, hi, alias) and opaque in mods
764767
*/
765768
case class TypeDef[-T >: Untyped] private[ast] (name: TypeName, rhs: Tree[T])(implicit @constructorOnly src: SourceFile)
766769
extends MemberDef[T] {
@@ -811,8 +814,6 @@ object Trees {
811814
extends ProxyTree[T] {
812815
type ThisTree[-T >: Untyped] = Annotated[T]
813816
def forwardTo: Tree[T] = arg
814-
override def disableOverlapChecks = true
815-
// disable overlaps checks since the WithBounds annotation swaps type and annotation.
816817
}
817818

818819
trait WithoutTypeOrPos[-T >: Untyped] extends Tree[T] {
@@ -1151,9 +1152,9 @@ object Trees {
11511152
case tree: ByNameTypeTree if (result eq tree.result) => tree
11521153
case _ => finalize(tree, untpd.ByNameTypeTree(result)(sourceFile(tree)))
11531154
}
1154-
def TypeBoundsTree(tree: Tree)(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree = tree match {
1155-
case tree: TypeBoundsTree if (lo eq tree.lo) && (hi eq tree.hi) => tree
1156-
case _ => finalize(tree, untpd.TypeBoundsTree(lo, hi)(sourceFile(tree)))
1155+
def TypeBoundsTree(tree: Tree)(lo: Tree, hi: Tree, alias: Tree)(implicit ctx: Context): TypeBoundsTree = tree match {
1156+
case tree: TypeBoundsTree if (lo eq tree.lo) && (hi eq tree.hi) && (alias eq tree.alias) => tree
1157+
case _ => finalize(tree, untpd.TypeBoundsTree(lo, hi, alias)(sourceFile(tree)))
11571158
}
11581159
def Bind(tree: Tree)(name: Name, body: Tree)(implicit ctx: Context): Bind = tree match {
11591160
case tree: Bind if (name eq tree.name) && (body eq tree.body) => tree
@@ -1304,8 +1305,8 @@ object Trees {
13041305
cpy.MatchTypeTree(tree)(transform(bound), transform(selector), transformSub(cases))
13051306
case ByNameTypeTree(result) =>
13061307
cpy.ByNameTypeTree(tree)(transform(result))
1307-
case TypeBoundsTree(lo, hi) =>
1308-
cpy.TypeBoundsTree(tree)(transform(lo), transform(hi))
1308+
case TypeBoundsTree(lo, hi, alias) =>
1309+
cpy.TypeBoundsTree(tree)(transform(lo), transform(hi), transform(alias))
13091310
case Bind(name, body) =>
13101311
cpy.Bind(tree)(name, transform(body))
13111312
case Alternative(trees) =>
@@ -1428,8 +1429,8 @@ object Trees {
14281429
this(this(this(x, bound), selector), cases)
14291430
case ByNameTypeTree(result) =>
14301431
this(x, result)
1431-
case TypeBoundsTree(lo, hi) =>
1432-
this(this(x, lo), hi)
1432+
case TypeBoundsTree(lo, hi, alias) =>
1433+
this(this(this(x, lo), hi), alias)
14331434
case Bind(name, body) =>
14341435
this(x, body)
14351436
case Alternative(trees) =>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
179179
def MatchTypeTree(bound: Tree, selector: Tree, cases: List[CaseDef])(implicit ctx: Context): MatchTypeTree =
180180
ta.assignType(untpd.MatchTypeTree(bound, selector, cases), bound, selector, cases)
181181

182-
def TypeBoundsTree(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree =
183-
ta.assignType(untpd.TypeBoundsTree(lo, hi), lo, hi)
182+
def TypeBoundsTree(lo: Tree, hi: Tree, alias: Tree = EmptyTree)(implicit ctx: Context): TypeBoundsTree =
183+
ta.assignType(untpd.TypeBoundsTree(lo, hi, alias), lo, hi, alias)
184184

185185
def Bind(sym: Symbol, body: Tree)(implicit ctx: Context): Bind =
186186
ta.assignType(untpd.Bind(sym.name, body), sym)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
376376
def LambdaTypeTree(tparams: List[TypeDef], body: Tree)(implicit src: SourceFile): LambdaTypeTree = new LambdaTypeTree(tparams, body)
377377
def MatchTypeTree(bound: Tree, selector: Tree, cases: List[CaseDef])(implicit src: SourceFile): MatchTypeTree = new MatchTypeTree(bound, selector, cases)
378378
def ByNameTypeTree(result: Tree)(implicit src: SourceFile): ByNameTypeTree = new ByNameTypeTree(result)
379-
def TypeBoundsTree(lo: Tree, hi: Tree)(implicit src: SourceFile): TypeBoundsTree = new TypeBoundsTree(lo, hi)
379+
def TypeBoundsTree(lo: Tree, hi: Tree, alias: Tree = EmptyTree)(implicit src: SourceFile): TypeBoundsTree = new TypeBoundsTree(lo, hi, alias)
380380
def Bind(name: Name, body: Tree)(implicit src: SourceFile): Bind = new Bind(name, body)
381381
def Alternative(trees: List[Tree])(implicit src: SourceFile): Alternative = new Alternative(trees)
382382
def UnApply(fun: Tree, implicits: List[Tree], patterns: List[Tree])(implicit src: SourceFile): UnApply = new UnApply(fun, implicits, patterns)

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

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -173,22 +173,6 @@ object Annotations {
173173
else None
174174
}
175175

176-
/** Extractor for WithBounds[T] annotations */
177-
object WithBounds {
178-
def unapply(ann: Annotation)(implicit ctx: Context): Option[TypeBounds] =
179-
if (ann.symbol == defn.WithBoundsAnnot) {
180-
import ast.Trees._
181-
// We need to extract the type of the type tree in the New itself.
182-
// The annotation's type has been simplified as the type of an expression,
183-
// which means that `&` or `|` might have been lost.
184-
// Test in pos/reference/opaque.scala
185-
val Apply(TypeApply(Select(New(tpt), nme.CONSTRUCTOR), _), Nil) = ann.tree
186-
val AppliedType(_, lo :: hi :: Nil) = tpt.tpe
187-
Some(TypeBounds(lo, hi))
188-
}
189-
else None
190-
}
191-
192176
def makeSourceFile(path: String)(implicit ctx: Context): Annotation =
193177
apply(defn.SourceFileAnnot, Literal(Constant(path)))
194178
}

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,9 @@ trait ConstraintHandling[AbstractContext] {
379379
case bounds: TypeBounds =>
380380
val lower = constraint.lower(param)
381381
val upper = constraint.upper(param)
382-
if (lower.nonEmpty && !bounds.lo.isRef(defn.NothingClass) ||
383-
upper.nonEmpty && !bounds.hi.isRef(defn.AnyClass)) constr_println(i"INIT*** $tl")
382+
if lower.nonEmpty && !bounds.lo.isRef(defn.NothingClass)
383+
|| upper.nonEmpty && !bounds.hi.isAny
384+
then constr_println(i"INIT*** $tl")
384385
lower.forall(addOneBound(_, bounds.hi, isUpper = true)) &&
385386
upper.forall(addOneBound(_, bounds.lo, isUpper = false))
386387
case _ =>
@@ -523,13 +524,22 @@ trait ConstraintHandling[AbstractContext] {
523524
pruneLambdaParams(bound)
524525
}
525526

527+
def kindCompatible(tp1: Type, tp2: Type): Boolean =
528+
val tparams1 = tp1.typeParams
529+
val tparams2 = tp2.typeParams
530+
tparams1.corresponds(tparams2)((p1, p2) => kindCompatible(p1.paramInfo, p2.paramInfo))
531+
&& (tparams1.isEmpty || kindCompatible(tp1.hkResult, tp2.hkResult))
532+
|| tp1.hasAnyKind
533+
|| tp2.hasAnyKind
534+
526535
try bound match {
527536
case bound: TypeParamRef if constraint contains bound =>
528537
addParamBound(bound)
529538
case _ =>
530539
val pbound = prune(bound)
531-
pbound.exists && (
532-
if (fromBelow) addLowerBound(param, pbound) else addUpperBound(param, pbound))
540+
pbound.exists
541+
&& kindCompatible(param, pbound)
542+
&& (if fromBelow then addLowerBound(param, pbound) else addUpperBound(param, pbound))
533543
}
534544
finally addConstraintInvocations -= 1
535545
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ object Contexts {
599599
def setDebug: this.type = setSetting(base.settings.Ydebug, true)
600600
}
601601

602-
given ops: extension (c: Context) with
602+
extension ops on (c: Context) with
603603
def addNotNullInfo(info: NotNullInfo) =
604604
c.withNotNullInfos(c.notNullInfos.extendWith(info))
605605

0 commit comments

Comments
 (0)