Skip to content

Transform/constructors #176

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

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
da53cc6
Avoid creating ConstantTypes by TypeAssigner after erasure.
odersky Oct 11, 2014
398b1da
Add possibility to compile all files in a directory and all subdirect…
odersky Oct 11, 2014
1920197
Replace call to unimplemented method runtimeCall
odersky Sep 17, 2014
2b784e1
Facturing out EnclosingMethodTraverser from CapturedVars
odersky Sep 17, 2014
842ba24
Make enteredAfter, installAfter more forgiving as to when they are ca…
odersky Sep 17, 2014
ec5b2ce
Add isProperlyContainedIn method
odersky Sep 17, 2014
0762198
Fix lifting of application:
odersky Sep 18, 2014
b4d5ef2
Replace tree.withName with {tpd|untpd}.rename.tree
odersky Sep 18, 2014
4a8c530
Take receiver into account when selecting default getters.
odersky Sep 18, 2014
ee976b8
Treat @static as a source flag.
odersky Sep 18, 2014
b157b28
Allow relaxed typing of applications
odersky Sep 18, 2014
fe0cea4
Take environment into account when typing a closure.
odersky Sep 18, 2014
ce08c2f
Erasure should keep prefix in termrefs.
odersky Sep 18, 2014
6d03e30
Drop type declarations from erased ClassInfo
odersky Sep 21, 2014
e1be088
Uncurry also in DefDef trees, not just in infos.
odersky Sep 21, 2014
0a04924
Fix handling of type params in secondary constructors
odersky Sep 21, 2014
41f92ae
Fix tree typing to account for trees after constructors is run.
odersky Sep 21, 2014
7d39cbc
New utility methods in SymUtils
odersky Sep 21, 2014
360d10e
Account for PolyProto and IgnoredProto types in expectedTypeStr
odersky Sep 21, 2014
f65f0f4
Fix to primaryConstructor
odersky Sep 21, 2014
0e32cf8
Add constructors phase
odersky Sep 21, 2014
77ad36d
Combine captured vars and constructors into one macro phase.
odersky Sep 21, 2014
2081bd9
Fix rewriting of by-name class parameter accessors.
odersky Sep 23, 2014
40179ca
Completed constructors phase
odersky Sep 23, 2014
88bfdeb
Made TypeVars uncahable keys
odersky Sep 23, 2014
056c7f0
Fix caching logic in baseTypeRef
odersky Sep 23, 2014
eae997c
Added method to help traversing children in a TreeTraverser
odersky Sep 24, 2014
5708b17
Move private fields into constructor
odersky Sep 24, 2014
462eaf1
Fix errors in SymDenotations.isCachable.
DarkDimius Oct 11, 2014
57c110d
After-rebase fix: weaken owner-chain restriction.
DarkDimius Oct 11, 2014
8cbc5b3
ElimByName now handles casts to by-name-parameter TermRefs
odersky Oct 11, 2014
4f4bf41
Merge remote-tracking branch 'staging/transform/constructors' into tr…
odersky Oct 11, 2014
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
23 changes: 18 additions & 5 deletions src/dotty/tools/dotc/transform/ElimByName.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,29 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform
cpy.Apply(tree)(tree.fun, args1)
}

private def becomesFunction(symd: SymDenotation)(implicit ctx: Context) =
/** If denotation had an ExprType before, it now gets a function type */
private def exprBecomesFunction(symd: SymDenotation)(implicit ctx: Context) =
(symd is Param) || (symd is (ParamAccessor, butNot = Method))

override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree = {
val origDenot = originalDenotation(tree)
if (becomesFunction(origDenot) && (origDenot.info.isInstanceOf[ExprType]))
/** Map `tree` to `tree.apply()` is `ftree` was of ExprType and becomes now a function */
private def applyIfFunction(tree: Tree, ftree: Tree)(implicit ctx: Context) = {
val origDenot = originalDenotation(ftree)
if (exprBecomesFunction(origDenot) && (origDenot.info.isInstanceOf[ExprType]))
tree.select(defn.Function0_apply).appliedToNone
else tree
}

override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree =
applyIfFunction(tree, tree)

override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
case TypeApply(Select(_, nme.asInstanceOf_), arg :: Nil) =>
// tree might be of form e.asInstanceOf[x.type] where x becomes a function.
// See pos/t296.scala
applyIfFunction(tree, arg)
case _ => tree
}

def elimByNameParams(tp: Type)(implicit ctx: Context): Type = tp match {
case tp: PolyType =>
tp.derivedPolyType(tp.paramNames, tp.paramBounds, elimByNameParams(tp.resultType))
Expand All @@ -102,6 +115,6 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform
}

def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type =
if (becomesFunction(sym)) transformParamInfo(tp)
if (exprBecomesFunction(sym)) transformParamInfo(tp)
else elimByNameParams(tp)
}
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ object Erasure extends TypeTestsCasts{

override def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
assert(tree.hasType)
val erased = erasedType(tree)(ctx.withPhase(ctx.erasurePhase))
val erased = erasedType(tree)
ctx.log(s"promoting ${tree.show}: ${erased.showWithUnderlying()}")
tree.withType(erased)
}
Expand Down
5 changes: 3 additions & 2 deletions src/dotty/tools/dotc/typer/TypeAssigner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,11 @@ trait TypeAssigner {

def assignType(tree: untpd.Literal)(implicit ctx: Context) =
tree.withType {
tree.const.tag match {
val value = tree.const
value.tag match {
case UnitTag => defn.UnitType
case NullTag => defn.NullType
case _ => ConstantType(tree.const)
case _ => if (ctx.erasedTypes) value.tpe else ConstantType(value)
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/dotc/tests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class tests extends CompilerTest {
@Test def dotc_typer = compileDir(dotcDir + "tools/dotc/typer", twice)
@Test def dotc_util = compileDir(dotcDir + "tools/dotc/util", twice)
@Test def tools_io = compileDir(dotcDir + "tools/io", twice)
@Test def tools = compileDir(dotcDir + "tools", twice)(allowDeepSubtypes)
@Test def tools = compileDir(dotcDir + "tools", "-deep" :: twice)(allowDeepSubtypes)

@Test def testNonCyclic = compileArgs(Array(
dotcDir + "tools/dotc/CompilationUnit.scala",
Expand Down
8 changes: 6 additions & 2 deletions test/test/CompilerTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ class CompilerTest extends DottyTest {
compileDir(Directory(path), args, xerrors)

def compileDir(dir: Directory, args: List[String], xerrors: Int)(implicit defaultOptions: List[String]): Unit = {
val fileNames = dir.deepFiles.toArray.map(_.toString).filter(_ endsWith ".scala")
compileArgs(fileNames ++ args, xerrors)
val (files, normArgs) = args match {
case "-deep" :: args1 => (dir.deepFiles, args1)
case _ => (dir.files, args)
}
val fileNames = files.toArray.map(_.toString).filter(_ endsWith ".scala")
compileArgs(fileNames ++ normArgs, xerrors)
}

def compileFiles(path: String, args: List[String] = Nil)(implicit defaultOptions: List[String]): Unit = {
Expand Down
34 changes: 34 additions & 0 deletions tests/neg/t7093-generics-encoding.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Encoding with type fields of the
// variance test in pos. This time, the
// test does not pass because of the encoding
// This points to a difference between type members
// and parameters which we should investigate further.
object Test2 {

trait A {
type X
protected[this] def f(x: X): X = x
}

trait B extends A {
type X <: B
def kaboom = f(new B {})
}

// protected[this] disables variance checking
// of the signature of `f`.
//
// C's parent list unifies A[B] with A[C]
//
// The protected[this] loophole is widely used
// in the collections, every newBuilder method
// would fail variance checking otherwise.
class C extends B with A {
type X <: C
override protected[this] def f(c: C) = c
}

// java.lang.ClassCastException: B$$anon$1 cannot be cast to C
// at C.f(<console>:15)
new C().kaboom
}
13 changes: 13 additions & 0 deletions tests/neg/t7093.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

object Test2 {

trait A {
type X
protected[this] def f(x: X): X = x
}

trait B extends A {
type X <: B
def kaboom = f(new B {})
}
}
12 changes: 12 additions & 0 deletions tests/pending/pos/test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
object Test {

object returns {

def foo(x: Int): Int = {
return 3
}
}

}


5 changes: 5 additions & 0 deletions tests/pos/test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object Test {

def foo(x: Int): Int = return 3

}
5 changes: 5 additions & 0 deletions tests/pos/trees.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Tree[T]

class Empty[T] extends Tree[Nothing]
class Node[T](elem: T, l: Tree[T], r: Tree[T])