Skip to content

Commit faa80de

Browse files
committed
Also include companions of prefixes in implicit scope
In that way, we include all of the implicit scope of Scala 2, except for package objects. The idea is that everything that is reasonable should be included in the implicit scope. Package objects were excluded since they had a dual purpose: 1. as a way to define implicits that are in scope for a whole project 2. as a prefix for implicits of all types coming out of that project It's often that one wants only (1) but then is surprised to also get (2). # Conflicts: # compiler/src/dotty/tools/dotc/typer/Implicits.scala # tests/pos/i9103.scala
1 parent 793ffd9 commit faa80de

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -500,13 +500,6 @@ trait ImplicitRunInfo:
500500
private var parts: mutable.LinkedHashSet[Type] = _
501501
private val partSeen = TypeHashSet()
502502

503-
def traversePrefix(pre: Type): Unit = pre match
504-
case pre: TermRef =>
505-
if migrateTo3 then traverse(pre.info)
506-
traversePrefix(pre.prefix)
507-
case _ =>
508-
traverse(pre)
509-
510503
def traverse(t: Type) =
511504
if partSeen.contains(t) then ()
512505
else if implicitScopeCache.contains(t) then parts += t
@@ -516,13 +509,13 @@ trait ImplicitRunInfo:
516509
case t: TypeRef =>
517510
if isAnchor(t.symbol) then
518511
parts += t
519-
traversePrefix(t.prefix)
512+
traverse(t.prefix)
520513
else
521514
traverse(t.underlying)
522515
case t: TermRef =>
523516
if !isExcluded(t.symbol) then
524517
traverse(t.info)
525-
traversePrefix(t.prefix)
518+
traverse(t.prefix)
526519
case t: ThisType if t.cls.is(Module) && t.cls.isStaticOwner =>
527520
traverse(t.cls.sourceModule.termRef)
528521
case t: ConstantType =>

tests/pos/i9103.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
object a:
2+
type Foo[T]
3+
given as Foo[Unit] = ???
4+
5+
val b = a
6+
7+
def test1 = summon[b.Foo[Unit]] // no ambiguity between b.given_Foo and a.given_Foo
8+
9+
val n: Long = 1
10+
val total: BigInt = 2
11+
val remainder = n % identity(total) // object BigInt is in implicit scope of `total.type`
12+
13+
trait Show[T] {def show(a: T): String}
14+
15+
object S extends LowPriorityInstances {
16+
class Permissions
17+
}
18+
19+
sealed trait LowPriorityInstances
20+
object LowPriorityInstances {
21+
given S.Permissions = ???
22+
given Show[S.Permissions] = _ => "perms"
23+
}
24+
25+
def test =
26+
println(implicitly[S.Permissions]) // companions of base classes of S are in implicit scope
27+
println(implicitly[Show[S.Permissions]])
28+

0 commit comments

Comments
 (0)