Description
Reproducing steps
This code compiles (and, in my opinion, it shouldn't):
let p = Some(45).and_then({|x|
Some(x * 2)
});
While this doesn't:
let p = Some(45).and_then({|x|
println!("doubling {}", x);
Some(x * 2)
})
Error message 1 (using x)
The error message is absolutely unintuitive and won't help anyone:
<anon>:4:14: 4:15 error: unresolved name `x` [E0425]
<anon>:4 Some(x * 2)
^
error: aborting due to previous error
Error message 2 (not using x)
When the last expression does not use a parameter from the list, the generated error message is even more frightening to newcomers (albeit in retrospect, this one makes more sense):
<anon>:2:22: 5:7 error: the trait `core::ops::FnOnce<(_,)>` is not implemented for the type `core::option::Option<_>` [E0277]
<anon>:2 let p = Some(45).and_then({|x|
<anon>:3 println!("doubling {}", x);
<anon>:4 Some(100 * 2)
<anon>:5 });
<anon>:2:22: 5:7 help: see the detailed explanation for E0277
<anon>:2:22: 5:7 error: the trait `core::ops::FnOnce<(_,)>` is not implemented for the type `core::option::Option<_>` [E0277]
<anon>:2 let p = Some(45).and_then({|x|
<anon>:3 println!("doubling {}", x);
<anon>:4 Some(100 * 2)
<anon>:5 });
<anon>:2:22: 5:7 help: see the detailed explanation for E0277
error: aborting due to 2 previous errors
Proposed solution
Emit a warning when encountering this fallible syntax.
Anecdotic background
Having used a lot of Ruby, I had grown way accustomed to the { |x| x * 2 }
syntax. Although I had seen the proper Rust syntax a couple of times, it never was emphasized and the significance never stuck. I spent 30+ minutes trying to figure out why a println! statement breaks the build, generating a random error message that has no obvious connections to the actual bug at hand. Only after inquiring the IRC channel did a solution unveil itself. It shouldn't happen.