Skip to content

Tracking issue for future-incompatibility lint resolve_trait_on_defaulted_unit #39216

Closed

Description

@canndrew

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

Activity

  1. dtolnay commented on Feb 16, 2017

    @dtolnay
    Member

    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.

  2. alexcrichton commented on Feb 16, 2017

    @alexcrichton
    Member

    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?

  3. canndrew commented on Feb 21, 2017

    @canndrew
    ContributorAuthor

    @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 #39009. I guess the diagnostics will need to be improved :/

  4. nikomatsakis commented on Feb 21, 2017

    @nikomatsakis
    Contributor

    @dtolnay I believe that case of the ? expressions in particular was a bug, and should have been fixed by #39485.

  5. nikomatsakis commented on Feb 21, 2017

    @nikomatsakis
    Contributor

    @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.

  6. canndrew commented on Feb 27, 2017

    @canndrew
    ContributorAuthor

    @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.

  7. added
    B-unstableBlocker: Implemented in the nightly compiler and unstable.
    on Mar 1, 2017
  8. bluss commented on Mar 6, 2017

    @bluss
    Contributor

    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.

  9. nikomatsakis commented on Mar 6, 2017

    @nikomatsakis
    Contributor

    @bluss note that i've overhauling a lot of this machinery to address regressions in #40224 as well. I'm not sure what affect this will have on petgraph though.

  10. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    on Jul 22, 2017
  11. Xion commented on Jan 22, 2018

    @Xion

    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?

  12. nikomatsakis commented on Jan 23, 2018

    @nikomatsakis
    Contributor

    @Xion it is not, but we are starting to move towards making it so.

  13. added 2 commits that reference this issue on Oct 16, 2019
  14. 2 remaining items

  15. pnkfelix commented on Mar 18, 2022

    @pnkfelix
    Contributor

    Visiting for T-compiler backlog bonanza.

    Blocking bug: #51125

    @rustbot label: +S-tracking-impl-incomplete

  16. added 3 commits that reference this issue on Apr 3, 2024
    b3193f6
    d9cb2bf
    645bb72
  17. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    on Sep 14, 2024
  18. changed the title [-]Tracking issue for `resolve_trait_on_defaulted_unit` compatibility lint[/-] [+]Tracking issue for future-incompatibility lint `resolve_trait_on_defaulted_unit`[/+] on Sep 14, 2024
  19. fmease commented on Sep 14, 2024

    @fmease
    Member

    The lint resolve_trait_on_defaulted_unit no longer gets emitted by the compiler and was marked as removed by … #48950 (which is odd on its own). I guess we should close this tracking issue?

    We now have the future-incompatibility lint dependency_on_unit_never_type_fallback which I think is the successor of this lint? However it lacks a tracking issue).

    cc @WaffleLapkin

  20. removed
    B-unstableBlocker: Implemented in the nightly compiler and unstable.
    on Sep 14, 2024
  21. WaffleLapkin commented on Sep 20, 2024

    @WaffleLapkin
    Member

    @fmease yes, I believe dependency_on_unit_never_type_fallback supersedes the lint described here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-future-incompatibilityCategory: Future-incompatibility lintsC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCS-tracking-impl-incompleteStatus: The implementation is incomplete.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions