Change:
The error here is extremely unclear to me: Not sure if actually a bug in rust (That's my intuition, this looks very valid to me) or just an issue where the error message is incredibly unhelpful.
The error is a bit confusing if you're not familiar with closures. Check out the chapters on and in the book to understand the semantics and performance tradeoffs. Currently in Rust, no two closures, even if identical, have the same type. Closures are essentially anonymous structs (containing the environment they close over) expanded at compile time, and made to impl the Fn* family of traits. In your code, producing a bare closure from a match arm that could produce other closures is not possible. You must use trait objects. The easiest approach would probably be to just box each closure, and coerce it into a trait object with a type annotation. There may be other ways to accomplish what you want. And if you aren't closing over your environment, just use function pointers. Or if your situation ultimately allows for it, use generics in some way.
Sorry, I forgot to mention that this is a regression from about a week ago when built On Friday, April 3, 2015, ebfull wrote:
Closures in rust used to be "boxed" so they acted similar to my first example solution.
Great fix, and thanks for the explaination!
If you're satisfied the issue can be closed now.
Thanks!

Discussion:
fn report_and_explain_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::type_err<'tcx>) { <ins> let span = trace.origin.span(); </ins> self.report_type_error(trace, terr); <del> ty::note_and_explain_type_err(self.tcx, terr); </del> <ins> ty::note_and_explain_type_err(self.tcx, terr, span); </ins> } /// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived

} self.give_suggestion(same_regions); for &(ref trace, terr) in trace_origins { <del> self.report_type_error(trace.clone(), &terr); </del> <ins> self.report_and_explain_type_error(trace.clone(), &terr); </ins> } }

error_str)); if let Some(err) = err { <del> ty::note_and_explain_type_err(self.tcx, err) </del> <ins> ty::note_and_explain_type_err(self.tcx, err, sp) </ins> } } }

} } <del> pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) { </del> <ins> pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>, sp: Span) { </ins> match *err { terr_regions_does_not_outlive(subregion, superregion) => { note_and_explain_region(cx, "", subregion, "...");

"expected concrete lifetime is ", conc_region, ""); } <ins> terr_sorts(values) => { let expected_str = ty_sort_string(cx, values.expected); let found_str = ty_sort_string(cx, values.found); if expected_str == found_str && expected_str == "closure" { cx.sess.span_note(sp, &format!("no two closures, even if identical, have the same  type")); cx.sess.span_help(sp, &format!("consider boxing your closure and/or  using it as a trait object")); } } </ins> _ => {} } }

self.diagnostic().handler().note(msg) } pub fn help(&self, msg: &str) { <del> self.diagnostic().handler().note(msg) </del> <ins> self.diagnostic().handler().help(msg) </ins> } pub fn opt_span_bug(&self, opt_sp: Option<Span>, msg: &str) -> ! { match opt_sp {

.ty_to_string( actual_structure_type), type_error_description); <del> ty::note_and_explain_type_err(tcx, &type_error); </del> <ins> ty::note_and_explain_type_err(tcx, &type_error, path.span); </ins> } } }

msg(), ty::type_err_to_str(tcx, terr)); <del> ty::note_and_explain_type_err(tcx, terr); </del> <ins> ty::note_and_explain_type_err(tcx, terr, span); </ins> false } }

<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn closure_to_loc() { let mut x = |c| c + 1; x = |c| c + 1; //~^ ERROR mismatched types //~| NOTE no two closures, even if identical, have the same type //~| HELP consider boxing your closure and/or using it as a trait object } fn closure_from_match() { let x = match 1usize { 1 => |c| c + 1, 2 => |c| c - 1, _ => |c| c - 1 }; //~^^^^^ ERROR match arms have incompatible types //~| NOTE no two closures, even if identical, have the same type //~| HELP consider boxing your closure and/or using it as a trait object } fn main() { } </ins>