about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/infer/resolve.rs10
-rw-r--r--src/librustc/ty/context.rs2
-rw-r--r--src/librustc/ty/flags.rs5
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/test/run-pass/issue-43853.rs24
5 files changed, 39 insertions, 4 deletions
diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs
index 2e8b843d07b..6a1f8f1d069 100644
--- a/src/librustc/infer/resolve.rs
+++ b/src/librustc/infer/resolve.rs
@@ -111,8 +111,10 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
     }
 
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-        if !t.needs_infer() {
+        if !t.needs_infer() && !ty::keep_local(&t) {
             t // micro-optimize -- if there is nothing in this type that this fold affects...
+                // ^ we need to have the `keep_local` check to un-default
+                // defaulted tuples.
         } else {
             let t = self.infcx.shallow_resolve(t);
             match t.sty {
@@ -131,6 +133,12 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
                 ty::TyInfer(_) => {
                     bug!("Unexpected type in full type resolver: {:?}", t);
                 }
+                ty::TyTuple(tys, true) => {
+                    // Un-default defaulted tuples - we are going to a
+                    // different infcx, and the default will just cause
+                    // pollution.
+                    self.tcx().intern_tup(tys, false)
+                }
                 _ => {
                     t.super_fold_with(self)
                 }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 6b9cbabf20e..003af204f1e 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1195,7 +1195,7 @@ macro_rules! direct_interners {
     }
 }
 
-fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
+pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
     x.has_type_flags(ty::TypeFlags::KEEP_IN_LOCAL_TCX)
 }
 
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index ce2bb23660c..31ed61a919e 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -151,7 +151,10 @@ impl FlagComputation {
                 self.add_ty(m.ty);
             }
 
-            &ty::TyTuple(ref ts, _) => {
+            &ty::TyTuple(ref ts, is_default) => {
+                if is_default {
+                    self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX);
+                }
                 self.add_tys(&ts[..]);
             }
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 28a73f4a4d3..b91eb3ec68f 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -76,7 +76,7 @@ pub use self::sty::TypeVariants::*;
 pub use self::binding::BindingMode;
 pub use self::binding::BindingMode::*;
 
-pub use self::context::{TyCtxt, GlobalArenas, tls};
+pub use self::context::{TyCtxt, GlobalArenas, tls, keep_local};
 pub use self::context::{Lift, TypeckTables};
 
 pub use self::instance::{Instance, InstanceDef};
diff --git a/src/test/run-pass/issue-43853.rs b/src/test/run-pass/issue-43853.rs
new file mode 100644
index 00000000000..f55d584ea24
--- /dev/null
+++ b/src/test/run-pass/issue-43853.rs
@@ -0,0 +1,24 @@
+// 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.
+
+use std::panic;
+
+fn test() {
+    wait(|| panic!());
+}
+
+fn wait<T, F: FnOnce() -> T>(f: F) -> F::Output {
+    From::from(f())
+}
+
+fn main() {
+    let result = panic::catch_unwind(move || test());
+    assert!(result.is_err());
+}