diff --git a/.travis.yml b/.travis.yml index 87197a37f1d..0abd858d822 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ services: # our configure script, so disable auto submodule management. git: submodules: false + depth: 1 before_install: - docker build -t rust -f src/etc/Dockerfile src/etc diff --git a/src/etc/Dockerfile b/src/etc/Dockerfile index 94be84a3ebd..83d54789ff3 100644 --- a/src/etc/Dockerfile +++ b/src/etc/Dockerfile @@ -23,11 +23,5 @@ RUN apt-get update && apt-get -y install \ libedit-dev zlib1g-dev \ llvm-3.7-tools cmake -# When we compile compiler-rt we pass it the llvm-config we just installed on -# the system, but unfortunately it doesn't infer correctly where -# LLVMConfig.cmake is so we need to coerce it a bit... -RUN mkdir -p /usr/lib/llvm-3.7/build/share/llvm -RUN ln -s /usr/share/llvm-3.7/cmake /usr/lib/llvm-3.7/build/share/llvm/cmake - RUN mkdir /build WORKDIR /build diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 7fc6e54d69f..21387a1aa95 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -49,7 +49,6 @@ #![feature(specialization)] #![feature(staged_api)] #![feature(step_by)] -#![feature(unboxed_closures)] #![feature(unicode)] #![feature(unique)] #![feature(unsafe_no_drop_flag)] diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index ccef6c02f9d..ff2b8cdea22 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -577,15 +577,13 @@ impl [T] { /// /// # Example /// - /// Print the slice two elements at a time (i.e. `[1,2]`, - /// `[3,4]`, `[5]`): - /// - /// ```rust - /// let v = &[1, 2, 3, 4, 5]; - /// - /// for chunk in v.chunks(2) { - /// println!("{:?}", chunk); - /// } + /// ``` + /// let slice = ['l', 'o', 'r', 'e', 'm']; + /// let mut iter = slice.chunks(2); + /// assert_eq!(iter.next().unwrap(), &['l', 'o']); + /// assert_eq!(iter.next().unwrap(), &['r', 'e']); + /// assert_eq!(iter.next().unwrap(), &['m']); + /// assert!(iter.next().is_none()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index ef0042808f9..9428b4096bf 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -31,7 +31,6 @@ #![feature(step_by)] #![feature(test)] #![feature(try_from)] -#![feature(unboxed_closures)] #![feature(unicode)] #![feature(unique)] diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index a06fc21764d..aded220c0cd 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -867,7 +867,7 @@ pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) { } } -#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq)] pub struct IdRange { pub min: NodeId, pub max: NodeId, @@ -893,6 +893,7 @@ impl IdRange { self.min = cmp::min(self.min, id); self.max = cmp::max(self.max, id + 1); } + } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 960e32ae99f..aed3613f44e 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -32,6 +32,7 @@ use hir::print as pprust; use arena::TypedArena; use std::cell::RefCell; +use std::cmp; use std::io; use std::mem; @@ -127,7 +128,10 @@ impl<'ast> MapEntry<'ast> { EntryStructCtor(id, _) => id, EntryLifetime(id, _) => id, EntryTyParam(id, _) => id, - _ => return None + + NotPresent | + RootCrate | + RootInlinedParent(_) => return None, }) } @@ -196,6 +200,10 @@ pub struct Map<'ast> { map: RefCell>>, definitions: RefCell, + + /// All NodeIds that are numerically greater or equal to this value come + /// from inlined items. + local_node_id_watermark: NodeId, } impl<'ast> Map<'ast> { @@ -550,6 +558,13 @@ impl<'ast> Map<'ast> { } } + pub fn expect_inlined_item(&self, id: NodeId) -> &'ast InlinedItem { + match self.find_entry(id) { + Some(RootInlinedParent(inlined_item)) => inlined_item, + _ => bug!("expected inlined item, found {}", self.node_to_string(id)), + } + } + /// Returns the name associated with the given NodeId's AST. pub fn name(&self, id: NodeId) -> Name { match self.get(id) { @@ -649,6 +664,10 @@ impl<'ast> Map<'ast> { pub fn node_to_user_string(&self, id: NodeId) -> String { node_id_to_string(self, id, false) } + + pub fn is_inlined(&self, id: NodeId) -> bool { + id >= self.local_node_id_watermark + } } pub struct NodesMatchingSuffix<'a, 'ast:'a> { @@ -765,13 +784,37 @@ pub trait FoldOps { } /// A Folder that updates IDs and Span's according to fold_ops. -struct IdAndSpanUpdater { - fold_ops: F +pub struct IdAndSpanUpdater { + fold_ops: F, + min_id_assigned: NodeId, + max_id_assigned: NodeId, +} + +impl IdAndSpanUpdater { + pub fn new(fold_ops: F) -> IdAndSpanUpdater { + IdAndSpanUpdater { + fold_ops: fold_ops, + min_id_assigned: ::std::u32::MAX, + max_id_assigned: ::std::u32::MIN, + } + } + + pub fn id_range(&self) -> intravisit::IdRange { + intravisit::IdRange { + min: self.min_id_assigned, + max: self.max_id_assigned + 1, + } + } } impl Folder for IdAndSpanUpdater { fn new_id(&mut self, id: NodeId) -> NodeId { - self.fold_ops.new_id(id) + let id = self.fold_ops.new_id(id); + + self.min_id_assigned = cmp::min(self.min_id_assigned, id); + self.max_id_assigned = cmp::max(self.max_id_assigned, id); + + id } fn new_span(&mut self, span: Span) -> Span { @@ -802,11 +845,14 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest, entries, vector_length, (entries as f64 / vector_length as f64) * 100.); } + let local_node_id_watermark = map.len() as NodeId; + Map { forest: forest, dep_graph: forest.dep_graph.clone(), map: RefCell::new(map), definitions: RefCell::new(definitions), + local_node_id_watermark: local_node_id_watermark } } @@ -818,7 +864,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, ii: InlinedItem, fold_ops: F) -> &'ast InlinedItem { - let mut fld = IdAndSpanUpdater { fold_ops: fold_ops }; + let mut fld = IdAndSpanUpdater::new(fold_ops); let ii = match ii { II::Item(i) => II::Item(i.map(|i| fld.fold_item(i))), II::TraitItem(d, ti) => { @@ -835,6 +881,12 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let ii = map.forest.inlined_items.alloc(ii); let ii_parent_id = fld.new_id(DUMMY_NODE_ID); + // Assert that the ii_parent_id is the last NodeId in our reserved range + assert!(ii_parent_id == fld.max_id_assigned); + // Assert that we did not violate the invariant that all inlined HIR items + // have NodeIds greater than or equal to `local_node_id_watermark` + assert!(fld.min_id_assigned >= map.local_node_id_watermark); + let defs = &mut *map.definitions.borrow_mut(); let mut def_collector = DefCollector::extend(ii_parent_id, parent_def_path.clone(), diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 484aacfd9ec..32344a7b9c8 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -120,12 +120,6 @@ pub struct ChildItem { pub vis: ty::Visibility, } -pub enum FoundAst<'ast> { - Found(&'ast InlinedItem), - FoundParent(DefId, &'ast hir::Item), - NotFound, -} - #[derive(Copy, Clone, Debug)] pub struct ExternCrate { /// def_id of an `extern crate` in the current crate that caused @@ -250,7 +244,10 @@ pub trait CrateStore<'tcx> { // misc. metadata fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> FoundAst<'tcx>; + -> Option<(&'tcx InlinedItem, ast::NodeId)>; + fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option; + fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option; + fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Option>; fn is_item_mir_available(&self, def: DefId) -> bool; @@ -447,7 +444,16 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { // misc. metadata fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> FoundAst<'tcx> { bug!("maybe_get_item_ast") } + -> Option<(&'tcx InlinedItem, ast::NodeId)> { + bug!("maybe_get_item_ast") + } + fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option { + bug!("local_node_for_inlined_defid") + } + fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option { + bug!("defid_for_inlined_node") + } + fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Option> { bug!("maybe_get_item_mir") } fn is_item_mir_available(&self, def: DefId) -> bool { diff --git a/src/librustc_back/target/x86_64_rumprun_netbsd.rs b/src/librustc_back/target/x86_64_rumprun_netbsd.rs index 537d15f4603..fd6578c2a2a 100644 --- a/src/librustc_back/target/x86_64_rumprun_netbsd.rs +++ b/src/librustc_back/target/x86_64_rumprun_netbsd.rs @@ -12,6 +12,7 @@ use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); + base.cpu = "x86-64".to_string(); base.pre_link_args.push("-m64".to_string()); base.linker = "x86_64-rumprun-netbsd-gcc".to_string(); base.ar = "x86_64-rumprun-netbsd-ar".to_string(); diff --git a/src/librustc_back/target/x86_64_unknown_bitrig.rs b/src/librustc_back/target/x86_64_unknown_bitrig.rs index 81710b99b80..38209655898 100644 --- a/src/librustc_back/target/x86_64_unknown_bitrig.rs +++ b/src/librustc_back/target/x86_64_unknown_bitrig.rs @@ -12,6 +12,7 @@ use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::bitrig_base::opts(); + base.cpu = "x86-64".to_string(); base.max_atomic_width = 64; base.pre_link_args.push("-m64".to_string()); diff --git a/src/librustc_back/target/x86_64_unknown_netbsd.rs b/src/librustc_back/target/x86_64_unknown_netbsd.rs index 5145e52d6b4..2d0b1e2a933 100644 --- a/src/librustc_back/target/x86_64_unknown_netbsd.rs +++ b/src/librustc_back/target/x86_64_unknown_netbsd.rs @@ -12,6 +12,7 @@ use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); + base.cpu = "x86-64".to_string(); base.max_atomic_width = 64; base.pre_link_args.push("-m64".to_string()); diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index dd21bb17a2d..d424b57c938 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -17,7 +17,7 @@ use self::EvalHint::*; use rustc::hir::map as ast_map; use rustc::hir::map::blocks::FnLikeNode; -use rustc::middle::cstore::{self, InlinedItem}; +use rustc::middle::cstore::InlinedItem; use rustc::traits; use rustc::hir::def::{Def, PathResolution}; use rustc::hir::def_id::DefId; @@ -142,13 +142,13 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let mut used_substs = false; let expr_ty = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) { - cstore::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node { + Some((&InlinedItem::Item(ref item), _)) => match item.node { hir::ItemConst(ref ty, ref const_expr) => { Some((&**const_expr, tcx.ast_ty_to_prim_ty(ty))) }, _ => None }, - cstore::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node { + Some((&InlinedItem::TraitItem(trait_id, ref ti), _)) => match ti.node { hir::ConstTraitItem(_, _) => { used_substs = true; if let Some(substs) = substs { @@ -163,7 +163,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } _ => None }, - cstore::FoundAst::Found(&InlinedItem::ImplItem(_, ref ii)) => match ii.node { + Some((&InlinedItem::ImplItem(_, ref ii), _)) => match ii.node { hir::ImplItemKind::Const(ref ty, ref expr) => { Some((&**expr, tcx.ast_ty_to_prim_ty(ty))) }, @@ -198,8 +198,8 @@ fn inline_const_fn_from_external_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let fn_id = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) { - cstore::FoundAst::Found(&InlinedItem::Item(ref item)) => Some(item.id), - cstore::FoundAst::Found(&InlinedItem::ImplItem(_, ref item)) => Some(item.id), + Some((&InlinedItem::Item(ref item), _)) => Some(item.id), + Some((&InlinedItem::ImplItem(_, ref item), _)) => Some(item.id), _ => None }; tcx.extern_const_fns.borrow_mut().insert(def_id, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 766e3883f26..f49d47fb081 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -31,7 +31,6 @@ #![feature(set_stdio)] #![feature(staged_api)] #![feature(question_mark)] -#![feature(unboxed_closures)] extern crate arena; extern crate flate; diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 454c805ab57..c39ad414492 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -88,8 +88,9 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext, rbml_w.writer.seek(SeekFrom::Current(0))); // Folding could be avoided with a smarter encoder. - let ii = simplify_ast(ii); + let (ii, expected_id_range) = simplify_ast(ii); let id_range = inlined_item_id_range(&ii); + assert_eq!(expected_id_range, id_range); rbml_w.start_tag(c::tag_ast as usize); id_range.encode(rbml_w); @@ -186,6 +187,10 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> { pub fn tr_id(&self, id: ast::NodeId) -> ast::NodeId { // from_id_range should be non-empty assert!(!self.from_id_range.empty()); + // Make sure that translating the NodeId will actually yield a + // meaningful result + assert!(self.from_id_range.contains(id)); + // Use wrapping arithmetic because otherwise it introduces control flow. // Maybe we should just have the control flow? -- aatch (id.wrapping_sub(self.from_id_range.min).wrapping_add(self.to_id_range.min)) @@ -279,9 +284,23 @@ fn encode_ast(rbml_w: &mut Encoder, item: &InlinedItem) { rbml_w.end_tag(); } -struct NestedItemsDropper; +struct NestedItemsDropper { + id_range: IdRange +} impl Folder for NestedItemsDropper { + + // The unit tests below run on HIR with NodeIds not properly assigned. That + // causes an integer overflow. So we just don't track the id_range when + // building the unit tests. + #[cfg(not(test))] + fn new_id(&mut self, id: ast::NodeId) -> ast::NodeId { + // Record the range of NodeIds we are visiting, so we can do a sanity + // check later + self.id_range.add(id); + id + } + fn fold_block(&mut self, blk: P) -> P { blk.and_then(|hir::Block {id, stmts, expr, rules, span, ..}| { let stmts_sans_items = stmts.into_iter().filter_map(|stmt| { @@ -322,10 +341,12 @@ impl Folder for NestedItemsDropper { // As it happens, trans relies on the fact that we do not export // nested items, as otherwise it would get confused when translating // inlined items. -fn simplify_ast(ii: InlinedItemRef) -> InlinedItem { - let mut fld = NestedItemsDropper; +fn simplify_ast(ii: InlinedItemRef) -> (InlinedItem, IdRange) { + let mut fld = NestedItemsDropper { + id_range: IdRange::max() + }; - match ii { + let ii = match ii { // HACK we're not dropping items. InlinedItemRef::Item(i) => { InlinedItem::Item(P(fold::noop_fold_item(i.clone(), &mut fld))) @@ -339,7 +360,9 @@ fn simplify_ast(ii: InlinedItemRef) -> InlinedItem { InlinedItemRef::Foreign(i) => { InlinedItem::Foreign(P(fold::noop_fold_foreign_item(i.clone(), &mut fld))) } - } + }; + + (ii, fld.id_range) } fn decode_ast(item_doc: rbml::Doc) -> InlinedItem { @@ -361,8 +384,18 @@ impl tr for Def { match *self { Def::Fn(did) => Def::Fn(did.tr(dcx)), Def::Method(did) => Def::Method(did.tr(dcx)), - Def::SelfTy(opt_did, impl_id) => { Def::SelfTy(opt_did.map(|did| did.tr(dcx)), - impl_id.map(|id| dcx.tr_id(id))) } + Def::SelfTy(opt_did, impl_id) => { + // Since the impl_id will never lie within the reserved range of + // imported NodeIds, it does not make sense to translate it. + // The result would not make any sense within the importing crate. + // We also don't allow for impl items to be inlined (just their + // members), so even if we had a DefId here, we wouldn't be able + // to do much with it. + // So, we set the id to DUMMY_NODE_ID. That way we make it + // explicit that this is no usable NodeId. + Def::SelfTy(opt_did.map(|did| did.tr(dcx)), + impl_id.map(|_| ast::DUMMY_NODE_ID)) + } Def::Mod(did) => { Def::Mod(did.tr(dcx)) } Def::ForeignMod(did) => { Def::ForeignMod(did.tr(dcx)) } Def::Static(did, m) => { Def::Static(did.tr(dcx), m) } @@ -1361,7 +1394,7 @@ fn test_simplification() { with_testing_context(|lcx| { let hir_item = lcx.lower_item(&item); let item_in = InlinedItemRef::Item(&hir_item); - let item_out = simplify_ast(item_in); + let (item_out, _) = simplify_ast(item_in); let item_exp = InlinedItem::Item(P(lcx.lower_item("e_item!(&cx, fn new_int_alist() -> alist { return alist {eq_fn: eq_int, data: Vec::new()}; diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index 850d6c91f66..862245b9b78 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -14,7 +14,7 @@ use decoder; use encoder; use loader; -use middle::cstore::{CrateStore, CrateSource, ChildItem, ExternCrate, FoundAst, DefLike}; +use middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate, DefLike}; use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference}; use rustc::hir::def; use middle::lang_items; @@ -482,12 +482,146 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { result } - fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> FoundAst<'tcx> + fn maybe_get_item_ast<'a>(&'tcx self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId) + -> Option<(&'tcx InlinedItem, ast::NodeId)> { - self.dep_graph.read(DepNode::MetaData(def)); - let cdata = self.get_crate_data(def.krate); - decoder::maybe_get_item_ast(&cdata, tcx, def.index) + self.dep_graph.read(DepNode::MetaData(def_id)); + + match self.inlined_item_cache.borrow().get(&def_id) { + Some(&None) => { + return None; // Not inlinable + } + Some(&Some(ref cached_inlined_item)) => { + // Already inline + debug!("maybe_get_item_ast({}): already inline as node id {}", + tcx.item_path_str(def_id), cached_inlined_item.item_id); + return Some((tcx.map.expect_inlined_item(cached_inlined_item.inlined_root), + cached_inlined_item.item_id)); + } + None => { + // Not seen yet + } + } + + debug!("maybe_get_item_ast({}): inlining item", tcx.item_path_str(def_id)); + + let cdata = self.get_crate_data(def_id.krate); + let inlined = decoder::maybe_get_item_ast(&cdata, tcx, def_id.index); + + let cache_inlined_item = |original_def_id, inlined_item_id, inlined_root_node_id| { + let cache_entry = cstore::CachedInlinedItem { + inlined_root: inlined_root_node_id, + item_id: inlined_item_id, + }; + self.inlined_item_cache + .borrow_mut() + .insert(original_def_id, Some(cache_entry)); + self.defid_for_inlined_node + .borrow_mut() + .insert(inlined_item_id, original_def_id); + }; + + let find_inlined_item_root = |inlined_item_id| { + let mut node = inlined_item_id; + let mut path = Vec::with_capacity(10); + + // If we can't find the inline root after a thousand hops, we can + // be pretty sure there's something wrong with the HIR map. + for _ in 0 .. 1000 { + path.push(node); + let parent_node = tcx.map.get_parent_node(node); + if parent_node == node { + return node; + } + node = parent_node; + } + bug!("cycle in HIR map parent chain") + }; + + match inlined { + decoder::FoundAst::NotFound => { + self.inlined_item_cache + .borrow_mut() + .insert(def_id, None); + } + decoder::FoundAst::Found(&InlinedItem::Item(ref item)) => { + let inlined_root_node_id = find_inlined_item_root(item.id); + cache_inlined_item(def_id, item.id, inlined_root_node_id); + } + decoder::FoundAst::Found(&InlinedItem::Foreign(ref item)) => { + let inlined_root_node_id = find_inlined_item_root(item.id); + cache_inlined_item(def_id, item.id, inlined_root_node_id); + } + decoder::FoundAst::FoundParent(parent_did, item) => { + let inlined_root_node_id = find_inlined_item_root(item.id); + cache_inlined_item(parent_did, item.id, inlined_root_node_id); + + match item.node { + hir::ItemEnum(ref ast_def, _) => { + let ast_vs = &ast_def.variants; + let ty_vs = &tcx.lookup_adt_def(parent_did).variants; + assert_eq!(ast_vs.len(), ty_vs.len()); + for (ast_v, ty_v) in ast_vs.iter().zip(ty_vs.iter()) { + cache_inlined_item(ty_v.did, + ast_v.node.data.id(), + inlined_root_node_id); + } + } + hir::ItemStruct(ref struct_def, _) => { + if struct_def.is_struct() { + bug!("instantiate_inline: called on a non-tuple struct") + } else { + cache_inlined_item(def_id, + struct_def.id(), + inlined_root_node_id); + } + } + _ => bug!("instantiate_inline: item has a \ + non-enum, non-struct parent") + } + } + decoder::FoundAst::Found(&InlinedItem::TraitItem(_, ref trait_item)) => { + let inlined_root_node_id = find_inlined_item_root(trait_item.id); + cache_inlined_item(def_id, trait_item.id, inlined_root_node_id); + + // Associated consts already have to be evaluated in `typeck`, so + // the logic to do that already exists in `middle`. In order to + // reuse that code, it needs to be able to look up the traits for + // inlined items. + let ty_trait_item = tcx.impl_or_trait_item(def_id).clone(); + let trait_item_def_id = tcx.map.local_def_id(trait_item.id); + tcx.impl_or_trait_items.borrow_mut() + .insert(trait_item_def_id, ty_trait_item); + } + decoder::FoundAst::Found(&InlinedItem::ImplItem(_, ref impl_item)) => { + let inlined_root_node_id = find_inlined_item_root(impl_item.id); + cache_inlined_item(def_id, impl_item.id, inlined_root_node_id); + } + } + + // We can be sure to hit the cache now + return self.maybe_get_item_ast(tcx, def_id); + } + + fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option { + assert!(!def_id.is_local()); + match self.inlined_item_cache.borrow().get(&def_id) { + Some(&Some(ref cached_inlined_item)) => { + Some(cached_inlined_item.item_id) + } + Some(&None) => { + None + } + _ => { + bug!("Trying to lookup inlined NodeId for unexpected item"); + } + } + } + + fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option { + self.defid_for_inlined_node.borrow().get(&node_id).map(|x| *x) } fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) @@ -634,3 +768,4 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { visible_parent_map } } + diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 6baa0ac23f3..d786cc5ba0e 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -25,7 +25,7 @@ use rustc::dep_graph::DepGraph; use rustc::hir::def_id::{DefIndex, DefId}; use rustc::hir::map::DefKey; use rustc::hir::svh::Svh; -use rustc::middle::cstore::{ExternCrate}; +use rustc::middle::cstore::ExternCrate; use rustc::session::config::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap}; @@ -96,6 +96,13 @@ pub struct CrateMetadata { pub explicitly_linked: Cell, } +pub struct CachedInlinedItem { + /// The NodeId of the RootInlinedParent HIR map entry + pub inlined_root: ast::NodeId, + /// The local NodeId of the inlined entity + pub item_id: ast::NodeId, +} + pub struct CStore { pub dep_graph: DepGraph, metas: RefCell>>, @@ -105,6 +112,8 @@ pub struct CStore { used_libraries: RefCell>, used_link_args: RefCell>, statically_included_foreign_items: RefCell, + pub inlined_item_cache: RefCell>>, + pub defid_for_inlined_node: RefCell>, pub visible_parent_map: RefCell>, } @@ -119,6 +128,8 @@ impl CStore { used_link_args: RefCell::new(Vec::new()), statically_included_foreign_items: RefCell::new(NodeSet()), visible_parent_map: RefCell::new(FnvHashMap()), + inlined_item_cache: RefCell::new(FnvHashMap()), + defid_for_inlined_node: RefCell::new(FnvHashMap()), } } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 24e8b33f44c..d8fd25d6277 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -30,7 +30,7 @@ use rustc::util::nodemap::FnvHashMap; use rustc::hir; use rustc::session::config::PanicStrategy; -use middle::cstore::{FoundAst, InlinedItem, LinkagePreference}; +use middle::cstore::{InlinedItem, LinkagePreference}; use middle::cstore::{DefLike, DlDef, DlField, DlImpl, tls}; use rustc::hir::def::Def; use rustc::hir::def_id::{DefId, DefIndex}; @@ -755,6 +755,12 @@ pub fn maybe_get_item_name(cdata: Cmd, id: DefIndex) -> Option { maybe_item_name(cdata.lookup_item(id)) } +pub enum FoundAst<'ast> { + Found(&'ast InlinedItem), + FoundParent(DefId, &'ast hir::Item), + NotFound, +} + pub fn maybe_get_item_ast<'a, 'tcx>(cdata: Cmd, tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefIndex) -> FoundAst<'tcx> { debug!("Looking up item: {:?}", id); diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index d057f623383..61d8a0837c1 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -1235,7 +1235,6 @@ pub fn inlined_variant_def<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, inlined_vid: ast::NodeId) -> ty::VariantDef<'tcx> { - let ctor_ty = ccx.tcx().node_id_to_type(inlined_vid); debug!("inlined_variant_def: ctor_ty={:?} inlined_vid={:?}", ctor_ty, inlined_vid); @@ -1245,13 +1244,18 @@ pub fn inlined_variant_def<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, }), ..}) => ty, _ => ctor_ty }.ty_adt_def().unwrap(); - let inlined_vid_def_id = ccx.tcx().map.local_def_id(inlined_vid); - adt_def.variants.iter().find(|v| { - inlined_vid_def_id == v.did || - ccx.external().borrow().get(&v.did) == Some(&Some(inlined_vid)) - }).unwrap_or_else(|| { - bug!("no variant for {:?}::{}", adt_def, inlined_vid) - }) + let variant_def_id = if ccx.tcx().map.is_inlined(inlined_vid) { + ccx.defid_for_inlined_node(inlined_vid).unwrap() + } else { + ccx.tcx().map.local_def_id(inlined_vid) + }; + + adt_def.variants + .iter() + .find(|v| variant_def_id == v.did) + .unwrap_or_else(|| { + bug!("no variant for {:?}::{}", adt_def, inlined_vid) + }) } // To avoid UB from LLVM, these two functions mask RHS with an diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 571d2731fb2..27048994254 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -1026,7 +1026,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId) .get(TransItem::Static(id)) .expect("Local statics should always be in the SymbolMap"); // Make sure that this is never executed for something inlined. - assert!(!ccx.external_srcs().borrow().contains_key(&id)); + assert!(!ccx.tcx().map.is_inlined(id)); let defined_in_current_codegen_unit = ccx.codegen_unit() .items() diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 792169b08a4..5a3c1c8512a 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -37,7 +37,7 @@ use session::Session; use session::config; use symbol_map::SymbolMap; use util::sha2::Sha256; -use util::nodemap::{NodeMap, NodeSet, DefIdMap, FnvHashMap, FnvHashSet}; +use util::nodemap::{NodeSet, DefIdMap, FnvHashMap, FnvHashSet}; use std::ffi::{CStr, CString}; use std::cell::{Cell, RefCell}; @@ -102,11 +102,6 @@ pub struct LocalCrateContext<'tcx> { needs_unwind_cleanup_cache: RefCell, bool>>, fn_pointer_shims: RefCell, ValueRef>>, drop_glues: RefCell, (ValueRef, FnType)>>, - /// Track mapping of external ids to local items imported for inlining - external: RefCell>>, - /// Backwards version of the `external` map (inlined items to where they - /// came from) - external_srcs: RefCell>, /// Cache instances of monomorphic and polymorphic items instances: RefCell, ValueRef>>, monomorphizing: RefCell>, @@ -630,8 +625,6 @@ impl<'tcx> LocalCrateContext<'tcx> { needs_unwind_cleanup_cache: RefCell::new(FnvHashMap()), fn_pointer_shims: RefCell::new(FnvHashMap()), drop_glues: RefCell::new(FnvHashMap()), - external: RefCell::new(DefIdMap()), - external_srcs: RefCell::new(NodeMap()), instances: RefCell::new(FnvHashMap()), monomorphizing: RefCell::new(DefIdMap()), vtables: RefCell::new(FnvHashMap()), @@ -825,12 +818,12 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local().drop_glues } - pub fn external<'a>(&'a self) -> &'a RefCell>> { - &self.local().external + pub fn local_node_for_inlined_defid<'a>(&'a self, def_id: DefId) -> Option { + self.sess().cstore.local_node_for_inlined_defid(def_id) } - pub fn external_srcs<'a>(&'a self) -> &'a RefCell> { - &self.local().external_srcs + pub fn defid_for_inlined_node<'a>(&'a self, node_id: ast::NodeId) -> Option { + self.sess().cstore.defid_for_inlined_node(node_id) } pub fn instances<'a>(&'a self) -> &'a RefCell, ValueRef>> { diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 387f24378ce..1d718d4b57a 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -326,13 +326,12 @@ impl<'tcx> TypeMap<'tcx> { // First, find out the 'real' def_id of the type. Items inlined from // other crates have to be mapped back to their source. let def_id = if let Some(node_id) = cx.tcx().map.as_local_node_id(def_id) { - match cx.external_srcs().borrow().get(&node_id).cloned() { - Some(source_def_id) => { - // The given def_id identifies the inlined copy of a - // type definition, let's take the source of the copy. - source_def_id - } - None => def_id + if cx.tcx().map.is_inlined(node_id) { + // The given def_id identifies the inlined copy of a + // type definition, let's take the source of the copy. + cx.defid_for_inlined_node(node_id).unwrap() + } else { + def_id } } else { def_id @@ -1846,7 +1845,7 @@ pub fn create_global_var_metadata(cx: &CrateContext, // crate should already contain debuginfo for it. More importantly, the // global might not even exist in un-inlined form anywhere which would lead // to a linker errors. - if cx.external_srcs().borrow().contains_key(&node_id) { + if cx.tcx().map.is_inlined(node_id) { return; } diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index ed20d949d55..0cb52c8768b 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -438,10 +438,9 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }); // Try to get some span information, if we have an inlined item. - let definition_span = match cx.external().borrow().get(&instance.def) { - Some(&Some(node_id)) => cx.tcx().map.span(node_id), - _ => cx.tcx().map.def_id_span(instance.def, syntax_pos::DUMMY_SP) - }; + let definition_span = cx.tcx() + .map + .def_id_span(instance.def, syntax_pos::DUMMY_SP); (containing_scope, definition_span) } diff --git a/src/librustc_trans/debuginfo/utils.rs b/src/librustc_trans/debuginfo/utils.rs index 1e0afa4534b..facdfe73ddc 100644 --- a/src/librustc_trans/debuginfo/utils.rs +++ b/src/librustc_trans/debuginfo/utils.rs @@ -86,10 +86,7 @@ pub fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: DefId) }); // Try to get some span information, if we have an inlined item. - let definition_span = match cx.external().borrow().get(&def_id) { - Some(&Some(node_id)) => cx.tcx().map.span(node_id), - _ => cx.tcx().map.def_id_span(def_id, syntax_pos::DUMMY_SP) - }; + let definition_span = cx.tcx().map.def_id_span(def_id, syntax_pos::DUMMY_SP); (containing_scope, definition_span) } diff --git a/src/librustc_trans/inline.rs b/src/librustc_trans/inline.rs index 4077b894d62..8581fccf10a 100644 --- a/src/librustc_trans/inline.rs +++ b/src/librustc_trans/inline.rs @@ -8,14 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::cstore::{FoundAst, InlinedItem}; use rustc::hir::def_id::DefId; use base::push_ctxt; use common::*; use monomorphize::Instance; use rustc::dep_graph::DepNode; -use rustc::hir; fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option { debug!("instantiate_inline({:?})", fn_id); @@ -23,104 +21,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option { let tcx = ccx.tcx(); let _task = tcx.dep_graph.in_task(DepNode::TransInlinedItem(fn_id)); - match ccx.external().borrow().get(&fn_id) { - Some(&Some(node_id)) => { - // Already inline - debug!("instantiate_inline({}): already inline as node id {}", - tcx.item_path_str(fn_id), node_id); - let node_def_id = tcx.map.local_def_id(node_id); - return Some(node_def_id); - } - Some(&None) => { - return None; // Not inlinable - } - None => { - // Not seen yet - } - } - - let inlined = tcx.sess.cstore.maybe_get_item_ast(tcx, fn_id); - let inline_id = match inlined { - FoundAst::NotFound => { - ccx.external().borrow_mut().insert(fn_id, None); - return None; - } - FoundAst::Found(&InlinedItem::Item(ref item)) => { - ccx.external().borrow_mut().insert(fn_id, Some(item.id)); - ccx.external_srcs().borrow_mut().insert(item.id, fn_id); - - ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1); - - item.id - } - FoundAst::Found(&InlinedItem::Foreign(ref item)) => { - ccx.external().borrow_mut().insert(fn_id, Some(item.id)); - ccx.external_srcs().borrow_mut().insert(item.id, fn_id); - item.id - } - FoundAst::FoundParent(parent_id, item) => { - ccx.external().borrow_mut().insert(parent_id, Some(item.id)); - ccx.external_srcs().borrow_mut().insert(item.id, parent_id); - - let mut my_id = 0; - match item.node { - hir::ItemEnum(ref ast_def, _) => { - let ast_vs = &ast_def.variants; - let ty_vs = &tcx.lookup_adt_def(parent_id).variants; - assert_eq!(ast_vs.len(), ty_vs.len()); - for (ast_v, ty_v) in ast_vs.iter().zip(ty_vs.iter()) { - if ty_v.did == fn_id { my_id = ast_v.node.data.id(); } - ccx.external().borrow_mut().insert(ty_v.did, Some(ast_v.node.data.id())); - ccx.external_srcs().borrow_mut().insert(ast_v.node.data.id(), ty_v.did); - } - } - hir::ItemStruct(ref struct_def, _) => { - if struct_def.is_struct() { - bug!("instantiate_inline: called on a \ - non-tuple struct") - } else { - ccx.external().borrow_mut().insert(fn_id, Some(struct_def.id())); - ccx.external_srcs().borrow_mut().insert(struct_def.id(), fn_id); - my_id = struct_def.id(); - } - } - _ => bug!("instantiate_inline: item has a \ - non-enum, non-struct parent") - } - my_id - } - FoundAst::Found(&InlinedItem::TraitItem(_, ref trait_item)) => { - ccx.external().borrow_mut().insert(fn_id, Some(trait_item.id)); - ccx.external_srcs().borrow_mut().insert(trait_item.id, fn_id); - - ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1); - - // Associated consts already have to be evaluated in `typeck`, so - // the logic to do that already exists in `middle`. In order to - // reuse that code, it needs to be able to look up the traits for - // inlined items. - let ty_trait_item = tcx.impl_or_trait_item(fn_id).clone(); - let trait_item_def_id = tcx.map.local_def_id(trait_item.id); - tcx.impl_or_trait_items.borrow_mut() - .insert(trait_item_def_id, ty_trait_item); - - // If this is a default method, we can't look up the - // impl type. But we aren't going to translate anyways, so - // don't. - trait_item.id - } - FoundAst::Found(&InlinedItem::ImplItem(_, ref impl_item)) => { - ccx.external().borrow_mut().insert(fn_id, Some(impl_item.id)); - ccx.external_srcs().borrow_mut().insert(impl_item.id, fn_id); - - ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1); - - impl_item.id - } - }; - - let inline_def_id = tcx.map.local_def_id(inline_id); - Some(inline_def_id) + tcx.sess + .cstore + .maybe_get_item_ast(tcx, fn_id) + .map(|(_, inline_id)| { + tcx.map.local_def_id(inline_id) + }) } pub fn get_local_instance(ccx: &CrateContext, fn_id: DefId) diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 7a7f1901736..2d1769b8637 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -284,6 +284,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { // After this point, bcx is the block for the call to panic. bcx = panic_block.build(); + debug_loc.apply_to_bcx(&bcx); // Get the location information. let loc = bcx.sess().codemap().lookup_char_pos(span.lo); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b642a712219..3b2bca4ab39 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1313,6 +1313,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // item is declared. let bound = match (&ty.sty, ty_path_def) { (_, Def::SelfTy(Some(trait_did), Some(impl_id))) => { + // For Def::SelfTy() values inlined from another crate, the + // impl_id will be DUMMY_NODE_ID, which would cause problems + // here. But we should never run into an impl from another crate + // in this pass. + assert!(impl_id != ast::DUMMY_NODE_ID); + // `Self` in an impl of a trait - we have a concrete self type and a // trait reference. let trait_ref = tcx.impl_trait_ref(tcx.map.local_def_id(impl_id)).unwrap(); @@ -1518,6 +1524,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } Def::SelfTy(_, Some(impl_id)) => { // Self in impl (we know the concrete type). + + // For Def::SelfTy() values inlined from another crate, the + // impl_id will be DUMMY_NODE_ID, which would cause problems + // here. But we should never run into an impl from another crate + // in this pass. + assert!(impl_id != ast::DUMMY_NODE_ID); + tcx.prohibit_type_params(base_segments); let ty = tcx.node_id_to_type(impl_id); if let Some(free_substs) = self.get_free_substs() { diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 9c6727ebbfc..bd2c05ba66d 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -27,33 +27,8 @@ use rustc::hir; /// to `trait_id` (this only cares about the trait, not the specific /// method that is called) pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id: DefId) { - let tcx = ccx.tcx; - let did = Some(trait_id); - let li = &tcx.lang_items; - - if did == li.drop_trait() { - span_err!(tcx.sess, span, E0040, "explicit use of destructor method"); - } else if !tcx.sess.features.borrow().unboxed_closures { - // the #[feature(unboxed_closures)] feature isn't - // activated so we need to enforce the closure - // restrictions. - - let method = if did == li.fn_trait() { - "call" - } else if did == li.fn_mut_trait() { - "call_mut" - } else if did == li.fn_once_trait() { - "call_once" - } else { - return // not a closure method, everything is OK. - }; - - struct_span_err!(tcx.sess, span, E0174, - "explicit use of unboxed closure method `{}` is experimental", - method) - .help("add `#![feature(unboxed_closures)]` to the crate \ - attributes to enable") - .emit(); + if ccx.tcx.lang_items.drop_trait() == Some(trait_id) { + span_err!(ccx.tcx.sess, span, E0040, "explicit use of destructor method"); } } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 500f624ea3f..cd2259a2834 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1944,89 +1944,6 @@ To learn more about traits, take a look at the Book: https://doc.rust-lang.org/book/traits.html "##, -E0174: r##" -This error occurs because of the explicit use of unboxed closure methods -that are an experimental feature in current Rust version. - -Example of erroneous code: - -```compile_fail -fn foo(mut f: F) { - f.call(("call",)); - // error: explicit use of unboxed closure method `call` - f.call_mut(("call_mut",)); - // error: explicit use of unboxed closure method `call_mut` - f.call_once(("call_once",)); - // error: explicit use of unboxed closure method `call_once` -} - -fn bar(text: &str) { - println!("Calling {} it works!", text); -} - -fn main() { - foo(bar); -} -``` - -Rust's implementation of closures is a bit different than other languages. -They are effectively syntax sugar for traits `Fn`, `FnMut` and `FnOnce`. -To understand better how the closures are implemented see here: -https://doc.rust-lang.org/book/closures.html#closure-implementation - -To fix this you can call them using parenthesis, like this: `foo()`. -When you execute the closure with parenthesis, under the hood you are executing -the method `call`, `call_mut` or `call_once`. However, using them explicitly is -currently an experimental feature. - -Example of an implicit call: - -``` -fn foo(f: F) { - f("using ()"); // Calling using () it works! -} - -fn bar(text: &str) { - println!("Calling {} it works!", text); -} - -fn main() { - foo(bar); -} -``` - -To enable the explicit calls you need to add `#![feature(unboxed_closures)]`. - -This feature is still unstable so you will also need to add -`#![feature(fn_traits)]`. -More details about this issue here: -https://github.com/rust-lang/rust/issues/29625 - -Example of use: - -``` -#![feature(fn_traits)] -#![feature(unboxed_closures)] - -fn foo(mut f: F) { - f.call(("call",)); // Calling 'call' it works! - f.call_mut(("call_mut",)); // Calling 'call_mut' it works! - f.call_once(("call_once",)); // Calling 'call_once' it works! -} - -fn bar(text: &str) { - println!("Calling '{}' it works!", text); -} - -fn main() { - foo(bar); -} -``` - -To see more about closures take a look here: -https://doc.rust-lang.org/book/closures.html` -"##, - E0178: r##" In types, the `+` type operator has low precedence, so it is often necessary to use parentheses. @@ -4049,6 +3966,7 @@ register_diagnostics! { E0167, // E0168, // E0173, // manual implementations of unboxed closure traits are experimental +// E0174, E0182, E0183, // E0187, // can't infer the kind of the closure diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6883c22d675..d609ad84a83 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2691,7 +2691,12 @@ fn register_def(cx: &DocContext, def: Def) -> DefId { Def::Static(i, _) => (i, TypeStatic), Def::Variant(i, _) => (i, TypeEnum), Def::SelfTy(Some(def_id), _) => (def_id, TypeTrait), - Def::SelfTy(_, Some(impl_id)) => return cx.map.local_def_id(impl_id), + Def::SelfTy(_, Some(impl_id)) => { + // For Def::SelfTy() values inlined from another crate, the + // impl_id will be DUMMY_NODE_ID, which would cause problems. + // But we should never run into an impl from another crate here. + return cx.map.local_def_id(impl_id) + } _ => return def.def_id() }; if did.is_local() { return did } diff --git a/src/test/compile-fail/associated-types/bound-lifetime-constrained.rs b/src/test/compile-fail/associated-types/bound-lifetime-constrained.rs index f60f06b4ec8..de6ce798d63 100644 --- a/src/test/compile-fail/associated-types/bound-lifetime-constrained.rs +++ b/src/test/compile-fail/associated-types/bound-lifetime-constrained.rs @@ -12,7 +12,6 @@ #![allow(dead_code)] #![feature(rustc_attrs)] -#![feature(unboxed_closures)] #![deny(hr_lifetime_in_assoc_type)] trait Foo<'a> { diff --git a/src/test/compile-fail/associated-types/cache/wasm-issue-32330.rs b/src/test/compile-fail/associated-types/cache/wasm-issue-32330.rs index 01db4770a38..6ba09acc0e7 100644 --- a/src/test/compile-fail/associated-types/cache/wasm-issue-32330.rs +++ b/src/test/compile-fail/associated-types/cache/wasm-issue-32330.rs @@ -13,7 +13,6 @@ #![allow(dead_code, unused_variables)] #![deny(hr_lifetime_in_assoc_type)] -#![feature(unboxed_closures)] use std::str::Chars; diff --git a/src/test/compile-fail/borrowck/borrowck-call-is-borrow-issue-12224.rs b/src/test/compile-fail/borrowck/borrowck-call-is-borrow-issue-12224.rs index 7626f354eb4..e4ae565fe92 100644 --- a/src/test/compile-fail/borrowck/borrowck-call-is-borrow-issue-12224.rs +++ b/src/test/compile-fail/borrowck/borrowck-call-is-borrow-issue-12224.rs @@ -10,8 +10,6 @@ // Ensure that invoking a closure counts as a unique immutable borrow -#![feature(unboxed_closures)] - type Fn<'a> = Box; struct Test<'a> { diff --git a/src/test/compile-fail/borrowck/borrowck-unboxed-closures.rs b/src/test/compile-fail/borrowck/borrowck-unboxed-closures.rs index 1c12ca9c1de..0f9829ab259 100644 --- a/src/test/compile-fail/borrowck/borrowck-unboxed-closures.rs +++ b/src/test/compile-fail/borrowck/borrowck-unboxed-closures.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(overloaded_calls, unboxed_closures)] - fn a isize>(mut f: F) { let g = &mut f; f(1, 2); //~ ERROR cannot borrow `f` as immutable diff --git a/src/test/compile-fail/feature-gate-unboxed-closures-method-calls.rs b/src/test/compile-fail/feature-gate-unboxed-closures-method-calls.rs index eea1f61d639..253d1633b1c 100644 --- a/src/test/compile-fail/feature-gate-unboxed-closures-method-calls.rs +++ b/src/test/compile-fail/feature-gate-unboxed-closures-method-calls.rs @@ -11,9 +11,9 @@ #![allow(dead_code)] fn foo(mut f: F) { - f.call(()); //~ ERROR explicit use of unboxed closure method `call` - f.call_mut(()); //~ ERROR explicit use of unboxed closure method `call_mut` - f.call_once(()); //~ ERROR explicit use of unboxed closure method `call_once` + f.call(()); //~ ERROR use of unstable library feature 'fn_traits' + f.call_mut(()); //~ ERROR use of unstable library feature 'fn_traits' + f.call_once(()); //~ ERROR use of unstable library feature 'fn_traits' } fn main() {} diff --git a/src/test/compile-fail/feature-gate-unboxed-closures-ufcs-calls.rs b/src/test/compile-fail/feature-gate-unboxed-closures-ufcs-calls.rs index f15c5c4da2c..902b3c1774c 100644 --- a/src/test/compile-fail/feature-gate-unboxed-closures-ufcs-calls.rs +++ b/src/test/compile-fail/feature-gate-unboxed-closures-ufcs-calls.rs @@ -10,10 +10,10 @@ #![allow(dead_code)] -fn foo(mut f: F, mut g: F) { - Fn::call(&g, ()); //~ ERROR explicit use of unboxed closure method `call` - FnMut::call_mut(&mut g, ()); //~ ERROR explicit use of unboxed closure method `call_mut` - FnOnce::call_once(g, ()); //~ ERROR explicit use of unboxed closure method `call_once` +fn foo(mut f: F) { + Fn::call(&f, ()); //~ ERROR use of unstable library feature 'fn_traits' + FnMut::call_mut(&mut f, ()); //~ ERROR use of unstable library feature 'fn_traits' + FnOnce::call_once(f, ()); //~ ERROR use of unstable library feature 'fn_traits' } fn main() {} diff --git a/src/test/compile-fail/fn-trait-formatting.rs b/src/test/compile-fail/fn-trait-formatting.rs index fd140cd1d39..e01a0412cef 100644 --- a/src/test/compile-fail/fn-trait-formatting.rs +++ b/src/test/compile-fail/fn-trait-formatting.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] #![feature(box_syntax)] fn needs_fn(x: F) where F: Fn(isize) -> isize {} diff --git a/src/test/compile-fail/issue-16939.rs b/src/test/compile-fail/issue-16939.rs index 7ec3fef5c87..e16c58b8a6c 100644 --- a/src/test/compile-fail/issue-16939.rs +++ b/src/test/compile-fail/issue-16939.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(overloaded_calls, unboxed_closures)] - // Make sure we don't ICE when making an overloaded call with the // wrong arity. diff --git a/src/test/compile-fail/issue-17033.rs b/src/test/compile-fail/issue-17033.rs index f0fe01b4159..0ec05b941a9 100644 --- a/src/test/compile-fail/issue-17033.rs +++ b/src/test/compile-fail/issue-17033.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(overloaded_calls)] - fn f<'r>(p: &'r mut fn(p: &mut ())) { (*p)(()) //~ ERROR mismatched types //~| expected type `&mut ()` diff --git a/src/test/compile-fail/issue-17545.rs b/src/test/compile-fail/issue-17545.rs index 84800218efc..49435f83ce3 100644 --- a/src/test/compile-fail/issue-17545.rs +++ b/src/test/compile-fail/issue-17545.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - pub fn foo<'a, F: Fn(&'a ())>(bar: F) { bar.call(( &(), //~ ERROR borrowed value does not live long enough diff --git a/src/test/compile-fail/issue-17551.rs b/src/test/compile-fail/issue-17551.rs index 5781cb74117..5e69553d3a4 100644 --- a/src/test/compile-fail/issue-17551.rs +++ b/src/test/compile-fail/issue-17551.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - use std::marker; struct B(marker::PhantomData); diff --git a/src/test/compile-fail/issue-18532.rs b/src/test/compile-fail/issue-18532.rs index 9cf922ae990..94eab97c42a 100644 --- a/src/test/compile-fail/issue-18532.rs +++ b/src/test/compile-fail/issue-18532.rs @@ -12,8 +12,6 @@ // when a type error or unconstrained type variable propagates // into it. -#![feature(unboxed_closures)] - fn main() { (return)((),()); //~^ ERROR the type of this value must be known diff --git a/src/test/compile-fail/issue-19521.rs b/src/test/compile-fail/issue-19521.rs index 58a95e9da2b..93d95ca0b0f 100644 --- a/src/test/compile-fail/issue-19521.rs +++ b/src/test/compile-fail/issue-19521.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - fn main() { "".homura()(); //~ ERROR no method named `homura` found } diff --git a/src/test/compile-fail/issue-19707.rs b/src/test/compile-fail/issue-19707.rs index 9affb44b744..beeb7da6d38 100644 --- a/src/test/compile-fail/issue-19707.rs +++ b/src/test/compile-fail/issue-19707.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] #![allow(dead_code)] type foo = fn(&u8, &u8) -> &u8; //~ ERROR missing lifetime specifier diff --git a/src/test/compile-fail/issue-4335.rs b/src/test/compile-fail/issue-4335.rs index 0089bff3e8f..9a1b5d9b83d 100644 --- a/src/test/compile-fail/issue-4335.rs +++ b/src/test/compile-fail/issue-4335.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - fn id(t: T) -> T { t } fn f<'r, T>(v: &'r T) -> Box T + 'r> { diff --git a/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs b/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs index 5af326b4298..df9a3519d5d 100644 --- a/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs +++ b/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs @@ -12,8 +12,6 @@ // bound must be noncopyable. For details see // http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/ -#![feature(unboxed_closures)] - struct R<'a> { // This struct is needed to create the // otherwise infinite type of a fn that diff --git a/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs b/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs index 5db9a01c012..8ec6036762f 100644 --- a/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs +++ b/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures, overloaded_calls)] - use std::ops::FnMut; fn main() { diff --git a/src/test/compile-fail/regions-escape-unboxed-closure.rs b/src/test/compile-fail/regions-escape-unboxed-closure.rs index abbefd25488..cf41fad2708 100644 --- a/src/test/compile-fail/regions-escape-unboxed-closure.rs +++ b/src/test/compile-fail/regions-escape-unboxed-closure.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - fn with_int(f: &mut FnMut(&isize)) { } diff --git a/src/test/compile-fail/regions-return-ref-to-upvar-issue-17403.rs b/src/test/compile-fail/regions-return-ref-to-upvar-issue-17403.rs index 1e2224eafae..99e5cc03153 100644 --- a/src/test/compile-fail/regions-return-ref-to-upvar-issue-17403.rs +++ b/src/test/compile-fail/regions-return-ref-to-upvar-issue-17403.rs @@ -10,8 +10,6 @@ // Test that closures cannot subvert aliasing restrictions -#![feature(overloaded_calls, unboxed_closures)] - fn main() { // Unboxed closure case { diff --git a/src/test/compile-fail/regions-steal-closure.rs b/src/test/compile-fail/regions-steal-closure.rs index a30d8471a31..8ade8b239b3 100644 --- a/src/test/compile-fail/regions-steal-closure.rs +++ b/src/test/compile-fail/regions-steal-closure.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - struct closure_box<'a> { cl: Box, } diff --git a/src/test/compile-fail/unboxed-closure-immutable-capture.rs b/src/test/compile-fail/unboxed-closure-immutable-capture.rs index 5be2738b47e..2d998374229 100644 --- a/src/test/compile-fail/unboxed-closure-immutable-capture.rs +++ b/src/test/compile-fail/unboxed-closure-immutable-capture.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - // Test that even unboxed closures that are capable of mutating their // environment cannot mutate captured variables that have not been // declared mutable (#18335) diff --git a/src/test/compile-fail/unboxed-closure-region.rs b/src/test/compile-fail/unboxed-closure-region.rs index eee1b6ce30b..1c86dda3378 100644 --- a/src/test/compile-fail/unboxed-closure-region.rs +++ b/src/test/compile-fail/unboxed-closure-region.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - // Test that an unboxed closure that captures a free variable by // reference cannot escape the region of that variable. fn main() { diff --git a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs index 21450856ae6..465bddd060d 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - fn f isize>(x: F) {} //~ ERROR trait `Nonexist` is not in scope type Typedef = isize; diff --git a/src/test/compile-fail/unboxed-closures-borrow-conflict.rs b/src/test/compile-fail/unboxed-closures-borrow-conflict.rs index 372f3277931..ad7e6784a0a 100644 --- a/src/test/compile-fail/unboxed-closures-borrow-conflict.rs +++ b/src/test/compile-fail/unboxed-closures-borrow-conflict.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - // Test that an unboxed closure that mutates a free variable will // cause borrow conflicts. diff --git a/src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs b/src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs index 1e2b01856e7..5436a855ee7 100644 --- a/src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs +++ b/src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs @@ -11,8 +11,6 @@ // That a closure whose expected argument types include two distinct // bound regions. -#![feature(unboxed_closures)] - use std::cell::Cell; fn doit(val: T, f: &F) diff --git a/src/test/compile-fail/unboxed-closures-infer-explicit-call-too-early.rs b/src/test/compile-fail/unboxed-closures-infer-explicit-call-too-early.rs index 226b516e09d..62f6ee56ca5 100644 --- a/src/test/compile-fail/unboxed-closures-infer-explicit-call-too-early.rs +++ b/src/test/compile-fail/unboxed-closures-infer-explicit-call-too-early.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - fn main() { let mut zero = || {}; let () = zero.call_mut(()); diff --git a/src/test/compile-fail/unboxed-closures-type-mismatch.rs b/src/test/compile-fail/unboxed-closures-type-mismatch.rs index 91182393ac8..dba4c8cc2e9 100644 --- a/src/test/compile-fail/unboxed-closures-type-mismatch.rs +++ b/src/test/compile-fail/unboxed-closures-type-mismatch.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - use std::ops::FnMut; pub fn main() { diff --git a/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs b/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs index cba7ad82ee1..2b0a8baf4f2 100644 --- a/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs +++ b/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs @@ -10,8 +10,6 @@ // Tests that unsafe extern fn pointers do not implement any Fn traits. -#![feature(unboxed_closures)] - use std::ops::{Fn,FnMut,FnOnce}; unsafe fn square(x: &isize) -> isize { (*x) * (*x) } diff --git a/src/test/compile-fail/unboxed-closures-wrong-abi.rs b/src/test/compile-fail/unboxed-closures-wrong-abi.rs index dd891bc473c..f6ba25f4368 100644 --- a/src/test/compile-fail/unboxed-closures-wrong-abi.rs +++ b/src/test/compile-fail/unboxed-closures-wrong-abi.rs @@ -10,8 +10,6 @@ // Tests that unsafe extern fn pointers do not implement any Fn traits. -#![feature(unboxed_closures)] - use std::ops::{Fn,FnMut,FnOnce}; extern "C" fn square(x: &isize) -> isize { (*x) * (*x) } diff --git a/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs b/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs index f9edd5df673..9d907ffc17f 100644 --- a/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs +++ b/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs @@ -10,8 +10,6 @@ // Tests that unsafe extern fn pointers do not implement any Fn traits. -#![feature(unboxed_closures)] - use std::ops::{Fn,FnMut,FnOnce}; unsafe fn square(x: isize) -> isize { x * x } diff --git a/src/test/debuginfo/var-captured-in-sendable-closure.rs b/src/test/debuginfo/var-captured-in-sendable-closure.rs index aa269edadd8..b415546faea 100644 --- a/src/test/debuginfo/var-captured-in-sendable-closure.rs +++ b/src/test/debuginfo/var-captured-in-sendable-closure.rs @@ -40,7 +40,7 @@ // lldb-check:[...]$2 = 5 #![allow(unused_variables)] -#![feature(unboxed_closures, box_syntax)] +#![feature(box_syntax)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] diff --git a/src/test/debuginfo/var-captured-in-stack-closure.rs b/src/test/debuginfo/var-captured-in-stack-closure.rs index 6def5cf2859..e60f964dd09 100644 --- a/src/test/debuginfo/var-captured-in-stack-closure.rs +++ b/src/test/debuginfo/var-captured-in-stack-closure.rs @@ -69,7 +69,7 @@ // lldb-command:print *owned // lldb-check:[...]$9 = 6 -#![feature(unboxed_closures, box_syntax)] +#![feature(box_syntax)] #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] diff --git a/src/test/run-pass/assignability-trait.rs b/src/test/run-pass/assignability-trait.rs index 0ee460052c7..c364240f4ad 100644 --- a/src/test/run-pass/assignability-trait.rs +++ b/src/test/run-pass/assignability-trait.rs @@ -12,9 +12,6 @@ // making method calls, but only if there aren't any matches without // it. - -#![feature(unboxed_closures)] - trait iterable { fn iterate(&self, blk: F) -> bool where F: FnMut(&A) -> bool; } diff --git a/src/test/run-pass/associated-types-impl-redirect.rs b/src/test/run-pass/associated-types-impl-redirect.rs index 4082580a123..3e34367a215 100644 --- a/src/test/run-pass/associated-types-impl-redirect.rs +++ b/src/test/run-pass/associated-types-impl-redirect.rs @@ -14,7 +14,7 @@ // for `ByRef`. The right answer was to consider the result ambiguous // until more type information was available. -#![feature(lang_items, unboxed_closures)] +#![feature(lang_items)] #![no_implicit_prelude] use std::marker::Sized; diff --git a/src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs b/src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs index 082ad53d559..ef1225d39a7 100644 --- a/src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs +++ b/src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs @@ -14,7 +14,7 @@ // for `ByRef`. The right answer was to consider the result ambiguous // until more type information was available. -#![feature(lang_items, unboxed_closures)] +#![feature(lang_items)] #![no_implicit_prelude] use std::marker::Sized; diff --git a/src/test/run-pass/auxiliary/issue-18711.rs b/src/test/run-pass/auxiliary/issue-18711.rs index a29dcc00cdd..c247c0223fc 100644 --- a/src/test/run-pass/auxiliary/issue-18711.rs +++ b/src/test/run-pass/auxiliary/issue-18711.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] #![crate_type = "rlib"] pub fn inner(f: F) -> F { diff --git a/src/test/run-pass/auxiliary/unboxed-closures-cross-crate.rs b/src/test/run-pass/auxiliary/unboxed-closures-cross-crate.rs index dac20dd2f7a..dc9798a2101 100644 --- a/src/test/run-pass/auxiliary/unboxed-closures-cross-crate.rs +++ b/src/test/run-pass/auxiliary/unboxed-closures-cross-crate.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - use std::ops::Add; #[inline] diff --git a/src/test/run-pass/bare-fn-implements-fn-mut.rs b/src/test/run-pass/bare-fn-implements-fn-mut.rs index e8118e90a9f..30a11ca2536 100644 --- a/src/test/run-pass/bare-fn-implements-fn-mut.rs +++ b/src/test/run-pass/bare-fn-implements-fn-mut.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - use std::ops::FnMut; fn call_f(mut f: F) { diff --git a/src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs b/src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs index bbc668f5cab..158594df8ca 100644 --- a/src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs +++ b/src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs @@ -11,7 +11,6 @@ #![allow(unknown_features)] #![feature(box_syntax)] -#![feature(unboxed_closures)] pub fn main() { let bar: Box<_> = box 3; diff --git a/src/test/run-pass/capture-clauses-unboxed-closures.rs b/src/test/run-pass/capture-clauses-unboxed-closures.rs index 5e7d5aacb8d..e8a9dc7b8f3 100644 --- a/src/test/run-pass/capture-clauses-unboxed-closures.rs +++ b/src/test/run-pass/capture-clauses-unboxed-closures.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(unboxed_closures)] - fn each<'a,T,F:FnMut(&'a T)>(x: &'a [T], mut f: F) { for val in x { f(val) diff --git a/src/test/run-pass/closure-bounds-can-capture-chan.rs b/src/test/run-pass/closure-bounds-can-capture-chan.rs index dbbac8a1633..5268e855d5f 100644 --- a/src/test/run-pass/closure-bounds-can-capture-chan.rs +++ b/src/test/run-pass/closure-bounds-can-capture-chan.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - use std::sync::mpsc::channel; fn foo(blk: F) { diff --git a/src/test/run-pass/closure-reform.rs b/src/test/run-pass/closure-reform.rs index 0fa67e873f8..a37733bdc2d 100644 --- a/src/test/run-pass/closure-reform.rs +++ b/src/test/run-pass/closure-reform.rs @@ -11,8 +11,6 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -#![feature(unboxed_closures)] - fn call_it(f: F) where F : FnOnce(String) -> String { diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs index 4dae1131c6d..3f6f1aa6b5f 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/run-pass/hashmap-memory.rs @@ -9,7 +9,7 @@ // except according to those terms. #![allow(unknown_features)] -#![feature(unboxed_closures, std_misc)] +#![feature(std_misc)] /** A somewhat reduced test case to expose some Valgrind issues. diff --git a/src/test/run-pass/hrtb-parse.rs b/src/test/run-pass/hrtb-parse.rs index ecd0bc681c3..cdffaef66eb 100644 --- a/src/test/run-pass/hrtb-parse.rs +++ b/src/test/run-pass/hrtb-parse.rs @@ -13,7 +13,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] #![allow(unused_variables)] #![allow(dead_code)] diff --git a/src/test/run-pass/hrtb-precedence-of-plus-where-clause.rs b/src/test/run-pass/hrtb-precedence-of-plus-where-clause.rs index bc00a0758f4..46ea2562961 100644 --- a/src/test/run-pass/hrtb-precedence-of-plus-where-clause.rs +++ b/src/test/run-pass/hrtb-precedence-of-plus-where-clause.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - // Test that `F : Fn(isize) -> isize + Send` is interpreted as two // distinct bounds on `F`. diff --git a/src/test/run-pass/hrtb-precedence-of-plus.rs b/src/test/run-pass/hrtb-precedence-of-plus.rs index 892f2f1ae9d..d93e52a8f5f 100644 --- a/src/test/run-pass/hrtb-precedence-of-plus.rs +++ b/src/test/run-pass/hrtb-precedence-of-plus.rs @@ -11,7 +11,6 @@ // pretty-expanded FIXME #23616 #![allow(unknown_features)] -#![feature(unboxed_closures)] // Test that `Fn(isize) -> isize + 'static` parses as `(Fn(isize) -> isize) + // 'static` and not `Fn(isize) -> (isize + 'static)`. The latter would diff --git a/src/test/run-pass/hrtb-trait-object-paren-notation.rs b/src/test/run-pass/hrtb-trait-object-paren-notation.rs index fefbd004766..5b9d4a834d8 100644 --- a/src/test/run-pass/hrtb-trait-object-paren-notation.rs +++ b/src/test/run-pass/hrtb-trait-object-paren-notation.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(unboxed_closures)] - // A basic test of using a higher-ranked trait bound. trait FnLike { diff --git a/src/test/run-pass/hrtb-unboxed-closure-trait.rs b/src/test/run-pass/hrtb-unboxed-closure-trait.rs index 008e7ddbc9c..6666b61a4a7 100644 --- a/src/test/run-pass/hrtb-unboxed-closure-trait.rs +++ b/src/test/run-pass/hrtb-unboxed-closure-trait.rs @@ -10,8 +10,6 @@ // Test HRTB used with the `Fn` trait. -#![feature(unboxed_closures)] - fn foo(f: F) { let x = 22; f(&x); diff --git a/src/test/run-pass/issue-10718.rs b/src/test/run-pass/issue-10718.rs index 0a6e454e181..fedd94e22e7 100644 --- a/src/test/run-pass/issue-10718.rs +++ b/src/test/run-pass/issue-10718.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - fn f(p: F) { p(); } diff --git a/src/test/run-pass/issue-16560.rs b/src/test/run-pass/issue-16560.rs index 596f0d20155..e91569f8b24 100644 --- a/src/test/run-pass/issue-16560.rs +++ b/src/test/run-pass/issue-16560.rs @@ -10,8 +10,6 @@ // ignore-emscripten no threads support -#![feature(unboxed_closures)] - use std::thread; use std::mem; diff --git a/src/test/run-pass/issue-16668.rs b/src/test/run-pass/issue-16668.rs index 786c701a042..0fd99650284 100644 --- a/src/test/run-pass/issue-16668.rs +++ b/src/test/run-pass/issue-16668.rs @@ -11,7 +11,6 @@ // ignore-pretty #![allow(unknown_features)] -#![feature(unboxed_closures)] struct Parser<'a, I, O> { parse: Box Result + 'a> diff --git a/src/test/run-pass/issue-16774.rs b/src/test/run-pass/issue-16774.rs index 627717ab1cd..9ec5910c2f6 100644 --- a/src/test/run-pass/issue-16774.rs +++ b/src/test/run-pass/issue-16774.rs @@ -12,7 +12,6 @@ #![allow(unknown_features)] #![feature(box_syntax)] #![feature(box_patterns)] -#![feature(unboxed_closures)] use std::ops::{Deref, DerefMut}; diff --git a/src/test/run-pass/issue-17816.rs b/src/test/run-pass/issue-17816.rs index 8e3cb414566..a9aa4cdd4f6 100644 --- a/src/test/run-pass/issue-17816.rs +++ b/src/test/run-pass/issue-17816.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - use std::marker::PhantomData; fn main() { diff --git a/src/test/run-pass/issue-18652.rs b/src/test/run-pass/issue-18652.rs index 8ab645e54ad..cea0beaf5f0 100644 --- a/src/test/run-pass/issue-18652.rs +++ b/src/test/run-pass/issue-18652.rs @@ -12,9 +12,6 @@ // once closure as an optimization by trans. This used to hit an // incorrect assert. - -#![feature(unboxed_closures)] - fn main() { let x = 2u8; let y = 3u8; diff --git a/src/test/run-pass/issue-18685.rs b/src/test/run-pass/issue-18685.rs index e4537e158d1..b569dbc8062 100644 --- a/src/test/run-pass/issue-18685.rs +++ b/src/test/run-pass/issue-18685.rs @@ -13,8 +13,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - trait Tr { fn foo(&self); diff --git a/src/test/run-pass/issue-18711.rs b/src/test/run-pass/issue-18711.rs index 277ad3260c5..8239d74d6df 100644 --- a/src/test/run-pass/issue-18711.rs +++ b/src/test/run-pass/issue-18711.rs @@ -13,8 +13,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - // aux-build:issue-18711.rs extern crate issue_18711 as issue; diff --git a/src/test/run-pass/issue-19127.rs b/src/test/run-pass/issue-19127.rs index c5eb5069328..8d169917cad 100644 --- a/src/test/run-pass/issue-19127.rs +++ b/src/test/run-pass/issue-19127.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - fn foo T>(f: F) {} fn id<'a>(input: &'a u8) -> &'a u8 { input } diff --git a/src/test/run-pass/issue-19135.rs b/src/test/run-pass/issue-19135.rs index 5e6dd567d63..ca2098138ef 100644 --- a/src/test/run-pass/issue-19135.rs +++ b/src/test/run-pass/issue-19135.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - use std::marker::PhantomData; #[derive(Debug)] diff --git a/src/test/run-pass/mir_trans_calls.rs b/src/test/run-pass/mir_trans_calls.rs index ca3294a87ad..7ff684a5ef3 100644 --- a/src/test/run-pass/mir_trans_calls.rs +++ b/src/test/run-pass/mir_trans_calls.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(rustc_attrs, unboxed_closures, fn_traits)] +#![feature(rustc_attrs, fn_traits)] #[rustc_mir] fn test1(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) { diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index dfc86497c96..0ba019c591c 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -21,6 +21,8 @@ use std::sync::mpsc::channel; use std::time::Duration; use std::thread::{self, Builder}; +const TARGET_CNT: usize = 200; + fn main() { // This test has a chance to time out, try to not let it time out thread::spawn(move|| -> () { @@ -42,8 +44,9 @@ fn main() { }); let (tx, rx) = channel(); + let mut spawned_cnt = 0; - for _ in 0..1000 { + for _ in 0..TARGET_CNT { let tx = tx.clone(); let res = Builder::new().stack_size(64 * 1024).spawn(move|| { match TcpStream::connect(addr) { @@ -66,6 +69,6 @@ fn main() { for _ in 0..spawned_cnt { rx.recv().unwrap(); } - assert_eq!(spawned_cnt, 1000); + assert_eq!(spawned_cnt, TARGET_CNT); process::exit(0); } diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs index 24dc73d4a43..0de6fbc91cc 100644 --- a/src/test/run-pass/trait-bounds-in-arc.rs +++ b/src/test/run-pass/trait-bounds-in-arc.rs @@ -16,7 +16,6 @@ #![allow(unknown_features)] #![feature(box_syntax, std_misc)] -#![feature(unboxed_closures)] use std::sync::Arc; use std::sync::mpsc::channel; diff --git a/src/test/run-pass/type-id-higher-rank.rs b/src/test/run-pass/type-id-higher-rank.rs index 3030833c772..c29fb5e86f5 100644 --- a/src/test/run-pass/type-id-higher-rank.rs +++ b/src/test/run-pass/type-id-higher-rank.rs @@ -12,7 +12,7 @@ // Also acts as a regression test for an ICE (issue #19791) -#![feature(unboxed_closures, core)] +#![feature(core)] use std::any::{Any, TypeId}; diff --git a/src/test/run-pass/unboxed-closures-all-traits.rs b/src/test/run-pass/unboxed-closures-all-traits.rs index c28d4f463e5..201500d0c62 100644 --- a/src/test/run-pass/unboxed-closures-all-traits.rs +++ b/src/test/run-pass/unboxed-closures-all-traits.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(lang_items, unboxed_closures)] +#![feature(lang_items)] fn a isize>(f: F) -> isize { f(1, 2) diff --git a/src/test/run-pass/unboxed-closures-blanket-fn-mut.rs b/src/test/run-pass/unboxed-closures-blanket-fn-mut.rs index 54c92900c89..23ec0cb5f60 100644 --- a/src/test/run-pass/unboxed-closures-blanket-fn-mut.rs +++ b/src/test/run-pass/unboxed-closures-blanket-fn-mut.rs @@ -10,8 +10,7 @@ // Test that you can supply `&F` where `F: FnMut()`. - -#![feature(lang_items, unboxed_closures)] +#![feature(lang_items)] fn a i32>(mut f: F) -> i32 { f() diff --git a/src/test/run-pass/unboxed-closures-blanket-fn.rs b/src/test/run-pass/unboxed-closures-blanket-fn.rs index eb474473094..2aa48e7d2ad 100644 --- a/src/test/run-pass/unboxed-closures-blanket-fn.rs +++ b/src/test/run-pass/unboxed-closures-blanket-fn.rs @@ -10,8 +10,7 @@ // Test that you can supply `&F` where `F: Fn()`. - -#![feature(lang_items, unboxed_closures)] +#![feature(lang_items)] fn a i32>(f: F) -> i32 { f() diff --git a/src/test/run-pass/unboxed-closures-boxed.rs b/src/test/run-pass/unboxed-closures-boxed.rs index 5dea6a7c6db..069f26841d2 100644 --- a/src/test/run-pass/unboxed-closures-boxed.rs +++ b/src/test/run-pass/unboxed-closures-boxed.rs @@ -10,7 +10,6 @@ #![allow(unknown_features)] #![feature(box_syntax)] -#![feature(unboxed_closures)] use std::ops::FnMut; diff --git a/src/test/run-pass/unboxed-closures-by-ref.rs b/src/test/run-pass/unboxed-closures-by-ref.rs index e3ddfdbac00..b251215909a 100644 --- a/src/test/run-pass/unboxed-closures-by-ref.rs +++ b/src/test/run-pass/unboxed-closures-by-ref.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(unboxed_closures)] - // Test by-ref capture of environment in unboxed closure types fn call_fn(f: F) { diff --git a/src/test/run-pass/unboxed-closures-call-fn-autoderef.rs b/src/test/run-pass/unboxed-closures-call-fn-autoderef.rs index 64236ce563b..56c53bcafce 100644 --- a/src/test/run-pass/unboxed-closures-call-fn-autoderef.rs +++ b/src/test/run-pass/unboxed-closures-call-fn-autoderef.rs @@ -10,9 +10,6 @@ // Test that the call operator autoderefs when calling a bounded type parameter. - -#![feature(unboxed_closures)] - use std::ops::FnMut; fn call_with_2(x: &fn(isize) -> isize) -> isize diff --git a/src/test/run-pass/unboxed-closures-call-sugar-autoderef.rs b/src/test/run-pass/unboxed-closures-call-sugar-autoderef.rs index 67ab84f0276..63667ec11d6 100644 --- a/src/test/run-pass/unboxed-closures-call-sugar-autoderef.rs +++ b/src/test/run-pass/unboxed-closures-call-sugar-autoderef.rs @@ -10,9 +10,6 @@ // Test that the call operator autoderefs when calling a bounded type parameter. - -#![feature(unboxed_closures)] - use std::ops::FnMut; fn call_with_2(x: &mut F) -> isize diff --git a/src/test/run-pass/unboxed-closures-call-sugar-object-autoderef.rs b/src/test/run-pass/unboxed-closures-call-sugar-object-autoderef.rs index c82026235c2..a92fb05306f 100644 --- a/src/test/run-pass/unboxed-closures-call-sugar-object-autoderef.rs +++ b/src/test/run-pass/unboxed-closures-call-sugar-object-autoderef.rs @@ -11,7 +11,6 @@ // Test that the call operator autoderefs when calling to an object type. #![allow(unknown_features)] -#![feature(unboxed_closures)] use std::ops::FnMut; diff --git a/src/test/run-pass/unboxed-closures-call-sugar-object.rs b/src/test/run-pass/unboxed-closures-call-sugar-object.rs index 629da1091ac..5dd2343cfd1 100644 --- a/src/test/run-pass/unboxed-closures-call-sugar-object.rs +++ b/src/test/run-pass/unboxed-closures-call-sugar-object.rs @@ -9,7 +9,6 @@ // except according to those terms. #![allow(unknown_features)] -#![feature(unboxed_closures)] use std::ops::FnMut; diff --git a/src/test/run-pass/unboxed-closures-counter-not-moved.rs b/src/test/run-pass/unboxed-closures-counter-not-moved.rs index cb5f190bcd7..0b85916d224 100644 --- a/src/test/run-pass/unboxed-closures-counter-not-moved.rs +++ b/src/test/run-pass/unboxed-closures-counter-not-moved.rs @@ -10,7 +10,6 @@ // Test that we mutate a counter on the stack only when we expect to. - fn call(f: F) where F : FnOnce() { f(); } diff --git a/src/test/run-pass/unboxed-closures-direct-sugary-call.rs b/src/test/run-pass/unboxed-closures-direct-sugary-call.rs index c91aa6ed0d9..c8da4a6992a 100644 --- a/src/test/run-pass/unboxed-closures-direct-sugary-call.rs +++ b/src/test/run-pass/unboxed-closures-direct-sugary-call.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - fn main() { let mut unboxed = || {}; unboxed(); diff --git a/src/test/run-pass/unboxed-closures-drop.rs b/src/test/run-pass/unboxed-closures-drop.rs index 78f4905aef9..57f2f87e246 100644 --- a/src/test/run-pass/unboxed-closures-drop.rs +++ b/src/test/run-pass/unboxed-closures-drop.rs @@ -11,9 +11,6 @@ // A battery of tests to ensure destructors of unboxed closure environments // run at the right times. - -#![feature(unboxed_closures)] - static mut DROP_COUNT: usize = 0; fn drop_count() -> usize { diff --git a/src/test/run-pass/unboxed-closures-extern-fn.rs b/src/test/run-pass/unboxed-closures-extern-fn.rs index 57acbae4ce6..eddb6080d17 100644 --- a/src/test/run-pass/unboxed-closures-extern-fn.rs +++ b/src/test/run-pass/unboxed-closures-extern-fn.rs @@ -10,10 +10,6 @@ // Checks that extern fn pointers implement the full range of Fn traits. - -#![feature(unboxed_closures)] -#![feature(unboxed_closures)] - use std::ops::{Fn,FnMut,FnOnce}; fn square(x: isize) -> isize { x * x } diff --git a/src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs b/src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs index 2e63c600a46..f90aced3dbe 100644 --- a/src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs +++ b/src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs @@ -11,7 +11,6 @@ // Checks that the Fn trait hierarchy rules permit // any Fn trait to be used where Fn is implemented. - #![feature(unboxed_closures, fn_traits)] use std::ops::{Fn,FnMut,FnOnce}; diff --git a/src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs b/src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs index ce93fcafc9e..0a977cef442 100644 --- a/src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs +++ b/src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs @@ -11,7 +11,6 @@ // Checks that the Fn trait hierarchy rules permit // FnMut or FnOnce to be used where FnMut is implemented. - #![feature(unboxed_closures, fn_traits)] struct S; diff --git a/src/test/run-pass/unboxed-closures-generic.rs b/src/test/run-pass/unboxed-closures-generic.rs index 47936ba9382..01c81ef98d5 100644 --- a/src/test/run-pass/unboxed-closures-generic.rs +++ b/src/test/run-pass/unboxed-closures-generic.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] - use std::ops::FnMut; fn call_iti32>(y: i32, mut f: F) -> i32 { diff --git a/src/test/run-pass/unboxed-closures-infer-fnmut-calling-fnmut.rs b/src/test/run-pass/unboxed-closures-infer-fnmut-calling-fnmut.rs index 2da899ed95b..17833033492 100644 --- a/src/test/run-pass/unboxed-closures-infer-fnmut-calling-fnmut.rs +++ b/src/test/run-pass/unboxed-closures-infer-fnmut-calling-fnmut.rs @@ -11,7 +11,6 @@ // Test that we are able to infer a suitable kind for this closure // that is just called (`FnMut`). - fn main() { let mut counter = 0; diff --git a/src/test/run-pass/unboxed-closures-infer-fnmut-move.rs b/src/test/run-pass/unboxed-closures-infer-fnmut-move.rs index 32fc3433e84..794527249bf 100644 --- a/src/test/run-pass/unboxed-closures-infer-fnmut-move.rs +++ b/src/test/run-pass/unboxed-closures-infer-fnmut-move.rs @@ -11,7 +11,6 @@ // Test that we are able to infer a suitable kind for this `move` // closure that is just called (`FnMut`). - fn main() { let mut counter = 0; diff --git a/src/test/run-pass/unboxed-closures-infer-fnmut.rs b/src/test/run-pass/unboxed-closures-infer-fnmut.rs index a8469f4019a..67f36b9a920 100644 --- a/src/test/run-pass/unboxed-closures-infer-fnmut.rs +++ b/src/test/run-pass/unboxed-closures-infer-fnmut.rs @@ -11,7 +11,6 @@ // Test that we are able to infer a suitable kind for this closure // that is just called (`FnMut`). - fn main() { let mut counter = 0; diff --git a/src/test/run-pass/unboxed-closures-infer-kind.rs b/src/test/run-pass/unboxed-closures-infer-kind.rs index fa668475f58..c04df7ed5f8 100644 --- a/src/test/run-pass/unboxed-closures-infer-kind.rs +++ b/src/test/run-pass/unboxed-closures-infer-kind.rs @@ -11,9 +11,6 @@ // Test that we can infer the "kind" of an unboxed closure based on // the expected type. - -#![feature(unboxed_closures)] - // Test by-ref capture of environment in unboxed closure types fn call_fn(f: F) { diff --git a/src/test/run-pass/unboxed-closures-infer-upvar.rs b/src/test/run-pass/unboxed-closures-infer-upvar.rs index f2423145b19..1401fe7470b 100644 --- a/src/test/run-pass/unboxed-closures-infer-upvar.rs +++ b/src/test/run-pass/unboxed-closures-infer-upvar.rs @@ -11,7 +11,6 @@ // Test that the type variable in the type(`Vec<_>`) of a closed over // variable does not interfere with type inference. - fn f(mut f: F) { f(); } diff --git a/src/test/run-pass/unboxed-closures-move-mutable.rs b/src/test/run-pass/unboxed-closures-move-mutable.rs index 1aca3174e1f..a55b0a0185e 100644 --- a/src/test/run-pass/unboxed-closures-move-mutable.rs +++ b/src/test/run-pass/unboxed-closures-move-mutable.rs @@ -10,7 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] #![deny(unused_mut)] // Test that mutating a mutable upvar in a capture-by-value unboxed diff --git a/src/test/run-pass/unboxed-closures-move-some-upvars-in-by-ref-closure.rs b/src/test/run-pass/unboxed-closures-move-some-upvars-in-by-ref-closure.rs index e2b286738e7..99663646254 100644 --- a/src/test/run-pass/unboxed-closures-move-some-upvars-in-by-ref-closure.rs +++ b/src/test/run-pass/unboxed-closures-move-some-upvars-in-by-ref-closure.rs @@ -11,7 +11,6 @@ // Test that in a by-ref once closure we move some variables even as // we capture others by mutable reference. - fn call(f: F) where F : FnOnce() { f(); } diff --git a/src/test/run-pass/unboxed-closures-simple.rs b/src/test/run-pass/unboxed-closures-simple.rs index ec341981669..429afb95248 100644 --- a/src/test/run-pass/unboxed-closures-simple.rs +++ b/src/test/run-pass/unboxed-closures-simple.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(unboxed_closures)] - use std::ops::FnMut; pub fn main() { diff --git a/src/test/run-pass/unboxed-closures-single-word-env.rs b/src/test/run-pass/unboxed-closures-single-word-env.rs index 166054e88b7..3ed055a7884 100644 --- a/src/test/run-pass/unboxed-closures-single-word-env.rs +++ b/src/test/run-pass/unboxed-closures-single-word-env.rs @@ -11,9 +11,6 @@ // Ensures that single-word environments work right in unboxed closures. // These take a different path in codegen. - -#![feature(unboxed_closures)] - fn a isize>(f: F) -> isize { f(1, 2) } diff --git a/src/test/run-pass/unboxed-closures-static-call-fn-once.rs b/src/test/run-pass/unboxed-closures-static-call-fn-once.rs index e90a3443610..c13e9513ce3 100644 --- a/src/test/run-pass/unboxed-closures-static-call-fn-once.rs +++ b/src/test/run-pass/unboxed-closures-static-call-fn-once.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - fn main() { let onetime = |x| x; onetime(0); diff --git a/src/test/run-pass/unboxed-closures-sugar-object.rs b/src/test/run-pass/unboxed-closures-sugar-object.rs index 49b9b7f061e..b7d367f2353 100644 --- a/src/test/run-pass/unboxed-closures-sugar-object.rs +++ b/src/test/run-pass/unboxed-closures-sugar-object.rs @@ -10,9 +10,7 @@ // Test unboxed closure sugar used in object types. - #![allow(dead_code)] -#![feature(unboxed_closures)] struct Foo { t: T, u: U diff --git a/src/test/run-pass/unboxed-closures-unique-type-id.rs b/src/test/run-pass/unboxed-closures-unique-type-id.rs index 30c45fc766a..40071ec9754 100644 --- a/src/test/run-pass/unboxed-closures-unique-type-id.rs +++ b/src/test/run-pass/unboxed-closures-unique-type-id.rs @@ -19,9 +19,6 @@ // // compile-flags: -g - -#![feature(unboxed_closures)] - use std::ptr; pub fn replace_map<'a, T, F>(src: &mut T, prod: F) where F: FnOnce(T) -> T { diff --git a/src/test/run-pass/unboxed-closures-zero-args.rs b/src/test/run-pass/unboxed-closures-zero-args.rs index cb3a18a18c1..9e6a7cce1fd 100644 --- a/src/test/run-pass/unboxed-closures-zero-args.rs +++ b/src/test/run-pass/unboxed-closures-zero-args.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - fn main() { let mut zero = || {}; let () = zero(); diff --git a/src/test/run-pass/where-clauses-unboxed-closures.rs b/src/test/run-pass/where-clauses-unboxed-closures.rs index c509cbe2a5e..8a775caaac6 100644 --- a/src/test/run-pass/where-clauses-unboxed-closures.rs +++ b/src/test/run-pass/where-clauses-unboxed-closures.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(unboxed_closures)] - struct Bencher; // ICE