Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b820d79

Browse files
Merge branch 'main' of https://github.com/lampepfl/dotty into better-crash-handling
2 parents 3e96f81 + 13b8d7d commit b820d79

File tree

212 files changed

+4227
-843
lines changed

Some content is hidden

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

212 files changed

+4227
-843
lines changed

‎.github/workflows/ci.yaml‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,18 @@ name: Dotty
22

33
on:
44
push:
5-
tags:
6-
- '**'
5+
## Be careful if you add or remove something here! Quoting from
6+
## <https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushbranchestagsbranches-ignoretags-ignore>:
7+
##
8+
## > If you define only tags/tags-ignore or only branches/branches-ignore, the
9+
## > workflow won't run for events affecting the undefined Git ref. If you
10+
## > define neither tags/tags-ignore or branches/branches-ignore, the workflow
11+
## > will run for events affecting either branches or tags.
12+
##
13+
## We want the CI to run on both branches and tags, so we should either have:
14+
## - both (tags or tags-ignore) and (branches or branches-ignore),
15+
## - or neither of them.
16+
## But it's important to not have only one or the other.
717
pull_request:
818
schedule:
919
- cron: '0 3 * * *' # Every day at 3 AM

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import core.Decorators._
1616
import config.{SourceVersion, Feature}
1717
import StdNames.nme
1818
import scala.annotation.internal.sharable
19+
import scala.util.control.NoStackTrace
1920
import transform.MacroAnnotations
2021

2122
class CompilationUnit protected (val source: SourceFile) {
@@ -105,7 +106,7 @@ class CompilationUnit protected (val source: SourceFile) {
105106

106107
object CompilationUnit {
107108

108-
class SuspendException extends Exception
109+
class SuspendException extends ExceptionwithNoStackTrace
109110

110111
/** Make a compilation unit for top class `clsd` with the contents of the `unpickled` tree */
111112
def apply(clsd: ClassDenotation, unpickled: Tree, forceTrees: Boolean)(using Context): CompilationUnit =

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class Compiler {
3535
protected def frontendPhases: List[List[Phase]] =
3636
List(new Parser) :: // Compiler frontend: scanner, parser
3737
List(new TyperPhase) :: // Compiler frontend: namer, typer
38+
List(new CheckUnused) :: // Check for unused elements
3839
List(new YCheckPositions) :: // YCheck positions
3940
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
4041
List(new semanticdb.ExtractSemanticDB) :: // Extract info into .semanticdb files

‎compiler/src/dotty/tools/dotc/ast/NavigateAST.scala‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package ast
44
import core.Contexts._
55
import core.Decorators._
66
import util.Spans._
7-
import Trees.{MemberDef, DefTree, WithLazyField}
7+
import Trees.{MemberDef, DefTree, WithLazyFields}
88
import dotty.tools.dotc.core.Types.AnnotatedType
99
import dotty.tools.dotc.core.Types.ImportType
1010
import dotty.tools.dotc.core.Types.Type
@@ -106,16 +106,14 @@ object NavigateAST {
106106
// FIXME: We shouldn't be manually forcing trees here, we should replace
107107
// our usage of `productIterator` by something in `Positioned` that takes
108108
// care of low-level details like this for us.
109-
p match {
110-
case p: WithLazyField[?] =>
111-
p.forceIfLazy
109+
p match
110+
case p: WithLazyFields => p.forceFields()
112111
case _ =>
113-
}
114112
val iterator = p match
115113
case defdef: DefTree[?] =>
116114
p.productIterator ++ defdef.mods.productIterator
117115
case _ =>
118-
p.productIterator
116+
p.productIterator
119117
childPath(iterator, p :: path)
120118
}
121119
else {

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

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,24 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] =>
110110
case _ => 0
111111
}
112112

113+
/** The type arguments of a possibly curried call */
114+
def typeArgss(tree: Tree): List[List[Tree]] =
115+
@tailrec
116+
def loop(tree: Tree, argss: List[List[Tree]]): List[List[Tree]] = tree match
117+
case TypeApply(fn, args) => loop(fn, args :: argss)
118+
case Apply(fn, args) => loop(fn, argss)
119+
case _ => argss
120+
loop(tree, Nil)
121+
122+
/** The term arguments of a possibly curried call */
123+
def termArgss(tree: Tree): List[List[Tree]] =
124+
@tailrec
125+
def loop(tree: Tree, argss: List[List[Tree]]): List[List[Tree]] = tree match
126+
case Apply(fn, args) => loop(fn, args :: argss)
127+
case TypeApply(fn, args) => loop(fn, argss)
128+
case _ => argss
129+
loop(tree, Nil)
130+
113131
/** All term arguments of an application in a single flattened list */
114132
def allArguments(tree: Tree): List[Tree] = unsplice(tree) match {
115133
case Apply(fn, args) => allArguments(fn) ::: args
@@ -295,7 +313,7 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] =>
295313
*/
296314
def parentsKind(parents: List[Tree])(using Context): FlagSet = parents match {
297315
case Nil => NoInitsInterface
298-
case Apply(_, _ :: _) :: _ => EmptyFlags
316+
case Apply(_, _ :: _) :: _ |Block(_, _) :: _ => EmptyFlags
299317
case _ :: parents1 => parentsKind(parents1)
300318
}
301319

@@ -308,6 +326,50 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] =>
308326
case Block(_, expr) => forallResults(expr, p)
309327
case _ => p(tree)
310328
}
329+
330+
def appliedCore(tree: Tree): Tree = tree match {
331+
case Apply(fn, _) => appliedCore(fn)
332+
case TypeApply(fn, _) => appliedCore(fn)
333+
case AppliedTypeTree(fn, _) => appliedCore(fn)
334+
case tree => tree
335+
}
336+
337+
/** Is tree an application with result `this.type`?
338+
* Accept `b.addOne(x)` and also `xs(i) += x`
339+
* where the op is an assignment operator.
340+
*/
341+
def isThisTypeResult(tree: Tree)(using Context): Boolean = appliedCore(tree) match {
342+
case fun @ Select(receiver, op) =>
343+
val argss = termArgss(tree)
344+
tree.tpe match {
345+
case ThisType(tref) =>
346+
tref.symbol == receiver.symbol
347+
case tref: TermRef =>
348+
tref.symbol == receiver.symbol || argss.exists(_.exists(tref.symbol == _.symbol))
349+
case _ =>
350+
def checkSingle(sym: Symbol): Boolean =
351+
(sym == receiver.symbol) || {
352+
receiver match {
353+
case Apply(_, _) => op.isOpAssignmentName // xs(i) += x
354+
case _ => receiver.symbol != NoSymbol &&
355+
(receiver.symbol.isGetter || receiver.symbol.isField) // xs.addOne(x) for var xs
356+
}
357+
}
358+
@tailrec def loop(mt: Type): Boolean = mt match {
359+
case m: MethodType =>
360+
m.resType match {
361+
case ThisType(tref) => checkSingle(tref.symbol)
362+
case tref: TermRef => checkSingle(tref.symbol)
363+
case restpe => loop(restpe)
364+
}
365+
case PolyType(_, restpe) => loop(restpe)
366+
case _ => false
367+
}
368+
fun.symbol != NoSymbol && loop(fun.symbol.info)
369+
}
370+
case _ =>
371+
tree.tpe.isInstanceOf[ThisType]
372+
}
311373
}
312374

313375
trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped] =>
@@ -683,24 +745,6 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
683745
}
684746
}
685747

686-
/** The type arguments of a possibly curried call */
687-
def typeArgss(tree: Tree): List[List[Tree]] =
688-
@tailrec
689-
def loop(tree: Tree, argss: List[List[Tree]]): List[List[Tree]] = tree match
690-
case TypeApply(fn, args) => loop(fn, args :: argss)
691-
case Apply(fn, args) => loop(fn, argss)
692-
case _ => argss
693-
loop(tree, Nil)
694-
695-
/** The term arguments of a possibly curried call */
696-
def termArgss(tree: Tree): List[List[Tree]] =
697-
@tailrec
698-
def loop(tree: Tree, argss: List[List[Tree]]): List[List[Tree]] = tree match
699-
case Apply(fn, args) => loop(fn, args :: argss)
700-
case TypeApply(fn, args) => loop(fn, argss)
701-
case _ => argss
702-
loop(tree, Nil)
703-
704748
/** The type and term arguments of a possibly curried call, in the order they are given */
705749
def allArgss(tree: Tree): List[List[Tree]] =
706750
@tailrec
@@ -1035,7 +1079,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
10351079
case Inlined(_, Nil, expr) => unapply(expr)
10361080
case Block(Nil, expr) => unapply(expr)
10371081
case _ =>
1038-
tree.tpe.widenTermRefExpr.normalized match
1082+
tree.tpe.widenTermRefExpr.dealias.normalized match
10391083
case ConstantType(Constant(x)) => Some(x)
10401084
case _ => None
10411085
}

‎compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ class TreeMapWithImplicits extends tpd.TreeMapWithPreciseStatContexts {
5555
transform(tree.tpt),
5656
transform(tree.rhs)(using nestedScopeCtx(tree.paramss.flatten)))
5757
}
58-
case impl @ Template(constr, parents, self, _) =>
58+
case impl @ Template(constr, _, self, _) =>
5959
cpy.Template(tree)(
6060
transformSub(constr),
61-
transform(parents)(using ctx.superCallContext),
61+
transform(impl.parents)(using ctx.superCallContext),
6262
Nil,
6363
transformSelf(self),
6464
transformStats(impl.body, tree.symbol))

‎compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ class TreeTypeMap(
9292
cpy.Inlined(tree)(call, bindings1, expanded1)
9393

9494
override def transform(tree: tpd.Tree)(using Context): tpd.Tree = treeMap(tree) match {
95-
case impl @ Template(constr, parents, self, _) =>
95+
case impl @ Template(constr, _, self, _) =>
9696
val tmap = withMappedSyms(localSyms(impl :: self :: Nil))
9797
cpy.Template(impl)(
9898
constr = tmap.transformSub(constr),
99-
parents = parents.mapconserve(transform),
99+
parents = impl.parents.mapconserve(transform),
100100
self = tmap.transformSub(self),
101101
body = impl.body mapconserve
102102
(tmap.transform(_)(using ctx.withOwner(mapOwner(impl.symbol.owner))))

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

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -407,12 +407,12 @@ object Trees {
407407
}
408408

409409
/** A ValDef or DefDef tree */
410-
abstract class ValOrDefDef[+T <: Untyped](implicit @constructorOnly src: SourceFile) extends MemberDef[T]withWithLazyField[Tree[T]] {
410+
abstract class ValOrDefDef[+T <: Untyped](implicit @constructorOnly src: SourceFile) extends MemberDef[T], WithLazyFields {
411411
type ThisTree[+T <: Untyped] <: ValOrDefDef[T]
412412
def name: TermName
413413
def tpt: Tree[T]
414-
def unforcedRhs: LazyTree[T]= unforced
415-
def rhs(using Context): Tree[T]= forceIfLazy
414+
def unforcedRhs: LazyTree[T]
415+
def rhs(using Context): Tree[T]
416416
}
417417

418418
trait ValOrTypeDef[+T <: Untyped] extends MemberDef[T]:
@@ -808,8 +808,10 @@ object Trees {
808808
extends ValOrDefDef[T], ValOrTypeDef[T] {
809809
type ThisTree[+T <: Untyped] = ValDef[T]
810810
assert(isEmpty || (tpt ne genericEmptyTree))
811-
def unforced: LazyTree[T] = preRhs
812-
protected def force(x: Tree[T @uncheckedVariance]): Unit = preRhs = x
811+
812+
def unforcedRhs: LazyTree[T] = preRhs
813+
def forceFields()(using Context): Unit = preRhs = force(preRhs)
814+
def rhs(using Context): Tree[T] = { forceFields(); preRhs.asInstanceOf[Tree[T]] }
813815
}
814816

815817
/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
@@ -818,8 +820,10 @@ object Trees {
818820
extends ValOrDefDef[T] {
819821
type ThisTree[+T <: Untyped] = DefDef[T]
820822
assert(tpt ne genericEmptyTree)
821-
def unforced: LazyTree[T] = preRhs
822-
protected def force(x: Tree[T @uncheckedVariance]): Unit = preRhs = x
823+
824+
def unforcedRhs: LazyTree[T] = preRhs
825+
def forceFields()(using Context): Unit = preRhs = force(preRhs)
826+
def rhs(using Context): Tree[T] = { forceFields(); preRhs.asInstanceOf[Tree[T]] }
823827

824828
def leadingTypeParams(using Context): List[TypeDef[T]] = paramss match
825829
case (tparams @ (tparam: TypeDef[_]) :: _) :: _ => tparams.asInstanceOf[List[TypeDef[T]]]
@@ -855,16 +859,20 @@ object Trees {
855859
* if this is of class untpd.DerivingTemplate.
856860
* Typed templates only have parents.
857861
*/
858-
case class Template[+T <: Untyped] private[ast] (constr: DefDef[T], parentsOrDerived: List[Tree[T]], self: ValDef[T], private var preBody: LazyTreeList[T])(implicit @constructorOnly src: SourceFile)
859-
extends DefTree[T] with WithLazyField[List[Tree[T]]] {
862+
case class Template[+T <: Untyped] private[ast] (constr: DefDef[T], privatevarpreParentsOrDerived:LazyTreeList[T], self: ValDef[T], private var preBody: LazyTreeList[T])(implicit @constructorOnly src: SourceFile)
863+
extends DefTree[T] with WithLazyFields {
860864
type ThisTree[+T <: Untyped] = Template[T]
861-
def unforcedBody: LazyTreeList[T] = unforced
862-
def unforced: LazyTreeList[T] = preBody
863-
protected def force(x: List[Tree[T @uncheckedVariance]]): Unit = preBody = x
864-
def body(using Context): List[Tree[T]] = forceIfLazy
865865

866-
def parents: List[Tree[T]] = parentsOrDerived // overridden by DerivingTemplate
867-
def derived: List[untpd.Tree] = Nil // overridden by DerivingTemplate
866+
def forceFields()(using Context): Unit =
867+
preParentsOrDerived = force(preParentsOrDerived)
868+
preBody = force(preBody)
869+
870+
def unforcedBody: LazyTreeList[T] = preBody
871+
def body(using Context): List[Tree[T]] = { forceFields(); preBody.asInstanceOf[List[Tree[T]]] }
872+
def parentsOrDerived(using Context): List[Tree[T]] = { forceFields(); preParentsOrDerived.asInstanceOf[List[Tree[T]]] }
873+
874+
def parents(using Context): List[Tree[T]] = parentsOrDerived // overridden by DerivingTemplate
875+
def derived: List[untpd.Tree] = Nil // overridden by DerivingTemplate
868876
}
869877

870878

@@ -1008,30 +1016,27 @@ object Trees {
10081016

10091017
// ----- Lazy trees and tree sequences
10101018

1011-
/** A tree that can have a lazy field
1012-
* The field is represented by some private `var` which is
1013-
* accessed by `unforced` and `force`. Forcing the field will
1014-
* set the `var` to the underlying value.
1015-
*/
1016-
trait WithLazyField[+T <: AnyRef] {
1017-
def unforced: T | Lazy[T]
1018-
protected def force(x: T @uncheckedVariance): Unit
1019-
def forceIfLazy(using Context): T = unforced match {
1020-
case lzy: Lazy[T @unchecked] =>
1021-
val x = lzy.complete
1022-
force(x)
1023-
x
1024-
case x: T @ unchecked => x
1025-
}
1026-
}
1027-
10281019
/** A base trait for lazy tree fields.
10291020
* These can be instantiated with Lazy instances which
10301021
* can delay tree construction until the field is first demanded.
10311022
*/
1032-
trait Lazy[+T <: AnyRef] {
1023+
trait Lazy[+T <: AnyRef]:
10331024
def complete(using Context): T
1034-
}
1025+
1026+
/** A tree that can have a lazy fields.
1027+
* Such fields are variables of type `T | Lazy[T]`, for some tyope `T`.
1028+
*/
1029+
trait WithLazyFields:
1030+
1031+
/** If `x` is lazy, computes the underlying value */
1032+
protected def force[T <: AnyRef](x: T | Lazy[T])(using Context): T = x match
1033+
case x: Lazy[T] @unchecked => x.complete
1034+
case x: T @unchecked => x
1035+
1036+
/** Assigns all lazy fields their underlying non-lazy value. */
1037+
def forceFields()(using Context): Unit
1038+
1039+
end WithLazyFields
10351040

10361041
// ----- Generic Tree Instances, inherited from `tpt` and `untpd`.
10371042

@@ -1355,7 +1360,7 @@ object Trees {
13551360
DefDef(tree: Tree)(name, paramss, tpt, rhs)
13561361
def TypeDef(tree: TypeDef)(name: TypeName = tree.name, rhs: Tree = tree.rhs)(using Context): TypeDef =
13571362
TypeDef(tree: Tree)(name, rhs)
1358-
def Template(tree: Template)(constr: DefDef = tree.constr, parents: List[Tree] = tree.parents, derived: List[untpd.Tree] = tree.derived, self: ValDef = tree.self, body: LazyTreeList = tree.unforcedBody)(usingContext): Template =
1363+
def Template(tree: Template)(usingContext)(constr: DefDef = tree.constr, parents: List[Tree] = tree.parents, derived: List[untpd.Tree] = tree.derived, self: ValDef = tree.self, body: LazyTreeList = tree.unforcedBody): Template =
13591364
Template(tree: Tree)(constr, parents, derived, self, body)
13601365
def Hole(tree: Hole)(isTerm: Boolean = tree.isTerm, idx: Int = tree.idx, args: List[Tree] = tree.args, content: Tree = tree.content, tpt: Tree = tree.tpt)(using Context): Hole =
13611366
Hole(tree: Tree)(isTerm, idx, args, content, tpt)
@@ -1618,8 +1623,8 @@ object Trees {
16181623
inContext(localCtx(tree)) {
16191624
this(x, rhs)
16201625
}
1621-
case tree @ Template(constr, parents, self, _) if tree.derived.isEmpty =>
1622-
this(this(this(this(x, constr), parents), self), tree.body)
1626+
case tree @ Template(constr, _, self, _) if tree.derived.isEmpty =>
1627+
this(this(this(this(x, constr), tree.parents), self), tree.body)
16231628
case Import(expr, _) =>
16241629
this(x, expr)
16251630
case Export(expr, _) =>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /