}
}
+ fn tstore_to_closure(s: &TraitStore) -> ~str {
+ match s {
+ &UniqTraitStore => "proc".to_owned(),
+ &RegionTraitStore(..) => "closure".to_owned()
+ }
+ }
+
match *err {
terr_mismatch => "types differ".to_owned(),
terr_fn_style_mismatch(values) => {
values.expected.to_str(), values.found.to_str())
}
terr_sigil_mismatch(values) => {
- format!("expected {} closure, found {} closure",
- values.expected.to_str(),
- values.found.to_str())
+ format!("expected {}, found {}",
+ tstore_to_closure(&values.expected),
+ tstore_to_closure(&values.found))
}
terr_mutability => "values differ in mutability".to_owned(),
terr_box_mutability => "boxed values differ in mutability".to_owned(),
let expected_sty = unpack_expected(fcx,
expected,
|x| Some((*x).clone()));
- let error_happened = false;
let (expected_sig,
expected_onceness,
expected_bounds) = {
replace_late_bound_regions_in_fn_sig(
tcx, &cenv.sig,
|_| fcx.inh.infcx.fresh_bound_region(expr.id));
- (Some(sig), cenv.onceness, cenv.bounds)
+ let onceness = match (&store, &cenv.store) {
+ // As the closure type and onceness go, only three
+ // combinations are legit:
+ // once closure
+ // many closure
+ // once proc
+ // If the actual and expected closure type disagree with
+ // each other, set expected onceness to be always Once or
+ // Many according to the actual type. Otherwise, it will
+ // yield either an illegal "many proc" or a less known
+ // "once closure" in the error message.
+ (&ty::UniqTraitStore, &ty::UniqTraitStore) |
+ (&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) =>
+ cenv.onceness,
+ (&ty::UniqTraitStore, _) => ast::Once,
+ (&ty::RegionTraitStore(..), _) => ast::Many,
+ };
+ (Some(sig), onceness, cenv.bounds)
}
_ => {
// Not an error! Means we're inferring the closure type
store,
decl,
expected_sig);
-
- let fty_sig;
- let fty = if error_happened {
- fty_sig = FnSig {
- binder_id: ast::CRATE_NODE_ID,
- inputs: fn_ty.sig.inputs.iter().map(|_| ty::mk_err()).collect(),
- output: ty::mk_err(),
- variadic: false
- };
- ty::mk_err()
- } else {
- fty_sig = fn_ty.sig.clone();
- ty::mk_closure(tcx, fn_ty.clone())
- };
-
- debug!("check_expr_fn_with_unifier fty={}",
- fcx.infcx().ty_to_str(fty));
+ let fty_sig = fn_ty.sig.clone();
+ let fty = ty::mk_closure(tcx, fn_ty);
+ debug!("check_expr_fn fty={}", fcx.infcx().ty_to_str(fty));
fcx.write_ty(expr.id, fty);
--- /dev/null
+// Copyright 2012-2014 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.
+
+// Test that a mismatched proc / closure type is correctly reported.
+
+fn expect_closure(_: ||) {}
+
+fn expect_proc(_: proc()) {}
+
+fn main() {
+ expect_closure(proc() {});
+ //~^ ERROR mismatched types: expected `||` but found `proc()` (expected closure, found proc)
+
+ expect_proc(|| {});
+ //~^ ERROR mismatched types: expected `proc()` but found `||` (expected proc, found closure)
+}