diff --git a/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs new file mode 100644 index 0000000000000..4a08bf28bf3ca --- /dev/null +++ b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs @@ -0,0 +1,39 @@ +//! Test for issue +//! Related to higher-ranked lifetime inference with unboxed closures and FnOnce. + +#![feature(fn_traits, unboxed_closures)] + +fn test FnOnce<(&'x str,)>>(_: F) {} + +struct Compose(F, G); + +impl FnOnce<(T,)> for Compose +where + F: FnOnce<(T,)>, + G: FnOnce<(F::Output,)>, +{ + type Output = G::Output; + extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { + (self.1)((self.0)(x)) + } +} + +struct Str<'a>(&'a str); + +fn mk_str<'a>(s: &'a str) -> Str<'a> { + Str(s) +} + +fn main() { + let _: for<'a> fn(&'a str) -> Str<'a> = mk_str; + let _: for<'a> fn(&'a str) -> Str<'a> = Str; + //~^ ERROR: mismatched types + + test(|_: &str| {}); + test(mk_str); + test(Str); + + test(Compose(|_: &str| {}, |_| {})); + test(Compose(mk_str, |_| {})); + test(Compose(Str, |_| {})); +} diff --git a/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr new file mode 100644 index 0000000000000..a31d99f45d590 --- /dev/null +++ b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/fn-traits-hrtb-coercion.rs:29:45 + | +LL | let _: for<'a> fn(&'a str) -> Str<'a> = Str; + | ------------------------------ ^^^ one type is more general than the other + | | + | expected due to this + | + = note: expected fn pointer `for<'a> fn(&'a _) -> Str<'a>` + found struct constructor `fn(&_) -> Str<'_> {Str::<'_>}` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.