rust-lang / rust-lang/rust

Type inference failure when f64 ops are not explicitly stated

Open
#122,595 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-inference C-bug T-compiler T-lang
Dominant language
Rust
Stars
119k
Forks
16.2k
PR merge metrics
PR metrics pending

Description

I tried this code:

use std::ops::Add;

fn some_op<T>(a: &f64, b: &T) -> T
where
    for <'a> &'a f64: Add<&'a T, Output = T>
    {
        let t = 2.5_f64;
        &(a + &t) + b
    }

#[derive(Debug)]
struct MyStruct {
    val: f64
}

impl Add<&MyStruct> for &f64 {
    type Output = MyStruct;
    fn add(self, other: &MyStruct) -> MyStruct {
        MyStruct {val: self + other.val}
    }
}

fn main() {
    let a = 1.5_f64;
    let b = MyStruct{val: 3.5_f64};
    println!("{:?}", some_op(&a, &b));
}

This code is valid due to the implementation of Add<&f64> for &f64 in the standard library.
The compiler reports this error:

error[E0308]: mismatched types
 --> src/main.rs:8:15
  |
3 | fn some_op<T>(a: &f64, b: &T) -> T
  |            - expected this type parameter
...
8 |         &(a + &t) + b
  |               ^^ expected `&T`, found `&f64`
  |
  = note: expected reference `&T`
             found reference `&f64`

error[E0369]: cannot add `&T` to `&T`
 --> src/main.rs:8:19
  |
8 |         &(a + &t) + b
  |         --------- ^ - &T
  |         |
  |         &T
  |
help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
  |
5 |     for <'a> &'a f64: Add<&'a T, Output = T>, &T: Add<&T, Output = T>
  |                                             +++++++++++++++++++++++++

The expected type is not necessary and E0308 should not appear and finding f64 is correct.
If the following bound is added the code compiles without issue:

fn some_op<T>(a: &f64, b: &T) -> T
where
    for <'a> &'a f64: Add<&'a T, Output = T> + Add<&'a f64, Output = f64>
Meta

rustc --version --verbose:

1.76.0
Also tested nightly. 1.78.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the supplied Rust reproducer with the stable and nightly versions mentioned in the issue, then reduce it while preserving the type-inference failure. Done means the valid example no longer produces the E0308 error or requires the additional f64 bound, with behavior checked against a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.