Skip to content

Commit c3f1aee

Browse files
SuperCl4shtgodzik
authored andcommitted
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]> [Cherry-picked 70a169a]
1 parent 8b3b5b8 commit c3f1aee

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
@@ -296,7 +296,7 @@ class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tre
296296
extends TypeMismatchMsg(found, expected)(TypeMismatchID):
297297

298298
private val shouldSuggestNN =
299-
if expected.isValueType then
299+
if ctx.mode.is(Mode.SafeNulls) && expected.isValueType then
300300
found frozen_<:< OrNull(expected)
301301
else false
302302

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

363363
override def actions(using Context) =
364-
if shouldSuggestNN then
365-
inTree match {
366-
case Some(tree) if tree != null =>
367-
val content = tree.source.content().slice(tree.srcPos.startPos.start, tree.srcPos.endPos.end).mkString
368-
val replacement = tree match
369-
case Apply(fun, args) => "(" + content + ").nn"
370-
case _ => content + ".nn"
371-
List(
372-
CodeAction(title = """Add .nn""",
364+
inTree match {
365+
case Some(tree) if shouldSuggestNN =>
366+
val content = tree.source.content().slice(tree.srcPos.startPos.start, tree.srcPos.endPos.end).mkString
367+
val replacement = tree match
368+
case a @ Apply(_, _) if a.applyKind == ApplyKind.Using =>
369+
content + ".nn"
370+
case _ @ (Select(_, _) | Ident(_)) => content + ".nn"
371+
case _ => "(" + content + ").nn"
372+
List(
373+
CodeAction(title = """Add .nn""",
373374
description = None,
374375
patches = List(
375376
ActionPatch(tree.srcPos.sourcePos, replacement)
376377
)
377-
)
378378
)
379-
case _ =>
380-
List()
381-
}
382-
else
383-
List()
384-
379+
)
380+
case _ =>
381+
List()
382+
}
385383
end TypeMismatch
386384

387385
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
@@ -165,7 +165,7 @@ class CodeActionTest extends DottyTest:
165165
ctxx = ctxx
166166
)
167167

168-
@Test def addNN =
168+
@Test def addNN1 =
169169
val ctxx = newContext
170170
ctxx.setSetting(ctxx.settings.YexplicitNulls, true)
171171
checkCodeAction(
@@ -238,6 +238,57 @@ class CodeActionTest extends DottyTest:
238238
| val t: String = (s.q(s, s)).nn""".stripMargin,
239239
ctxx = ctxx
240240
)
241+
242+
@Test def addNN5 =
243+
val ctxx = newContext
244+
ctxx.setSetting(ctxx.settings.YexplicitNulls, true)
245+
checkCodeAction(
246+
code =
247+
"""val s: String | Null = ???
248+
|val t: String = s match {
249+
| case _: String => "foo"
250+
| case _ => s
251+
|}""".stripMargin,
252+
title = "Add .nn",
253+
expected =
254+
"""val s: String | Null = ???
255+
|val t: String = s match {
256+
| case _: String => "foo"
257+
| case _ => s.nn
258+
|}""".stripMargin,
259+
ctxx = ctxx
260+
)
261+
262+
@Test def addNN6 =
263+
val ctxx = newContext
264+
ctxx.setSetting(ctxx.settings.YexplicitNulls, true)
265+
checkCodeAction(
266+
code =
267+
"""val s: String | Null = ???
268+
|val t: String = if (s != null) "foo" else s""".stripMargin,
269+
title = "Add .nn",
270+
expected =
271+
"""val s: String | Null = ???
272+
|val t: String = if (s != null) "foo" else s.nn""".stripMargin,
273+
ctxx = ctxx
274+
)
275+
276+
@Test def addNN7 =
277+
val ctxx = newContext
278+
ctxx.setSetting(ctxx.settings.YexplicitNulls, true)
279+
checkCodeAction(
280+
code =
281+
"""given ctx: String | Null = null
282+
|def f(using c: String): String = c
283+
|val s: String = f(using ctx)""".stripMargin,
284+
title = "Add .nn",
285+
expected =
286+
"""given ctx: String | Null = null
287+
|def f(using c: String): String = c
288+
|val s: String = f(using ctx.nn)""".stripMargin,
289+
ctxx = ctxx
290+
)
291+
241292
// Make sure we're not using the default reporter, which is the ConsoleReporter,
242293
// meaning they will get reported in the test run and that's it.
243294
private def newContext =

0 commit comments

Comments
 (0)