Skip to content
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

Tracking issue for future-incompatibility lint resolve_trait_on_defaulted_unit #39216

Closed
2 of 3 tasks
canndrew opened this issue Jan 21, 2017 · 13 comments
Closed
2 of 3 tasks
Labels
C-future-incompatibility Category: Future-incompatibility lints C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC S-tracking-impl-incomplete Status: The implementation is incomplete. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@canndrew
Copy link
Contributor

canndrew commented Jan 21, 2017

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

@dtolnay
Copy link
Member

dtolnay commented Feb 16, 2017

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.

@alexcrichton
Copy link
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?

@canndrew
Copy link
Contributor Author

@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 :/

@nikomatsakis
Copy link
Contributor

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

@nikomatsakis
Copy link
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.

@canndrew
Copy link
Contributor Author

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

@brson brson added the B-unstable Blocker: Implemented in the nightly compiler and unstable. label Mar 1, 2017
@bluss
Copy link
Member

bluss commented Mar 6, 2017

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.

@nikomatsakis
Copy link
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.

@Xion
Copy link

Xion commented Jan 22, 2018

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?

@nikomatsakis
Copy link
Contributor

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

bors-servo pushed a commit to servo/core-foundation-rs that referenced this issue Oct 16, 2019
Fixes so the compiler can infer msg_send! return types

Currently, due to a quirk in Rust's type inference interacting with the structure of the `msg_send!` macro, a `()` return type will be inferred when the compiler cannot otherwise determine the return type. This behavior is expected to change, and in the future could resolve to a `!` return type, which results in undefined behavior.

Linting has previously been added for this in rust-lang/rust#39216, but it did not catch these cases due to SSheldon/rust-objc#62. An upcoming version of objc will be fixed to stop hiding these errors, at which point they will become compile errors.

This change fixes these errors and allows cocoa to compile with the fixed version of objc.
bors-servo pushed a commit to servo/core-foundation-rs that referenced this issue Oct 17, 2019
Fixes so the compiler can infer msg_send! return types (backport to 0.18)

This is a backport of #340 onto the 0.18 release.

Currently, due to a quirk in Rust's type inference interacting with the structure of the `msg_send!` macro, a `()` return type will be inferred when the compiler cannot otherwise determine the return type. This behavior is expected to change, and in the future could resolve to a `!` return type, which results in undefined behavior.

Linting has previously been added for this in rust-lang/rust#39216, but it did not catch these cases due to SSheldon/rust-objc#62. An upcoming version of objc will be fixed to stop hiding these errors, at which point they will become compile errors.

This change fixes these errors and allows cocoa to compile with the fixed version of objc.
Osspial pushed a commit to rust-windowing/winit that referenced this issue Oct 18, 2019
* Fix so the compiler can infer msg_send! return type

Currently, due to a quirk in Rust's type inference interacting with the
structure of the msg_send! macro, a () return type will be inferred when
the compiler cannot otherwise determine the return type. This behavior
is expected to change, and in the future could resolve to a ! return
type, which results in undefined behavior.

Linting has previously been added for this in rust-lang/rust#39216, but
it did not catch these cases due to SSheldon/rust-objc#62. An upcoming
version of objc will be fixed to stop hiding these errors, at which
point they will become compile errors.

This change fixes these errors and allows winit to compile with the
fixed version of objc.

* Bump cocoa to 0.19.1
jdm pushed a commit to servo/surfman that referenced this issue Oct 19, 2019
Currently, due to a quirk in Rust's type inference interacting with the
structure of the msg_send! macro, a () return type will be inferred when
the compiler cannot otherwise determine the return type. This behavior
is expected to change, and in the future could resolve to a ! return
type, which results in undefined behavior.

Linting has previously been added for this in rust-lang/rust#39216, but
it did not catch these cases due to SSheldon/rust-objc#62. objc has been
fixed to stop hiding these errors as of version 0.2.7, and they are now
compile errors.

This change fixes these errors and allows compiling with the
latest version of objc.
hecrj pushed a commit to hecrj/winit that referenced this issue Oct 20, 2019
…1227)

* Fix so the compiler can infer msg_send! return type

Currently, due to a quirk in Rust's type inference interacting with the
structure of the msg_send! macro, a () return type will be inferred when
the compiler cannot otherwise determine the return type. This behavior
is expected to change, and in the future could resolve to a ! return
type, which results in undefined behavior.

Linting has previously been added for this in rust-lang/rust#39216, but
it did not catch these cases due to SSheldon/rust-objc#62. An upcoming
version of objc will be fixed to stop hiding these errors, at which
point they will become compile errors.

This change fixes these errors and allows winit to compile with the
fixed version of objc.

* Bump cocoa to 0.19.1
@pnkfelix pnkfelix added the C-future-incompatibility Category: Future-incompatibility lints label Mar 17, 2022
@pnkfelix
Copy link
Member

Visiting for T-compiler backlog bonanza.

Blocking bug: #51125

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

@rustbot rustbot added the S-tracking-impl-incomplete Status: The implementation is incomplete. label Mar 18, 2022
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 3, 2024
…-operator-to-not-screw-with-inference-will-it-obey, r=<try>

Stop skewing inference in ?'s desugaring

**NB**: this is a breaking change (although arguably a bug fix) and as such shouldn't be taken lightly.

This changes `expr?`'s desugaring like so (simplified, see code for more info):
```rust
// old
match expr {
    Ok(val) => val,
    Err(err) => return Err(err),
}

// new
match expr {
    Ok(val) => val,
    Err(err) => core::convert::absurd(return Err(err)),
}

// core::convert
pub const fn absurd<T>(x: !) -> T { x }
```

This prevents `!` from the `return` from skewing inference:
```rust
// previously: ok (never type spontaneous decay skews inference, `T = ()`)
// with this pr: can't infer the type for `T`
Err(())?;
```

Fixes rust-lang#51125
Closes rust-lang#39216
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 4, 2024
…-operator-to-not-screw-with-inference-will-it-obey, r=<try>

Stop skewing inference in ?'s desugaring

**NB**: this is a breaking change (although arguably a bug fix) and as such shouldn't be taken lightly.

This changes `expr?`'s desugaring like so (simplified, see code for more info):
```rust
// old
match expr {
    Ok(val) => val,
    Err(err) => return Err(err),
}

// new
match expr {
    Ok(val) => val,
    Err(err) => core::convert::absurd(return Err(err)),
}

// core::convert
pub const fn absurd<T>(x: !) -> T { x }
```

This prevents `!` from the `return` from skewing inference:
```rust
// previously: ok (never type spontaneous decay skews inference, `T = ()`)
// with this pr: can't infer the type for `T`
Err(())?;
```

Fixes rust-lang#51125
Closes rust-lang#39216
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 5, 2024
…-operator-to-not-screw-with-inference-will-it-obey, r=<try>

Stop skewing inference in ?'s desugaring

**NB**: this is a breaking change (although arguably a bug fix) and as such shouldn't be taken lightly.

This changes `expr?`'s desugaring like so (simplified, see code for more info):
```rust
// old
match expr {
    Ok(val) => val,
    Err(err) => return Err(err),
}

// new
match expr {
    Ok(val) => val,
    Err(err) => core::convert::absurd(return Err(err)),
}

// core::convert
pub const fn absurd<T>(x: !) -> T { x }
```

This prevents `!` from the `return` from skewing inference:
```rust
// previously: ok (never type spontaneous decay skews inference, `T = ()`)
// with this pr: can't infer the type for `T`
Err(())?;
```

Fixes rust-lang#51125
Closes rust-lang#39216
@fmease fmease added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue. labels Sep 14, 2024
@fmease fmease changed the title Tracking issue for resolve_trait_on_defaulted_unit compatibility lint Tracking issue for future-incompatibility lint resolve_trait_on_defaulted_unit Sep 14, 2024
@fmease
Copy link
Member

fmease commented Sep 14, 2024

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

@fmease fmease removed the B-unstable Blocker: Implemented in the nightly compiler and unstable. label Sep 14, 2024
@WaffleLapkin
Copy link
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
Labels
C-future-incompatibility Category: Future-incompatibility lints C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC S-tracking-impl-incomplete Status: The implementation is incomplete. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.