Open canndrew opened 7 years ago
Is there any hope of treating let _ = Deserialize::deserialize(foo)?
more like let _ = Default::default()
and producing the same "cannot infer type" message? Inferring !
does not make any more or less sense to me than inferring ()
.
Has this already been discussed elsewhere? I don't see any links in your comment.
FWIW futures-rs ran into this warning and I found it pretty hard to fix, I was just randomly annotating unknown types until I finally found that location in the commit.
Also out of curiosity, what PR was this introduced with?
@dtolnay: @eddyb and @nikomatsakis have brought that idea up before and they might have an opinion on whether it's worth trying to implement.
@alexcrichton: This was added in https://github.com/rust-lang/rust/pull/39009. I guess the diagnostics will need to be improved :/
@dtolnay I believe that case of the ?
expressions in particular was a bug, and should have been fixed by https://github.com/rust-lang/rust/pull/39485.
@alexcrichton hmm, yeah, that's frustrating; we're not super good at highlighting where a type annotation is needed, though we've been getting somewhat better. Maybe "closure return type" would make a good example.
@dtolnay I believe that case of the
?
expressions in particular was a bug, and should have been fixed by #39485.
True, though the general case of us having "defaulting" behavior around ()
/!
at all still remains.
Thanks for the extensive write-up. petgraph's test suite triggered this in:
warning: code relies on type inference rules which are likely to change
--> src/algo/dominators.rs:260:9
|
260 | assert_eq!(None, doms.dominators(99).map(|_| unreachable!()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(resolve_trait_on_defaulted_unit)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #39216 <https://github.com/rust-lang/rust/issues/39216>
= note: this error originates in a macro outside of the current crate
Solution is to use for example None::<()>
to have the type explicit. We'd of course like to use None::<!>
when stable.
petgraph might have the record in running into most Rust breaking changes ever.
@bluss note that i've overhauling a lot of this machinery to address regressions in https://github.com/rust-lang/rust/pull/40224 as well. I'm not sure what affect this will have on petgraph though.
I've got to this issue from a compiler message when trying some serde/serde_json workaround, and I noticed the message still says the problem will become a hard error.
Well, it is a hard error already :) I'm thinking the message should be reworded perhaps?
@Xion it is not, but we are starting to move towards making it so.
Visiting for T-compiler backlog bonanza.
Blocking bug: #51125
@rustbot label: +S-tracking-impl-incomplete
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:
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: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: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:
Current status
resolve_trait_on_defaulted_unit
lint as warn-by-defaultresolve_trait_on_defaulted_unit
lint deny-by-defaultresolve_trait_on_defaulted_unit
lint a hard error