aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-21 11:16:59 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-21 11:16:59 +0200
commit02394593cf6ed5c092c398cdb1908ea5b0928d6a (patch)
tree6e26b7daaaae2ca12038e30340995c145c22bbd1
parentf19ea205446ec1d5e356097c56312829e31dfc13 (diff)
downloaddotty-02394593cf6ed5c092c398cdb1908ea5b0928d6a.tar.gz
dotty-02394593cf6ed5c092c398cdb1908ea5b0928d6a.tar.bz2
dotty-02394593cf6ed5c092c398cdb1908ea5b0928d6a.zip
Fixes to import handling and adaptation and implicits
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala2
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala8
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala19
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala5
-rw-r--r--src/dotty/tools/dotc/core/Types.scala11
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala10
-rw-r--r--src/dotty/tools/dotc/typer/ImportInfo.scala11
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala43
8 files changed, 66 insertions, 43 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index ed86849b9..ebfde1a62 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -255,8 +255,6 @@ object Contexts {
_condensed
}
- def implicitsEnabled: Boolean = ???
-
/** A fresh clone of this context. */
def fresh: FreshContext = {
val newctx = super.clone.asInstanceOf[FreshContext]
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 272b6f505..208c59213 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -159,7 +159,7 @@ object Denotations {
def suchThat(p: Symbol => Boolean): SingleDenotation
/** Does this denotation have an alternative that satisfies the predicate `p`? */
- def hasAltWith(p: Symbol => Boolean): Boolean
+ def hasAltWith(p: SingleDenotation => Boolean): Boolean
/** The denotation made up from the alternatives of this denotation that
* are accessible from prefix `pre`, or NoDenotation if no accessible alternative exists.
@@ -352,7 +352,7 @@ object Denotations {
else sd1
else sd2
}
- def hasAltWith(p: Symbol => Boolean): Boolean =
+ def hasAltWith(p: SingleDenotation => Boolean): Boolean =
denot1.hasAltWith(p) || denot2.hasAltWith(p)
def accessibleFrom(pre: Type, superAccess: Boolean)(implicit ctx: Context): Denotation = {
val d1 = denot1 accessibleFrom (pre, superAccess)
@@ -400,8 +400,8 @@ object Denotations {
def suchThat(p: Symbol => Boolean): SingleDenotation =
if (p(symbol)) this else NoDenotation
- def hasAltWith(p: Symbol => Boolean): Boolean =
- p(symbol)
+ def hasAltWith(p: SingleDenotation => Boolean): Boolean =
+ p(this)
def accessibleFrom(pre: Type, superAccess: Boolean)(implicit ctx: Context): Denotation =
if (symbol isAccessibleFrom (pre, superAccess)) this else NoDenotation
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 621023ab7..06544d0ed 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -524,20 +524,23 @@ object SymDenotations {
* and which is also defined in the same scope and compilation unit.
* NoSymbol if this module does not exist.
*/
- final def companionModule(implicit ctx: Context): Symbol = {
- owner.info.decl(name.stripModuleClassSuffix.toTermName)
- .suchThat(sym => (sym is Module) && sym.isCoDefinedWith(symbol))
- .symbol
- }
+ final def companionModule(implicit ctx: Context): Symbol =
+ if (owner.exists)
+ owner.info.decl(name.stripModuleClassSuffix.toTermName)
+ .suchThat(sym => (sym is Module) && sym.isCoDefinedWith(symbol))
+ .symbol
+ else NoSymbol
/** The class with the same (type-) name as this module or module class,
* and which is also defined in the same scope and compilation unit.
* NoSymbol if this class does not exist.
*/
final def companionClass(implicit ctx: Context): Symbol =
- owner.info.decl(name.stripModuleClassSuffix.toTypeName)
- .suchThat(sym => sym.isClass && sym.isCoDefinedWith(symbol))
- .symbol
+ if (owner.exists)
+ owner.info.decl(name.stripModuleClassSuffix.toTypeName)
+ .suchThat(sym => sym.isClass && sym.isCoDefinedWith(symbol))
+ .symbol
+ else NoSymbol
/** If this is a class, the module class of its companion object.
* If this is a module class, its companion class.
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 17204bf1c..3cf15479d 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -138,6 +138,8 @@ class TypeComparer(implicit val ctx: Context) extends DotClass {
}
case tp2: AnnotatedType =>
isSubType(tp1, tp2.tpe) // todo: refine?
+ case tp2: ProtoType =>
+ tp2.isMatchedBy(tp1)
case ErrorType =>
true
case _ =>
@@ -184,7 +186,8 @@ class TypeComparer(implicit val ctx: Context) extends DotClass {
case tp2: RefinedType =>
isSubType(tp1, tp2.parent) && (
tp2.refinedName == nme.WILDCARD ||
- tp2.matchesInfo(tp1.member(tp2.refinedName).info))
+ tp1.member(tp2.refinedName).hasAltWith(alt =>
+ isSubType(alt.info, tp2.refinedInfo)))
case AndType(tp21, tp22) =>
isSubType(tp1, tp21) && isSubType(tp1, tp22)
case OrType(tp21, tp22) =>
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index e263cf076..6afd4e92d 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1130,6 +1130,11 @@ object Types {
*/
trait BindingType extends Type
+ /** A trait for proto-types, used as expected types in typer */
+ trait ProtoType extends UncachedGroundType {
+ def isMatchedBy(tp: Type)(implicit ctx: Context): Boolean
+ }
+
// --- NamedTypes ------------------------------------------------------------------
/** A NamedType of the form Prefix # name */
@@ -1952,8 +1957,8 @@ object Types {
if (annots.isEmpty) underlying
else (underlying /: annots)((tp, ann) => AnnotatedType(ann, tp))
}
- // Special type objects and classes -----------------------------------------------------
+ // Special type objects and classes -----------------------------------------------------
/** The type of an import clause tree */
case class ImportType(expr: Tree) extends UncachedGroundType
@@ -2222,7 +2227,7 @@ object Types {
/** A filter for names of deferred term definitions of a given type */
object abstractTermNameFilter extends NameFilter {
def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean =
- name.isTermName && (pre member name).hasAltWith(_ is Deferred)
+ name.isTermName && (pre member name).hasAltWith(_.symbol is Deferred)
}
object typeNameFilter extends NameFilter {
@@ -2235,7 +2240,7 @@ object Types {
object implicitFilter extends NameFilter {
def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean =
- (pre member name).hasAltWith(_ is Implicit)
+ (pre member name).hasAltWith(_.symbol is Implicit)
}
// ----- Exceptions -------------------------------------------------------------
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 9f7956203..b98ea5dc9 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -163,11 +163,11 @@ trait Implicits { self: Typer =>
import tpd._
- override def viewExists(from: Type, to: Type)(implicit ctx: Context): Boolean = (
- !from.isError
- && !to.isError
- && ctx.implicitsEnabled
- && inferView(dummyTreeOfType(from), to) != EmptyTree
+ override def viewExists(from: Type, to: Type)(implicit ctx: Context): Boolean = !(
+ from.isError
+ || to.isError
+ || (ctx.mode is Mode.ImplicitsDisabled)
+ || (inferView(dummyTreeOfType(from), to) eq EmptyTree)
)
/** Find an implicit conversion to apply to given tree `from` so that the
diff --git a/src/dotty/tools/dotc/typer/ImportInfo.scala b/src/dotty/tools/dotc/typer/ImportInfo.scala
index 1b8cd115d..89ffc1f29 100644
--- a/src/dotty/tools/dotc/typer/ImportInfo.scala
+++ b/src/dotty/tools/dotc/typer/ImportInfo.scala
@@ -7,6 +7,7 @@ import ast.Trees._
import core._
import util.SimpleMap
import Symbols._, Names._, Denotations._, Types._, Contexts._, StdNames._, Flags._
+import typer.ErrorReporting.InfoString
object ImportInfo {
/** The import info for a root import from given symbol `sym` */
@@ -87,4 +88,14 @@ class ImportInfo(val sym: Symbol, val selectors: List[untpd.Tree], val rootImpor
denot <- pre.member(name).altsWith(_ is Implicit)
} yield TermRef(pre, name) withDenot denot
}
+
+ override def toString = {
+ val siteStr = site.show
+ val exprStr = if (siteStr endsWith ".type") siteStr dropRight 5 else siteStr
+ val selectorStr = selectors match {
+ case Ident(name) :: Nil => name.show
+ case _ => "{...}"
+ }
+ i"import $exprStr.$selectorStr"
+ }
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index abdc041fa..cdcf43272 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -224,7 +224,7 @@ class Typer extends Namer with Applications with Implicits {
* or defined in <symbol>
*/
def bindingString(prec: Int, whereFound: Context, qualifier: String = "") =
- if (prec == wildImport || prec == namedImport) i"imported$qualifier by ${whereFound.tree}"
+ if (prec == wildImport || prec == namedImport) i"imported$qualifier by ${whereFound.importInfo}"
else i"defined$qualifier in ${whereFound.owner}"
/** Check that any previously found result from an inner context
@@ -254,10 +254,11 @@ class Typer extends Namer with Applications with Implicits {
tree.pos)
found
}
+ val Name = name.toTermName
selectors match {
- case Pair(Ident(from), Ident(`name`)) :: rest =>
+ case Pair(Ident(from), Ident(Name)) :: rest =>
checkUnambiguous(selectionType(site, name, tree.pos))
- case Ident(`name`) :: rest =>
+ case Ident(Name) :: rest =>
checkUnambiguous(selectionType(site, name, tree.pos))
case _ :: rest =>
namedImportRef(site, rest)
@@ -305,6 +306,7 @@ class Typer extends Namer with Applications with Implicits {
}
}
val curImport = ctx.importInfo
+ if (curImport != null && curImport.rootImport && previous.exists) return previous
if (prevPrec < namedImport && (curImport ne outer.importInfo)) {
val namedImp = namedImportRef(curImport.site, curImport.selectors)
if (namedImp.exists)
@@ -1033,23 +1035,24 @@ class Typer extends Namer with Applications with Implicits {
err.typeMismatch(tree, pt)
}
- tree.tpe.widen match {
- case ref: TermRef =>
- adaptOverloaded(ref)
- case poly: PolyType =>
- if (pt.isInstanceOf[PolyProtoType]) tree
- else {
- val tracked = ctx.track(poly)
- val tvars = ctx.newTypeVars(tracked, tree.pos)
- adapt(tpd.TypeApply(tree, tvars map (tpd.TypeTree(_))), pt)
- }
- case NoType if tree.isInstanceOf[WithoutType[_]] =>
- tree
- case tp =>
- pt match {
- case pt: FunProtoType => adaptToArgs(tp, pt)
- case _ => adaptNoArgs(tp)
- }
+ tree match {
+ case _: MemberDef | _: PackageDef | _: Import | _: WithoutType[_] => tree
+ case _ => tree.tpe.widen match {
+ case ref: TermRef =>
+ adaptOverloaded(ref)
+ case poly: PolyType =>
+ if (pt.isInstanceOf[PolyProtoType]) tree
+ else {
+ val tracked = ctx.track(poly)
+ val tvars = ctx.newTypeVars(tracked, tree.pos)
+ adapt(tpd.TypeApply(tree, tvars map (tpd.TypeTree(_))), pt)
+ }
+ case tp =>
+ pt match {
+ case pt: FunProtoType => adaptToArgs(tp, pt)
+ case _ => adaptNoArgs(tp)
+ }
+ }
}
}
} \ No newline at end of file