-
Notifications
You must be signed in to change notification settings - Fork 1.1k
warn about unnecessary uses of .nn #23327
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
base: main
Are you sure you want to change the base?
Conversation
@@ -1088,7 +1088,19 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer | |||
errorTree(tree, em"cannot convert to type selection") // will never be printed due to fallback | |||
} | |||
|
|||
if (tree.qualifier.isType) { | |||
def warnUnnecessaryNN(tree: Tree): Unit = { | |||
if ctx.explicitNulls then { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you agree we should check unnecessary nn even without explicit nulls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could, but I didn't want to rock the boat too much before we fine-tune which corner cases should/shouldn't warn.
@@ -50,6 +50,18 @@ object NullOpsDecorator: | |||
val stripped = self.stripNull() | |||
stripped ne self | |||
} | |||
|
|||
def admitsNull(using Context): Boolean = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are basically checking if a type has Null
as a subtype, I'm not sure whether we should widen a singleton type.
For example,
val s: String | Null = ???
val ss: s.type | Null = ???
val snotnull: s.type = ss.nn
I'd like to allow ss.nn
to say if it returns a value, the value is equal to s
and not null.
@@ -373,7 +373,7 @@ object Types extends TypeUtils { | |||
final def isNotNull(using Context): Boolean = this match { | |||
case tp: ConstantType => tp.value.value != null | |||
case tp: FlexibleType => false | |||
case tp: ClassInfo => !tp.cls.isNullableClass && tp.cls != defn.NothingClass | |||
case tp: ClassInfo => !tp.cls.isNullableClass && !tp.isNothingType | |||
case tp: AppliedType => tp.superType.isNotNull | |||
case tp: TypeBounds => tp.lo.isNotNull |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking about admitsNull
, I'm now wondering: should we check the hi
of a type bound? For example, T >: String <: String | Null
, I don't think T
is "NotNull".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test we want is NullType <:< tp
, but <:<
has side effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry, never mind, I thought this was about admitsNull
.
For isNotNull
, you may be right, but it didn't change (the case for TypeBounds
). It was like that before this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, but you said admitsNull
.
For admitsNull
, the test is NullType <:< tp
, so lo
is right when tp
is a TypeBounds
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I mean the case tp: TypeBounds
in isNotNull
. I feel it is not correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. It should be hi
, not lo
. I've pushed a fix.
I can't figure out the bootstrapped test failures. It seems to be a Heisenbug. Locally, if I do |
Issue warnings when
.nn
is called on a receiver that is already not null or when the expected type of the result of.nn
admits null.cc @noti0na1