diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 21139c8dde2..9fa2bc8a2a7 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -426,30 +426,26 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     {
         debug!("note_issue_32330: terr={:?}", terr);
         match *terr {
-            TypeError::RegionsInsufficientlyPolymorphic(_, &Region::ReVar(vid)) |
-            TypeError::RegionsOverlyPolymorphic(_, &Region::ReVar(vid)) => {
-                match self.region_vars.var_origin(vid) {
-                    RegionVariableOrigin::EarlyBoundRegion(_, _, Some(Issue32330 {
-                        fn_def_id,
-                        region_name
-                    })) => {
-                        diag.note(
-                            &format!("lifetime parameter `{0}` declared on fn `{1}` \
-                                      appears only in the return type, \
-                                      but here is required to be higher-ranked, \
-                                      which means that `{0}` must appear in both \
-                                      argument and return types",
-                                     region_name,
-                                     self.tcx.item_path_str(fn_def_id)));
-                        diag.note(
-                            &format!("this error is the result of a recent bug fix; \
-                                      for more information, see issue #33685 \
-                                      <https://github.com/rust-lang/rust/issues/33685>"));
-                    }
-                    _ => { }
-                }
+            TypeError::RegionsInsufficientlyPolymorphic(_, _, Some(box Issue32330 {
+                fn_def_id, region_name
+            })) |
+            TypeError::RegionsOverlyPolymorphic(_, _, Some(box Issue32330 {
+                fn_def_id, region_name
+            })) => {
+                diag.note(
+                    &format!("lifetime parameter `{0}` declared on fn `{1}` \
+                              appears only in the return type, \
+                              but here is required to be higher-ranked, \
+                              which means that `{0}` must appear in both \
+                              argument and return types",
+                             region_name,
+                             self.tcx.item_path_str(fn_def_id)));
+                diag.note(
+                    &format!("this error is the result of a recent bug fix; \
+                              for more information, see issue #33685 \
+                              <https://github.com/rust-lang/rust/issues/33685>"));
             }
-            _ => { }
+            _ => {}
         }
     }
 
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs
index e919f025409..e3ffc99c0e9 100644
--- a/src/librustc/infer/higher_ranked/mod.rs
+++ b/src/librustc/infer/higher_ranked/mod.rs
@@ -15,6 +15,7 @@ use super::{CombinedSnapshot,
             InferCtxt,
             LateBoundRegion,
             HigherRankedType,
+            RegionVariableOrigin,
             SubregionOrigin,
             SkolemizationMap};
 use super::combine::CombineFields;
@@ -656,14 +657,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                        skol_br,
                        tainted_region);
 
+                let issue_32330 = if let &ty::ReVar(vid) = tainted_region {
+                    match self.region_vars.var_origin(vid) {
+                        RegionVariableOrigin::EarlyBoundRegion(_, _, issue_32330) => {
+                            issue_32330.map(Box::new)
+                        }
+                        _ => None
+                    }
+                } else {
+                    None
+                };
+
                 if overly_polymorphic {
                     debug!("Overly polymorphic!");
                     return Err(TypeError::RegionsOverlyPolymorphic(skol_br,
-                                                                   tainted_region));
+                                                                   tainted_region,
+                                                                   issue_32330));
                 } else {
                     debug!("Not as polymorphic!");
                     return Err(TypeError::RegionsInsufficientlyPolymorphic(skol_br,
-                                                                           tainted_region));
+                                                                           tainted_region,
+                                                                           issue_32330));
                 }
             }
         }
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 5a696446b4b..73d9c8b00ae 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -39,8 +39,8 @@ pub enum TypeError<'tcx> {
     RegionsDoesNotOutlive(&'tcx Region, &'tcx Region),
     RegionsNotSame(&'tcx Region, &'tcx Region),
     RegionsNoOverlap(&'tcx Region, &'tcx Region),
-    RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region),
-    RegionsOverlyPolymorphic(BoundRegion, &'tcx Region),
+    RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
+    RegionsOverlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
     Sorts(ExpectedFound<Ty<'tcx>>),
     IntMismatch(ExpectedFound<ty::IntVarValue>),
     FloatMismatch(ExpectedFound<ast::FloatTy>),
@@ -116,11 +116,11 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             RegionsNoOverlap(..) => {
                 write!(f, "lifetimes do not intersect")
             }
-            RegionsInsufficientlyPolymorphic(br, _) => {
+            RegionsInsufficientlyPolymorphic(br, _, _) => {
                 write!(f, "expected bound lifetime parameter {}, \
                            found concrete lifetime", br)
             }
-            RegionsOverlyPolymorphic(br, _) => {
+            RegionsOverlyPolymorphic(br, _, _) => {
                 write!(f, "expected concrete lifetime, \
                            found bound lifetime parameter {}", br)
             }
@@ -253,15 +253,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 self.note_and_explain_region(db, "...does not overlap ",
                                            region2, "");
             }
-            RegionsInsufficientlyPolymorphic(_, conc_region) => {
+            RegionsInsufficientlyPolymorphic(_, conc_region, _) => {
                 self.note_and_explain_region(db, "concrete lifetime that was found is ",
                                            conc_region, "");
             }
-            RegionsOverlyPolymorphic(_, &ty::ReVar(_)) => {
+            RegionsOverlyPolymorphic(_, &ty::ReVar(_), _) => {
                 // don't bother to print out the message below for
                 // inference variables, it's not very illuminating.
             }
-            RegionsOverlyPolymorphic(_, conc_region) => {
+            RegionsOverlyPolymorphic(_, conc_region, _) => {
                 self.note_and_explain_region(db, "expected concrete lifetime is ",
                                            conc_region, "");
             }
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 49824e8a738..9126600e3f6 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -293,11 +293,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
             RegionsNoOverlap(a, b) => {
                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsNoOverlap(a, b))
             }
-            RegionsInsufficientlyPolymorphic(a, b) => {
-                return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b))
+            RegionsInsufficientlyPolymorphic(a, b, ref c) => {
+                let c = c.clone();
+                return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b, c))
             }
-            RegionsOverlyPolymorphic(a, b) => {
-                return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
+            RegionsOverlyPolymorphic(a, b, ref c) => {
+                let c = c.clone();
+                return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b, c))
             }
             IntMismatch(x) => IntMismatch(x),
             FloatMismatch(x) => FloatMismatch(x),
diff --git a/src/test/compile-fail/issue-40000.rs b/src/test/compile-fail/issue-40000.rs
new file mode 100644
index 00000000000..9be114ebcb6
--- /dev/null
+++ b/src/test/compile-fail/issue-40000.rs
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+
+#![feature(closure_to_fn_coercion)]
+
+fn main() {
+    let bar: fn(&mut u32) = |_| {}; //~ ERROR mismatched types
+    //~| expected concrete lifetime, found bound lifetime parameter
+
+    fn foo(x: Box<Fn(&i32)>) {}
+    let bar = Box::new(|x: &i32| {}) as Box<Fn(_)>;
+    foo(bar); //~ ERROR mismatched types
+    //~| expected concrete lifetime, found bound lifetime parameter
+}