diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index 2e8b843d07b30..6a1f8f1d06927 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 6b9cbabf20e97..003af204f1ed7 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 ce2bb23660ce0..31ed61a919e7c 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 28a73f4a4d387..b91eb3ec68ffa 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 0000000000000..f55d584ea24fb --- /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 or the MIT license +// , 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: F) -> F::Output { + From::from(f()) +} + +fn main() { + let result = panic::catch_unwind(move || test()); + assert!(result.is_err()); +}