- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
          Fallback {float} to f32 when f32: From<{float}> and add impl From<f16> for f32
          #139087
        
          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
base: master
Are you sure you want to change the base?
Conversation
| Some changes occurred in src/tools/clippy cc @rust-lang/clippy | 
ef59666    to
    bb79c28      
    Compare
  
    
      
        
              This comment has been minimized.
        
        
      
    
  This comment has been minimized.
bb79c28    to
    afe5b7f      
    Compare
  
    
      
        
              This comment has been minimized.
        
        
      
    
  This comment has been minimized.
afe5b7f    to
    f4cb5a7      
    Compare
  
    | @bors try | 
Fallback `{float}` to `f32` when `f32: From<{float}>` and add `impl From<f16> for f32`
Currently, the following code compiles:
```rust
fn foo::<T: Into<f32>>(_: T) {}
fn main() {
    foo(1.0);
}
```
This is because the only `From<{float}>` impl for `f32` is currently `From<f32>`. However, once `impl From<f16> for f32` is added this is no longer the case. This would cause the float literal to fallback to `f64`, subsequently causing a type error as `f32` does not implement `From<f64>`. While this kind of change to type inference isn't technically a breaking change according to Rust's breaking change policy, the previous attempt to add `impl From<f16> for f32` was removed rust-lang#123830 due to the large number of crates affected (by my count, there were root regressions in 42 crates and 52 GitHub repos, not including duplicates). This PR solves this problem by using `f32` as the fallback type for `{float}` when there is a trait predicate of `f32: From<{float}>`. This allows adding `impl From<f16> for f32` without affecting the code that currently compiles (such as the example above; this PR shouldn't affect what is possible on stable).
This PR also allows adding a future-incompatibility warning if the lang team wants one; alternatively this could be expanded in the future into something more general like `@tgross35` suggested in rust-lang#123831 (comment). I think it would be also possible to disallow the `f32` fallback in a future edition.
This will need a crater check.
For reference, I've based the implementation loosely on the existing `calculate_diverging_fallback`. This first commit adds the `f32` fallback and the second adds `impl From<f16> for f32`. I think this falls under the types team, so
r? types
Fixes: rust-lang#123831
Tracking issue: rust-lang#116909
`@rustbot` label +T-lang +T-types +T-libs-api +F-f16_and_f128
To decide on whether a future-incompatibility warning is desired or otherwise (see above):
`@rustbot` label +I-lang-nominated
    | ☀️ Try build successful - checks-actions | 
| @craterbot check | 
| 👌 Experiment  ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more | 
| 🚧 Experiment  ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more | 
| 🚨 Report generation of  🆘 Can someone from the infra team check in on this? @rust-lang/infra | 
| @craterbot retry-report | 
| 🛠️ Generation of the report for  ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more | 
| 🎉 Experiment  
 | 
| 
 Agree with @jackh726 here, and would add that ideally it'd work well enough that we don't need to add the hack at all. | 
| I think Boxy may have hinted at this, but is implementation complexity across both solvers the reason we can't do a more general solution at this time? At a surface level it seems "easy" to solve both the float and int examples by trying  | 
| ☔ The latest upstream changes (presumably #140682) made this pull request unmergeable. Please resolve the merge conflicts. | 
ab64774    to
    6e6d23c      
    Compare
  
    | Talked to @compiler-errors about the more general fallback at all hands. My understanding of the problem is that by the time the solver knows there is an unfulfilled obligation, it is already done solving and has no way to backtrack. So (aiui) it might be possible to infer the type of the literal at the location of the  @Amanieu suggested there might be a way to keep track of the two possible solutions. | 
| In the spirit of brainstorming, I wonder whether pattern types could ever have a role to play here. E.g., in fn f<T: Into<u32>>(_: T) {}
fn main() {
    f(1);
}maybe we could say that the literal falls back to  Of course, pattern types are hard, and are I'm sure especially challenging to combine with floats. cc @oli-obk | 
6e6d23c    to
    b2fa77a      
    Compare
  
    | changes to  | 
| 
 Adding a FCW without the trait impl would require a completely different implementation as the FCW as implemented relies on the float var reaching the fallback stage in order to warn about it. As the added trait impl ( 
 I don't think this would work for float literals due to double rounding. | 
| There seems to be a bit of a split of opinion between "add a FCW and eventually remove the  | 
      
        
              This comment has been minimized.
        
        
      
    
  This comment has been minimized.
b2fa77a    to
    bac7aea      
    Compare
  
    | I've opened a PR to run Crater to measure the impact of the trait impl and FCW at #142723. | 
bac7aea    to
    71c00e2      
    Compare
  
    [crater] Add `impl From<f16> for f32` Crater run to see what the effects of adding `impl From<f16> for f32` without changing the fallback (a.k.a. things that would be caught by the FCW in #139087). This needs a ``@craterbot` check`.
| ☔ The latest upstream changes (presumably #145423) made this pull request unmergeable. Please resolve the merge conflicts. | 
Currently, the following code compiles:
This is because the only
From<{float}>impl forf32is currentlyFrom<f32>. However, onceimpl From<f16> for f32is added this is no longer the case. This would cause the float literal to fallback tof64, subsequently causing a type error asf32does not implementFrom<f64>. While this kind of change to type inference isn't technically a breaking change according to Rust's breaking change policy, the previous attempt to addimpl From<f16> for f32was removed #123830 due to the large number of crates affected (by my count, there were root regressions in 42 crates and 52 GitHub repos, not including duplicates). This PR solves this problem by usingf32as the fallback type for{float}when there is a trait predicate off32: From<{float}>. This allows addingimpl From<f16> for f32without affecting the code that currently compiles (such as the example above; this PR shouldn't affect what is possible on stable).This PR also allows adding a future-incompatibility warning for the fallback to
f32(currently implemented in the third commit) if the lang team wants one (allowing thef32fallback to be removed in the future); alternatively this could be expanded in the future into something more general like @tgross35 suggested in #123831 (comment). I think it would be also possible to disallow thef32fallback in a future edition.As expected, a crater check showed no non-spurious regressions.
For reference, I've based the implementation loosely on the existing
calculate_diverging_fallback. This first commit adds thef32fallback, the second addsimpl From<f16> for f32, and the third adds a FCW lint for thef32fallback. I think this falls under the types team, sor? types
Fixes: #123831
Tracking issue: #116909
@rustbot label +T-lang +T-types +T-libs-api +F-f16_and_f128
To decide on whether a future-incompatibility warning is desired or otherwise (see above):
@rustbot label +I-lang-nominated