(index<- )        ./librustc/middle/lang_items.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  // Detecting language items.
  12  //
  13  // Language items are items that represent concepts intrinsic to the language
  14  // itself. Examples are:
  15  //
  16  // * Traits that specify "kinds"; e.g. "Share", "Send".
  17  //
  18  // * Traits that represent operators; e.g. "Add", "Sub", "Index".
  19  //
  20  // * Functions called by the compiler itself.
  21  
  22  
  23  use driver::session::Session;
  24  use metadata::csearch::each_lang_item;
  25  use middle::ty;
  26  use syntax::ast;
  27  use syntax::ast_util::local_def;
  28  use syntax::attr::AttrMetaMethods;
  29  use syntax::parse::token::InternedString;
  30  use syntax::visit::Visitor;
  31  use syntax::visit;
  32  
  33  use collections::HashMap;
  34  use std::iter::Enumerate;
  35  use std::slice;
  36  
  37  // The actual lang items defined come at the end of this file in one handy table.
  38  // So you probably just want to nip down to the end.
  39  macro_rules! lets_do_this {
  40      (
  41          $( $variant:ident, $name:expr, $method:ident; )*
  42      ) => {
  43  
  44  #[deriving(FromPrimitive)]
  45  pub enum LangItem {
  46      $($variant),*
  47  }
  48  
  49  pub struct LanguageItems {
  50      pub items: Vec<Option<ast::DefId>> ,
  51  }
  52  
  53  impl LanguageItems {
  54      pub fn new() -> LanguageItems {
  55          fn foo(_LangItem) -> Option<ast::DefId> { None }
  56  
  57          LanguageItems {
  58              items: vec!($(foo($variant)),*)
  59          }
  60      }
  61  
  62      pub fn items<'a>(&'a self) -> Enumerate<slice::Items<'a, Option<ast::DefId>>> {
  63          self.items.iter().enumerate()
  64      }
  65  
  66      pub fn item_name(indexuint) -> &'static str {
  67          let itemOption<LangItem> = FromPrimitive::from_uint(index);
  68          match item {
  69              $( Some($variant) => $name, )*
  70              None => "???"
  71          }
  72      }
  73  
  74      pub fn require(&self, itLangItem) -> Result<ast::DefId, ~str> {
  75          match self.items.get(it as uint) {
  76              &Some(id) => Ok(id),
  77              &None => {
  78                  Err(format!("requires `{}` lang_item",
  79                              LanguageItems::item_name(it as uint)))
  80              }
  81          }
  82      }
  83  
  84      pub fn to_builtin_kind(&self, idast::DefId) -> Option<ty::BuiltinBound> {
  85          if Some(id) == self.send_trait() {
  86              Some(ty::BoundSend)
  87          } else if Some(id) == self.sized_trait() {
  88              Some(ty::BoundSized)
  89          } else if Some(id) == self.copy_trait() {
  90              Some(ty::BoundCopy)
  91          } else if Some(id) == self.share_trait() {
  92              Some(ty::BoundShare)
  93          } else {
  94              None
  95          }
  96      }
  97  
  98      $(
  99          #[allow(dead_code)]
 100          pub fn $method(&self) -> Option<ast::DefId> {
 101              *self.items.get($variant as uint)
 102          }
 103      )*
 104  }
 105  
 106  struct LanguageItemCollector<'a> {
 107      items: LanguageItems,
 108  
 109      session: &'a Session,
 110  
 111      item_refs: HashMap<&'static str, uint>,
 112  }
 113  
 114  impl<'a> Visitor<()> for LanguageItemCollector<'a> {
 115      fn visit_item(&mut self, item&ast::Item, _()) {
 116          match extract(item.attrs.as_slice()) {
 117              Some(value) => {
 118                  let item_index = self.item_refs.find_equiv(&value).map(|x| *x);
 119  
 120                  match item_index {
 121                      Some(item_index) => {
 122                          self.collect_item(item_index, local_def(item.id))
 123                      }
 124                      None => {}
 125                  }
 126              }
 127              None => {}
 128          }
 129  
 130          visit::walk_item(self, item, ());
 131      }
 132  }
 133  
 134  impl<'a> LanguageItemCollector<'a> {
 135      pub fn new(session&'a Session) -> LanguageItemCollector<'a> {
 136          let mut item_refs = HashMap::new();
 137  
 138          $( item_refs.insert($name, $variant as uint); )*
 139  
 140          LanguageItemCollector {
 141              session: session,
 142              items: LanguageItems::new(),
 143              item_refs: item_refs
 144          }
 145      }
 146  
 147      pub fn collect_item(&mut self, item_indexuint, item_def_idast::DefId) {
 148          // Check for duplicates.
 149          match self.items.items.get(item_index) {
 150              &Some(original_def_id) if original_def_id != item_def_id => {
 151                  self.session.err(format!("duplicate entry for `{}`",
 152                                        LanguageItems::item_name(item_index)));
 153              }
 154              &Some(_) | &None => {
 155                  // OK.
 156              }
 157          }
 158  
 159          // Matched.
 160          *self.items.items.get_mut(item_index) = Some(item_def_id);
 161      }
 162  
 163      pub fn collect_local_language_items(&mut self, krate&ast::Crate) {
 164          visit::walk_crate(self, krate, ());
 165      }
 166  
 167      pub fn collect_external_language_items(&mut self) {
 168          let crate_store = &self.session.cstore;
 169          crate_store.iter_crate_data(|crate_number, _crate_metadata| {
 170              each_lang_item(crate_store, crate_number, |node_id, item_index| {
 171                  let def_id = ast::DefId { krate: crate_number, node: node_id };
 172                  self.collect_item(item_index, def_id);
 173                  true
 174              });
 175          })
 176      }
 177  
 178      pub fn collect(&mut self, krate&ast::Crate) {
 179          self.collect_local_language_items(krate);
 180          self.collect_external_language_items();
 181      }
 182  }
 183  
 184  pub fn extract(attrs: &[ast::Attribute]) -> Option<InternedString> {
 185      for attribute in attrs.iter() {
 186          match attribute.name_str_pair() {
 187              Some((ref key, ref value)) if key.equiv(&("lang")) => {
 188                  return Some((*value).clone());
 189              }
 190              Some(..) | None => {}
 191          }
 192      }
 193  
 194      return None;
 195  }
 196  
 197  pub fn collect_language_items(krate: &ast::Crate,
 198                                session: &Session) -> LanguageItems {
 199      let mut collector = LanguageItemCollector::new(session);
 200      collector.collect(krate);
 201      let LanguageItemCollector { items, .. } = collector;
 202      session.abort_if_errors();
 203      items
 204  }
 205  
 206  // End of the macro
 207      }
 208  }
 209  
 210  lets_do_this! {
 211  //  Variant name,                    Name,                      Method name;
 212      SendTraitLangItem,               "send",                    send_trait;
 213      SizedTraitLangItem,              "sized",                   sized_trait;
 214      CopyTraitLangItem,               "copy",                    copy_trait;
 215      ShareTraitLangItem,              "share",                   share_trait;
 216  
 217      DropTraitLangItem,               "drop",                    drop_trait;
 218  
 219      AddTraitLangItem,                "add",                     add_trait;
 220      SubTraitLangItem,                "sub",                     sub_trait;
 221      MulTraitLangItem,                "mul",                     mul_trait;
 222      DivTraitLangItem,                "div",                     div_trait;
 223      RemTraitLangItem,                "rem",                     rem_trait;
 224      NegTraitLangItem,                "neg",                     neg_trait;
 225      NotTraitLangItem,                "not",                     not_trait;
 226      BitXorTraitLangItem,             "bitxor",                  bitxor_trait;
 227      BitAndTraitLangItem,             "bitand",                  bitand_trait;
 228      BitOrTraitLangItem,              "bitor",                   bitor_trait;
 229      ShlTraitLangItem,                "shl",                     shl_trait;
 230      ShrTraitLangItem,                "shr",                     shr_trait;
 231      IndexTraitLangItem,              "index",                   index_trait;
 232  
 233      UnsafeTypeLangItem,              "unsafe",                  unsafe_type;
 234  
 235      DerefTraitLangItem,              "deref",                   deref_trait;
 236      DerefMutTraitLangItem,           "deref_mut",               deref_mut_trait;
 237  
 238      EqTraitLangItem,                 "eq",                      eq_trait;
 239      OrdTraitLangItem,                "ord",                     ord_trait;
 240  
 241      StrEqFnLangItem,                 "str_eq",                  str_eq_fn;
 242      UniqStrEqFnLangItem,             "uniq_str_eq",             uniq_str_eq_fn;
 243      FailFnLangItem,                  "fail_",                   fail_fn;
 244      FailBoundsCheckFnLangItem,       "fail_bounds_check",       fail_bounds_check_fn;
 245      ExchangeMallocFnLangItem,        "exchange_malloc",         exchange_malloc_fn;
 246      ClosureExchangeMallocFnLangItem, "closure_exchange_malloc", closure_exchange_malloc_fn;
 247      ExchangeFreeFnLangItem,          "exchange_free",           exchange_free_fn;
 248      MallocFnLangItem,                "malloc",                  malloc_fn;
 249      FreeFnLangItem,                  "free",                    free_fn;
 250      StrDupUniqFnLangItem,            "strdup_uniq",             strdup_uniq_fn;
 251  
 252      StartFnLangItem,                 "start",                   start_fn;
 253  
 254      TyDescStructLangItem,            "ty_desc",                 ty_desc;
 255      TyVisitorTraitLangItem,          "ty_visitor",              ty_visitor;
 256      OpaqueStructLangItem,            "opaque",                  opaque;
 257  
 258      TypeIdLangItem,                  "type_id",                 type_id;
 259  
 260      EhPersonalityLangItem,           "eh_personality",          eh_personality_fn;
 261  
 262      ManagedHeapLangItem,             "managed_heap",            managed_heap;
 263      ExchangeHeapLangItem,            "exchange_heap",           exchange_heap;
 264      GcLangItem,                      "gc",                      gc;
 265      OwnedBoxLangItem,                "owned_box",               owned_box;
 266  
 267      CovariantTypeItem,               "covariant_type",          covariant_type;
 268      ContravariantTypeItem,           "contravariant_type",      contravariant_type;
 269      InvariantTypeItem,               "invariant_type",          invariant_type;
 270  
 271      CovariantLifetimeItem,           "covariant_lifetime",      covariant_lifetime;
 272      ContravariantLifetimeItem,       "contravariant_lifetime",  contravariant_lifetime;
 273      InvariantLifetimeItem,           "invariant_lifetime",      invariant_lifetime;
 274  
 275      NoSendItem,                      "no_send_bound",           no_send_bound;
 276      NoCopyItem,                      "no_copy_bound",           no_copy_bound;
 277      NoShareItem,                     "no_share_bound",          no_share_bound;
 278      ManagedItem,                     "managed_bound",           managed_bound;
 279  }


librustc/middle/lang_items.rs:55:8-55:8 -fn- definition:
        fn foo(_: LangItem) -> Option<ast::DefId> { None }
        LanguageItems {
            items: vec!($(foo($variant)),*)
references:- 53


librustc/middle/lang_items.rs:105:1-105:1 -struct- definition:
struct LanguageItemCollector<'a> {
    items: LanguageItems,
    session: &'a Session,
references:- 5
200:     collector.collect(krate);
201:     let LanguageItemCollector { items, .. } = collector;
202:     session.abort_if_errors();


librustc/middle/lang_items.rs:48:1-48:1 -struct- definition:
pub struct LanguageItems {
    pub items: Vec<Option<ast::DefId>> ,
}
references:- 10
57:         LanguageItems {
58:             items: vec!($(foo($variant)),*)
--
106: struct LanguageItemCollector<'a> {
107:     items: LanguageItems,
--
197: pub fn collect_language_items(krate: &ast::Crate,
198:                               session: &Session) -> LanguageItems {
199:     let mut collector = LanguageItemCollector::new(session);
librustc/middle/ty.rs:
288:     pub normalized_cache: RefCell<HashMap<t, t>>,
289:     pub lang_items: middle::lang_items::LanguageItems,
290:     // A mapping of fake provided method def_ids to the default implementation
--
1077:                region_maps: middle::region::RegionMaps,
1078:                lang_items: middle::lang_items::LanguageItems)
1079:             -> ctxt {
librustc/middle/resolve.rs:
858:     session: &'a Session,
859:     lang_items: &'a LanguageItems,
--
5380: pub fn resolve_crate(session: &Session,
5381:                      lang_items: &LanguageItems,
5382:                      krate: &Crate)


librustc/middle/lang_items.rs:44:27-44:27 -enum- definition:
pub enum LangItem {
    $($variant),*
}
references:- 9
45: pub enum LangItem {
--
74:     pub fn require(&self, it: LangItem) -> Result<ast::DefId, ~str> {
75:         match self.items.get(it as uint) {
librustc/middle/trans/common.rs:
858:                 msg: &str,
859:                 li: LangItem)
860:                 -> ast::DefId {
librustc/middle/trans/base.rs:
365:                       t: ty::t,
366:                       alloc_fn: LangItem,
367:                       size: ValueRef)