From a01248f0f3713ee9cb57699833a3d31e04c259e7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 18 Nov 2022 08:40:47 +0100 Subject: [PATCH] Workaround `case x @ U() : T =>` This kind of patterns were disabled in #16150. Fixes #16367 --- .../pos-with-compiler-cc/dotc/core/Types.scala | 14 +++++++++----- .../dotc/typer/Typer.scala | 18 +++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/tests/pos-with-compiler-cc/dotc/core/Types.scala b/tests/pos-with-compiler-cc/dotc/core/Types.scala index 967f4e2bc370..2e806492ad67 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Types.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Types.scala @@ -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 diff --git a/tests/pos-with-compiler-cc/dotc/typer/Typer.scala b/tests/pos-with-compiler-cc/dotc/typer/Typer.scala index 25776c07c8a0..9e0f8edebe4e 100644 --- a/tests/pos-with-compiler-cc/dotc/typer/Typer.scala +++ b/tests/pos-with-compiler-cc/dotc/typer/Typer.scala @@ -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