diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 8ed177c82a8f7..d95000ece5ae6 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -774,9 +774,8 @@ impl LintPass for UnusedResults { warned |= check_must_use(cx, &it.attrs[], s.span); } } else { - csearch::get_item_attrs(&cx.sess().cstore, did, |attrs| { - warned |= check_must_use(cx, &attrs[], s.span); - }); + let attrs = csearch::get_item_attrs(&cx.sess().cstore, did); + warned |= check_must_use(cx, &attrs[], s.span); } } _ => {} diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index cfff7c9935bc8..0bbd11bea0a48 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -203,13 +203,11 @@ pub fn get_methods_if_impl(cstore: &cstore::CStore, decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.node) } -pub fn get_item_attrs(cstore: &cstore::CStore, - def_id: ast::DefId, - f: F) where - F: FnOnce(Vec), -{ +pub fn get_item_attrs(cstore: &cstore::CStore, + def_id: ast::DefId) + -> Vec { let cdata = cstore.get_crate_data(def_id.krate); - decoder::get_item_attrs(&*cdata, def_id.node, f) + decoder::get_item_attrs(&*cdata, def_id.node) } pub fn get_struct_fields(cstore: &cstore::CStore, diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 5ac8f908bf164..dfbff7156886d 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1025,18 +1025,16 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, ret } -pub fn get_item_attrs(cdata: Cmd, - orig_node_id: ast::NodeId, - f: F) where - F: FnOnce(Vec), -{ +pub fn get_item_attrs(cdata: Cmd, + orig_node_id: ast::NodeId) + -> Vec { // The attributes for a tuple struct are attached to the definition, not the ctor; // we assume that someone passing in a tuple struct ctor is actually wanting to // look at the definition let node_id = get_tuple_struct_definition_if_ctor(cdata, orig_node_id); let node_id = node_id.map(|x| x.node).unwrap_or(orig_node_id); let item = lookup_item(node_id, cdata.data()); - f(get_attributes(item)); + get_attributes(item) } pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap> { diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 6b4dd101286d6..e9ef214543d6e 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -70,7 +70,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, span: Span) -> Option { let def_id = trait_ref.def_id; let mut report = None; - ty::each_attr(infcx.tcx, def_id, |item| { + for item in ty::get_attrs(infcx.tcx, def_id).iter() { if item.check_name("rustc_on_unimplemented") { let err_sp = if item.meta().span == DUMMY_SP { span @@ -136,11 +136,9 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, eg `#[rustc_on_unimplemented = \"foo\"]`", trait_str).as_slice()); } - false - } else { - true + break; } - }); + } report } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index cf30969ebefcc..236aa3818c77a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -68,7 +68,7 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; use util::nodemap::{FnvHashMap}; use arena::TypedArena; -use std::borrow::BorrowFrom; +use std::borrow::{BorrowFrom, Cow}; use std::cell::{Cell, RefCell}; use std::cmp::{self, Ordering}; use std::fmt::{self, Show}; @@ -76,6 +76,7 @@ use std::hash::{Hash, Writer, SipHasher, Hasher}; use std::mem; use std::ops; use std::rc::Rc; +use std::vec::CowVec; use collections::enum_set::{EnumSet, CLike}; use std::collections::{HashMap, HashSet}; use syntax::abi; @@ -5555,40 +5556,20 @@ pub fn predicates<'tcx>( vec } -/// Iterate over attributes of a definition. -// (This should really be an iterator, but that would require csearch and -// decoder to use iterators instead of higher-order functions.) -pub fn each_attr(tcx: &ctxt, did: DefId, mut f: F) -> bool where - F: FnMut(&ast::Attribute) -> bool, -{ +/// Get the attributes of a definition. +pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId) + -> CowVec<'tcx, ast::Attribute> { if is_local(did) { let item = tcx.map.expect_item(did.node); - item.attrs.iter().all(|attr| f(attr)) + Cow::Borrowed(&item.attrs[]) } else { - info!("getting foreign attrs"); - let mut cont = true; - csearch::get_item_attrs(&tcx.sess.cstore, did, |attrs| { - if cont { - cont = attrs.iter().all(|attr| f(attr)); - } - }); - info!("done"); - cont + Cow::Owned(csearch::get_item_attrs(&tcx.sess.cstore, did)) } } /// Determine whether an item is annotated with an attribute pub fn has_attr(tcx: &ctxt, did: DefId, attr: &str) -> bool { - let mut found = false; - each_attr(tcx, did, |item| { - if item.check_name(attr) { - found = true; - false - } else { - true - } - }); - found + get_attrs(tcx, did).iter().any(|item| item.check_name(attr)) } /// Determine whether an item is annotated with `#[repr(packed)]` @@ -5605,13 +5586,9 @@ pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool { pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc> { memoized(&tcx.repr_hint_cache, did, |did: DefId| { Rc::new(if did.krate == LOCAL_CRATE { - let mut acc = Vec::new(); - ty::each_attr(tcx, did, |meta| { - acc.extend(attr::find_repr_attrs(tcx.sess.diagnostic(), - meta).into_iter()); - true - }); - acc + get_attrs(tcx, did).iter().flat_map(|meta| { + attr::find_repr_attrs(tcx.sess.diagnostic(), meta).into_iter() + }).collect() } else { csearch::get_repr_attrs(&tcx.sess.cstore, did) }) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index c1efec8600114..28558c5a204f1 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -248,9 +248,8 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>, let f = decl_rust_fn(ccx, fn_ty, name); - csearch::get_item_attrs(&ccx.sess().cstore, did, |attrs| { - set_llvm_fn_attrs(ccx, &attrs[], f) - }); + let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did); + set_llvm_fn_attrs(ccx, &attrs[], f); ccx.externs().borrow_mut().insert(name.to_string(), f); f @@ -353,12 +352,11 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId, // don't do this then linker errors can be generated where the linker // complains that one object files has a thread local version of the // symbol and another one doesn't. - ty::each_attr(ccx.tcx(), did, |attr| { + for attr in ty::get_attrs(ccx.tcx(), did).iter() { if attr.check_name("thread_local") { llvm::set_thread_local(c, true); } - true - }); + } ccx.externs().borrow_mut().insert(name.to_string(), c); return c; } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3e2474468adb6..ccaefadc1fcd9 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -126,13 +126,8 @@ fn try_inline_def(cx: &DocContext, tcx: &ty::ctxt, pub fn load_attrs(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> Vec { - let mut attrs = Vec::new(); - csearch::get_item_attrs(&tcx.sess.cstore, did, |v| { - attrs.extend(v.into_iter().map(|a| { - a.clean(cx) - })); - }); - attrs + let attrs = csearch::get_item_attrs(&tcx.sess.cstore, did); + attrs.into_iter().map(|a| a.clean(cx)).collect() } /// Record an external fully qualified name in the external_paths cache.