File tree 4 files changed +45
-6
lines changed
compiler/src/dotty/tools/dotc
4 files changed +45
-6
lines changed Original file line number Diff line number Diff line change @@ -703,6 +703,16 @@ object Types {
703
703
}
704
704
findMember(name, pre, required, excluded)
705
705
}
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
706
716
707
717
/** Find member of this type with given `name`, all `required`
708
718
* flags and no `excluded` flag and produce a denotation that contains
@@ -1006,7 +1016,7 @@ object Types {
1006
1016
final def implicitMembers (using Context ): List [TermRef ] = {
1007
1017
record(" implicitMembers" )
1008
1018
memberDenots(implicitFilter,
1009
- (name, buf) => buf ++= member (name).altsWith(_.isOneOf( GivenOrImplicitVal ) ))
1019
+ (name, buf) => buf ++= implicitMembersNamed (name))
1010
1020
.toList.map(d => TermRef (this , d.symbol.asTerm))
1011
1021
}
1012
1022
Original file line number Diff line number Diff line change @@ -148,7 +148,7 @@ class ImportInfo(symf: Context ?=> Symbol,
148
148
else
149
149
for
150
150
renamed <- reverseMapping.keys
151
- denot <- pre.member (reverseMapping(renamed).nn).altsWith(_.isOneOf( GivenOrImplicitVal ) )
151
+ denot <- pre.implicitMembersNamed (reverseMapping(renamed).nn)
152
152
yield
153
153
val original = reverseMapping(renamed).nn
154
154
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
288
288
case ImportType (expr) =>
289
289
val pre = expr.tpe
290
290
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)
292
295
// Pass refctx so that any errors are reported in the context of the
293
296
// reference instead of the context of the import scope
294
- if denot0 .exists then
297
+ if accessibleDenot .exists then
295
298
val denot =
296
299
if checkBounds then
297
- denot0 .filterWithPredicate { mbr =>
300
+ accessibleDenot .filterWithPredicate { mbr =>
298
301
mbr.matchesImportBound(if mbr.symbol.is(Given ) then imp.givenBound else imp.wildcardBound)
299
302
}
300
- else denot0
303
+ else accessibleDenot
301
304
def isScalaJsPseudoUnion =
302
305
denot.name == tpnme.raw.BAR && ctx.settings.scalajs.value && denot.symbol == JSDefinitions .jsdefn.PseudoUnionClass
303
306
// 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