diff options
| author | James Miller <james@aatch.net> | 2016-08-31 16:40:43 +1200 |
|---|---|---|
| committer | James Miller <james@aatch.net> | 2016-08-31 16:43:14 +1200 |
| commit | e0279d71926d0fd7925f55f600bc9947dd070e68 (patch) | |
| tree | 9eda0dcbca81bdafa21bafca8ab970f0b1661ea3 | |
| parent | eac41469d778d18ae7bf38fa917ed0fe122f944b (diff) | |
| download | rust-e0279d71926d0fd7925f55f600bc9947dd070e68.tar.gz rust-e0279d71926d0fd7925f55f600bc9947dd070e68.zip | |
Normalize the function signature of closures
Previously we didn't normalize the function signatures used for closures. This didn't cause a problem in most cases, but caused an ICE in during MIR type checking. Fixes #36139
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 7 | ||||
| -rw-r--r-- | src/librustc_typeck/check/closure.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/issue-36139-normalize-closure-sig.rs | 28 |
3 files changed, 36 insertions, 1 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f24a7cf2121..844b39c6d16 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1877,11 +1877,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { hir::DefaultReturn(..) => self.tcx().mk_nil(), }; + let input_tys = self_ty.into_iter().chain(arg_tys).collect(); + + debug!("ty_of_method_or_bare_fn: input_tys={:?}", input_tys); + debug!("ty_of_method_or_bare_fn: output_ty={:?}", output_ty); + (self.tcx().mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, sig: ty::Binder(ty::FnSig { - inputs: self_ty.into_iter().chain(arg_tys).collect(), + inputs: input_tys, output: output_ty, variadic: decl.variadic }), diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 46e8c27f6d3..aa61974e039 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -74,6 +74,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let fn_sig = self.tcx.liberate_late_bound_regions( self.tcx.region_maps.call_site_extent(expr.id, body.id), &fn_ty.sig); + let fn_sig = + (**self).normalize_associated_types_in(body.span, body.id, &fn_sig); check_fn(self, hir::Unsafety::Normal, expr.id, &fn_sig, decl, expr.id, &body); diff --git a/src/test/run-pass/issue-36139-normalize-closure-sig.rs b/src/test/run-pass/issue-36139-normalize-closure-sig.rs new file mode 100644 index 00000000000..adde0ed3066 --- /dev/null +++ b/src/test/run-pass/issue-36139-normalize-closure-sig.rs @@ -0,0 +1,28 @@ +// Copyright 2016 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. + +// Previously the closure's argument would be inferred to +// <S as ITrait<'a>>::Item, causing an error in MIR type +// checking + +trait ITrait<'a> {type Item;} + +struct S {} + +impl<'a> ITrait<'a> for S { type Item = &'a mut usize; } + +fn m<T, I, F>(_: F) + where I: for<'a> ITrait<'a>, + F: for<'a> FnMut(<I as ITrait<'a>>::Item) { } + + +fn main() { + m::<usize,S,_>(|x| { *x += 1; }); +} |
