diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-10-13 16:48:33 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-10-13 16:48:33 +0000 |
commit | 15f4e9fc9bab8a7d4e2240dd2eb47d4f63c63c04 (patch) | |
tree | ed3c7c4c5c21a3c7694f1da1261462e90e615641 /src | |
parent | 0e7b7a50c6dab3097608bf477d89e13c4332a602 (diff) | |
download | scala-15f4e9fc9bab8a7d4e2240dd2eb47d4f63c63c04.tar.gz scala-15f4e9fc9bab8a7d4e2240dd2eb47d4f63c63c04.tar.bz2 scala-15f4e9fc9bab8a7d4e2240dd2eb47d4f63c63c04.zip |
closes #3862.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 2 |
2 files changed, 9 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index f4f0d1e4a7..d4063746a2 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -2373,15 +2373,20 @@ A type's typeSymbol should never be inspected directly. addBound(tp) true } else { // higher-kinded type var with same arity as tp + // needed because HK unification is limited to constraints of the shape TC1[T1,..., TN] <: TC2[T'1,...,T'N], which precludes e.g., Nothing <: ?TC[?T] + def isKindPolymorphic(tp: Type) = tp.typeSymbol == NothingClass || tp.typeSymbol == AnyClass + // TODO: fancier unification, maybe rewrite constraint as follows? + // val sym = constr.hiBounds map {_.typeSymbol} find { _.typeParams.length == typeArgs.length} + // this <: tp.baseType(sym) def unifyHK(tp: Type) = - (typeArgs.length == tp.typeArgs.length) && { + (typeArgs.length == tp.typeArgs.length || isKindPolymorphic(tp)) && { // register type constructor (the type without its type arguments) as bound addBound(tp.typeConstructor) // check subtyping of higher-order type vars // use variances as defined in the type parameter that we're trying to infer (the result is sanity-checked later) - checkArgs(tp.typeArgs, typeArgs, params) + isKindPolymorphic(tp) || checkArgs(tp.typeArgs, typeArgs, params) } - unifyHK(tp) || unifyHK(tp.dealias) + unifyHK(tp) || unifyHK(tp.dealias) } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 4d0cc0c041..70df60cc55 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -886,7 +886,7 @@ self: Analyzer => case TypeRef(_, tsym, _) if (tsym.isAbstractType) => implicitManifestOrOfExpectedType(pt.bounds.lo) case _ => - searchImplicit(implicitsOfExpectedType, false) + searchImplicit(implicitsOfExpectedType, false) // shouldn't we pass `pt` to `implicitsOfExpectedType`, or is the recursive case for an abstract type really only meant for manifests? } /** The result of the implicit search: |