about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonathan Turner <jonathandturner@users.noreply.github.com>2016-09-02 15:28:51 -0700
committerGitHub <noreply@github.com>2016-09-02 15:28:51 -0700
commit9327edd773d6ff0dfb5e6c799ed4016f936f6575 (patch)
treefd0d83a5df5efc21d89d22f2fed000fe8593214f
parent445fe52b7212d10fb6fb9df035ff0fe951c81af5 (diff)
parente0279d71926d0fd7925f55f600bc9947dd070e68 (diff)
downloadrust-9327edd773d6ff0dfb5e6c799ed4016f936f6575.tar.gz
rust-9327edd773d6ff0dfb5e6c799ed4016f936f6575.zip
Rollup merge of #36160 - Aatch:normalize-closure-sig, r=eddyb
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

r? @eddyb
-rw-r--r--src/librustc_typeck/astconv.rs7
-rw-r--r--src/librustc_typeck/check/closure.rs2
-rw-r--r--src/test/run-pass/issue-36139-normalize-closure-sig.rs28
3 files changed, 36 insertions, 1 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 7f655ad3d14..6c9cc5f5e13 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1878,11 +1878,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 516dd9c6422..8980cb90760 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; });
+}