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