Skip to content

Commit 697c54d

Browse files
Merge pull request #13606 from dotty-staging/various
Some small improvements
2 parents b9c8a60 + bbaff2b commit 697c54d

File tree

5 files changed

+71
-48
lines changed

5 files changed

+71
-48
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,11 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
458458
def AppliedTypeTree(tpt: Tree, arg: Tree)(implicit src: SourceFile): AppliedTypeTree =
459459
AppliedTypeTree(tpt, arg :: Nil)
460460

461-
def TypeTree(tpe: Type)(using Context): TypedSplice = TypedSplice(TypeTree().withTypeUnchecked(tpe))
461+
def TypeTree(tpe: Type)(using Context): TypedSplice =
462+
TypedSplice(TypeTree().withTypeUnchecked(tpe))
463+
464+
def InferredTypeTree(tpe: Type)(using Context): TypedSplice =
465+
TypedSplice(new InferredTypeTree().withTypeUnchecked(tpe))
462466

463467
def unitLiteral(implicit src: SourceFile): Literal = Literal(Constant(()))
464468

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,11 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
289289
tree.fun,
290290
tree.args.mapConserve(arg =>
291291
if (methType.isImplicitMethod && arg.span.isSynthetic)
292-
PruneErasedDefs.trivialErasedTree(arg)
292+
arg match
293+
case _: RefTree | _: Apply | _: TypeApply if arg.symbol.is(Erased) =>
294+
dropInlines.transform(arg)
295+
case _ =>
296+
PruneErasedDefs.trivialErasedTree(arg)
293297
else dropInlines.transform(arg)))
294298
else
295299
tree

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,54 @@ object RefChecks {
192192

193193
// Override checking ------------------------------------------------------------
194194

195+
/** A class for checking all overriding pairs of `class` with a given check function */
196+
class OverridingPairsChecker(clazz: ClassSymbol, self: Type)(using Context) extends OverridingPairs.Cursor(clazz):
197+
198+
override def matches(sym1: Symbol, sym2: Symbol): Boolean =
199+
isOverridingPair(sym1, sym2, self)
200+
201+
private def inLinearizationOrder(sym1: Symbol, sym2: Symbol, parent: Symbol): Boolean =
202+
val owner1 = sym1.owner
203+
val owner2 = sym2.owner
204+
def precedesIn(bcs: List[ClassSymbol]): Boolean = (bcs: @unchecked) match
205+
case bc :: bcs1 =>
206+
if owner1 eq bc then true
207+
else if owner2 eq bc then false
208+
else precedesIn(bcs1)
209+
case _ =>
210+
false
211+
precedesIn(parent.asClass.baseClasses)
212+
213+
// We can exclude pairs safely from checking only under two additional conditions
214+
// - their signatures also match in the parent class.
215+
// See neg/i12828.scala for an example where this matters.
216+
// - They overriding/overridden appear in linearization order.
217+
// See neg/i5094.scala for an example where this matters.
218+
override def canBeHandledByParent(sym1: Symbol, sym2: Symbol, parent: Symbol): Boolean =
219+
isOverridingPair(sym1, sym2, parent.thisType)
220+
.showing(i"already handled ${sym1.showLocated}: ${sym1.asSeenFrom(parent.thisType).signature}, ${sym2.showLocated}: ${sym2.asSeenFrom(parent.thisType).signature} = $result", refcheck)
221+
&& inLinearizationOrder(sym1, sym2, parent)
222+
223+
def checkAll(checkOverride: (Symbol, Symbol) => Unit) =
224+
while hasNext do
225+
checkOverride(overriding, overridden)
226+
next()
227+
228+
// The OverridingPairs cursor does assume that concrete overrides abstract
229+
// We have to check separately for an abstract definition in a subclass that
230+
// overrides a concrete definition in a superclass. E.g. the following (inspired
231+
// from neg/i11130.scala) needs to be rejected as well:
232+
//
233+
// class A { type T = B }
234+
// class B extends A { override type T }
235+
for dcl <- clazz.info.decls.iterator do
236+
if dcl.is(Deferred) then
237+
for other <- dcl.allOverriddenSymbols do
238+
if !other.is(Deferred) then
239+
checkOverride(dcl, other)
240+
end checkAll
241+
end OverridingPairsChecker
242+
195243
/** 1. Check all members of class `clazz` for overriding conditions.
196244
* That is for overriding member M and overridden member O:
197245
*
@@ -469,50 +517,7 @@ object RefChecks {
469517
}*/
470518
}
471519

472-
val opc = new OverridingPairs.Cursor(clazz):
473-
override def matches(sym1: Symbol, sym2: Symbol): Boolean =
474-
isOverridingPair(sym1, sym2, self)
475-
476-
private def inLinearizationOrder(sym1: Symbol, sym2: Symbol, parent: Symbol): Boolean =
477-
val owner1 = sym1.owner
478-
val owner2 = sym2.owner
479-
def precedesIn(bcs: List[ClassSymbol]): Boolean = (bcs: @unchecked) match
480-
case bc :: bcs1 =>
481-
if owner1 eq bc then true
482-
else if owner2 eq bc then false
483-
else precedesIn(bcs1)
484-
case _ =>
485-
false
486-
precedesIn(parent.asClass.baseClasses)
487-
488-
// We can exclude pairs safely from checking only under two additional conditions
489-
// - their signatures also match in the parent class.
490-
// See neg/i12828.scala for an example where this matters.
491-
// - They overriding/overridden appear in linearization order.
492-
// See neg/i5094.scala for an example where this matters.
493-
override def canBeHandledByParent(sym1: Symbol, sym2: Symbol, parent: Symbol): Boolean =
494-
isOverridingPair(sym1, sym2, parent.thisType)
495-
.showing(i"already handled ${sym1.showLocated}: ${sym1.asSeenFrom(parent.thisType).signature}, ${sym2.showLocated}: ${sym2.asSeenFrom(parent.thisType).signature} = $result", refcheck)
496-
&& inLinearizationOrder(sym1, sym2, parent)
497-
end opc
498-
499-
while opc.hasNext do
500-
checkOverride(opc.overriding, opc.overridden)
501-
opc.next()
502-
503-
// The OverridingPairs cursor does assume that concrete overrides abstract
504-
// We have to check separately for an abstract definition in a subclass that
505-
// overrides a concrete definition in a superclass. E.g. the following (inspired
506-
// from neg/i11130.scala) needs to be rejected as well:
507-
//
508-
// class A { type T = B }
509-
// class B extends A { override type T }
510-
for dcl <- clazz.info.decls.iterator do
511-
if dcl.is(Deferred) then
512-
for other <- dcl.allOverriddenSymbols do
513-
if !other.is(Deferred) then
514-
checkOverride(dcl, other)
515-
520+
OverridingPairsChecker(clazz, self).checkAll(checkOverride)
516521
printMixinOverrideErrors()
517522

518523
// Verifying a concrete class has nothing unimplemented.

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,8 +1134,8 @@ class Typer extends Namer
11341134
*/
11351135
private def decomposeProtoFunction(pt: Type, defaultArity: Int, pos: SrcPos)(using Context): (List[Type], untpd.Tree) = {
11361136
def typeTree(tp: Type) = tp match {
1137-
case _: WildcardType => untpd.TypeTree()
1138-
case _ => untpd.TypeTree(tp)
1137+
case _: WildcardType => new untpd.InferredTypeTree()
1138+
case _ => untpd.InferredTypeTree(tp)
11391139
}
11401140
def interpolateWildcards = new TypeMap {
11411141
def apply(t: Type): Type = t match

compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ abstract class SimpleIdentitySet[+Elem <: AnyRef] {
1212
def contains[E >: Elem <: AnyRef](x: E): Boolean
1313
def foreach(f: Elem => Unit): Unit
1414
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean
15+
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B]
1516
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A
1617
def toList: List[Elem]
1718

@@ -55,6 +56,7 @@ object SimpleIdentitySet {
5556
def contains[E <: AnyRef](x: E): Boolean = false
5657
def foreach(f: Nothing => Unit): Unit = ()
5758
def exists[E <: AnyRef](p: E => Boolean): Boolean = false
59+
def map[B <: AnyRef](f: Nothing => B): SimpleIdentitySet[B] = empty
5860
def /: [A, E <: AnyRef](z: A)(f: (A, E) => A): A = z
5961
def toList = Nil
6062
}
@@ -69,6 +71,8 @@ object SimpleIdentitySet {
6971
def foreach(f: Elem => Unit): Unit = f(x0.asInstanceOf[Elem])
7072
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean =
7173
p(x0.asInstanceOf[E])
74+
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
75+
Set1(f(x0.asInstanceOf[Elem]))
7276
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A =
7377
f(z, x0.asInstanceOf[E])
7478
def toList = x0.asInstanceOf[Elem] :: Nil
@@ -86,6 +90,8 @@ object SimpleIdentitySet {
8690
def foreach(f: Elem => Unit): Unit = { f(x0.asInstanceOf[Elem]); f(x1.asInstanceOf[Elem]) }
8791
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean =
8892
p(x0.asInstanceOf[E]) || p(x1.asInstanceOf[E])
93+
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
94+
Set2(f(x0.asInstanceOf[Elem]), f(x1.asInstanceOf[Elem]))
8995
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A =
9096
f(f(z, x0.asInstanceOf[E]), x1.asInstanceOf[E])
9197
def toList = x0.asInstanceOf[Elem] :: x1.asInstanceOf[Elem] :: Nil
@@ -114,6 +120,8 @@ object SimpleIdentitySet {
114120
}
115121
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean =
116122
p(x0.asInstanceOf[E]) || p(x1.asInstanceOf[E]) || p(x2.asInstanceOf[E])
123+
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
124+
Set3(f(x0.asInstanceOf[Elem]), f(x1.asInstanceOf[Elem]), f(x2.asInstanceOf[Elem]))
117125
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A =
118126
f(f(f(z, x0.asInstanceOf[E]), x1.asInstanceOf[E]), x2.asInstanceOf[E])
119127
def toList = x0.asInstanceOf[Elem] :: x1.asInstanceOf[Elem] :: x2.asInstanceOf[Elem] :: Nil
@@ -156,6 +164,8 @@ object SimpleIdentitySet {
156164
}
157165
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean =
158166
xs.asInstanceOf[Array[E]].exists(p)
167+
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
168+
SetN(xs.map(x => f(x.asInstanceOf[Elem]).asInstanceOf[AnyRef]))
159169
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A =
160170
xs.asInstanceOf[Array[E]].foldLeft(z)(f)
161171
def toList: List[Elem] = {

0 commit comments

Comments
 (0)