Considere el siguiente código Rust:
fn f() -> i32 {
loop {
println!("Infinite loop!");
}
println!("Unreachable");
}
Esto compila (con una advertencia) y se ejecuta, a pesar de que el tipo de retorno es incorrecto. Parece que el compilador está bien con el tipo de retorno de ()
en la última línea porque detecta que este código es inalcanzable.
Sin embargo, si eliminamos el último punto y coma:
fn f() -> i32 {
loop {
println!("Infinite loop!");
}
println!("Unreachable")
}
Entonces el código ya no se compila, dando un error de tipo:
error[E0308]: mismatched types
--> src/main.rs:14:5
|
14 | println!("Unreachable")
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `()`
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
¿Por qué es esto? ¿No es el mismo tipo de retorno ()
, en ambos fragmentos de código?
Nota: Estoy interesado en comprender por qué el compilador Rust se comporta de manera diferente en estos dos ejemplos, es decir, cómo se implementa el compilador Rust. No quise hacer una pregunta filosófica sobre cómo "debería" comportarse, desde la perspectiva del diseño del lenguaje (entiendo que tal pregunta probablemente estaría fuera de tema).
!
como el tipo de retorno debido al bucle infinito, lo cual tiene sentido. En el segundo caso, hay una expresión de retorno, por lo que el solucionador de inferencia de tipos la usa para inferir el tipo, lo que también tiene sentido. No creo que esto esté especificado en la referencia del lenguaje, ni creo que importe de ninguna manera, solo omita la declaración inalcanzable y estará bien.