Skip to content

Safe initialization for Scala #7789

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 112 commits into from
Feb 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
baccbd8
Add basic definitions
liufengyun Dec 9, 2019
337c4b6
Add Env definition
liufengyun Dec 9, 2019
52c8441
Add SuperRef as potential
liufengyun Dec 10, 2019
91baf28
Add phase SetDefTree
liufengyun Dec 10, 2019
68ec7ec
Add summarization of expression
liufengyun Dec 10, 2019
f47577a
Add documentation for Warm
liufengyun Dec 10, 2019
fa6c182
Tweak summariztion
liufengyun Dec 10, 2019
bb513dc
Handle Lazy ValDef
liufengyun Dec 10, 2019
891d6d8
Handle TypeDef and DefDef in summarization
liufengyun Dec 10, 2019
1ac3356
WIP - add checking
liufengyun Dec 10, 2019
0494ac1
WIP - implementation linearization
liufengyun Dec 11, 2019
cbc4a31
Handle lazy fields
liufengyun Dec 11, 2019
820c67b
Support traceOp
liufengyun Dec 11, 2019
6f11bf6
Summarize bindings in inlined
liufengyun Dec 11, 2019
c58a967
WIP - summarization of new
liufengyun Dec 11, 2019
073eec2
WIP - introduce ClassSummary
liufengyun Dec 12, 2019
594c1bf
Add show to ClassSummary
liufengyun Dec 12, 2019
94267d7
Add code to summarize class
liufengyun Dec 12, 2019
b94ce00
Fix typing errors
liufengyun Dec 13, 2019
67e7165
Fix Summary and Summarization errors
liufengyun Dec 13, 2019
e5e1c68
Fix more typing errors in Checking
liufengyun Dec 13, 2019
dc680dc
Remove obsolete cases in Checking
liufengyun Dec 13, 2019
5310886
More fixes
liufengyun Dec 13, 2019
6e6a181
WIP
liufengyun Dec 13, 2019
994c240
Add asSeenFrom
liufengyun Dec 13, 2019
4eb8eaa
WIP - Fix expand
liufengyun Dec 13, 2019
9244e27
WIP - Fix more type checking
liufengyun Dec 13, 2019
06ee111
Fix compilation: overloading does not work well with extension methods
liufengyun Dec 13, 2019
e923bf4
Fix compilation warnings
liufengyun Dec 13, 2019
617a6d9
Handle outer
liufengyun Dec 14, 2019
4f76c6a
WIP - asSeenFrom
liufengyun Dec 14, 2019
554620c
Fix Potentials.asSeenFrom
liufengyun Dec 14, 2019
949a009
Fix Effects.asSeenFrom
liufengyun Dec 14, 2019
5c59fee
Lazy access as method calls
liufengyun Dec 14, 2019
13ce15e
Remove virtual from MethodCall and MethodReturn
liufengyun Dec 14, 2019
917ac30
Remove RootPotential
liufengyun Dec 14, 2019
5d34ea1
Code refactoring
liufengyun Dec 14, 2019
9f7c853
Implement resolve and resolveSuper
liufengyun Dec 14, 2019
ac2b9dc
Add checker phase
liufengyun Dec 15, 2019
bcd7c58
Add initialization to compiler phases
liufengyun Dec 15, 2019
077eb5b
First example works
liufengyun Dec 15, 2019
8a9c0cf
Handle class parameters
liufengyun Dec 15, 2019
25c7a90
Handle ignored methods
liufengyun Dec 15, 2019
bf917a7
Ignore non-instantiable classes
liufengyun Dec 15, 2019
8ba171c
Handle A & B for this via self type
liufengyun Dec 15, 2019
99679b8
Fix classSymbol in parents
liufengyun Dec 15, 2019
43d46cd
Fix summarization of class
liufengyun Dec 15, 2019
9b99ffc
A method call might be a field access
liufengyun Dec 15, 2019
ec03ffd
Parent child tests are green
liufengyun Dec 15, 2019
6e3e41d
Fix infinite loop in asSeenFrom
liufengyun Dec 15, 2019
8ab9c8b
Handle Lazy field access in checking
liufengyun Dec 15, 2019
38c2d1d
Handle constructor select properly
liufengyun Dec 15, 2019
c7d2a0a
Fix missing pot in constructor selection
liufengyun Dec 15, 2019
d0e54b0
Fix summarization of lambdas and ValDef
liufengyun Dec 15, 2019
10c620d
Fix primary constructor effects
liufengyun Dec 15, 2019
d2d498b
Fix missed effects in new-expressions
liufengyun Dec 15, 2019
97e4ee4
Fix length of field select which causes non-termination
liufengyun Dec 15, 2019
9996f50
Remove obsolete freedom tests
liufengyun Dec 15, 2019
e6cabb4
Migrate feature tests
liufengyun Dec 15, 2019
f351d80
Migrate tests
liufengyun Dec 15, 2019
60cbb7d
Migrate function tests
liufengyun Dec 16, 2019
1a9b409
Migrate hybrid tests
liufengyun Dec 16, 2019
58c8dc1
Fix secondary constructor
liufengyun Dec 16, 2019
0a1fbfa
Handle HKLambdaType in new expression
liufengyun Dec 16, 2019
56d402e
Treat local methods as called
liufengyun Dec 16, 2019
3ea4894
Fix lazy val access
liufengyun Dec 16, 2019
89b0815
Fix expansion of SuperRef
liufengyun Dec 16, 2019
99e42b5
Fix asSeenFrom
liufengyun Dec 16, 2019
79de26c
Handle reference of ConstantType in summarization
liufengyun Dec 16, 2019
02ddbd7
Mark Object.synchronized as ignored
liufengyun Dec 16, 2019
10f51f7
Ignore EnumValues.register
liufengyun Dec 16, 2019
c48a8e4
All misc tests green
liufengyun Dec 16, 2019
41ffc62
Fix indentation warning
liufengyun Dec 16, 2019
89972d3
Add back lazylists
liufengyun Dec 16, 2019
4c96a4b
Respect @unchecked annotation
liufengyun Dec 16, 2019
3cf5dcb
Refactor crash tests
liufengyun Dec 16, 2019
cd57149
Fix crash due to var x:T = _
liufengyun Dec 16, 2019
11e5767
Enable more tests
liufengyun Dec 16, 2019
1e04d6e
Fix exception in super resolution
liufengyun Dec 16, 2019
2976e97
Initial work on documentation
liufengyun Dec 17, 2019
bef686a
Doc tweaks
liufengyun Dec 17, 2019
414d8a8
Add link in sidebar
liufengyun Dec 17, 2019
0480b96
Fix typo in docs
liufengyun Dec 17, 2019
d2a3a8b
Explain the potential Outer in docs
liufengyun Dec 17, 2019
eb1a49c
Add scopability an explicit principle
liufengyun Dec 18, 2019
3c16fd9
Fix typos in documentation
liufengyun Dec 18, 2019
21b5662
Make doc align with paper
liufengyun Dec 19, 2019
2e0268c
Address review and add docs
liufengyun Jan 13, 2020
a9a6742
Rename Leak to Promote
liufengyun Jan 17, 2020
b2b4976
Add definition of Errors
liufengyun Jan 17, 2020
2ac188f
More errors
liufengyun Jan 17, 2020
085cf64
Accumulate errors in effect checking
liufengyun Jan 17, 2020
9b12559
Add error reporting
liufengyun Jan 17, 2020
4a5c718
Refine error messages
liufengyun Jan 17, 2020
ce42450
Fix tests: more friendly error messages for functions
liufengyun Jan 17, 2020
8ed50b8
Enforce that only initialized values may be returned
liufengyun Jan 17, 2020
49e3efb
Use build-in mechanism to get definitions
liufengyun Jan 27, 2020
d4b54a7
Address review
liufengyun Jan 27, 2020
3c2d818
Refine error messages
liufengyun Jan 28, 2020
a42bab2
Fix exception
liufengyun Jan 28, 2020
6ded31f
Fix exception: not all traits have constructors
liufengyun Jan 28, 2020
2e54c6a
Fix exception: Any and AnyVal don't have constructors
liufengyun Jan 28, 2020
328f6a9
Fix exception
liufengyun Jan 28, 2020
ba63e45
Fix extractor for closureDef
liufengyun Jan 28, 2020
d3ce80a
Fix crash: SuperType.supertpe can be AndType
liufengyun Jan 28, 2020
4d500bd
Fix crash: polymorphic function apply does not have symbols
liufengyun Jan 28, 2020
8379ee1
Fix crash: handle annotations in parents
liufengyun Jan 28, 2020
8192b2c
Handle by-name parameters properly
liufengyun Jan 28, 2020
5581d74
Refactor expand
liufengyun Jan 28, 2020
7b5fc1a
Better explain scopability
liufengyun Jan 30, 2020
1694e4a
Refine stacktrace printing
liufengyun Jan 31, 2020
6a4d06a
Fix syntax change
liufengyun Feb 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ class Compiler {
new CheckReentrant, // Internal use only: Check that compiled program has no data races involving global vars
new ElimPackagePrefixes, // Eliminate references to package prefixes in Select nodes
new CookComments, // Cook the comments: expand variables, doc, etc.
new CheckStatic) :: // Check restrictions that apply to @static members
new CheckStatic, // Check restrictions that apply to @static members
new init.Checker) :: // Check initialization of objects
List(new CompleteJavaEnums, // Fill in constructors for Java enums
new ElimRepeated, // Rewrite vararg parameters and arguments
new ExpandSAMs, // Expand single abstract method closures to anonymous classes
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
/** An extractor for def of a closure contained the block of the closure. */
object closureDef {
def unapply(tree: Tree)(implicit ctx: Context): Option[DefDef] = tree match {
case Block((meth @ DefDef(nme.ANON_FUN, _, _, _, _)) :: Nil, closure: Closure) =>
case Block((meth : DefDef) :: Nil, closure: Closure) if meth.symbol == closure.meth.symbol =>
Some(meth)
case Block(Nil, expr) =>
unapply(expr)
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/config/Printers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ object Printers {
val implicits: Printer = noPrinter
val implicitsDetailed: Printer = noPrinter
val lexical: Printer = noPrinter
val init: Printer = noPrinter
val inlining: Printer = noPrinter
val interactiv: Printer = noPrinter
val nullables: Printer = noPrinter
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class ScalaSettings extends Settings.SettingGroup {
val YnoKindPolymorphism: Setting[Boolean] = BooleanSetting("-Yno-kind-polymorphism", "Enable kind polymorphism (see https://dotty.epfl.ch/docs/reference/kind-polymorphism.html). Potentially unsound.")
val YexplicitNulls: Setting[Boolean] = BooleanSetting("-Yexplicit-nulls", "Make reference types non-nullable. Nullable types can be expressed with unions: e.g. String|Null.")
val YerasedTerms: Setting[Boolean] = BooleanSetting("-Yerased-terms", "Allows the use of erased terms.")
val YcheckInit: Setting[Boolean] = BooleanSetting("-Ycheck-init", "Check initialization of objects")

/** Area-specific debug output */
val YexplainLowlevel: Setting[Boolean] = BooleanSetting("-Yexplain-lowlevel", "When explaining type errors, show types at a lower level.")
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,9 @@ object Symbols {
*/
def retainsDefTree(implicit ctx: Context): Boolean =
ctx.settings.YretainTrees.value ||
denot.owner.isTerm || // no risk of leaking memory after a run for these
denot.isOneOf(InlineOrProxy) // need to keep inline info
denot.owner.isTerm || // no risk of leaking memory after a run for these
denot.isOneOf(InlineOrProxy) || // need to keep inline info
ctx.settings.YcheckInit.value // initialization check

/** The last denotation of this symbol */
private var lastDenot: SymDenotation = _
Expand Down
63 changes: 63 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/init/Checker.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package dotty.tools.dotc
package transform
package init


import dotty.tools.dotc._
import ast.tpd

import dotty.tools.dotc.core._
import Contexts.Context
import Types._

import dotty.tools.dotc.transform._
import MegaPhase._


import scala.collection.mutable


class Checker extends MiniPhase {
import tpd._

val phaseName = "initChecker"

// cache of class summary
private val baseEnv = Env(null, mutable.Map.empty)

override val runsAfter = Set(Pickler.name)

override def isEnabled(implicit ctx: Context): Boolean =
super.isEnabled && ctx.settings.YcheckInit.value

override def transformTypeDef(tree: TypeDef)(implicit ctx: Context): tpd.Tree = {
if (!tree.isClassDef) return tree

val cls = tree.symbol.asClass
val instantiable: Boolean =
cls.is(Flags.Module) ||
!cls.isOneOf(Flags.AbstractOrTrait) && {
// see `Checking.checkInstantiable` in typer
val tp = cls.appliedRef
val stp = SkolemType(tp)
val selfType = cls.givenSelfType.asSeenFrom(stp, cls)
!selfType.exists || stp <:< selfType
}

// A concrete class may not be instantiated if the self type is not satisfied
if (instantiable) {
implicit val state = Checking.State(
visited = mutable.Set.empty,
path = Vector.empty,
thisClass = cls,
fieldsInited = mutable.Set.empty,
parentsInited = mutable.Set.empty,
env = baseEnv.withCtx(ctx)
)

Checking.checkClassBody(tree)
}

tree
}
}
Loading