Skip to content

Skip caching provisional OrType atoms #16295

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3423,25 +3423,29 @@ object Types {
private var myAtoms: Atoms = _
private var myWidened: Type = _

private def computeAtoms()(using Context): Atoms =
if tp1.hasClassSymbol(defn.NothingClass) then tp2.atoms
else if tp2.hasClassSymbol(defn.NothingClass) then tp1.atoms
else tp1.atoms | tp2.atoms

private def computeWidenSingletons()(using Context): Type =
val tp1w = tp1.widenSingletons
val tp2w = tp2.widenSingletons
if ((tp1 eq tp1w) && (tp2 eq tp2w)) this else TypeComparer.lub(tp1w, tp2w, isSoft = isSoft)

private def ensureAtomsComputed()(using Context): Unit =
if atomsRunId != ctx.runId then
myAtoms =
if tp1.hasClassSymbol(defn.NothingClass) then tp2.atoms
else if tp2.hasClassSymbol(defn.NothingClass) then tp1.atoms
else tp1.atoms | tp2.atoms
val tp1w = tp1.widenSingletons
val tp2w = tp2.widenSingletons
myWidened = if ((tp1 eq tp1w) && (tp2 eq tp2w)) this else TypeComparer.lub(tp1w, tp2w, isSoft = isSoft)
if atomsRunId != ctx.runId && !isProvisional then
myAtoms = computeAtoms()
myWidened = computeWidenSingletons()
atomsRunId = ctx.runId

override def atoms(using Context): Atoms =
ensureAtomsComputed()
myAtoms
if isProvisional then computeAtoms() else myAtoms

override def widenSingletons(using Context): Type = {
override def widenSingletons(using Context): Type =
ensureAtomsComputed()
myWidened
}
if isProvisional then computeWidenSingletons() else myWidened

def derivedOrType(tp1: Type, tp2: Type, soft: Boolean = isSoft)(using Context): Type =
if ((tp1 eq this.tp1) && (tp2 eq this.tp2) && soft == isSoft) this
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -258,16 +258,17 @@ class PlainPrinter(_ctx: Context) extends Printer {
if annot.symbol == defn.InlineParamAnnot || annot.symbol == defn.ErasedParamAnnot then toText(tpe)
else toTextLocal(tpe) ~ " " ~ toText(annot)
case tp: TypeVar =>
def toTextCaret(tp: Type) = if printDebug then toTextLocal(tp) ~ Str("^") else toText(tp)
if (tp.isInstantiated)
toTextLocal(tp.instanceOpt) ~ (Str("^") provided printDebug)
toTextCaret(tp.instanceOpt)
else {
val constr = ctx.typerState.constraint
val bounds =
if constr.contains(tp) then
withMode(Mode.Printing)(TypeComparer.fullBounds(tp.origin))
else
TypeBounds.empty
if (bounds.isTypeAlias) toText(bounds.lo) ~ (Str("^") provided printDebug)
if (bounds.isTypeAlias) toTextCaret(bounds.lo)
else if (ctx.settings.YshowVarBounds.value) "(" ~ toText(tp.origin) ~ "?" ~ toText(bounds) ~ ")"
else toText(tp.origin)
}
Expand Down
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/printing/Printer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ abstract class Printer {
* ### `atPrec` vs `changePrec`
*
* This is to be used when changing precedence inside some sort of parentheses:
* for instance, to print T[A]` use
* for instance, to print `T[A]` use
* `toText(T) ~ '[' ~ atPrec(GlobalPrec) { toText(A) } ~ ']'`.
*
* If the presence of the parentheses depends on precedence, inserting them manually is most certainly a bug.
Expand Down Expand Up @@ -60,8 +60,7 @@ abstract class Printer {
* A op B op' C parses as (A op B) op' C if op and op' are left-associative, and as
* A op (B op' C) if they're right-associative, so we need respectively
* ```scala
* val isType = ??? // is this a term or type operator?
* val prec = parsing.precedence(op, isType)
* val prec = parsing.precedence(op)
* // either:
* changePrec(prec) { toText(a) ~ op ~ atPrec(prec + 1) { toText(b) } } // for left-associative op and op'
* // or:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:16:61 ----------------------------
16 | val c = js.constructorTag[NativeJSClass with NativeJSTrait] // error
| ^
| (NativeJSClass & NativeJSTrait) is not a class type
| NativeJSClass & NativeJSTrait is not a class type
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:17:59 ----------------------------
17 | val d = js.constructorTag[NativeJSClass { def bar: Int }] // error
| ^
Expand All @@ -25,7 +25,7 @@
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:22:49 ----------------------------
22 | val g = js.constructorTag[JSClass with JSTrait] // error
| ^
| (JSClass & JSTrait) is not a class type
| JSClass & JSTrait is not a class type
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:23:53 ----------------------------
23 | val h = js.constructorTag[JSClass { def bar: Int }] // error
| ^
Expand Down
3 changes: 3 additions & 0 deletions tests/pos/i15813.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Box[T]
def dep1[T1 <: Singleton, T2 <: T1](t1: T1)(t2: T2): Box[T1] = ???
val d1 = dep1(1)(2)