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