Expected Rustc Behavior?

Hi everyone.

I stumbled upon some Rust code that seems syntactically incorrect, but manages to pass rustc (nightly-2020-06-15-x86_64-unknown-linux-gnu).

fn test() {
 let x1_0: std::collections::VecDeque<i32> = std::collections::VecDeque::new();//LAYER:0
 let x2_0: & std::collections::VecDeque<i32> = & x1_0;//LAYER:1
 let x3_0: std::collections::vec_deque::Iter<i32> = x2_0.iter();//LAYER:2
 let x4_0: std::string::String = //LAYER:3
 return;
}
fn main() {
test();
 }

It seems to pass on Rust Playground as well.

I am not sure if why this compiles, given that the entire RHS of the assignment is missing on line 5. My best guess at this point is that, since the new value has a trivial, 1-line, lifetime, it gets optimized away.

Since I am not familiar with rustc internals, I was wondering if this is expected behavior.

Thanks.
~Yoshiki

Rust's syntax is not whitespace sensitive like python, so the fn test() is syntactically same as below:

fn test() {
 let x1_0: std::collections::VecDeque<i32> = std::collections::VecDeque::new();//LAYER:0
 let x2_0: & std::collections::VecDeque<i32> = & x1_0;//LAYER:1
 let x3_0: std::collections::vec_deque::Iter<i32> = x2_0.iter();//LAYER:2
 let x4_0: std::string::String = return;
}

This is valid code since the return is an expression which yields !(never) type so it can be assigned to variable with whatever type. Welcome to the expression-oriented language!

If you need more rationals assigning never typed expression into variable, this is my mental model around the never type. It's clear the return expression never yields actual value since it just return the function out. So it never yields value, it also means it never yields value other than the String type. So coercing ! into String is valid within the type system's guarantee.

4 Likes

Another way to think about these rationales is the question mark operator desugaring:

let value = match maybeValue {
    Some(value) => value,
    None => return None,
};

In this case, expression return None must be assignable to the type of value.

1 Like

@Hyeonu and @Cerberuser.

Thank you for the detailed answer.

I've never thought of return as having a type, but now that I think about it, it would be weird if it didn't.

I find the static semantics of the !/never type a quite an interesting choice. From the naming, it feels like it is an "uninhabitable" type, but it can be safely assigned because no operation can be done after return.

Thank you again for the answer.

It is indeed an uninhabitable type.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.