diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 6b4dd101286d..e9ef214543d6 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 2cef5f8353fa..236aa3818c77 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,35 +5556,20 @@ pub fn predicates<'tcx>( vec } -/// Iterate over attributes of a definition. -// (This should really be an iterator.) -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 attrs = csearch::get_item_attrs(&tcx.sess.cstore, did); - let 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)]` @@ -5600,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 fe7c0d4cf694..36757470dc06 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -352,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; }