Skip to content

Commit 2c20198

Browse files
noti0na1WojciechMazur
authored andcommitted
Move warning to RefCheck
[Cherry-picked 1d3d0c4]
1 parent 2f48f0d commit 2c20198

File tree

4 files changed

+66
-58
lines changed

4 files changed

+66
-58
lines changed

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,18 @@ object RefChecks {
11851185
report.warning(ExtensionNullifiedByMember(sym, target), sym.srcPos)
11861186
end checkExtensionMethods
11871187

1188+
/** Check that public (and protected) methods/fields do not expose flexible types. */
1189+
def checkPublicFlexibleTypes(sym: Symbol)(using Context): Unit =
1190+
if ctx.explicitNulls && !ctx.isJava
1191+
&& sym.exists && !sym.is(Private) && sym.owner.isClass
1192+
&& !sym.isOneOf(Synthetic | InlineProxy | Param) then
1193+
val resTp = sym.info.finalResultType
1194+
if resTp.existsPart(_.isInstanceOf[FlexibleType], StopAt.Static) then
1195+
report.warning(
1196+
em"${sym.show} exposes a flexible type in its inferred result type ${resTp}. Consider annotating the type explicitly",
1197+
sym.srcPos
1198+
)
1199+
11881200
/** Verify that references in the user-defined `@implicitNotFound` message are valid.
11891201
* (i.e. they refer to a type variable that really occurs in the signature of the annotated symbol.)
11901202
*/
@@ -1321,6 +1333,7 @@ class RefChecks extends MiniPhase { thisPhase =>
13211333
val sym = tree.symbol
13221334
checkNoPrivateOverrides(sym)
13231335
checkVolatile(sym)
1336+
checkPublicFlexibleTypes(sym)
13241337
if (sym.exists && sym.owner.isTerm) {
13251338
tree.rhs match {
13261339
case Ident(nme.WILDCARD) => report.error(UnboundPlaceholderParameter(), sym.srcPos)
@@ -1336,6 +1349,7 @@ class RefChecks extends MiniPhase { thisPhase =>
13361349
checkImplicitNotFoundAnnotation.defDef(sym.denot)
13371350
checkUnaryMethods(sym)
13381351
checkExtensionMethods(sym)
1352+
checkPublicFlexibleTypes(sym)
13391353
tree
13401354
}
13411355

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3083,32 +3083,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
30833083
//todo: make sure dependent method types do not depend on implicits or by-name params
30843084
}
30853085

3086-
/** (1) Check that the signature of the class member does not return a repeated parameter type.
3087-
* (2) Check that the signature of the public class member does not expose a flexible type.
3088-
* (3) Make sure the definition's symbol is `sym`.
3089-
* (4) Set the `defTree` of `sym` to be `mdef`.
3086+
/** (1) Check that the signature of the class member does not return a repeated parameter type
3087+
* (2) Make sure the definition's symbol is `sym`.
3088+
* (3) Set the `defTree` of `sym` to be `mdef`.
30903089
*/
30913090
private def postProcessInfo(mdef: MemberDef, sym: Symbol)(using Context): MemberDef =
30923091
if (!sym.isOneOf(Synthetic | InlineProxy | Param) && sym.info.finalResultType.isRepeatedParam)
30933092
report.error(em"Cannot return repeated parameter type ${sym.info.finalResultType}", sym.srcPos)
3094-
3095-
// Warn if a public method/field exposes FlexibleType in its result type under explicit nulls
3096-
// and encourage explicit annotation.
3097-
if ctx.phase.isTyper && ctx.explicitNulls && !ctx.isJava
3098-
&& sym.exists && sym.isPublic && sym.owner.isClass
3099-
&& !sym.isOneOf(Synthetic | InlineProxy | Param) then
3100-
val resTp = sym.info.finalResultType
3101-
if resTp.existsPart(_.isInstanceOf[FlexibleType], StopAt.Static) then
3102-
val suggestion = resTp match
3103-
case ft: FlexibleType =>
3104-
val hi = ft.hi
3105-
i"Consider annotating the type as ${hi} or ${hi} | Null explicitly"
3106-
case _ => "Consider annotating the type explicitly"
3107-
report.warning(
3108-
em"Public ${sym.show} exposes a flexible type ${resTp} in its inferred signature. $suggestion",
3109-
sym.srcPos
3110-
)
3111-
31123093
mdef.ensureHasSym(sym)
31133094
mdef.setDefTree
31143095

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,56 @@
1-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:2:6 --------------------------------------------------
2-
2 | def f = s.trim // warn
1+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:4:6 --------------------------------------------------
2+
4 | def f = s.trim // warn
33
| ^
4-
|Public method f exposes a flexible type (String)? in its inferred signature. Consider annotating the type as String or String | Null explicitly
5-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:6:6 --------------------------------------------------
6-
6 | def h = (s.trim, s.length) // warn
7-
| ^
8-
|Public method h exposes a flexible type ((String)?, Int) in its inferred signature. Consider annotating the type explicitly
9-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:7:6 --------------------------------------------------
10-
7 | val ss = s.replace("a", "A") // warn
11-
| ^
12-
|Public value ss exposes a flexible type (String)? in its inferred signature. Consider annotating the type as String or String | Null explicitly
4+
| method f exposes a flexible type in its inferred result type (String)?. Consider annotating the type explicitly
135
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:8:6 --------------------------------------------------
14-
8 | val ss2 = Seq(s.trim) // warn
6+
8 | def h = (s.trim, s.length) // warn
157
| ^
16-
|Public value ss2 exposes a flexible type Seq[(String)?] in its inferred signature. Consider annotating the type explicitly
17-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:16:6 -------------------------------------------------
18-
16 | def f = s2.trim // warn
8+
|method h exposes a flexible type in its inferred result type ((String)?, Int). Consider annotating the type explicitly
9+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:9:16 -------------------------------------------------
10+
9 | protected def i = s.trim // warn
11+
| ^
12+
| method i exposes a flexible type in its inferred result type (String)?. Consider annotating the type explicitly
13+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:11:19 ------------------------------------------------
14+
11 | private[foo] def k = s.trim // warn
15+
| ^
16+
| method k exposes a flexible type in its inferred result type (String)?. Consider annotating the type explicitly
17+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:12:6 -------------------------------------------------
18+
12 | val ss = s.replace("a", "A") // warn
1919
| ^
20-
|Public method f exposes a flexible type (String)? in its inferred signature. Consider annotating the type as String or String | Null explicitly
21-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:20:6 -------------------------------------------------
22-
20 | def h = (s2.trim, s2.length) // warn
20+
| value ss exposes a flexible type in its inferred result type (String)?. Consider annotating the type explicitly
21+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:13:6 -------------------------------------------------
22+
13 | val ss2 = Seq(s.trim) // warn
2323
| ^
24-
|Public method h exposes a flexible type ((String)?, Int) in its inferred signature. Consider annotating the type explicitly
24+
|value ss2 exposes a flexible type in its inferred result type Seq[(String)?]. Consider annotating the type explicitly
2525
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:21:6 -------------------------------------------------
26-
21 | val ss = s2.replace("a", "A") // warn
26+
21 | def f = s2.trim // warn
27+
| ^
28+
| method f exposes a flexible type in its inferred result type (String)?. Consider annotating the type explicitly
29+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:25:6 -------------------------------------------------
30+
25 | def h = (s2.trim, s2.length) // warn
2731
| ^
28-
|Public value ss exposes a flexible type (String)? in its inferred signature. Consider annotating the type as String or String | Null explicitly
29-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:22:6 -------------------------------------------------
30-
22 | val ss2 = Seq(s2.trim) // warn
32+
|method h exposes a flexible type in its inferred result type ((String)?, Int). Consider annotating the type explicitly
33+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:26:6 -------------------------------------------------
34+
26 | val ss = s2.replace("a", "A") // warn
3135
| ^
32-
|Public value ss2 exposes a flexible type Seq[(String)?] in its inferred signature. Consider annotating the type explicitly
33-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:27:4 -------------------------------------------------
34-
27 |def f = s2.trim // warn
36+
| value ss exposes a flexible type in its inferred result type (String)?. Consider annotating the type explicitly
37+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:27:6 -------------------------------------------------
38+
27 | val ss2 = Seq(s2.trim) // warn
39+
| ^
40+
|value ss2 exposes a flexible type in its inferred result type Seq[(String)?]. Consider annotating the type explicitly
41+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:32:4 -------------------------------------------------
42+
32 |def f = s2.trim // warn
3543
| ^
36-
|Public method f exposes a flexible type (String)? in its inferred signature. Consider annotating the type as String or String | Null explicitly
37-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:31:4 -------------------------------------------------
38-
31 |def h = (s2.trim, s2.length) // warn
44+
| method f exposes a flexible type in its inferred result type (String)?. Consider annotating the type explicitly
45+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:36:4 -------------------------------------------------
46+
36 |def h = (s2.trim, s2.length) // warn
3947
| ^
40-
|Public method h exposes a flexible type ((String)?, Int) in its inferred signature. Consider annotating the type explicitly
41-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:32:4 -------------------------------------------------
42-
32 |val ss = s2.replace("a", "A") // warn
48+
|method h exposes a flexible type in its inferred result type ((String)?, Int). Consider annotating the type explicitly
49+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:37:4 -------------------------------------------------
50+
37 |val ss = s2.replace("a", "A") // warn
4351
| ^
44-
|Public value ss exposes a flexible type (String)? in its inferred signature. Consider annotating the type as String or String | Null explicitly
45-
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:33:4 -------------------------------------------------
46-
33 |val ss2 = Seq(s2.trim) // warn
52+
| value ss exposes a flexible type in its inferred result type (String)?. Consider annotating the type explicitly
53+
-- Warning: tests/explicit-nulls/warn/expose-flexible-types.scala:38:4 -------------------------------------------------
54+
38 |val ss2 = Seq(s2.trim) // warn
4755
| ^
48-
|Public value ss2 exposes a flexible type Seq[(String)?] in its inferred signature. Consider annotating the type explicitly
56+
|value ss2 exposes a flexible type in its inferred result type Seq[(String)?]. Consider annotating the type explicitly

tests/explicit-nulls/warn/expose-flexible-types.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
package foo
2+
13
class C(s: String):
24
def f = s.trim // warn
35
def g: String =
46
val s2 = s.trim
57
s2
68
def h = (s.trim, s.length) // warn
9+
protected def i = s.trim // warn
10+
private def j = s.trim
11+
private[foo] def k = s.trim // warn
712
val ss = s.replace("a", "A") // warn
813
val ss2 = Seq(s.trim) // warn
914
val ss3: Seq[String] =

0 commit comments

Comments
 (0)