# Regarding type inference of numeric types with closures

**URL:** <https://internals.rust-lang.org/t/regarding-type-inference-of-numeric-types-with-closures/7185>\
**Category:** language design\
**Created:** [March 30, 2018, 1:18pm UTC](https://internals.rust-lang.org/t/regarding-type-inference-of-numeric-types-with-closures/7185 "2018-03-30T13:18:15Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bzar](https://avatars.discourse-cdn.com/v4/letter/b/e99b99/32.png) [@bzar](https://internals.rust-lang.org/u/bzar)\
**Post date:** [March 30, 2018, 1:18pm UTC](https://internals.rust-lang.org/t/regarding-type-inference-of-numeric-types-with-closures/7185/1 "2018-03-30T13:18:15Z")

</div>

(I made [this post](https://www.reddit.com/r/rust/comments/87yxrq/regarding_type_inference_of_numeric_types_with/) on reddit and received a suggestion to repost it here.)

I noticed yesterday a curious property of type inference in Rust. The following does not work:

```
Box::new(|| 1) as Box<Fn() -> u32>

```

Rust first infers the closure return type as i32, creates a box of that, then attempts to convert it into a trait object with incorrect return type u32.

However, the following does work:

```
fn box_fn<F, R>(f: F) -> Box<Fn() -> R> where F: Fn() -> R + 'static {
    Box::new(f) as Box<Fn() -> R>
}
fn requires_u32(f: Box<Fn() -> u32>) -> u32 {
    f()
}
requires_u32(box_fn(|| 1));

```

Now the very generic closure wrapper needs to get its types straight first, which it does by figuring the calling expression needs a Fn() -\> u32, matching the R type as such. Then the lambda is created within this explicitly u32 return value requiring context, making it all work out.

Could such inferrence be extended to type conversions such as in the first bit of code? Such that the conversion would be evaluated first as requiring something convertable into a specific type, which could be used to guide type inferrence on the left side?

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [March 31, 2018, 4:56am UTC](https://internals.rust-lang.org/t/regarding-type-inference-of-numeric-types-with-closures/7185/2 "2018-03-31T04:56:51Z")

</div>

Another thing that works

```rust
let _: Box<Fn() -> u32> = Box::new(|| 1);

```

Sadly `#![feature(type_ascription)]` doesn’t work, since it can’t coerce (yet?):

```rust
error[E0308]: mismatched types
 --> src/main.rs:3:5
  |
3 | Box::new(|| 1): Box<Fn() -> u32>;
  | ^^^^^^^^^^^^^^ expected trait std::ops::Fn, found closure
  |
  = note: expected type `std::boxed::Box<std::ops::Fn() -> u32>`
             found type `std::boxed::Box<[closure@src/main.rs:3:14: 3:18]>`

```

---

<div class="post-metadata">

**Author:** ![leodasvacas](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/leodasvacas/32/4060_2.png) [@leodasvacas](https://internals.rust-lang.org/u/leodasvacas)\
**Post date:** [April 2, 2018, 11:59am UTC](https://internals.rust-lang.org/t/regarding-type-inference-of-numeric-types-with-closures/7185/3 "2018-04-02T11:59:05Z")

</div>

I’ve been [fiddling with this stuff](https://github.com/rust-lang/rust/pull/46714). Right now we do numeric fallback to `i32` before checking cast coercions. This is backwards incompatible to change, consider this:

```rust
   let cap = 512 * 512;
  cap as u8;
  // Assert `cap` did not get inferred to `u8` and overflowed.
  assert_ne!(cap, 0);

```

If we changed this behaviour we’d infer `cap` to `u8` which might not be desirable. So even though it’s not always ideal it seems unlikely that we will want to change this behaviour.

---

<div class="post-metadata">

**Author:** ![bzar](https://avatars.discourse-cdn.com/v4/letter/b/e99b99/32.png) [@bzar](https://internals.rust-lang.org/u/bzar)\
**Post date:** [April 7, 2018, 9:01am UTC](https://internals.rust-lang.org/t/regarding-type-inference-of-numeric-types-with-closures/7185/4 "2018-04-07T09:01:46Z")

</div>

That’s a **really** good point! Though I suppose `as` doesn’t need to actually change the inferrence as long as the left side is castable to the right side? So it more should restrict the types the left side _can_ be rather than dicate what it _should_ be?

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:29am UTC](https://internals.rust-lang.org/t/regarding-type-inference-of-numeric-types-with-closures/7185/5 "2019-03-25T08:29:59Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
