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