]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/collect.rs
Rollup merge of #41135 - japaric:unstable-docs, r=steveklabnik
[rust.git] / src / librustc_typeck / collect.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*
12
13 # Collect phase
14
15 The collect phase of type check has the job of visiting all items,
16 determining their type, and writing that type into the `tcx.types`
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 a pair of `Generics` and `Ty`.  Type
26 parameters themselves are represented as `ty_param()` instances.
27
28 The phasing of type conversion is somewhat complicated. There is no
29 clear set of phases we can enforce (e.g., converting traits first,
30 then types, or something like that) because the user can introduce
31 arbitrary interdependencies. So instead we generally convert things
32 lazilly and on demand, and include logic that checks for cycles.
33 Demand is driven by calls to `AstConv::get_item_type_scheme` or
34 `AstConv::lookup_trait_def`.
35
36 Currently, we "convert" types and traits in two phases (note that
37 conversion only affects the types of items / enum variants / methods;
38 it does not e.g. compute the types of individual expressions):
39
40 0. Intrinsics
41 1. Trait/Type definitions
42
43 Conversion itself is done by simply walking each of the items in turn
44 and invoking an appropriate function (e.g., `trait_def_of_item` or
45 `convert_item`). However, it is possible that while converting an
46 item, we may need to compute the *type scheme* or *trait definition*
47 for other items.
48
49 There are some shortcomings in this design:
50 - Because the item generics include defaults, cycles through type
51   parameter defaults are illegal even if those defaults are never
52   employed. This is not necessarily a bug.
53
54 */
55
56 use astconv::{AstConv, Bounds};
57 use lint;
58 use constrained_type_params as ctp;
59 use middle::lang_items::SizedTraitLangItem;
60 use middle::const_val::ConstVal;
61 use middle::resolve_lifetime as rl;
62 use rustc_const_eval::{ConstContext, report_const_eval_err};
63 use rustc::ty::subst::Substs;
64 use rustc::ty::{ToPredicate, ReprOptions};
65 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
66 use rustc::ty::maps::Providers;
67 use rustc::ty::util::IntTypeExt;
68 use rustc::dep_graph::DepNode;
69 use util::common::MemoizationMap;
70 use util::nodemap::{NodeMap, FxHashMap};
71
72 use rustc_const_math::ConstInt;
73
74 use std::cell::RefCell;
75 use std::collections::BTreeMap;
76
77 use syntax::{abi, ast};
78 use syntax::codemap::Spanned;
79 use syntax::symbol::{Symbol, keywords};
80 use syntax_pos::{Span, DUMMY_SP};
81
82 use rustc::hir::{self, map as hir_map};
83 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
84 use rustc::hir::def::{Def, CtorKind};
85 use rustc::hir::def_id::DefId;
86
87 ///////////////////////////////////////////////////////////////////////////
88 // Main entry point
89
90 pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
91     let mut visitor = CollectItemTypesVisitor { tcx: tcx };
92     tcx.visit_all_item_likes_in_krate(DepNode::CollectItem, &mut visitor.as_deep_visitor());
93 }
94
95 pub fn provide(providers: &mut Providers) {
96     *providers = Providers {
97         ty,
98         generics,
99         predicates,
100         super_predicates,
101         type_param_predicates,
102         trait_def,
103         adt_def,
104         impl_trait_ref,
105         ..*providers
106     };
107 }
108
109 ///////////////////////////////////////////////////////////////////////////
110
111 /// Context specific to some particular item. This is what implements
112 /// AstConv. It has information about the predicates that are defined
113 /// on the trait. Unfortunately, this predicate information is
114 /// available in various different forms at various points in the
115 /// process. So we can't just store a pointer to e.g. the AST or the
116 /// parsed ty form, we have to be more flexible. To this end, the
117 /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
118 /// `get_type_parameter_bounds` requests, drawing the information from
119 /// the AST (`hir::Generics`), recursively.
120 struct ItemCtxt<'a,'tcx:'a> {
121     tcx: TyCtxt<'a, 'tcx, 'tcx>,
122     item_def_id: DefId,
123 }
124
125 ///////////////////////////////////////////////////////////////////////////
126
127 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
128     tcx: TyCtxt<'a, 'tcx, 'tcx>
129 }
130
131 impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> {
132     /// Collect item types is structured into two tasks. The outer
133     /// task, `CollectItem`, walks the entire content of an item-like
134     /// thing, including its body. It also spawns an inner task,
135     /// `CollectItemSig`, which walks only the signature. This inner
136     /// task is the one that writes the item-type into the various
137     /// maps.  This setup ensures that the item body is never
138     /// accessible to the task that computes its signature, so that
139     /// changes to the body don't affect the signature.
140     ///
141     /// Consider an example function `foo` that also has a closure in its body:
142     ///
143     /// ```
144     /// fn foo(<sig>) {
145     ///     ...
146     ///     let bar = || ...; // we'll label this closure as "bar" below
147     /// }
148     /// ```
149     ///
150     /// This results in a dep-graph like so. I've labeled the edges to
151     /// document where they arise.
152     ///
153     /// ```
154     /// [HirBody(foo)] -2--> [CollectItem(foo)] -4-> [ItemSignature(bar)]
155     ///                       ^           ^
156     ///                       1           3
157     /// [Hir(foo)] -----------+-6-> [CollectItemSig(foo)] -5-> [ItemSignature(foo)]
158     /// ```
159     ///
160     /// 1. This is added by the `visit_all_item_likes_in_krate`.
161     /// 2. This is added when we fetch the item body.
162     /// 3. This is added because `CollectItem` launches `CollectItemSig`.
163     ///    - it is arguably false; if we refactor the `with_task` system;
164     ///      we could get probably rid of it, but it is also harmless enough.
165     /// 4. This is added by the code in `visit_expr` when we write to `item_types`.
166     /// 5. This is added by the code in `convert_item` when we write to `item_types`;
167     ///    note that this write occurs inside the `CollectItemSig` task.
168     /// 6. Added by reads from within `op`.
169     fn with_collect_item_sig(&self, id: ast::NodeId, op: fn(TyCtxt<'a, 'tcx, 'tcx>, ast::NodeId)) {
170         let def_id = self.tcx.hir.local_def_id(id);
171         self.tcx.dep_graph.with_task(DepNode::CollectItemSig(def_id), self.tcx, id, op);
172     }
173 }
174
175 impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
176     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
177         NestedVisitorMap::OnlyBodies(&self.tcx.hir)
178     }
179
180     fn visit_item(&mut self, item: &'tcx hir::Item) {
181         self.with_collect_item_sig(item.id, convert_item);
182         intravisit::walk_item(self, item);
183     }
184
185     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
186         for param in &generics.ty_params {
187             if param.default.is_some() {
188                 let def_id = self.tcx.hir.local_def_id(param.id);
189                 self.tcx.item_type(def_id);
190             }
191         }
192         intravisit::walk_generics(self, generics);
193     }
194
195     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
196         if let hir::ExprClosure(..) = expr.node {
197             let def_id = self.tcx.hir.local_def_id(expr.id);
198             self.tcx.item_generics(def_id);
199             self.tcx.item_type(def_id);
200         }
201         intravisit::walk_expr(self, expr);
202     }
203
204     fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
205         if let hir::TyImplTrait(..) = ty.node {
206             let def_id = self.tcx.hir.local_def_id(ty.id);
207             self.tcx.item_generics(def_id);
208             self.tcx.item_predicates(def_id);
209         }
210         intravisit::walk_ty(self, ty);
211     }
212
213     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
214         self.with_collect_item_sig(trait_item.id, convert_trait_item);
215         intravisit::walk_trait_item(self, trait_item);
216     }
217
218     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
219         self.with_collect_item_sig(impl_item.id, convert_impl_item);
220         intravisit::walk_impl_item(self, impl_item);
221     }
222 }
223
224 ///////////////////////////////////////////////////////////////////////////
225 // Utility types and common code for the above passes.
226
227 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
228     fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
229            -> ItemCtxt<'a,'tcx> {
230         ItemCtxt {
231             tcx: tcx,
232             item_def_id: item_def_id,
233         }
234     }
235 }
236
237 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
238     fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
239         AstConv::ast_ty_to_ty(self, ast_ty)
240     }
241 }
242
243 impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
244     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.tcx }
245
246     fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
247         &self.tcx.ast_ty_to_ty_cache
248     }
249
250     fn get_type_parameter_bounds(&self,
251                                  span: Span,
252                                  def_id: DefId)
253                                  -> ty::GenericPredicates<'tcx>
254     {
255         ty::queries::type_param_predicates::get(self.tcx, span, (self.item_def_id, def_id))
256     }
257
258     fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
259         None
260     }
261
262     fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>)
263                 -> Option<&'tcx ty::Region> {
264         None
265     }
266
267     fn ty_infer(&self, span: Span) -> Ty<'tcx> {
268         struct_span_err!(
269             self.tcx().sess,
270             span,
271             E0121,
272             "the type placeholder `_` is not allowed within types on item signatures"
273         ).span_label(span, &format!("not allowed in type signatures"))
274         .emit();
275         self.tcx().types.err
276     }
277
278     fn projected_ty_from_poly_trait_ref(&self,
279                                         span: Span,
280                                         poly_trait_ref: ty::PolyTraitRef<'tcx>,
281                                         item_name: ast::Name)
282                                         -> Ty<'tcx>
283     {
284         if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) {
285             self.tcx().mk_projection(trait_ref, item_name)
286         } else {
287             // no late-bound regions, we can just ignore the binder
288             span_err!(self.tcx().sess, span, E0212,
289                 "cannot extract an associated type from a higher-ranked trait bound \
290                  in this context");
291             self.tcx().types.err
292         }
293     }
294
295     fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
296         // types in item signatures are not normalized, to avoid undue
297         // dependencies.
298         ty
299     }
300
301     fn set_tainted_by_errors(&self) {
302         // no obvious place to track this, just let it go
303     }
304 }
305
306 fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
307                                    (item_def_id, def_id): (DefId, DefId))
308                                    -> ty::GenericPredicates<'tcx> {
309     use rustc::hir::map::*;
310     use rustc::hir::*;
311
312     // In the AST, bounds can derive from two places. Either
313     // written inline like `<T:Foo>` or in a where clause like
314     // `where T:Foo`.
315
316     let param_id = tcx.hir.as_local_node_id(def_id).unwrap();
317     let param_owner = tcx.hir.ty_param_owner(param_id);
318     let param_owner_def_id = tcx.hir.local_def_id(param_owner);
319     let generics = tcx.item_generics(param_owner_def_id);
320     let index = generics.type_param_to_index[&def_id.index];
321     let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id));
322
323     // Don't look for bounds where the type parameter isn't in scope.
324     let parent = if item_def_id == param_owner_def_id {
325         None
326     } else {
327         tcx.item_generics(item_def_id).parent
328     };
329
330     let mut result = parent.map_or(ty::GenericPredicates {
331         parent: None,
332         predicates: vec![]
333     }, |parent| {
334         let icx = ItemCtxt::new(tcx, parent);
335         icx.get_type_parameter_bounds(DUMMY_SP, def_id)
336     });
337
338     let item_node_id = tcx.hir.as_local_node_id(item_def_id).unwrap();
339     let ast_generics = match tcx.hir.get(item_node_id) {
340         NodeTraitItem(item) => {
341             match item.node {
342                 TraitItemKind::Method(ref sig, _) => &sig.generics,
343                 _ => return result
344             }
345         }
346
347         NodeImplItem(item) => {
348             match item.node {
349                 ImplItemKind::Method(ref sig, _) => &sig.generics,
350                 _ => return result
351             }
352         }
353
354         NodeItem(item) => {
355             match item.node {
356                 ItemFn(.., ref generics, _) |
357                 ItemImpl(_, _, ref generics, ..) |
358                 ItemTy(_, ref generics) |
359                 ItemEnum(_, ref generics) |
360                 ItemStruct(_, ref generics) |
361                 ItemUnion(_, ref generics) => generics,
362                 ItemTrait(_, ref generics, ..) => {
363                     // Implied `Self: Trait` and supertrait bounds.
364                     if param_id == item_node_id {
365                         result.predicates.push(ty::TraitRef {
366                             def_id: item_def_id,
367                             substs: Substs::identity_for_item(tcx, item_def_id)
368                         }.to_predicate());
369                     }
370                     generics
371                 }
372                 _ => return result
373             }
374         }
375
376         NodeForeignItem(item) => {
377             match item.node {
378                 ForeignItemFn(_, _, ref generics) => generics,
379                 _ => return result
380             }
381         }
382
383         _ => return result
384     };
385
386     let icx = ItemCtxt::new(tcx, item_def_id);
387     result.predicates.extend(
388         icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty));
389     result
390 }
391
392 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
393     /// Find bounds from hir::Generics. This requires scanning through the
394     /// AST. We do this to avoid having to convert *all* the bounds, which
395     /// would create artificial cycles. Instead we can only convert the
396     /// bounds for a type parameter `X` if `X::Foo` is used.
397     fn type_parameter_bounds_in_generics(&self,
398                                          ast_generics: &hir::Generics,
399                                          param_id: ast::NodeId,
400                                          ty: Ty<'tcx>)
401                                          -> Vec<ty::Predicate<'tcx>>
402     {
403         let from_ty_params =
404             ast_generics.ty_params
405                 .iter()
406                 .filter(|p| p.id == param_id)
407                 .flat_map(|p| p.bounds.iter())
408                 .flat_map(|b| predicates_from_bound(self, ty, b));
409
410         let from_where_clauses =
411             ast_generics.where_clause
412                 .predicates
413                 .iter()
414                 .filter_map(|wp| match *wp {
415                     hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
416                     _ => None
417                 })
418                 .filter(|bp| is_param(self.tcx, &bp.bounded_ty, param_id))
419                 .flat_map(|bp| bp.bounds.iter())
420                 .flat_map(|b| predicates_from_bound(self, ty, b));
421
422         from_ty_params.chain(from_where_clauses).collect()
423     }
424 }
425
426 /// Tests whether this is the AST for a reference to the type
427 /// parameter with id `param_id`. We use this so as to avoid running
428 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
429 /// conversion of the type to avoid inducing unnecessary cycles.
430 fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
431                       ast_ty: &hir::Ty,
432                       param_id: ast::NodeId)
433                       -> bool
434 {
435     if let hir::TyPath(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
436         match path.def {
437             Def::SelfTy(Some(def_id), None) |
438             Def::TyParam(def_id) => {
439                 def_id == tcx.hir.local_def_id(param_id)
440             }
441             _ => false
442         }
443     } else {
444         false
445     }
446 }
447
448 fn ensure_no_ty_param_bounds(tcx: TyCtxt,
449                              span: Span,
450                              generics: &hir::Generics,
451                              thing: &'static str) {
452     let mut warn = false;
453
454     for ty_param in generics.ty_params.iter() {
455         for bound in ty_param.bounds.iter() {
456             match *bound {
457                 hir::TraitTyParamBound(..) => {
458                     warn = true;
459                 }
460                 hir::RegionTyParamBound(..) => { }
461             }
462         }
463     }
464
465     for predicate in generics.where_clause.predicates.iter() {
466         match *predicate {
467             hir::WherePredicate::BoundPredicate(..) => {
468                 warn = true;
469             }
470             hir::WherePredicate::RegionPredicate(..) => { }
471             hir::WherePredicate::EqPredicate(..) => { }
472         }
473     }
474
475     if warn {
476         // According to accepted RFC #XXX, we should
477         // eventually accept these, but it will not be
478         // part of this PR. Still, convert to warning to
479         // make bootstrapping easier.
480         span_warn!(tcx.sess, span, E0122,
481                    "trait bounds are not (yet) enforced \
482                    in {} definitions",
483                    thing);
484     }
485 }
486
487 fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
488     let it = tcx.hir.expect_item(item_id);
489     debug!("convert: item {} with id {}", it.name, it.id);
490     let def_id = tcx.hir.local_def_id(item_id);
491     match it.node {
492         // These don't define types.
493         hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => {
494         }
495         hir::ItemForeignMod(ref foreign_mod) => {
496             for item in &foreign_mod.items {
497                 let def_id = tcx.hir.local_def_id(item.id);
498                 tcx.item_generics(def_id);
499                 tcx.item_type(def_id);
500                 tcx.item_predicates(def_id);
501             }
502         }
503         hir::ItemEnum(ref enum_definition, _) => {
504             tcx.item_generics(def_id);
505             tcx.item_type(def_id);
506             tcx.item_predicates(def_id);
507             convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
508         },
509         hir::ItemDefaultImpl(..) => {
510             tcx.impl_trait_ref(def_id);
511         }
512         hir::ItemImpl(..) => {
513             tcx.item_generics(def_id);
514             tcx.item_type(def_id);
515             tcx.impl_trait_ref(def_id);
516             tcx.item_predicates(def_id);
517         },
518         hir::ItemTrait(..) => {
519             tcx.item_generics(def_id);
520             tcx.lookup_trait_def(def_id);
521             ty::queries::super_predicates::get(tcx, it.span, def_id);
522             tcx.item_predicates(def_id);
523         },
524         hir::ItemStruct(ref struct_def, _) |
525         hir::ItemUnion(ref struct_def, _) => {
526             tcx.item_generics(def_id);
527             tcx.item_type(def_id);
528             tcx.item_predicates(def_id);
529
530             for f in struct_def.fields() {
531                 let def_id = tcx.hir.local_def_id(f.id);
532                 tcx.item_generics(def_id);
533                 tcx.item_type(def_id);
534                 tcx.item_predicates(def_id);
535             }
536
537             if !struct_def.is_struct() {
538                 convert_variant_ctor(tcx, struct_def.id());
539             }
540         },
541         hir::ItemTy(_, ref generics) => {
542             ensure_no_ty_param_bounds(tcx, it.span, generics, "type");
543             tcx.item_generics(def_id);
544             tcx.item_type(def_id);
545             tcx.item_predicates(def_id);
546         },
547         _ => {
548             tcx.item_generics(def_id);
549             tcx.item_type(def_id);
550             tcx.item_predicates(def_id);
551         },
552     }
553 }
554
555 fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: ast::NodeId) {
556     let trait_item = tcx.hir.expect_trait_item(trait_item_id);
557     let def_id = tcx.hir.local_def_id(trait_item.id);
558     tcx.item_generics(def_id);
559
560     match trait_item.node {
561         hir::TraitItemKind::Const(..) |
562         hir::TraitItemKind::Type(_, Some(_)) |
563         hir::TraitItemKind::Method(..) => {
564             tcx.item_type(def_id);
565         }
566
567         hir::TraitItemKind::Type(_, None) => {}
568     };
569
570     tcx.item_predicates(def_id);
571 }
572
573 fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: ast::NodeId) {
574     let def_id = tcx.hir.local_def_id(impl_item_id);
575     tcx.item_generics(def_id);
576     tcx.item_type(def_id);
577     tcx.item_predicates(def_id);
578 }
579
580 fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
581                                   ctor_id: ast::NodeId) {
582     let def_id = tcx.hir.local_def_id(ctor_id);
583     tcx.item_generics(def_id);
584     tcx.item_type(def_id);
585     tcx.item_predicates(def_id);
586 }
587
588 fn evaluate_disr_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
589                                 body: hir::BodyId)
590                                 -> Result<ConstVal<'tcx>, ()> {
591     let e = &tcx.hir.body(body).value;
592     ConstContext::new(tcx, body).eval(e).map_err(|err| {
593         // enum variant evaluation happens before the global constant check
594         // so we need to report the real error
595         report_const_eval_err(tcx, &err, e.span, "enum discriminant");
596     })
597 }
598
599 fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
600                                         def_id: DefId,
601                                         variants: &[hir::Variant]) {
602     let def = tcx.lookup_adt_def(def_id);
603     let repr_type = def.repr.discr_type();
604     let initial = repr_type.initial_discriminant(tcx);
605     let mut prev_discr = None::<ConstInt>;
606
607     // fill the discriminant values and field types
608     for variant in variants {
609         let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr());
610         prev_discr = Some(if let Some(e) = variant.node.disr_expr {
611             let expr_did = tcx.hir.local_def_id(e.node_id);
612             let result = tcx.maps.monomorphic_const_eval.memoize(expr_did, || {
613                 evaluate_disr_expr(tcx, e)
614             });
615
616             match result {
617                 Ok(ConstVal::Integral(x)) => Some(x),
618                 _ => None
619             }
620         } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
621             Some(discr)
622         } else {
623             struct_span_err!(tcx.sess, variant.span, E0370,
624                              "enum discriminant overflowed")
625                 .span_label(variant.span, &format!("overflowed on value after {}",
626                                                    prev_discr.unwrap()))
627                 .note(&format!("explicitly set `{} = {}` if that is desired outcome",
628                                variant.node.name, wrapped_discr))
629                 .emit();
630             None
631         }.unwrap_or(wrapped_discr));
632
633         for f in variant.node.data.fields() {
634             let def_id = tcx.hir.local_def_id(f.id);
635             tcx.item_generics(def_id);
636             tcx.item_type(def_id);
637             tcx.item_predicates(def_id);
638         }
639
640         // Convert the ctor, if any. This also registers the variant as
641         // an item.
642         convert_variant_ctor(tcx, variant.node.data.id());
643     }
644 }
645
646 fn convert_struct_variant<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
647                                     did: DefId,
648                                     name: ast::Name,
649                                     discr: ty::VariantDiscr,
650                                     def: &hir::VariantData)
651                                     -> ty::VariantDef {
652     let mut seen_fields: FxHashMap<ast::Name, Span> = FxHashMap();
653     let node_id = tcx.hir.as_local_node_id(did).unwrap();
654     let fields = def.fields().iter().map(|f| {
655         let fid = tcx.hir.local_def_id(f.id);
656         let dup_span = seen_fields.get(&f.name).cloned();
657         if let Some(prev_span) = dup_span {
658             struct_span_err!(tcx.sess, f.span, E0124,
659                              "field `{}` is already declared",
660                              f.name)
661                 .span_label(f.span, &"field already declared")
662                 .span_label(prev_span, &format!("`{}` first declared here", f.name))
663                 .emit();
664         } else {
665             seen_fields.insert(f.name, f.span);
666         }
667
668         ty::FieldDef {
669             did: fid,
670             name: f.name,
671             vis: ty::Visibility::from_hir(&f.vis, node_id, tcx)
672         }
673     }).collect();
674     ty::VariantDef {
675         did: did,
676         name: name,
677         discr: discr,
678         fields: fields,
679         ctor_kind: CtorKind::from_hir(def),
680     }
681 }
682
683 fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
684                      def_id: DefId)
685                      -> &'tcx ty::AdtDef {
686     use rustc::hir::map::*;
687     use rustc::hir::*;
688
689     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
690     let item = match tcx.hir.get(node_id) {
691         NodeItem(item) => item,
692         _ => bug!()
693     };
694
695     let repr = ReprOptions::new(tcx, def_id);
696     let (kind, variants) = match item.node {
697         ItemEnum(ref def, _) => {
698             let mut distance_from_explicit = 0;
699             (AdtKind::Enum, def.variants.iter().map(|v| {
700                 let did = tcx.hir.local_def_id(v.node.data.id());
701                 let discr = if let Some(e) = v.node.disr_expr {
702                     distance_from_explicit = 0;
703                     ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.node_id))
704                 } else {
705                     ty::VariantDiscr::Relative(distance_from_explicit)
706                 };
707                 distance_from_explicit += 1;
708
709                 convert_struct_variant(tcx, did, v.node.name, discr, &v.node.data)
710             }).collect())
711         }
712         ItemStruct(ref def, _) => {
713             // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
714             let ctor_id = if !def.is_struct() {
715                 Some(tcx.hir.local_def_id(def.id()))
716             } else {
717                 None
718             };
719             (AdtKind::Struct, vec![
720                 convert_struct_variant(tcx, ctor_id.unwrap_or(def_id), item.name,
721                                        ty::VariantDiscr::Relative(0), def)
722             ])
723         }
724         ItemUnion(ref def, _) => {
725             (AdtKind::Union, vec![
726                 convert_struct_variant(tcx, def_id, item.name,
727                                        ty::VariantDiscr::Relative(0), def)
728             ])
729         }
730         _ => bug!()
731     };
732     tcx.alloc_adt_def(def_id, kind, variants, repr)
733 }
734
735 /// Ensures that the super-predicates of the trait with def-id
736 /// trait_def_id are converted and stored. This also ensures that
737 /// the transitive super-predicates are converted;
738 fn super_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
739                               trait_def_id: DefId)
740                               -> ty::GenericPredicates<'tcx> {
741     debug!("super_predicates(trait_def_id={:?})", trait_def_id);
742     let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap();
743
744     let item = match tcx.hir.get(trait_node_id) {
745         hir_map::NodeItem(item) => item,
746         _ => bug!("trait_node_id {} is not an item", trait_node_id)
747     };
748
749     let (generics, bounds) = match item.node {
750         hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
751         _ => span_bug!(item.span,
752                        "super_predicates invoked on non-trait"),
753     };
754
755     let icx = ItemCtxt::new(tcx, trait_def_id);
756
757     // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
758     let self_param_ty = tcx.mk_self_type();
759     let superbounds1 = compute_bounds(&icx,
760                                       self_param_ty,
761                                       bounds,
762                                       SizedByDefault::No,
763                                       item.span);
764
765     let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
766
767     // Convert any explicit superbounds in the where clause,
768     // e.g. `trait Foo where Self : Bar`:
769     let superbounds2 = icx.type_parameter_bounds_in_generics(generics, item.id, self_param_ty);
770
771     // Combine the two lists to form the complete set of superbounds:
772     let superbounds: Vec<_> = superbounds1.into_iter().chain(superbounds2).collect();
773
774     // Now require that immediate supertraits are converted,
775     // which will, in turn, reach indirect supertraits.
776     for bound in superbounds.iter().filter_map(|p| p.to_opt_poly_trait_ref()) {
777         ty::queries::super_predicates::get(tcx, item.span, bound.def_id());
778     }
779
780     ty::GenericPredicates {
781         parent: None,
782         predicates: superbounds
783     }
784 }
785
786 fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
787                        def_id: DefId)
788                        -> &'tcx ty::TraitDef {
789     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
790     let item = tcx.hir.expect_item(node_id);
791
792     let unsafety = match item.node {
793         hir::ItemTrait(unsafety, ..) => unsafety,
794         _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
795     };
796
797     let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
798     if paren_sugar && !tcx.sess.features.borrow().unboxed_closures {
799         let mut err = tcx.sess.struct_span_err(
800             item.span,
801             "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
802              which traits can use parenthetical notation");
803         help!(&mut err,
804             "add `#![feature(unboxed_closures)]` to \
805              the crate attributes to use it");
806         err.emit();
807     }
808
809     let def_path_hash = tcx.def_path_hash(def_id);
810     let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, def_path_hash);
811
812     if tcx.hir.trait_is_auto(def_id) {
813         def.record_has_default_impl();
814     }
815
816     tcx.alloc_trait_def(def)
817 }
818
819 fn generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
820                       def_id: DefId)
821                       -> &'tcx ty::Generics {
822     use rustc::hir::map::*;
823     use rustc::hir::*;
824
825     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
826
827     let node = tcx.hir.get(node_id);
828     let parent_def_id = match node {
829         NodeImplItem(_) |
830         NodeTraitItem(_) |
831         NodeVariant(_) |
832         NodeStructCtor(_) |
833         NodeField(_) => {
834             let parent_id = tcx.hir.get_parent(node_id);
835             Some(tcx.hir.local_def_id(parent_id))
836         }
837         NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
838             Some(tcx.closure_base_def_id(def_id))
839         }
840         NodeTy(&hir::Ty { node: hir::TyImplTrait(..), .. }) => {
841             let mut parent_id = node_id;
842             loop {
843                 match tcx.hir.get(parent_id) {
844                     NodeItem(_) | NodeImplItem(_) | NodeTraitItem(_) => break,
845                     _ => {
846                         parent_id = tcx.hir.get_parent_node(parent_id);
847                     }
848                 }
849             }
850             Some(tcx.hir.local_def_id(parent_id))
851         }
852         _ => None
853     };
854
855     let mut opt_self = None;
856     let mut allow_defaults = false;
857
858     let no_generics = hir::Generics::empty();
859     let ast_generics = match node {
860         NodeTraitItem(item) => {
861             match item.node {
862                 TraitItemKind::Method(ref sig, _) => &sig.generics,
863                 _ => &no_generics
864             }
865         }
866
867         NodeImplItem(item) => {
868             match item.node {
869                 ImplItemKind::Method(ref sig, _) => &sig.generics,
870                 _ => &no_generics
871             }
872         }
873
874         NodeItem(item) => {
875             match item.node {
876                 ItemFn(.., ref generics, _) |
877                 ItemImpl(_, _, ref generics, ..) => generics,
878
879                 ItemTy(_, ref generics) |
880                 ItemEnum(_, ref generics) |
881                 ItemStruct(_, ref generics) |
882                 ItemUnion(_, ref generics) => {
883                     allow_defaults = true;
884                     generics
885                 }
886
887                 ItemTrait(_, ref generics, ..) => {
888                     // Add in the self type parameter.
889                     //
890                     // Something of a hack: use the node id for the trait, also as
891                     // the node id for the Self type parameter.
892                     let param_id = item.id;
893
894                     opt_self = Some(ty::TypeParameterDef {
895                         index: 0,
896                         name: keywords::SelfType.name(),
897                         def_id: tcx.hir.local_def_id(param_id),
898                         has_default: false,
899                         object_lifetime_default: rl::Set1::Empty,
900                         pure_wrt_drop: false,
901                     });
902
903                     allow_defaults = true;
904                     generics
905                 }
906
907                 _ => &no_generics
908             }
909         }
910
911         NodeForeignItem(item) => {
912             match item.node {
913                 ForeignItemStatic(..) => &no_generics,
914                 ForeignItemFn(_, _, ref generics) => generics
915             }
916         }
917
918         _ => &no_generics
919     };
920
921     let has_self = opt_self.is_some();
922     let mut parent_has_self = false;
923     let mut own_start = has_self as u32;
924     let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
925         let generics = tcx.item_generics(def_id);
926         assert_eq!(has_self, false);
927         parent_has_self = generics.has_self;
928         own_start = generics.count() as u32;
929         (generics.parent_regions + generics.regions.len() as u32,
930             generics.parent_types + generics.types.len() as u32)
931     });
932
933     let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
934     let regions = early_lifetimes.enumerate().map(|(i, l)| {
935         let issue_32330 = tcx.named_region_map.issue_32330.get(&l.lifetime.id).cloned();
936         ty::RegionParameterDef {
937             name: l.lifetime.name,
938             index: own_start + i as u32,
939             def_id: tcx.hir.local_def_id(l.lifetime.id),
940             pure_wrt_drop: l.pure_wrt_drop,
941             issue_32330: issue_32330,
942         }
943     }).collect::<Vec<_>>();
944
945     let object_lifetime_defaults =
946         tcx.named_region_map.object_lifetime_defaults.get(&node_id);
947
948     // Now create the real type parameters.
949     let type_start = own_start + regions.len() as u32;
950     let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
951         if p.name == keywords::SelfType.name() {
952             span_bug!(p.span, "`Self` should not be the name of a regular parameter");
953         }
954
955         if !allow_defaults && p.default.is_some() {
956             if !tcx.sess.features.borrow().default_type_parameter_fallback {
957                 tcx.sess.add_lint(
958                     lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
959                     p.id,
960                     p.span,
961                     format!("defaults for type parameters are only allowed in `struct`, \
962                              `enum`, `type`, or `trait` definitions."));
963             }
964         }
965
966         ty::TypeParameterDef {
967             index: type_start + i as u32,
968             name: p.name,
969             def_id: tcx.hir.local_def_id(p.id),
970             has_default: p.default.is_some(),
971             object_lifetime_default:
972                 object_lifetime_defaults.map_or(rl::Set1::Empty, |o| o[i]),
973             pure_wrt_drop: p.pure_wrt_drop,
974         }
975     });
976     let mut types: Vec<_> = opt_self.into_iter().chain(types).collect();
977
978     // provide junk type parameter defs - the only place that
979     // cares about anything but the length is instantiation,
980     // and we don't do that for closures.
981     if let NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) = node {
982         tcx.with_freevars(node_id, |fv| {
983             types.extend(fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
984                 index: type_start + i as u32,
985                 name: Symbol::intern("<upvar>"),
986                 def_id: def_id,
987                 has_default: false,
988                 object_lifetime_default: rl::Set1::Empty,
989                 pure_wrt_drop: false,
990             }));
991         });
992     }
993
994     let mut type_param_to_index = BTreeMap::new();
995     for param in &types {
996         type_param_to_index.insert(param.def_id.index, param.index);
997     }
998
999     tcx.alloc_generics(ty::Generics {
1000         parent: parent_def_id,
1001         parent_regions: parent_regions,
1002         parent_types: parent_types,
1003         regions: regions,
1004         types: types,
1005         type_param_to_index: type_param_to_index,
1006         has_self: has_self || parent_has_self
1007     })
1008 }
1009
1010 fn ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1011                 def_id: DefId)
1012                 -> Ty<'tcx> {
1013     use rustc::hir::map::*;
1014     use rustc::hir::*;
1015
1016     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1017
1018     let icx = ItemCtxt::new(tcx, def_id);
1019
1020     match tcx.hir.get(node_id) {
1021         NodeTraitItem(item) => {
1022             match item.node {
1023                 TraitItemKind::Method(ref sig, _) => {
1024                     let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
1025                     let substs = Substs::identity_for_item(tcx, def_id);
1026                     tcx.mk_fn_def(def_id, substs, fty)
1027                 }
1028                 TraitItemKind::Const(ref ty, _) |
1029                 TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
1030                 TraitItemKind::Type(_, None) => {
1031                     span_bug!(item.span, "associated type missing default");
1032                 }
1033             }
1034         }
1035
1036         NodeImplItem(item) => {
1037             match item.node {
1038                 ImplItemKind::Method(ref sig, _) => {
1039                     let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
1040                     let substs = Substs::identity_for_item(tcx, def_id);
1041                     tcx.mk_fn_def(def_id, substs, fty)
1042                 }
1043                 ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
1044                 ImplItemKind::Type(ref ty) => {
1045                     if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() {
1046                         span_err!(tcx.sess, item.span, E0202,
1047                                   "associated types are not allowed in inherent impls");
1048                     }
1049
1050                     icx.to_ty(ty)
1051                 }
1052             }
1053         }
1054
1055         NodeItem(item) => {
1056             match item.node {
1057                 ItemStatic(ref t, ..) | ItemConst(ref t, _) |
1058                 ItemTy(ref t, _) | ItemImpl(.., ref t, _) => {
1059                     icx.to_ty(t)
1060                 }
1061                 ItemFn(ref decl, unsafety, _, abi, _, _) => {
1062                     let tofd = AstConv::ty_of_fn(&icx, unsafety, abi, &decl);
1063                     let substs = Substs::identity_for_item(tcx, def_id);
1064                     tcx.mk_fn_def(def_id, substs, tofd)
1065                 }
1066                 ItemEnum(..) |
1067                 ItemStruct(..) |
1068                 ItemUnion(..) => {
1069                     let def = tcx.lookup_adt_def(def_id);
1070                     let substs = Substs::identity_for_item(tcx, def_id);
1071                     tcx.mk_adt(def, substs)
1072                 }
1073                 ItemDefaultImpl(..) |
1074                 ItemTrait(..) |
1075                 ItemMod(..) |
1076                 ItemForeignMod(..) |
1077                 ItemExternCrate(..) |
1078                 ItemUse(..) => {
1079                     span_bug!(
1080                         item.span,
1081                         "compute_type_of_item: unexpected item type: {:?}",
1082                         item.node);
1083                 }
1084             }
1085         }
1086
1087         NodeForeignItem(foreign_item) => {
1088             let abi = tcx.hir.get_foreign_abi(node_id);
1089
1090             match foreign_item.node {
1091                 ForeignItemFn(ref fn_decl, _, _) => {
1092                     compute_type_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
1093                 }
1094                 ForeignItemStatic(ref t, _) => icx.to_ty(t)
1095             }
1096         }
1097
1098         NodeStructCtor(&ref def) |
1099         NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => {
1100             let ty = tcx.item_type(tcx.hir.get_parent_did(node_id));
1101             match *def {
1102                 VariantData::Unit(..) | VariantData::Struct(..) => ty,
1103                 VariantData::Tuple(ref fields, _) => {
1104                     let inputs = fields.iter().map(|f| {
1105                         tcx.item_type(tcx.hir.local_def_id(f.id))
1106                     });
1107                     let substs = Substs::identity_for_item(tcx, def_id);
1108                     tcx.mk_fn_def(def_id, substs, ty::Binder(tcx.mk_fn_sig(
1109                         inputs,
1110                         ty,
1111                         false,
1112                         hir::Unsafety::Normal,
1113                         abi::Abi::Rust
1114                     )))
1115                 }
1116             }
1117         }
1118
1119         NodeField(field) => icx.to_ty(&field.ty),
1120
1121         NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
1122             tcx.mk_closure(def_id, Substs::for_item(
1123                 tcx, def_id,
1124                 |def, _| {
1125                     let region = def.to_early_bound_region_data();
1126                     tcx.mk_region(ty::ReEarlyBound(region))
1127                 },
1128                 |def, _| tcx.mk_param_from_def(def)
1129             ))
1130         }
1131
1132         NodeExpr(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
1133             NodeTy(&hir::Ty { node: TyArray(_, body), .. }) |
1134             NodeTy(&hir::Ty { node: TyTypeof(body), .. }) |
1135             NodeExpr(&hir::Expr { node: ExprRepeat(_, body), .. })
1136                 if body.node_id == node_id => tcx.types.usize,
1137
1138             NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(e), .. }, .. })
1139                 if e.node_id == node_id => {
1140                     tcx.lookup_adt_def(tcx.hir.get_parent_did(node_id))
1141                         .repr.discr_type().to_ty(tcx)
1142                 }
1143
1144             x => {
1145                 bug!("unexpected expr parent in type_of_def_id(): {:?}", x);
1146             }
1147         },
1148
1149         NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => {
1150             icx.to_ty(ty)
1151         }
1152
1153         NodeTy(&hir::Ty { node: TyImplTrait(..), .. }) => {
1154             let owner = tcx.hir.get_parent_did(node_id);
1155             tcx.item_tables(owner).node_id_to_type(node_id)
1156         }
1157
1158         x => {
1159             bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
1160         }
1161     }
1162 }
1163
1164 fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1165                             def_id: DefId)
1166                             -> Option<ty::TraitRef<'tcx>> {
1167     let icx = ItemCtxt::new(tcx, def_id);
1168
1169     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1170     match tcx.hir.expect_item(node_id).node {
1171         hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
1172             Some(AstConv::instantiate_mono_trait_ref(&icx,
1173                                                      ast_trait_ref,
1174                                                      tcx.mk_self_type()))
1175         }
1176         hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
1177             opt_trait_ref.as_ref().map(|ast_trait_ref| {
1178                 let selfty = tcx.item_type(def_id);
1179                 AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1180             })
1181         }
1182         _ => bug!()
1183     }
1184 }
1185
1186 // Is it marked with ?Sized
1187 fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1188                                 ast_bounds: &[hir::TyParamBound],
1189                                 span: Span) -> bool
1190 {
1191     let tcx = astconv.tcx();
1192
1193     // Try to find an unbound in bounds.
1194     let mut unbound = None;
1195     for ab in ast_bounds {
1196         if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab  {
1197             if unbound.is_none() {
1198                 unbound = Some(ptr.trait_ref.clone());
1199             } else {
1200                 span_err!(tcx.sess, span, E0203,
1201                           "type parameter has more than one relaxed default \
1202                                                 bound, only one is supported");
1203             }
1204         }
1205     }
1206
1207     let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1208     match unbound {
1209         Some(ref tpb) => {
1210             // FIXME(#8559) currently requires the unbound to be built-in.
1211             if let Ok(kind_id) = kind_id {
1212                 if tpb.path.def != Def::Trait(kind_id) {
1213                     tcx.sess.span_warn(span,
1214                                        "default bound relaxed for a type parameter, but \
1215                                        this does nothing because the given bound is not \
1216                                        a default. Only `?Sized` is supported");
1217                 }
1218             }
1219         }
1220         _ if kind_id.is_ok() => {
1221             return false;
1222         }
1223         // No lang item for Sized, so we can't add it as a bound.
1224         None => {}
1225     }
1226
1227     true
1228 }
1229
1230 /// Returns the early-bound lifetimes declared in this generics
1231 /// listing.  For anything other than fns/methods, this is just all
1232 /// the lifetimes that are declared. For fns or methods, we have to
1233 /// screen out those that do not appear in any where-clauses etc using
1234 /// `resolve_lifetime::early_bound_lifetimes`.
1235 fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1236     tcx: TyCtxt<'a, 'tcx, 'tcx>,
1237     ast_generics: &'a hir::Generics)
1238     -> impl Iterator<Item=&'a hir::LifetimeDef>
1239 {
1240     ast_generics
1241         .lifetimes
1242         .iter()
1243         .filter(move |l| !tcx.named_region_map.late_bound.contains(&l.lifetime.id))
1244 }
1245
1246 fn predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1247                         def_id: DefId)
1248                         -> ty::GenericPredicates<'tcx> {
1249     use rustc::hir::map::*;
1250     use rustc::hir::*;
1251
1252     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1253     let node = tcx.hir.get(node_id);
1254
1255     let mut is_trait = None;
1256
1257     let icx = ItemCtxt::new(tcx, def_id);
1258     let no_generics = hir::Generics::empty();
1259     let ast_generics = match node {
1260         NodeTraitItem(item) => {
1261             match item.node {
1262                 TraitItemKind::Method(ref sig, _) => &sig.generics,
1263                 _ => &no_generics
1264             }
1265         }
1266
1267         NodeImplItem(item) => {
1268             match item.node {
1269                 ImplItemKind::Method(ref sig, _) => &sig.generics,
1270                 _ => &no_generics
1271             }
1272         }
1273
1274         NodeItem(item) => {
1275             match item.node {
1276                 ItemFn(.., ref generics, _) |
1277                 ItemImpl(_, _, ref generics, ..) |
1278                 ItemTy(_, ref generics) |
1279                 ItemEnum(_, ref generics) |
1280                 ItemStruct(_, ref generics) |
1281                 ItemUnion(_, ref generics) => {
1282                     generics
1283                 }
1284
1285                 ItemTrait(_, ref generics, .., ref items) => {
1286                     is_trait = Some((ty::TraitRef {
1287                         def_id: def_id,
1288                         substs: Substs::identity_for_item(tcx, def_id)
1289                     }, items));
1290                     generics
1291                 }
1292
1293                 _ => &no_generics
1294             }
1295         }
1296
1297         NodeForeignItem(item) => {
1298             match item.node {
1299                 ForeignItemStatic(..) => &no_generics,
1300                 ForeignItemFn(_, _, ref generics) => generics
1301             }
1302         }
1303
1304         NodeTy(&Ty { node: TyImplTrait(ref bounds), span, .. }) => {
1305             let substs = Substs::identity_for_item(tcx, def_id);
1306             let anon_ty = tcx.mk_anon(def_id, substs);
1307
1308             // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
1309             let bounds = compute_bounds(&icx, anon_ty, bounds,
1310                                         SizedByDefault::Yes,
1311                                         span);
1312             return ty::GenericPredicates {
1313                 parent: None,
1314                 predicates: bounds.predicates(tcx, anon_ty)
1315             };
1316         }
1317
1318         _ => &no_generics
1319     };
1320
1321     let generics = tcx.item_generics(def_id);
1322     let parent_count = generics.parent_count() as u32;
1323     let has_own_self = generics.has_self && parent_count == 0;
1324
1325     let mut predicates = vec![];
1326
1327     // Below we'll consider the bounds on the type parameters (including `Self`)
1328     // and the explicit where-clauses, but to get the full set of predicates
1329     // on a trait we need to add in the supertrait bounds and bounds found on
1330     // associated types.
1331     if let Some((trait_ref, _)) = is_trait {
1332         predicates = tcx.item_super_predicates(def_id).predicates;
1333
1334         // Add in a predicate that `Self:Trait` (where `Trait` is the
1335         // current trait).  This is needed for builtin bounds.
1336         predicates.push(trait_ref.to_poly_trait_ref().to_predicate());
1337     }
1338
1339     // Collect the region predicates that were declared inline as
1340     // well. In the case of parameters declared on a fn or method, we
1341     // have to be careful to only iterate over early-bound regions.
1342     let mut index = parent_count + has_own_self as u32;
1343     for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
1344         let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
1345             index: index,
1346             name: param.lifetime.name
1347         }));
1348         index += 1;
1349
1350         for bound in &param.bounds {
1351             let bound_region = AstConv::ast_region_to_region(&icx, bound, None);
1352             let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1353             predicates.push(outlives.to_predicate());
1354         }
1355     }
1356
1357     // Collect the predicates that were written inline by the user on each
1358     // type parameter (e.g., `<T:Foo>`).
1359     for param in &ast_generics.ty_params {
1360         let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx);
1361         index += 1;
1362
1363         let bounds = compute_bounds(&icx,
1364                                     param_ty,
1365                                     &param.bounds,
1366                                     SizedByDefault::Yes,
1367                                     param.span);
1368         predicates.extend(bounds.predicates(tcx, param_ty));
1369     }
1370
1371     // Add in the bounds that appear in the where-clause
1372     let where_clause = &ast_generics.where_clause;
1373     for predicate in &where_clause.predicates {
1374         match predicate {
1375             &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1376                 let ty = icx.to_ty(&bound_pred.bounded_ty);
1377
1378                 for bound in bound_pred.bounds.iter() {
1379                     match bound {
1380                         &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1381                             let mut projections = Vec::new();
1382
1383                             let trait_ref =
1384                                 AstConv::instantiate_poly_trait_ref(&icx,
1385                                                                     poly_trait_ref,
1386                                                                     ty,
1387                                                                     &mut projections);
1388
1389                             predicates.push(trait_ref.to_predicate());
1390
1391                             for projection in &projections {
1392                                 predicates.push(projection.to_predicate());
1393                             }
1394                         }
1395
1396                         &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1397                             let region = AstConv::ast_region_to_region(&icx,
1398                                                                        lifetime,
1399                                                                        None);
1400                             let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1401                             predicates.push(ty::Predicate::TypeOutlives(pred))
1402                         }
1403                     }
1404                 }
1405             }
1406
1407             &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1408                 let r1 = AstConv::ast_region_to_region(&icx, &region_pred.lifetime, None);
1409                 for bound in &region_pred.bounds {
1410                     let r2 = AstConv::ast_region_to_region(&icx, bound, None);
1411                     let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1412                     predicates.push(ty::Predicate::RegionOutlives(pred))
1413                 }
1414             }
1415
1416             &hir::WherePredicate::EqPredicate(..) => {
1417                 // FIXME(#20041)
1418             }
1419         }
1420     }
1421
1422     // Add predicates from associated type bounds.
1423     if let Some((self_trait_ref, trait_items)) = is_trait {
1424         predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
1425             let trait_item = tcx.hir.trait_item(trait_item_ref.id);
1426             let bounds = match trait_item.node {
1427                 hir::TraitItemKind::Type(ref bounds, _) => bounds,
1428                 _ => {
1429                     return vec![].into_iter();
1430                 }
1431             };
1432
1433             let assoc_ty = tcx.mk_projection(self_trait_ref, trait_item.name);
1434
1435             let bounds = compute_bounds(&ItemCtxt::new(tcx, def_id),
1436                                         assoc_ty,
1437                                         bounds,
1438                                         SizedByDefault::Yes,
1439                                         trait_item.span);
1440
1441             bounds.predicates(tcx, assoc_ty).into_iter()
1442         }))
1443     }
1444
1445     // Subtle: before we store the predicates into the tcx, we
1446     // sort them so that predicates like `T: Foo<Item=U>` come
1447     // before uses of `U`.  This avoids false ambiguity errors
1448     // in trait checking. See `setup_constraining_predicates`
1449     // for details.
1450     if let NodeItem(&Item { node: ItemImpl(..), .. }) = node {
1451         let self_ty = tcx.item_type(def_id);
1452         let trait_ref = tcx.impl_trait_ref(def_id);
1453         ctp::setup_constraining_predicates(&mut predicates,
1454                                            trait_ref,
1455                                            &mut ctp::parameters_for_impl(self_ty, trait_ref));
1456     }
1457
1458     ty::GenericPredicates {
1459         parent: generics.parent,
1460         predicates: predicates
1461     }
1462 }
1463
1464 pub enum SizedByDefault { Yes, No, }
1465
1466 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
1467 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1468 /// built-in trait (formerly known as kind): Send.
1469 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1470                                         param_ty: ty::Ty<'tcx>,
1471                                         ast_bounds: &[hir::TyParamBound],
1472                                         sized_by_default: SizedByDefault,
1473                                         span: Span)
1474                                         -> Bounds<'tcx>
1475 {
1476     let mut region_bounds = vec![];
1477     let mut trait_bounds = vec![];
1478     for ast_bound in ast_bounds {
1479         match *ast_bound {
1480             hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
1481                 trait_bounds.push(b);
1482             }
1483             hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
1484             hir::RegionTyParamBound(ref l) => {
1485                 region_bounds.push(l);
1486             }
1487         }
1488     }
1489
1490     let mut projection_bounds = vec![];
1491
1492     let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
1493         astconv.instantiate_poly_trait_ref(bound,
1494                                            param_ty,
1495                                            &mut projection_bounds)
1496     }).collect();
1497
1498     let region_bounds = region_bounds.into_iter().map(|r| {
1499         astconv.ast_region_to_region(r, None)
1500     }).collect();
1501
1502     trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
1503
1504     let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
1505         !is_unsized(astconv, ast_bounds, span)
1506     } else {
1507         false
1508     };
1509
1510     Bounds {
1511         region_bounds: region_bounds,
1512         implicitly_sized: implicitly_sized,
1513         trait_bounds: trait_bounds,
1514         projection_bounds: projection_bounds,
1515     }
1516 }
1517
1518 /// Converts a specific TyParamBound from the AST into a set of
1519 /// predicates that apply to the self-type. A vector is returned
1520 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
1521 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
1522 /// and `<T as Bar>::X == i32`).
1523 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
1524                                param_ty: Ty<'tcx>,
1525                                bound: &hir::TyParamBound)
1526                                -> Vec<ty::Predicate<'tcx>>
1527 {
1528     match *bound {
1529         hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
1530             let mut projections = Vec::new();
1531             let pred = astconv.instantiate_poly_trait_ref(tr,
1532                                                           param_ty,
1533                                                           &mut projections);
1534             projections.into_iter()
1535                        .map(|p| p.to_predicate())
1536                        .chain(Some(pred.to_predicate()))
1537                        .collect()
1538         }
1539         hir::RegionTyParamBound(ref lifetime) => {
1540             let region = astconv.ast_region_to_region(lifetime, None);
1541             let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
1542             vec![ty::Predicate::TypeOutlives(pred)]
1543         }
1544         hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
1545             Vec::new()
1546         }
1547     }
1548 }
1549
1550 fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
1551     tcx: TyCtxt<'a, 'tcx, 'tcx>,
1552     def_id: DefId,
1553     decl: &hir::FnDecl,
1554     abi: abi::Abi)
1555     -> Ty<'tcx>
1556 {
1557     let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl);
1558
1559     // feature gate SIMD types in FFI, since I (huonw) am not sure the
1560     // ABIs are handled at all correctly.
1561     if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic
1562             && !tcx.sess.features.borrow().simd_ffi {
1563         let check = |ast_ty: &hir::Ty, ty: ty::Ty| {
1564             if ty.is_simd() {
1565                 tcx.sess.struct_span_err(ast_ty.span,
1566                               &format!("use of SIMD type `{}` in FFI is highly experimental and \
1567                                         may result in invalid code",
1568                                        tcx.hir.node_to_pretty_string(ast_ty.id)))
1569                     .help("add #![feature(simd_ffi)] to the crate attributes to enable")
1570                     .emit();
1571             }
1572         };
1573         for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
1574             check(&input, ty)
1575         }
1576         if let hir::Return(ref ty) = decl.output {
1577             check(&ty, *fty.output().skip_binder())
1578         }
1579     }
1580
1581     let substs = Substs::identity_for_item(tcx, def_id);
1582     tcx.mk_fn_def(def_id, substs, fty)
1583 }