diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-07-18 11:29:44 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-08-19 09:26:40 +1000 |
commit | a56afcd6192ae69633df23137576505015d34992 (patch) | |
tree | 7a1da49f51ae3ce4b723edfe1f29b06b8e2fd74f /test | |
parent | c141254b97a48e47ed7a6bfa08922671cc639081 (diff) | |
download | scala-a56afcd6192ae69633df23137576505015d34992.tar.gz scala-a56afcd6192ae69633df23137576505015d34992.tar.bz2 scala-a56afcd6192ae69633df23137576505015d34992.zip |
Type#contains should peer into RefinementTypeRef-s
Usually, `contains` should not look into class symbol infos.
For instance, we expect that:
```
scala> trait C { def foo: Int }; typeOf[C].contains(IntClass)
defined trait C
res1: Boolean = false
```
We do, however, look at the decls of a `RefinedType` in contains:
```
scala> typeOf[{ def foo: Int }].contains(IntClass)
res2: Boolean = true
```
Things get a little vague, however, when we consider a type ref
to the refinement class symbol of a refined type.
```
scala> TypeRef(NoPrefix, typeOf[{ def foo: Int }].typeSymbol, Nil)
res3: $r.intp.global.Type = AnyRef{def foo: Int}
scala> .contains(IntClass)
res4: Boolean = false
```
These show up in the first element of the base type seq of a refined
type, e.g:
```
scala> typeOf[{ def foo: Int }].typeSymbol.tpe_*
res5: $r.intp.global.Type = AnyRef{def foo: Int}
scala> typeOf[{ def foo: Int }].baseTypeSeq(0).getClass
res7: Class[_ <: $r.intp.global.Type] = class scala.reflect.internal.Types$RefinementTypeRef
scala> typeOf[{ def foo: Int }].typeSymbol.tpe_*.getClass
res6: Class[_ <: $r.intp.global.Type] = class scala.reflect.internal.Types$RefinementTypeRef
```
This commit takes the opinion that a `RefinementTypeRef` should be
transparent with respect to `contains`. This paves the way for fixing
the base type sequences of existential types over refinement types.
The implementation of `ContainsCollector` was already calling
`normalize`, which goes from `RefinementTypeRef` to `RefinedType`.
This commit maps over the result, which looks in the parents and
decls.
Diffstat (limited to 'test')
-rw-r--r-- | test/files/pos/typevar-in-prefix.scala | 9 | ||||
-rw-r--r-- | test/junit/scala/reflect/internal/TypesTest.scala | 11 |
2 files changed, 20 insertions, 0 deletions
diff --git a/test/files/pos/typevar-in-prefix.scala b/test/files/pos/typevar-in-prefix.scala new file mode 100644 index 0000000000..929648b789 --- /dev/null +++ b/test/files/pos/typevar-in-prefix.scala @@ -0,0 +1,9 @@ +trait Test1 { + abstract class Setting + def Bool: Setting + + class C[T <: Setting](val s: T) + val setting1 = null.asInstanceOf[_1.s.type forSome { val _1: C[Setting] }] + // the derived accessor for this val was not using an inferred type, as was + // the intention of the implementation in MethodSynthesis. +} diff --git a/test/junit/scala/reflect/internal/TypesTest.scala b/test/junit/scala/reflect/internal/TypesTest.scala index 05a77cfb47..45a4369396 100644 --- a/test/junit/scala/reflect/internal/TypesTest.scala +++ b/test/junit/scala/reflect/internal/TypesTest.scala @@ -58,4 +58,15 @@ class TypesTest { Assert.fail(xs.mkString("\n")) } } + + @Test + def testRefinementContains(): Unit = { + val refinement = typeOf[{def foo: Int}] + assert(refinement.isInstanceOf[RefinedType]) + assert(refinement.contains(IntClass)) + val elem0 = refinement.baseTypeSeq(0) + assert(elem0.isInstanceOf[RefinementTypeRef]) + assert(elem0.contains(IntClass)) + } + } |