Skip to content

Commit 12cce7b

Browse files
authored
Merge branch 'master' into argument-file-fix-13552
2 parents b0b5392 + ffd9471 commit 12cce7b

File tree

102 files changed

+1355
-541
lines changed

Some content is hidden

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

102 files changed

+1355
-541
lines changed

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ class CompilationUnit protected (val source: SourceFile) {
5656
*/
5757
var needsQuotePickling: Boolean = false
5858

59-
/** A structure containing a temporary map for generating inline accessors */
60-
val inlineAccessors: InlineAccessors = new InlineAccessors
61-
6259
var suspended: Boolean = false
6360
var suspendedAtInliningPhase: Boolean = false
6461

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
113113
case _ => 0
114114
}
115115

116-
/** The (last) list of arguments of an application */
117-
def arguments(tree: Tree): List[Tree] = unsplice(tree) match {
118-
case Apply(_, args) => args
119-
case TypeApply(fn, _) => arguments(fn)
120-
case Block(_, expr) => arguments(expr)
116+
/** All term arguments of an application in a single flattened list */
117+
def allArguments(tree: Tree): List[Tree] = unsplice(tree) match {
118+
case Apply(fn, args) => allArguments(fn) ::: args
119+
case TypeApply(fn, _) => allArguments(fn)
120+
case Block(_, expr) => allArguments(expr)
121121
case _ => Nil
122122
}
123123

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

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ import StdNames._
77
import dotty.tools.dotc.ast.tpd
88
import scala.util.Try
99
import util.Spans.Span
10+
import printing.{Showable, Printer}
11+
import printing.Texts.Text
12+
import annotation.internal.sharable
1013

1114
object Annotations {
1215

1316
def annotClass(tree: Tree)(using Context) =
1417
if (tree.symbol.isConstructor) tree.symbol.owner
1518
else tree.tpe.typeSymbol
1619

17-
abstract class Annotation {
20+
abstract class Annotation extends Showable {
1821
def tree(using Context): Tree
1922

2023
def symbol(using Context): Symbol = annotClass(tree)
@@ -26,7 +29,8 @@ object Annotations {
2629
def derivedAnnotation(tree: Tree)(using Context): Annotation =
2730
if (tree eq this.tree) this else Annotation(tree)
2831

29-
def arguments(using Context): List[Tree] = ast.tpd.arguments(tree)
32+
/** All arguments to this annotation in a single flat list */
33+
def arguments(using Context): List[Tree] = ast.tpd.allArguments(tree)
3034

3135
def argument(i: Int)(using Context): Option[Tree] = {
3236
val args = arguments
@@ -44,15 +48,48 @@ object Annotations {
4448
/** The tree evaluation has finished. */
4549
def isEvaluated: Boolean = true
4650

51+
/** Normally, type map over all tree nodes of this annotation, but can
52+
* be overridden. Returns EmptyAnnotation if type type map produces a range
53+
* type, since ranges cannot be types of trees.
54+
*/
55+
def mapWith(tm: TypeMap)(using Context) =
56+
val args = arguments
57+
if args.isEmpty then this
58+
else
59+
val findDiff = new TreeAccumulator[Type]:
60+
def apply(x: Type, tree: Tree)(using Context): Type =
61+
if tm.isRange(x) then x
62+
else
63+
val tp1 = tm(tree.tpe)
64+
foldOver(if tp1 =:= tree.tpe then x else tp1, tree)
65+
val diff = findDiff(NoType, args)
66+
if tm.isRange(diff) then EmptyAnnotation
67+
else if diff.exists then derivedAnnotation(tm.mapOver(tree))
68+
else this
69+
70+
/** Does this annotation refer to a parameter of `tl`? */
71+
def refersToParamOf(tl: TermLambda)(using Context): Boolean =
72+
val args = arguments
73+
if args.isEmpty then false
74+
else tree.existsSubTree {
75+
case id: Ident => id.tpe match
76+
case TermParamRef(tl1, _) => tl eq tl1
77+
case _ => false
78+
case _ => false
79+
}
80+
81+
/** A string representation of the annotation. Overridden in BodyAnnotation.
82+
*/
83+
def toText(printer: Printer): Text = printer.annotText(this)
84+
4785
def ensureCompleted(using Context): Unit = tree
4886

4987
def sameAnnotation(that: Annotation)(using Context): Boolean =
5088
symbol == that.symbol && tree.sameTree(that.tree)
5189
}
5290

53-
case class ConcreteAnnotation(t: Tree) extends Annotation {
91+
case class ConcreteAnnotation(t: Tree) extends Annotation:
5492
def tree(using Context): Tree = t
55-
}
5693

5794
abstract class LazyAnnotation extends Annotation {
5895
protected var mySym: Symbol | (Context ?=> Symbol)
@@ -98,6 +135,7 @@ object Annotations {
98135
if (tree eq this.tree) this else ConcreteBodyAnnotation(tree)
99136
override def arguments(using Context): List[Tree] = Nil
100137
override def ensureCompleted(using Context): Unit = ()
138+
override def toText(printer: Printer): Text = "@Body"
101139
}
102140

103141
class ConcreteBodyAnnotation(body: Tree) extends BodyAnnotation {
@@ -194,6 +232,8 @@ object Annotations {
194232
apply(defn.SourceFileAnnot, Literal(Constant(path)))
195233
}
196234

235+
@sharable val EmptyAnnotation = Annotation(EmptyTree)
236+
197237
def ThrowsAnnotation(cls: ClassSymbol)(using Context): Annotation = {
198238
val tref = cls.typeRef
199239
Annotation(defn.ThrowsAnnot.typeRef.appliedTo(tref), Ident(tref))

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

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2526,17 +2526,6 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25262526
case _ => false
25272527
})
25282528

2529-
/** Can we enumerate all instantiations of this type? */
2530-
def isClosedSum(tp: Symbol): Boolean =
2531-
tp.is(Sealed) && tp.isOneOf(AbstractOrTrait) && !tp.hasAnonymousChild
2532-
2533-
/** Splits a closed type into a disjunction of smaller types.
2534-
* It should hold that `tp` and `decompose(tp).reduce(_ or _)`
2535-
* denote the same set of values.
2536-
*/
2537-
def decompose(sym: Symbol, tp: Type): List[Type] =
2538-
sym.children.map(x => refineUsingParent(tp, x)).filter(_.exists)
2539-
25402529
def fullyInstantiated(tp: Type): Boolean = new TypeAccumulator[Boolean] {
25412530
override def apply(x: Boolean, t: Type) =
25422531
x && {
@@ -2558,6 +2547,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25582547
case (tp1: TypeRef, tp2: TypeRef) if tp1.symbol.isClass && tp2.symbol.isClass =>
25592548
val cls1 = tp1.classSymbol
25602549
val cls2 = tp2.classSymbol
2550+
def isDecomposable(tp: Symbol): Boolean =
2551+
tp.is(Sealed) && !tp.hasAnonymousChild
2552+
def decompose(sym: Symbol, tp: Type): List[Type] =
2553+
sym.children.map(x => refineUsingParent(tp, x)).filter(_.exists)
25612554
if (cls1.derivesFrom(cls2) || cls2.derivesFrom(cls1))
25622555
false
25632556
else
@@ -2570,9 +2563,13 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25702563
// subtype, so they must be unrelated by single inheritance
25712564
// of classes.
25722565
true
2573-
else if (isClosedSum(cls1))
2566+
else if (isDecomposable(cls1))
2567+
// At this point, !cls1.derivesFrom(cls2): we know that direct
2568+
// instantiations of `cls1` (terms of the form `new cls1`) are not
2569+
// of type `tp2`. Therefore, we can safely decompose `cls1` using
2570+
// `.children`, even if `cls1` is non abstract.
25742571
decompose(cls1, tp1).forall(x => provablyDisjoint(x, tp2))
2575-
else if (isClosedSum(cls2))
2572+
else if (isDecomposable(cls2))
25762573
decompose(cls2, tp2).forall(x => provablyDisjoint(x, tp1))
25772574
else
25782575
false

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,13 @@ object TypeOps:
164164
// with Nulls (which have no base classes). Under -Yexplicit-nulls, we take
165165
// corrective steps, so no widening is wanted.
166166
simplify(l, theMap) | simplify(r, theMap)
167-
case AnnotatedType(parent, annot)
168-
if annot.symbol == defn.UncheckedVarianceAnnot && !ctx.mode.is(Mode.Type) && !theMap.isInstanceOf[SimplifyKeepUnchecked] =>
169-
simplify(parent, theMap)
167+
case tp @ AnnotatedType(parent, annot) =>
168+
val parent1 = simplify(parent, theMap)
169+
if annot.symbol == defn.UncheckedVarianceAnnot
170+
&& !ctx.mode.is(Mode.Type)
171+
&& !theMap.isInstanceOf[SimplifyKeepUnchecked]
172+
then parent1
173+
else tp.derivedAnnotatedType(parent1, annot)
170174
case _: MatchType =>
171175
val normed = tp.tryNormalize
172176
if (normed.exists) normed else mapOver

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

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,17 @@ object Types {
13891389
/** Like `dealiasKeepAnnots`, but keeps only refining annotations */
13901390
final def dealiasKeepRefiningAnnots(using Context): Type = dealias1(keepIfRefining)
13911391

1392+
/** Approximate this type with a type that does not contain skolem types. */
1393+
final def deskolemized(using Context): Type =
1394+
val deskolemizer = new ApproximatingTypeMap {
1395+
def apply(tp: Type) = /*trace(i"deskolemize($tp) at $variance", show = true)*/
1396+
tp match {
1397+
case tp: SkolemType => range(defn.NothingType, atVariance(1)(apply(tp.info)))
1398+
case _ => mapOver(tp)
1399+
}
1400+
}
1401+
deskolemizer(this)
1402+
13921403
/** The result of normalization using `tryNormalize`, or the type itself if
13931404
* tryNormlize yields NoType
13941405
*/
@@ -3601,6 +3612,9 @@ object Types {
36013612
case tp: AppliedType => tp.fold(status, compute(_, _, theAcc))
36023613
case tp: TypeVar if !tp.isInstantiated => combine(status, Provisional)
36033614
case tp: TermParamRef if tp.binder eq thisLambdaType => TrueDeps
3615+
case AnnotatedType(parent, ann) =>
3616+
if ann.refersToParamOf(thisLambdaType) then TrueDeps
3617+
else compute(status, parent, theAcc)
36043618
case _: ThisType | _: BoundType | NoPrefix => status
36053619
case _ =>
36063620
(if theAcc != null then theAcc else DepAcc()).foldOver(status, tp)
@@ -3653,8 +3667,10 @@ object Types {
36533667
if (isResultDependent) {
36543668
val dropDependencies = new ApproximatingTypeMap {
36553669
def apply(tp: Type) = tp match {
3656-
case tp @ TermParamRef(thisLambdaType, _) =>
3670+
case tp @ TermParamRef(`thisLambdaType`, _) =>
36573671
range(defn.NothingType, atVariance(1)(apply(tp.underlying)))
3672+
case AnnotatedType(parent, ann) if ann.refersToParamOf(thisLambdaType) =>
3673+
mapOver(parent)
36583674
case _ => mapOver(tp)
36593675
}
36603676
}
@@ -4104,18 +4120,17 @@ object Types {
41044120

41054121
override def underlying(using Context): Type = tycon
41064122

4107-
override def superType(using Context): Type = {
4108-
if (ctx.period != validSuper) {
4109-
cachedSuper = tycon match {
4123+
override def superType(using Context): Type =
4124+
if ctx.period != validSuper then
4125+
validSuper = if (tycon.isProvisional) Nowhere else ctx.period
4126+
cachedSuper = tycon match
41104127
case tycon: HKTypeLambda => defn.AnyType
41114128
case tycon: TypeRef if tycon.symbol.isClass => tycon
4112-
case tycon: TypeProxy => tycon.superType.applyIfParameterized(args)
4129+
case tycon: TypeProxy =>
4130+
if isMatchAlias then validSuper = Nowhere
4131+
tycon.superType.applyIfParameterized(args).normalized
41134132
case _ => defn.AnyType
4114-
}
4115-
validSuper = if (tycon.isProvisional) Nowhere else ctx.period
4116-
}
41174133
cachedSuper
4118-
}
41194134

41204135
override def translucentSuperType(using Context): Type = tycon match {
41214136
case tycon: TypeRef if tycon.symbol.isOpaqueAlias =>
@@ -5379,6 +5394,8 @@ object Types {
53795394
variance = saved
53805395
derivedLambdaType(tp)(ptypes1, this(restpe))
53815396

5397+
def isRange(tp: Type): Boolean = tp.isInstanceOf[Range]
5398+
53825399
/** Map this function over given type */
53835400
def mapOver(tp: Type): Type = {
53845401
record(s"TypeMap mapOver ${getClass}")
@@ -5422,8 +5439,9 @@ object Types {
54225439

54235440
case tp @ AnnotatedType(underlying, annot) =>
54245441
val underlying1 = this(underlying)
5425-
if (underlying1 eq underlying) tp
5426-
else derivedAnnotatedType(tp, underlying1, mapOver(annot))
5442+
val annot1 = annot.mapWith(this)
5443+
if annot1 eq EmptyAnnotation then underlying1
5444+
else derivedAnnotatedType(tp, underlying1, annot1)
54275445

54285446
case _: ThisType
54295447
| _: BoundType
@@ -5495,9 +5513,6 @@ object Types {
54955513
else newScopeWith(elems1: _*)
54965514
}
54975515

5498-
def mapOver(annot: Annotation): Annotation =
5499-
annot.derivedAnnotation(mapOver(annot.tree))
5500-
55015516
def mapOver(tree: Tree): Tree = treeTypeMap(tree)
55025517

55035518
/** Can be overridden. By default, only the prefix is mapped. */
@@ -5544,8 +5559,6 @@ object Types {
55445559

55455560
protected def emptyRange = range(defn.NothingType, defn.AnyType)
55465561

5547-
protected def isRange(tp: Type): Boolean = tp.isInstanceOf[Range]
5548-
55495562
protected def lower(tp: Type): Type = tp match {
55505563
case tp: Range => tp.lo
55515564
case _ => tp

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,10 @@ class PlainPrinter(_ctx: Context) extends Printer {
404404
case tp: ExprType =>
405405
// parameterless methods require special treatment, see #11201
406406
(if (isParameter) ": => " else ": ") ~ toTextGlobal(tp.widenExpr)
407+
case tp: PolyType =>
408+
"[" ~ paramsText(tp) ~ "]"
409+
~ (Str(": ") provided !tp.resultType.isInstanceOf[MethodType])
410+
~ toTextGlobal(tp.resultType)
407411
case tp =>
408412
": " ~ toTextGlobal(tp)
409413
}
@@ -539,7 +543,10 @@ class PlainPrinter(_ctx: Context) extends Printer {
539543
case _ => literalText(String.valueOf(const.value))
540544
}
541545

542-
def toText(annot: Annotation): Text = s"@${annot.symbol.name}" // for now
546+
/** Usual target for `Annotation#toText`, overridden in RefinedPrinter */
547+
def annotText(annot: Annotation): Text = s"@${annot.symbol.name}"
548+
549+
def toText(annot: Annotation): Text = annot.toText(this)
543550

544551
def toText(param: LambdaParam): Text =
545552
varianceSign(param.paramVariance)
@@ -570,7 +577,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
570577
Text()
571578

572579
nodeName ~ "(" ~ elems ~ tpSuffix ~ ")" ~ (Str(tree.sourcePos.toString) provided printDebug)
573-
}.close // todo: override in refined printer
580+
}.close
574581

575582
def toText(pos: SourcePosition): Text =
576583
if (!pos.exists) "<no position>"

compiler/src/dotty/tools/dotc/printing/Printer.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ abstract class Printer {
119119
/** A description of sym's location */
120120
def extendedLocationText(sym: Symbol): Text
121121

122+
/** Textual description of regular annotation in terms of its tree */
123+
def annotText(annot: Annotation): Text
124+
122125
/** Textual representation of denotation */
123126
def toText(denot: Denotation): Text
124127

0 commit comments

Comments
 (0)