Skip to content

Commit 70a169a

Browse files
committed
Add SafeNulls check before computing subtyping relation, fix edge cases for in-line match and if, improve formatting, and add more test
Signed-off-by: Seyon Sivatharan <[email protected]>
1 parent 8229c8b commit 70a169a

File tree

2 files changed

+67
-18
lines changed

2 files changed

+67
-18
lines changed

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tre
301301
extends TypeMismatchMsg(found, expected)(TypeMismatchID):
302302

303303
private val shouldSuggestNN =
304-
if expected.isValueType then
304+
if ctx.mode.is(Mode.SafeNulls) && expected.isValueType then
305305
found frozen_<:< OrNull(expected)
306306
else false
307307

@@ -366,27 +366,25 @@ class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tre
366366
treeStr + "\n" + super.explain
367367

368368
override def actions(using Context) =
369-
if shouldSuggestNN then
370-
inTree match {
371-
case Some(tree) if tree != null =>
372-
val content = tree.source.content().slice(tree.srcPos.startPos.start, tree.srcPos.endPos.end).mkString
373-
val replacement = tree match
374-
case Apply(fun, args) => "(" + content + ").nn"
375-
case _ => content + ".nn"
376-
List(
377-
CodeAction(title = """Add .nn""",
369+
inTree match {
370+
case Some(tree) if shouldSuggestNN =>
371+
val content = tree.source.content().slice(tree.srcPos.startPos.start, tree.srcPos.endPos.end).mkString
372+
val replacement = tree match
373+
case a @ Apply(_, _) if a.applyKind == ApplyKind.Using =>
374+
content + ".nn"
375+
case _ @ (Select(_, _) | Ident(_)) => content + ".nn"
376+
case _ => "(" + content + ").nn"
377+
List(
378+
CodeAction(title = """Add .nn""",
378379
description = None,
379380
patches = List(
380381
ActionPatch(tree.srcPos.sourcePos, replacement)
381382
)
382-
)
383383
)
384-
case _ =>
385-
List()
386-
}
387-
else
388-
List()
389-
384+
)
385+
case _ =>
386+
List()
387+
}
390388
end TypeMismatch
391389

392390
class NotAMember(site: Type, val name: Name, selected: String, proto: Type, addendum: => String = "")(using Context)

compiler/test/dotty/tools/dotc/reporting/CodeActionTest.scala

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class CodeActionTest extends DottyTest:
179179
ctxx = ctxx
180180
)
181181

182-
@Test def addNN =
182+
@Test def addNN1 =
183183
val ctxx = newContext
184184
ctxx.setSetting(ctxx.settings.YexplicitNulls, true)
185185
checkCodeAction(
@@ -252,6 +252,57 @@ class CodeActionTest extends DottyTest:
252252
| val t: String = (s.q(s, s)).nn""".stripMargin,
253253
ctxx = ctxx
254254
)
255+
256+
@Test def addNN5 =
257+
val ctxx = newContext
258+
ctxx.setSetting(ctxx.settings.YexplicitNulls, true)
259+
checkCodeAction(
260+
code =
261+
"""val s: String | Null = ???
262+
|val t: String = s match {
263+
| case _: String => "foo"
264+
| case _ => s
265+
|}""".stripMargin,
266+
title = "Add .nn",
267+
expected =
268+
"""val s: String | Null = ???
269+
|val t: String = s match {
270+
| case _: String => "foo"
271+
| case _ => s.nn
272+
|}""".stripMargin,
273+
ctxx = ctxx
274+
)
275+
276+
@Test def addNN6 =
277+
val ctxx = newContext
278+
ctxx.setSetting(ctxx.settings.YexplicitNulls, true)
279+
checkCodeAction(
280+
code =
281+
"""val s: String | Null = ???
282+
|val t: String = if (s != null) "foo" else s""".stripMargin,
283+
title = "Add .nn",
284+
expected =
285+
"""val s: String | Null = ???
286+
|val t: String = if (s != null) "foo" else s.nn""".stripMargin,
287+
ctxx = ctxx
288+
)
289+
290+
@Test def addNN7 =
291+
val ctxx = newContext
292+
ctxx.setSetting(ctxx.settings.YexplicitNulls, true)
293+
checkCodeAction(
294+
code =
295+
"""given ctx: String | Null = null
296+
|def f(using c: String): String = c
297+
|val s: String = f(using ctx)""".stripMargin,
298+
title = "Add .nn",
299+
expected =
300+
"""given ctx: String | Null = null
301+
|def f(using c: String): String = c
302+
|val s: String = f(using ctx.nn)""".stripMargin,
303+
ctxx = ctxx
304+
)
305+
255306
// Make sure we're not using the default reporter, which is the ConsoleReporter,
256307
// meaning they will get reported in the test run and that's it.
257308
private def newContext =

0 commit comments

Comments
 (0)