Silly question about rust type inferring


#1

Why can not compile:
> fn main() {
> let _u =897.89;
> println!("{}", u.sin());
> }


#2

Perhaps because that literal and that method are compatible with both a computation on f32 and f64. And ambiguities can’t be accepted.


#3

Its strange to me, for the binding must have the CONCRETE type or not? i deem that type of _u is f64 (by default)


#4

Because _u is not the same as u.


#5

it is my typing error… the problem is still misty to me


#6

You always need concrete types (except for generics). In the end the compiler has to generate machine code and for this it has to know all types.


#7

well even so once more - why the compiler cannot defer correct type for the binding… and take an appropriate method in this very simple case


#8

There is no “correct” type.

fn main() {
    let u : f32 = 897.89;
    println!("{}", u.sin()); // -0.56916034
}
fn main() {
    let u : f64 = 897.89;
    println!("{}", u.sin()); // -0.569172373693109
}

Both are correct and give you a different result and different machine code.


#9

i know about… but spoke of another thing…- default type for floating literals…- it is f64 (or f32 - it does not matter which. it may depend on platform but well defined for it… or not?) - so i see no ambiguity. I imply on the simple thing - the type of _u is known BEFORE execution of println!


#10

Unfortunately, that’s simply not the case. For integers, we can just assume i32 because it “just works” unless you’re dealing with large numbers (usually, numbers in programs are small, e.g. counters). However, the size of a float affects it’s precision so f32 and f64 will behave differently even for small numbers.

@troplin’s point is that a program where u is an f32 is a very different program (it literally prints out a different answer) than one where u is an f64.


#11

Oh, my bad, you’re right. I wasn’t aware of the default types.
Type inference is not strictly forward, so “known before” doesn’t really matter.

My guess is, that the sin() method confuses the type inference engine, because f32::sin and f64::sin have the same name but are completely unrelated.
Normally, the type inference engine has to decide among some set of types that all implement a specific trait. Here that common trait is missing for sin.


#12
  1. but the book states of f64 (as default for floats and i32 for integers) is it wrong? or it is just the type deferring problem for current realization of rustc
  2. what is the real type of _u

#13

I think this the problem is, that default types are only considered if type inference is ambiguous.
The type inference engine tries to resolve sin, which is not possible at that time, because default types are only decided later.

EDIT: Just to be clear, I’m trying to guess what’s going on in the compiler. It’s still a bug IMO, you should file an issue if there isn’t already one.


#14

Huh. Your right. I guess I just never use floats.


#15

I think this might be a bug. In other contexts, like a trait being implemented for both, it does default to f64.