removed contractiveness requirement for implicit methods
git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@14485 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
e1c6cfdb2b
commit
f6f9dcf544
|
@ -22,8 +22,8 @@ class Names {
|
|||
private final val HASH_SIZE = 0x8000
|
||||
private final val HASH_MASK = 0x7FFF
|
||||
private final val NAME_SIZE = 0x20000
|
||||
private final val MAX_LEN = 255 // for longer names use a partial MD5 hash
|
||||
private final val PREFIX_LEN = 128 // the length of the prefix to keep unhashed
|
||||
private final val MAX_LEN = 240 // for longer names use a partial MD5 hash
|
||||
private final val PREFIX_LEN = 100 // the length of the prefix to keep unhashed
|
||||
private final val SUFFIX_LEN = 64 // the length of the suffix to keep unhashed
|
||||
|
||||
final val nameDebug = false
|
||||
|
|
|
@ -810,9 +810,9 @@ trait Namers { self: Analyzer =>
|
|||
clazz.tpe
|
||||
|
||||
case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
|
||||
val result =
|
||||
newNamer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs);
|
||||
checkContractive(sym, result)
|
||||
//val result =
|
||||
newNamer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs)
|
||||
//checkContractive(sym, result)
|
||||
|
||||
case vdef @ ValDef(mods, _, tpt, rhs) =>
|
||||
val typer1 = typer.constrTyperIf(sym.hasFlag(PARAM | PRESUPER) && sym.owner.isConstructor)
|
||||
|
|
|
@ -134,6 +134,8 @@ trait Typers { self: Analyzer =>
|
|||
private def argMode(fun: Tree, mode: Int) =
|
||||
if (treeInfo.isSelfOrSuperConstrCall(fun)) mode | SCCmode else mode
|
||||
|
||||
private var pendingImplicits: List[Type] = List()
|
||||
|
||||
abstract class Typer(context0: Context) {
|
||||
import context0.unit
|
||||
|
||||
|
@ -3294,18 +3296,56 @@ trait Typers { self: Analyzer =>
|
|||
case _ => tp.isError
|
||||
}
|
||||
|
||||
private def dominates(dtor: Type, dted: Type): Boolean = {
|
||||
def simplify(tp: Type): Type = tp match {
|
||||
case RefinedType(parents, defs) => intersectionType(parents, tp.typeSymbol.owner)
|
||||
case AnnotatedType(attribs, tp, selfsym) => tp
|
||||
case _ => tp
|
||||
}
|
||||
def sum(xs: List[Int]) = (0 /: xs)(_ + _)
|
||||
def complexity(tp: Type): Int = tp match {
|
||||
case SingleType(pre, sym) => complexity(pre) + 1
|
||||
case TypeRef(pre, sym, args) => complexity(pre) + sum(args map complexity) + 1
|
||||
case TypeBounds(lo, hi) => complexity(lo) + complexity(hi)
|
||||
case ClassInfoType(parents, defs, clazz) => sum(parents map complexity) + 1
|
||||
case MethodType(paramtypes, result) => sum(paramtypes map complexity) + complexity(result) + 1
|
||||
case PolyType(tparams, result) => sum(tparams map (_.info) map complexity) + complexity(result) + 1
|
||||
case ExistentialType(tparams, result) => sum(tparams map (_.info) map complexity) + complexity(result) + 1
|
||||
case _ => 1
|
||||
}
|
||||
val dtor1 = simplify(dtor)
|
||||
val dted1 = simplify(dted)
|
||||
(dtor1.typeSymbol == dted1.typeSymbol) &&
|
||||
(dtor1 =:= dted1 || complexity(dtor1) > complexity(dted1))
|
||||
}
|
||||
|
||||
/** Try to construct a typed tree from given implicit info with given
|
||||
* expected type.
|
||||
*
|
||||
* @param pos Position for error reporting
|
||||
* @param info The given implicit info describing the implicit definition
|
||||
* @param pt The expected type
|
||||
* @param pt0 The unnormalized expected type
|
||||
* @param pt The normalized expected type
|
||||
* @param isLocal Is implicit definition visible without prefix?
|
||||
* @return A typed tree if the implicit info can be made to conform
|
||||
* to <code>pt</code>, EmptyTree otherwise.
|
||||
* @pre <code>info.tpe</code> does not contain an error
|
||||
*/
|
||||
private def typedImplicit(pos: Position, info: ImplicitInfo, pt0: Type, pt: Type, isLocal: Boolean): Tree = {
|
||||
private def typedImplicit(pos: Position, info: ImplicitInfo, pt0: Type, pt: Type, isLocal: Boolean): Tree =
|
||||
pendingImplicits find (dominates(pt, _)) match {
|
||||
case Some(pending) =>
|
||||
context.error(pos, "diverging implicit expansion for type "+pending)
|
||||
EmptyTree
|
||||
case None =>
|
||||
try {
|
||||
pendingImplicits = pt :: pendingImplicits
|
||||
typedImplicit0(pos, info, pt0, pt, isLocal)
|
||||
} finally {
|
||||
pendingImplicits = pendingImplicits.tail
|
||||
}
|
||||
}
|
||||
|
||||
private def typedImplicit0(pos: Position, info: ImplicitInfo, pt0: Type, pt: Type, isLocal: Boolean): Tree = {
|
||||
def isStable(tp: Type): Boolean = tp match {
|
||||
case TypeRef(pre, sym, _) => sym.isPackageClass || sym.isModuleClass && isStable(pre)
|
||||
case _ => tp.isStable
|
||||
|
|
|
@ -126,6 +126,14 @@ object Predef {
|
|||
def unapply[A, B, C](x: Tuple3[A, B, C]): Option[Tuple3[A, B, C]] = Some(x)
|
||||
}
|
||||
|
||||
class Ensuring[A](x: A) {
|
||||
def ensuring(cond: Boolean): A = { assert(cond); x }
|
||||
def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x }
|
||||
def ensuring(cond: A => Boolean): A = { assert(cond(x)); x }
|
||||
def ensuring(cond: A => Boolean, msg: Any): A = { assert(cond(x), msg); x }
|
||||
}
|
||||
implicit def any2Ensuring[A](x: A): Ensuring[A] = new Ensuring(x)
|
||||
|
||||
class ArrowAssoc[A](x: A) {
|
||||
def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
|
||||
}
|
||||
|
@ -183,14 +191,6 @@ object Predef {
|
|||
|
||||
implicit def any2stringadd(x: Any) = new runtime.StringAdd(x)
|
||||
|
||||
class Ensuring[A](x: A) {
|
||||
def ensuring(cond: Boolean): A = { assert(cond); x }
|
||||
def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x }
|
||||
def ensuring(cond: A => Boolean): A = { assert(cond(x)); x }
|
||||
def ensuring(cond: A => Boolean, msg: Any): A = { assert(cond(x), msg); x }
|
||||
}
|
||||
implicit def any2Ensuring[A](x: A): Ensuring[A] = new Ensuring(x)
|
||||
|
||||
implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc)
|
||||
|
||||
implicit def unit2ordered(x: Unit): Ordered[Unit] = new Ordered[Unit] with Proxy {
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
bug696.scala:3: error: implicit method WithType is not contractive,
|
||||
because the implicit parameter type TypeUtil0.Type[S]
|
||||
is not strictly contained in the signature TypeUtil0.Type[S with T]
|
||||
implicit def WithType[S,T](implicit tpeS : Type[S], tpeT : Type[T]) : Type[S with T] = null
|
||||
^
|
||||
bug696.scala:4: error: no implicit argument matching parameter type TypeUtil0.Type[Any] was found.
|
||||
as[Any](null);
|
||||
^
|
||||
two errors found
|
||||
one error found
|
||||
|
|
Loading…
Reference in New Issue