about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2017-08-14 12:04:52 +0200
committerMichael Woerister <michaelwoerister@posteo>2017-08-14 12:04:52 +0200
commitf2df18579b139216f15a2ea17e27bb980f02a0ab (patch)
tree430f03c56ed38adb2d7382da6ae65527df99f0e4
parentbae4fafdfb756690ee31ac939299380cc559c697 (diff)
downloadrust-f2df18579b139216f15a2ea17e27bb980f02a0ab.tar.gz
rust-f2df18579b139216f15a2ea17e27bb980f02a0ab.zip
Mark closures return via impl-trait as reachable.
-rw-r--r--src/librustc/middle/reachable.rs3
-rw-r--r--src/librustc_privacy/lib.rs1
-rw-r--r--src/test/run-pass/impl-trait/auxiliary/xcrate.rs11
-rw-r--r--src/test/run-pass/impl-trait/xcrate.rs1
4 files changed, 16 insertions, 0 deletions
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index df828c8d8e7..4a608c69d14 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -296,6 +296,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     hir::ImplItemKind::Type(_) => {}
                 }
             }
+            hir_map::NodeExpr(&hir::Expr { node: hir::ExprClosure(.., body, _), .. }) => {
+                self.visit_nested_body(body);
+            }
             // Nothing to recurse on for these
             hir_map::NodeForeignItem(_) |
             hir_map::NodeVariant(_) |
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 9fa5fea20d9..81cf22e3b37 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -448,6 +448,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b
             ty::TyDynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
             ty::TyProjection(ref proj) => Some(proj.item_def_id),
             ty::TyFnDef(def_id, ..) |
+            ty::TyClosure(def_id, ..) |
             ty::TyAnon(def_id, _) => Some(def_id),
             _ => None
         };
diff --git a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs b/src/test/run-pass/impl-trait/auxiliary/xcrate.rs
index be353f6d563..e9074f8c230 100644
--- a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs
+++ b/src/test/run-pass/impl-trait/auxiliary/xcrate.rs
@@ -13,3 +13,14 @@
 pub fn fourway_add(a: i32) -> impl Fn(i32) -> impl Fn(i32) -> impl Fn(i32) -> i32 {
     move |b| move |c| move |d| a + b + c + d
 }
+
+fn some_internal_fn() -> u32 {
+    1
+}
+
+// See #40839
+pub fn return_closure_accessing_internal_fn() -> impl Fn() -> u32 {
+    || {
+        some_internal_fn() + 1
+    }
+}
diff --git a/src/test/run-pass/impl-trait/xcrate.rs b/src/test/run-pass/impl-trait/xcrate.rs
index fe3ed7b3465..6d00c46fa35 100644
--- a/src/test/run-pass/impl-trait/xcrate.rs
+++ b/src/test/run-pass/impl-trait/xcrate.rs
@@ -14,4 +14,5 @@ extern crate xcrate;
 
 fn main() {
     assert_eq!(xcrate::fourway_add(1)(2)(3)(4), 10);
+    xcrate::return_closure_accessing_internal_fn()();
 }