Skip to content

Commit 7546867

Browse files
committed
Skip caching provisional OrType atoms
Also, fix printing TypeVars when not using -Yprint-debug so that it doesn't add redudant and misleading parentheses, which can lead to the perception that a tuple was inferred.
1 parent 275cfa8 commit 7546867

File tree

5 files changed

+26
-19
lines changed

5 files changed

+26
-19
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

+16-12
Original file line numberDiff line numberDiff line change
@@ -3423,25 +3423,29 @@ object Types {
34233423
private var myAtoms: Atoms = _
34243424
private var myWidened: Type = _
34253425

3426+
private def computeAtoms()(using Context): Atoms =
3427+
if tp1.hasClassSymbol(defn.NothingClass) then tp2.atoms
3428+
else if tp2.hasClassSymbol(defn.NothingClass) then tp1.atoms
3429+
else tp1.atoms | tp2.atoms
3430+
3431+
private def computeWidenSingletons()(using Context): Type =
3432+
val tp1w = tp1.widenSingletons
3433+
val tp2w = tp2.widenSingletons
3434+
if ((tp1 eq tp1w) && (tp2 eq tp2w)) this else TypeComparer.lub(tp1w, tp2w, isSoft = isSoft)
3435+
34263436
private def ensureAtomsComputed()(using Context): Unit =
3427-
if atomsRunId != ctx.runId then
3428-
myAtoms =
3429-
if tp1.hasClassSymbol(defn.NothingClass) then tp2.atoms
3430-
else if tp2.hasClassSymbol(defn.NothingClass) then tp1.atoms
3431-
else tp1.atoms | tp2.atoms
3432-
val tp1w = tp1.widenSingletons
3433-
val tp2w = tp2.widenSingletons
3434-
myWidened = if ((tp1 eq tp1w) && (tp2 eq tp2w)) this else TypeComparer.lub(tp1w, tp2w, isSoft = isSoft)
3437+
if atomsRunId != ctx.runId && !isProvisional then
3438+
myAtoms = computeAtoms()
3439+
myWidened = computeWidenSingletons()
34353440
atomsRunId = ctx.runId
34363441

34373442
override def atoms(using Context): Atoms =
34383443
ensureAtomsComputed()
3439-
myAtoms
3444+
if isProvisional then computeAtoms() else myAtoms
34403445

3441-
override def widenSingletons(using Context): Type = {
3446+
override def widenSingletons(using Context): Type =
34423447
ensureAtomsComputed()
3443-
myWidened
3444-
}
3448+
if isProvisional then computeWidenSingletons() else myWidened
34453449

34463450
def derivedOrType(tp1: Type, tp2: Type, soft: Boolean = isSoft)(using Context): Type =
34473451
if ((tp1 eq this.tp1) && (tp2 eq this.tp2) && soft == isSoft) this

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -258,16 +258,17 @@ class PlainPrinter(_ctx: Context) extends Printer {
258258
if annot.symbol == defn.InlineParamAnnot || annot.symbol == defn.ErasedParamAnnot then toText(tpe)
259259
else toTextLocal(tpe) ~ " " ~ toText(annot)
260260
case tp: TypeVar =>
261+
def toTextCaret(tp: Type) = if printDebug then toTextLocal(tp) ~ Str("^") else toText(tp)
261262
if (tp.isInstantiated)
262-
toTextLocal(tp.instanceOpt) ~ (Str("^") provided printDebug)
263+
toTextCaret(tp.instanceOpt)
263264
else {
264265
val constr = ctx.typerState.constraint
265266
val bounds =
266267
if constr.contains(tp) then
267268
withMode(Mode.Printing)(TypeComparer.fullBounds(tp.origin))
268269
else
269270
TypeBounds.empty
270-
if (bounds.isTypeAlias) toText(bounds.lo) ~ (Str("^") provided printDebug)
271+
if (bounds.isTypeAlias) toTextCaret(bounds.lo)
271272
else if (ctx.settings.YshowVarBounds.value) "(" ~ toText(tp.origin) ~ "?" ~ toText(bounds) ~ ")"
272273
else toText(tp.origin)
273274
}

compiler/src/dotty/tools/dotc/printing/Printer.scala

+2-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ abstract class Printer {
3131
* ### `atPrec` vs `changePrec`
3232
*
3333
* This is to be used when changing precedence inside some sort of parentheses:
34-
* for instance, to print T[A]` use
34+
* for instance, to print `T[A]` use
3535
* `toText(T) ~ '[' ~ atPrec(GlobalPrec) { toText(A) } ~ ']'`.
3636
*
3737
* If the presence of the parentheses depends on precedence, inserting them manually is most certainly a bug.
@@ -60,8 +60,7 @@ abstract class Printer {
6060
* A op B op' C parses as (A op B) op' C if op and op' are left-associative, and as
6161
* A op (B op' C) if they're right-associative, so we need respectively
6262
* ```scala
63-
* val isType = ??? // is this a term or type operator?
64-
* val prec = parsing.precedence(op, isType)
63+
* val prec = parsing.precedence(op)
6564
* // either:
6665
* changePrec(prec) { toText(a) ~ op ~ atPrec(prec + 1) { toText(b) } } // for left-associative op and op'
6766
* // or:

tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:16:61 ----------------------------
1010
16 | val c = js.constructorTag[NativeJSClass with NativeJSTrait] // error
1111
| ^
12-
| (NativeJSClass & NativeJSTrait) is not a class type
12+
| NativeJSClass & NativeJSTrait is not a class type
1313
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:17:59 ----------------------------
1414
17 | val d = js.constructorTag[NativeJSClass { def bar: Int }] // error
1515
| ^
@@ -25,7 +25,7 @@
2525
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:22:49 ----------------------------
2626
22 | val g = js.constructorTag[JSClass with JSTrait] // error
2727
| ^
28-
| (JSClass & JSTrait) is not a class type
28+
| JSClass & JSTrait is not a class type
2929
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:23:53 ----------------------------
3030
23 | val h = js.constructorTag[JSClass { def bar: Int }] // error
3131
| ^

tests/pos/i15813.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Box[T]
2+
def dep1[T1 <: Singleton, T2 <: T1](t1: T1)(t2: T2): Box[T1] = ???
3+
val d1 = dep1(1)(2)

0 commit comments

Comments
 (0)