diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 45b0a571bd08a..fb3be84931992 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -126,6 +126,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (sig, kind) } ty::TyInfer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), + ty::TyFnPtr(sig) => (Some(sig.skip_binder().clone()), Some(ty::ClosureKind::Fn)), _ => (None, None), } } diff --git a/src/test/compile-fail/closure-no-fn.rs b/src/test/compile-fail/closure-no-fn-1.rs similarity index 77% rename from src/test/compile-fail/closure-no-fn.rs rename to src/test/compile-fail/closure-no-fn-1.rs index fe179e8a48f16..10c99703a97ff 100644 --- a/src/test/compile-fail/closure-no-fn.rs +++ b/src/test/compile-fail/closure-no-fn-1.rs @@ -15,10 +15,4 @@ fn main() { let mut a = 0u8; let foo: fn(u8) -> u8 = |v: u8| { a += v; a }; //~^ ERROR mismatched types - let b = 0u8; - let bar: fn() -> u8 = || { b }; - //~^ ERROR mismatched types - let baz: fn() -> u8 = || { b } as fn() -> u8; - //~^ ERROR mismatched types - //~^^ ERROR non-scalar cast } diff --git a/src/test/compile-fail/closure-no-fn-2.rs b/src/test/compile-fail/closure-no-fn-2.rs new file mode 100644 index 0000000000000..a6438bb5f2418 --- /dev/null +++ b/src/test/compile-fail/closure-no-fn-2.rs @@ -0,0 +1,18 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensure that capturing closures are never coerced to fns +// Especially interesting as non-capturing closures can be. + +fn main() { + let b = 0u8; + let bar: fn() -> u8 = || { b }; + //~^ ERROR mismatched types +} diff --git a/src/test/compile-fail/closure-no-fn-3.rs b/src/test/compile-fail/closure-no-fn-3.rs new file mode 100644 index 0000000000000..85dbc899208f6 --- /dev/null +++ b/src/test/compile-fail/closure-no-fn-3.rs @@ -0,0 +1,18 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensure that capturing closures are never coerced to fns +// Especially interesting as non-capturing closures can be. + +fn main() { + let b = 0u8; + let baz: fn() -> u8 = (|| { b }) as fn() -> u8; + //~^ ERROR non-scalar cast +} diff --git a/src/test/compile-fail/issue-40000.rs b/src/test/compile-fail/issue-40000.rs index 9be114ebcb6e0..3ccee0f12becb 100644 --- a/src/test/compile-fail/issue-40000.rs +++ b/src/test/compile-fail/issue-40000.rs @@ -11,8 +11,7 @@ #![feature(closure_to_fn_coercion)] fn main() { - let bar: fn(&mut u32) = |_| {}; //~ ERROR mismatched types - //~| expected concrete lifetime, found bound lifetime parameter + let bar: fn(&mut u32) = |_| {}; fn foo(x: Box) {} let bar = Box::new(|x: &i32| {}) as Box; diff --git a/src/test/run-pass/closure_to_fn_coercion-expected-types.rs b/src/test/run-pass/closure_to_fn_coercion-expected-types.rs new file mode 100644 index 0000000000000..7214ebfaf0703 --- /dev/null +++ b/src/test/run-pass/closure_to_fn_coercion-expected-types.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// Ensure that we deduce expected argument types when a `fn()` type is expected (#41755) + +#![feature(closure_to_fn_coercion)] +fn foo(f: fn(Vec) -> usize) { } + +fn main() { + foo(|x| x.len()) +}