]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/astconv.rs
Auto merge of #44278 - Binero:master, r=BurntSushi
[rust.git] / src / librustc_typeck / astconv.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 //! Conversion from AST representation of types to the ty.rs
12 //! representation.  The main routine here is `ast_ty_to_ty()`: each use
13 //! is parameterized by an instance of `AstConv`.
14
15 use rustc::middle::const_val::ConstVal;
16 use rustc_data_structures::accumulate_vec::AccumulateVec;
17 use hir;
18 use hir::def::Def;
19 use hir::def_id::DefId;
20 use middle::resolve_lifetime as rl;
21 use rustc::ty::subst::{Kind, Subst, Substs};
22 use rustc::traits;
23 use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
24 use rustc::ty::wf::object_region_bounds;
25 use rustc_back::slice;
26 use require_c_abi_if_variadic;
27 use util::common::ErrorReported;
28 use util::nodemap::FxHashSet;
29
30 use std::iter;
31 use syntax::{abi, ast};
32 use syntax::feature_gate::{GateIssue, emit_feature_err};
33 use syntax_pos::Span;
34
35 pub trait AstConv<'gcx, 'tcx> {
36     fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
37
38     /// Returns the set of bounds in scope for the type parameter with
39     /// the given id.
40     fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
41                                  -> ty::GenericPredicates<'tcx>;
42
43     /// What lifetime should we use when a lifetime is omitted (and not elided)?
44     fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>)
45                 -> Option<ty::Region<'tcx>>;
46
47     /// What type should we use when a type is omitted?
48     fn ty_infer(&self, span: Span) -> Ty<'tcx>;
49
50     /// Same as ty_infer, but with a known type parameter definition.
51     fn ty_infer_for_def(&self,
52                         _def: &ty::TypeParameterDef,
53                         _substs: &[Kind<'tcx>],
54                         span: Span) -> Ty<'tcx> {
55         self.ty_infer(span)
56     }
57
58     /// Projecting an associated type from a (potentially)
59     /// higher-ranked trait reference is more complicated, because of
60     /// the possibility of late-bound regions appearing in the
61     /// associated type binding. This is not legal in function
62     /// signatures for that reason. In a function body, we can always
63     /// handle it because we can use inference variables to remove the
64     /// late-bound regions.
65     fn projected_ty_from_poly_trait_ref(&self,
66                                         span: Span,
67                                         item_def_id: DefId,
68                                         poly_trait_ref: ty::PolyTraitRef<'tcx>)
69                                         -> Ty<'tcx>;
70
71     /// Normalize an associated type coming from the user.
72     fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
73
74     /// Invoked when we encounter an error from some prior pass
75     /// (e.g. resolve) that is translated into a ty-error. This is
76     /// used to help suppress derived errors typeck might otherwise
77     /// report.
78     fn set_tainted_by_errors(&self);
79
80     fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
81 }
82
83 struct ConvertedBinding<'tcx> {
84     item_name: ast::Name,
85     ty: Ty<'tcx>,
86     span: Span,
87 }
88
89 /// Dummy type used for the `Self` of a `TraitRef` created for converting
90 /// a trait object, and which gets removed in `ExistentialTraitRef`.
91 /// This type must not appear anywhere in other converted types.
92 const TRAIT_OBJECT_DUMMY_SELF: ty::TypeVariants<'static> = ty::TyInfer(ty::FreshTy(0));
93
94 impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
95     pub fn ast_region_to_region(&self,
96         lifetime: &hir::Lifetime,
97         def: Option<&ty::RegionParameterDef>)
98         -> ty::Region<'tcx>
99     {
100         let tcx = self.tcx();
101         let lifetime_name = |def_id| {
102             tcx.hir.name(tcx.hir.as_local_node_id(def_id).unwrap())
103         };
104
105         let hir_id = tcx.hir.node_to_hir_id(lifetime.id);
106         let r = match tcx.named_region(hir_id) {
107             Some(rl::Region::Static) => {
108                 tcx.types.re_static
109             }
110
111             Some(rl::Region::LateBound(debruijn, id)) => {
112                 let name = lifetime_name(id);
113                 tcx.mk_region(ty::ReLateBound(debruijn,
114                     ty::BrNamed(id, name)))
115             }
116
117             Some(rl::Region::LateBoundAnon(debruijn, index)) => {
118                 tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(index)))
119             }
120
121             Some(rl::Region::EarlyBound(index, id)) => {
122                 let name = lifetime_name(id);
123                 tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
124                     def_id: id,
125                     index,
126                     name,
127                 }))
128             }
129
130             Some(rl::Region::Free(scope, id)) => {
131                 let name = lifetime_name(id);
132                 tcx.mk_region(ty::ReFree(ty::FreeRegion {
133                     scope,
134                     bound_region: ty::BrNamed(id, name)
135                 }))
136
137                     // (*) -- not late-bound, won't change
138             }
139
140             None => {
141                 self.re_infer(lifetime.span, def).expect("unelided lifetime in signature")
142             }
143         };
144
145         debug!("ast_region_to_region(lifetime={:?}) yields {:?}",
146                 lifetime,
147                 r);
148
149         r
150     }
151
152     /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
153     /// returns an appropriate set of substitutions for this particular reference to `I`.
154     pub fn ast_path_substs_for_ty(&self,
155         span: Span,
156         def_id: DefId,
157         item_segment: &hir::PathSegment)
158         -> &'tcx Substs<'tcx>
159     {
160
161         let (substs, assoc_bindings) =
162             item_segment.with_parameters(|parameters| {
163                 self.create_substs_for_ast_path(
164                     span,
165                     def_id,
166                     parameters,
167                     item_segment.infer_types,
168                     None)
169             });
170
171         assoc_bindings.first().map(|b| self.prohibit_projection(b.span));
172
173         substs
174     }
175
176     /// Given the type/region arguments provided to some path (along with
177     /// an implicit Self, if this is a trait reference) returns the complete
178     /// set of substitutions. This may involve applying defaulted type parameters.
179     ///
180     /// Note that the type listing given here is *exactly* what the user provided.
181     fn create_substs_for_ast_path(&self,
182         span: Span,
183         def_id: DefId,
184         parameters: &hir::PathParameters,
185         infer_types: bool,
186         self_ty: Option<Ty<'tcx>>)
187         -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
188     {
189         let tcx = self.tcx();
190
191         debug!("create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
192                parameters={:?})",
193                def_id, self_ty, parameters);
194
195         // If the type is parameterized by this region, then replace this
196         // region with the current anon region binding (in other words,
197         // whatever & would get replaced with).
198         let decl_generics = tcx.generics_of(def_id);
199         let num_types_provided = parameters.types.len();
200         let expected_num_region_params = decl_generics.regions.len();
201         let supplied_num_region_params = parameters.lifetimes.len();
202         if expected_num_region_params != supplied_num_region_params {
203             report_lifetime_number_error(tcx, span,
204                                          supplied_num_region_params,
205                                          expected_num_region_params);
206         }
207
208         // If a self-type was declared, one should be provided.
209         assert_eq!(decl_generics.has_self, self_ty.is_some());
210
211         // Check the number of type parameters supplied by the user.
212         let ty_param_defs = &decl_generics.types[self_ty.is_some() as usize..];
213         if !infer_types || num_types_provided > ty_param_defs.len() {
214             check_type_argument_count(tcx, span, num_types_provided, ty_param_defs);
215         }
216
217         let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
218         let default_needs_object_self = |p: &ty::TypeParameterDef| {
219             if is_object && p.has_default {
220                 if tcx.at(span).type_of(p.def_id).has_self_ty() {
221                     // There is no suitable inference default for a type parameter
222                     // that references self, in an object type.
223                     return true;
224                 }
225             }
226
227             false
228         };
229
230         let substs = Substs::for_item(tcx, def_id, |def, _| {
231             let i = def.index as usize - self_ty.is_some() as usize;
232             if let Some(lifetime) = parameters.lifetimes.get(i) {
233                 self.ast_region_to_region(lifetime, Some(def))
234             } else {
235                 tcx.types.re_static
236             }
237         }, |def, substs| {
238             let i = def.index as usize;
239
240             // Handle Self first, so we can adjust the index to match the AST.
241             if let (0, Some(ty)) = (i, self_ty) {
242                 return ty;
243             }
244
245             let i = i - self_ty.is_some() as usize - decl_generics.regions.len();
246             if i < num_types_provided {
247                 // A provided type parameter.
248                 self.ast_ty_to_ty(&parameters.types[i])
249             } else if infer_types {
250                 // No type parameters were provided, we can infer all.
251                 let ty_var = if !default_needs_object_self(def) {
252                     self.ty_infer_for_def(def, substs, span)
253                 } else {
254                     self.ty_infer(span)
255                 };
256                 ty_var
257             } else if def.has_default {
258                 // No type parameter provided, but a default exists.
259
260                 // If we are converting an object type, then the
261                 // `Self` parameter is unknown. However, some of the
262                 // other type parameters may reference `Self` in their
263                 // defaults. This will lead to an ICE if we are not
264                 // careful!
265                 if default_needs_object_self(def) {
266                     struct_span_err!(tcx.sess, span, E0393,
267                                      "the type parameter `{}` must be explicitly specified",
268                                      def.name)
269                         .span_label(span, format!("missing reference to `{}`", def.name))
270                         .note(&format!("because of the default `Self` reference, \
271                                         type parameters must be specified on object types"))
272                         .emit();
273                     tcx.types.err
274                 } else {
275                     // This is a default type parameter.
276                     self.normalize_ty(
277                         span,
278                         tcx.at(span).type_of(def.def_id)
279                             .subst_spanned(tcx, substs, Some(span))
280                     )
281                 }
282             } else {
283                 // We've already errored above about the mismatch.
284                 tcx.types.err
285             }
286         });
287
288         let assoc_bindings = parameters.bindings.iter().map(|binding| {
289             ConvertedBinding {
290                 item_name: binding.name,
291                 ty: self.ast_ty_to_ty(&binding.ty),
292                 span: binding.span,
293             }
294         }).collect();
295
296         debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}) -> {:?}",
297                decl_generics, self_ty, substs);
298
299         (substs, assoc_bindings)
300     }
301
302     /// Instantiates the path for the given trait reference, assuming that it's
303     /// bound to a valid trait type. Returns the def_id for the defining trait.
304     /// Fails if the type is a type other than a trait type.
305     ///
306     /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
307     /// are disallowed. Otherwise, they are pushed onto the vector given.
308     pub fn instantiate_mono_trait_ref(&self,
309         trait_ref: &hir::TraitRef,
310         self_ty: Ty<'tcx>)
311         -> ty::TraitRef<'tcx>
312     {
313         self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
314
315         let trait_def_id = self.trait_def_id(trait_ref);
316         self.ast_path_to_mono_trait_ref(trait_ref.path.span,
317                                         trait_def_id,
318                                         self_ty,
319                                         trait_ref.path.segments.last().unwrap())
320     }
321
322     fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
323         let path = &trait_ref.path;
324         match path.def {
325             Def::Trait(trait_def_id) => trait_def_id,
326             Def::Err => {
327                 self.tcx().sess.fatal("cannot continue compilation due to previous error");
328             }
329             _ => {
330                 span_fatal!(self.tcx().sess, path.span, E0245, "`{}` is not a trait",
331                             self.tcx().hir.node_to_pretty_string(trait_ref.ref_id));
332             }
333         }
334     }
335
336     pub fn instantiate_poly_trait_ref(&self,
337         ast_trait_ref: &hir::PolyTraitRef,
338         self_ty: Ty<'tcx>,
339         poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
340         -> ty::PolyTraitRef<'tcx>
341     {
342         let trait_ref = &ast_trait_ref.trait_ref;
343         let trait_def_id = self.trait_def_id(trait_ref);
344
345         debug!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
346
347         self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
348
349         let (substs, assoc_bindings) =
350             self.create_substs_for_ast_trait_ref(trait_ref.path.span,
351                                                  trait_def_id,
352                                                  self_ty,
353                                                  trait_ref.path.segments.last().unwrap());
354         let poly_trait_ref = ty::Binder(ty::TraitRef::new(trait_def_id, substs));
355
356         poly_projections.extend(assoc_bindings.iter().filter_map(|binding| {
357             // specify type to assert that error was already reported in Err case:
358             let predicate: Result<_, ErrorReported> =
359                 self.ast_type_binding_to_poly_projection_predicate(trait_ref.ref_id,
360                                                                    poly_trait_ref,
361                                                                    binding);
362             predicate.ok() // ok to ignore Err() because ErrorReported (see above)
363         }));
364
365         debug!("ast_path_to_poly_trait_ref({:?}, projections={:?}) -> {:?}",
366                trait_ref, poly_projections, poly_trait_ref);
367         poly_trait_ref
368     }
369
370     fn ast_path_to_mono_trait_ref(&self,
371                                   span: Span,
372                                   trait_def_id: DefId,
373                                   self_ty: Ty<'tcx>,
374                                   trait_segment: &hir::PathSegment)
375                                   -> ty::TraitRef<'tcx>
376     {
377         let (substs, assoc_bindings) =
378             self.create_substs_for_ast_trait_ref(span,
379                                                  trait_def_id,
380                                                  self_ty,
381                                                  trait_segment);
382         assoc_bindings.first().map(|b| self.prohibit_projection(b.span));
383         ty::TraitRef::new(trait_def_id, substs)
384     }
385
386     fn create_substs_for_ast_trait_ref(&self,
387                                        span: Span,
388                                        trait_def_id: DefId,
389                                        self_ty: Ty<'tcx>,
390                                        trait_segment: &hir::PathSegment)
391                                        -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
392     {
393         debug!("create_substs_for_ast_trait_ref(trait_segment={:?})",
394                trait_segment);
395
396         let trait_def = self.tcx().trait_def(trait_def_id);
397
398         if !self.tcx().sess.features.borrow().unboxed_closures &&
399            trait_segment.with_parameters(|p| p.parenthesized) != trait_def.paren_sugar {
400             // For now, require that parenthetical notation be used only with `Fn()` etc.
401             let msg = if trait_def.paren_sugar {
402                 "the precise format of `Fn`-family traits' type parameters is subject to change. \
403                  Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead"
404             } else {
405                 "parenthetical notation is only stable when used with `Fn`-family traits"
406             };
407             emit_feature_err(&self.tcx().sess.parse_sess, "unboxed_closures",
408                              span, GateIssue::Language, msg);
409         }
410
411         trait_segment.with_parameters(|parameters| {
412             self.create_substs_for_ast_path(span,
413                                             trait_def_id,
414                                             parameters,
415                                             trait_segment.infer_types,
416                                             Some(self_ty))
417         })
418     }
419
420     fn trait_defines_associated_type_named(&self,
421                                            trait_def_id: DefId,
422                                            assoc_name: ast::Name)
423                                            -> bool
424     {
425         self.tcx().associated_items(trait_def_id).any(|item| {
426             item.kind == ty::AssociatedKind::Type && item.name == assoc_name
427         })
428     }
429
430     fn ast_type_binding_to_poly_projection_predicate(
431         &self,
432         _path_id: ast::NodeId,
433         trait_ref: ty::PolyTraitRef<'tcx>,
434         binding: &ConvertedBinding<'tcx>)
435         -> Result<ty::PolyProjectionPredicate<'tcx>, ErrorReported>
436     {
437         let tcx = self.tcx();
438
439         // Given something like `U : SomeTrait<T=X>`, we want to produce a
440         // predicate like `<U as SomeTrait>::T = X`. This is somewhat
441         // subtle in the event that `T` is defined in a supertrait of
442         // `SomeTrait`, because in that case we need to upcast.
443         //
444         // That is, consider this case:
445         //
446         // ```
447         // trait SubTrait : SuperTrait<int> { }
448         // trait SuperTrait<A> { type T; }
449         //
450         // ... B : SubTrait<T=foo> ...
451         // ```
452         //
453         // We want to produce `<B as SuperTrait<int>>::T == foo`.
454
455         // Find any late-bound regions declared in `ty` that are not
456         // declared in the trait-ref. These are not wellformed.
457         //
458         // Example:
459         //
460         //     for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
461         //     for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
462         let late_bound_in_trait_ref = tcx.collect_constrained_late_bound_regions(&trait_ref);
463         let late_bound_in_ty = tcx.collect_referenced_late_bound_regions(&ty::Binder(binding.ty));
464         debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
465         debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
466         for br in late_bound_in_ty.difference(&late_bound_in_trait_ref) {
467             let br_name = match *br {
468                 ty::BrNamed(_, name) => name,
469                 _ => {
470                     span_bug!(
471                         binding.span,
472                         "anonymous bound region {:?} in binding but not trait ref",
473                         br);
474                 }
475             };
476             struct_span_err!(tcx.sess,
477                              binding.span,
478                              E0582,
479                              "binding for associated type `{}` references lifetime `{}`, \
480                               which does not appear in the trait input types",
481                              binding.item_name, br_name)
482                 .emit();
483         }
484
485         // Simple case: X is defined in the current trait.
486         if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
487             return Ok(trait_ref.map_bound(|trait_ref| {
488                 ty::ProjectionPredicate {
489                     projection_ty: ty::ProjectionTy::from_ref_and_name(
490                         tcx,
491                         trait_ref,
492                         binding.item_name,
493                     ),
494                     ty: binding.ty,
495                 }
496             }));
497         }
498
499         // Otherwise, we have to walk through the supertraits to find
500         // those that do.
501         let candidates =
502             traits::supertraits(tcx, trait_ref.clone())
503             .filter(|r| self.trait_defines_associated_type_named(r.def_id(), binding.item_name));
504
505         let candidate = self.one_bound_for_assoc_type(candidates,
506                                                       &trait_ref.to_string(),
507                                                       &binding.item_name.as_str(),
508                                                       binding.span)?;
509
510         Ok(candidate.map_bound(|trait_ref| {
511             ty::ProjectionPredicate {
512                 projection_ty: ty::ProjectionTy::from_ref_and_name(
513                     tcx,
514                     trait_ref,
515                     binding.item_name,
516                 ),
517                 ty: binding.ty,
518             }
519         }))
520     }
521
522     fn ast_path_to_ty(&self,
523         span: Span,
524         did: DefId,
525         item_segment: &hir::PathSegment)
526         -> Ty<'tcx>
527     {
528         let substs = self.ast_path_substs_for_ty(span, did, item_segment);
529         self.normalize_ty(
530             span,
531             self.tcx().at(span).type_of(did).subst(self.tcx(), substs)
532         )
533     }
534
535     /// Transform a PolyTraitRef into a PolyExistentialTraitRef by
536     /// removing the dummy Self type (TRAIT_OBJECT_DUMMY_SELF).
537     fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
538                                 -> ty::ExistentialTraitRef<'tcx> {
539         assert_eq!(trait_ref.self_ty().sty, TRAIT_OBJECT_DUMMY_SELF);
540         ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref)
541     }
542
543     fn conv_object_ty_poly_trait_ref(&self,
544         span: Span,
545         trait_bounds: &[hir::PolyTraitRef],
546         lifetime: &hir::Lifetime)
547         -> Ty<'tcx>
548     {
549         let tcx = self.tcx();
550
551         if trait_bounds.is_empty() {
552             span_err!(tcx.sess, span, E0224,
553                       "at least one non-builtin trait is required for an object type");
554             return tcx.types.err;
555         }
556
557         let mut projection_bounds = vec![];
558         let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF);
559         let principal = self.instantiate_poly_trait_ref(&trait_bounds[0],
560                                                         dummy_self,
561                                                         &mut projection_bounds);
562
563         for trait_bound in trait_bounds[1..].iter() {
564             // Sanity check for non-principal trait bounds
565             self.instantiate_poly_trait_ref(trait_bound,
566                                             dummy_self,
567                                             &mut vec![]);
568         }
569
570         let (auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]);
571
572         if !trait_bounds.is_empty() {
573             let b = &trait_bounds[0];
574             let span = b.trait_ref.path.span;
575             struct_span_err!(self.tcx().sess, span, E0225,
576                 "only Send/Sync traits can be used as additional traits in a trait object")
577                 .span_label(span, "non-Send/Sync additional trait")
578                 .emit();
579         }
580
581         // Erase the dummy_self (TRAIT_OBJECT_DUMMY_SELF) used above.
582         let existential_principal = principal.map_bound(|trait_ref| {
583             self.trait_ref_to_existential(trait_ref)
584         });
585         let existential_projections = projection_bounds.iter().map(|bound| {
586             bound.map_bound(|b| {
587                 let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
588                 ty::ExistentialProjection {
589                     ty: b.ty,
590                     item_def_id: b.projection_ty.item_def_id,
591                     substs: trait_ref.substs,
592                 }
593             })
594         });
595
596         // check that there are no gross object safety violations,
597         // most importantly, that the supertraits don't contain Self,
598         // to avoid ICE-s.
599         let object_safety_violations =
600             tcx.astconv_object_safety_violations(principal.def_id());
601         if !object_safety_violations.is_empty() {
602             tcx.report_object_safety_error(
603                 span, principal.def_id(), object_safety_violations)
604                 .emit();
605             return tcx.types.err;
606         }
607
608         let mut associated_types = FxHashSet::default();
609         for tr in traits::supertraits(tcx, principal) {
610             associated_types.extend(tcx.associated_items(tr.def_id())
611                 .filter(|item| item.kind == ty::AssociatedKind::Type)
612                 .map(|item| item.def_id));
613         }
614
615         for projection_bound in &projection_bounds {
616             associated_types.remove(&projection_bound.0.projection_ty.item_def_id);
617         }
618
619         for item_def_id in associated_types {
620             let assoc_item = tcx.associated_item(item_def_id);
621             let trait_def_id = assoc_item.container.id();
622             struct_span_err!(tcx.sess, span, E0191,
623                 "the value of the associated type `{}` (from the trait `{}`) must be specified",
624                         assoc_item.name,
625                         tcx.item_path_str(trait_def_id))
626                         .span_label(span, format!(
627                             "missing associated type `{}` value", assoc_item.name))
628                         .emit();
629         }
630
631         let mut v =
632             iter::once(ty::ExistentialPredicate::Trait(*existential_principal.skip_binder()))
633             .chain(auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait))
634             .chain(existential_projections
635                    .map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder())))
636             .collect::<AccumulateVec<[_; 8]>>();
637         v.sort_by(|a, b| a.cmp(tcx, b));
638         let existential_predicates = ty::Binder(tcx.mk_existential_predicates(v.into_iter()));
639
640
641         // Explicitly specified region bound. Use that.
642         let region_bound = if !lifetime.is_elided() {
643             self.ast_region_to_region(lifetime, None)
644         } else {
645             self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
646                 let hir_id = tcx.hir.node_to_hir_id(lifetime.id);
647                 if tcx.named_region(hir_id).is_some() {
648                     self.ast_region_to_region(lifetime, None)
649                 } else {
650                     self.re_infer(span, None).unwrap_or_else(|| {
651                         span_err!(tcx.sess, span, E0228,
652                                   "the lifetime bound for this object type cannot be deduced \
653                                    from context; please supply an explicit bound");
654                         tcx.types.re_static
655                     })
656                 }
657             })
658         };
659
660         debug!("region_bound: {:?}", region_bound);
661
662         let ty = tcx.mk_dynamic(existential_predicates, region_bound);
663         debug!("trait_object_type: {:?}", ty);
664         ty
665     }
666
667     fn report_ambiguous_associated_type(&self,
668                                         span: Span,
669                                         type_str: &str,
670                                         trait_str: &str,
671                                         name: &str) {
672         struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type")
673             .span_label(span, "ambiguous associated type")
674             .note(&format!("specify the type using the syntax `<{} as {}>::{}`",
675                   type_str, trait_str, name))
676             .emit();
677
678     }
679
680     // Search for a bound on a type parameter which includes the associated item
681     // given by `assoc_name`. `ty_param_def_id` is the `DefId` for the type parameter
682     // This function will fail if there are no suitable bounds or there is
683     // any ambiguity.
684     fn find_bound_for_assoc_item(&self,
685                                  ty_param_def_id: DefId,
686                                  assoc_name: ast::Name,
687                                  span: Span)
688                                  -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
689     {
690         let tcx = self.tcx();
691
692         let bounds: Vec<_> = self.get_type_parameter_bounds(span, ty_param_def_id)
693             .predicates.into_iter().filter_map(|p| p.to_opt_poly_trait_ref()).collect();
694
695         // Check that there is exactly one way to find an associated type with the
696         // correct name.
697         let suitable_bounds =
698             traits::transitive_bounds(tcx, &bounds)
699             .filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name));
700
701         let param_node_id = tcx.hir.as_local_node_id(ty_param_def_id).unwrap();
702         let param_name = tcx.hir.ty_param_name(param_node_id);
703         self.one_bound_for_assoc_type(suitable_bounds,
704                                       &param_name.as_str(),
705                                       &assoc_name.as_str(),
706                                       span)
707     }
708
709
710     // Checks that bounds contains exactly one element and reports appropriate
711     // errors otherwise.
712     fn one_bound_for_assoc_type<I>(&self,
713                                 mut bounds: I,
714                                 ty_param_name: &str,
715                                 assoc_name: &str,
716                                 span: Span)
717         -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
718         where I: Iterator<Item=ty::PolyTraitRef<'tcx>>
719     {
720         let bound = match bounds.next() {
721             Some(bound) => bound,
722             None => {
723                 struct_span_err!(self.tcx().sess, span, E0220,
724                           "associated type `{}` not found for `{}`",
725                           assoc_name,
726                           ty_param_name)
727                   .span_label(span, format!("associated type `{}` not found", assoc_name))
728                   .emit();
729                 return Err(ErrorReported);
730             }
731         };
732
733         if let Some(bound2) = bounds.next() {
734             let bounds = iter::once(bound).chain(iter::once(bound2)).chain(bounds);
735             let mut err = struct_span_err!(
736                 self.tcx().sess, span, E0221,
737                 "ambiguous associated type `{}` in bounds of `{}`",
738                 assoc_name,
739                 ty_param_name);
740             err.span_label(span, format!("ambiguous associated type `{}`", assoc_name));
741
742             for bound in bounds {
743                 let bound_span = self.tcx().associated_items(bound.def_id()).find(|item| {
744                     item.kind == ty::AssociatedKind::Type && item.name == assoc_name
745                 })
746                 .and_then(|item| self.tcx().hir.span_if_local(item.def_id));
747
748                 if let Some(span) = bound_span {
749                     err.span_label(span, format!("ambiguous `{}` from `{}`",
750                                                   assoc_name,
751                                                   bound));
752                 } else {
753                     span_note!(&mut err, span,
754                                "associated type `{}` could derive from `{}`",
755                                ty_param_name,
756                                bound);
757                 }
758             }
759             err.emit();
760         }
761
762         return Ok(bound);
763     }
764
765     // Create a type from a path to an associated type.
766     // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
767     // and item_segment is the path segment for D. We return a type and a def for
768     // the whole path.
769     // Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
770     // parameter or Self.
771     pub fn associated_path_def_to_ty(&self,
772                                      ref_id: ast::NodeId,
773                                      span: Span,
774                                      ty: Ty<'tcx>,
775                                      ty_path_def: Def,
776                                      item_segment: &hir::PathSegment)
777                                      -> (Ty<'tcx>, Def)
778     {
779         let tcx = self.tcx();
780         let assoc_name = item_segment.name;
781
782         debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
783
784         self.prohibit_type_params(slice::ref_slice(item_segment));
785
786         // Find the type of the associated item, and the trait where the associated
787         // item is declared.
788         let bound = match (&ty.sty, ty_path_def) {
789             (_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
790                 // `Self` in an impl of a trait - we have a concrete self type and a
791                 // trait reference.
792                 let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
793                     Some(trait_ref) => trait_ref,
794                     None => {
795                         // A cycle error occurred, most likely.
796                         return (tcx.types.err, Def::Err);
797                     }
798                 };
799
800                 let candidates =
801                     traits::supertraits(tcx, ty::Binder(trait_ref))
802                     .filter(|r| self.trait_defines_associated_type_named(r.def_id(),
803                                                                          assoc_name));
804
805                 match self.one_bound_for_assoc_type(candidates,
806                                                     "Self",
807                                                     &assoc_name.as_str(),
808                                                     span) {
809                     Ok(bound) => bound,
810                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
811                 }
812             }
813             (&ty::TyParam(_), Def::SelfTy(Some(param_did), None)) |
814             (&ty::TyParam(_), Def::TyParam(param_did)) => {
815                 match self.find_bound_for_assoc_item(param_did, assoc_name, span) {
816                     Ok(bound) => bound,
817                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
818                 }
819             }
820             _ => {
821                 // Don't print TyErr to the user.
822                 if !ty.references_error() {
823                     self.report_ambiguous_associated_type(span,
824                                                           &ty.to_string(),
825                                                           "Trait",
826                                                           &assoc_name.as_str());
827                 }
828                 return (tcx.types.err, Def::Err);
829             }
830         };
831
832         let trait_did = bound.0.def_id;
833         let item = tcx.associated_items(trait_did).find(|i| i.name == assoc_name)
834                                                   .expect("missing associated type");
835
836         let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, bound);
837         let ty = self.normalize_ty(span, ty);
838
839         let def = Def::AssociatedTy(item.def_id);
840         let def_scope = tcx.adjust(assoc_name, item.container.id(), ref_id).1;
841         if !item.vis.is_accessible_from(def_scope, tcx) {
842             let msg = format!("{} `{}` is private", def.kind_name(), assoc_name);
843             tcx.sess.span_err(span, &msg);
844         }
845         tcx.check_stability(item.def_id, ref_id, span);
846
847         (ty, def)
848     }
849
850     fn qpath_to_ty(&self,
851                    span: Span,
852                    opt_self_ty: Option<Ty<'tcx>>,
853                    item_def_id: DefId,
854                    trait_segment: &hir::PathSegment,
855                    item_segment: &hir::PathSegment)
856                    -> Ty<'tcx>
857     {
858         let tcx = self.tcx();
859         let trait_def_id = tcx.parent_def_id(item_def_id).unwrap();
860
861         self.prohibit_type_params(slice::ref_slice(item_segment));
862
863         let self_ty = if let Some(ty) = opt_self_ty {
864             ty
865         } else {
866             let path_str = tcx.item_path_str(trait_def_id);
867             self.report_ambiguous_associated_type(span,
868                                                   "Type",
869                                                   &path_str,
870                                                   &item_segment.name.as_str());
871             return tcx.types.err;
872         };
873
874         debug!("qpath_to_ty: self_type={:?}", self_ty);
875
876         let trait_ref = self.ast_path_to_mono_trait_ref(span,
877                                                         trait_def_id,
878                                                         self_ty,
879                                                         trait_segment);
880
881         debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
882
883         self.normalize_ty(span, tcx.mk_projection(item_def_id, trait_ref.substs))
884     }
885
886     pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
887         for segment in segments {
888             segment.with_parameters(|parameters| {
889                 for typ in &parameters.types {
890                     struct_span_err!(self.tcx().sess, typ.span, E0109,
891                                      "type parameters are not allowed on this type")
892                         .span_label(typ.span, "type parameter not allowed")
893                         .emit();
894                     break;
895                 }
896                 for lifetime in &parameters.lifetimes {
897                     struct_span_err!(self.tcx().sess, lifetime.span, E0110,
898                                      "lifetime parameters are not allowed on this type")
899                         .span_label(lifetime.span,
900                                     "lifetime parameter not allowed on this type")
901                         .emit();
902                     break;
903                 }
904                 for binding in &parameters.bindings {
905                     self.prohibit_projection(binding.span);
906                     break;
907                 }
908             })
909         }
910     }
911
912     pub fn prohibit_projection(&self, span: Span) {
913         let mut err = struct_span_err!(self.tcx().sess, span, E0229,
914                                        "associated type bindings are not allowed here");
915         err.span_label(span, "associated type not allowed here").emit();
916     }
917
918     // Check a type Path and convert it to a Ty.
919     pub fn def_to_ty(&self,
920                      opt_self_ty: Option<Ty<'tcx>>,
921                      path: &hir::Path,
922                      permit_variants: bool)
923                      -> Ty<'tcx> {
924         let tcx = self.tcx();
925
926         debug!("base_def_to_ty(def={:?}, opt_self_ty={:?}, path_segments={:?})",
927                path.def, opt_self_ty, path.segments);
928
929         let span = path.span;
930         match path.def {
931             Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => {
932                 assert_eq!(opt_self_ty, None);
933                 self.prohibit_type_params(path.segments.split_last().unwrap().1);
934                 self.ast_path_to_ty(span, did, path.segments.last().unwrap())
935             }
936             Def::Variant(did) if permit_variants => {
937                 // Convert "variant type" as if it were a real type.
938                 // The resulting `Ty` is type of the variant's enum for now.
939                 assert_eq!(opt_self_ty, None);
940                 self.prohibit_type_params(path.segments.split_last().unwrap().1);
941                 self.ast_path_to_ty(span,
942                                     tcx.parent_def_id(did).unwrap(),
943                                     path.segments.last().unwrap())
944             }
945             Def::TyParam(did) => {
946                 assert_eq!(opt_self_ty, None);
947                 self.prohibit_type_params(&path.segments);
948
949                 let node_id = tcx.hir.as_local_node_id(did).unwrap();
950                 let item_id = tcx.hir.get_parent_node(node_id);
951                 let item_def_id = tcx.hir.local_def_id(item_id);
952                 let generics = tcx.generics_of(item_def_id);
953                 let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index];
954                 tcx.mk_param(index, tcx.hir.name(node_id))
955             }
956             Def::SelfTy(_, Some(def_id)) => {
957                 // Self in impl (we know the concrete type).
958
959                 assert_eq!(opt_self_ty, None);
960                 self.prohibit_type_params(&path.segments);
961
962                 tcx.at(span).type_of(def_id)
963             }
964             Def::SelfTy(Some(_), None) => {
965                 // Self in trait.
966                 assert_eq!(opt_self_ty, None);
967                 self.prohibit_type_params(&path.segments);
968                 tcx.mk_self_type()
969             }
970             Def::AssociatedTy(def_id) => {
971                 self.prohibit_type_params(&path.segments[..path.segments.len()-2]);
972                 self.qpath_to_ty(span,
973                                  opt_self_ty,
974                                  def_id,
975                                  &path.segments[path.segments.len()-2],
976                                  path.segments.last().unwrap())
977             }
978             Def::PrimTy(prim_ty) => {
979                 assert_eq!(opt_self_ty, None);
980                 self.prohibit_type_params(&path.segments);
981                 match prim_ty {
982                     hir::TyBool => tcx.types.bool,
983                     hir::TyChar => tcx.types.char,
984                     hir::TyInt(it) => tcx.mk_mach_int(it),
985                     hir::TyUint(uit) => tcx.mk_mach_uint(uit),
986                     hir::TyFloat(ft) => tcx.mk_mach_float(ft),
987                     hir::TyStr => tcx.mk_str()
988                 }
989             }
990             Def::Err => {
991                 for segment in &path.segments {
992                     segment.with_parameters(|parameters| {
993                         for ty in &parameters.types {
994                             self.ast_ty_to_ty(ty);
995                         }
996                         for binding in &parameters.bindings {
997                             self.ast_ty_to_ty(&binding.ty);
998                         }
999                     });
1000                 }
1001                 self.set_tainted_by_errors();
1002                 return self.tcx().types.err;
1003             }
1004             _ => span_bug!(span, "unexpected definition: {:?}", path.def)
1005         }
1006     }
1007
1008     /// Parses the programmer's textual representation of a type into our
1009     /// internal notion of a type.
1010     pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
1011         debug!("ast_ty_to_ty(id={:?}, ast_ty={:?})",
1012                ast_ty.id, ast_ty);
1013
1014         let tcx = self.tcx();
1015
1016         let result_ty = match ast_ty.node {
1017             hir::TySlice(ref ty) => {
1018                 tcx.mk_slice(self.ast_ty_to_ty(&ty))
1019             }
1020             hir::TyPtr(ref mt) => {
1021                 tcx.mk_ptr(ty::TypeAndMut {
1022                     ty: self.ast_ty_to_ty(&mt.ty),
1023                     mutbl: mt.mutbl
1024                 })
1025             }
1026             hir::TyRptr(ref region, ref mt) => {
1027                 let r = self.ast_region_to_region(region, None);
1028                 debug!("TyRef r={:?}", r);
1029                 let t = self.ast_ty_to_ty(&mt.ty);
1030                 tcx.mk_ref(r, ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
1031             }
1032             hir::TyNever => {
1033                 tcx.types.never
1034             },
1035             hir::TyTup(ref fields) => {
1036                 tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t)), false)
1037             }
1038             hir::TyBareFn(ref bf) => {
1039                 require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
1040                 tcx.mk_fn_ptr(self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl))
1041             }
1042             hir::TyTraitObject(ref bounds, ref lifetime) => {
1043                 self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
1044             }
1045             hir::TyImplTrait(_) => {
1046                 // Figure out if we can allow an `impl Trait` here, by walking up
1047                 // to a `fn` or inherent `impl` method, going only through `Ty`
1048                 // or `TraitRef` nodes (as nothing else should be in types) and
1049                 // ensuring that we reach the `fn`/method signature's return type.
1050                 let mut node_id = ast_ty.id;
1051                 let fn_decl = loop {
1052                     let parent = tcx.hir.get_parent_node(node_id);
1053                     match tcx.hir.get(parent) {
1054                         hir::map::NodeItem(&hir::Item {
1055                             node: hir::ItemFn(ref fn_decl, ..), ..
1056                         }) => break Some(fn_decl),
1057
1058                         hir::map::NodeImplItem(&hir::ImplItem {
1059                             node: hir::ImplItemKind::Method(ref sig, _), ..
1060                         }) => {
1061                             match tcx.hir.expect_item(tcx.hir.get_parent(parent)).node {
1062                                 hir::ItemImpl(.., None, _, _) => {
1063                                     break Some(&sig.decl)
1064                                 }
1065                                 _ => break None
1066                             }
1067                         }
1068
1069                         hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => {}
1070
1071                         _ => break None
1072                     }
1073                     node_id = parent;
1074                 };
1075                 let allow = fn_decl.map_or(false, |fd| {
1076                     match fd.output {
1077                         hir::DefaultReturn(_) => false,
1078                         hir::Return(ref ty) => ty.id == node_id
1079                     }
1080                 });
1081
1082                 // Create the anonymized type.
1083                 if allow {
1084                     let def_id = tcx.hir.local_def_id(ast_ty.id);
1085                     tcx.mk_anon(def_id, Substs::identity_for_item(tcx, def_id))
1086                 } else {
1087                     span_err!(tcx.sess, ast_ty.span, E0562,
1088                               "`impl Trait` not allowed outside of function \
1089                                and inherent method return types");
1090                     tcx.types.err
1091                 }
1092             }
1093             hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
1094                 debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
1095                 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
1096                     self.ast_ty_to_ty(qself)
1097                 });
1098                 self.def_to_ty(opt_self_ty, path, false)
1099             }
1100             hir::TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => {
1101                 debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment);
1102                 let ty = self.ast_ty_to_ty(qself);
1103
1104                 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
1105                     path.def
1106                 } else {
1107                     Def::Err
1108                 };
1109                 self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
1110             }
1111             hir::TyArray(ref ty, length) => {
1112                 let length_def_id = tcx.hir.body_owner_def_id(length);
1113                 let substs = Substs::identity_for_item(tcx, length_def_id);
1114                 let length = tcx.mk_const(ty::Const {
1115                     val: ConstVal::Unevaluated(length_def_id, substs),
1116                     ty: tcx.types.usize
1117                 });
1118                 let array_ty = tcx.mk_ty(ty::TyArray(self.ast_ty_to_ty(&ty), length));
1119                 self.normalize_ty(ast_ty.span, array_ty)
1120             }
1121             hir::TyTypeof(ref _e) => {
1122                 struct_span_err!(tcx.sess, ast_ty.span, E0516,
1123                                  "`typeof` is a reserved keyword but unimplemented")
1124                     .span_label(ast_ty.span, "reserved keyword")
1125                     .emit();
1126
1127                 tcx.types.err
1128             }
1129             hir::TyInfer => {
1130                 // TyInfer also appears as the type of arguments or return
1131                 // values in a ExprClosure, or as
1132                 // the type of local variables. Both of these cases are
1133                 // handled specially and will not descend into this routine.
1134                 self.ty_infer(ast_ty.span)
1135             }
1136             hir::TyErr => {
1137                 tcx.types.err
1138             }
1139         };
1140
1141         self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
1142         result_ty
1143     }
1144
1145     pub fn ty_of_arg(&self,
1146                      ty: &hir::Ty,
1147                      expected_ty: Option<Ty<'tcx>>)
1148                      -> Ty<'tcx>
1149     {
1150         match ty.node {
1151             hir::TyInfer if expected_ty.is_some() => {
1152                 self.record_ty(ty.hir_id, expected_ty.unwrap(), ty.span);
1153                 expected_ty.unwrap()
1154             }
1155             _ => self.ast_ty_to_ty(ty),
1156         }
1157     }
1158
1159     pub fn ty_of_fn(&self,
1160                     unsafety: hir::Unsafety,
1161                     abi: abi::Abi,
1162                     decl: &hir::FnDecl)
1163                     -> ty::PolyFnSig<'tcx> {
1164         debug!("ty_of_fn");
1165
1166         let tcx = self.tcx();
1167         let input_tys: Vec<Ty> =
1168             decl.inputs.iter().map(|a| self.ty_of_arg(a, None)).collect();
1169
1170         let output_ty = match decl.output {
1171             hir::Return(ref output) => self.ast_ty_to_ty(output),
1172             hir::DefaultReturn(..) => tcx.mk_nil(),
1173         };
1174
1175         debug!("ty_of_fn: output_ty={:?}", output_ty);
1176
1177         let bare_fn_ty = ty::Binder(tcx.mk_fn_sig(
1178             input_tys.into_iter(),
1179             output_ty,
1180             decl.variadic,
1181             unsafety,
1182             abi
1183         ));
1184
1185         // Find any late-bound regions declared in return type that do
1186         // not appear in the arguments. These are not wellformed.
1187         //
1188         // Example:
1189         //     for<'a> fn() -> &'a str <-- 'a is bad
1190         //     for<'a> fn(&'a String) -> &'a str <-- 'a is ok
1191         let inputs = bare_fn_ty.inputs();
1192         let late_bound_in_args = tcx.collect_constrained_late_bound_regions(
1193             &inputs.map_bound(|i| i.to_owned()));
1194         let output = bare_fn_ty.output();
1195         let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
1196         for br in late_bound_in_ret.difference(&late_bound_in_args) {
1197             let br_name = match *br {
1198                 ty::BrNamed(_, name) => name,
1199                 _ => {
1200                     span_bug!(
1201                         decl.output.span(),
1202                         "anonymous bound region {:?} in return but not args",
1203                         br);
1204                 }
1205             };
1206             struct_span_err!(tcx.sess,
1207                              decl.output.span(),
1208                              E0581,
1209                              "return type references lifetime `{}`, \
1210                              which does not appear in the fn input types",
1211                              br_name)
1212                 .emit();
1213         }
1214
1215         bare_fn_ty
1216     }
1217
1218     pub fn ty_of_closure(&self,
1219         unsafety: hir::Unsafety,
1220         decl: &hir::FnDecl,
1221         abi: abi::Abi,
1222         expected_sig: Option<ty::FnSig<'tcx>>)
1223         -> ty::PolyFnSig<'tcx>
1224     {
1225         debug!("ty_of_closure(expected_sig={:?})",
1226                expected_sig);
1227
1228         let input_tys = decl.inputs.iter().enumerate().map(|(i, a)| {
1229             let expected_arg_ty = expected_sig.as_ref().and_then(|e| {
1230                 // no guarantee that the correct number of expected args
1231                 // were supplied
1232                 if i < e.inputs().len() {
1233                     Some(e.inputs()[i])
1234                 } else {
1235                     None
1236                 }
1237             });
1238             self.ty_of_arg(a, expected_arg_ty)
1239         });
1240
1241         let expected_ret_ty = expected_sig.as_ref().map(|e| e.output());
1242
1243         let output_ty = match decl.output {
1244             hir::Return(ref output) => {
1245                 if let (&hir::TyInfer, Some(expected_ret_ty)) = (&output.node, expected_ret_ty) {
1246                     self.record_ty(output.hir_id, expected_ret_ty, output.span);
1247                     expected_ret_ty
1248                 } else {
1249                     self.ast_ty_to_ty(&output)
1250                 }
1251             }
1252             hir::DefaultReturn(span) => {
1253                 if let Some(expected_ret_ty) = expected_ret_ty {
1254                     expected_ret_ty
1255                 } else {
1256                     self.ty_infer(span)
1257                 }
1258             }
1259         };
1260
1261         debug!("ty_of_closure: output_ty={:?}", output_ty);
1262
1263         ty::Binder(self.tcx().mk_fn_sig(
1264             input_tys,
1265             output_ty,
1266             decl.variadic,
1267             unsafety,
1268             abi
1269         ))
1270     }
1271
1272     /// Given the bounds on an object, determines what single region bound (if any) we can
1273     /// use to summarize this type. The basic idea is that we will use the bound the user
1274     /// provided, if they provided one, and otherwise search the supertypes of trait bounds
1275     /// for region bounds. It may be that we can derive no bound at all, in which case
1276     /// we return `None`.
1277     fn compute_object_lifetime_bound(&self,
1278         span: Span,
1279         existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
1280         -> Option<ty::Region<'tcx>> // if None, use the default
1281     {
1282         let tcx = self.tcx();
1283
1284         debug!("compute_opt_region_bound(existential_predicates={:?})",
1285                existential_predicates);
1286
1287         // No explicit region bound specified. Therefore, examine trait
1288         // bounds and see if we can derive region bounds from those.
1289         let derived_region_bounds =
1290             object_region_bounds(tcx, existential_predicates);
1291
1292         // If there are no derived region bounds, then report back that we
1293         // can find no region bound. The caller will use the default.
1294         if derived_region_bounds.is_empty() {
1295             return None;
1296         }
1297
1298         // If any of the derived region bounds are 'static, that is always
1299         // the best choice.
1300         if derived_region_bounds.iter().any(|&r| ty::ReStatic == *r) {
1301             return Some(tcx.types.re_static);
1302         }
1303
1304         // Determine whether there is exactly one unique region in the set
1305         // of derived region bounds. If so, use that. Otherwise, report an
1306         // error.
1307         let r = derived_region_bounds[0];
1308         if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
1309             span_err!(tcx.sess, span, E0227,
1310                       "ambiguous lifetime bound, explicit lifetime bound required");
1311         }
1312         return Some(r);
1313     }
1314 }
1315
1316 /// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the
1317 /// remaining general trait bounds.
1318 fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1319                                          trait_bounds: &'b [hir::PolyTraitRef])
1320     -> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
1321 {
1322     let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
1323         match bound.trait_ref.path.def {
1324             Def::Trait(trait_did) => {
1325                 // Checks whether `trait_did` refers to one of the builtin
1326                 // traits, like `Send`, and adds it to `auto_traits` if so.
1327                 if Some(trait_did) == tcx.lang_items().send_trait() ||
1328                     Some(trait_did) == tcx.lang_items().sync_trait() {
1329                     let segments = &bound.trait_ref.path.segments;
1330                     segments[segments.len() - 1].with_parameters(|parameters| {
1331                         if !parameters.types.is_empty() {
1332                             check_type_argument_count(tcx, bound.trait_ref.path.span,
1333                                                       parameters.types.len(), &[]);
1334                         }
1335                         if !parameters.lifetimes.is_empty() {
1336                             report_lifetime_number_error(tcx, bound.trait_ref.path.span,
1337                                                          parameters.lifetimes.len(), 0);
1338                         }
1339                     });
1340                     true
1341                 } else {
1342                     false
1343                 }
1344             }
1345             _ => false
1346         }
1347     });
1348
1349     let auto_traits = auto_traits.into_iter().map(|tr| {
1350         if let Def::Trait(trait_did) = tr.trait_ref.path.def {
1351             trait_did
1352         } else {
1353             unreachable!()
1354         }
1355     }).collect::<Vec<_>>();
1356
1357     (auto_traits, trait_bounds)
1358 }
1359
1360 fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
1361                              ty_param_defs: &[ty::TypeParameterDef]) {
1362     let accepted = ty_param_defs.len();
1363     let required = ty_param_defs.iter().take_while(|x| !x.has_default).count();
1364     if supplied < required {
1365         let expected = if required < accepted {
1366             "expected at least"
1367         } else {
1368             "expected"
1369         };
1370         let arguments_plural = if required == 1 { "" } else { "s" };
1371
1372         struct_span_err!(tcx.sess, span, E0243,
1373                 "wrong number of type arguments: {} {}, found {}",
1374                 expected, required, supplied)
1375             .span_label(span,
1376                 format!("{} {} type argument{}",
1377                     expected,
1378                     required,
1379                     arguments_plural))
1380             .emit();
1381     } else if supplied > accepted {
1382         let expected = if required < accepted {
1383             format!("expected at most {}", accepted)
1384         } else {
1385             format!("expected {}", accepted)
1386         };
1387         let arguments_plural = if accepted == 1 { "" } else { "s" };
1388
1389         struct_span_err!(tcx.sess, span, E0244,
1390                 "wrong number of type arguments: {}, found {}",
1391                 expected, supplied)
1392             .span_label(
1393                 span,
1394                 format!("{} type argument{}",
1395                     if accepted == 0 { "expected no" } else { &expected },
1396                     arguments_plural)
1397             )
1398             .emit();
1399     }
1400 }
1401
1402 fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected: usize) {
1403     let label = if number < expected {
1404         if expected == 1 {
1405             format!("expected {} lifetime parameter", expected)
1406         } else {
1407             format!("expected {} lifetime parameters", expected)
1408         }
1409     } else {
1410         let additional = number - expected;
1411         if additional == 1 {
1412             "unexpected lifetime parameter".to_string()
1413         } else {
1414             format!("{} unexpected lifetime parameters", additional)
1415         }
1416     };
1417     struct_span_err!(tcx.sess, span, E0107,
1418                      "wrong number of lifetime parameters: expected {}, found {}",
1419                      expected, number)
1420         .span_label(span, label)
1421         .emit();
1422 }
1423
1424 // A helper struct for conveniently grouping a set of bounds which we pass to
1425 // and return from functions in multiple places.
1426 #[derive(PartialEq, Eq, Clone, Debug)]
1427 pub struct Bounds<'tcx> {
1428     pub region_bounds: Vec<ty::Region<'tcx>>,
1429     pub implicitly_sized: bool,
1430     pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
1431     pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
1432 }
1433
1434 impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
1435     pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
1436                       -> Vec<ty::Predicate<'tcx>>
1437     {
1438         let mut vec = Vec::new();
1439
1440         // If it could be sized, and is, add the sized predicate
1441         if self.implicitly_sized {
1442             if let Some(sized) = tcx.lang_items().sized_trait() {
1443                 let trait_ref = ty::TraitRef {
1444                     def_id: sized,
1445                     substs: tcx.mk_substs_trait(param_ty, &[])
1446                 };
1447                 vec.push(trait_ref.to_predicate());
1448             }
1449         }
1450
1451         for &region_bound in &self.region_bounds {
1452             // account for the binder being introduced below; no need to shift `param_ty`
1453             // because, at present at least, it can only refer to early-bound regions
1454             let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
1455             vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
1456         }
1457
1458         for bound_trait_ref in &self.trait_bounds {
1459             vec.push(bound_trait_ref.to_predicate());
1460         }
1461
1462         for projection in &self.projection_bounds {
1463             vec.push(projection.to_predicate());
1464         }
1465
1466         vec
1467     }
1468 }
1469
1470 pub enum ExplicitSelf<'tcx> {
1471     ByValue,
1472     ByReference(ty::Region<'tcx>, hir::Mutability),
1473     ByBox
1474 }
1475
1476 impl<'tcx> ExplicitSelf<'tcx> {
1477     /// We wish to (for now) categorize an explicit self
1478     /// declaration like `self: SomeType` into either `self`,
1479     /// `&self`, `&mut self`, or `Box<self>`. We do this here
1480     /// by some simple pattern matching. A more precise check
1481     /// is done later in `check_method_self_type()`.
1482     ///
1483     /// Examples:
1484     ///
1485     /// ```
1486     /// impl Foo for &T {
1487     ///     // Legal declarations:
1488     ///     fn method1(self: &&T); // ExplicitSelf::ByReference
1489     ///     fn method2(self: &T); // ExplicitSelf::ByValue
1490     ///     fn method3(self: Box<&T>); // ExplicitSelf::ByBox
1491     ///
1492     ///     // Invalid cases will be caught later by `check_method_self_type`:
1493     ///     fn method_err1(self: &mut T); // ExplicitSelf::ByReference
1494     /// }
1495     /// ```
1496     ///
1497     /// To do the check we just count the number of "modifiers"
1498     /// on each type and compare them. If they are the same or
1499     /// the impl has more, we call it "by value". Otherwise, we
1500     /// look at the outermost modifier on the method decl and
1501     /// call it by-ref, by-box as appropriate. For method1, for
1502     /// example, the impl type has one modifier, but the method
1503     /// type has two, so we end up with
1504     /// ExplicitSelf::ByReference.
1505     pub fn determine(untransformed_self_ty: Ty<'tcx>,
1506                      self_arg_ty: Ty<'tcx>)
1507                      -> ExplicitSelf<'tcx> {
1508         fn count_modifiers(ty: Ty) -> usize {
1509             match ty.sty {
1510                 ty::TyRef(_, mt) => count_modifiers(mt.ty) + 1,
1511                 ty::TyAdt(def, _) if def.is_box() => count_modifiers(ty.boxed_ty()) + 1,
1512                 _ => 0,
1513             }
1514         }
1515
1516         let impl_modifiers = count_modifiers(untransformed_self_ty);
1517         let method_modifiers = count_modifiers(self_arg_ty);
1518
1519         if impl_modifiers >= method_modifiers {
1520             ExplicitSelf::ByValue
1521         } else {
1522             match self_arg_ty.sty {
1523                 ty::TyRef(r, mt) => ExplicitSelf::ByReference(r, mt.mutbl),
1524                 ty::TyAdt(def, _) if def.is_box() => ExplicitSelf::ByBox,
1525                 _ => ExplicitSelf::ByValue,
1526             }
1527         }
1528     }
1529 }