diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2011-06-15 16:32:38 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2011-06-15 16:32:38 +0000 |
commit | 8b66af0cfe29ab6026215e44f4d4b148316c159d (patch) | |
tree | be5eddd59b29dbda48ce2c151ba4d2d59a882960 | |
parent | 0cebb74f673de59c357c5284935db0cfc69bbe40 (diff) | |
download | scala-8b66af0cfe29ab6026215e44f4d4b148316c159d.tar.gz scala-8b66af0cfe29ab6026215e44f4d4b148316c159d.tar.bz2 scala-8b66af0cfe29ab6026215e44f4d4b148316c159d.zip |
closes #4692: unification in type constructor i...
closes #4692: unification in type constructor inference now widens *and*
dealiases when necessary
in 2.8.1 implicit conversion search started with a widened type, so that
combo never came up
no review
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 5 | ||||
-rw-r--r-- | test/files/pos/t4692.scala | 27 |
2 files changed, 30 insertions, 2 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 3264c34d4b..cc5c2fa5c1 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -2484,8 +2484,9 @@ A type's typeSymbol should never be inspected directly. // this <: tp.baseType(sym) if (suspended) checkSubtype(tp, origin) else if (constr.instValid) checkSubtype(tp, constr.inst) // type var is already set - else isRelatable(tp) && { - unifySimple || unifyFull(tp) || unifyFull(tp.dealias) || unifyFull(tp.widen) || unifyParents + else isRelatable(tp) && { // gradually let go of some type precision in hopes of finding a type that has the same shape as the type variable + // okay, this just screams "CLEAN ME UP" -- I think we could use tp.widen instead of tp straight from the get-go in registerBound, since we don't infer singleton types anyway (but maybe that'll change?) + unifySimple || unifyFull(tp) || unifyFull(tp.dealias) || unifyFull(tp.widen) || unifyFull(tp.widen.dealias) || unifyParents } } diff --git a/test/files/pos/t4692.scala b/test/files/pos/t4692.scala new file mode 100644 index 0000000000..409daf2257 --- /dev/null +++ b/test/files/pos/t4692.scala @@ -0,0 +1,27 @@ +class TypeAliasVsImplicitTest { + + class For[m[_], a](x: m[a]) { + def map[b](y: a => b): m[b] = throw new Error + } + implicit def toFor[m[_], a](x: m[a]): For[m, a] = new For[m, a](x) + + trait MyList[A] + + def foo(xs: MyList[Int]) = xs.map(x => x) // compiles fine. + + type MyListOfInt = MyList[Int] + def bar(xs: MyListOfInt) = xs.map(x => x) // doesn't compile: value map is not a member of TypeAliasVsImplicitTest.this.MyListOfInt +} + +// minimal case -- the bug was in type constructor inference where `xs.type` needed to be widened *and* dealiased +// in 2.8.1 implicit conversion search started with a widened type, so that combo never came up +// object Test { +// class For[m[_], a](x: m[a]) +// def toFor[m[_], a](x: m[a]): For[m, a] = new For[m, a](x) +// +// trait MyList[A] +// type MyListOfInt = MyList[Int] +// +// val xs: MyListOfInt = error("") +// toFor(xs : xs.type) +// }
\ No newline at end of file |