(index<- )        ./librustc/middle/typeck/collect.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-2014 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  /*
   12  
   13  # Collect phase
   14  
   15  The collect phase of type check has the job of visiting all items,
   16  determining their type, and writing that type into the `tcx.tcache`
   17  table.  Despite its name, this table does not really operate as a
   18  *cache*, at least not for the types of items defined within the
   19  current crate: we assume that after the collect phase, the types of
   20  all local items will be present in the table.
   21  
   22  Unlike most of the types that are present in Rust, the types computed
   23  for each item are in fact polytypes.  In "layman's terms", this means
   24  that they are generic types that may have type parameters (more
   25  mathematically phrased, they are universally quantified over a set of
   26  type parameters).  Polytypes are represented by an instance of
   27  `ty::ty_param_bounds_and_ty`.  This combines the core type along with
   28  a list of the bounds for each parameter.  Type parameters themselves
   29  are represented as `ty_param()` instances.
   30  
   31  */
   32  
   33  
   34  use metadata::csearch;
   35  use middle::lang_items::SizedTraitLangItem;
   36  use middle::resolve_lifetime;
   37  use middle::ty::{ImplContainer, MethodContainer, TraitContainer, substs};
   38  use middle::ty::{ty_param_bounds_and_ty};
   39  use middle::ty;
   40  use middle::subst::Subst;
   41  use middle::typeck::astconv::{AstConv, ty_of_arg};
   42  use middle::typeck::astconv::{ast_ty_to_ty};
   43  use middle::typeck::astconv;
   44  use middle::typeck::rscope::*;
   45  use middle::typeck::{CrateCtxt, lookup_def_tcx, no_params, write_ty_to_tcx};
   46  use util::ppaux;
   47  use util::ppaux::Repr;
   48  
   49  use std::rc::Rc;
   50  use collections::{HashMap, HashSet};
   51  
   52  use syntax::abi;
   53  use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound,
   54                    TraitTyParamBound};
   55  use syntax::ast;
   56  use syntax::ast_map;
   57  use syntax::ast_util::{local_def, split_trait_methods};
   58  use syntax::codemap::Span;
   59  use syntax::codemap;
   60  use syntax::parse::token::special_idents;
   61  use syntax::parse::token;
   62  use syntax::print::pprust::{path_to_str};
   63  use syntax::visit;
   64  use syntax::owned_slice::OwnedSlice;
   65  
   66  struct CollectItemTypesVisitor<'a> {
   67      ccx: &'a CrateCtxt<'a>
   68  }
   69  
   70  impl<'a> visit::Visitor<()> for CollectItemTypesVisitor<'a> {
   71      fn visit_item(&mut self, i&ast::Item, _()) {
   72          convert(self.ccx, i);
   73          visit::walk_item(self, i, ());
   74      }
   75      fn visit_foreign_item(&mut self, i&ast::ForeignItem, _()) {
   76          convert_foreign(self.ccx, i);
   77          visit::walk_foreign_item(self, i, ());
   78      }
   79  }
   80  
   81  pub fn collect_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
   82      fn collect_intrinsic_type(ccx: &CrateCtxt,
   83                                lang_itemast::DefId) {
   84          let ty::ty_param_bounds_and_ty { ty: ty, .. } =
   85              ccx.get_item_ty(lang_item);
   86          ccx.tcx.intrinsic_defs.borrow_mut().insert(lang_item, ty);
   87      }
   88  
   89      match ccx.tcx.lang_items.ty_desc() {
   90          Some(id) => { collect_intrinsic_type(ccx, id); } None => {}
   91      }
   92      match ccx.tcx.lang_items.opaque() {
   93          Some(id) => { collect_intrinsic_type(ccx, id); } None => {}
   94      }
   95  
   96      let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
   97      visit::walk_crate(&mut visitor, krate, ());
   98  }
   99  
  100  pub trait ToTy {
  101      fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &ast::Ty) -> ty::t;
  102  }
  103  
  104  impl<'a> ToTy for CrateCtxt<'a> {
  105      fn to_ty<RS:RegionScope>(&self, rs&RS, ast_ty&ast::Ty) -> ty::t {
  106          ast_ty_to_ty(self, rs, ast_ty)
  107      }
  108  }
  109  
  110  impl<'a> AstConv for CrateCtxt<'a> {
  111      fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
  112  
  113      fn get_item_ty(&self, idast::DefId) -> ty::ty_param_bounds_and_ty {
  114          if id.krate != ast::LOCAL_CRATE {
  115              return csearch::get_type(self.tcx, id)
  116          }
  117  
  118          match self.tcx.map.find(id.node) {
  119              Some(ast_map::NodeItem(item)) => ty_of_item(self, item),
  120              Some(ast_map::NodeForeignItem(foreign_item)) => {
  121                  let abi = self.tcx.map.get_foreign_abi(id.node);
  122                  ty_of_foreign_item(self, foreign_item, abi)
  123              }
  124              x => {
  125                  self.tcx.sess.bug(format!("unexpected sort of node \
  126                                             in get_item_ty(){:?}", x));
  127              }
  128          }
  129      }
  130  
  131      fn get_trait_def(&self, idast::DefId) -> Rc<ty::TraitDef> {
  132          get_trait_def(self, id)
  133      }
  134  
  135      fn ty_infer(&self, spanSpan) -> ty::t {
  136          self.tcx.sess.span_err(span, "the type placeholder `_` is not \
  137                                        allowed within types on item signatures.");
  138          ty::mk_err()
  139      }
  140  }
  141  
  142  pub fn get_enum_variant_types(ccx: &CrateCtxt,
  143                                enum_tyty::t,
  144                                variants: &[ast::P<ast::Variant>],
  145                                generics: &ast::Generics) {
  146      let tcx = ccx.tcx;
  147  
  148      // Create a set of parameter types shared among all the variants.
  149      for variant in variants.iter() {
  150          // Nullary enum constructors get turned into constants; n-ary enum
  151          // constructors get turned into functions.
  152          let scope = variant.node.id;
  153          let result_ty = match variant.node.kind {
  154              ast::TupleVariantKind(ref args) if args.len() > 0 => {
  155                  let rs = ExplicitRscope;
  156                  let input_tysVec<_> = args.iter().map(|va| ccx.to_ty(&rs, va.ty)).collect();
  157                  ty::mk_ctor_fn(tcx, scope, input_tys.as_slice(), enum_ty)
  158              }
  159  
  160              ast::TupleVariantKind(_) => {
  161                  enum_ty
  162              }
  163  
  164              ast::StructVariantKind(struct_def) => {
  165                  let tpt = ty_param_bounds_and_ty {
  166                      generics: ty_generics_for_type(ccx, generics),
  167                      ty: enum_ty
  168                  };
  169  
  170                  convert_struct(ccx, struct_def, tpt, variant.node.id);
  171  
  172                  let input_tysVec<_> = struct_def.fields.iter().map(
  173                      |f| ty::node_id_to_type(ccx.tcx, f.node.id)).collect();
  174                  ty::mk_ctor_fn(tcx, scope, input_tys.as_slice(), enum_ty)
  175              }
  176          };
  177  
  178          let tpt = ty_param_bounds_and_ty {
  179              generics: ty_generics_for_type(ccx, generics),
  180              ty: result_ty
  181          };
  182  
  183          tcx.tcache.borrow_mut().insert(local_def(variant.node.id), tpt);
  184  
  185          write_ty_to_tcx(tcx, variant.node.id, result_ty);
  186      }
  187  }
  188  
  189  pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_idast::NodeId) {
  190      let tcx = ccx.tcx;
  191      match tcx.map.get(trait_id) {
  192          ast_map::NodeItem(item) => {
  193              match item.node {
  194                  ast::ItemTrait(ref generics, _, _, ref ms) => {
  195                      let trait_ty_generics = ty_generics_for_type(ccx, generics);
  196  
  197                      // For each method, construct a suitable ty::Method and
  198                      // store it into the `tcx.methods` table:
  199                      for m in ms.iter() {
  200                          let ty_method = Rc::new(match m {
  201                              &ast::Required(ref m) => {
  202                                  ty_method_of_trait_method(
  203                                      ccx, trait_id, &trait_ty_generics,
  204                                      &m.id, &m.ident, &m.explicit_self,
  205                                      &m.generics, &m.fn_style, m.decl)
  206                              }
  207  
  208                              &ast::Provided(ref m) => {
  209                                  ty_method_of_trait_method(
  210                                      ccx, trait_id, &trait_ty_generics,
  211                                      &m.id, &m.ident, &m.explicit_self,
  212                                      &m.generics, &m.fn_style, m.decl)
  213                              }
  214                          });
  215  
  216                          if ty_method.explicit_self == ast::SelfStatic {
  217                              make_static_method_ty(ccx, trait_id, &*ty_method,
  218                                                    &trait_ty_generics);
  219                          }
  220  
  221                          tcx.methods.borrow_mut().insert(ty_method.def_id,
  222                                                          ty_method);
  223                      }
  224  
  225                      // Add an entry mapping
  226                      let method_def_ids = Rc::new(ms.iter().map(|m| {
  227                          match m {
  228                              &ast::Required(ref ty_method) => {
  229                                  local_def(ty_method.id)
  230                              }
  231                              &ast::Provided(ref method) => {
  232                                  local_def(method.id)
  233                              }
  234                          }
  235                      }).collect());
  236  
  237                      let trait_def_id = local_def(trait_id);
  238                      tcx.trait_method_def_ids.borrow_mut()
  239                          .insert(trait_def_id, method_def_ids);
  240                  }
  241                  _ => {} // Ignore things that aren't traits.
  242              }
  243          }
  244          _ => { /* Ignore things that aren't traits */ }
  245      }
  246  
  247      fn make_static_method_ty(ccx&CrateCtxt,
  248                               trait_idast::NodeId,
  249                               m&ty::Method,
  250                               trait_ty_generics&ty::Generics) {
  251          // If declaration is
  252          //
  253          //     trait Trait<'a,'b,'c,a,b,c> {
  254          //        fn foo<'d,'e,'f,d,e,f>(...) -> Self;
  255          //     }
  256          //
  257          // and we will create a function like
  258          //
  259          //     fn foo<'a,'b,'c,   // First the lifetime params from trait
  260          //            'd,'e,'f,   // Then lifetime params from `foo()`
  261          //            a,b,c,      // Then type params from trait
  262          //            D:Trait<'a,'b,'c,a,b,c>, // Then this sucker
  263          //            E,F,G       // Then type params from `foo()`, offset by 1
  264          //           >(...) -> D' {}
  265          //
  266          // Note that `Self` is replaced with an explicit type
  267          // parameter D that is sandwiched in between the trait params
  268          // and the method params, and thus the indices of the method
  269          // type parameters are offset by 1 (that is, the method
  270          // parameters are mapped from d, e, f to E, F, and G).  The
  271          // choice of this ordering is somewhat arbitrary.
  272          //
  273          // Note also that the bound for `D` is `Trait<'a,'b,'c,a,b,c>`.
  274          // This implies that the lifetime parameters that were inherited
  275          // from the trait (i.e., `'a`, `'b`, and `'c`) all must be early
  276          // bound, since they appear in a trait bound.
  277          //
  278          // Also, this system is rather a hack that should be replaced
  279          // with a more uniform treatment of Self (which is partly
  280          // underway).
  281  
  282          // build up a subst that shifts all of the parameters over
  283          // by one and substitute in a new type param for self
  284  
  285          let tcx = ccx.tcx;
  286  
  287          let dummy_defid = ast::DefId {krate: 0, node: 0};
  288  
  289          // Represents [A',B',C']
  290          let num_trait_bounds = trait_ty_generics.type_param_defs().len();
  291          let non_shifted_trait_tps = Vec::from_fn(num_trait_bounds, |i| {
  292              ty::mk_param(tcx, i, trait_ty_generics.type_param_defs()[i].def_id)
  293          });
  294  
  295          // Represents [D']
  296          let self_param = ty::mk_param(tcx, num_trait_bounds,
  297                                        dummy_defid);
  298  
  299          // Represents [E',F',G']
  300          let num_method_bounds = m.generics.type_param_defs().len();
  301          let shifted_method_tps = Vec::from_fn(num_method_bounds, |i| {
  302              ty::mk_param(tcx, i + num_trait_bounds + 1,
  303                           m.generics.type_param_defs()[i].def_id)
  304          });
  305  
  306          // Convert the regions 'a, 'b, 'c defined on the trait into
  307          // bound regions on the fn. Note that because these appear in the
  308          // bound for `Self` they must be early bound.
  309          let new_early_region_param_defs = trait_ty_generics.region_param_defs.clone();
  310          let rps_from_trait =
  311              trait_ty_generics.region_param_defs().iter().
  312              enumerate().
  313              map(|(index,d)| ty::ReEarlyBound(d.def_id.node, index, d.name)).
  314              collect();
  315  
  316          // build up the substitution from
  317          //     'a,'b,'c => 'a,'b,'c
  318          //     A,B,C => A',B',C'
  319          //     Self => D'
  320          //     D,E,F => E',F',G'
  321          let substs = substs {
  322              regions: ty::NonerasedRegions(rps_from_trait),
  323              self_ty: Some(self_param),
  324              tps: non_shifted_trait_tps.append(shifted_method_tps.as_slice())
  325          };
  326  
  327          // create the type of `foo`, applying the substitution above
  328          let ty = ty::subst(tcx,
  329                             &substs,
  330                             ty::mk_bare_fn(tcx, m.fty.clone()));
  331  
  332          // create the type parameter definitions for `foo`, applying
  333          // the substitution to any traits that appear in their bounds.
  334  
  335          // add in the type parameters from the trait
  336          let mut new_type_param_defs = Vec::new();
  337          let substd_type_param_defs =
  338              trait_ty_generics.type_param_defs.subst(tcx, &substs);
  339          new_type_param_defs.push_all(substd_type_param_defs.as_slice());
  340  
  341          // add in the "self" type parameter
  342          let self_trait_def = get_trait_def(ccx, local_def(trait_id));
  343          let self_trait_ref = self_trait_def.trait_ref.subst(tcx, &substs);
  344          new_type_param_defs.push(ty::TypeParameterDef {
  345              ident: special_idents::self_,
  346              def_id: dummy_defid,
  347              bounds: Rc::new(ty::ParamBounds {
  348                  builtin_bounds: ty::EmptyBuiltinBounds(),
  349                  trait_bounds: vec!(self_trait_ref)
  350              }),
  351              default: None
  352          });
  353  
  354          // add in the type parameters from the method
  355          let substd_type_param_defs = m.generics.type_param_defs.subst(tcx, &substs);
  356          new_type_param_defs.push_all(substd_type_param_defs.as_slice());
  357  
  358          debug!("static method {} type_param_defs={} ty={}, substs={}",
  359                 m.def_id.repr(tcx),
  360                 new_type_param_defs.repr(tcx),
  361                 ty.repr(tcx),
  362                 substs.repr(tcx));
  363  
  364          tcx.tcache.borrow_mut().insert(m.def_id,
  365                            ty_param_bounds_and_ty {
  366                                generics: ty::Generics {
  367                                    type_param_defs: Rc::new(new_type_param_defs),
  368                                    region_param_defs: new_early_region_param_defs
  369                                },
  370                                ty: ty
  371                            });
  372      }
  373  
  374      fn ty_method_of_trait_method(this&CrateCtxt,
  375                                   trait_idast::NodeId,
  376                                   trait_generics&ty::Generics,
  377                                   m_id&ast::NodeId,
  378                                   m_ident: &ast::Ident,
  379                                   m_explicit_self&ast::ExplicitSelf,
  380                                   m_generics: &ast::Generics,
  381                                   m_fn_style&ast::FnStyle,
  382                                   m_decl&ast::FnDecl) -> ty::Method
  383      {
  384          let trait_self_ty = ty::mk_self(this.tcx, local_def(trait_id));
  385          let fty = astconv::ty_of_method(this, *m_id, *m_fn_style, trait_self_ty,
  386                                          *m_explicit_self, m_decl);
  387          let num_trait_type_params = trait_generics.type_param_defs().len();
  388          let ty_generics = ty_generics_for_fn_or_method(this, m_generics,
  389                                                         num_trait_type_params);
  390          ty::Method::new(
  391              *m_ident,
  392              ty_generics,
  393              fty,
  394              m_explicit_self.node,
  395              // assume public, because this is only invoked on trait methods
  396              ast::Public,
  397              local_def(*m_id),
  398              TraitContainer(local_def(trait_id)),
  399              None
  400          )
  401      }
  402  }
  403  
  404  pub fn ensure_supertraits(ccx: &CrateCtxt,
  405                            idast::NodeId,
  406                            spcodemap::Span,
  407                            ast_trait_refs: &[ast::TraitRef],
  408                            sizedast::Sized)
  409                            -> ty::BuiltinBounds
  410  {
  411      let tcx = ccx.tcx;
  412  
  413      // Called only the first time trait_def_of_item is called.
  414      // Supertraits are ensured at the same time.
  415      assert!(!tcx.supertraits.borrow().contains_key(&local_def(id)));
  416  
  417      let self_ty = ty::mk_self(ccx.tcx, local_def(id));
  418      let mut ty_trait_refsVec<Rc<ty::TraitRef>> = Vec::new();
  419      let mut bounds = ty::EmptyBuiltinBounds();
  420      for ast_trait_ref in ast_trait_refs.iter() {
  421          let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, ast_trait_ref);
  422          // FIXME(#8559): Need to instantiate the trait_ref whether or not it's a
  423          // builtin trait, so that the trait's node id appears in the tcx trait_ref
  424          // map. This is only needed for metadata; see the similar fixme in encoder.rs.
  425          let trait_ref = instantiate_trait_ref(ccx, ast_trait_ref, self_ty);
  426          if !ty::try_add_builtin_trait(ccx.tcx, trait_def_id, &mut bounds) {
  427  
  428              // FIXME(#5527) Could have same trait multiple times
  429              if ty_trait_refs.iter().any(|other_trait| other_trait.def_id == trait_ref.def_id) {
  430                  // This means a trait inherited from the same supertrait more
  431                  // than once.
  432                  tcx.sess.span_err(sp, "duplicate supertrait in trait declaration");
  433                  break;
  434              } else {
  435                  ty_trait_refs.push(trait_ref);
  436              }
  437          }
  438      }
  439      if sized == ast::StaticSize {
  440          match tcx.lang_items.require(SizedTraitLangItem) {
  441              Ok(def_id) => { ty::try_add_builtin_trait(tcx, def_id, &mut bounds); },
  442              Err(s) => tcx.sess.err(s),
  443          };
  444      }
  445  
  446      tcx.supertraits.borrow_mut().insert(local_def(id), Rc::new(ty_trait_refs));
  447      bounds
  448  }
  449  
  450  pub fn convert_field(ccx: &CrateCtxt,
  451                       struct_generics: &ty::Generics,
  452                       v: &ast::StructField,
  453                       originast::DefId) -> ty::field_ty {
  454      let tt = ccx.to_ty(&ExplicitRscope, v.node.ty);
  455      write_ty_to_tcx(ccx.tcx, v.node.id, tt);
  456      /* add the field to the tcache */
  457      ccx.tcx.tcache.borrow_mut().insert(local_def(v.node.id),
  458                                         ty::ty_param_bounds_and_ty {
  459                                             generics: struct_generics.clone(),
  460                                             ty: tt
  461                                         });
  462  
  463      match v.node.kind {
  464          ast::NamedField(ident, visibility) => {
  465              ty::field_ty {
  466                  name: ident.name,
  467                  id: local_def(v.node.id),
  468                  vis: visibility,
  469                  origin: origin,
  470              }
  471          }
  472          ast::UnnamedField(visibility) => {
  473              ty::field_ty {
  474                  name: special_idents::unnamed_field.name,
  475                  id: local_def(v.node.id),
  476                  vis: visibility,
  477                  origin: origin,
  478              }
  479          }
  480      }
  481  }
  482  
  483  fn convert_methods(ccx: &CrateCtxt,
  484                     containerMethodContainer,
  485                     ms: &[@ast::Method],
  486                     untransformed_rcvr_tyty::t,
  487                     rcvr_ty_generics: &ty::Generics,
  488                     rcvr_ast_generics: &ast::Generics,
  489                     rcvr_visibilityast::Visibility)
  490  {
  491      let tcx = ccx.tcx;
  492      let mut seen_methods = HashSet::new();
  493      for m in ms.iter() {
  494          if !seen_methods.insert(m.ident.repr(ccx.tcx)) {
  495              tcx.sess.span_err(m.span, "duplicate method in trait impl");
  496          }
  497  
  498          let num_rcvr_ty_params = rcvr_ty_generics.type_param_defs().len();
  499          let m_ty_generics = ty_generics_for_fn_or_method(ccx, &m.generics,
  500                                                           num_rcvr_ty_params);
  501          let mty = Rc::new(ty_of_method(ccx,
  502                                         container,
  503                                         *m,
  504                                         untransformed_rcvr_ty,
  505                                         rcvr_ast_generics,
  506                                         rcvr_visibility));
  507          let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
  508          debug!("method {} (id {}) has type {}",
  509                  m.ident.repr(ccx.tcx),
  510                  m.id,
  511                  fty.repr(ccx.tcx));
  512          tcx.tcache.borrow_mut().insert(
  513              local_def(m.id),
  514  
  515              // n.b.: the type of a method is parameterized by both
  516              // the parameters on the receiver and those on the method
  517              // itself
  518              ty_param_bounds_and_ty {
  519                  generics: ty::Generics {
  520                      type_param_defs: Rc::new(Vec::from_slice(rcvr_ty_generics.type_param_defs())
  521                                               .append(m_ty_generics.type_param_defs())),
  522                      region_param_defs: Rc::new(Vec::from_slice(rcvr_ty_generics.region_param_defs())
  523                                                 .append(m_ty_generics.region_param_defs())),
  524                  },
  525                  ty: fty
  526              });
  527  
  528          write_ty_to_tcx(tcx, m.id, fty);
  529  
  530          tcx.methods.borrow_mut().insert(mty.def_id, mty);
  531      }
  532  
  533      fn ty_of_method(ccx: &CrateCtxt,
  534                      containerMethodContainer,
  535                      m: &ast::Method,
  536                      untransformed_rcvr_tyty::t,
  537                      rcvr_generics: &ast::Generics,
  538                      rcvr_visibilityast::Visibility) -> ty::Method
  539      {
  540          let fty = astconv::ty_of_method(ccx, m.id, m.fn_style,
  541                                          untransformed_rcvr_ty,
  542                                          m.explicit_self, m.decl);
  543  
  544          // if the method specifies a visibility, use that, otherwise
  545          // inherit the visibility from the impl (so `foo` in `pub impl
  546          // { fn foo(); }` is public, but private in `priv impl { fn
  547          // foo(); }`).
  548          let method_vis = m.vis.inherit_from(rcvr_visibility);
  549  
  550          let num_rcvr_type_params = rcvr_generics.ty_params.len();
  551          let m_ty_generics =
  552              ty_generics_for_fn_or_method(ccx, &m.generics, num_rcvr_type_params);
  553          ty::Method::new(
  554              m.ident,
  555              m_ty_generics,
  556              fty,
  557              m.explicit_self.node,
  558              method_vis,
  559              local_def(m.id),
  560              container,
  561              None
  562          )
  563      }
  564  }
  565  
  566  pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
  567                                   spanSpan,
  568                                   generics: &ast::Generics,
  569                                   thing: &'static str) {
  570      for ty_param in generics.ty_params.iter() {
  571          if ty_param.bounds.len() > 0 {
  572              ccx.tcx.sess.span_err(
  573                  span,
  574                  format!("trait bounds are not allowed in {} definitions", thing));
  575          }
  576      }
  577  }
  578  
  579  fn ensure_generics_abi(ccx: &CrateCtxt,
  580                         spanSpan,
  581                         abiabi::Abi,
  582                         generics: &ast::Generics) {
  583      if generics.ty_params.len() > 0 &&
  584         !(abi == abi::Rust || abi == abi::RustIntrinsic) {
  585          ccx.tcx.sess.span_err(span,
  586                                "foreign functions may not use type parameters");
  587      }
  588  }
  589  
  590  pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
  591      let tcx = ccx.tcx;
  592      debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id);
  593      match it.node {
  594          // These don't define types.
  595          ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {}
  596          ast::ItemEnum(ref enum_definition, ref generics) => {
  597              ensure_no_ty_param_bounds(ccx, it.span, generics, "enumeration");
  598              let tpt = ty_of_item(ccx, it);
  599              write_ty_to_tcx(tcx, it.id, tpt.ty);
  600              get_enum_variant_types(ccx,
  601                                     tpt.ty,
  602                                     enum_definition.variants.as_slice(),
  603                                     generics);
  604          },
  605          ast::ItemImpl(ref generics, ref opt_trait_ref, selfty, ref ms) => {
  606              let ty_generics = ty_generics_for_type(ccx, generics);
  607              let selfty = ccx.to_ty(&ExplicitRscope, selfty);
  608              write_ty_to_tcx(tcx, it.id, selfty);
  609  
  610              tcx.tcache.borrow_mut().insert(local_def(it.id),
  611                                  ty_param_bounds_and_ty {
  612                                      generics: ty_generics.clone(),
  613                                      ty: selfty});
  614  
  615              // If there is a trait reference, treat the methods as always public.
  616              // This is to work around some incorrect behavior in privacy checking:
  617              // when the method belongs to a trait, it should acquire the privacy
  618              // from the trait, not the impl. Forcing the visibility to be public
  619              // makes things sorta work.
  620              let parent_visibility = if opt_trait_ref.is_some() {
  621                  ast::Public
  622              } else {
  623                  it.vis
  624              };
  625  
  626              convert_methods(ccx,
  627                              ImplContainer(local_def(it.id)),
  628                              ms.as_slice(),
  629                              selfty,
  630                              &ty_generics,
  631                              generics,
  632                              parent_visibility);
  633  
  634              for trait_ref in opt_trait_ref.iter() {
  635                  instantiate_trait_ref(ccx, trait_ref, selfty);
  636              }
  637          },
  638          ast::ItemTrait(ref generics, _, _, ref trait_methods) => {
  639              let trait_def = trait_def_of_item(ccx, it);
  640  
  641              // Run convert_methods on the provided methods.
  642              let (_, provided_methods) =
  643                  split_trait_methods(trait_methods.as_slice());
  644              let untransformed_rcvr_ty = ty::mk_self(tcx, local_def(it.id));
  645              convert_methods(ccx,
  646                              TraitContainer(local_def(it.id)),
  647                              provided_methods.as_slice(),
  648                              untransformed_rcvr_ty,
  649                              &trait_def.generics,
  650                              generics,
  651                              it.vis);
  652  
  653              // We need to do this *after* converting methods, since
  654              // convert_methods produces a tcache entry that is wrong for
  655              // static trait methods. This is somewhat unfortunate.
  656              ensure_trait_methods(ccx, it.id);
  657          },
  658          ast::ItemStruct(struct_def, ref generics) => {
  659              ensure_no_ty_param_bounds(ccx, it.span, generics, "structure");
  660  
  661              // Write the class type.
  662              let tpt = ty_of_item(ccx, it);
  663              write_ty_to_tcx(tcx, it.id, tpt.ty);
  664  
  665              tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
  666  
  667              // Write the super-struct type, if it exists.
  668              match struct_def.super_struct {
  669                  Some(ty) => {
  670                      let supserty = ccx.to_ty(&ExplicitRscope, ty);
  671                      write_ty_to_tcx(tcx, it.id, supserty);
  672                  },
  673                  _ => {},
  674              }
  675  
  676              convert_struct(ccx, struct_def, tpt, it.id);
  677          },
  678          ast::ItemTy(_, ref generics) => {
  679              ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
  680              let tpt = ty_of_item(ccx, it);
  681              write_ty_to_tcx(tcx, it.id, tpt.ty);
  682          },
  683          ast::ItemFn(_, _, abi, ref generics, _) => {
  684              ensure_generics_abi(ccx, it.span, abi, generics);
  685              let tpt = ty_of_item(ccx, it);
  686              write_ty_to_tcx(tcx, it.id, tpt.ty);
  687          },
  688          _ => {
  689              // This call populates the type cache with the converted type
  690              // of the item in passing. All we have to do here is to write
  691              // it into the node type table.
  692              let tpt = ty_of_item(ccx, it);
  693              write_ty_to_tcx(tcx, it.id, tpt.ty);
  694          },
  695      }
  696  }
  697  
  698  pub fn convert_struct(ccx: &CrateCtxt,
  699                        struct_def: &ast::StructDef,
  700                        tptty::ty_param_bounds_and_ty,
  701                        idast::NodeId) {
  702      let tcx = ccx.tcx;
  703  
  704      // Write the type of each of the members and check for duplicate fields.
  705      let mut seen_fieldsHashMap<ast::Name, Span> = HashMap::new();
  706      let field_tys = struct_def.fields.iter().map(|f| {
  707          let result = convert_field(ccx, &tpt.generics, f, local_def(id));
  708  
  709          if result.name != special_idents::unnamed_field.name {
  710              let dup = match seen_fields.find(&result.name) {
  711                  Some(prev_span) => {
  712                      tcx.sess.span_err(f.span,
  713                          format!("field `{}` is already declared", token::get_name(result.name)));
  714                      tcx.sess.span_note(*prev_span,
  715                          "previously declared here");
  716                      true
  717                  },
  718                  None => false,
  719              };
  720              // FIXME(#6393) this whole dup thing is just to satisfy
  721              // the borrow checker :-(
  722              if !dup {
  723                  seen_fields.insert(result.name, f.span);
  724              }
  725          }
  726  
  727          result
  728      }).collect();
  729  
  730      tcx.struct_fields.borrow_mut().insert(local_def(id), Rc::new(field_tys));
  731  
  732      let super_struct = match struct_def.super_struct {
  733          Some(t) => match t.node {
  734              ast::TyPath(_, _, path_id) => {
  735                  let def_map = tcx.def_map.borrow();
  736                  match def_map.find(&path_id) {
  737                      Some(&ast::DefStruct(def_id)) => {
  738                          // FIXME(#12511) Check for cycles in the inheritance hierarchy.
  739                          // Check super-struct is virtual.
  740                          match tcx.map.find(def_id.node) {
  741                              Some(ast_map::NodeItem(i)) => match i.node {
  742                                  ast::ItemStruct(struct_def, _) => {
  743                                      if !struct_def.is_virtual {
  744                                          tcx.sess.span_err(t.span,
  745                                              "struct inheritance is only \
  746                                               allowed from virtual structs");
  747                                      }
  748                                  },
  749                                  _ => {},
  750                              },
  751                              _ => {},
  752                          }
  753  
  754                          Some(def_id)
  755                      },
  756                      _ => None,
  757                  }
  758              }
  759              _ => None,
  760          },
  761          None => None,
  762      };
  763      tcx.superstructs.borrow_mut().insert(local_def(id), super_struct);
  764  
  765      let substs = mk_item_substs(ccx, &tpt.generics, None);
  766      let selfty = ty::mk_struct(tcx, local_def(id), substs);
  767  
  768      // If this struct is enum-like or tuple-like, create the type of its
  769      // constructor.
  770      match struct_def.ctor_id {
  771          None => {}
  772          Some(ctor_id) => {
  773              if struct_def.fields.len() == 0 {
  774                  // Enum-like.
  775                  write_ty_to_tcx(tcx, ctor_id, selfty);
  776  
  777                  tcx.tcache.borrow_mut().insert(local_def(ctor_id), tpt);
  778              } else if struct_def.fields.get(0).node.kind.is_unnamed() {
  779                  // Tuple-like.
  780                  let inputsVec<_> = struct_def.fields.iter().map(
  781                          |field| tcx.tcache.borrow().get(
  782                              &local_def(field.node.id)).ty).collect();
  783                  let ctor_fn_ty = ty::mk_ctor_fn(tcx,
  784                                                  ctor_id,
  785                                                  inputs.as_slice(),
  786                                                  selfty);
  787                  write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty);
  788                  tcx.tcache.borrow_mut().insert(local_def(ctor_id),
  789                                    ty_param_bounds_and_ty {
  790                      generics: tpt.generics,
  791                      ty: ctor_fn_ty
  792                  });
  793              }
  794          }
  795      }
  796  }
  797  
  798  pub fn convert_foreign(ccx: &CrateCtxt, i: &ast::ForeignItem) {
  799      // As above, this call populates the type table with the converted
  800      // type of the foreign item. We simply write it into the node type
  801      // table.
  802  
  803      // For reasons I cannot fully articulate, I do so hate the AST
  804      // map, and I regard each time that I use it as a personal and
  805      // moral failing, but at the moment it seems like the only
  806      // convenient way to extract the ABI. - ndm
  807      let abi = ccx.tcx.map.get_foreign_abi(i.id);
  808  
  809      let tpt = ty_of_foreign_item(ccx, i, abi);
  810      write_ty_to_tcx(ccx.tcx, i.id, tpt.ty);
  811  
  812      ccx.tcx.tcache.borrow_mut().insert(local_def(i.id), tpt);
  813  }
  814  
  815  pub fn instantiate_trait_ref(ccx: &CrateCtxt,
  816                               ast_trait_ref: &ast::TraitRef,
  817                               self_tyty::t) -> Rc<ty::TraitRef> {
  818      /*!
  819       * Instantiates the path for the given trait reference, assuming that
  820       * it's bound to a valid trait type. Returns the def_id for the defining
  821       * trait. Fails if the type is a type other than a trait type.
  822       */
  823  
  824      // FIXME(#5121) -- distinguish early vs late lifetime params
  825      let rscope = ExplicitRscope;
  826  
  827      match lookup_def_tcx(ccx.tcx, ast_trait_ref.path.span, ast_trait_ref.ref_id) {
  828          ast::DefTrait(trait_did) => {
  829              let trait_ref =
  830                  astconv::ast_path_to_trait_ref(
  831                      ccx, &rscope, trait_did, Some(self_ty), &ast_trait_ref.path);
  832  
  833              ccx.tcx.trait_refs.borrow_mut().insert(ast_trait_ref.ref_id,
  834                                                     trait_ref.clone());
  835              trait_ref
  836          }
  837          _ => {
  838              ccx.tcx.sess.span_fatal(
  839                  ast_trait_ref.path.span,
  840                  format!("`{}` is not a trait",
  841                      path_to_str(&ast_trait_ref.path)));
  842          }
  843      }
  844  }
  845  
  846  fn get_trait_def(ccx: &CrateCtxt, trait_idast::DefId) -> Rc<ty::TraitDef> {
  847      if trait_id.krate != ast::LOCAL_CRATE {
  848          return ty::lookup_trait_def(ccx.tcx, trait_id)
  849      }
  850  
  851      match ccx.tcx.map.get(trait_id.node) {
  852          ast_map::NodeItem(item) => trait_def_of_item(ccx, item),
  853          _ => ccx.tcx.sess.bug(format!("get_trait_def({}): not an item",
  854                                     trait_id.node))
  855      }
  856  }
  857  
  858  pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
  859      let def_id = local_def(it.id);
  860      let tcx = ccx.tcx;
  861      match tcx.trait_defs.borrow().find(&def_id) {
  862          Some(def) => return def.clone(),
  863          _ => {}
  864      }
  865  
  866      match it.node {
  867          ast::ItemTrait(ref generics, sized, ref supertraits, _) => {
  868              let self_ty = ty::mk_self(tcx, def_id);
  869              let ty_generics = ty_generics_for_type(ccx, generics);
  870              let substs = mk_item_substs(ccx, &ty_generics, Some(self_ty));
  871              let bounds = ensure_supertraits(ccx,
  872                                              it.id,
  873                                              it.span,
  874                                              supertraits.as_slice(),
  875                                              sized);
  876              let trait_def = Rc::new(ty::TraitDef {
  877                  generics: ty_generics,
  878                  bounds: bounds,
  879                  trait_ref: Rc::new(ty::TraitRef {
  880                      def_id: def_id,
  881                      substs: substs
  882                  })
  883              });
  884              tcx.trait_defs.borrow_mut().insert(def_id, trait_def.clone());
  885              trait_def
  886          }
  887          ref s => {
  888              tcx.sess.span_bug(
  889                  it.span,
  890                  format!("trait_def_of_item invoked on {:?}", s));
  891          }
  892      }
  893  }
  894  
  895  pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
  896                    -> ty::ty_param_bounds_and_ty {
  897      let def_id = local_def(it.id);
  898      let tcx = ccx.tcx;
  899      match tcx.tcache.borrow().find(&def_id) {
  900          Some(tpt) => return tpt.clone(),
  901          _ => {}
  902      }
  903      match it.node {
  904          ast::ItemStatic(t, _, _) => {
  905              let typ = ccx.to_ty(&ExplicitRscope, t);
  906              let tpt = no_params(typ);
  907  
  908              tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
  909              return tpt;
  910          }
  911          ast::ItemFn(decl, fn_style, abi, ref generics, _) => {
  912              let ty_generics = ty_generics_for_fn_or_method(ccx, generics, 0);
  913              let tofd = astconv::ty_of_bare_fn(ccx,
  914                                                it.id,
  915                                                fn_style,
  916                                                abi,
  917                                                decl);
  918              let tpt = ty_param_bounds_and_ty {
  919                  generics: ty_generics,
  920                  ty: ty::mk_bare_fn(ccx.tcx, tofd)
  921              };
  922              debug!("type of {} (id {}) is {}",
  923                      token::get_ident(it.ident),
  924                      it.id,
  925                      ppaux::ty_to_str(tcx, tpt.ty));
  926  
  927              ccx.tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
  928              return tpt;
  929          }
  930          ast::ItemTy(t, ref generics) => {
  931              match tcx.tcache.borrow_mut().find(&local_def(it.id)) {
  932                  Some(tpt) => return tpt.clone(),
  933                  None => { }
  934              }
  935  
  936              let tpt = {
  937                  let ty = ccx.to_ty(&ExplicitRscope, t);
  938                  ty_param_bounds_and_ty {
  939                      generics: ty_generics_for_type(ccx, generics),
  940                      ty: ty
  941                  }
  942              };
  943  
  944              tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
  945              return tpt;
  946          }
  947          ast::ItemEnum(_, ref generics) => {
  948              // Create a new generic polytype.
  949              let ty_generics = ty_generics_for_type(ccx, generics);
  950              let substs = mk_item_substs(ccx, &ty_generics, None);
  951              let t = ty::mk_enum(tcx, local_def(it.id), substs);
  952              let tpt = ty_param_bounds_and_ty {
  953                  generics: ty_generics,
  954                  ty: t
  955              };
  956  
  957              tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
  958              return tpt;
  959          }
  960          ast::ItemTrait(..) => {
  961              tcx.sess.span_bug(
  962                  it.span,
  963                  format!("invoked ty_of_item on trait"));
  964          }
  965          ast::ItemStruct(_, ref generics) => {
  966              let ty_generics = ty_generics_for_type(ccx, generics);
  967              let substs = mk_item_substs(ccx, &ty_generics, None);
  968              let t = ty::mk_struct(tcx, local_def(it.id), substs);
  969              let tpt = ty_param_bounds_and_ty {
  970                  generics: ty_generics,
  971                  ty: t
  972              };
  973  
  974              tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
  975              return tpt;
  976          }
  977          ast::ItemImpl(..) | ast::ItemMod(_) |
  978          ast::ItemForeignMod(_) | ast::ItemMac(_) => fail!(),
  979      }
  980  }
  981  
  982  pub fn ty_of_foreign_item(ccx: &CrateCtxt,
  983                            it: &ast::ForeignItem,
  984                            abiabi::Abi) -> ty::ty_param_bounds_and_ty
  985  {
  986      match it.node {
  987          ast::ForeignItemFn(fn_decl, ref generics) => {
  988              ty_of_foreign_fn_decl(ccx,
  989                                    fn_decl,
  990                                    local_def(it.id),
  991                                    generics,
  992                                    abi)
  993          }
  994          ast::ForeignItemStatic(t, _) => {
  995              ty::ty_param_bounds_and_ty {
  996                  generics: ty::Generics {
  997                      type_param_defs: Rc::new(Vec::new()),
  998                      region_param_defs: Rc::new(Vec::new()),
  999                  },
 1000                  ty: ast_ty_to_ty(ccx, &ExplicitRscope, t)
 1001              }
 1002          }
 1003      }
 1004  }
 1005  
 1006  fn ty_generics_for_type(ccx: &CrateCtxt,
 1007                          generics: &ast::Generics)
 1008                          -> ty::Generics {
 1009      ty_generics(ccx, &generics.lifetimes, &generics.ty_params, 0)
 1010  }
 1011  
 1012  fn ty_generics_for_fn_or_method(ccx: &CrateCtxt,
 1013                                  generics: &ast::Generics,
 1014                                  base_index: uint)
 1015                                  -> ty::Generics {
 1016      let early_lifetimes = resolve_lifetime::early_bound_lifetimes(generics);
 1017      ty_generics(ccx, &early_lifetimes, &generics.ty_params, base_index)
 1018  }
 1019  
 1020  fn ty_generics(ccx: &CrateCtxt,
 1021                 lifetimes: &Vec<ast::Lifetime>,
 1022                 ty_params: &OwnedSlice<ast::TyParam>,
 1023                 base_index: uint) -> ty::Generics {
 1024      return ty::Generics {
 1025          region_param_defs: Rc::new(lifetimes.iter().map(|l| {
 1026                  ty::RegionParameterDef { name: l.name,
 1027                                           def_id: local_def(l.id) }
 1028              }).collect()),
 1029          type_param_defs: Rc::new(ty_params.iter().enumerate().map(|(offset, param)| {
 1030              let existing_def_opt = {
 1031                  let ty_param_defs = ccx.tcx.ty_param_defs.borrow();
 1032                  ty_param_defs.find(&param.id).map(|def| def.clone())
 1033              };
 1034              existing_def_opt.unwrap_or_else(|| {
 1035                  let param_ty = ty::param_ty {idx: base_index + offset,
 1036                                               def_id: local_def(param.id)};
 1037                  let bounds = Rc::new(compute_bounds(ccx,
 1038                                                      param_ty,
 1039                                                      &param.bounds,
 1040                                                      param.sized,
 1041                                                      param.ident,
 1042                                                      param.span));
 1043                  let default = param.default.map(|path| {
 1044                      let ty = ast_ty_to_ty(ccx, &ExplicitRscope, path);
 1045                      let cur_idx = param_ty.idx;
 1046  
 1047                      ty::walk_ty(ty, |t| {
 1048                          match ty::get(t).sty {
 1049                              ty::ty_param(p) => if p.idx > cur_idx {
 1050                                  ccx.tcx.sess.span_err(path.span,
 1051                                                          "type parameters with a default cannot use \
 1052                                                          forward declared identifiers")
 1053                              },
 1054                              _ => {}
 1055                          }
 1056                      });
 1057  
 1058                      ty
 1059                  });
 1060  
 1061                  let def = ty::TypeParameterDef {
 1062                      ident: param.ident,
 1063                      def_id: local_def(param.id),
 1064                      bounds: bounds,
 1065                      default: default
 1066                  };
 1067                  debug!("def for param: {}", def.repr(ccx.tcx));
 1068                  ccx.tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
 1069                  def
 1070              })
 1071          }).collect()),
 1072      };
 1073  
 1074      fn compute_bounds(
 1075          ccx&CrateCtxt,
 1076          param_tyty::param_ty,
 1077          ast_bounds&OwnedSlice<ast::TyParamBound>,
 1078          sizedast::Sized,
 1079          identast::Ident,
 1080          spanSpan) -> ty::ParamBounds
 1081      {
 1082          /*!
 1083           * Translate the AST's notion of ty param bounds (which are an
 1084           * enum consisting of a newtyped Ty or a region) to ty's
 1085           * notion of ty param bounds, which can either be user-defined
 1086           * traits, or the built-in trait (formerly known as kind): Send.
 1087           */
 1088  
 1089          let mut param_bounds = ty::ParamBounds {
 1090              builtin_bounds: ty::EmptyBuiltinBounds(),
 1091              trait_bounds: Vec::new()
 1092          };
 1093          for ast_bound in ast_bounds.iter() {
 1094              match *ast_bound {
 1095                  TraitTyParamBound(ref b) => {
 1096                      let ty = ty::mk_param(ccx.tcx, param_ty.idx, param_ty.def_id);
 1097                      let trait_ref = instantiate_trait_ref(ccx, b, ty);
 1098                      if !ty::try_add_builtin_trait(
 1099                              ccx.tcx, trait_ref.def_id,
 1100                              &mut param_bounds.builtin_bounds) {
 1101                          // Must be a user-defined trait
 1102                          param_bounds.trait_bounds.push(trait_ref);
 1103                      }
 1104                  }
 1105  
 1106                  StaticRegionTyParamBound => {
 1107                      param_bounds.builtin_bounds.add(ty::BoundStatic);
 1108                  }
 1109  
 1110                  OtherRegionTyParamBound(span) => {
 1111                      if !ccx.tcx.sess.features.issue_5723_bootstrap.get() {
 1112                          ccx.tcx.sess.span_err(
 1113                              span,
 1114                              format!("only the 'static lifetime is \
 1115                                       accepted here."));
 1116                      }
 1117                  }
 1118              }
 1119          }
 1120  
 1121          if sized == ast::StaticSize {
 1122              match ccx.tcx.lang_items.require(SizedTraitLangItem) {
 1123                  Ok(def_id) => { ty::try_add_builtin_trait(ccx.tcx,
 1124                                                            def_id,
 1125                                                            &mut param_bounds.builtin_bounds); },
 1126                  // Fixme(13367) after `type` makes it into the snapshot, we can check this properly
 1127                  Err(_s) => {}, //ccx.tcx.sess.err(s),
 1128              }
 1129          }
 1130  
 1131          check_bounds_compatible(ccx.tcx, &param_bounds, ident, span);
 1132  
 1133          param_bounds
 1134      }
 1135  
 1136      fn check_bounds_compatible(tcx&ty::ctxt,
 1137                                 param_bounds&ty::ParamBounds,
 1138                                 identast::Ident,
 1139                                 spanSpan) {
 1140          // Currently the only bound which is incompatible with other bounds is
 1141          // Sized/Unsized.
 1142          if !param_bounds.builtin_bounds.contains_elem(ty::BoundSized) {
 1143              ty::each_bound_trait_and_supertraits(tcx,
 1144                                                   param_bounds.trait_bounds.as_slice(),
 1145                                                   |trait_ref| {
 1146                  let trait_def = ty::lookup_trait_def(tcx, trait_ref.def_id);
 1147                  if trait_def.bounds.contains_elem(ty::BoundSized) {
 1148                      tcx.sess.span_err(span,
 1149                          format!("incompatible bounds on type parameter {}, \
 1150                                   bound {} does not allow unsized type",
 1151                          token::get_ident(ident),
 1152                          ppaux::trait_ref_to_str(tcx, &*trait_ref)));
 1153                  }
 1154                  true
 1155              });
 1156          }
 1157      }
 1158  }
 1159  
 1160  pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
 1161                               decl: &ast::FnDecl,
 1162                               def_idast::DefId,
 1163                               ast_generics: &ast::Generics,
 1164                               abiabi::Abi)
 1165                            -> ty::ty_param_bounds_and_ty {
 1166  
 1167      for i in decl.inputs.iter() {
 1168          match (*i).pat.node {
 1169              ast::PatIdent(_, _, _) => (),
 1170              ast::PatWild => (),
 1171              _ => ccx.tcx.sess.span_err((*i).pat.span,
 1172                      "patterns aren't allowed in foreign function declarations")
 1173          }
 1174      }
 1175  
 1176      let ty_generics_for_fn_or_method =
 1177          ty_generics_for_fn_or_method(ccx, ast_generics, 0);
 1178      let rb = BindingRscope::new(def_id.node);
 1179      let input_tys = decl.inputs
 1180                          .iter()
 1181                          .map(|a| ty_of_arg(ccx, &rb, a, None))
 1182                          .collect();
 1183  
 1184      let output_ty = ast_ty_to_ty(ccx, &rb, decl.output);
 1185  
 1186      let t_fn = ty::mk_bare_fn(
 1187          ccx.tcx,
 1188          ty::BareFnTy {
 1189              abi: abi,
 1190              fn_style: ast::UnsafeFn,
 1191              sig: ty::FnSig {binder_id: def_id.node,
 1192                              inputs: input_tys,
 1193                              output: output_ty,
 1194                              variadic: decl.variadic}
 1195          });
 1196      let tpt = ty_param_bounds_and_ty {
 1197          generics: ty_generics_for_fn_or_method,
 1198          ty: t_fn
 1199      };
 1200  
 1201      ccx.tcx.tcache.borrow_mut().insert(def_id, tpt.clone());
 1202      return tpt;
 1203  }
 1204  
 1205  pub fn mk_item_substs(ccx: &CrateCtxt,
 1206                        ty_generics: &ty::Generics,
 1207                        self_tyOption<ty::t>) -> ty::substs
 1208  {
 1209      let paramsVec<ty::t> =
 1210          ty_generics.type_param_defs().iter().enumerate().map(
 1211              |(i, t)| ty::mk_param(ccx.tcx, i, t.def_id)).collect();
 1212  
 1213      let regionsOwnedSlice<ty::Region> =
 1214          ty_generics.region_param_defs().iter().enumerate().map(
 1215              |(i, l)| ty::ReEarlyBound(l.def_id.node, i, l.name)).collect();
 1216  
 1217      substs {regions: ty::NonerasedRegions(regions),
 1218              self_ty: self_ty,
 1219              tps: params}
 1220  }


librustc/middle/typeck/collect.rs:697:1-697:1 -fn- definition:
pub fn convert_struct(ccx: &CrateCtxt,
                      struct_def: &ast::StructDef,
                      tpt: ty::ty_param_bounds_and_ty,
references:- 2
170:                 convert_struct(ccx, struct_def, tpt, variant.node.id);
--
676:             convert_struct(ccx, struct_def, tpt, it.id);
677:         },


librustc/middle/typeck/collect.rs:482:1-482:1 -fn- definition:
fn convert_methods(ccx: &CrateCtxt,
                   container: MethodContainer,
                   ms: &[@ast::Method],
references:- 2
626:             convert_methods(ccx,
627:                             ImplContainer(local_def(it.id)),
--
644:             let untransformed_rcvr_ty = ty::mk_self(tcx, local_def(it.id));
645:             convert_methods(ccx,
646:                             TraitContainer(local_def(it.id)),


librustc/middle/typeck/collect.rs:894:1-894:1 -fn- definition:
pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
                  -> ty::ty_param_bounds_and_ty {
    let def_id = local_def(it.id);
references:- 6
118:         match self.tcx.map.find(id.node) {
119:             Some(ast_map::NodeItem(item)) => ty_of_item(self, item),
120:             Some(ast_map::NodeForeignItem(foreign_item)) => {
--
597:             ensure_no_ty_param_bounds(ccx, it.span, generics, "enumeration");
598:             let tpt = ty_of_item(ccx, it);
599:             write_ty_to_tcx(tcx, it.id, tpt.ty);
--
679:             ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
680:             let tpt = ty_of_item(ccx, it);
681:             write_ty_to_tcx(tcx, it.id, tpt.ty);
--
691:             // it into the node type table.
692:             let tpt = ty_of_item(ccx, it);
693:             write_ty_to_tcx(tcx, it.id, tpt.ty);


librustc/middle/typeck/collect.rs:857:1-857:1 -fn- definition:
pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
    let def_id = local_def(it.id);
    let tcx = ccx.tcx;
references:- 2
638:         ast::ItemTrait(ref generics, _, _, ref trait_methods) => {
639:             let trait_def = trait_def_of_item(ccx, it);
--
851:     match ccx.tcx.map.get(trait_id.node) {
852:         ast_map::NodeItem(item) => trait_def_of_item(ccx, item),
853:         _ => ccx.tcx.sess.bug(format!("get_trait_def({}): not an item",


librustc/middle/typeck/collect.rs:82:4-82:4 -fn- definition:
    fn collect_intrinsic_type(ccx: &CrateCtxt,
                              lang_item: ast::DefId) {
        let ty::ty_param_bounds_and_ty { ty: ty, .. } =
references:- 2
89:     match ccx.tcx.lang_items.ty_desc() {
90:         Some(id) => { collect_intrinsic_type(ccx, id); } None => {}
91:     }
92:     match ccx.tcx.lang_items.opaque() {
93:         Some(id) => { collect_intrinsic_type(ccx, id); } None => {}
94:     }


librustc/middle/typeck/collect.rs:1005:1-1005:1 -fn- definition:
fn ty_generics_for_type(ccx: &CrateCtxt,
                        generics: &ast::Generics)
                        -> ty::Generics {
references:- 8
868:             let self_ty = ty::mk_self(tcx, def_id);
869:             let ty_generics = ty_generics_for_type(ccx, generics);
870:             let substs = mk_item_substs(ccx, &ty_generics, Some(self_ty));
--
948:             // Create a new generic polytype.
949:             let ty_generics = ty_generics_for_type(ccx, generics);
950:             let substs = mk_item_substs(ccx, &ty_generics, None);
--
965:         ast::ItemStruct(_, ref generics) => {
966:             let ty_generics = ty_generics_for_type(ccx, generics);
967:             let substs = mk_item_substs(ccx, &ty_generics, None);


librustc/middle/typeck/collect.rs:981:1-981:1 -fn- definition:
pub fn ty_of_foreign_item(ccx: &CrateCtxt,
                          it: &ast::ForeignItem,
                          abi: abi::Abi) -> ty::ty_param_bounds_and_ty
references:- 2
121:                 let abi = self.tcx.map.get_foreign_abi(id.node);
122:                 ty_of_foreign_item(self, foreign_item, abi)
123:             }
--
809:     let tpt = ty_of_foreign_item(ccx, i, abi);
810:     write_ty_to_tcx(ccx.tcx, i.id, tpt.ty);


librustc/middle/typeck/collect.rs:814:1-814:1 -fn- definition:
pub fn instantiate_trait_ref(ccx: &CrateCtxt,
                             ast_trait_ref: &ast::TraitRef,
                             self_ty: ty::t) -> Rc<ty::TraitRef> {
references:- 3
424:         // map. This is only needed for metadata; see the similar fixme in encoder.rs.
425:         let trait_ref = instantiate_trait_ref(ccx, ast_trait_ref, self_ty);
426:         if !ty::try_add_builtin_trait(ccx.tcx, trait_def_id, &mut bounds) {
--
1096:                     let ty = ty::mk_param(ccx.tcx, param_ty.idx, param_ty.def_id);
1097:                     let trait_ref = instantiate_trait_ref(ccx, b, ty);
1098:                     if !ty::try_add_builtin_trait(


librustc/middle/typeck/collect.rs:1011:1-1011:1 -fn- definition:
fn ty_generics_for_fn_or_method(ccx: &CrateCtxt,
                                generics: &ast::Generics,
                                base_index: uint)
references:- 5
498:         let num_rcvr_ty_params = rcvr_ty_generics.type_param_defs().len();
499:         let m_ty_generics = ty_generics_for_fn_or_method(ccx, &m.generics,
500:                                                          num_rcvr_ty_params);
--
1176:     let ty_generics_for_fn_or_method =
1177:         ty_generics_for_fn_or_method(ccx, ast_generics, 0);
1178:     let rb = BindingRscope::new(def_id.node);


librustc/middle/typeck/collect.rs:65:1-65:1 -struct- definition:
struct CollectItemTypesVisitor<'a> {
    ccx: &'a CrateCtxt<'a>
}
references:- 2
70: impl<'a> visit::Visitor<()> for CollectItemTypesVisitor<'a> {
71:     fn visit_item(&mut self, i: &ast::Item, _: ()) {
--
96:     let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
97:     visit::walk_crate(&mut visitor, krate, ());


librustc/middle/typeck/collect.rs:374:4-374:4 -fn- definition:
    fn ty_method_of_trait_method(this: &CrateCtxt,
                                 trait_id: ast::NodeId,
                                 trait_generics: &ty::Generics,
references:- 2
208:                             &ast::Provided(ref m) => {
209:                                 ty_method_of_trait_method(
210:                                     ccx, trait_id, &trait_ty_generics,


librustc/middle/typeck/collect.rs:845:1-845:1 -fn- definition:
fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> Rc<ty::TraitDef> {
    if trait_id.krate != ast::LOCAL_CRATE {
        return ty::lookup_trait_def(ccx.tcx, trait_id)
references:- 2
131:     fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef> {
132:         get_trait_def(self, id)
133:     }
--
341:         // add in the "self" type parameter
342:         let self_trait_def = get_trait_def(ccx, local_def(trait_id));
343:         let self_trait_ref = self_trait_def.trait_ref.subst(tcx, &substs);


librustc/middle/typeck/collect.rs:1204:1-1204:1 -fn- definition:
pub fn mk_item_substs(ccx: &CrateCtxt,
                      ty_generics: &ty::Generics,
                      self_ty: Option<ty::t>) -> ty::substs
references:- 4
966:             let ty_generics = ty_generics_for_type(ccx, generics);
967:             let substs = mk_item_substs(ccx, &ty_generics, None);
968:             let t = ty::mk_struct(tcx, local_def(it.id), substs);


librustc/middle/typeck/collect.rs:1019:1-1019:1 -fn- definition:
fn ty_generics(ccx: &CrateCtxt,
               lifetimes: &Vec<ast::Lifetime>,
               ty_params: &OwnedSlice<ast::TyParam>,
references:- 2
1008:                         -> ty::Generics {
1009:     ty_generics(ccx, &generics.lifetimes, &generics.ty_params, 0)
1010: }
--
1016:     let early_lifetimes = resolve_lifetime::early_bound_lifetimes(generics);
1017:     ty_generics(ccx, &early_lifetimes, &generics.ty_params, base_index)
1018: }


librustc/middle/typeck/collect.rs:565:1-565:1 -fn- definition:
pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
                                 span: Span,
                                 generics: &ast::Generics,
references:- 3
678:         ast::ItemTy(_, ref generics) => {
679:             ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
680:             let tpt = ty_of_item(ccx, it);