Tracking issue for future-incompatibility lint resolve_trait_on_defaulted_unit
· Issue #39216 · rust-lang/rust (original) (raw)
This is the summary issue for the resolve_trait_on_defaulted_unit
future-compatibility warning and other related errors. The goal of this page is describe why this change was made and how you can fix code that is affected by it. It also provides a place to ask questions or register a complaint if you feel the change should not be made. For more information on the policy around future-compatibility warnings, see our breaking change policy guidelines.
What is this lint about
Ordinarily, when a user doesn't specify the type of an expression and the type cannot be inferred, rust will raise an error. For example, consider this code:
let _ = Default::default();
Because we haven't specified the type of _
the compiler doesn't know what type of value the user is asking for a default of. And so we get this error:
error[E0282]: unable to infer enough type information about Self
--> example.rs:2:13
|
2 | let _ = Default::default();
| ^^^^^^^^^^^^^^^^ cannot infer type for Self
|
= note: type annotations or generic parameter binding required
error: aborting due to previous error
However, due to an unfortunate quirk in Rust's type inference algorithms it is sometimes possible to sneak situations like this past the compiler. In these cases, the unspecified type is defaulted to ()
. For an example of this, you can try deserializing an unspecified type with serde:
let _ = Deserialize::deserialize(foo)?;
In this case, the code will compile and will deserialize a value of type ()
.
This behaviour is set to change with the eventual rolling-out of feature(never_type)
. Where defaulting is still used types will instead default to !
. In the best case, code that currently relies on unspecified types defaulting to ()
will stop compiling. In the worst case, code will continue to compile but may execute differently, as in the above example where a !
will be deserialised instead.
The resolve_trait_on_defaulted_unit
warning is raised wherever the compiler thinks your program's behaviour may depend on the current defaulting rules.
How to fix this warning/error
Be specific about what type you're using. In the serde example above this could be done by simply adding a type annotation:
let _: () = Deserialize::deserialize(foo)?;
Current status
- Add warning for () to ! switch #39009 introduces the
resolve_trait_on_defaulted_unit
lint as warn-by-default - Make sufficiently old or low-impact compatibility lints deny-by-default #42894 makes the
resolve_trait_on_defaulted_unit
lint deny-by-default - PR ? makes the
resolve_trait_on_defaulted_unit
lint a hard error