]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/astconv.rs
Fix impl Trait Lifetime Handling
[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 namespace::Namespace;
22 use rustc::ty::subst::{Kind, Subst, Substs};
23 use rustc::traits;
24 use rustc::ty::{self, RegionKind, Ty, TyCtxt, ToPredicate, TypeFoldable};
25 use rustc::ty::wf::object_region_bounds;
26 use rustc_back::slice;
27 use require_c_abi_if_variadic;
28 use util::common::ErrorReported;
29 use util::nodemap::FxHashSet;
30
31 use std::iter;
32 use syntax::{abi, ast};
33 use syntax::symbol::Symbol;
34 use syntax::feature_gate::{GateIssue, emit_feature_err};
35 use syntax_pos::Span;
36
37 pub trait AstConv<'gcx, 'tcx> {
38     fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
39
40     /// Returns the set of bounds in scope for the type parameter with
41     /// the given id.
42     fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
43                                  -> ty::GenericPredicates<'tcx>;
44
45     /// What lifetime should we use when a lifetime is omitted (and not elided)?
46     fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>)
47                 -> Option<ty::Region<'tcx>>;
48
49     /// What type should we use when a type is omitted?
50     fn ty_infer(&self, span: Span) -> Ty<'tcx>;
51
52     /// Same as ty_infer, but with a known type parameter definition.
53     fn ty_infer_for_def(&self,
54                         _def: &ty::TypeParameterDef,
55                         _substs: &[Kind<'tcx>],
56                         span: Span) -> Ty<'tcx> {
57         self.ty_infer(span)
58     }
59
60     /// Projecting an associated type from a (potentially)
61     /// higher-ranked trait reference is more complicated, because of
62     /// the possibility of late-bound regions appearing in the
63     /// associated type binding. This is not legal in function
64     /// signatures for that reason. In a function body, we can always
65     /// handle it because we can use inference variables to remove the
66     /// late-bound regions.
67     fn projected_ty_from_poly_trait_ref(&self,
68                                         span: Span,
69                                         item_def_id: DefId,
70                                         poly_trait_ref: ty::PolyTraitRef<'tcx>)
71                                         -> Ty<'tcx>;
72
73     /// Normalize an associated type coming from the user.
74     fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
75
76     /// Invoked when we encounter an error from some prior pass
77     /// (e.g. resolve) that is translated into a ty-error. This is
78     /// used to help suppress derived errors typeck might otherwise
79     /// report.
80     fn set_tainted_by_errors(&self);
81
82     fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
83 }
84
85 struct ConvertedBinding<'tcx> {
86     item_name: ast::Name,
87     ty: Ty<'tcx>,
88     span: Span,
89 }
90
91 /// Dummy type used for the `Self` of a `TraitRef` created for converting
92 /// a trait object, and which gets removed in `ExistentialTraitRef`.
93 /// This type must not appear anywhere in other converted types.
94 const TRAIT_OBJECT_DUMMY_SELF: ty::TypeVariants<'static> = ty::TyInfer(ty::FreshTy(0));
95
96 impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
97     pub fn ast_region_to_region(&self,
98         lifetime: &hir::Lifetime,
99         def: Option<&ty::RegionParameterDef>)
100         -> ty::Region<'tcx>
101     {
102         let tcx = self.tcx();
103         let lifetime_name = |def_id| {
104             tcx.hir.name(tcx.hir.as_local_node_id(def_id).unwrap())
105         };
106
107         let hir_id = tcx.hir.node_to_hir_id(lifetime.id);
108         let r = match tcx.named_region(hir_id) {
109             Some(rl::Region::Static) => {
110                 tcx.types.re_static
111             }
112
113             Some(rl::Region::LateBound(debruijn, id)) => {
114                 let name = lifetime_name(id);
115                 tcx.mk_region(ty::ReLateBound(debruijn,
116                     ty::BrNamed(id, name)))
117             }
118
119             Some(rl::Region::LateBoundAnon(debruijn, index)) => {
120                 tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(index)))
121             }
122
123             Some(rl::Region::EarlyBound(index, id)) => {
124                 let name = lifetime_name(id);
125                 tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
126                     def_id: id,
127                     index,
128                     name,
129                 }))
130             }
131
132             Some(rl::Region::Free(scope, id)) => {
133                 let name = lifetime_name(id);
134                 tcx.mk_region(ty::ReFree(ty::FreeRegion {
135                     scope,
136                     bound_region: ty::BrNamed(id, name)
137                 }))
138
139                     // (*) -- not late-bound, won't change
140             }
141
142             None => {
143                 self.re_infer(lifetime.span, def).expect("unelided lifetime in signature")
144             }
145         };
146
147         debug!("ast_region_to_region(lifetime={:?}) yields {:?}",
148                 lifetime,
149                 r);
150
151         r
152     }
153
154     /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
155     /// returns an appropriate set of substitutions for this particular reference to `I`.
156     pub fn ast_path_substs_for_ty(&self,
157         span: Span,
158         def_id: DefId,
159         item_segment: &hir::PathSegment)
160         -> &'tcx Substs<'tcx>
161     {
162
163         let (substs, assoc_bindings) =
164             item_segment.with_parameters(|parameters| {
165                 self.create_substs_for_ast_path(
166                     span,
167                     def_id,
168                     parameters,
169                     item_segment.infer_types,
170                     None)
171             });
172
173         assoc_bindings.first().map(|b| self.prohibit_projection(b.span));
174
175         substs
176     }
177
178     /// Given the type/region arguments provided to some path (along with
179     /// an implicit Self, if this is a trait reference) returns the complete
180     /// set of substitutions. This may involve applying defaulted type parameters.
181     ///
182     /// Note that the type listing given here is *exactly* what the user provided.
183     fn create_substs_for_ast_path(&self,
184         span: Span,
185         def_id: DefId,
186         parameters: &hir::PathParameters,
187         infer_types: bool,
188         self_ty: Option<Ty<'tcx>>)
189         -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
190     {
191         let tcx = self.tcx();
192
193         debug!("create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
194                parameters={:?})",
195                def_id, self_ty, parameters);
196
197         // If the type is parameterized by this region, then replace this
198         // region with the current anon region binding (in other words,
199         // whatever & would get replaced with).
200         let decl_generics = tcx.generics_of(def_id);
201         let num_types_provided = parameters.types.len();
202         let expected_num_region_params = decl_generics.regions.len();
203         let supplied_num_region_params = parameters.lifetimes.len();
204         if expected_num_region_params != supplied_num_region_params {
205             report_lifetime_number_error(tcx, span,
206                                          supplied_num_region_params,
207                                          expected_num_region_params);
208         }
209
210         // If a self-type was declared, one should be provided.
211         assert_eq!(decl_generics.has_self, self_ty.is_some());
212
213         // Check the number of type parameters supplied by the user.
214         let ty_param_defs = &decl_generics.types[self_ty.is_some() as usize..];
215         if !infer_types || num_types_provided > ty_param_defs.len() {
216             check_type_argument_count(tcx, span, num_types_provided, ty_param_defs);
217         }
218
219         let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
220         let default_needs_object_self = |p: &ty::TypeParameterDef| {
221             if is_object && p.has_default {
222                 if tcx.at(span).type_of(p.def_id).has_self_ty() {
223                     // There is no suitable inference default for a type parameter
224                     // that references self, in an object type.
225                     return true;
226                 }
227             }
228
229             false
230         };
231
232         let substs = Substs::for_item(tcx, def_id, |def, _| {
233             let i = def.index as usize - self_ty.is_some() as usize;
234             if let Some(lifetime) = parameters.lifetimes.get(i) {
235                 self.ast_region_to_region(lifetime, Some(def))
236             } else {
237                 tcx.types.re_static
238             }
239         }, |def, substs| {
240             let i = def.index as usize;
241
242             // Handle Self first, so we can adjust the index to match the AST.
243             if let (0, Some(ty)) = (i, self_ty) {
244                 return ty;
245             }
246
247             let i = i - self_ty.is_some() as usize - decl_generics.regions.len();
248             if i < num_types_provided {
249                 // A provided type parameter.
250                 self.ast_ty_to_ty(&parameters.types[i])
251             } else if infer_types {
252                 // No type parameters were provided, we can infer all.
253                 let ty_var = if !default_needs_object_self(def) {
254                     self.ty_infer_for_def(def, substs, span)
255                 } else {
256                     self.ty_infer(span)
257                 };
258                 ty_var
259             } else if def.has_default {
260                 // No type parameter provided, but a default exists.
261
262                 // If we are converting an object type, then the
263                 // `Self` parameter is unknown. However, some of the
264                 // other type parameters may reference `Self` in their
265                 // defaults. This will lead to an ICE if we are not
266                 // careful!
267                 if default_needs_object_self(def) {
268                     struct_span_err!(tcx.sess, span, E0393,
269                                      "the type parameter `{}` must be explicitly specified",
270                                      def.name)
271                         .span_label(span, format!("missing reference to `{}`", def.name))
272                         .note(&format!("because of the default `Self` reference, \
273                                         type parameters must be specified on object types"))
274                         .emit();
275                     tcx.types.err
276                 } else {
277                     // This is a default type parameter.
278                     self.normalize_ty(
279                         span,
280                         tcx.at(span).type_of(def.def_id)
281                             .subst_spanned(tcx, substs, Some(span))
282                     )
283                 }
284             } else {
285                 // We've already errored above about the mismatch.
286                 tcx.types.err
287             }
288         });
289
290         let assoc_bindings = parameters.bindings.iter().map(|binding| {
291             ConvertedBinding {
292                 item_name: binding.name,
293                 ty: self.ast_ty_to_ty(&binding.ty),
294                 span: binding.span,
295             }
296         }).collect();
297
298         debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}) -> {:?}",
299                decl_generics, self_ty, substs);
300
301         (substs, assoc_bindings)
302     }
303
304     /// Instantiates the path for the given trait reference, assuming that it's
305     /// bound to a valid trait type. Returns the def_id for the defining trait.
306     /// Fails if the type is a type other than a trait type.
307     ///
308     /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
309     /// are disallowed. Otherwise, they are pushed onto the vector given.
310     pub fn instantiate_mono_trait_ref(&self,
311         trait_ref: &hir::TraitRef,
312         self_ty: Ty<'tcx>)
313         -> ty::TraitRef<'tcx>
314     {
315         self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
316
317         let trait_def_id = self.trait_def_id(trait_ref);
318         self.ast_path_to_mono_trait_ref(trait_ref.path.span,
319                                         trait_def_id,
320                                         self_ty,
321                                         trait_ref.path.segments.last().unwrap())
322     }
323
324     fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
325         let path = &trait_ref.path;
326         match path.def {
327             Def::Trait(trait_def_id) => trait_def_id,
328             Def::Err => {
329                 self.tcx().sess.fatal("cannot continue compilation due to previous error");
330             }
331             _ => {
332                 span_fatal!(self.tcx().sess, path.span, E0245, "`{}` is not a trait",
333                             self.tcx().hir.node_to_pretty_string(trait_ref.ref_id));
334             }
335         }
336     }
337
338     pub fn instantiate_poly_trait_ref(&self,
339         ast_trait_ref: &hir::PolyTraitRef,
340         self_ty: Ty<'tcx>,
341         poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
342         -> ty::PolyTraitRef<'tcx>
343     {
344         let trait_ref = &ast_trait_ref.trait_ref;
345         let trait_def_id = self.trait_def_id(trait_ref);
346
347         debug!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
348
349         self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
350
351         let (substs, assoc_bindings) =
352             self.create_substs_for_ast_trait_ref(trait_ref.path.span,
353                                                  trait_def_id,
354                                                  self_ty,
355                                                  trait_ref.path.segments.last().unwrap());
356         let poly_trait_ref = ty::Binder(ty::TraitRef::new(trait_def_id, substs));
357
358         poly_projections.extend(assoc_bindings.iter().filter_map(|binding| {
359             // specify type to assert that error was already reported in Err case:
360             let predicate: Result<_, ErrorReported> =
361                 self.ast_type_binding_to_poly_projection_predicate(poly_trait_ref, 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 &&
427             self.tcx().hygienic_eq(assoc_name, item.name, trait_def_id)
428         })
429     }
430
431     fn ast_type_binding_to_poly_projection_predicate(
432         &self,
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,
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 auto traits can be used as additional traits in a trait object")
577                 .span_label(span, "non-auto 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,
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: ast::Name,
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 &&
745                     self.tcx().hygienic_eq(assoc_name, item.name, bound.def_id())
746                 })
747                 .and_then(|item| self.tcx().hir.span_if_local(item.def_id));
748
749                 if let Some(span) = bound_span {
750                     err.span_label(span, format!("ambiguous `{}` from `{}`",
751                                                   assoc_name,
752                                                   bound));
753                 } else {
754                     span_note!(&mut err, span,
755                                "associated type `{}` could derive from `{}`",
756                                ty_param_name,
757                                bound);
758                 }
759             }
760             err.emit();
761         }
762
763         return Ok(bound);
764     }
765
766     // Create a type from a path to an associated type.
767     // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
768     // and item_segment is the path segment for D. We return a type and a def for
769     // the whole path.
770     // Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
771     // parameter or Self.
772     pub fn associated_path_def_to_ty(&self,
773                                      ref_id: ast::NodeId,
774                                      span: Span,
775                                      ty: Ty<'tcx>,
776                                      ty_path_def: Def,
777                                      item_segment: &hir::PathSegment)
778                                      -> (Ty<'tcx>, Def)
779     {
780         let tcx = self.tcx();
781         let assoc_name = item_segment.name;
782
783         debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
784
785         self.prohibit_type_params(slice::ref_slice(item_segment));
786
787         // Find the type of the associated item, and the trait where the associated
788         // item is declared.
789         let bound = match (&ty.sty, ty_path_def) {
790             (_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
791                 // `Self` in an impl of a trait - we have a concrete self type and a
792                 // trait reference.
793                 let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
794                     Some(trait_ref) => trait_ref,
795                     None => {
796                         // A cycle error occurred, most likely.
797                         return (tcx.types.err, Def::Err);
798                     }
799                 };
800
801                 let candidates =
802                     traits::supertraits(tcx, ty::Binder(trait_ref))
803                     .filter(|r| self.trait_defines_associated_type_named(r.def_id(),
804                                                                          assoc_name));
805
806                 match self.one_bound_for_assoc_type(candidates, "Self", assoc_name, span) {
807                     Ok(bound) => bound,
808                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
809                 }
810             }
811             (&ty::TyParam(_), Def::SelfTy(Some(param_did), None)) |
812             (&ty::TyParam(_), Def::TyParam(param_did)) => {
813                 match self.find_bound_for_assoc_item(param_did, assoc_name, span) {
814                     Ok(bound) => bound,
815                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
816                 }
817             }
818             _ => {
819                 // Don't print TyErr to the user.
820                 if !ty.references_error() {
821                     self.report_ambiguous_associated_type(span,
822                                                           &ty.to_string(),
823                                                           "Trait",
824                                                           &assoc_name.as_str());
825                 }
826                 return (tcx.types.err, Def::Err);
827             }
828         };
829
830         let trait_did = bound.0.def_id;
831         let (assoc_ident, def_scope) = tcx.adjust(assoc_name, trait_did, ref_id);
832         let item = tcx.associated_items(trait_did).find(|i| {
833             Namespace::from(i.kind) == Namespace::Type &&
834             i.name.to_ident() == assoc_ident
835         })
836         .expect("missing associated type");
837
838         let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, bound);
839         let ty = self.normalize_ty(span, ty);
840
841         let def = Def::AssociatedTy(item.def_id);
842         if !item.vis.is_accessible_from(def_scope, tcx) {
843             let msg = format!("{} `{}` is private", def.kind_name(), assoc_name);
844             tcx.sess.span_err(span, &msg);
845         }
846         tcx.check_stability(item.def_id, ref_id, span);
847
848         (ty, def)
849     }
850
851     fn qpath_to_ty(&self,
852                    span: Span,
853                    opt_self_ty: Option<Ty<'tcx>>,
854                    item_def_id: DefId,
855                    trait_segment: &hir::PathSegment,
856                    item_segment: &hir::PathSegment)
857                    -> Ty<'tcx>
858     {
859         let tcx = self.tcx();
860         let trait_def_id = tcx.parent_def_id(item_def_id).unwrap();
861
862         self.prohibit_type_params(slice::ref_slice(item_segment));
863
864         let self_ty = if let Some(ty) = opt_self_ty {
865             ty
866         } else {
867             let path_str = tcx.item_path_str(trait_def_id);
868             self.report_ambiguous_associated_type(span,
869                                                   "Type",
870                                                   &path_str,
871                                                   &item_segment.name.as_str());
872             return tcx.types.err;
873         };
874
875         debug!("qpath_to_ty: self_type={:?}", self_ty);
876
877         let trait_ref = self.ast_path_to_mono_trait_ref(span,
878                                                         trait_def_id,
879                                                         self_ty,
880                                                         trait_segment);
881
882         debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
883
884         self.normalize_ty(span, tcx.mk_projection(item_def_id, trait_ref.substs))
885     }
886
887     pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
888         for segment in segments {
889             segment.with_parameters(|parameters| {
890                 for typ in &parameters.types {
891                     struct_span_err!(self.tcx().sess, typ.span, E0109,
892                                      "type parameters are not allowed on this type")
893                         .span_label(typ.span, "type parameter not allowed")
894                         .emit();
895                     break;
896                 }
897                 for lifetime in &parameters.lifetimes {
898                     struct_span_err!(self.tcx().sess, lifetime.span, E0110,
899                                      "lifetime parameters are not allowed on this type")
900                         .span_label(lifetime.span,
901                                     "lifetime parameter not allowed on this type")
902                         .emit();
903                     break;
904                 }
905                 for binding in &parameters.bindings {
906                     self.prohibit_projection(binding.span);
907                     break;
908                 }
909             })
910         }
911     }
912
913     pub fn prohibit_projection(&self, span: Span) {
914         let mut err = struct_span_err!(self.tcx().sess, span, E0229,
915                                        "associated type bindings are not allowed here");
916         err.span_label(span, "associated type not allowed here").emit();
917     }
918
919     // Check a type Path and convert it to a Ty.
920     pub fn def_to_ty(&self,
921                      opt_self_ty: Option<Ty<'tcx>>,
922                      path: &hir::Path,
923                      permit_variants: bool)
924                      -> Ty<'tcx> {
925         let tcx = self.tcx();
926
927         debug!("base_def_to_ty(def={:?}, opt_self_ty={:?}, path_segments={:?})",
928                path.def, opt_self_ty, path.segments);
929
930         let span = path.span;
931         match path.def {
932             Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) |
933             Def::Union(did) | Def::TyForeign(did) => {
934                 assert_eq!(opt_self_ty, None);
935                 self.prohibit_type_params(path.segments.split_last().unwrap().1);
936                 self.ast_path_to_ty(span, did, path.segments.last().unwrap())
937             }
938             Def::Variant(did) if permit_variants => {
939                 // Convert "variant type" as if it were a real type.
940                 // The resulting `Ty` is type of the variant's enum for now.
941                 assert_eq!(opt_self_ty, None);
942                 self.prohibit_type_params(path.segments.split_last().unwrap().1);
943                 self.ast_path_to_ty(span,
944                                     tcx.parent_def_id(did).unwrap(),
945                                     path.segments.last().unwrap())
946             }
947             Def::TyParam(did) => {
948                 assert_eq!(opt_self_ty, None);
949                 self.prohibit_type_params(&path.segments);
950
951                 let node_id = tcx.hir.as_local_node_id(did).unwrap();
952                 let item_id = tcx.hir.get_parent_node(node_id);
953                 let item_def_id = tcx.hir.local_def_id(item_id);
954                 let generics = tcx.generics_of(item_def_id);
955                 let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index];
956                 tcx.mk_param(index, tcx.hir.name(node_id))
957             }
958             Def::SelfTy(_, Some(def_id)) => {
959                 // Self in impl (we know the concrete type).
960
961                 assert_eq!(opt_self_ty, None);
962                 self.prohibit_type_params(&path.segments);
963
964                 tcx.at(span).type_of(def_id)
965             }
966             Def::SelfTy(Some(_), None) => {
967                 // Self in trait.
968                 assert_eq!(opt_self_ty, None);
969                 self.prohibit_type_params(&path.segments);
970                 tcx.mk_self_type()
971             }
972             Def::AssociatedTy(def_id) => {
973                 self.prohibit_type_params(&path.segments[..path.segments.len()-2]);
974                 self.qpath_to_ty(span,
975                                  opt_self_ty,
976                                  def_id,
977                                  &path.segments[path.segments.len()-2],
978                                  path.segments.last().unwrap())
979             }
980             Def::PrimTy(prim_ty) => {
981                 assert_eq!(opt_self_ty, None);
982                 self.prohibit_type_params(&path.segments);
983                 match prim_ty {
984                     hir::TyBool => tcx.types.bool,
985                     hir::TyChar => tcx.types.char,
986                     hir::TyInt(it) => tcx.mk_mach_int(it),
987                     hir::TyUint(uit) => tcx.mk_mach_uint(uit),
988                     hir::TyFloat(ft) => tcx.mk_mach_float(ft),
989                     hir::TyStr => tcx.mk_str()
990                 }
991             }
992             Def::Err => {
993                 self.set_tainted_by_errors();
994                 return self.tcx().types.err;
995             }
996             _ => span_bug!(span, "unexpected definition: {:?}", path.def)
997         }
998     }
999
1000     /// Parses the programmer's textual representation of a type into our
1001     /// internal notion of a type.
1002     pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
1003         debug!("ast_ty_to_ty(id={:?}, ast_ty={:?})",
1004                ast_ty.id, ast_ty);
1005
1006         let tcx = self.tcx();
1007
1008         let result_ty = match ast_ty.node {
1009             hir::TySlice(ref ty) => {
1010                 tcx.mk_slice(self.ast_ty_to_ty(&ty))
1011             }
1012             hir::TyPtr(ref mt) => {
1013                 tcx.mk_ptr(ty::TypeAndMut {
1014                     ty: self.ast_ty_to_ty(&mt.ty),
1015                     mutbl: mt.mutbl
1016                 })
1017             }
1018             hir::TyRptr(ref region, ref mt) => {
1019                 let r = self.ast_region_to_region(region, None);
1020                 debug!("TyRef r={:?}", r);
1021                 let t = self.ast_ty_to_ty(&mt.ty);
1022                 tcx.mk_ref(r, ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
1023             }
1024             hir::TyNever => {
1025                 tcx.types.never
1026             },
1027             hir::TyTup(ref fields) => {
1028                 tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t)), false)
1029             }
1030             hir::TyBareFn(ref bf) => {
1031                 require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
1032                 tcx.mk_fn_ptr(self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl))
1033             }
1034             hir::TyTraitObject(ref bounds, ref lifetime) => {
1035                 self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
1036             }
1037             hir::TyImplTraitExistential(_, ref lifetimes) => {
1038                 let def_id = tcx.hir.local_def_id(ast_ty.id);
1039                 self.impl_trait_ty_to_ty(def_id, lifetimes)
1040             }
1041             hir::TyImplTraitUniversal(fn_def_id, _) => {
1042                 let impl_trait_def_id = tcx.hir.local_def_id(ast_ty.id);
1043                 let generics = tcx.generics_of(fn_def_id);
1044                 let index = generics.type_param_to_index[&impl_trait_def_id.index];
1045                 tcx.mk_param(index,
1046                              Symbol::intern(&tcx.hir.node_to_pretty_string(ast_ty.id)))
1047             }
1048             hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
1049                 debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
1050                 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
1051                     self.ast_ty_to_ty(qself)
1052                 });
1053                 self.def_to_ty(opt_self_ty, path, false)
1054             }
1055             hir::TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => {
1056                 debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment);
1057                 let ty = self.ast_ty_to_ty(qself);
1058
1059                 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
1060                     path.def
1061                 } else {
1062                     Def::Err
1063                 };
1064                 self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
1065             }
1066             hir::TyArray(ref ty, length) => {
1067                 let length_def_id = tcx.hir.body_owner_def_id(length);
1068                 let substs = Substs::identity_for_item(tcx, length_def_id);
1069                 let length = tcx.mk_const(ty::Const {
1070                     val: ConstVal::Unevaluated(length_def_id, substs),
1071                     ty: tcx.types.usize
1072                 });
1073                 let array_ty = tcx.mk_ty(ty::TyArray(self.ast_ty_to_ty(&ty), length));
1074                 self.normalize_ty(ast_ty.span, array_ty)
1075             }
1076             hir::TyTypeof(ref _e) => {
1077                 struct_span_err!(tcx.sess, ast_ty.span, E0516,
1078                                  "`typeof` is a reserved keyword but unimplemented")
1079                     .span_label(ast_ty.span, "reserved keyword")
1080                     .emit();
1081
1082                 tcx.types.err
1083             }
1084             hir::TyInfer => {
1085                 // TyInfer also appears as the type of arguments or return
1086                 // values in a ExprClosure, or as
1087                 // the type of local variables. Both of these cases are
1088                 // handled specially and will not descend into this routine.
1089                 self.ty_infer(ast_ty.span)
1090             }
1091             hir::TyErr => {
1092                 tcx.types.err
1093             }
1094         };
1095
1096         self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
1097         result_ty
1098     }
1099
1100     pub fn impl_trait_ty_to_ty(&self, def_id: DefId, lifetimes: &[hir::Lifetime]) -> Ty<'tcx> {
1101         debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
1102         let tcx = self.tcx();
1103         let generics = tcx.generics_of(def_id);
1104
1105         // Fill in the substs of the parent generics
1106         debug!("impl_trait_ty_to_ty: generics={:?}", generics);
1107         let mut substs = Vec::with_capacity(generics.count());
1108         if let Some(parent_id) = generics.parent {
1109             let parent_generics = tcx.generics_of(parent_id);
1110             Substs::fill_item(
1111                 &mut substs, tcx, parent_generics,
1112                 &mut |def, _| tcx.mk_region(
1113                     ty::ReEarlyBound(def.to_early_bound_region_data())),
1114                 &mut |def, _| tcx.mk_param_from_def(def)
1115             );
1116
1117             // Replace all lifetimes with 'static
1118             for subst in &mut substs {
1119                 if let Some(_) = subst.as_region() {
1120                     *subst = Kind::from(&RegionKind::ReStatic);
1121                 }
1122             }
1123             debug!("impl_trait_ty_to_ty: substs from parent = {:?}", substs);
1124         }
1125         assert_eq!(substs.len(), generics.parent_count());
1126
1127         // Fill in our own generics with the resolved lifetimes
1128         assert_eq!(lifetimes.len(), generics.own_count());
1129         substs.extend(lifetimes.iter().map(|lt|
1130             Kind::from(self.ast_region_to_region(lt, None))));
1131
1132         debug!("impl_trait_ty_to_ty: final substs = {:?}", substs);
1133
1134         tcx.mk_anon(def_id, tcx.intern_substs(&substs))
1135     }
1136
1137     pub fn ty_of_arg(&self,
1138                      ty: &hir::Ty,
1139                      expected_ty: Option<Ty<'tcx>>)
1140                      -> Ty<'tcx>
1141     {
1142         match ty.node {
1143             hir::TyInfer if expected_ty.is_some() => {
1144                 self.record_ty(ty.hir_id, expected_ty.unwrap(), ty.span);
1145                 expected_ty.unwrap()
1146             }
1147             _ => self.ast_ty_to_ty(ty),
1148         }
1149     }
1150
1151     pub fn ty_of_fn(&self,
1152                     unsafety: hir::Unsafety,
1153                     abi: abi::Abi,
1154                     decl: &hir::FnDecl)
1155                     -> ty::PolyFnSig<'tcx> {
1156         debug!("ty_of_fn");
1157
1158         let tcx = self.tcx();
1159         let input_tys: Vec<Ty> =
1160             decl.inputs.iter().map(|a| self.ty_of_arg(a, None)).collect();
1161
1162         let output_ty = match decl.output {
1163             hir::Return(ref output) => self.ast_ty_to_ty(output),
1164             hir::DefaultReturn(..) => tcx.mk_nil(),
1165         };
1166
1167         debug!("ty_of_fn: output_ty={:?}", output_ty);
1168
1169         let bare_fn_ty = ty::Binder(tcx.mk_fn_sig(
1170             input_tys.into_iter(),
1171             output_ty,
1172             decl.variadic,
1173             unsafety,
1174             abi
1175         ));
1176
1177         // Find any late-bound regions declared in return type that do
1178         // not appear in the arguments. These are not wellformed.
1179         //
1180         // Example:
1181         //     for<'a> fn() -> &'a str <-- 'a is bad
1182         //     for<'a> fn(&'a String) -> &'a str <-- 'a is ok
1183         let inputs = bare_fn_ty.inputs();
1184         let late_bound_in_args = tcx.collect_constrained_late_bound_regions(
1185             &inputs.map_bound(|i| i.to_owned()));
1186         let output = bare_fn_ty.output();
1187         let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
1188         for br in late_bound_in_ret.difference(&late_bound_in_args) {
1189             let br_name = match *br {
1190                 ty::BrNamed(_, name) => name,
1191                 _ => {
1192                     span_bug!(
1193                         decl.output.span(),
1194                         "anonymous bound region {:?} in return but not args",
1195                         br);
1196                 }
1197             };
1198             struct_span_err!(tcx.sess,
1199                              decl.output.span(),
1200                              E0581,
1201                              "return type references lifetime `{}`, \
1202                              which does not appear in the fn input types",
1203                              br_name)
1204                 .emit();
1205         }
1206
1207         bare_fn_ty
1208     }
1209
1210     /// Given the bounds on an object, determines what single region bound (if any) we can
1211     /// use to summarize this type. The basic idea is that we will use the bound the user
1212     /// provided, if they provided one, and otherwise search the supertypes of trait bounds
1213     /// for region bounds. It may be that we can derive no bound at all, in which case
1214     /// we return `None`.
1215     fn compute_object_lifetime_bound(&self,
1216         span: Span,
1217         existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
1218         -> Option<ty::Region<'tcx>> // if None, use the default
1219     {
1220         let tcx = self.tcx();
1221
1222         debug!("compute_opt_region_bound(existential_predicates={:?})",
1223                existential_predicates);
1224
1225         // No explicit region bound specified. Therefore, examine trait
1226         // bounds and see if we can derive region bounds from those.
1227         let derived_region_bounds =
1228             object_region_bounds(tcx, existential_predicates);
1229
1230         // If there are no derived region bounds, then report back that we
1231         // can find no region bound. The caller will use the default.
1232         if derived_region_bounds.is_empty() {
1233             return None;
1234         }
1235
1236         // If any of the derived region bounds are 'static, that is always
1237         // the best choice.
1238         if derived_region_bounds.iter().any(|&r| ty::ReStatic == *r) {
1239             return Some(tcx.types.re_static);
1240         }
1241
1242         // Determine whether there is exactly one unique region in the set
1243         // of derived region bounds. If so, use that. Otherwise, report an
1244         // error.
1245         let r = derived_region_bounds[0];
1246         if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
1247             span_err!(tcx.sess, span, E0227,
1248                       "ambiguous lifetime bound, explicit lifetime bound required");
1249         }
1250         return Some(r);
1251     }
1252 }
1253
1254 /// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the
1255 /// remaining general trait bounds.
1256 fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1257                                          trait_bounds: &'b [hir::PolyTraitRef])
1258     -> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
1259 {
1260     let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
1261         // Checks whether `trait_did` is an auto trait and adds it to `auto_traits` if so.
1262         match bound.trait_ref.path.def {
1263             Def::Trait(trait_did) if tcx.trait_is_auto(trait_did) => {
1264                 true
1265             }
1266             _ => false
1267         }
1268     });
1269
1270     let auto_traits = auto_traits.into_iter().map(|tr| {
1271         if let Def::Trait(trait_did) = tr.trait_ref.path.def {
1272             trait_did
1273         } else {
1274             unreachable!()
1275         }
1276     }).collect::<Vec<_>>();
1277
1278     (auto_traits, trait_bounds)
1279 }
1280
1281 fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
1282                              ty_param_defs: &[ty::TypeParameterDef]) {
1283     let accepted = ty_param_defs.len();
1284     let required = ty_param_defs.iter().take_while(|x| !x.has_default).count();
1285     if supplied < required {
1286         let expected = if required < accepted {
1287             "expected at least"
1288         } else {
1289             "expected"
1290         };
1291         let arguments_plural = if required == 1 { "" } else { "s" };
1292
1293         struct_span_err!(tcx.sess, span, E0243,
1294                 "wrong number of type arguments: {} {}, found {}",
1295                 expected, required, supplied)
1296             .span_label(span,
1297                 format!("{} {} type argument{}",
1298                     expected,
1299                     required,
1300                     arguments_plural))
1301             .emit();
1302     } else if supplied > accepted {
1303         let expected = if required < accepted {
1304             format!("expected at most {}", accepted)
1305         } else {
1306             format!("expected {}", accepted)
1307         };
1308         let arguments_plural = if accepted == 1 { "" } else { "s" };
1309
1310         struct_span_err!(tcx.sess, span, E0244,
1311                 "wrong number of type arguments: {}, found {}",
1312                 expected, supplied)
1313             .span_label(
1314                 span,
1315                 format!("{} type argument{}",
1316                     if accepted == 0 { "expected no" } else { &expected },
1317                     arguments_plural)
1318             )
1319             .emit();
1320     }
1321 }
1322
1323 fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected: usize) {
1324     let label = if number < expected {
1325         if expected == 1 {
1326             format!("expected {} lifetime parameter", expected)
1327         } else {
1328             format!("expected {} lifetime parameters", expected)
1329         }
1330     } else {
1331         let additional = number - expected;
1332         if additional == 1 {
1333             "unexpected lifetime parameter".to_string()
1334         } else {
1335             format!("{} unexpected lifetime parameters", additional)
1336         }
1337     };
1338     struct_span_err!(tcx.sess, span, E0107,
1339                      "wrong number of lifetime parameters: expected {}, found {}",
1340                      expected, number)
1341         .span_label(span, label)
1342         .emit();
1343 }
1344
1345 // A helper struct for conveniently grouping a set of bounds which we pass to
1346 // and return from functions in multiple places.
1347 #[derive(PartialEq, Eq, Clone, Debug)]
1348 pub struct Bounds<'tcx> {
1349     pub region_bounds: Vec<ty::Region<'tcx>>,
1350     pub implicitly_sized: bool,
1351     pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
1352     pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
1353 }
1354
1355 impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
1356     pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
1357                       -> Vec<ty::Predicate<'tcx>>
1358     {
1359         let mut vec = Vec::new();
1360
1361         // If it could be sized, and is, add the sized predicate
1362         if self.implicitly_sized {
1363             if let Some(sized) = tcx.lang_items().sized_trait() {
1364                 let trait_ref = ty::TraitRef {
1365                     def_id: sized,
1366                     substs: tcx.mk_substs_trait(param_ty, &[])
1367                 };
1368                 vec.push(trait_ref.to_predicate());
1369             }
1370         }
1371
1372         for &region_bound in &self.region_bounds {
1373             // account for the binder being introduced below; no need to shift `param_ty`
1374             // because, at present at least, it can only refer to early-bound regions
1375             let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
1376             vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
1377         }
1378
1379         for bound_trait_ref in &self.trait_bounds {
1380             vec.push(bound_trait_ref.to_predicate());
1381         }
1382
1383         for projection in &self.projection_bounds {
1384             vec.push(projection.to_predicate());
1385         }
1386
1387         vec
1388     }
1389 }