summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/files/neg/t5663-badwarneq.check22
-rw-r--r--test/files/neg/t5663-badwarneq.flags1
-rw-r--r--test/files/neg/t5663-badwarneq.scala76
-rw-r--r--test/files/neg/t5666.check37
-rw-r--r--test/files/neg/t5666.scala14
-rw-r--r--test/scaladoc/resources/implicits-base-res.scala68
-rw-r--r--test/scaladoc/resources/implicits-chaining-res.scala2
-rw-r--r--test/scaladoc/resources/implicits-elimination-res.scala7
-rw-r--r--test/scaladoc/resources/implicits-scopes-res.scala1
-rw-r--r--test/scaladoc/resources/implicits-shadowing-res.scala64
-rw-r--r--test/scaladoc/run/implicits-base.check (renamed from test/disabled/run/implicits-base.check)0
-rw-r--r--test/scaladoc/run/implicits-base.scala (renamed from test/disabled/run/implicits-base.scala)0
-rw-r--r--test/scaladoc/run/implicits-chaining.check (renamed from test/disabled/run/implicits-chaining.check)0
-rw-r--r--test/scaladoc/run/implicits-chaining.scala (renamed from test/disabled/run/implicits-chaining.scala)0
-rw-r--r--test/scaladoc/run/implicits-elimination.check (renamed from test/disabled/run/implicits-elimination.check)0
-rw-r--r--test/scaladoc/run/implicits-elimination.scala (renamed from test/disabled/run/implicits-elimination.scala)0
-rw-r--r--test/scaladoc/run/implicits-scopes.check (renamed from test/disabled/run/implicits-scopes.check)0
-rw-r--r--test/scaladoc/run/implicits-scopes.scala (renamed from test/disabled/run/implicits-scopes.scala)0
-rw-r--r--test/scaladoc/run/implicits-shadowing.check1
-rw-r--r--test/scaladoc/run/implicits-shadowing.scala70
20 files changed, 330 insertions, 33 deletions
diff --git a/test/files/neg/t5663-badwarneq.check b/test/files/neg/t5663-badwarneq.check
new file mode 100644
index 0000000000..00c2234e9d
--- /dev/null
+++ b/test/files/neg/t5663-badwarneq.check
@@ -0,0 +1,22 @@
+t5663-badwarneq.scala:42: error: comparing case class values of types Some[Int] and None.type using `==' will always yield false
+ println(new Some(1) == None) // Should complain on type, was: spuriously complains on fresh object
+ ^
+t5663-badwarneq.scala:43: error: comparing case class values of types Some[Int] and Thing using `==' will always yield false
+ println(Some(1) == new Thing(1)) // Should complain on type, was: spuriously complains on fresh object
+ ^
+t5663-badwarneq.scala:51: error: ThingOne and Thingy are unrelated: they will most likely never compare equal
+ println(t1 == t2) // true, but apparently unrelated, a compromise warning
+ ^
+t5663-badwarneq.scala:52: error: ThingThree and Thingy are unrelated: they will most likely never compare equal
+ println(t4 == t2) // true, complains because ThingThree is final and Thingy not a subclass, stronger claim than unrelated
+ ^
+t5663-badwarneq.scala:55: error: comparing case class values of types ThingTwo and Some[Int] using `==' will always yield false
+ println(t3 == Some(1)) // false, warn on different cases
+ ^
+t5663-badwarneq.scala:56: error: comparing values of types ThingOne and Cousin using `==' will always yield false
+ println(t1 == c) // should warn
+ ^
+t5663-badwarneq.scala:64: error: comparing case class values of types Simple and SimpleSibling.type using `==' will always yield false
+ println(new Simple() == SimpleSibling) // like Some(1) == None, but needn't be final case
+ ^
+7 errors found
diff --git a/test/files/neg/t5663-badwarneq.flags b/test/files/neg/t5663-badwarneq.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/t5663-badwarneq.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/t5663-badwarneq.scala b/test/files/neg/t5663-badwarneq.scala
new file mode 100644
index 0000000000..56ec389c03
--- /dev/null
+++ b/test/files/neg/t5663-badwarneq.scala
@@ -0,0 +1,76 @@
+
+// alias
+trait Thingy
+
+class Gramps
+
+// sibling classes that extend a case class
+case class Thing(i: Int) extends Gramps
+class ThingOne(x:Int) extends Thing(x)
+class ThingTwo(y:Int) extends Thing(y) with Thingy
+final class ThingThree(z:Int) extends Thing(z)
+
+// not case cousin
+class Cousin extends Gramps
+
+class SimpleParent
+case class Simple() extends SimpleParent
+case object SimpleSibling extends SimpleParent
+
+/* It's not possible to run partest without -deprecation.
+ * Since detecting the warnings requires a neg test with
+ * -Xfatal-warnings, and deprecation terminates the compile,
+ * we'll just comment out the nasty part. The point was
+ * just to show there's nothing special about a trait
+ * that extends a case class, which is only permitted
+ * (deprecatingly) by omitting the parens.
+ *
+// common ancestor is something else
+class AnyThing
+case class SomeThing extends AnyThing // deprecation
+class OtherThing extends AnyThing
+
+// how you inherit caseness doesn't matter
+trait InThing extends SomeThing
+class MyThing extends InThing
+*/
+
+object Test {
+ def main(a: Array[String]) {
+ // nothing to do with Gavin
+ println(new Some(1) == new Some(1)) // OK, true
+ println(new Some(1) == None) // Should complain on type, was: spuriously complains on fresh object
+ println(Some(1) == new Thing(1)) // Should complain on type, was: spuriously complains on fresh object
+
+ val t1 = new ThingOne(11)
+ val t2: Thingy = new ThingTwo(11)
+ val t3 = new ThingTwo(11)
+ val t4 = new ThingThree(11)
+ val c = new Cousin
+
+ println(t1 == t2) // true, but apparently unrelated, a compromise warning
+ println(t4 == t2) // true, complains because ThingThree is final and Thingy not a subclass, stronger claim than unrelated
+ println(t2 == t3) // OK, two Thingy
+ println(t3 == t2) // ditto with case receiver
+ println(t3 == Some(1)) // false, warn on different cases
+ println(t1 == c) // should warn
+
+ // don't warn on fresh cases
+ println(new ThingOne(11) == t1) // OK, was: two cases not warnable on trunk
+ println(new ThingTwo(11) == t2) // true, was: spuriously complains on fresh object
+ println(new ThingOne(11) == t3) // two cases not warnable on trunk
+ println(new ThingTwo(11) == t3) // ditto
+
+ println(new Simple() == SimpleSibling) // like Some(1) == None, but needn't be final case
+
+ /*
+ val mine = new MyThing
+ val some = new SomeThing
+ val other = new OtherThing
+ println(mine == some) // OK, two Something
+ println(some == mine)
+ println(mine == other) // OK, two Anything?
+ println(mine == t1) // false
+ */
+ }
+}
diff --git a/test/files/neg/t5666.check b/test/files/neg/t5666.check
new file mode 100644
index 0000000000..1be51d0138
--- /dev/null
+++ b/test/files/neg/t5666.check
@@ -0,0 +1,37 @@
+t5666.scala:2: error: class Any is abstract; cannot be instantiated
+ new Any
+ ^
+t5666.scala:3: error: trait AnyVal is abstract; cannot be instantiated
+ new AnyVal
+ ^
+t5666.scala:4: error: Double does not have a constructor
+ new Double
+ ^
+t5666.scala:5: error: Float does not have a constructor
+ new Float
+ ^
+t5666.scala:6: error: Long does not have a constructor
+ new Long
+ ^
+t5666.scala:7: error: Int does not have a constructor
+ new Int
+ ^
+t5666.scala:8: error: Char does not have a constructor
+ new Char
+ ^
+t5666.scala:9: error: Short does not have a constructor
+ new Short
+ ^
+t5666.scala:10: error: Byte does not have a constructor
+ new Byte
+ ^
+t5666.scala:11: error: Boolean does not have a constructor
+ new Boolean
+ ^
+t5666.scala:12: error: Unit does not have a constructor
+ new Unit
+ ^
+t5666.scala:13: error: trait Nothing is abstract; cannot be instantiated
+ new Nothing
+ ^
+12 errors found
diff --git a/test/files/neg/t5666.scala b/test/files/neg/t5666.scala
new file mode 100644
index 0000000000..ffaeaacdaf
--- /dev/null
+++ b/test/files/neg/t5666.scala
@@ -0,0 +1,14 @@
+object t5666 {
+ new Any
+ new AnyVal
+ new Double
+ new Float
+ new Long
+ new Int
+ new Char
+ new Short
+ new Byte
+ new Boolean
+ new Unit
+ new Nothing
+} \ No newline at end of file
diff --git a/test/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala
index db7ca4fa51..3e3d0f01a6 100644
--- a/test/scaladoc/resources/implicits-base-res.scala
+++ b/test/scaladoc/resources/implicits-base-res.scala
@@ -11,23 +11,27 @@ trait MyNumeric[R]
* - tests the complete type inference
* - the following inherited methods should appear:
* {{{
- * def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double
- * def convToIntA: Int // pimpA2: with a constraint that T = Int
- * def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double
- * def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope
- * def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope
- * def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints
- * def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar
- * def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double
- * // should not be abstract!
+ * def convToGtColonDoubleA(x: Double) // pimpA3: with a constraint that T <: Double
+ * def convToIntA(x: Int) // pimpA2: with a constraint that T = Int
+ * def convToManifestA(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double
+ * def convToMyNumericA(x: T) // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope
+ * def convToNumericA(x: T) // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope
+ * def convToPimpedA(x: Bar[Foo[T]]) // pimpA5: no constraints
+ * def convToPimpedA(x: S) // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar
+ * def convToTraversableOps(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double
+ * // should not be abstract!
* }}}
*/
class A[T] {
/** This should prevent the implicitly inherited `def convToPimpedA: T` from `pimpA0` from showing up */
- def convToPimpedA: T = sys.error("Let's check it out!")
+ def convToPimpedA(x: T): T = sys.error("Let's check it out!")
+ /** This should check implicit member elimination in the case of subtyping */
+ def foo(a: T, b: AnyRef): T
}
/** Companion object with implicit transformations */
object A {
+ import language.implicitConversions // according to SIP18
+
implicit def pimpA0[V](a: A[V]) = new PimpedA(a)
implicit def pimpA1[ZBUR: Numeric](a: A[ZBUR]) = new NumericA[ZBUR](a)
implicit def pimpA2(a: A[Int]) = new IntA(a)
@@ -36,7 +40,7 @@ object A {
implicit def pimpA5[Z](a: A[Z]): PimpedA[Bar[Foo[Z]]] = sys.error("not implemented")
implicit def pimpA6[Z: MyNumeric](a: A[Z]) = new MyNumericA[Z](a)
// TODO: Add H <: Double and see why it crashes for C and D -- context bounds, need to check!
- implicit def pimpA7[H <: Double : Manifest](a: A[H]) = new ManifestA[H](a) with MyTraversableOps[H] { def convToTraversableOps: H = sys.error("no") }
+ implicit def pimpA7[H <: Double : Manifest](a: A[H]) = new ManifestA[H](a) with MyTraversableOps[H] { def convToTraversableOps(x: H): H = sys.error("no") }
}
@@ -44,13 +48,13 @@ object A {
* - tests the existential type solving
* - the following inherited methods should appear:
* {{{
- * def convToGtColonDoubleA: Double // pimpA3: no constraints
- * def convToManifestA: Double // pimpA7: no constraints
- * def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope
- * def convToNumericA: Double // pimpA1: no constraintsd
- * def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints
- * def convToTraversableOps: Double // pimpA7: no constraints
- * // should not be abstract!
+ * def convToGtColonDoubleA(x: Double) // pimpA3: no constraints
+ * def convToManifestA(x: Double) // pimpA7: no constraints
+ * def convToMyNumericA(x: Double) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope
+ * def convToNumericA(x: Double) // pimpA1: no constraintsd
+ * def convToPimpedA(x: Bar[Foo[Double]]) // pimpA5: no constraints
+ * def convToTraversableOps(x: Double) // pimpA7: no constraints
+ * // should not be abstract!
* }}}
*/
class B extends A[Double]
@@ -61,10 +65,10 @@ object B extends A
* - tests asSeenFrom
* - the following inherited methods should appear:
* {{{
- * def convToIntA: Int // pimpA2: no constraints
- * def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope
- * def convToNumericA: Int // pimpA1: no constraints
- * def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints
+ * def convToIntA(x: Int) // pimpA2: no constraints
+ * def convToMyNumericA(x: Int) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope
+ * def convToNumericA(x: Int) // pimpA1: no constraints
+ * def convToPimpedA(x: Bar[Foo[Int]]) // pimpA5: no constraints
* }}}
*/
class C extends A[Int]
@@ -75,9 +79,9 @@ object C extends A
* - tests implicit elimination
* - the following inherited methods should appear:
* {{{
- * def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope
- * def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope
- * def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints
+ * def convToMyNumericA(x: String) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope
+ * def convToNumericA(x: String) // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope
+ * def convToPimpedA(x: Bar[Foo[String]]) // pimpA5: no constraints
* }}}
*/
class D extends A[String]
@@ -90,7 +94,7 @@ object D extends A
* - A, B and C should be implicitly converted to this */
class PimpedA[V](a: A[V]) {
/** The convToPimpedA: V documentation... */
- def convToPimpedA: V = sys.error("Not implemented")
+ def convToPimpedA(x: V): V = sys.error("Not implemented")
}
/** NumericA class <br/>
@@ -98,7 +102,7 @@ class PimpedA[V](a: A[V]) {
* - A, B and C should be implicitly converted to this */
class NumericA[U: Numeric](a: A[U]) {
/** The convToNumericA: U documentation... */
- def convToNumericA: U = implicitly[Numeric[U]].zero
+ def convToNumericA(x: U): U = implicitly[Numeric[U]].zero
}
/** IntA class <br/>
@@ -106,7 +110,7 @@ class NumericA[U: Numeric](a: A[U]) {
* - A and C should be implicitly converted to this */
class IntA(a: A[Int]) {
/** The convToIntA: Int documentation... */
- def convToIntA: Int = 0
+ def convToIntA(x: Int): Int = 0
}
/** GtColonDoubleA class <br/>
@@ -114,7 +118,7 @@ class IntA(a: A[Int]) {
* - A and B should be implicitly converted to this */
class GtColonDoubleA(a: A[T] forSome { type T <: Double }) {
/** The convToGtColonDoubleA: Double documentation... */
- def convToGtColonDoubleA: Double = 0
+ def convToGtColonDoubleA(x: Double): Double = 0
}
/** MyNumericA class <br/>
@@ -122,7 +126,7 @@ class GtColonDoubleA(a: A[T] forSome { type T <: Double }) {
* - A should be implicitly converted to this */
class MyNumericA[U: MyNumeric](a: A[U]) {
/** The convToMyNumericA: U documentation... */
- def convToMyNumericA: U = sys.error("dunno")
+ def convToMyNumericA(x: U): U = sys.error("dunno")
}
/** ManifestA class <br/>
@@ -130,7 +134,7 @@ class MyNumericA[U: MyNumeric](a: A[U]) {
* - A, B, C, D should be implicitly converted to this */
class ManifestA[W: Manifest](a: A[W]) {
/** The convToManifestA: W documentation... */
- def convToManifestA: W = sys.error("dunno")
+ def convToManifestA(x: W): W = sys.error("dunno")
}
/** MyTraversableOps class <br/>
@@ -138,6 +142,6 @@ class ManifestA[W: Manifest](a: A[W]) {
*/
trait MyTraversableOps[S] {
/** The convToTraversableOps: S documentation... */
- def convToTraversableOps: S
+ def convToTraversableOps(x: S): S
}
diff --git a/test/scaladoc/resources/implicits-chaining-res.scala b/test/scaladoc/resources/implicits-chaining-res.scala
index b20c8f846c..c005d5fe09 100644
--- a/test/scaladoc/resources/implicits-chaining-res.scala
+++ b/test/scaladoc/resources/implicits-chaining-res.scala
@@ -3,6 +3,8 @@
*/
package scala.test.scaladoc.implicits {
+ import language.implicitConversions // according to SIP18
+
// the classes involved
case class Z[U](a: U)
case class Intermediate[T, U](t: T, u: U)
diff --git a/test/scaladoc/resources/implicits-elimination-res.scala b/test/scaladoc/resources/implicits-elimination-res.scala
index 68743aee06..b23667440c 100644
--- a/test/scaladoc/resources/implicits-elimination-res.scala
+++ b/test/scaladoc/resources/implicits-elimination-res.scala
@@ -2,8 +2,13 @@
* Testing scaladoc implicits elimination
*/
package scala.test.scaladoc.implicits.elimination {
+
+ import language.implicitConversions // according to SIP18
+
/** No conversion, as B doesn't bring any member */
class A
class B { class C; trait V; type T; }
- object A { implicit def toB(a: A): B = null }
+ object A {
+ implicit def toB(a: A): B = null
+ }
}
diff --git a/test/scaladoc/resources/implicits-scopes-res.scala b/test/scaladoc/resources/implicits-scopes-res.scala
index 4e55c3e388..aaeb43f95b 100644
--- a/test/scaladoc/resources/implicits-scopes-res.scala
+++ b/test/scaladoc/resources/implicits-scopes-res.scala
@@ -2,6 +2,7 @@
* Testing scaladoc implicit scopes - looking for implicits in the right places
*/
package scala.test.scaladoc.implicits.scopes
+import language.implicitConversions // according to SIP18
// TEST1 - In package object
package object test1 {
diff --git a/test/scaladoc/resources/implicits-shadowing-res.scala b/test/scaladoc/resources/implicits-shadowing-res.scala
new file mode 100644
index 0000000000..c5e9493bf3
--- /dev/null
+++ b/test/scaladoc/resources/implicits-shadowing-res.scala
@@ -0,0 +1,64 @@
+/**
+ * Test scaladoc implicits distinguishing -- supress all members by implicit conversion that are shadowed by the
+ * class' own members
+ *
+ * {{{
+ * scala> class A { def foo(t: String) = 4 }
+ * defined class A
+ *
+ * scala> class B { def foo(t: Any) = 5 }
+ * defined class B
+ *
+ * scala> implicit def AtoB(a:A) = new B
+ * AtoB: (a: A)B
+ *
+ * scala> val a = new A
+ * a: A = A@28f553e3
+ *
+ * scala> a.foo("T")
+ * res1: Int = 4
+ *
+ * scala> a.foo(4)
+ * res2: Int = 5
+ * }}}
+ */
+package scala.test.scaladoc.implicits.shadowing
+import language.implicitConversions // according to SIP18
+
+/** conv5, conv8, conv9, conv10, conv11 should be visible */
+class A[T] {
+ def conv1: AnyRef = ???
+ def conv2: T = ???
+ def conv3(l: Int): AnyRef = ???
+ def conv4(l: AnyRef): AnyRef = ???
+ def conv5(l: String): AnyRef = ???
+ def conv6(l: AnyRef): AnyRef = ???
+ def conv7(l: AnyRef): String = ???
+ def conv8(l: String)(m: String): AnyRef = ???
+ def conv9(l: AnyRef)(m: AnyRef): AnyRef = ???
+ def conv10(l: T): T = ???
+ def conv11(l: T): T = ???
+}
+/** conv5, conv8, conv9, conv11 should be visible */
+class B extends A[Int]
+/** conv5, conv8, conv9, conv10, conv11 should be visible */
+class C extends A[Double]
+/** conv5, conv8, conv9, conv10 should be visible */
+class D extends A[AnyRef]
+
+class Z[T] {
+ def conv1: AnyRef = ???
+ def conv2: T = ???
+ def conv3(p: Int): AnyRef = ???
+ def conv4(p: String): AnyRef = ???
+ def conv5(p: AnyRef): AnyRef = ???
+ def conv6(p: AnyRef): String = ???
+ def conv7(p: AnyRef): AnyRef = ???
+ def conv8(p: String, q: String): AnyRef = ???
+ def conv9(p: AnyRef, q: AnyRef): AnyRef = ???
+ def conv10(p: Int): T = ???
+ def conv11(p: String): T = ???
+}
+object A {
+ implicit def AtoZ[T](a: A[T]) = new Z[T]
+}
diff --git a/test/disabled/run/implicits-base.check b/test/scaladoc/run/implicits-base.check
index 619c56180b..619c56180b 100644
--- a/test/disabled/run/implicits-base.check
+++ b/test/scaladoc/run/implicits-base.check
diff --git a/test/disabled/run/implicits-base.scala b/test/scaladoc/run/implicits-base.scala
index 06d017ed70..06d017ed70 100644
--- a/test/disabled/run/implicits-base.scala
+++ b/test/scaladoc/run/implicits-base.scala
diff --git a/test/disabled/run/implicits-chaining.check b/test/scaladoc/run/implicits-chaining.check
index 619c56180b..619c56180b 100644
--- a/test/disabled/run/implicits-chaining.check
+++ b/test/scaladoc/run/implicits-chaining.check
diff --git a/test/disabled/run/implicits-chaining.scala b/test/scaladoc/run/implicits-chaining.scala
index 858ca9ce61..858ca9ce61 100644
--- a/test/disabled/run/implicits-chaining.scala
+++ b/test/scaladoc/run/implicits-chaining.scala
diff --git a/test/disabled/run/implicits-elimination.check b/test/scaladoc/run/implicits-elimination.check
index 619c56180b..619c56180b 100644
--- a/test/disabled/run/implicits-elimination.check
+++ b/test/scaladoc/run/implicits-elimination.check
diff --git a/test/disabled/run/implicits-elimination.scala b/test/scaladoc/run/implicits-elimination.scala
index ed37b9cd90..ed37b9cd90 100644
--- a/test/disabled/run/implicits-elimination.scala
+++ b/test/scaladoc/run/implicits-elimination.scala
diff --git a/test/disabled/run/implicits-scopes.check b/test/scaladoc/run/implicits-scopes.check
index 619c56180b..619c56180b 100644
--- a/test/disabled/run/implicits-scopes.check
+++ b/test/scaladoc/run/implicits-scopes.check
diff --git a/test/disabled/run/implicits-scopes.scala b/test/scaladoc/run/implicits-scopes.scala
index 7b9e80e148..7b9e80e148 100644
--- a/test/disabled/run/implicits-scopes.scala
+++ b/test/scaladoc/run/implicits-scopes.scala
diff --git a/test/scaladoc/run/implicits-shadowing.check b/test/scaladoc/run/implicits-shadowing.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/implicits-shadowing.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/implicits-shadowing.scala b/test/scaladoc/run/implicits-shadowing.scala
new file mode 100644
index 0000000000..7835223d21
--- /dev/null
+++ b/test/scaladoc/run/implicits-shadowing.scala
@@ -0,0 +1,70 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ // test a file instead of a piece of code
+ override def resourceFile = "implicits-shadowing-res.scala"
+
+ // start implicits
+ def scaladocSettings = "-implicits"
+
+ def testModel(root: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE:
+ val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("shadowing")
+ var conv: ImplicitConversion = null
+
+//// class A ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val A = base._class("A")
+
+ conv = A._conversion(base._object("A").qualifiedName + ".AtoZ")
+ assert(conv.members.length == 5)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv10")
+ conv._member("conv11")
+ assert(conv.constraints.length == 0)
+
+//// class B ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val B = base._class("B")
+
+ conv = B._conversion(base._object("A").qualifiedName + ".AtoZ")
+ assert(conv.members.length == 4)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv11")
+ assert(conv.constraints.length == 0)
+
+//// class C ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val C = base._class("C")
+
+ conv = C._conversion(base._object("A").qualifiedName + ".AtoZ")
+ assert(conv.members.length == 5)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv10")
+ conv._member("conv11")
+ assert(conv.constraints.length == 0)
+
+//// class D ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val D = base._class("D")
+
+ conv = D._conversion(base._object("A").qualifiedName + ".AtoZ")
+ assert(conv.members.length == 4)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv10")
+ assert(conv.constraints.length == 0)
+ }
+} \ No newline at end of file