From 127a7679c105ed1ff18350978d3ddf81a5dd07fa Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 4 Feb 2014 21:48:37 +0100 Subject: SI-8129 Crack the case of the curiously incoherent Context - Typer is created with Context. - Typer creates an Inferencer with said Context. - Typer mutates Typer#context after each import statement - Typer mutates its current Context (e.g to disable implicits.) - Typer asks a question of Inferencer - Inferencer, looking at the old context, thinks that implicits are allowed - Inferencer saves implicit ambiguities into the wrong Context. Because of this bug, overload resolution in blocks or template bodies for applications that follow an import have been considering implicit coercions in the first try at static overload resolution, and, in the rare case that it encounters an ambigous implicit in the process, leaking an unpositioned ambiguout error. This commit ensures coherency between `typer.context` and `typer.infer.context` by making the latter delegate to the former. --- test/files/pos/t8219b.scala | 49 ++++++++++++++++++++++++++++++++++++++++++++ test/pending/pos/t8219.scala | 49 -------------------------------------------- 2 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 test/files/pos/t8219b.scala delete mode 100644 test/pending/pos/t8219.scala (limited to 'test') diff --git a/test/files/pos/t8219b.scala b/test/files/pos/t8219b.scala new file mode 100644 index 0000000000..d55d3139e1 --- /dev/null +++ b/test/files/pos/t8219b.scala @@ -0,0 +1,49 @@ +trait Equalizer[T] +trait Gen[A] + +class Broken { + implicit def const[T](x: T): Gen[T] = ??? + implicit def convertToEqualizer[T](left: T): Equalizer[T] = ??? + + def in(a: Any) = () + in { + import scala.None // any import will do.. + "" == "" // no longer a problem, see pos/t8129.scala + } + + // We used to fall into the errant code path above when `Any#==` and `AnyRef#==` + // were overloaded. + // + // Real classes couldn't get away with that overloading; it would result in + // a compiler error because the variants would collapse into an overriding + // relationship after erasure. + // + // + // But, a structural type can! This triggers the same error, and served as + // a backstop for this test if we change the signatures of `AnyRef#==` to + // override `Any#==`. + type T = { + def a(a: AnyRef): Boolean + def a(a: Any): Boolean + } + + def t: T = ??? + + in { + import scala.None // any import will do.. + t.a("") + } + + // Or, we can get here with ambiguous implicits from the formal parameter + // type of the less specific overload to that of the more specific. + object T { + def foo(a: Any) = true + def foo(a: String) = true + } + in { + import scala.None + implicit def any2str1(a: Any) = "" + implicit def any2str2(a: Any) = "" + T.foo("") + } +} diff --git a/test/pending/pos/t8219.scala b/test/pending/pos/t8219.scala deleted file mode 100644 index d55d3139e1..0000000000 --- a/test/pending/pos/t8219.scala +++ /dev/null @@ -1,49 +0,0 @@ -trait Equalizer[T] -trait Gen[A] - -class Broken { - implicit def const[T](x: T): Gen[T] = ??? - implicit def convertToEqualizer[T](left: T): Equalizer[T] = ??? - - def in(a: Any) = () - in { - import scala.None // any import will do.. - "" == "" // no longer a problem, see pos/t8129.scala - } - - // We used to fall into the errant code path above when `Any#==` and `AnyRef#==` - // were overloaded. - // - // Real classes couldn't get away with that overloading; it would result in - // a compiler error because the variants would collapse into an overriding - // relationship after erasure. - // - // - // But, a structural type can! This triggers the same error, and served as - // a backstop for this test if we change the signatures of `AnyRef#==` to - // override `Any#==`. - type T = { - def a(a: AnyRef): Boolean - def a(a: Any): Boolean - } - - def t: T = ??? - - in { - import scala.None // any import will do.. - t.a("") - } - - // Or, we can get here with ambiguous implicits from the formal parameter - // type of the less specific overload to that of the more specific. - object T { - def foo(a: Any) = true - def foo(a: String) = true - } - in { - import scala.None - implicit def any2str1(a: Any) = "" - implicit def any2str2(a: Any) = "" - T.foo("") - } -} -- cgit v1.2.3