diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 3a1be785580a..ddf941198eb0 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -477,7 +477,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>( def_id: fn_trait_def_id, substs: tcx.mk_substs(trait_substs), }); - ty::Binder((trait_ref, sig.0.output.unwrap())) + ty::Binder((trait_ref, sig.0.output.unwrap_or(ty::mk_nil(tcx)))) } impl<'tcx,O:Repr<'tcx>> Repr<'tcx> for super::Obligation<'tcx, O> { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9c8f30902baa..952996c90f52 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1092,6 +1092,13 @@ impl<'tcx> FnOutput<'tcx> { ty::FnDiverging => unreachable!() } } + + pub fn unwrap_or(self, def: Ty<'tcx>) -> Ty<'tcx> { + match self { + ty::FnConverging(t) => t, + ty::FnDiverging => def + } + } } pub type PolyFnOutput<'tcx> = Binder>; diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 3f9c14e0afe3..f54c0b7f8c4a 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -387,10 +387,11 @@ impl<'tcx> DeferredCallResolution<'tcx> for CallResolution<'tcx> { demand::eqtype(fcx, self.call_expr.span, self_arg_ty, method_arg_ty); } + let nilty = ty::mk_nil(fcx.tcx()); demand::eqtype(fcx, self.call_expr.span, - method_sig.output.unwrap(), - self.fn_sig.output.unwrap()); + method_sig.output.unwrap_or(nilty), + self.fn_sig.output.unwrap_or(nilty)); write_overloaded_call_method_map(fcx, self.call_expr, method_callee); } diff --git a/src/test/run-fail/diverging-closure.rs b/src/test/run-fail/diverging-closure.rs new file mode 100644 index 000000000000..6b98e0397b5a --- /dev/null +++ b/src/test/run-fail/diverging-closure.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern:oops + +fn main() { + let func = || -> ! { + panic!("oops"); + }; + func(); +}