-
Notifications
You must be signed in to change notification settings - Fork 132
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
Optional<T> should be Optional<T extends Object> #666
Comments
/cc @yjbanov and @davidmorgan for thoughts. |
Optional is intended as a substitute for non-nullable values. Ideally, it should have a generic type of `T extends Object` in order to prevent non-sensical declarations like `Optional<Foo?>`. Such declarations are unlikely to happen intentionally, but one could imagine the case of an Optional<T> used in another generic class, where T is a nullable type. In google#652, we prevented such uses by declaring Optional as Optional<T extends Object>. This turns out to be a significant breaking change, since previously, T implicitly extended `dynamic` and therefore checks like the following didn't produce any analysis errors: if (obj is Optional) { return obj.value.someMethod(); } where `someMethod` is a method defined on `T`. A survey of the Google codebase suggests this would be a fairly extensive breaking change. Given that Optional makes little sense once null-safety is enabled in the language by default, the simpler change may simply be to leave as-is and deprecate the class once null-safety lands in the language. It appears that there are no checks on the return type of `transform`, and this seems significantly unlikely, therefore we leave that change in place. This partially reverts 28301f9. Related: google#666
Optional is intended as a substitute for non-nullable values. Ideally, it should have a generic type of `T extends Object` in order to prevent non-sensical declarations like `Optional<Foo?>`. Such declarations are unlikely to happen intentionally, but one could imagine the case of an Optional<T> used in another generic class, where T is a nullable type. In #652, we prevented such uses by declaring Optional as Optional<T extends Object>. This turns out to be a significant breaking change, since previously, T implicitly extended `dynamic` and therefore checks like the following didn't produce any analysis errors: if (obj is Optional) { return obj.value.someMethod(); } where `someMethod` is a method defined on `T`. A survey of the Google codebase suggests this would be a fairly extensive breaking change. Given that Optional makes little sense once null-safety is enabled in the language by default, the simpler change may simply be to leave as-is and deprecate the class once null-safety lands in the language. It appears that there are no checks on the return type of `transform`, and this seems significantly unlikely, therefore we leave that change in place. This partially reverts 28301f9. Related: #666
Optional is intended as a substitute for non-nullable values. Ideally, it should have a generic type of `T extends Object` in order to prevent non-sensical declarations like `Optional<Foo?>`. Such declarations are unlikely to happen intentionally, but one could imagine the case of an Optional<T> used in another generic class, where T is a nullable type. In #652, we prevented such uses by declaring Optional as Optional<T extends Object>. This turns out to be a significant breaking change, since previously, T implicitly extended `dynamic` and therefore checks like the following didn't produce any analysis errors: if (obj is Optional) { return obj.value.someMethod(); } where `someMethod` is a method defined on `T`. A survey of the Google codebase suggests this would be a fairly extensive breaking change. Given that Optional makes little sense once null-safety is enabled in the language by default, the simpler change may simply be to leave as-is and deprecate the class once null-safety lands in the language. It appears that there are no checks on the return type of `transform`, and this seems significantly unlikely, therefore we leave that change in place. This partially reverts 28301f9. Related: #666
I think just making Thanks. |
sgtm. That avoids a breaking change before (eventual) removal. |
Given that Quiver 3.0 will have a minimum SDK constraint of 2.12.0, I'll deprecate it in that branch now. |
Closing this since we’re deprecating Optional; no need to force people through two migrations here. |
I propose that we reopen this issue. Even though deprecating |
Fwiw I have been running into this a fair bit where the migration tool suggests a nullable type for Optional objects, which makes no sense :(. Not sure if it is too breaking or what, but definitely seems wrong that |
Another idea here is you could do a less breaking change, where And it would be worth cleaning up any such instances in google3 as well. |
Optional is intended as a substitute for non-nullable values. Ideally, it should have a generic type of
T extends Object
in order to prevent non-sensical declarations likeOptional<Foo?>
. Such declarations are unlikely to happen intentionally, but one could imagine the case of an Optional used in another generic class, where T is a nullable type.Ideally, we should prevent such uses by declaring Optional as
Optional<T extends Object>
.This is a potentially significant breaking change, since currently T implicitly extends
dynamic
and therefore checks like the following don't produce any analysis errors:where
someMethod
is a method defined onT
. All such call sites would need to be fixed up toobj is Optional<AppropriateType>
.A survey of the Google codebase suggests this would be a fairly extensive breaking change. Given that Optional makes little sense once null-safety is enabled in the language by default, the simpler change may simply be to leave as-is and deprecate the class once null-safety lands in the language.
The text was updated successfully, but these errors were encountered: