From e78f6319dd13e9a12fb4e15c6897913227209611 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 6 Apr 2015 22:17:35 +0900 Subject: [PATCH] Fix diverging closures --- src/librustc/middle/traits/util.rs | 2 +- src/librustc/middle/ty.rs | 7 +++++++ src/librustc_typeck/check/callee.rs | 5 +++-- src/test/run-fail/diverging-closure.rs | 18 ++++++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 src/test/run-fail/diverging-closure.rs diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 297cea13207e5..a8a1ce2806767 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -506,7 +506,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 1123c9236312a..6f213b5713457 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 3f9c14e0afe39..f54c0b7f8c4a4 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 0000000000000..6b98e0397b5a3 --- /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(); +}