Skip to content

Tracking issue for future-incompatibility lint resolve_trait_on_defaulted_unit #39216

Closed
@canndrew

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

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

    Status

    Idea

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions