Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ambiguous reference with imports #2133

Closed
scabug opened this issue Jul 7, 2009 · 12 comments
Closed

ambiguous reference with imports #2133

scabug opened this issue Jul 7, 2009 · 12 comments

Comments

@scabug
Copy link

scabug commented Jul 7, 2009

The following code should print out "1" but instead

class Foo {
  private val x = 0
}
object test extends Application {
  val x = 1;
  {
    val f = new Foo
    import f._
    println(x)
  }
}

produces the error

test.scala:9: error: reference to x is ambiguous;
it is both defined in object test and imported subsequently by
import f._
    println(x)
            ^
one error found

both with Scala 2.7.5 and trunk. The import f._ statement should not see the private member x in class Foo.

@scabug
Copy link
Author

scabug commented Jul 7, 2009

Imported From: https://issues.scala-lang.org/browse/SI-2133?orig=1
Reporter: @michelou
See #3160, #3836

@scabug
Copy link
Author

scabug commented Jul 8, 2009

@paulp said:
Weird, I just logged in to report this same bug. How could it exist for so long and then be reported by two people on the same day, I don't know.

It's even more problematic than illustrated above. Here is how I ran into it:

trait Foo {
  object bar {
    private[this] def fn() = 5
  }
}

trait Foo2 {
  object bip {
    def fn() = 10
  }
}

class Bob extends AnyRef with Foo with Foo2 {
  import bip._
  import bar._
  
  def go() = fn()
}

// a.scala:17: error: reference to fn is ambiguous;
// it is imported twice in the same scope by
// import bar._
// and import bip._
//   def go() = fn()
//              ^

It fails no matter what visibility restrictions one places on it - private, private[foo], private[this].

@scabug
Copy link
Author

scabug commented Oct 5, 2009

@paulp said:
I notice this bug has priority "high" and is assigned to "Oliver Wong", both of which seem so unlikely that I'm going to suppose a database burp was involved. So I'm reassigning to scala-reviewer so it doesn't get lost. Apologies if this really is a high priority ticket assigned to the mysterious O.W.

@scabug
Copy link
Author

scabug commented Jul 13, 2010

@odersky said:
Paul's variant compiles now. Stephane's original example is not covered by the spec, which says that all importable members are counted. A member is importable as long as it is not private[this]. Why this wording? Because an inner class might validly
import the private members of its companion object.

@scabug
Copy link
Author

scabug commented Mar 12, 2012

@Blaisorblade said:
The spec should only allow private members to be imported when it makes sense - i.e., when they are accessible.
I've hit the following variant of this bug:

scala> object Foo {
     | private def println(x: Any) {}
     | }
defined module Foo

scala> import Foo._
import Foo._

scala> println(1)
<console>:12: error: method println in object Foo cannot be accessed in object Foo
              println(1)
              ^

Getting compile errors from private members violates the principle of encapsulation: adding a private member to a class cannot be allowed to affect code where that member is not accessible.

@scabug
Copy link
Author

scabug commented Apr 3, 2012

@paulp said:
This drives me nuts. I can't believe adding a private method to a class can break a bunch of unrelated files which happen to reference the name. It's not theoretical, it has happened to me several times.

@scabug
Copy link
Author

scabug commented Apr 4, 2012

@Blaisorblade said:
The status of these bugs can only be understood by reading all these three discussions.
The link is already in the comments, but those bugs are not easily reachable from this.

@scabug
Copy link
Author

scabug commented Jul 11, 2012

@odersky said:
It is as speced, so not a compiler bug, but rather a language enhancement. I need some wording how to rewrite Chapter 3, also for accommodating the recent changes where we allow type aliases. If the wording is there it should be simple to add to the compiler.

@scabug
Copy link
Author

scabug commented Oct 5, 2012

Ryan Hendrickson (ryan.hendrickson_bwater) said:
If Paul's fix for this gets pulled in before the deprecated "def x"s on Ensuring[A] and ArrowAssoc[A] are removed, then it would be super-cool to make those defs private[Predef] so that members named x can be pimped onto things while still preserving binary compatibility (since private[scope] members get Java-public bytecode generated for them).

@scabug
Copy link
Author

scabug commented Oct 15, 2013

@gkossakowski said:
Unassigning and rescheduling to M7 as previous deadline was missed.

@scabug
Copy link
Author

scabug commented Apr 8, 2016

@lrytz said:
both examples in this ticket compile with Scala 2.11.8 and 2.12. I didn't do any bisect, so don't know what change fixed it.

@scabug
Copy link
Author

scabug commented Apr 8, 2016

@lrytz said:
another example that fails in 2.10, works in 2.11+

object Foo {
  def s = "foo"
}
object Bar {
  private def s = "bar"
}
object Test {
  import Foo._
  import Bar._
  println(s)
}

@scabug scabug closed this as completed Jun 23, 2016
@scabug scabug added this to the 2.11.0-RC1 milestone Apr 7, 2017
som-snytt added a commit to som-snytt/scala that referenced this issue Jul 1, 2017
Implementation was massaged to fix 2133, 3160, 3836
and related tickets around import ergonomics, but
the spec lagged.

This specifies importing multiple type aliases and
that importable requires accessible.

Fixes scala/bug#2133
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant