]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/collect.rs
Auto merge of #28778 - arielb1:no-source, r=eddyb
[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, LOCAL_CRATE};
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 = DefId::local(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 trait_id.krate != LOCAL_CRATE {
320             return tcx.lookup_trait_def(trait_id)
321         }
322
323         let item = match tcx.map.get(trait_id.node) {
324             hir_map::NodeItem(item) => item,
325             _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
326         };
327
328         trait_def_of_item(self, &*item)
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 trait_def_id.is_local() {
406             trait_defines_associated_type_named(self.ccx, trait_def_id.node, 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.node == param_id
562             }
563             def::DefTyParam(_, _, def_id, _) => {
564                 path_res.depth == 0 && def_id == DefId::local(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 = DefId::local(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(DefId::local(v.node.id),
635                                ty::TypeScheme {
636                                    generics: struct_generics.clone(),
637                                    ty: tt
638                                });
639     ccx.tcx.predicates.borrow_mut().insert(DefId::local(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(DefId::local(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: DefId::local(id),
660         container: container,
661         ty: ty,
662         has_value: has_value
663     });
664     ccx.tcx.impl_or_trait_items.borrow_mut()
665        .insert(DefId::local(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: DefId::local(id),
680         container: container
681     });
682     ccx.tcx.impl_or_trait_items.borrow_mut()
683        .insert(DefId::local(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(DefId::local(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(DefId::local(it.id), Some(trait_ref));
769         }
770         hir::ItemImpl(_, _,
771                       ref generics,
772                       ref opt_trait_ref,
773                       ref selfty,
774                       ref impl_items) => {
775             // Create generics from the generics specified in the impl head.
776             debug!("convert: ast_generics={:?}", generics);
777             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
778             let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
779
780             debug!("convert: impl_bounds={:?}", ty_predicates);
781
782             let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
783             write_ty_to_tcx(tcx, it.id, selfty);
784
785             tcx.register_item_type(DefId::local(it.id),
786                                    TypeScheme { generics: ty_generics.clone(),
787                                                 ty: selfty });
788             tcx.predicates.borrow_mut().insert(DefId::local(it.id),
789                                                ty_predicates.clone());
790             if let &Some(ref ast_trait_ref) = opt_trait_ref {
791                 tcx.impl_trait_refs.borrow_mut().insert(
792                     DefId::local(it.id),
793                     Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
794                                                              &ExplicitRscope,
795                                                              ast_trait_ref,
796                                                              Some(selfty)))
797                         );
798             } else {
799                 tcx.impl_trait_refs.borrow_mut().insert(DefId::local(it.id), None);
800             }
801
802
803             // If there is a trait reference, treat the methods as always public.
804             // This is to work around some incorrect behavior in privacy checking:
805             // when the method belongs to a trait, it should acquire the privacy
806             // from the trait, not the impl. Forcing the visibility to be public
807             // makes things sorta work.
808             let parent_visibility = if opt_trait_ref.is_some() {
809                 hir::Public
810             } else {
811                 it.vis
812             };
813
814             // Convert all the associated consts.
815             // Also, check if there are any duplicate associated items
816             let mut seen_type_items = FnvHashSet();
817             let mut seen_value_items = FnvHashSet();
818
819             for impl_item in impl_items {
820                 let seen_items = match impl_item.node {
821                     hir::TypeImplItem(_) => &mut seen_type_items,
822                     _                    => &mut seen_value_items,
823                 };
824                 if !seen_items.insert(impl_item.name) {
825                     let desc = match impl_item.node {
826                         hir::ConstImplItem(_, _) => "associated constant",
827                         hir::TypeImplItem(_) => "associated type",
828                         hir::MethodImplItem(ref sig, _) =>
829                             match sig.explicit_self.node {
830                                 hir::SelfStatic => "associated function",
831                                 _ => "method",
832                             },
833                     };
834
835                     span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
836                 }
837
838                 if let hir::ConstImplItem(ref ty, _) = impl_item.node {
839                     let ty = ccx.icx(&ty_predicates)
840                                 .to_ty(&ExplicitRscope, &*ty);
841                     tcx.register_item_type(DefId::local(impl_item.id),
842                                            TypeScheme {
843                                                generics: ty_generics.clone(),
844                                                ty: ty,
845                                            });
846                     convert_associated_const(ccx, ImplContainer(DefId::local(it.id)),
847                                              impl_item.name, impl_item.id,
848                                              impl_item.vis.inherit_from(parent_visibility),
849                                              ty, true /* has_value */);
850                 }
851             }
852
853             // Convert all the associated types.
854             for impl_item in impl_items {
855                 if let hir::TypeImplItem(ref ty) = impl_item.node {
856                     if opt_trait_ref.is_none() {
857                         span_err!(tcx.sess, impl_item.span, E0202,
858                                   "associated types are not allowed in inherent impls");
859                     }
860
861                     let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
862
863                     convert_associated_type(ccx, ImplContainer(DefId::local(it.id)),
864                                             impl_item.name, impl_item.id, impl_item.vis,
865                                             Some(typ));
866                 }
867             }
868
869             let methods = impl_items.iter().filter_map(|ii| {
870                 if let hir::MethodImplItem(ref sig, _) = ii.node {
871                     // if the method specifies a visibility, use that, otherwise
872                     // inherit the visibility from the impl (so `foo` in `pub impl
873                     // { fn foo(); }` is public, but private in `impl { fn
874                     // foo(); }`).
875                     let method_vis = ii.vis.inherit_from(parent_visibility);
876                     Some((sig, ii.id, ii.name, method_vis, ii.span))
877                 } else {
878                     None
879                 }
880             });
881             convert_methods(ccx,
882                             ImplContainer(DefId::local(it.id)),
883                             methods,
884                             selfty,
885                             &ty_generics,
886                             &ty_predicates);
887
888             for impl_item in impl_items {
889                 if let hir::MethodImplItem(ref sig, ref body) = impl_item.node {
890                     let body_id = body.id;
891                     check_method_self_type(ccx,
892                                            &BindingRscope::new(),
893                                            ccx.method_ty(impl_item.id),
894                                            selfty,
895                                            &sig.explicit_self,
896                                            body_id);
897                 }
898             }
899
900             enforce_impl_params_are_constrained(tcx,
901                                                 generics,
902                                                 DefId::local(it.id),
903                                                 impl_items);
904         },
905         hir::ItemTrait(_, _, _, ref trait_items) => {
906             let trait_def = trait_def_of_item(ccx, it);
907             let _: Result<(), ErrorReported> = // any error is already reported, can ignore
908                 ccx.ensure_super_predicates(it.span, DefId::local(it.id));
909             convert_trait_predicates(ccx, it);
910             let trait_predicates = tcx.lookup_predicates(DefId::local(it.id));
911
912             debug!("convert: trait_bounds={:?}", trait_predicates);
913
914             // Convert all the associated types.
915             for trait_item in trait_items {
916                 match trait_item.node {
917                     hir::ConstTraitItem(ref ty, ref default) => {
918                         let ty = ccx.icx(&trait_predicates)
919                                     .to_ty(&ExplicitRscope, ty);
920                         tcx.register_item_type(DefId::local(trait_item.id),
921                                                TypeScheme {
922                                                    generics: trait_def.generics.clone(),
923                                                    ty: ty,
924                                                });
925                         convert_associated_const(ccx, TraitContainer(DefId::local(it.id)),
926                                                  trait_item.name, trait_item.id,
927                                                  hir::Public, ty, default.is_some());
928                     }
929                     _ => {}
930                 }
931             };
932
933             // Convert all the associated types.
934             for trait_item in trait_items {
935                 match trait_item.node {
936                     hir::TypeTraitItem(_, ref opt_ty) => {
937                         let typ = opt_ty.as_ref().map({
938                             |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
939                         });
940
941                         convert_associated_type(ccx, TraitContainer(DefId::local(it.id)),
942                                                 trait_item.name, trait_item.id, hir::Public,
943                                                 typ);
944                     }
945                     _ => {}
946                 }
947             };
948
949             let methods = trait_items.iter().filter_map(|ti| {
950                 let sig = match ti.node {
951                     hir::MethodTraitItem(ref sig, _) => sig,
952                     _ => return None,
953                 };
954                 Some((sig, ti.id, ti.name, hir::Inherited, ti.span))
955             });
956
957             // Run convert_methods on the trait methods.
958             convert_methods(ccx,
959                             TraitContainer(DefId::local(it.id)),
960                             methods,
961                             tcx.mk_self_type(),
962                             &trait_def.generics,
963                             &trait_predicates);
964
965             // Add an entry mapping
966             let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
967                 let def_id = DefId::local(trait_item.id);
968                 match trait_item.node {
969                     hir::ConstTraitItem(..) => {
970                         ty::ConstTraitItemId(def_id)
971                     }
972                     hir::MethodTraitItem(..) => {
973                         ty::MethodTraitItemId(def_id)
974                     }
975                     hir::TypeTraitItem(..) => {
976                         ty::TypeTraitItemId(def_id)
977                     }
978                 }
979             }).collect());
980             tcx.trait_item_def_ids.borrow_mut().insert(DefId::local(it.id), trait_item_def_ids);
981
982             // This must be done after `collect_trait_methods` so that
983             // we have a method type stored for every method.
984             for trait_item in trait_items {
985                 let sig = match trait_item.node {
986                     hir::MethodTraitItem(ref sig, _) => sig,
987                     _ => continue
988                 };
989                 check_method_self_type(ccx,
990                                        &BindingRscope::new(),
991                                        ccx.method_ty(trait_item.id),
992                                        tcx.mk_self_type(),
993                                        &sig.explicit_self,
994                                        it.id)
995             }
996         },
997         hir::ItemStruct(ref struct_def, _) => {
998             let (scheme, predicates) = convert_typed_item(ccx, it);
999             write_ty_to_tcx(tcx, it.id, scheme.ty);
1000
1001             let variant = tcx.lookup_adt_def_master(DefId::local(it.id)).struct_variant();
1002
1003             for (f, ty_f) in struct_def.fields.iter().zip(variant.fields.iter()) {
1004                 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1005             }
1006
1007             if let Some(ctor_id) = struct_def.ctor_id {
1008                 convert_variant_ctor(tcx, ctor_id, variant, scheme, predicates);
1009             }
1010         },
1011         hir::ItemTy(_, ref generics) => {
1012             ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
1013             let (scheme, _) = convert_typed_item(ccx, it);
1014             write_ty_to_tcx(tcx, it.id, scheme.ty);
1015         },
1016         _ => {
1017             // This call populates the type cache with the converted type
1018             // of the item in passing. All we have to do here is to write
1019             // it into the node type table.
1020             let (scheme, _) = convert_typed_item(ccx, it);
1021             write_ty_to_tcx(tcx, it.id, scheme.ty);
1022         },
1023     }
1024 }
1025
1026 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
1027                                   ctor_id: ast::NodeId,
1028                                   variant: ty::VariantDef<'tcx>,
1029                                   scheme: ty::TypeScheme<'tcx>,
1030                                   predicates: ty::GenericPredicates<'tcx>) {
1031     let ctor_ty = match variant.kind() {
1032         VariantKind::Unit | VariantKind::Dict => scheme.ty,
1033         VariantKind::Tuple => {
1034             let inputs: Vec<_> =
1035                 variant.fields
1036                 .iter()
1037                 .map(|field| field.unsubst_ty())
1038                 .collect();
1039             tcx.mk_ctor_fn(DefId::local(ctor_id),
1040                            &inputs[..],
1041                            scheme.ty)
1042         }
1043     };
1044     write_ty_to_tcx(tcx, ctor_id, ctor_ty);
1045     tcx.predicates.borrow_mut().insert(DefId::local(ctor_id), predicates);
1046     tcx.register_item_type(DefId::local(ctor_id),
1047                            TypeScheme {
1048                                generics: scheme.generics,
1049                                ty: ctor_ty
1050                            });
1051 }
1052
1053 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1054                                         def: ty::AdtDefMaster<'tcx>,
1055                                         scheme: ty::TypeScheme<'tcx>,
1056                                         predicates: ty::GenericPredicates<'tcx>,
1057                                         variants: &[P<hir::Variant>]) {
1058     let tcx = ccx.tcx;
1059     let icx = ccx.icx(&predicates);
1060
1061     // fill the field types
1062     for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
1063         match variant.node.kind {
1064             hir::TupleVariantKind(ref args) => {
1065                 let rs = ExplicitRscope;
1066                 let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
1067                 for (field, &ty) in ty_variant.fields.iter().zip(input_tys.iter()) {
1068                     field.fulfill_ty(ty);
1069                 }
1070             }
1071
1072             hir::StructVariantKind(ref struct_def) => {
1073                 for (f, ty_f) in struct_def.fields.iter().zip(ty_variant.fields.iter()) {
1074                     convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1075                 }
1076             }
1077         };
1078
1079         // Convert the ctor, if any. This also registers the variant as
1080         // an item.
1081         convert_variant_ctor(
1082             tcx,
1083             variant.node.id,
1084             ty_variant,
1085             scheme.clone(),
1086             predicates.clone()
1087         );
1088     }
1089 }
1090
1091 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1092                                 did: DefId,
1093                                 name: ast::Name,
1094                                 disr_val: ty::Disr,
1095                                 def: &hir::StructDef) -> ty::VariantDefData<'tcx, 'tcx> {
1096     let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
1097     let fields = def.fields.iter().map(|f| {
1098         let fid = DefId::local(f.node.id);
1099         match f.node.kind {
1100             hir::NamedField(name, vis) => {
1101                 let dup_span = seen_fields.get(&name).cloned();
1102                 if let Some(prev_span) = dup_span {
1103                     span_err!(tcx.sess, f.span, E0124,
1104                               "field `{}` is already declared",
1105                               name);
1106                     span_note!(tcx.sess, prev_span, "previously declared here");
1107                 } else {
1108                     seen_fields.insert(name, f.span);
1109                 }
1110
1111                 ty::FieldDefData::new(fid, name, vis)
1112             },
1113             hir::UnnamedField(vis) => {
1114                 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1115             }
1116         }
1117     }).collect();
1118     ty::VariantDefData {
1119         did: did,
1120         name: name,
1121         disr_val: disr_val,
1122         fields: fields
1123     }
1124 }
1125
1126 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1127                             it: &hir::Item,
1128                             def: &hir::StructDef)
1129                             -> ty::AdtDefMaster<'tcx>
1130 {
1131
1132     let did = DefId::local(it.id);
1133     tcx.intern_adt_def(
1134         did,
1135         ty::AdtKind::Struct,
1136         vec![convert_struct_variant(tcx, did, it.name, 0, def)]
1137     )
1138 }
1139
1140 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1141                           it: &hir::Item,
1142                           def: &hir::EnumDef)
1143                           -> ty::AdtDefMaster<'tcx>
1144 {
1145     fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1146                                 repr_ty: Ty<'tcx>,
1147                                 e: &hir::Expr) -> Option<ty::Disr> {
1148         debug!("disr expr, checking {}", pprust::expr_to_string(e));
1149
1150         let hint = UncheckedExprHint(repr_ty);
1151         match const_eval::eval_const_expr_partial(tcx, e, hint) {
1152             Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1153             Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1154             Ok(_) => {
1155                 let sign_desc = if repr_ty.is_signed() {
1156                     "signed"
1157                 } else {
1158                     "unsigned"
1159                 };
1160                 span_err!(tcx.sess, e.span, E0079,
1161                           "expected {} integer constant",
1162                           sign_desc);
1163                 None
1164             },
1165             Err(err) => {
1166               span_err!(tcx.sess, err.span, E0080,
1167                         "constant evaluation error: {}",
1168                         err.description());
1169                 None
1170             }
1171         }
1172     }
1173
1174     fn report_discrim_overflow(tcx: &ty::ctxt,
1175                                variant_span: Span,
1176                                variant_name: &str,
1177                                repr_type: attr::IntType,
1178                                prev_val: ty::Disr) {
1179         let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1180         let computed_value = repr_type.disr_string(computed_value);
1181         let prev_val = repr_type.disr_string(prev_val);
1182         let repr_type = repr_type.to_ty(tcx);
1183         span_err!(tcx.sess, variant_span, E0370,
1184                   "enum discriminant overflowed on value after {}: {}; \
1185                    set explicitly via {} = {} if that is desired outcome",
1186                   prev_val, repr_type, variant_name, computed_value);
1187     }
1188
1189     fn next_disr(tcx: &ty::ctxt,
1190                  v: &hir::Variant,
1191                  repr_type: attr::IntType,
1192                  prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1193         if let Some(prev_disr_val) = prev_disr_val {
1194             let result = repr_type.disr_incr(prev_disr_val);
1195             if let None = result {
1196                 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1197                                              repr_type, prev_disr_val);
1198             }
1199             result
1200         } else {
1201             Some(ty::INITIAL_DISCRIMINANT_VALUE)
1202         }
1203     }
1204     fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1205                                   v: &hir::Variant,
1206                                   disr: ty::Disr)
1207                                   -> ty::VariantDefData<'tcx, 'tcx>
1208     {
1209         let did = DefId::local(v.node.id);
1210         let name = v.node.name;
1211         match v.node.kind {
1212             hir::TupleVariantKind(ref va) => {
1213                 ty::VariantDefData {
1214                     did: did,
1215                     name: name,
1216                     disr_val: disr,
1217                     fields: va.iter().map(|&hir::VariantArg { id, .. }| {
1218                         ty::FieldDefData::new(
1219                             DefId::local(id),
1220                             special_idents::unnamed_field.name,
1221                             hir::Visibility::Public
1222                         )
1223                     }).collect()
1224                 }
1225             }
1226             hir::StructVariantKind(ref def) => {
1227                 convert_struct_variant(tcx, did, name, disr, &def)
1228             }
1229         }
1230     }
1231     let did = DefId::local(it.id);
1232     let repr_hints = tcx.lookup_repr_hints(did);
1233     let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1234     let mut prev_disr = None;
1235     let variants = def.variants.iter().map(|v| {
1236         let disr = match v.node.disr_expr {
1237             Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1238             None => next_disr(tcx, v, repr_type, prev_disr)
1239         }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1240
1241         let v = convert_enum_variant(tcx, v, disr);
1242         prev_disr = Some(disr);
1243         v
1244     }).collect();
1245     tcx.intern_adt_def(DefId::local(it.id), ty::AdtKind::Enum, variants)
1246 }
1247
1248 /// Ensures that the super-predicates of the trait with def-id
1249 /// trait_def_id are converted and stored. This does NOT ensure that
1250 /// the transitive super-predicates are converted; that is the job of
1251 /// the `ensure_super_predicates()` method in the `AstConv` impl
1252 /// above. Returns a list of trait def-ids that must be ensured as
1253 /// well to guarantee that the transitive superpredicates are
1254 /// converted.
1255 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1256                                 trait_def_id: DefId)
1257                                 -> Vec<DefId>
1258 {
1259     let tcx = ccx.tcx;
1260
1261     debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1262
1263     if trait_def_id.krate != LOCAL_CRATE {
1264         // If this trait comes from an external crate, then all of the
1265         // supertraits it may depend on also must come from external
1266         // crates, and hence all of them already have their
1267         // super-predicates "converted" (and available from crate
1268         // meta-data), so there is no need to transitively test them.
1269         return Vec::new();
1270     }
1271
1272     let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1273     let superpredicates = superpredicates.unwrap_or_else(|| {
1274         let trait_node_id = trait_def_id.node;
1275
1276         let item = match ccx.tcx.map.get(trait_node_id) {
1277             hir_map::NodeItem(item) => item,
1278             _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1279         };
1280
1281         let (generics, bounds) = match item.node {
1282             hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1283             _ => tcx.sess.span_bug(item.span,
1284                                    "ensure_super_predicates_step invoked on non-trait"),
1285         };
1286
1287         // In-scope when converting the superbounds for `Trait` are
1288         // that `Self:Trait` as well as any bounds that appear on the
1289         // generic types:
1290         let trait_def = trait_def_of_item(ccx, item);
1291         let self_predicate = ty::GenericPredicates {
1292             predicates: VecPerParamSpace::new(vec![],
1293                                               vec![trait_def.trait_ref.to_predicate()],
1294                                               vec![])
1295         };
1296         let scope = &(generics, &self_predicate);
1297
1298         // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1299         let self_param_ty = tcx.mk_self_type();
1300         let superbounds1 = compute_bounds(&ccx.icx(scope),
1301                                     self_param_ty,
1302                                     bounds,
1303                                     SizedByDefault::No,
1304                                     item.span);
1305
1306         let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1307
1308         // Convert any explicit superbounds in the where clause,
1309         // e.g. `trait Foo where Self : Bar`:
1310         let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1311
1312         // Combine the two lists to form the complete set of superbounds:
1313         let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1314         let superpredicates = ty::GenericPredicates {
1315             predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1316         };
1317         debug!("superpredicates for trait {:?} = {:?}",
1318                DefId::local(item.id),
1319                superpredicates);
1320
1321         tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1322
1323         superpredicates
1324     });
1325
1326     let def_ids: Vec<_> = superpredicates.predicates
1327                                          .iter()
1328                                          .filter_map(|p| p.to_opt_poly_trait_ref())
1329                                          .map(|tr| tr.def_id())
1330                                          .collect();
1331
1332     debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1333
1334     def_ids
1335 }
1336
1337 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1338                                it: &hir::Item)
1339                                -> &'tcx ty::TraitDef<'tcx>
1340 {
1341     let def_id = DefId::local(it.id);
1342     let tcx = ccx.tcx;
1343
1344     if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1345         return def.clone();
1346     }
1347
1348     let (unsafety, generics, items) = match it.node {
1349         hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1350         _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1351     };
1352
1353     let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1354     if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1355         ccx.tcx.sess.span_err(
1356             it.span,
1357             "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1358              which traits can use parenthetical notation");
1359         fileline_help!(ccx.tcx.sess, it.span,
1360                    "add `#![feature(unboxed_closures)]` to \
1361                     the crate attributes to use it");
1362     }
1363
1364     let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1365
1366     let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1367
1368     let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1369         match trait_item.node {
1370             hir::TypeTraitItem(..) => Some(trait_item.name),
1371             _ => None,
1372         }
1373     }).collect();
1374
1375     let trait_ref = ty::TraitRef {
1376         def_id: def_id,
1377         substs: substs,
1378     };
1379
1380     let trait_def = ty::TraitDef {
1381         paren_sugar: paren_sugar,
1382         unsafety: unsafety,
1383         generics: ty_generics,
1384         trait_ref: trait_ref,
1385         associated_type_names: associated_type_names,
1386         nonblanket_impls: RefCell::new(FnvHashMap()),
1387         blanket_impls: RefCell::new(vec![]),
1388         flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
1389     };
1390
1391     return tcx.intern_trait_def(trait_def);
1392
1393     fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1394                                  generics: &hir::Generics)
1395                                  -> Substs<'tcx>
1396     {
1397         let tcx = ccx.tcx;
1398
1399         // Creates a no-op substitution for the trait's type parameters.
1400         let regions =
1401             generics.lifetimes
1402                     .iter()
1403                     .enumerate()
1404                     .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1405                         param_id: def.lifetime.id,
1406                         space: TypeSpace,
1407                         index: i as u32,
1408                         name: def.lifetime.name
1409                     }))
1410                     .collect();
1411
1412         // Start with the generics in the type parameters...
1413         let types: Vec<_> =
1414             generics.ty_params
1415                     .iter()
1416                     .enumerate()
1417                     .map(|(i, def)| tcx.mk_param(TypeSpace,
1418                                                  i as u32, def.name))
1419                     .collect();
1420
1421         // ...and also create the `Self` parameter.
1422         let self_ty = tcx.mk_self_type();
1423
1424         Substs::new_trait(types, regions, self_ty)
1425     }
1426 }
1427
1428 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1429                                        trait_node_id: ast::NodeId,
1430                                        assoc_name: ast::Name)
1431                                        -> bool
1432 {
1433     let item = match ccx.tcx.map.get(trait_node_id) {
1434         hir_map::NodeItem(item) => item,
1435         _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1436     };
1437
1438     let trait_items = match item.node {
1439         hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1440         _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1441     };
1442
1443     trait_items.iter().any(|trait_item| {
1444         match trait_item.node {
1445             hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1446             _ => false,
1447         }
1448     })
1449 }
1450
1451 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1452     let tcx = ccx.tcx;
1453     let trait_def = trait_def_of_item(ccx, it);
1454
1455     let def_id = DefId::local(it.id);
1456
1457     let (generics, items) = match it.node {
1458         hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1459         ref s => {
1460             tcx.sess.span_bug(
1461                 it.span,
1462                 &format!("trait_def_of_item invoked on {:?}", s));
1463         }
1464     };
1465
1466     let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1467
1468     // `ty_generic_predicates` below will consider the bounds on the type
1469     // parameters (including `Self`) and the explicit where-clauses,
1470     // but to get the full set of predicates on a trait we need to add
1471     // in the supertrait bounds and anything declared on the
1472     // associated types.
1473     let mut base_predicates = super_predicates;
1474
1475     // Add in a predicate that `Self:Trait` (where `Trait` is the
1476     // current trait).  This is needed for builtin bounds.
1477     let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1478     base_predicates.predicates.push(SelfSpace, self_predicate);
1479
1480     // add in the explicit where-clauses
1481     let mut trait_predicates =
1482         ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1483
1484     let assoc_predicates = predicates_for_associated_types(ccx,
1485                                                            generics,
1486                                                            &trait_predicates,
1487                                                            trait_def.trait_ref,
1488                                                            items);
1489     trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1490
1491     let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1492     assert!(prev_predicates.is_none());
1493
1494     return;
1495
1496     fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1497                                                  ast_generics: &hir::Generics,
1498                                                  trait_predicates: &ty::GenericPredicates<'tcx>,
1499                                                  self_trait_ref: ty::TraitRef<'tcx>,
1500                                                  trait_items: &[P<hir::TraitItem>])
1501                                                  -> Vec<ty::Predicate<'tcx>>
1502     {
1503         trait_items.iter().flat_map(|trait_item| {
1504             let bounds = match trait_item.node {
1505                 hir::TypeTraitItem(ref bounds, _) => bounds,
1506                 _ => {
1507                     return vec!().into_iter();
1508                 }
1509             };
1510
1511             let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1512                                                  trait_item.name);
1513
1514             let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1515                                         assoc_ty,
1516                                         bounds,
1517                                         SizedByDefault::Yes,
1518                                         trait_item.span);
1519
1520             bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1521         }).collect()
1522     }
1523 }
1524
1525 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1526                                   def_id: DefId)
1527                                   -> ty::TypeScheme<'tcx>
1528 {
1529     if def_id.krate != LOCAL_CRATE {
1530         return ccx.tcx.lookup_item_type(def_id);
1531     }
1532
1533     match ccx.tcx.map.find(def_id.node) {
1534         Some(hir_map::NodeItem(item)) => {
1535             type_scheme_of_item(ccx, &*item)
1536         }
1537         Some(hir_map::NodeForeignItem(foreign_item)) => {
1538             let abi = ccx.tcx.map.get_foreign_abi(def_id.node);
1539             type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1540         }
1541         x => {
1542             ccx.tcx.sess.bug(&format!("unexpected sort of node \
1543                                             in get_item_type_scheme(): {:?}",
1544                                        x));
1545         }
1546     }
1547 }
1548
1549 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1550                                 it: &hir::Item)
1551                                 -> ty::TypeScheme<'tcx>
1552 {
1553     memoized(&ccx.tcx.tcache,
1554              DefId::local(it.id),
1555              |_| compute_type_scheme_of_item(ccx, it))
1556 }
1557
1558 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1559                                         it: &hir::Item)
1560                                         -> ty::TypeScheme<'tcx>
1561 {
1562     let tcx = ccx.tcx;
1563     match it.node {
1564         hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1565             let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1566             ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1567         }
1568         hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1569             let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1570             let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1571             let ty = tcx.mk_fn(Some(DefId::local(it.id)), tcx.mk_bare_fn(tofd));
1572             ty::TypeScheme { ty: ty, generics: ty_generics }
1573         }
1574         hir::ItemTy(ref t, ref generics) => {
1575             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1576             let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1577             ty::TypeScheme { ty: ty, generics: ty_generics }
1578         }
1579         hir::ItemEnum(ref ei, ref generics) => {
1580             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1581             let substs = mk_item_substs(ccx, &ty_generics);
1582             let def = convert_enum_def(tcx, it, ei);
1583             let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1584             ty::TypeScheme { ty: t, generics: ty_generics }
1585         }
1586         hir::ItemStruct(ref si, ref generics) => {
1587             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1588             let substs = mk_item_substs(ccx, &ty_generics);
1589             let def = convert_struct_def(tcx, it, si);
1590             let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1591             ty::TypeScheme { ty: t, generics: ty_generics }
1592         }
1593         hir::ItemDefaultImpl(..) |
1594         hir::ItemTrait(..) |
1595         hir::ItemImpl(..) |
1596         hir::ItemMod(..) |
1597         hir::ItemForeignMod(..) |
1598         hir::ItemExternCrate(..) |
1599         hir::ItemUse(..) => {
1600             tcx.sess.span_bug(
1601                 it.span,
1602                 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1603                          it.node));
1604         }
1605     }
1606 }
1607
1608 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1609                                 it: &hir::Item)
1610                                 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1611 {
1612     let tcx = ccx.tcx;
1613
1614     let tag = type_scheme_of_item(ccx, it);
1615     let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1616     let predicates = match it.node {
1617         hir::ItemStatic(..) | hir::ItemConst(..) => {
1618             ty::GenericPredicates::empty()
1619         }
1620         hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1621             ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1622         }
1623         hir::ItemTy(_, ref generics) => {
1624             ty_generic_predicates_for_type_or_impl(ccx, generics)
1625         }
1626         hir::ItemEnum(_, ref generics) => {
1627             ty_generic_predicates_for_type_or_impl(ccx, generics)
1628         }
1629         hir::ItemStruct(_, ref generics) => {
1630             ty_generic_predicates_for_type_or_impl(ccx, generics)
1631         }
1632         hir::ItemDefaultImpl(..) |
1633         hir::ItemTrait(..) |
1634         hir::ItemExternCrate(..) |
1635         hir::ItemUse(..) |
1636         hir::ItemImpl(..) |
1637         hir::ItemMod(..) |
1638         hir::ItemForeignMod(..) => {
1639             tcx.sess.span_bug(
1640                 it.span,
1641                 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1642                          it.node));
1643         }
1644     };
1645
1646     let prev_predicates = tcx.predicates.borrow_mut().insert(DefId::local(it.id),
1647                                                              predicates.clone());
1648     assert!(prev_predicates.is_none());
1649
1650     // Debugging aid.
1651     if tcx.has_attr(DefId::local(it.id), "rustc_object_lifetime_default") {
1652         let object_lifetime_default_reprs: String =
1653             scheme.generics.types.iter()
1654                                  .map(|t| match t.object_lifetime_default {
1655                                      ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1656                                      d => format!("{:?}", d),
1657                                  })
1658                                  .collect::<Vec<String>>()
1659                                  .join(",");
1660
1661         tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1662     }
1663
1664     return (scheme, predicates);
1665 }
1666
1667 fn type_scheme_of_foreign_item<'a, 'tcx>(
1668     ccx: &CrateCtxt<'a, 'tcx>,
1669     it: &hir::ForeignItem,
1670     abi: abi::Abi)
1671     -> ty::TypeScheme<'tcx>
1672 {
1673     memoized(&ccx.tcx.tcache,
1674              DefId::local(it.id),
1675              |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
1676 }
1677
1678 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1679     ccx: &CrateCtxt<'a, 'tcx>,
1680     it: &hir::ForeignItem,
1681     abi: abi::Abi)
1682     -> ty::TypeScheme<'tcx>
1683 {
1684     match it.node {
1685         hir::ForeignItemFn(ref fn_decl, ref generics) => {
1686             compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1687         }
1688         hir::ForeignItemStatic(ref t, _) => {
1689             ty::TypeScheme {
1690                 generics: ty::Generics::empty(),
1691                 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1692             }
1693         }
1694     }
1695 }
1696
1697 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1698                                   it: &hir::ForeignItem)
1699 {
1700     // For reasons I cannot fully articulate, I do so hate the AST
1701     // map, and I regard each time that I use it as a personal and
1702     // moral failing, but at the moment it seems like the only
1703     // convenient way to extract the ABI. - ndm
1704     let tcx = ccx.tcx;
1705     let abi = tcx.map.get_foreign_abi(it.id);
1706
1707     let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1708     write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1709
1710     let predicates = match it.node {
1711         hir::ForeignItemFn(_, ref generics) => {
1712             ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1713         }
1714         hir::ForeignItemStatic(..) => {
1715             ty::GenericPredicates::empty()
1716         }
1717     };
1718
1719     let prev_predicates = tcx.predicates.borrow_mut().insert(DefId::local(it.id), predicates);
1720     assert!(prev_predicates.is_none());
1721 }
1722
1723 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1724                                           generics: &hir::Generics)
1725                                           -> ty::Generics<'tcx> {
1726     ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1727 }
1728
1729 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1730                                                    generics: &hir::Generics)
1731                                                    -> ty::GenericPredicates<'tcx>
1732 {
1733     ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1734 }
1735
1736 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1737                                    trait_id: ast::NodeId,
1738                                    substs: &'tcx Substs<'tcx>,
1739                                    ast_generics: &hir::Generics)
1740                                    -> ty::Generics<'tcx>
1741 {
1742     debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1743            DefId::local(trait_id), substs);
1744
1745     let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1746
1747     // Add in the self type parameter.
1748     //
1749     // Something of a hack: use the node id for the trait, also as
1750     // the node id for the Self type parameter.
1751     let param_id = trait_id;
1752
1753     let parent = ccx.tcx.map.get_parent(param_id);
1754
1755     let def = ty::TypeParameterDef {
1756         space: SelfSpace,
1757         index: 0,
1758         name: special_idents::type_self.name,
1759         def_id: DefId::local(param_id),
1760         default_def_id: DefId::local(parent),
1761         default: None,
1762         object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1763     };
1764
1765     ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1766
1767     generics.types.push(SelfSpace, def);
1768
1769     return generics;
1770 }
1771
1772 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1773                                generics: &hir::Generics,
1774                                base_generics: &ty::Generics<'tcx>)
1775                                -> ty::Generics<'tcx>
1776 {
1777     ty_generics(ccx, FnSpace, generics, base_generics)
1778 }
1779
1780 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1781                                          generics: &hir::Generics,
1782                                          base_predicates: &ty::GenericPredicates<'tcx>)
1783                                          -> ty::GenericPredicates<'tcx>
1784 {
1785     ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1786 }
1787
1788 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1789 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1790                            bounds: &mut ty::BuiltinBounds,
1791                            ast_bounds: &[hir::TyParamBound],
1792                            span: Span)
1793 {
1794     let tcx = astconv.tcx();
1795
1796     // Try to find an unbound in bounds.
1797     let mut unbound = None;
1798     for ab in ast_bounds {
1799         if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab  {
1800             if unbound.is_none() {
1801                 assert!(ptr.bound_lifetimes.is_empty());
1802                 unbound = Some(ptr.trait_ref.clone());
1803             } else {
1804                 span_err!(tcx.sess, span, E0203,
1805                           "type parameter has more than one relaxed default \
1806                                                 bound, only one is supported");
1807             }
1808         }
1809     }
1810
1811     let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1812     match unbound {
1813         Some(ref tpb) => {
1814             // FIXME(#8559) currently requires the unbound to be built-in.
1815             let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1816             match kind_id {
1817                 Ok(kind_id) if trait_def_id != kind_id => {
1818                     tcx.sess.span_warn(span,
1819                                        "default bound relaxed for a type parameter, but \
1820                                        this does nothing because the given bound is not \
1821                                        a default. Only `?Sized` is supported");
1822                     tcx.try_add_builtin_trait(kind_id, bounds);
1823                 }
1824                 _ => {}
1825             }
1826         }
1827         _ if kind_id.is_ok() => {
1828             tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1829         }
1830         // No lang item for Sized, so we can't add it as a bound.
1831         None => {}
1832     }
1833 }
1834
1835 /// Returns the early-bound lifetimes declared in this generics
1836 /// listing.  For anything other than fns/methods, this is just all
1837 /// the lifetimes that are declared. For fns or methods, we have to
1838 /// screen out those that do not appear in any where-clauses etc using
1839 /// `resolve_lifetime::early_bound_lifetimes`.
1840 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1841                                        ast_generics: &hir::Generics)
1842                                        -> Vec<hir::LifetimeDef>
1843 {
1844     match space {
1845         SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1846         FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1847     }
1848 }
1849
1850 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1851                                   space: ParamSpace,
1852                                   ast_generics: &hir::Generics,
1853                                   base_predicates: &ty::GenericPredicates<'tcx>)
1854                                   -> ty::GenericPredicates<'tcx>
1855 {
1856     let tcx = ccx.tcx;
1857     let mut result = base_predicates.clone();
1858
1859     // Collect the predicates that were written inline by the user on each
1860     // type parameter (e.g., `<T:Foo>`).
1861     for (index, param) in ast_generics.ty_params.iter().enumerate() {
1862         let index = index as u32;
1863         let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1864         let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1865                                     param_ty,
1866                                     &param.bounds,
1867                                     SizedByDefault::Yes,
1868                                     param.span);
1869         let predicates = bounds.predicates(ccx.tcx, param_ty);
1870         result.predicates.extend(space, predicates.into_iter());
1871     }
1872
1873     // Collect the region predicates that were declared inline as
1874     // well. In the case of parameters declared on a fn or method, we
1875     // have to be careful to only iterate over early-bound regions.
1876     let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1877     for (index, param) in early_lifetimes.iter().enumerate() {
1878         let index = index as u32;
1879         let region =
1880             ty::ReEarlyBound(ty::EarlyBoundRegion {
1881                 param_id: param.lifetime.id,
1882                 space: space,
1883                 index: index,
1884                 name: param.lifetime.name
1885             });
1886         for bound in &param.bounds {
1887             let bound_region = ast_region_to_region(ccx.tcx, bound);
1888             let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1889             result.predicates.push(space, outlives.to_predicate());
1890         }
1891     }
1892
1893     // Add in the bounds that appear in the where-clause
1894     let where_clause = &ast_generics.where_clause;
1895     for predicate in &where_clause.predicates {
1896         match predicate {
1897             &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1898                 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1899                                       &ExplicitRscope,
1900                                       &*bound_pred.bounded_ty);
1901
1902                 for bound in bound_pred.bounds.iter() {
1903                     match bound {
1904                         &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1905                             let mut projections = Vec::new();
1906
1907                             let trait_ref =
1908                                 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1909                                                     ty,
1910                                                     poly_trait_ref,
1911                                                     &mut projections);
1912
1913                             result.predicates.push(space, trait_ref.to_predicate());
1914
1915                             for projection in &projections {
1916                                 result.predicates.push(space, projection.to_predicate());
1917                             }
1918                         }
1919
1920                         &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1921                             let region = ast_region_to_region(tcx, lifetime);
1922                             let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1923                             result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1924                         }
1925                     }
1926                 }
1927             }
1928
1929             &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1930                 let r1 = ast_region_to_region(tcx, &region_pred.lifetime);
1931                 for bound in &region_pred.bounds {
1932                     let r2 = ast_region_to_region(tcx, bound);
1933                     let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1934                     result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1935                 }
1936             }
1937
1938             &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1939                 // FIXME(#20041)
1940                 tcx.sess.span_bug(eq_pred.span,
1941                                     "Equality constraints are not yet \
1942                                         implemented (#20041)")
1943             }
1944         }
1945     }
1946
1947     return result;
1948 }
1949
1950 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1951                         space: ParamSpace,
1952                         ast_generics: &hir::Generics,
1953                         base_generics: &ty::Generics<'tcx>)
1954                         -> ty::Generics<'tcx>
1955 {
1956     let tcx = ccx.tcx;
1957     let mut result = base_generics.clone();
1958
1959     let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1960     for (i, l) in early_lifetimes.iter().enumerate() {
1961         let bounds = l.bounds.iter()
1962                              .map(|l| ast_region_to_region(tcx, l))
1963                              .collect();
1964         let def = ty::RegionParameterDef { name: l.lifetime.name,
1965                                            space: space,
1966                                            index: i as u32,
1967                                            def_id: DefId::local(l.lifetime.id),
1968                                            bounds: bounds };
1969         result.regions.push(space, def);
1970     }
1971
1972     assert!(result.types.is_empty_in(space));
1973
1974     // Now create the real type parameters.
1975     for i in 0..ast_generics.ty_params.len() {
1976         let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1977         debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1978         result.types.push(space, def);
1979     }
1980
1981     result
1982 }
1983
1984 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1985                                             path: &P<hir::Ty>,
1986                                             space: ParamSpace,
1987                                             index: u32)
1988                                             -> Ty<'tcx>
1989 {
1990     let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1991
1992     for leaf_ty in ty.walk() {
1993         if let ty::TyParam(p) = leaf_ty.sty {
1994             if p.space == space && p.idx >= index {
1995                 span_err!(ccx.tcx.sess, path.span, E0128,
1996                           "type parameters with a default cannot use \
1997                            forward declared identifiers");
1998
1999                 return ccx.tcx.types.err
2000             }
2001         }
2002     }
2003
2004     ty
2005 }
2006
2007 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2008                                              ast_generics: &hir::Generics,
2009                                              space: ParamSpace,
2010                                              index: u32)
2011                                              -> ty::TypeParameterDef<'tcx>
2012 {
2013     let param = &ast_generics.ty_params[index as usize];
2014
2015     let tcx = ccx.tcx;
2016     match tcx.ty_param_defs.borrow().get(&param.id) {
2017         Some(d) => { return d.clone(); }
2018         None => { }
2019     }
2020
2021     let default = param.default.as_ref().map(
2022         |def| convert_default_type_parameter(ccx, def, space, index)
2023     );
2024
2025     let object_lifetime_default =
2026         compute_object_lifetime_default(ccx, param.id,
2027                                         &param.bounds, &ast_generics.where_clause);
2028
2029     let parent = tcx.map.get_parent(param.id);
2030
2031     let def = ty::TypeParameterDef {
2032         space: space,
2033         index: index,
2034         name: param.name,
2035         def_id: DefId::local(param.id),
2036         default_def_id: DefId::local(parent),
2037         default: default,
2038         object_lifetime_default: object_lifetime_default,
2039     };
2040
2041     tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
2042
2043     def
2044 }
2045
2046 /// Scan the bounds and where-clauses on a parameter to extract bounds
2047 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
2048 /// This runs as part of computing the minimal type scheme, so we
2049 /// intentionally avoid just asking astconv to convert all the where
2050 /// clauses into a `ty::Predicate`. This is because that could induce
2051 /// artificial cycles.
2052 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2053                                             param_id: ast::NodeId,
2054                                             param_bounds: &[hir::TyParamBound],
2055                                             where_clause: &hir::WhereClause)
2056                                             -> ty::ObjectLifetimeDefault
2057 {
2058     let inline_bounds = from_bounds(ccx, param_bounds);
2059     let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
2060     let all_bounds: HashSet<_> = inline_bounds.into_iter()
2061                                               .chain(where_bounds)
2062                                               .collect();
2063     return if all_bounds.len() > 1 {
2064         ty::ObjectLifetimeDefault::Ambiguous
2065     } else if all_bounds.len() == 0 {
2066         ty::ObjectLifetimeDefault::BaseDefault
2067     } else {
2068         ty::ObjectLifetimeDefault::Specific(
2069             all_bounds.into_iter().next().unwrap())
2070     };
2071
2072     fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2073                             bounds: &[hir::TyParamBound])
2074                             -> Vec<ty::Region>
2075     {
2076         bounds.iter()
2077               .filter_map(|bound| {
2078                   match *bound {
2079                       hir::TraitTyParamBound(..) =>
2080                           None,
2081                       hir::RegionTyParamBound(ref lifetime) =>
2082                           Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
2083                   }
2084               })
2085               .collect()
2086     }
2087
2088     fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2089                                 param_id: ast::NodeId,
2090                                 predicates: &[hir::WherePredicate])
2091                                 -> Vec<ty::Region>
2092     {
2093         predicates.iter()
2094                   .flat_map(|predicate| {
2095                       match *predicate {
2096                           hir::WherePredicate::BoundPredicate(ref data) => {
2097                               if data.bound_lifetimes.is_empty() &&
2098                                   is_param(ccx.tcx, &data.bounded_ty, param_id)
2099                               {
2100                                   from_bounds(ccx, &data.bounds).into_iter()
2101                               } else {
2102                                   Vec::new().into_iter()
2103                               }
2104                           }
2105                           hir::WherePredicate::RegionPredicate(..) |
2106                           hir::WherePredicate::EqPredicate(..) => {
2107                               Vec::new().into_iter()
2108                           }
2109                       }
2110                   })
2111                   .collect()
2112     }
2113 }
2114
2115 enum SizedByDefault { Yes, No, }
2116
2117 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2118 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2119 /// built-in trait (formerly known as kind): Send.
2120 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2121                         param_ty: ty::Ty<'tcx>,
2122                         ast_bounds: &[hir::TyParamBound],
2123                         sized_by_default: SizedByDefault,
2124                         span: Span)
2125                         -> astconv::Bounds<'tcx>
2126 {
2127     let mut bounds =
2128         conv_param_bounds(astconv,
2129                           span,
2130                           param_ty,
2131                           ast_bounds);
2132
2133     if let SizedByDefault::Yes = sized_by_default {
2134         add_unsized_bound(astconv,
2135                           &mut bounds.builtin_bounds,
2136                           ast_bounds,
2137                           span);
2138     }
2139
2140     bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2141
2142     bounds
2143 }
2144
2145 /// Converts a specific TyParamBound from the AST into a set of
2146 /// predicates that apply to the self-type. A vector is returned
2147 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2148 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2149 /// and `<T as Bar>::X == i32`).
2150 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2151                                param_ty: Ty<'tcx>,
2152                                bound: &hir::TyParamBound)
2153                                -> Vec<ty::Predicate<'tcx>>
2154 {
2155     match *bound {
2156         hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2157             let mut projections = Vec::new();
2158             let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2159             projections.into_iter()
2160                        .map(|p| p.to_predicate())
2161                        .chain(Some(pred.to_predicate()))
2162                        .collect()
2163         }
2164         hir::RegionTyParamBound(ref lifetime) => {
2165             let region = ast_region_to_region(astconv.tcx(), lifetime);
2166             let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2167             vec![ty::Predicate::TypeOutlives(pred)]
2168         }
2169         hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2170             Vec::new()
2171         }
2172     }
2173 }
2174
2175 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2176                              param_ty: Ty<'tcx>,
2177                              trait_ref: &hir::PolyTraitRef,
2178                              projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2179                              -> ty::PolyTraitRef<'tcx>
2180 {
2181     astconv::instantiate_poly_trait_ref(astconv,
2182                                         &ExplicitRscope,
2183                                         trait_ref,
2184                                         Some(param_ty),
2185                                         projections)
2186 }
2187
2188 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2189                               span: Span,
2190                               param_ty: ty::Ty<'tcx>,
2191                               ast_bounds: &[hir::TyParamBound])
2192                               -> astconv::Bounds<'tcx>
2193 {
2194     let tcx = astconv.tcx();
2195     let astconv::PartitionedBounds {
2196         builtin_bounds,
2197         trait_bounds,
2198         region_bounds
2199     } = astconv::partition_bounds(tcx, span, &ast_bounds);
2200
2201     let mut projection_bounds = Vec::new();
2202
2203     let trait_bounds: Vec<ty::PolyTraitRef> =
2204         trait_bounds.iter()
2205                     .map(|bound| conv_poly_trait_ref(astconv,
2206                                                      param_ty,
2207                                                      *bound,
2208                                                      &mut projection_bounds))
2209                     .collect();
2210
2211     let region_bounds: Vec<ty::Region> =
2212         region_bounds.into_iter()
2213                      .map(|r| ast_region_to_region(tcx, r))
2214                      .collect();
2215
2216     astconv::Bounds {
2217         region_bounds: region_bounds,
2218         builtin_bounds: builtin_bounds,
2219         trait_bounds: trait_bounds,
2220         projection_bounds: projection_bounds,
2221     }
2222 }
2223
2224 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2225     ccx: &CrateCtxt<'a, 'tcx>,
2226     decl: &hir::FnDecl,
2227     ast_generics: &hir::Generics,
2228     abi: abi::Abi)
2229     -> ty::TypeScheme<'tcx>
2230 {
2231     for i in &decl.inputs {
2232         match (*i).pat.node {
2233             hir::PatIdent(_, _, _) => (),
2234             hir::PatWild(hir::PatWildSingle) => (),
2235             _ => {
2236                 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2237                           "patterns aren't allowed in foreign function declarations");
2238             }
2239         }
2240     }
2241
2242     let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2243
2244     let rb = BindingRscope::new();
2245     let input_tys = decl.inputs
2246                         .iter()
2247                         .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2248                         .collect();
2249
2250     let output = match decl.output {
2251         hir::Return(ref ty) =>
2252             ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2253         hir::DefaultReturn(..) =>
2254             ty::FnConverging(ccx.tcx.mk_nil()),
2255         hir::NoReturn(..) =>
2256             ty::FnDiverging
2257     };
2258
2259     let t_fn = ccx.tcx.mk_fn(None,
2260         ccx.tcx.mk_bare_fn(ty::BareFnTy {
2261             abi: abi,
2262             unsafety: hir::Unsafety::Unsafe,
2263             sig: ty::Binder(ty::FnSig {inputs: input_tys,
2264                                        output: output,
2265                                        variadic: decl.variadic}),
2266         }));
2267
2268     ty::TypeScheme {
2269         generics: ty_generics,
2270         ty: t_fn
2271     }
2272 }
2273
2274 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2275                             ty_generics: &ty::Generics<'tcx>)
2276                             -> Substs<'tcx>
2277 {
2278     let types =
2279         ty_generics.types.map(
2280             |def| ccx.tcx.mk_param_from_def(def));
2281
2282     let regions =
2283         ty_generics.regions.map(
2284             |def| def.to_early_bound_region());
2285
2286     Substs::new(types, regions)
2287 }
2288
2289 /// Verifies that the explicit self type of a method matches the impl
2290 /// or trait. This is a bit weird but basically because right now we
2291 /// don't handle the general case, but instead map it to one of
2292 /// several pre-defined options using various heuristics, this method
2293 /// comes back to check after the fact that explicit type the user
2294 /// wrote actually matches what the pre-defined option said.
2295 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
2296     ccx: &CrateCtxt<'a, 'tcx>,
2297     rs: &RS,
2298     method_type: Rc<ty::Method<'tcx>>,
2299     required_type: Ty<'tcx>,
2300     explicit_self: &hir::ExplicitSelf,
2301     body_id: ast::NodeId)
2302 {
2303     let tcx = ccx.tcx;
2304     if let hir::SelfExplicit(ref ast_type, _) = explicit_self.node {
2305         let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
2306         let base_type = match typ.sty {
2307             ty::TyRef(_, tm) => tm.ty,
2308             ty::TyBox(typ) => typ,
2309             _ => typ,
2310         };
2311
2312         let body_scope = tcx.region_maps.item_extent(body_id);
2313
2314         // "Required type" comes from the trait definition. It may
2315         // contain late-bound regions from the method, but not the
2316         // trait (since traits only have early-bound region
2317         // parameters).
2318         assert!(!base_type.has_regions_escaping_depth(1));
2319         let required_type_free =
2320             liberate_early_bound_regions(
2321                 tcx, body_scope,
2322                 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
2323
2324         // The "base type" comes from the impl. It too may have late-bound
2325         // regions from the method.
2326         assert!(!base_type.has_regions_escaping_depth(1));
2327         let base_type_free =
2328             liberate_early_bound_regions(
2329                 tcx, body_scope,
2330                 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
2331
2332         debug!("required_type={:?} required_type_free={:?} \
2333                 base_type={:?} base_type_free={:?}",
2334                required_type,
2335                required_type_free,
2336                base_type,
2337                base_type_free);
2338
2339         let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
2340         drop(::require_same_types(tcx,
2341                                   Some(&infcx),
2342                                   false,
2343                                   explicit_self.span,
2344                                   base_type_free,
2345                                   required_type_free,
2346                                   || {
2347                 format!("mismatched self type: expected `{}`",
2348                          required_type)
2349         }));
2350
2351         // We could conceviably add more free-region relations here,
2352         // but since this code is just concerned with checking that
2353         // the `&Self` types etc match up, it's not really necessary.
2354         // It would just allow people to be more approximate in some
2355         // cases. In any case, we can do it later as we feel the need;
2356         // I'd like this function to go away eventually.
2357         let free_regions = FreeRegionMap::new();
2358
2359         infcx.resolve_regions_and_report_errors(&free_regions, body_id);
2360     }
2361
2362     fn liberate_early_bound_regions<'tcx,T>(
2363         tcx: &ty::ctxt<'tcx>,
2364         scope: region::CodeExtent,
2365         value: &T)
2366         -> T
2367         where T : TypeFoldable<'tcx>
2368     {
2369         /*!
2370          * Convert early-bound regions into free regions; normally this is done by
2371          * applying the `free_substs` from the `ParameterEnvironment`, but this particular
2372          * method-self-type check is kind of hacky and done very early in the process,
2373          * before we really have a `ParameterEnvironment` to check.
2374          */
2375
2376         tcx.fold_regions(value, &mut false, |region, _| {
2377             match region {
2378                 ty::ReEarlyBound(data) => {
2379                     let def_id = DefId::local(data.param_id);
2380                     ty::ReFree(ty::FreeRegion { scope: scope,
2381                                                 bound_region: ty::BrNamed(def_id, data.name) })
2382                 }
2383                 _ => region
2384             }
2385         })
2386     }
2387 }
2388
2389 /// Checks that all the type parameters on an impl
2390 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2391                                              ast_generics: &hir::Generics,
2392                                              impl_def_id: DefId,
2393                                              impl_items: &[P<hir::ImplItem>])
2394 {
2395     let impl_scheme = tcx.lookup_item_type(impl_def_id);
2396     let impl_predicates = tcx.lookup_predicates(impl_def_id);
2397     let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2398
2399     // The trait reference is an input, so find all type parameters
2400     // reachable from there, to start (if this is an inherent impl,
2401     // then just examine the self type).
2402     let mut input_parameters: HashSet<_> =
2403         ctp::parameters_for_type(impl_scheme.ty).into_iter().collect();
2404     if let Some(ref trait_ref) = impl_trait_ref {
2405         input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref));
2406     }
2407
2408     ctp::identify_constrained_type_params(tcx,
2409                                           impl_predicates.predicates.as_slice(),
2410                                           impl_trait_ref,
2411                                           &mut input_parameters);
2412
2413     for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2414         let param_ty = ty::ParamTy { space: TypeSpace,
2415                                      idx: index as u32,
2416                                      name: ty_param.name };
2417         if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2418             report_unused_parameter(tcx, ty_param.span, "type", &param_ty.to_string());
2419         }
2420     }
2421
2422     // Every lifetime used in an associated type must be constrained.
2423
2424     let lifetimes_in_associated_types: HashSet<_> =
2425         impl_items.iter()
2426                   .map(|item| tcx.impl_or_trait_item(DefId::local(item.id)))
2427                   .filter_map(|item| match item {
2428                       ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2429                       ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2430                   })
2431                   .flat_map(|ty| ctp::parameters_for_type(ty))
2432                   .filter_map(|p| match p {
2433                       ctp::Parameter::Type(_) => None,
2434                       ctp::Parameter::Region(r) => Some(r),
2435                   })
2436                   .collect();
2437
2438     for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2439         let region = ty::EarlyBoundRegion { param_id: lifetime_def.lifetime.id,
2440                                             space: TypeSpace,
2441                                             index: index as u32,
2442                                             name: lifetime_def.lifetime.name };
2443         if
2444             lifetimes_in_associated_types.contains(&region) && // (*)
2445             !input_parameters.contains(&ctp::Parameter::Region(region))
2446         {
2447             report_unused_parameter(tcx, lifetime_def.lifetime.span,
2448                                     "lifetime", &region.name.to_string());
2449         }
2450     }
2451
2452     // (*) This is a horrible concession to reality. I think it'd be
2453     // better to just ban unconstrianed lifetimes outright, but in
2454     // practice people do non-hygenic macros like:
2455     //
2456     // ```
2457     // macro_rules! __impl_slice_eq1 {
2458     //     ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2459     //         impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2460     //            ....
2461     //         }
2462     //     }
2463     // }
2464     // ```
2465     //
2466     // In a concession to backwards compatbility, we continue to
2467     // permit those, so long as the lifetimes aren't used in
2468     // associated types. I believe this is sound, because lifetimes
2469     // used elsewhere are not projected back out.
2470 }
2471
2472 fn report_unused_parameter(tcx: &ty::ctxt,
2473                            span: Span,
2474                            kind: &str,
2475                            name: &str)
2476 {
2477     span_err!(tcx.sess, span, E0207,
2478               "the {} parameter `{}` is not constrained by the \
2479                impl trait, self type, or predicates",
2480               kind, name);
2481 }