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