Skip to content

Fix #9321: Make not-null detection more robust #9443

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 3 commits into from
Aug 4, 2020
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
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,11 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
def unapply(tree: tpd.TypeApply)(using Context): Option[tpd.Tree] = tree match
case TypeApply(Select(qual: RefTree, nme.asInstanceOfPM), arg :: Nil) =>
arg.tpe match
case AndType(ref, _) if qual.tpe eq ref => Some(qual)
case AndType(ref, nn1) if qual.tpe eq ref =>
qual.tpe.widen match
case OrNull(nn2) if nn1 eq nn2 =>
Some(qual)
case _ => None
case _ => None
case _ => None
end AssertNotNull
Expand Down
6 changes: 4 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Nullables.scala
Original file line number Diff line number Diff line change
Expand Up @@ -480,10 +480,12 @@ object Nullables:
if mt.paramInfos.exists(_.isInstanceOf[ExprType]) && !fn.symbol.is(Inline) =>
app match
case Apply(fn, args) =>
val dropNotNull = new TreeMap:
object dropNotNull extends TreeMap:
var dropped: Boolean = false
override def transform(t: Tree)(using Context) = t match
case AssertNotNull(t0) if t0.symbol.is(Mutable) =>
nullables.println(i"dropping $t")
dropped = true
transform(t0)
case t: ValDef if !t.symbol.is(Lazy) => super.transform(t)
case t: MemberDef =>
Expand All @@ -502,7 +504,7 @@ object Nullables:
def postProcess(formal: Type, arg: Tree): Tree =
val nestedCtx = ctx.fresh.setNewTyperState()
val arg1 = dropNotNull.transform(arg)(using nestedCtx)
if arg1 eq arg then arg
if !dropNotNull.dropped then arg
else
val arg2 = retyper.typed(arg1, formal)(using nestedCtx)
if nestedCtx.reporter.hasErrors || !(arg2.tpe <:< formal) then
Expand Down
16 changes: 16 additions & 0 deletions tests/pos-macros/i9321/macros.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import scala.quoted._

type Foo
type F[X]
def varargsFunc(funcs0: Foo*) = ???

inline def mcr1: F[String] = ${ mcr1Impl }
def mcr1Impl(using QuoteContext): Expr[F[String]] = '{???}

inline def mcr2: Unit = ${mcr2Impl}
def mcr2Impl(using ctx: QuoteContext): Expr[Unit] =
val func: Expr[Seq[Foo] => Unit] =
'{ (esx: Seq[Foo]) => varargsFunc(esx: _*) }
val trees: Expr[Seq[Foo]] =
'{Nil}
Expr.betaReduce('{$func($trees)})
5 changes: 5 additions & 0 deletions tests/pos-macros/i9321/test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def f(x: => Any) = ???
def g = f {
mcr1
mcr2
}