mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 01:34:21 +00:00
auto merge of #13657 : edwardw/rust/ppaux-ice, r=alexcrichton
Closes #13599
This commit is contained in:
commit
92f6b925a9
@ -3331,6 +3331,13 @@ pub fn type_err_to_str(cx: &ctxt, err: &type_err) -> ~str {
|
||||
}
|
||||
}
|
||||
|
||||
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) => {
|
||||
@ -3346,9 +3353,9 @@ pub fn type_err_to_str(cx: &ctxt, err: &type_err) -> ~str {
|
||||
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(),
|
||||
|
@ -2182,7 +2182,6 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
let expected_sty = unpack_expected(fcx,
|
||||
expected,
|
||||
|x| Some((*x).clone()));
|
||||
let error_happened = false;
|
||||
let (expected_sig,
|
||||
expected_onceness,
|
||||
expected_bounds) = {
|
||||
@ -2192,7 +2191,24 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
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
|
||||
@ -2218,23 +2234,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
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);
|
||||
|
||||
|
23
src/test/compile-fail/issue-13599.rs
Normal file
23
src/test/compile-fail/issue-13599.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// 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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user