File tree Expand file tree Collapse file tree 4 files changed +45
-6
lines changed
compiler/src/dotty/tools/dotc Expand file tree Collapse file tree 4 files changed +45
-6
lines changed Original file line number Diff line number Diff line change @@ -703,6 +703,16 @@ object Types {
703703 }
704704 findMember(name, pre, required, excluded)
705705 }
706+
707+ /** The implicit members with given name. If there are none and the denotation
708+ * contains private members, also look for shadowed non-private implicits.
709+ */
710+ def implicitMembersNamed (name : Name )(using Context ): List [SingleDenotation ] =
711+ val d = member(name)
712+ val alts = d.altsWith(_.isOneOf(GivenOrImplicitVal ))
713+ if alts.isEmpty && d.hasAltWith(_.symbol.is(Private )) then
714+ nonPrivateMember(name).altsWith(_.isOneOf(GivenOrImplicitVal ))
715+ else alts
706716
707717 /** Find member of this type with given `name`, all `required`
708718 * flags and no `excluded` flag and produce a denotation that contains
@@ -1006,7 +1016,7 @@ object Types {
10061016 final def implicitMembers (using Context ): List [TermRef ] = {
10071017 record(" implicitMembers" )
10081018 memberDenots(implicitFilter,
1009- (name, buf) => buf ++= member (name).altsWith(_.isOneOf( GivenOrImplicitVal ) ))
1019+ (name, buf) => buf ++= implicitMembersNamed (name))
10101020 .toList.map(d => TermRef (this , d.symbol.asTerm))
10111021 }
10121022
Original file line number Diff line number Diff line change @@ -148,7 +148,7 @@ class ImportInfo(symf: Context ?=> Symbol,
148148 else
149149 for
150150 renamed <- reverseMapping.keys
151- denot <- pre.member (reverseMapping(renamed).nn).altsWith(_.isOneOf( GivenOrImplicitVal ) )
151+ denot <- pre.implicitMembersNamed (reverseMapping(renamed).nn)
152152 yield
153153 val original = reverseMapping(renamed).nn
154154 val ref = TermRef (pre, original, denot)
Original file line number Diff line number Diff line change @@ -288,16 +288,19 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
288288 case ImportType (expr) =>
289289 val pre = expr.tpe
290290 val denot0 = pre.memberBasedOnFlags(name, required, excluded)
291- .accessibleFrom(pre)(using refctx)
291+ var accessibleDenot = denot0.accessibleFrom(pre)(using refctx)
292+ if ! accessibleDenot.exists && denot0.hasAltWith(_.symbol.is(Private )) then
293+ accessibleDenot = pre.memberBasedOnFlags(name, required, excluded | Private )
294+ .accessibleFrom(pre)(using refctx)
292295 // Pass refctx so that any errors are reported in the context of the
293296 // reference instead of the context of the import scope
294- if denot0 .exists then
297+ if accessibleDenot .exists then
295298 val denot =
296299 if checkBounds then
297- denot0 .filterWithPredicate { mbr =>
300+ accessibleDenot .filterWithPredicate { mbr =>
298301 mbr.matchesImportBound(if mbr.symbol.is(Given ) then imp.givenBound else imp.wildcardBound)
299302 }
300- else denot0
303+ else accessibleDenot
301304 def isScalaJsPseudoUnion =
302305 denot.name == tpnme.raw.BAR && ctx.settings.scalajs.value && denot.symbol == JSDefinitions .jsdefn.PseudoUnionClass
303306 // Just like Scala2Unpickler reinterprets Scala.js pseudo-unions
Original file line number Diff line number Diff line change 1+ class Conf
2+
3+ class Bar (_conf : Conf ) {
4+ implicit val conf : Conf = _conf
5+ }
6+
7+ class Foo (conf : Conf ) extends Bar (conf)
8+ // class Foo(_conf: Conf) extends Bar(_conf)
9+ // using a different name fixes it
10+
11+ class Test {
12+ def test (foo : Foo ) = {
13+ import foo .*
14+ // implicit val conf: Conf = foo.conf
15+ // manually redefining it also fixes it
16+ assert(conf != null )
17+ assert(implicitly[Conf ] != null )
18+ }
19+ def test2 (foo : Foo ) = {
20+ import foo .conf
21+ // implicit val conf: Conf = foo.conf
22+ // manually redefining it also fixes it
23+ assert(conf != null )
24+ assert(implicitly[Conf ] != null )
25+ }
26+ }
You can’t perform that action at this time.
0 commit comments