]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/collect.rs
Auto merge of #28717 - nagisa:optional-no-landing-pads, r=alexcrichton
[rust.git] / src / librustc_typeck / collect.rs
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 type schemes. This means that they are
24 generic types that may have type parameters. TypeSchemes are
25 represented by an instance of `ty::TypeScheme`.  This combines the
26 core type along with a list of the bounds for each parameter. Type
27 parameters themselves are represented as `ty_param()` instances.
28
29 The phasing of type conversion is somewhat complicated. There is no
30 clear set of phases we can enforce (e.g., converting traits first,
31 then types, or something like that) because the user can introduce
32 arbitrary interdependencies. So instead we generally convert things
33 lazilly and on demand, and include logic that checks for cycles.
34 Demand is driven by calls to `AstConv::get_item_type_scheme` or
35 `AstConv::lookup_trait_def`.
36
37 Currently, we "convert" types and traits in three phases (note that
38 conversion only affects the types of items / enum variants / methods;
39 it does not e.g. compute the types of individual expressions):
40
41 0. Intrinsics
42 1. Trait definitions
43 2. Type definitions
44
45 Conversion itself is done by simply walking each of the items in turn
46 and invoking an appropriate function (e.g., `trait_def_of_item` or
47 `convert_item`). However, it is possible that while converting an
48 item, we may need to compute the *type scheme* or *trait definition*
49 for other items.
50
51 There are some shortcomings in this design:
52
53 - Before walking the set of supertraits for a given trait, you must
54   call `ensure_super_predicates` on that trait def-id. Otherwise,
55   `lookup_super_predicates` will result in ICEs.
56 - Because the type scheme includes defaults, cycles through type
57   parameter defaults are illegal even if those defaults are never
58   employed. This is not necessarily a bug.
59 - The phasing of trait definitions before type definitions does not
60   seem to be necessary, sufficient, or particularly helpful, given that
61   processing a trait definition can trigger processing a type def and
62   vice versa. However, if I remove it, I get ICEs, so some more work is
63   needed in that area. -nmatsakis
64
65 */
66
67 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
68 use middle::def;
69 use middle::def_id::DefId;
70 use constrained_type_params as ctp;
71 use middle::lang_items::SizedTraitLangItem;
72 use middle::free_region::FreeRegionMap;
73 use middle::region;
74 use middle::resolve_lifetime;
75 use middle::const_eval::{self, ConstVal};
76 use middle::const_eval::EvalHint::UncheckedExprHint;
77 use middle::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
78 use middle::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
79 use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty, TypeScheme};
80 use middle::ty::{VariantKind};
81 use middle::ty::fold::{TypeFolder, TypeFoldable};
82 use middle::ty::util::IntTypeExt;
83 use middle::infer;
84 use rscope::*;
85 use rustc::front::map as hir_map;
86 use util::common::{ErrorReported, memoized};
87 use util::nodemap::{FnvHashMap, FnvHashSet};
88 use write_ty_to_tcx;
89
90 use std::cell::{Cell, RefCell};
91 use std::collections::HashSet;
92 use std::rc::Rc;
93
94 use syntax::abi;
95 use syntax::ast;
96 use syntax::attr;
97 use syntax::codemap::Span;
98 use syntax::parse::token::special_idents;
99 use syntax::ptr::P;
100 use rustc_front::hir;
101 use rustc_front::visit;
102 use rustc_front::print::pprust;
103
104 ///////////////////////////////////////////////////////////////////////////
105 // Main entry point
106
107 pub fn collect_item_types(tcx: &ty::ctxt) {
108     let ccx = &CrateCtxt { tcx: tcx, stack: RefCell::new(Vec::new()) };
109
110     let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
111     visit::walk_crate(&mut visitor, ccx.tcx.map.krate());
112
113     let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
114     visit::walk_crate(&mut visitor, ccx.tcx.map.krate());
115 }
116
117 ///////////////////////////////////////////////////////////////////////////
118
119 struct CrateCtxt<'a,'tcx:'a> {
120     tcx: &'a ty::ctxt<'tcx>,
121
122     // This stack is used to identify cycles in the user's source.
123     // Note that these cycles can cross multiple items.
124     stack: RefCell<Vec<AstConvRequest>>,
125 }
126
127 /// Context specific to some particular item. This is what implements
128 /// AstConv. It has information about the predicates that are defined
129 /// on the trait. Unfortunately, this predicate information is
130 /// available in various different forms at various points in the
131 /// process. So we can't just store a pointer to e.g. the AST or the
132 /// parsed ty form, we have to be more flexible. To this end, the
133 /// `ItemCtxt` is parameterized by a `GetTypeParameterBounds` object
134 /// that it uses to satisfy `get_type_parameter_bounds` requests.
135 /// This object might draw the information from the AST
136 /// (`hir::Generics`) or it might draw from a `ty::GenericPredicates`
137 /// or both (a tuple).
138 struct ItemCtxt<'a,'tcx:'a> {
139     ccx: &'a CrateCtxt<'a,'tcx>,
140     param_bounds: &'a (GetTypeParameterBounds<'tcx>+'a),
141 }
142
143 #[derive(Copy, Clone, PartialEq, Eq)]
144 enum AstConvRequest {
145     GetItemTypeScheme(DefId),
146     GetTraitDef(DefId),
147     EnsureSuperPredicates(DefId),
148     GetTypeParameterBounds(ast::NodeId),
149 }
150
151 ///////////////////////////////////////////////////////////////////////////
152 // First phase: just collect *trait definitions* -- basically, the set
153 // of type parameters and supertraits. This is information we need to
154 // know later when parsing field defs.
155
156 struct CollectTraitDefVisitor<'a, 'tcx: 'a> {
157     ccx: &'a CrateCtxt<'a, 'tcx>
158 }
159
160 impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> {
161     fn visit_item(&mut self, i: &hir::Item) {
162         match i.node {
163             hir::ItemTrait(..) => {
164                 // computing the trait def also fills in the table
165                 let _ = trait_def_of_item(self.ccx, i);
166             }
167             _ => { }
168         }
169
170         visit::walk_item(self, i);
171     }
172 }
173
174 ///////////////////////////////////////////////////////////////////////////
175 // Second phase: collection proper.
176
177 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
178     ccx: &'a CrateCtxt<'a, 'tcx>
179 }
180
181 impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
182     fn visit_item(&mut self, i: &hir::Item) {
183         convert_item(self.ccx, i);
184         visit::walk_item(self, i);
185     }
186     fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
187         convert_foreign_item(self.ccx, i);
188         visit::walk_foreign_item(self, i);
189     }
190 }
191
192 ///////////////////////////////////////////////////////////////////////////
193 // Utility types and common code for the above passes.
194
195 impl<'a,'tcx> CrateCtxt<'a,'tcx> {
196     fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> {
197         ItemCtxt { ccx: self, param_bounds: param_bounds }
198     }
199
200     fn method_ty(&self, method_id: ast::NodeId) -> Rc<ty::Method<'tcx>> {
201         let def_id = self.tcx.map.local_def_id(method_id);
202         match *self.tcx.impl_or_trait_items.borrow().get(&def_id).unwrap() {
203             ty::MethodTraitItem(ref mty) => mty.clone(),
204             _ => {
205                 self.tcx.sess.bug(&format!("method with id {} has the wrong type", method_id));
206             }
207         }
208     }
209
210     fn cycle_check<F,R>(&self,
211                         span: Span,
212                         request: AstConvRequest,
213                         code: F)
214                         -> Result<R,ErrorReported>
215         where F: FnOnce() -> Result<R,ErrorReported>
216     {
217         {
218             let mut stack = self.stack.borrow_mut();
219             match stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
220                 None => { }
221                 Some((i, _)) => {
222                     let cycle = &stack[i..];
223                     self.report_cycle(span, cycle);
224                     return Err(ErrorReported);
225                 }
226             }
227             stack.push(request);
228         }
229
230         let result = code();
231
232         self.stack.borrow_mut().pop();
233         result
234     }
235
236     fn report_cycle(&self,
237                     span: Span,
238                     cycle: &[AstConvRequest])
239     {
240         assert!(!cycle.is_empty());
241         let tcx = self.tcx;
242
243         span_err!(tcx.sess, span, E0391,
244             "unsupported cyclic reference between types/traits detected");
245
246         match cycle[0] {
247             AstConvRequest::GetItemTypeScheme(def_id) |
248             AstConvRequest::GetTraitDef(def_id) => {
249                 tcx.sess.note(
250                     &format!("the cycle begins when processing `{}`...",
251                              tcx.item_path_str(def_id)));
252             }
253             AstConvRequest::EnsureSuperPredicates(def_id) => {
254                 tcx.sess.note(
255                     &format!("the cycle begins when computing the supertraits of `{}`...",
256                              tcx.item_path_str(def_id)));
257             }
258             AstConvRequest::GetTypeParameterBounds(id) => {
259                 let def = tcx.type_parameter_def(id);
260                 tcx.sess.note(
261                     &format!("the cycle begins when computing the bounds \
262                               for type parameter `{}`...",
263                              def.name));
264             }
265         }
266
267         for request in &cycle[1..] {
268             match *request {
269                 AstConvRequest::GetItemTypeScheme(def_id) |
270                 AstConvRequest::GetTraitDef(def_id) => {
271                     tcx.sess.note(
272                         &format!("...which then requires processing `{}`...",
273                                  tcx.item_path_str(def_id)));
274                 }
275                 AstConvRequest::EnsureSuperPredicates(def_id) => {
276                     tcx.sess.note(
277                         &format!("...which then requires computing the supertraits of `{}`...",
278                                  tcx.item_path_str(def_id)));
279                 }
280                 AstConvRequest::GetTypeParameterBounds(id) => {
281                     let def = tcx.type_parameter_def(id);
282                     tcx.sess.note(
283                         &format!("...which then requires computing the bounds \
284                                   for type parameter `{}`...",
285                                  def.name));
286                 }
287             }
288         }
289
290         match cycle[0] {
291             AstConvRequest::GetItemTypeScheme(def_id) |
292             AstConvRequest::GetTraitDef(def_id) => {
293                 tcx.sess.note(
294                     &format!("...which then again requires processing `{}`, completing the cycle.",
295                              tcx.item_path_str(def_id)));
296             }
297             AstConvRequest::EnsureSuperPredicates(def_id) => {
298                 tcx.sess.note(
299                     &format!("...which then again requires computing the supertraits of `{}`, \
300                               completing the cycle.",
301                              tcx.item_path_str(def_id)));
302             }
303             AstConvRequest::GetTypeParameterBounds(id) => {
304                 let def = tcx.type_parameter_def(id);
305                 tcx.sess.note(
306                     &format!("...which then again requires computing the bounds \
307                               for type parameter `{}`, completing the cycle.",
308                              def.name));
309             }
310         }
311     }
312
313     /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
314     fn get_trait_def(&self, trait_id: DefId)
315                      -> &'tcx ty::TraitDef<'tcx>
316     {
317         let tcx = self.tcx;
318
319         if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
320             let item = match tcx.map.get(trait_id) {
321                 hir_map::NodeItem(item) => item,
322                 _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
323             };
324
325             trait_def_of_item(self, &*item)
326         } else {
327             tcx.lookup_trait_def(trait_id)
328         }
329     }
330
331     /// Ensure that the (transitive) super predicates for
332     /// `trait_def_id` are available. This will report a cycle error
333     /// if a trait `X` (transitively) extends itself in some form.
334     fn ensure_super_predicates(&self, span: Span, trait_def_id: DefId)
335                                -> Result<(), ErrorReported>
336     {
337         self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
338             let def_ids = ensure_super_predicates_step(self, trait_def_id);
339
340             for def_id in def_ids {
341                 try!(self.ensure_super_predicates(span, def_id));
342             }
343
344             Ok(())
345         })
346     }
347 }
348
349 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
350     fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &hir::Ty) -> Ty<'tcx> {
351         ast_ty_to_ty(self, rs, ast_ty)
352     }
353 }
354
355 impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
356     fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
357
358     fn get_item_type_scheme(&self, span: Span, id: DefId)
359                             -> Result<ty::TypeScheme<'tcx>, ErrorReported>
360     {
361         self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
362             Ok(type_scheme_of_def_id(self.ccx, id))
363         })
364     }
365
366     fn get_trait_def(&self, span: Span, id: DefId)
367                      -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
368     {
369         self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
370             Ok(self.ccx.get_trait_def(id))
371         })
372     }
373
374     fn ensure_super_predicates(&self,
375                                span: Span,
376                                trait_def_id: DefId)
377                                -> Result<(), ErrorReported>
378     {
379         debug!("ensure_super_predicates(trait_def_id={:?})",
380                trait_def_id);
381
382         self.ccx.ensure_super_predicates(span, trait_def_id)
383     }
384
385
386     fn get_type_parameter_bounds(&self,
387                                  span: Span,
388                                  node_id: ast::NodeId)
389                                  -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
390     {
391         self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
392             let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
393                                      .into_iter()
394                                      .filter_map(|p| p.to_opt_poly_trait_ref())
395                                      .collect();
396             Ok(v)
397         })
398     }
399
400     fn trait_defines_associated_type_named(&self,
401                                            trait_def_id: DefId,
402                                            assoc_name: ast::Name)
403                                            -> bool
404     {
405         if let Some(trait_id) = self.tcx().map.as_local_node_id(trait_def_id) {
406             trait_defines_associated_type_named(self.ccx, trait_id, assoc_name)
407         } else {
408             let trait_def = self.tcx().lookup_trait_def(trait_def_id);
409             trait_def.associated_type_names.contains(&assoc_name)
410         }
411     }
412
413         fn ty_infer(&self,
414                     _ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
415                     _substs: Option<&mut Substs<'tcx>>,
416                     _space: Option<ParamSpace>,
417                     span: Span) -> Ty<'tcx> {
418         span_err!(self.tcx().sess, span, E0121,
419                   "the type placeholder `_` is not allowed within types on item signatures");
420         self.tcx().types.err
421     }
422
423     fn projected_ty(&self,
424                     _span: Span,
425                     trait_ref: ty::TraitRef<'tcx>,
426                     item_name: ast::Name)
427                     -> Ty<'tcx>
428     {
429         self.tcx().mk_projection(trait_ref, item_name)
430     }
431 }
432
433 /// Interface used to find the bounds on a type parameter from within
434 /// an `ItemCtxt`. This allows us to use multiple kinds of sources.
435 trait GetTypeParameterBounds<'tcx> {
436     fn get_type_parameter_bounds(&self,
437                                  astconv: &AstConv<'tcx>,
438                                  span: Span,
439                                  node_id: ast::NodeId)
440                                  -> Vec<ty::Predicate<'tcx>>;
441 }
442
443 /// Find bounds from both elements of the tuple.
444 impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B)
445     where A : GetTypeParameterBounds<'tcx>, B : GetTypeParameterBounds<'tcx>
446 {
447     fn get_type_parameter_bounds(&self,
448                                  astconv: &AstConv<'tcx>,
449                                  span: Span,
450                                  node_id: ast::NodeId)
451                                  -> Vec<ty::Predicate<'tcx>>
452     {
453         let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
454         v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id));
455         v
456     }
457 }
458
459 /// Empty set of bounds.
460 impl<'tcx> GetTypeParameterBounds<'tcx> for () {
461     fn get_type_parameter_bounds(&self,
462                                  _astconv: &AstConv<'tcx>,
463                                  _span: Span,
464                                  _node_id: ast::NodeId)
465                                  -> Vec<ty::Predicate<'tcx>>
466     {
467         Vec::new()
468     }
469 }
470
471 /// Find bounds from the parsed and converted predicates.  This is
472 /// used when converting methods, because by that time the predicates
473 /// from the trait/impl have been fully converted.
474 impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
475     fn get_type_parameter_bounds(&self,
476                                  astconv: &AstConv<'tcx>,
477                                  _span: Span,
478                                  node_id: ast::NodeId)
479                                  -> Vec<ty::Predicate<'tcx>>
480     {
481         let def = astconv.tcx().type_parameter_def(node_id);
482
483         self.predicates
484             .iter()
485             .filter(|predicate| {
486                 match **predicate {
487                     ty::Predicate::Trait(ref data) => {
488                         data.skip_binder().self_ty().is_param(def.space, def.index)
489                     }
490                     ty::Predicate::TypeOutlives(ref data) => {
491                         data.skip_binder().0.is_param(def.space, def.index)
492                     }
493                     ty::Predicate::Equate(..) |
494                     ty::Predicate::RegionOutlives(..) |
495                     ty::Predicate::WellFormed(..) |
496                     ty::Predicate::ObjectSafe(..) |
497                     ty::Predicate::Projection(..) => {
498                         false
499                     }
500                 }
501             })
502             .cloned()
503             .collect()
504     }
505 }
506
507 /// Find bounds from hir::Generics. This requires scanning through the
508 /// AST. We do this to avoid having to convert *all* the bounds, which
509 /// would create artificial cycles. Instead we can only convert the
510 /// bounds for those a type parameter `X` if `X::Foo` is used.
511 impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
512     fn get_type_parameter_bounds(&self,
513                                  astconv: &AstConv<'tcx>,
514                                  _: Span,
515                                  node_id: ast::NodeId)
516                                  -> Vec<ty::Predicate<'tcx>>
517     {
518         // In the AST, bounds can derive from two places. Either
519         // written inline like `<T:Foo>` or in a where clause like
520         // `where T:Foo`.
521
522         let def = astconv.tcx().type_parameter_def(node_id);
523         let ty = astconv.tcx().mk_param_from_def(&def);
524
525         let from_ty_params =
526             self.ty_params
527                 .iter()
528                 .filter(|p| p.id == node_id)
529                 .flat_map(|p| p.bounds.iter())
530                 .flat_map(|b| predicates_from_bound(astconv, ty, b));
531
532         let from_where_clauses =
533             self.where_clause
534                 .predicates
535                 .iter()
536                 .filter_map(|wp| match *wp {
537                     hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
538                     _ => None
539                 })
540                 .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
541                 .flat_map(|bp| bp.bounds.iter())
542                 .flat_map(|b| predicates_from_bound(astconv, ty, b));
543
544         from_ty_params.chain(from_where_clauses).collect()
545     }
546 }
547
548 /// Tests whether this is the AST for a reference to the type
549 /// parameter with id `param_id`. We use this so as to avoid running
550 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
551 /// conversion of the type to avoid inducing unnecessary cycles.
552 fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
553                   ast_ty: &hir::Ty,
554                   param_id: ast::NodeId)
555                   -> bool
556 {
557     if let hir::TyPath(None, _) = ast_ty.node {
558         let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
559         match path_res.base_def {
560             def::DefSelfTy(Some(def_id), None) => {
561                 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
562             }
563             def::DefTyParam(_, _, def_id, _) => {
564                 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
565             }
566             _ => {
567                 false
568             }
569         }
570     } else {
571         false
572     }
573 }
574
575
576 fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
577                             container: ImplOrTraitItemContainer,
578                             sig: &hir::MethodSig,
579                             id: ast::NodeId,
580                             name: ast::Name,
581                             vis: hir::Visibility,
582                             untransformed_rcvr_ty: Ty<'tcx>,
583                             rcvr_ty_generics: &ty::Generics<'tcx>,
584                             rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
585     let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
586
587     let ty_generic_predicates =
588         ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
589
590     let (fty, explicit_self_category) =
591         astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
592                               sig, untransformed_rcvr_ty);
593
594     let def_id = ccx.tcx.map.local_def_id(id);
595     let ty_method = ty::Method::new(name,
596                                     ty_generics,
597                                     ty_generic_predicates,
598                                     fty,
599                                     explicit_self_category,
600                                     vis,
601                                     def_id,
602                                     container);
603
604     let fty = ccx.tcx.mk_fn(Some(def_id),
605                             ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
606     debug!("method {} (id {}) has type {:?}",
607             name, id, fty);
608     ccx.tcx.register_item_type(def_id, TypeScheme {
609         generics: ty_method.generics.clone(),
610         ty: fty
611     });
612     ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
613
614     write_ty_to_tcx(ccx.tcx, id, fty);
615
616     debug!("writing method type: def_id={:?} mty={:?}",
617             def_id, ty_method);
618
619     ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
620         ty::MethodTraitItem(Rc::new(ty_method)));
621 }
622
623 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
624                            struct_generics: &ty::Generics<'tcx>,
625                            struct_predicates: &ty::GenericPredicates<'tcx>,
626                            v: &hir::StructField,
627                            ty_f: ty::FieldDefMaster<'tcx>)
628 {
629     let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &*v.node.ty);
630     ty_f.fulfill_ty(tt);
631     write_ty_to_tcx(ccx.tcx, v.node.id, tt);
632
633     /* add the field to the tcache */
634     ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(v.node.id),
635                                ty::TypeScheme {
636                                    generics: struct_generics.clone(),
637                                    ty: tt
638                                });
639     ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(v.node.id),
640                                            struct_predicates.clone());
641 }
642
643 fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
644                                       container: ImplOrTraitItemContainer,
645                                       name: ast::Name,
646                                       id: ast::NodeId,
647                                       vis: hir::Visibility,
648                                       ty: ty::Ty<'tcx>,
649                                       has_value: bool)
650 {
651     ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(id),
652                                            ty::GenericPredicates::empty());
653
654     write_ty_to_tcx(ccx.tcx, id, ty);
655
656     let associated_const = Rc::new(ty::AssociatedConst {
657         name: name,
658         vis: vis,
659         def_id: ccx.tcx.map.local_def_id(id),
660         container: container,
661         ty: ty,
662         has_value: has_value
663     });
664     ccx.tcx.impl_or_trait_items.borrow_mut()
665        .insert(ccx.tcx.map.local_def_id(id), ty::ConstTraitItem(associated_const));
666 }
667
668 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
669                                      container: ImplOrTraitItemContainer,
670                                      name: ast::Name,
671                                      id: ast::NodeId,
672                                      vis: hir::Visibility,
673                                      ty: Option<Ty<'tcx>>)
674 {
675     let associated_type = Rc::new(ty::AssociatedType {
676         name: name,
677         vis: vis,
678         ty: ty,
679         def_id: ccx.tcx.map.local_def_id(id),
680         container: container
681     });
682     ccx.tcx.impl_or_trait_items.borrow_mut()
683        .insert(ccx.tcx.map.local_def_id(id), ty::TypeTraitItem(associated_type));
684 }
685
686 fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
687                                  container: ImplOrTraitItemContainer,
688                                  methods: I,
689                                  untransformed_rcvr_ty: Ty<'tcx>,
690                                  rcvr_ty_generics: &ty::Generics<'tcx>,
691                                  rcvr_ty_predicates: &ty::GenericPredicates<'tcx>)
692     where I: Iterator<Item=(&'i hir::MethodSig, ast::NodeId, ast::Name, hir::Visibility, Span)>
693 {
694     debug!("convert_methods(untransformed_rcvr_ty={:?}, rcvr_ty_generics={:?}, \
695                             rcvr_ty_predicates={:?})",
696            untransformed_rcvr_ty,
697            rcvr_ty_generics,
698            rcvr_ty_predicates);
699
700     for (sig, id, name, vis, _span) in methods {
701         convert_method(ccx,
702                        container,
703                        sig,
704                        id,
705                        name,
706                        vis,
707                        untransformed_rcvr_ty,
708                        rcvr_ty_generics,
709                        rcvr_ty_predicates);
710     }
711 }
712
713 fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
714                                  span: Span,
715                                  generics: &hir::Generics,
716                                  thing: &'static str) {
717     let mut warn = false;
718
719     for ty_param in generics.ty_params.iter() {
720         for bound in ty_param.bounds.iter() {
721             match *bound {
722                 hir::TraitTyParamBound(..) => {
723                     warn = true;
724                 }
725                 hir::RegionTyParamBound(..) => { }
726             }
727         }
728     }
729
730     if warn {
731         // According to accepted RFC #XXX, we should
732         // eventually accept these, but it will not be
733         // part of this PR. Still, convert to warning to
734         // make bootstrapping easier.
735         span_warn!(ccx.tcx.sess, span, E0122,
736                    "trait bounds are not (yet) enforced \
737                    in {} definitions",
738                    thing);
739     }
740 }
741
742 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
743     let tcx = ccx.tcx;
744     debug!("convert: item {} with id {}", it.name, it.id);
745     match it.node {
746         // These don't define types.
747         hir::ItemExternCrate(_) | hir::ItemUse(_) |
748         hir::ItemForeignMod(_) | hir::ItemMod(_) => {
749         }
750         hir::ItemEnum(ref enum_definition, _) => {
751             let (scheme, predicates) = convert_typed_item(ccx, it);
752             write_ty_to_tcx(tcx, it.id, scheme.ty);
753             convert_enum_variant_types(ccx,
754                                        tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
755                                        scheme,
756                                        predicates,
757                                        &enum_definition.variants);
758         },
759         hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
760             let trait_ref =
761                 astconv::instantiate_mono_trait_ref(&ccx.icx(&()),
762                                                     &ExplicitRscope,
763                                                     ast_trait_ref,
764                                                     None);
765
766             tcx.record_trait_has_default_impl(trait_ref.def_id);
767
768             tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
769                                                     Some(trait_ref));
770         }
771         hir::ItemImpl(_, _,
772                       ref generics,
773                       ref opt_trait_ref,
774                       ref selfty,
775                       ref impl_items) => {
776             // Create generics from the generics specified in the impl head.
777             debug!("convert: ast_generics={:?}", generics);
778             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
779             let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
780
781             debug!("convert: impl_bounds={:?}", ty_predicates);
782
783             let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
784             write_ty_to_tcx(tcx, it.id, selfty);
785
786             tcx.register_item_type(ccx.tcx.map.local_def_id(it.id),
787                                    TypeScheme { generics: ty_generics.clone(),
788                                                 ty: selfty });
789             tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
790                                                ty_predicates.clone());
791             if let &Some(ref ast_trait_ref) = opt_trait_ref {
792                 tcx.impl_trait_refs.borrow_mut().insert(
793                     ccx.tcx.map.local_def_id(it.id),
794                     Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
795                                                              &ExplicitRscope,
796                                                              ast_trait_ref,
797                                                              Some(selfty)))
798                         );
799             } else {
800                 tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id), None);
801             }
802
803
804             // If there is a trait reference, treat the methods as always public.
805             // This is to work around some incorrect behavior in privacy checking:
806             // when the method belongs to a trait, it should acquire the privacy
807             // from the trait, not the impl. Forcing the visibility to be public
808             // makes things sorta work.
809             let parent_visibility = if opt_trait_ref.is_some() {
810                 hir::Public
811             } else {
812                 it.vis
813             };
814
815             // Convert all the associated consts.
816             // Also, check if there are any duplicate associated items
817             let mut seen_type_items = FnvHashSet();
818             let mut seen_value_items = FnvHashSet();
819
820             for impl_item in impl_items {
821                 let seen_items = match impl_item.node {
822                     hir::TypeImplItem(_) => &mut seen_type_items,
823                     _                    => &mut seen_value_items,
824                 };
825                 if !seen_items.insert(impl_item.name) {
826                     let desc = match impl_item.node {
827                         hir::ConstImplItem(_, _) => "associated constant",
828                         hir::TypeImplItem(_) => "associated type",
829                         hir::MethodImplItem(ref sig, _) =>
830                             match sig.explicit_self.node {
831                                 hir::SelfStatic => "associated function",
832                                 _ => "method",
833                             },
834                     };
835
836                     span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
837                 }
838
839                 if let hir::ConstImplItem(ref ty, _) = impl_item.node {
840                     let ty = ccx.icx(&ty_predicates)
841                                 .to_ty(&ExplicitRscope, &*ty);
842                     tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id),
843                                            TypeScheme {
844                                                generics: ty_generics.clone(),
845                                                ty: ty,
846                                            });
847                     convert_associated_const(ccx, ImplContainer(ccx.tcx.map.local_def_id(it.id)),
848                                              impl_item.name, impl_item.id,
849                                              impl_item.vis.inherit_from(parent_visibility),
850                                              ty, true /* has_value */);
851                 }
852             }
853
854             // Convert all the associated types.
855             for impl_item in impl_items {
856                 if let hir::TypeImplItem(ref ty) = impl_item.node {
857                     if opt_trait_ref.is_none() {
858                         span_err!(tcx.sess, impl_item.span, E0202,
859                                   "associated types are not allowed in inherent impls");
860                     }
861
862                     let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
863
864                     convert_associated_type(ccx, ImplContainer(ccx.tcx.map.local_def_id(it.id)),
865                                             impl_item.name, impl_item.id, impl_item.vis,
866                                             Some(typ));
867                 }
868             }
869
870             let methods = impl_items.iter().filter_map(|ii| {
871                 if let hir::MethodImplItem(ref sig, _) = ii.node {
872                     // if the method specifies a visibility, use that, otherwise
873                     // inherit the visibility from the impl (so `foo` in `pub impl
874                     // { fn foo(); }` is public, but private in `impl { fn
875                     // foo(); }`).
876                     let method_vis = ii.vis.inherit_from(parent_visibility);
877                     Some((sig, ii.id, ii.name, method_vis, ii.span))
878                 } else {
879                     None
880                 }
881             });
882             convert_methods(ccx,
883                             ImplContainer(ccx.tcx.map.local_def_id(it.id)),
884                             methods,
885                             selfty,
886                             &ty_generics,
887                             &ty_predicates);
888
889             for impl_item in impl_items {
890                 if let hir::MethodImplItem(ref sig, ref body) = impl_item.node {
891                     let body_id = body.id;
892                     check_method_self_type(ccx,
893                                            &BindingRscope::new(),
894                                            ccx.method_ty(impl_item.id),
895                                            selfty,
896                                            &sig.explicit_self,
897                                            body_id);
898                 }
899             }
900
901             enforce_impl_params_are_constrained(tcx,
902                                                 generics,
903                                                 ccx.tcx.map.local_def_id(it.id),
904                                                 impl_items);
905         },
906         hir::ItemTrait(_, _, _, ref trait_items) => {
907             let trait_def = trait_def_of_item(ccx, it);
908             let _: Result<(), ErrorReported> = // any error is already reported, can ignore
909                 ccx.ensure_super_predicates(it.span, ccx.tcx.map.local_def_id(it.id));
910             convert_trait_predicates(ccx, it);
911             let trait_predicates = tcx.lookup_predicates(ccx.tcx.map.local_def_id(it.id));
912
913             debug!("convert: trait_bounds={:?}", trait_predicates);
914
915             // Convert all the associated types.
916             for trait_item in trait_items {
917                 match trait_item.node {
918                     hir::ConstTraitItem(ref ty, ref default) => {
919                         let ty = ccx.icx(&trait_predicates)
920                                     .to_ty(&ExplicitRscope, ty);
921                         tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
922                                                TypeScheme {
923                                                    generics: trait_def.generics.clone(),
924                                                    ty: ty,
925                                                });
926                         convert_associated_const(ccx,
927                                                  TraitContainer(ccx.tcx.map.local_def_id(it.id)),
928                                                  trait_item.name,
929                                                  trait_item.id,
930                                                  hir::Public,
931                                                  ty,
932                                                  default.is_some())
933                     }
934                     _ => {}
935                 }
936             };
937
938             // Convert all the associated types.
939             for trait_item in trait_items {
940                 match trait_item.node {
941                     hir::TypeTraitItem(_, ref opt_ty) => {
942                         let typ = opt_ty.as_ref().map({
943                             |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
944                         });
945
946                         convert_associated_type(ccx,
947                                                 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
948                                                 trait_item.name,
949                                                 trait_item.id,
950                                                 hir::Public,
951                                                 typ);
952                     }
953                     _ => {}
954                 }
955             };
956
957             let methods = trait_items.iter().filter_map(|ti| {
958                 let sig = match ti.node {
959                     hir::MethodTraitItem(ref sig, _) => sig,
960                     _ => return None,
961                 };
962                 Some((sig, ti.id, ti.name, hir::Inherited, ti.span))
963             });
964
965             // Run convert_methods on the trait methods.
966             convert_methods(ccx,
967                             TraitContainer(ccx.tcx.map.local_def_id(it.id)),
968                             methods,
969                             tcx.mk_self_type(),
970                             &trait_def.generics,
971                             &trait_predicates);
972
973             // Add an entry mapping
974             let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
975                 let def_id = ccx.tcx.map.local_def_id(trait_item.id);
976                 match trait_item.node {
977                     hir::ConstTraitItem(..) => {
978                         ty::ConstTraitItemId(def_id)
979                     }
980                     hir::MethodTraitItem(..) => {
981                         ty::MethodTraitItemId(def_id)
982                     }
983                     hir::TypeTraitItem(..) => {
984                         ty::TypeTraitItemId(def_id)
985                     }
986                 }
987             }).collect());
988             tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
989                                                        trait_item_def_ids);
990
991             // This must be done after `collect_trait_methods` so that
992             // we have a method type stored for every method.
993             for trait_item in trait_items {
994                 let sig = match trait_item.node {
995                     hir::MethodTraitItem(ref sig, _) => sig,
996                     _ => continue
997                 };
998                 check_method_self_type(ccx,
999                                        &BindingRscope::new(),
1000                                        ccx.method_ty(trait_item.id),
1001                                        tcx.mk_self_type(),
1002                                        &sig.explicit_self,
1003                                        it.id)
1004             }
1005         },
1006         hir::ItemStruct(ref struct_def, _) => {
1007             let (scheme, predicates) = convert_typed_item(ccx, it);
1008             write_ty_to_tcx(tcx, it.id, scheme.ty);
1009
1010             let it_def_id = ccx.tcx.map.local_def_id(it.id);
1011             let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
1012
1013             for (f, ty_f) in struct_def.fields.iter().zip(variant.fields.iter()) {
1014                 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1015             }
1016
1017             if let Some(ctor_id) = struct_def.ctor_id {
1018                 convert_variant_ctor(tcx, ctor_id, variant, scheme, predicates);
1019             }
1020         },
1021         hir::ItemTy(_, ref generics) => {
1022             ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
1023             let (scheme, _) = convert_typed_item(ccx, it);
1024             write_ty_to_tcx(tcx, it.id, scheme.ty);
1025         },
1026         _ => {
1027             // This call populates the type cache with the converted type
1028             // of the item in passing. All we have to do here is to write
1029             // it into the node type table.
1030             let (scheme, _) = convert_typed_item(ccx, it);
1031             write_ty_to_tcx(tcx, it.id, scheme.ty);
1032         },
1033     }
1034 }
1035
1036 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
1037                                   ctor_id: ast::NodeId,
1038                                   variant: ty::VariantDef<'tcx>,
1039                                   scheme: ty::TypeScheme<'tcx>,
1040                                   predicates: ty::GenericPredicates<'tcx>) {
1041     let ctor_ty = match variant.kind() {
1042         VariantKind::Unit | VariantKind::Dict => scheme.ty,
1043         VariantKind::Tuple => {
1044             let inputs: Vec<_> =
1045                 variant.fields
1046                 .iter()
1047                 .map(|field| field.unsubst_ty())
1048                 .collect();
1049             tcx.mk_ctor_fn(tcx.map.local_def_id(ctor_id),
1050                            &inputs[..],
1051                            scheme.ty)
1052         }
1053     };
1054     write_ty_to_tcx(tcx, ctor_id, ctor_ty);
1055     tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
1056     tcx.register_item_type(tcx.map.local_def_id(ctor_id),
1057                            TypeScheme {
1058                                generics: scheme.generics,
1059                                ty: ctor_ty
1060                            });
1061 }
1062
1063 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1064                                         def: ty::AdtDefMaster<'tcx>,
1065                                         scheme: ty::TypeScheme<'tcx>,
1066                                         predicates: ty::GenericPredicates<'tcx>,
1067                                         variants: &[P<hir::Variant>]) {
1068     let tcx = ccx.tcx;
1069     let icx = ccx.icx(&predicates);
1070
1071     // fill the field types
1072     for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
1073         match variant.node.kind {
1074             hir::TupleVariantKind(ref args) => {
1075                 let rs = ExplicitRscope;
1076                 let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
1077                 for (field, &ty) in ty_variant.fields.iter().zip(input_tys.iter()) {
1078                     field.fulfill_ty(ty);
1079                 }
1080             }
1081
1082             hir::StructVariantKind(ref struct_def) => {
1083                 for (f, ty_f) in struct_def.fields.iter().zip(ty_variant.fields.iter()) {
1084                     convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1085                 }
1086             }
1087         };
1088
1089         // Convert the ctor, if any. This also registers the variant as
1090         // an item.
1091         convert_variant_ctor(
1092             tcx,
1093             variant.node.id,
1094             ty_variant,
1095             scheme.clone(),
1096             predicates.clone()
1097         );
1098     }
1099 }
1100
1101 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1102                                 did: DefId,
1103                                 name: ast::Name,
1104                                 disr_val: ty::Disr,
1105                                 def: &hir::StructDef,
1106                                 ctor_id: DefId) -> ty::VariantDefData<'tcx, 'tcx> {
1107     let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
1108     let fields = def.fields.iter().map(|f| {
1109         let fid = tcx.map.local_def_id(f.node.id);
1110         match f.node.kind {
1111             hir::NamedField(name, vis) => {
1112                 let dup_span = seen_fields.get(&name).cloned();
1113                 if let Some(prev_span) = dup_span {
1114                     span_err!(tcx.sess, f.span, E0124,
1115                               "field `{}` is already declared",
1116                               name);
1117                     span_note!(tcx.sess, prev_span, "previously declared here");
1118                 } else {
1119                     seen_fields.insert(name, f.span);
1120                 }
1121
1122                 ty::FieldDefData::new(fid, name, vis)
1123             },
1124             hir::UnnamedField(vis) => {
1125                 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1126             }
1127         }
1128     }).collect();
1129     ty::VariantDefData {
1130         did: did,
1131         name: name,
1132         disr_val: disr_val,
1133         fields: fields,
1134         ctor_id: ctor_id
1135     }
1136 }
1137
1138 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1139                             it: &hir::Item,
1140                             def: &hir::StructDef)
1141                             -> ty::AdtDefMaster<'tcx>
1142 {
1143
1144     let did = tcx.map.local_def_id(it.id);
1145     let ctor_id = def.ctor_id.map_or(did,
1146         |ctor_id| tcx.map.local_def_id(ctor_id));
1147     tcx.intern_adt_def(
1148         did,
1149         ty::AdtKind::Struct,
1150         vec![convert_struct_variant(tcx, did, it.name, 0, def, ctor_id)]
1151     )
1152 }
1153
1154 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1155                           it: &hir::Item,
1156                           def: &hir::EnumDef)
1157                           -> ty::AdtDefMaster<'tcx>
1158 {
1159     fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1160                                 repr_ty: Ty<'tcx>,
1161                                 e: &hir::Expr) -> Option<ty::Disr> {
1162         debug!("disr expr, checking {}", pprust::expr_to_string(e));
1163
1164         let hint = UncheckedExprHint(repr_ty);
1165         match const_eval::eval_const_expr_partial(tcx, e, hint) {
1166             Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1167             Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1168             Ok(_) => {
1169                 let sign_desc = if repr_ty.is_signed() {
1170                     "signed"
1171                 } else {
1172                     "unsigned"
1173                 };
1174                 span_err!(tcx.sess, e.span, E0079,
1175                           "expected {} integer constant",
1176                           sign_desc);
1177                 None
1178             },
1179             Err(err) => {
1180                 span_err!(tcx.sess, err.span, E0080,
1181                           "constant evaluation error: {}",
1182                           err.description());
1183                 if !e.span.contains(err.span) {
1184                     tcx.sess.span_note(e.span, "for enum discriminant here");
1185                 }
1186                 None
1187             }
1188         }
1189     }
1190
1191     fn report_discrim_overflow(tcx: &ty::ctxt,
1192                                variant_span: Span,
1193                                variant_name: &str,
1194                                repr_type: attr::IntType,
1195                                prev_val: ty::Disr) {
1196         let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1197         let computed_value = repr_type.disr_string(computed_value);
1198         let prev_val = repr_type.disr_string(prev_val);
1199         let repr_type = repr_type.to_ty(tcx);
1200         span_err!(tcx.sess, variant_span, E0370,
1201                   "enum discriminant overflowed on value after {}: {}; \
1202                    set explicitly via {} = {} if that is desired outcome",
1203                   prev_val, repr_type, variant_name, computed_value);
1204     }
1205
1206     fn next_disr(tcx: &ty::ctxt,
1207                  v: &hir::Variant,
1208                  repr_type: attr::IntType,
1209                  prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1210         if let Some(prev_disr_val) = prev_disr_val {
1211             let result = repr_type.disr_incr(prev_disr_val);
1212             if let None = result {
1213                 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1214                                              repr_type, prev_disr_val);
1215             }
1216             result
1217         } else {
1218             Some(ty::INITIAL_DISCRIMINANT_VALUE)
1219         }
1220     }
1221     fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1222                                   v: &hir::Variant,
1223                                   disr: ty::Disr)
1224                                   -> ty::VariantDefData<'tcx, 'tcx>
1225     {
1226         let did = tcx.map.local_def_id(v.node.id);
1227         let name = v.node.name;
1228         match v.node.kind {
1229             hir::TupleVariantKind(ref va) => {
1230                 ty::VariantDefData {
1231                     did: did,
1232                     name: name,
1233                     disr_val: disr,
1234                     fields: va.iter().map(|&hir::VariantArg { id, .. }| {
1235                         ty::FieldDefData::new(
1236                             tcx.map.local_def_id(id),
1237                             special_idents::unnamed_field.name,
1238                             hir::Visibility::Public
1239                         )
1240                     }).collect(),
1241                     ctor_id: did
1242                 }
1243             }
1244             hir::StructVariantKind(ref def) => {
1245                 convert_struct_variant(tcx, did, name, disr, &def, did)
1246             }
1247         }
1248     }
1249     let did = tcx.map.local_def_id(it.id);
1250     let repr_hints = tcx.lookup_repr_hints(did);
1251     let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1252     let mut prev_disr = None;
1253     let variants = def.variants.iter().map(|v| {
1254         let disr = match v.node.disr_expr {
1255             Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1256             None => next_disr(tcx, v, repr_type, prev_disr)
1257         }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1258
1259         let v = convert_enum_variant(tcx, v, disr);
1260         prev_disr = Some(disr);
1261         v
1262     }).collect();
1263     tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
1264 }
1265
1266 /// Ensures that the super-predicates of the trait with def-id
1267 /// trait_def_id are converted and stored. This does NOT ensure that
1268 /// the transitive super-predicates are converted; that is the job of
1269 /// the `ensure_super_predicates()` method in the `AstConv` impl
1270 /// above. Returns a list of trait def-ids that must be ensured as
1271 /// well to guarantee that the transitive superpredicates are
1272 /// converted.
1273 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1274                                 trait_def_id: DefId)
1275                                 -> Vec<DefId>
1276 {
1277     let tcx = ccx.tcx;
1278
1279     debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1280
1281     let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
1282         n
1283     } else {
1284         // If this trait comes from an external crate, then all of the
1285         // supertraits it may depend on also must come from external
1286         // crates, and hence all of them already have their
1287         // super-predicates "converted" (and available from crate
1288         // meta-data), so there is no need to transitively test them.
1289         return Vec::new();
1290     };
1291
1292     let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1293     let superpredicates = superpredicates.unwrap_or_else(|| {
1294         let item = match ccx.tcx.map.get(trait_node_id) {
1295             hir_map::NodeItem(item) => item,
1296             _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1297         };
1298
1299         let (generics, bounds) = match item.node {
1300             hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1301             _ => tcx.sess.span_bug(item.span,
1302                                    "ensure_super_predicates_step invoked on non-trait"),
1303         };
1304
1305         // In-scope when converting the superbounds for `Trait` are
1306         // that `Self:Trait` as well as any bounds that appear on the
1307         // generic types:
1308         let trait_def = trait_def_of_item(ccx, item);
1309         let self_predicate = ty::GenericPredicates {
1310             predicates: VecPerParamSpace::new(vec![],
1311                                               vec![trait_def.trait_ref.to_predicate()],
1312                                               vec![])
1313         };
1314         let scope = &(generics, &self_predicate);
1315
1316         // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1317         let self_param_ty = tcx.mk_self_type();
1318         let superbounds1 = compute_bounds(&ccx.icx(scope),
1319                                     self_param_ty,
1320                                     bounds,
1321                                     SizedByDefault::No,
1322                                     item.span);
1323
1324         let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1325
1326         // Convert any explicit superbounds in the where clause,
1327         // e.g. `trait Foo where Self : Bar`:
1328         let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1329
1330         // Combine the two lists to form the complete set of superbounds:
1331         let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1332         let superpredicates = ty::GenericPredicates {
1333             predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1334         };
1335         debug!("superpredicates for trait {:?} = {:?}",
1336                tcx.map.local_def_id(item.id),
1337                superpredicates);
1338
1339         tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1340
1341         superpredicates
1342     });
1343
1344     let def_ids: Vec<_> = superpredicates.predicates
1345                                          .iter()
1346                                          .filter_map(|p| p.to_opt_poly_trait_ref())
1347                                          .map(|tr| tr.def_id())
1348                                          .collect();
1349
1350     debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1351
1352     def_ids
1353 }
1354
1355 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1356                                it: &hir::Item)
1357                                -> &'tcx ty::TraitDef<'tcx>
1358 {
1359     let def_id = ccx.tcx.map.local_def_id(it.id);
1360     let tcx = ccx.tcx;
1361
1362     if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1363         return def.clone();
1364     }
1365
1366     let (unsafety, generics, items) = match it.node {
1367         hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1368         _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1369     };
1370
1371     let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1372     if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1373         ccx.tcx.sess.span_err(
1374             it.span,
1375             "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1376              which traits can use parenthetical notation");
1377         fileline_help!(ccx.tcx.sess, it.span,
1378                    "add `#![feature(unboxed_closures)]` to \
1379                     the crate attributes to use it");
1380     }
1381
1382     let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1383
1384     let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1385
1386     let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1387         match trait_item.node {
1388             hir::TypeTraitItem(..) => Some(trait_item.name),
1389             _ => None,
1390         }
1391     }).collect();
1392
1393     let trait_ref = ty::TraitRef {
1394         def_id: def_id,
1395         substs: substs,
1396     };
1397
1398     let trait_def = ty::TraitDef {
1399         paren_sugar: paren_sugar,
1400         unsafety: unsafety,
1401         generics: ty_generics,
1402         trait_ref: trait_ref,
1403         associated_type_names: associated_type_names,
1404         nonblanket_impls: RefCell::new(FnvHashMap()),
1405         blanket_impls: RefCell::new(vec![]),
1406         flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
1407     };
1408
1409     return tcx.intern_trait_def(trait_def);
1410
1411     fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1412                                  generics: &hir::Generics)
1413                                  -> Substs<'tcx>
1414     {
1415         let tcx = ccx.tcx;
1416
1417         // Creates a no-op substitution for the trait's type parameters.
1418         let regions =
1419             generics.lifetimes
1420                     .iter()
1421                     .enumerate()
1422                     .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1423                         def_id: tcx.map.local_def_id(def.lifetime.id),
1424                         space: TypeSpace,
1425                         index: i as u32,
1426                         name: def.lifetime.name
1427                     }))
1428                     .collect();
1429
1430         // Start with the generics in the type parameters...
1431         let types: Vec<_> =
1432             generics.ty_params
1433                     .iter()
1434                     .enumerate()
1435                     .map(|(i, def)| tcx.mk_param(TypeSpace,
1436                                                  i as u32, def.name))
1437                     .collect();
1438
1439         // ...and also create the `Self` parameter.
1440         let self_ty = tcx.mk_self_type();
1441
1442         Substs::new_trait(types, regions, self_ty)
1443     }
1444 }
1445
1446 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1447                                        trait_node_id: ast::NodeId,
1448                                        assoc_name: ast::Name)
1449                                        -> bool
1450 {
1451     let item = match ccx.tcx.map.get(trait_node_id) {
1452         hir_map::NodeItem(item) => item,
1453         _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1454     };
1455
1456     let trait_items = match item.node {
1457         hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1458         _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1459     };
1460
1461     trait_items.iter().any(|trait_item| {
1462         match trait_item.node {
1463             hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1464             _ => false,
1465         }
1466     })
1467 }
1468
1469 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1470     let tcx = ccx.tcx;
1471     let trait_def = trait_def_of_item(ccx, it);
1472
1473     let def_id = ccx.tcx.map.local_def_id(it.id);
1474
1475     let (generics, items) = match it.node {
1476         hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1477         ref s => {
1478             tcx.sess.span_bug(
1479                 it.span,
1480                 &format!("trait_def_of_item invoked on {:?}", s));
1481         }
1482     };
1483
1484     let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1485
1486     // `ty_generic_predicates` below will consider the bounds on the type
1487     // parameters (including `Self`) and the explicit where-clauses,
1488     // but to get the full set of predicates on a trait we need to add
1489     // in the supertrait bounds and anything declared on the
1490     // associated types.
1491     let mut base_predicates = super_predicates;
1492
1493     // Add in a predicate that `Self:Trait` (where `Trait` is the
1494     // current trait).  This is needed for builtin bounds.
1495     let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1496     base_predicates.predicates.push(SelfSpace, self_predicate);
1497
1498     // add in the explicit where-clauses
1499     let mut trait_predicates =
1500         ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1501
1502     let assoc_predicates = predicates_for_associated_types(ccx,
1503                                                            generics,
1504                                                            &trait_predicates,
1505                                                            trait_def.trait_ref,
1506                                                            items);
1507     trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1508
1509     let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1510     assert!(prev_predicates.is_none());
1511
1512     return;
1513
1514     fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1515                                                  ast_generics: &hir::Generics,
1516                                                  trait_predicates: &ty::GenericPredicates<'tcx>,
1517                                                  self_trait_ref: ty::TraitRef<'tcx>,
1518                                                  trait_items: &[P<hir::TraitItem>])
1519                                                  -> Vec<ty::Predicate<'tcx>>
1520     {
1521         trait_items.iter().flat_map(|trait_item| {
1522             let bounds = match trait_item.node {
1523                 hir::TypeTraitItem(ref bounds, _) => bounds,
1524                 _ => {
1525                     return vec!().into_iter();
1526                 }
1527             };
1528
1529             let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1530                                                  trait_item.name);
1531
1532             let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1533                                         assoc_ty,
1534                                         bounds,
1535                                         SizedByDefault::Yes,
1536                                         trait_item.span);
1537
1538             bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1539         }).collect()
1540     }
1541 }
1542
1543 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1544                                   def_id: DefId)
1545                                   -> ty::TypeScheme<'tcx>
1546 {
1547     if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
1548         match ccx.tcx.map.find(node_id) {
1549             Some(hir_map::NodeItem(item)) => {
1550                 type_scheme_of_item(ccx, &*item)
1551             }
1552             Some(hir_map::NodeForeignItem(foreign_item)) => {
1553                 let abi = ccx.tcx.map.get_foreign_abi(node_id);
1554                 type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1555             }
1556             x => {
1557                 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1558                                            in get_item_type_scheme(): {:?}",
1559                                           x));
1560             }
1561         }
1562     } else {
1563         ccx.tcx.lookup_item_type(def_id)
1564     }
1565 }
1566
1567 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1568                                 it: &hir::Item)
1569                                 -> ty::TypeScheme<'tcx>
1570 {
1571     memoized(&ccx.tcx.tcache,
1572              ccx.tcx.map.local_def_id(it.id),
1573              |_| compute_type_scheme_of_item(ccx, it))
1574 }
1575
1576 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1577                                         it: &hir::Item)
1578                                         -> ty::TypeScheme<'tcx>
1579 {
1580     let tcx = ccx.tcx;
1581     match it.node {
1582         hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1583             let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1584             ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1585         }
1586         hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1587             let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1588             let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1589             let ty = tcx.mk_fn(Some(ccx.tcx.map.local_def_id(it.id)), tcx.mk_bare_fn(tofd));
1590             ty::TypeScheme { ty: ty, generics: ty_generics }
1591         }
1592         hir::ItemTy(ref t, ref generics) => {
1593             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1594             let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1595             ty::TypeScheme { ty: ty, generics: ty_generics }
1596         }
1597         hir::ItemEnum(ref ei, ref generics) => {
1598             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1599             let substs = mk_item_substs(ccx, &ty_generics);
1600             let def = convert_enum_def(tcx, it, ei);
1601             let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1602             ty::TypeScheme { ty: t, generics: ty_generics }
1603         }
1604         hir::ItemStruct(ref si, ref generics) => {
1605             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1606             let substs = mk_item_substs(ccx, &ty_generics);
1607             let def = convert_struct_def(tcx, it, si);
1608             let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1609             ty::TypeScheme { ty: t, generics: ty_generics }
1610         }
1611         hir::ItemDefaultImpl(..) |
1612         hir::ItemTrait(..) |
1613         hir::ItemImpl(..) |
1614         hir::ItemMod(..) |
1615         hir::ItemForeignMod(..) |
1616         hir::ItemExternCrate(..) |
1617         hir::ItemUse(..) => {
1618             tcx.sess.span_bug(
1619                 it.span,
1620                 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1621                          it.node));
1622         }
1623     }
1624 }
1625
1626 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1627                                 it: &hir::Item)
1628                                 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1629 {
1630     let tcx = ccx.tcx;
1631
1632     let tag = type_scheme_of_item(ccx, it);
1633     let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1634     let predicates = match it.node {
1635         hir::ItemStatic(..) | hir::ItemConst(..) => {
1636             ty::GenericPredicates::empty()
1637         }
1638         hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1639             ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1640         }
1641         hir::ItemTy(_, ref generics) => {
1642             ty_generic_predicates_for_type_or_impl(ccx, generics)
1643         }
1644         hir::ItemEnum(_, ref generics) => {
1645             ty_generic_predicates_for_type_or_impl(ccx, generics)
1646         }
1647         hir::ItemStruct(_, ref generics) => {
1648             ty_generic_predicates_for_type_or_impl(ccx, generics)
1649         }
1650         hir::ItemDefaultImpl(..) |
1651         hir::ItemTrait(..) |
1652         hir::ItemExternCrate(..) |
1653         hir::ItemUse(..) |
1654         hir::ItemImpl(..) |
1655         hir::ItemMod(..) |
1656         hir::ItemForeignMod(..) => {
1657             tcx.sess.span_bug(
1658                 it.span,
1659                 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1660                          it.node));
1661         }
1662     };
1663
1664     let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1665                                                              predicates.clone());
1666     assert!(prev_predicates.is_none());
1667
1668     // Debugging aid.
1669     if tcx.has_attr(ccx.tcx.map.local_def_id(it.id), "rustc_object_lifetime_default") {
1670         let object_lifetime_default_reprs: String =
1671             scheme.generics.types.iter()
1672                                  .map(|t| match t.object_lifetime_default {
1673                                      ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1674                                      d => format!("{:?}", d),
1675                                  })
1676                                  .collect::<Vec<String>>()
1677                                  .join(",");
1678
1679         tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1680     }
1681
1682     return (scheme, predicates);
1683 }
1684
1685 fn type_scheme_of_foreign_item<'a, 'tcx>(
1686     ccx: &CrateCtxt<'a, 'tcx>,
1687     it: &hir::ForeignItem,
1688     abi: abi::Abi)
1689     -> ty::TypeScheme<'tcx>
1690 {
1691     memoized(&ccx.tcx.tcache,
1692              ccx.tcx.map.local_def_id(it.id),
1693              |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
1694 }
1695
1696 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1697     ccx: &CrateCtxt<'a, 'tcx>,
1698     it: &hir::ForeignItem,
1699     abi: abi::Abi)
1700     -> ty::TypeScheme<'tcx>
1701 {
1702     match it.node {
1703         hir::ForeignItemFn(ref fn_decl, ref generics) => {
1704             compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1705         }
1706         hir::ForeignItemStatic(ref t, _) => {
1707             ty::TypeScheme {
1708                 generics: ty::Generics::empty(),
1709                 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1710             }
1711         }
1712     }
1713 }
1714
1715 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1716                                   it: &hir::ForeignItem)
1717 {
1718     // For reasons I cannot fully articulate, I do so hate the AST
1719     // map, and I regard each time that I use it as a personal and
1720     // moral failing, but at the moment it seems like the only
1721     // convenient way to extract the ABI. - ndm
1722     let tcx = ccx.tcx;
1723     let abi = tcx.map.get_foreign_abi(it.id);
1724
1725     let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1726     write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1727
1728     let predicates = match it.node {
1729         hir::ForeignItemFn(_, ref generics) => {
1730             ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1731         }
1732         hir::ForeignItemStatic(..) => {
1733             ty::GenericPredicates::empty()
1734         }
1735     };
1736
1737     let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1738                                                              predicates);
1739     assert!(prev_predicates.is_none());
1740 }
1741
1742 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1743                                           generics: &hir::Generics)
1744                                           -> ty::Generics<'tcx> {
1745     ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1746 }
1747
1748 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1749                                                    generics: &hir::Generics)
1750                                                    -> ty::GenericPredicates<'tcx>
1751 {
1752     ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1753 }
1754
1755 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1756                                    trait_id: ast::NodeId,
1757                                    substs: &'tcx Substs<'tcx>,
1758                                    ast_generics: &hir::Generics)
1759                                    -> ty::Generics<'tcx>
1760 {
1761     debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1762            ccx.tcx.map.local_def_id(trait_id), substs);
1763
1764     let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1765
1766     // Add in the self type parameter.
1767     //
1768     // Something of a hack: use the node id for the trait, also as
1769     // the node id for the Self type parameter.
1770     let param_id = trait_id;
1771
1772     let parent = ccx.tcx.map.get_parent(param_id);
1773
1774     let def = ty::TypeParameterDef {
1775         space: SelfSpace,
1776         index: 0,
1777         name: special_idents::type_self.name,
1778         def_id: ccx.tcx.map.local_def_id(param_id),
1779         default_def_id: ccx.tcx.map.local_def_id(parent),
1780         default: None,
1781         object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1782     };
1783
1784     ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1785
1786     generics.types.push(SelfSpace, def);
1787
1788     return generics;
1789 }
1790
1791 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1792                                generics: &hir::Generics,
1793                                base_generics: &ty::Generics<'tcx>)
1794                                -> ty::Generics<'tcx>
1795 {
1796     ty_generics(ccx, FnSpace, generics, base_generics)
1797 }
1798
1799 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1800                                          generics: &hir::Generics,
1801                                          base_predicates: &ty::GenericPredicates<'tcx>)
1802                                          -> ty::GenericPredicates<'tcx>
1803 {
1804     ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1805 }
1806
1807 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1808 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1809                            bounds: &mut ty::BuiltinBounds,
1810                            ast_bounds: &[hir::TyParamBound],
1811                            span: Span)
1812 {
1813     let tcx = astconv.tcx();
1814
1815     // Try to find an unbound in bounds.
1816     let mut unbound = None;
1817     for ab in ast_bounds {
1818         if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab  {
1819             if unbound.is_none() {
1820                 assert!(ptr.bound_lifetimes.is_empty());
1821                 unbound = Some(ptr.trait_ref.clone());
1822             } else {
1823                 span_err!(tcx.sess, span, E0203,
1824                           "type parameter has more than one relaxed default \
1825                                                 bound, only one is supported");
1826             }
1827         }
1828     }
1829
1830     let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1831     match unbound {
1832         Some(ref tpb) => {
1833             // FIXME(#8559) currently requires the unbound to be built-in.
1834             let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1835             match kind_id {
1836                 Ok(kind_id) if trait_def_id != kind_id => {
1837                     tcx.sess.span_warn(span,
1838                                        "default bound relaxed for a type parameter, but \
1839                                        this does nothing because the given bound is not \
1840                                        a default. Only `?Sized` is supported");
1841                     tcx.try_add_builtin_trait(kind_id, bounds);
1842                 }
1843                 _ => {}
1844             }
1845         }
1846         _ if kind_id.is_ok() => {
1847             tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1848         }
1849         // No lang item for Sized, so we can't add it as a bound.
1850         None => {}
1851     }
1852 }
1853
1854 /// Returns the early-bound lifetimes declared in this generics
1855 /// listing.  For anything other than fns/methods, this is just all
1856 /// the lifetimes that are declared. For fns or methods, we have to
1857 /// screen out those that do not appear in any where-clauses etc using
1858 /// `resolve_lifetime::early_bound_lifetimes`.
1859 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1860                                        ast_generics: &hir::Generics)
1861                                        -> Vec<hir::LifetimeDef>
1862 {
1863     match space {
1864         SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1865         FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1866     }
1867 }
1868
1869 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1870                                   space: ParamSpace,
1871                                   ast_generics: &hir::Generics,
1872                                   base_predicates: &ty::GenericPredicates<'tcx>)
1873                                   -> ty::GenericPredicates<'tcx>
1874 {
1875     let tcx = ccx.tcx;
1876     let mut result = base_predicates.clone();
1877
1878     // Collect the predicates that were written inline by the user on each
1879     // type parameter (e.g., `<T:Foo>`).
1880     for (index, param) in ast_generics.ty_params.iter().enumerate() {
1881         let index = index as u32;
1882         let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1883         let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1884                                     param_ty,
1885                                     &param.bounds,
1886                                     SizedByDefault::Yes,
1887                                     param.span);
1888         let predicates = bounds.predicates(ccx.tcx, param_ty);
1889         result.predicates.extend(space, predicates.into_iter());
1890     }
1891
1892     // Collect the region predicates that were declared inline as
1893     // well. In the case of parameters declared on a fn or method, we
1894     // have to be careful to only iterate over early-bound regions.
1895     let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1896     for (index, param) in early_lifetimes.iter().enumerate() {
1897         let index = index as u32;
1898         let def_id = tcx.map.local_def_id(param.lifetime.id);
1899         let region =
1900             ty::ReEarlyBound(ty::EarlyBoundRegion {
1901                 def_id: def_id,
1902                 space: space,
1903                 index: index,
1904                 name: param.lifetime.name
1905             });
1906         for bound in &param.bounds {
1907             let bound_region = ast_region_to_region(ccx.tcx, bound);
1908             let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1909             result.predicates.push(space, outlives.to_predicate());
1910         }
1911     }
1912
1913     // Add in the bounds that appear in the where-clause
1914     let where_clause = &ast_generics.where_clause;
1915     for predicate in &where_clause.predicates {
1916         match predicate {
1917             &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1918                 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1919                                       &ExplicitRscope,
1920                                       &*bound_pred.bounded_ty);
1921
1922                 for bound in bound_pred.bounds.iter() {
1923                     match bound {
1924                         &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1925                             let mut projections = Vec::new();
1926
1927                             let trait_ref =
1928                                 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1929                                                     ty,
1930                                                     poly_trait_ref,
1931                                                     &mut projections);
1932
1933                             result.predicates.push(space, trait_ref.to_predicate());
1934
1935                             for projection in &projections {
1936                                 result.predicates.push(space, projection.to_predicate());
1937                             }
1938                         }
1939
1940                         &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1941                             let region = ast_region_to_region(tcx, lifetime);
1942                             let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1943                             result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1944                         }
1945                     }
1946                 }
1947             }
1948
1949             &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1950                 let r1 = ast_region_to_region(tcx, &region_pred.lifetime);
1951                 for bound in &region_pred.bounds {
1952                     let r2 = ast_region_to_region(tcx, bound);
1953                     let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1954                     result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1955                 }
1956             }
1957
1958             &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1959                 // FIXME(#20041)
1960                 tcx.sess.span_bug(eq_pred.span,
1961                                     "Equality constraints are not yet \
1962                                         implemented (#20041)")
1963             }
1964         }
1965     }
1966
1967     return result;
1968 }
1969
1970 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1971                         space: ParamSpace,
1972                         ast_generics: &hir::Generics,
1973                         base_generics: &ty::Generics<'tcx>)
1974                         -> ty::Generics<'tcx>
1975 {
1976     let tcx = ccx.tcx;
1977     let mut result = base_generics.clone();
1978
1979     let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1980     for (i, l) in early_lifetimes.iter().enumerate() {
1981         let bounds = l.bounds.iter()
1982                              .map(|l| ast_region_to_region(tcx, l))
1983                              .collect();
1984         let def = ty::RegionParameterDef { name: l.lifetime.name,
1985                                            space: space,
1986                                            index: i as u32,
1987                                            def_id: ccx.tcx.map.local_def_id(l.lifetime.id),
1988                                            bounds: bounds };
1989         result.regions.push(space, def);
1990     }
1991
1992     assert!(result.types.is_empty_in(space));
1993
1994     // Now create the real type parameters.
1995     for i in 0..ast_generics.ty_params.len() {
1996         let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1997         debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1998         result.types.push(space, def);
1999     }
2000
2001     result
2002 }
2003
2004 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2005                                             path: &P<hir::Ty>,
2006                                             space: ParamSpace,
2007                                             index: u32)
2008                                             -> Ty<'tcx>
2009 {
2010     let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
2011
2012     for leaf_ty in ty.walk() {
2013         if let ty::TyParam(p) = leaf_ty.sty {
2014             if p.space == space && p.idx >= index {
2015                 span_err!(ccx.tcx.sess, path.span, E0128,
2016                           "type parameters with a default cannot use \
2017                            forward declared identifiers");
2018
2019                 return ccx.tcx.types.err
2020             }
2021         }
2022     }
2023
2024     ty
2025 }
2026
2027 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2028                                              ast_generics: &hir::Generics,
2029                                              space: ParamSpace,
2030                                              index: u32)
2031                                              -> ty::TypeParameterDef<'tcx>
2032 {
2033     let param = &ast_generics.ty_params[index as usize];
2034
2035     let tcx = ccx.tcx;
2036     match tcx.ty_param_defs.borrow().get(&param.id) {
2037         Some(d) => { return d.clone(); }
2038         None => { }
2039     }
2040
2041     let default = param.default.as_ref().map(
2042         |def| convert_default_type_parameter(ccx, def, space, index)
2043     );
2044
2045     let object_lifetime_default =
2046         compute_object_lifetime_default(ccx, param.id,
2047                                         &param.bounds, &ast_generics.where_clause);
2048
2049     let parent = tcx.map.get_parent(param.id);
2050
2051     let def = ty::TypeParameterDef {
2052         space: space,
2053         index: index,
2054         name: param.name,
2055         def_id: ccx.tcx.map.local_def_id(param.id),
2056         default_def_id: ccx.tcx.map.local_def_id(parent),
2057         default: default,
2058         object_lifetime_default: object_lifetime_default,
2059     };
2060
2061     tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
2062
2063     def
2064 }
2065
2066 /// Scan the bounds and where-clauses on a parameter to extract bounds
2067 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
2068 /// This runs as part of computing the minimal type scheme, so we
2069 /// intentionally avoid just asking astconv to convert all the where
2070 /// clauses into a `ty::Predicate`. This is because that could induce
2071 /// artificial cycles.
2072 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2073                                             param_id: ast::NodeId,
2074                                             param_bounds: &[hir::TyParamBound],
2075                                             where_clause: &hir::WhereClause)
2076                                             -> ty::ObjectLifetimeDefault
2077 {
2078     let inline_bounds = from_bounds(ccx, param_bounds);
2079     let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
2080     let all_bounds: HashSet<_> = inline_bounds.into_iter()
2081                                               .chain(where_bounds)
2082                                               .collect();
2083     return if all_bounds.len() > 1 {
2084         ty::ObjectLifetimeDefault::Ambiguous
2085     } else if all_bounds.len() == 0 {
2086         ty::ObjectLifetimeDefault::BaseDefault
2087     } else {
2088         ty::ObjectLifetimeDefault::Specific(
2089             all_bounds.into_iter().next().unwrap())
2090     };
2091
2092     fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2093                             bounds: &[hir::TyParamBound])
2094                             -> Vec<ty::Region>
2095     {
2096         bounds.iter()
2097               .filter_map(|bound| {
2098                   match *bound {
2099                       hir::TraitTyParamBound(..) =>
2100                           None,
2101                       hir::RegionTyParamBound(ref lifetime) =>
2102                           Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
2103                   }
2104               })
2105               .collect()
2106     }
2107
2108     fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2109                                 param_id: ast::NodeId,
2110                                 predicates: &[hir::WherePredicate])
2111                                 -> Vec<ty::Region>
2112     {
2113         predicates.iter()
2114                   .flat_map(|predicate| {
2115                       match *predicate {
2116                           hir::WherePredicate::BoundPredicate(ref data) => {
2117                               if data.bound_lifetimes.is_empty() &&
2118                                   is_param(ccx.tcx, &data.bounded_ty, param_id)
2119                               {
2120                                   from_bounds(ccx, &data.bounds).into_iter()
2121                               } else {
2122                                   Vec::new().into_iter()
2123                               }
2124                           }
2125                           hir::WherePredicate::RegionPredicate(..) |
2126                           hir::WherePredicate::EqPredicate(..) => {
2127                               Vec::new().into_iter()
2128                           }
2129                       }
2130                   })
2131                   .collect()
2132     }
2133 }
2134
2135 enum SizedByDefault { Yes, No, }
2136
2137 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2138 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2139 /// built-in trait (formerly known as kind): Send.
2140 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2141                         param_ty: ty::Ty<'tcx>,
2142                         ast_bounds: &[hir::TyParamBound],
2143                         sized_by_default: SizedByDefault,
2144                         span: Span)
2145                         -> astconv::Bounds<'tcx>
2146 {
2147     let mut bounds =
2148         conv_param_bounds(astconv,
2149                           span,
2150                           param_ty,
2151                           ast_bounds);
2152
2153     if let SizedByDefault::Yes = sized_by_default {
2154         add_unsized_bound(astconv,
2155                           &mut bounds.builtin_bounds,
2156                           ast_bounds,
2157                           span);
2158     }
2159
2160     bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2161
2162     bounds
2163 }
2164
2165 /// Converts a specific TyParamBound from the AST into a set of
2166 /// predicates that apply to the self-type. A vector is returned
2167 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2168 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2169 /// and `<T as Bar>::X == i32`).
2170 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2171                                param_ty: Ty<'tcx>,
2172                                bound: &hir::TyParamBound)
2173                                -> Vec<ty::Predicate<'tcx>>
2174 {
2175     match *bound {
2176         hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2177             let mut projections = Vec::new();
2178             let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2179             projections.into_iter()
2180                        .map(|p| p.to_predicate())
2181                        .chain(Some(pred.to_predicate()))
2182                        .collect()
2183         }
2184         hir::RegionTyParamBound(ref lifetime) => {
2185             let region = ast_region_to_region(astconv.tcx(), lifetime);
2186             let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2187             vec![ty::Predicate::TypeOutlives(pred)]
2188         }
2189         hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2190             Vec::new()
2191         }
2192     }
2193 }
2194
2195 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2196                              param_ty: Ty<'tcx>,
2197                              trait_ref: &hir::PolyTraitRef,
2198                              projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2199                              -> ty::PolyTraitRef<'tcx>
2200 {
2201     astconv::instantiate_poly_trait_ref(astconv,
2202                                         &ExplicitRscope,
2203                                         trait_ref,
2204                                         Some(param_ty),
2205                                         projections)
2206 }
2207
2208 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2209                               span: Span,
2210                               param_ty: ty::Ty<'tcx>,
2211                               ast_bounds: &[hir::TyParamBound])
2212                               -> astconv::Bounds<'tcx>
2213 {
2214     let tcx = astconv.tcx();
2215     let astconv::PartitionedBounds {
2216         builtin_bounds,
2217         trait_bounds,
2218         region_bounds
2219     } = astconv::partition_bounds(tcx, span, &ast_bounds);
2220
2221     let mut projection_bounds = Vec::new();
2222
2223     let trait_bounds: Vec<ty::PolyTraitRef> =
2224         trait_bounds.iter()
2225                     .map(|bound| conv_poly_trait_ref(astconv,
2226                                                      param_ty,
2227                                                      *bound,
2228                                                      &mut projection_bounds))
2229                     .collect();
2230
2231     let region_bounds: Vec<ty::Region> =
2232         region_bounds.into_iter()
2233                      .map(|r| ast_region_to_region(tcx, r))
2234                      .collect();
2235
2236     astconv::Bounds {
2237         region_bounds: region_bounds,
2238         builtin_bounds: builtin_bounds,
2239         trait_bounds: trait_bounds,
2240         projection_bounds: projection_bounds,
2241     }
2242 }
2243
2244 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2245     ccx: &CrateCtxt<'a, 'tcx>,
2246     decl: &hir::FnDecl,
2247     ast_generics: &hir::Generics,
2248     abi: abi::Abi)
2249     -> ty::TypeScheme<'tcx>
2250 {
2251     for i in &decl.inputs {
2252         match (*i).pat.node {
2253             hir::PatIdent(_, _, _) => (),
2254             hir::PatWild(hir::PatWildSingle) => (),
2255             _ => {
2256                 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2257                           "patterns aren't allowed in foreign function declarations");
2258             }
2259         }
2260     }
2261
2262     let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2263
2264     let rb = BindingRscope::new();
2265     let input_tys = decl.inputs
2266                         .iter()
2267                         .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2268                         .collect();
2269
2270     let output = match decl.output {
2271         hir::Return(ref ty) =>
2272             ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2273         hir::DefaultReturn(..) =>
2274             ty::FnConverging(ccx.tcx.mk_nil()),
2275         hir::NoReturn(..) =>
2276             ty::FnDiverging
2277     };
2278
2279     let t_fn = ccx.tcx.mk_fn(None,
2280         ccx.tcx.mk_bare_fn(ty::BareFnTy {
2281             abi: abi,
2282             unsafety: hir::Unsafety::Unsafe,
2283             sig: ty::Binder(ty::FnSig {inputs: input_tys,
2284                                        output: output,
2285                                        variadic: decl.variadic}),
2286         }));
2287
2288     ty::TypeScheme {
2289         generics: ty_generics,
2290         ty: t_fn
2291     }
2292 }
2293
2294 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2295                             ty_generics: &ty::Generics<'tcx>)
2296                             -> Substs<'tcx>
2297 {
2298     let types =
2299         ty_generics.types.map(
2300             |def| ccx.tcx.mk_param_from_def(def));
2301
2302     let regions =
2303         ty_generics.regions.map(
2304             |def| def.to_early_bound_region());
2305
2306     Substs::new(types, regions)
2307 }
2308
2309 /// Verifies that the explicit self type of a method matches the impl
2310 /// or trait. This is a bit weird but basically because right now we
2311 /// don't handle the general case, but instead map it to one of
2312 /// several pre-defined options using various heuristics, this method
2313 /// comes back to check after the fact that explicit type the user
2314 /// wrote actually matches what the pre-defined option said.
2315 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
2316     ccx: &CrateCtxt<'a, 'tcx>,
2317     rs: &RS,
2318     method_type: Rc<ty::Method<'tcx>>,
2319     required_type: Ty<'tcx>,
2320     explicit_self: &hir::ExplicitSelf,
2321     body_id: ast::NodeId)
2322 {
2323     let tcx = ccx.tcx;
2324     if let hir::SelfExplicit(ref ast_type, _) = explicit_self.node {
2325         let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
2326         let base_type = match typ.sty {
2327             ty::TyRef(_, tm) => tm.ty,
2328             ty::TyBox(typ) => typ,
2329             _ => typ,
2330         };
2331
2332         let body_scope = tcx.region_maps.item_extent(body_id);
2333
2334         // "Required type" comes from the trait definition. It may
2335         // contain late-bound regions from the method, but not the
2336         // trait (since traits only have early-bound region
2337         // parameters).
2338         assert!(!base_type.has_regions_escaping_depth(1));
2339         let required_type_free =
2340             liberate_early_bound_regions(
2341                 tcx, body_scope,
2342                 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
2343
2344         // The "base type" comes from the impl. It too may have late-bound
2345         // regions from the method.
2346         assert!(!base_type.has_regions_escaping_depth(1));
2347         let base_type_free =
2348             liberate_early_bound_regions(
2349                 tcx, body_scope,
2350                 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
2351
2352         debug!("required_type={:?} required_type_free={:?} \
2353                 base_type={:?} base_type_free={:?}",
2354                required_type,
2355                required_type_free,
2356                base_type,
2357                base_type_free);
2358
2359         let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
2360         drop(::require_same_types(tcx,
2361                                   Some(&infcx),
2362                                   false,
2363                                   explicit_self.span,
2364                                   base_type_free,
2365                                   required_type_free,
2366                                   || {
2367                 format!("mismatched self type: expected `{}`",
2368                          required_type)
2369         }));
2370
2371         // We could conceviably add more free-region relations here,
2372         // but since this code is just concerned with checking that
2373         // the `&Self` types etc match up, it's not really necessary.
2374         // It would just allow people to be more approximate in some
2375         // cases. In any case, we can do it later as we feel the need;
2376         // I'd like this function to go away eventually.
2377         let free_regions = FreeRegionMap::new();
2378
2379         infcx.resolve_regions_and_report_errors(&free_regions, body_id);
2380     }
2381
2382     fn liberate_early_bound_regions<'tcx,T>(
2383         tcx: &ty::ctxt<'tcx>,
2384         scope: region::CodeExtent,
2385         value: &T)
2386         -> T
2387         where T : TypeFoldable<'tcx>
2388     {
2389         /*!
2390          * Convert early-bound regions into free regions; normally this is done by
2391          * applying the `free_substs` from the `ParameterEnvironment`, but this particular
2392          * method-self-type check is kind of hacky and done very early in the process,
2393          * before we really have a `ParameterEnvironment` to check.
2394          */
2395
2396         tcx.fold_regions(value, &mut false, |region, _| {
2397             match region {
2398                 ty::ReEarlyBound(data) => {
2399                     ty::ReFree(ty::FreeRegion {
2400                         scope: scope,
2401                         bound_region: ty::BrNamed(data.def_id, data.name)
2402                     })
2403                 }
2404                 _ => region
2405             }
2406         })
2407     }
2408 }
2409
2410 /// Checks that all the type parameters on an impl
2411 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2412                                              ast_generics: &hir::Generics,
2413                                              impl_def_id: DefId,
2414                                              impl_items: &[P<hir::ImplItem>])
2415 {
2416     let impl_scheme = tcx.lookup_item_type(impl_def_id);
2417     let impl_predicates = tcx.lookup_predicates(impl_def_id);
2418     let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2419
2420     // The trait reference is an input, so find all type parameters
2421     // reachable from there, to start (if this is an inherent impl,
2422     // then just examine the self type).
2423     let mut input_parameters: HashSet<_> =
2424         ctp::parameters_for_type(impl_scheme.ty).into_iter().collect();
2425     if let Some(ref trait_ref) = impl_trait_ref {
2426         input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref));
2427     }
2428
2429     ctp::identify_constrained_type_params(tcx,
2430                                           impl_predicates.predicates.as_slice(),
2431                                           impl_trait_ref,
2432                                           &mut input_parameters);
2433
2434     for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2435         let param_ty = ty::ParamTy { space: TypeSpace,
2436                                      idx: index as u32,
2437                                      name: ty_param.name };
2438         if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2439             report_unused_parameter(tcx, ty_param.span, "type", &param_ty.to_string());
2440         }
2441     }
2442
2443     // Every lifetime used in an associated type must be constrained.
2444
2445     let lifetimes_in_associated_types: HashSet<_> =
2446         impl_items.iter()
2447                   .map(|item| tcx.impl_or_trait_item(tcx.map.local_def_id(item.id)))
2448                   .filter_map(|item| match item {
2449                       ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2450                       ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2451                   })
2452                   .flat_map(|ty| ctp::parameters_for_type(ty))
2453                   .filter_map(|p| match p {
2454                       ctp::Parameter::Type(_) => None,
2455                       ctp::Parameter::Region(r) => Some(r),
2456                   })
2457                   .collect();
2458
2459     for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2460         let def_id = tcx.map.local_def_id(lifetime_def.lifetime.id);
2461         let region = ty::EarlyBoundRegion { def_id: def_id,
2462                                             space: TypeSpace,
2463                                             index: index as u32,
2464                                             name: lifetime_def.lifetime.name };
2465         if
2466             lifetimes_in_associated_types.contains(&region) && // (*)
2467             !input_parameters.contains(&ctp::Parameter::Region(region))
2468         {
2469             report_unused_parameter(tcx, lifetime_def.lifetime.span,
2470                                     "lifetime", &region.name.to_string());
2471         }
2472     }
2473
2474     // (*) This is a horrible concession to reality. I think it'd be
2475     // better to just ban unconstrianed lifetimes outright, but in
2476     // practice people do non-hygenic macros like:
2477     //
2478     // ```
2479     // macro_rules! __impl_slice_eq1 {
2480     //     ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2481     //         impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2482     //            ....
2483     //         }
2484     //     }
2485     // }
2486     // ```
2487     //
2488     // In a concession to backwards compatbility, we continue to
2489     // permit those, so long as the lifetimes aren't used in
2490     // associated types. I believe this is sound, because lifetimes
2491     // used elsewhere are not projected back out.
2492 }
2493
2494 fn report_unused_parameter(tcx: &ty::ctxt,
2495                            span: Span,
2496                            kind: &str,
2497                            name: &str)
2498 {
2499     span_err!(tcx.sess, span, E0207,
2500               "the {} parameter `{}` is not constrained by the \
2501                impl trait, self type, or predicates",
2502               kind, name);
2503 }