Skip to content

Commit

Permalink
Workaround case x @ U() : T => (fix main branch) (#16369)
Browse files Browse the repository at this point in the history
This kind of patterns were disabled in #16150.

Fixes #16367
  • Loading branch information
nicolasstucki authored Nov 18, 2022
2 parents a1729b0 + a01248f commit 298ff3f
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
14 changes: 9 additions & 5 deletions tests/pos-with-compiler-cc/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1289,11 +1289,15 @@ object Types {
* then the top-level union isn't widened. This is needed so that type inference can infer nullable types.
*/
def widenUnion(using Context): Type = widen match
case tp @ OrNull(tp1): OrType =>
// Don't widen `T|Null`, since otherwise we wouldn't be able to infer nullable unions.
val tp1Widen = tp1.widenUnionWithoutNull
if (tp1Widen.isRef(defn.AnyClass)) tp1Widen
else tp.derivedOrType(tp1Widen, defn.NullType)
case tp @ OrNull(tp1) =>
tp match
case tp: OrType =>
// Don't widen `T|Null`, since otherwise we wouldn't be able to infer nullable unions.
val tp1Widen = tp1.widenUnionWithoutNull
if (tp1Widen.isRef(defn.AnyClass)) tp1Widen
else tp.derivedOrType(tp1Widen, defn.NullType)
case _ =>
tp.widenUnionWithoutNull
case tp =>
tp.widenUnionWithoutNull

Expand Down
18 changes: 11 additions & 7 deletions tests/pos-with-compiler-cc/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -477,13 +477,17 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
* (x: T | Null) => x.$asInstanceOf$[x.type & T]
*/
def toNotNullTermRef(tree: Tree, pt: Type)(using Context): Tree = tree.tpe match
case ref @ OrNull(tpnn) : TermRef
if pt != AssignProto && // Ensure it is not the lhs of Assign
ctx.notNullInfos.impliesNotNull(ref) &&
// If a reference is in the context, it is already trackable at the point we add it.
// Hence, we don't use isTracked in the next line, because checking use out of order is enough.
!ref.usedOutOfOrder =>
tree.cast(AndType(ref, tpnn))
case tp @ OrNull(tpnn) =>
tp match
case ref: TermRef
if pt != AssignProto && // Ensure it is not the lhs of Assign
ctx.notNullInfos.impliesNotNull(ref) &&
// If a reference is in the context, it is already trackable at the point we add it.
// Hence, we don't use isTracked in the next line, because checking use out of order is enough.
!ref.usedOutOfOrder =>
tree.cast(AndType(ref, tpnn))
case _ =>
tree
case _ =>
tree

Expand Down

0 comments on commit 298ff3f

Please sign in to comment.