]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/astconv.rs
Auto merge of #36862 - chamoysvoice:E0220, r=GuillaumeGomez
[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` and a `RegionScope`.
14 //!
15 //! The parameterization of `ast_ty_to_ty()` is because it behaves
16 //! somewhat differently during the collect and check phases,
17 //! particularly with respect to looking up the types of top-level
18 //! items.  In the collect phase, the crate context is used as the
19 //! `AstConv` instance; in this phase, the `get_item_type_scheme()`
20 //! function triggers a recursive call to `type_scheme_of_item()`
21 //! (note that `ast_ty_to_ty()` will detect recursive types and report
22 //! an error).  In the check phase, when the FnCtxt is used as the
23 //! `AstConv`, `get_item_type_scheme()` just looks up the item type in
24 //! `tcx.tcache` (using `ty::lookup_item_type`).
25 //!
26 //! The `RegionScope` trait controls what happens when the user does
27 //! not specify a region in some location where a region is required
28 //! (e.g., if the user writes `&Foo` as a type rather than `&'a Foo`).
29 //! See the `rscope` module for more details.
30 //!
31 //! Unlike the `AstConv` trait, the region scope can change as we descend
32 //! the type.  This is to accommodate the fact that (a) fn types are binding
33 //! scopes and (b) the default region may change.  To understand case (a),
34 //! consider something like:
35 //!
36 //!   type foo = { x: &a.int, y: |&a.int| }
37 //!
38 //! The type of `x` is an error because there is no region `a` in scope.
39 //! In the type of `y`, however, region `a` is considered a bound region
40 //! as it does not already appear in scope.
41 //!
42 //! Case (b) says that if you have a type:
43 //!   type foo<'a> = ...;
44 //!   type bar = fn(&foo, &a.foo)
45 //! The fully expanded version of type bar is:
46 //!   type bar = fn(&'foo &, &a.foo<'a>)
47 //! Note that the self region for the `foo` defaulted to `&` in the first
48 //! case but `&a` in the second.  Basically, defaults that appear inside
49 //! an rptr (`&r.T`) use the region `r` that appears in the rptr.
50
51 use rustc_const_eval::eval_length;
52 use hir::{self, SelfKind};
53 use hir::def::{Def, PathResolution};
54 use hir::def_id::DefId;
55 use hir::print as pprust;
56 use middle::resolve_lifetime as rl;
57 use rustc::lint;
58 use rustc::ty::subst::{Subst, Substs};
59 use rustc::traits;
60 use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
61 use rustc::ty::wf::object_region_bounds;
62 use rustc_back::slice;
63 use require_c_abi_if_variadic;
64 use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
65              ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope,
66              ElisionFailureInfo, ElidedLifetime};
67 use rscope::{AnonTypeScope, MaybeWithAnonTypes};
68 use util::common::{ErrorReported, FN_OUTPUT_NAME};
69 use util::nodemap::{NodeMap, FnvHashSet};
70
71 use std::cell::RefCell;
72 use syntax::{abi, ast};
73 use syntax::feature_gate::{GateIssue, emit_feature_err};
74 use syntax::parse::token::{self, keywords};
75 use syntax_pos::{Span, Pos};
76 use errors::DiagnosticBuilder;
77
78 pub trait AstConv<'gcx, 'tcx> {
79     fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
80
81     /// A cache used for the result of `ast_ty_to_ty_cache`
82     fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>>;
83
84     /// Returns the generic type and lifetime parameters for an item.
85     fn get_generics(&self, span: Span, id: DefId)
86                     -> Result<&'tcx ty::Generics<'tcx>, ErrorReported>;
87
88     /// Identify the type scheme for an item with a type, like a type
89     /// alias, fn, or struct. This allows you to figure out the set of
90     /// type parameters defined on the item.
91     fn get_item_type_scheme(&self, span: Span, id: DefId)
92                             -> Result<ty::TypeScheme<'tcx>, ErrorReported>;
93
94     /// Returns the `TraitDef` for a given trait. This allows you to
95     /// figure out the set of type parameters defined on the trait.
96     fn get_trait_def(&self, span: Span, id: DefId)
97                      -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>;
98
99     /// Ensure that the super-predicates for the trait with the given
100     /// id are available and also for the transitive set of
101     /// super-predicates.
102     fn ensure_super_predicates(&self, span: Span, id: DefId)
103                                -> Result<(), ErrorReported>;
104
105     /// Returns the set of bounds in scope for the type parameter with
106     /// the given id.
107     fn get_type_parameter_bounds(&self, span: Span, def_id: ast::NodeId)
108                                  -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>;
109
110     /// Returns true if the trait with id `trait_def_id` defines an
111     /// associated type with the name `name`.
112     fn trait_defines_associated_type_named(&self, trait_def_id: DefId, name: ast::Name)
113                                            -> bool;
114
115     /// Return an (optional) substitution to convert bound type parameters that
116     /// are in scope into free ones. This function should only return Some
117     /// within a fn body.
118     /// See ParameterEnvironment::free_substs for more information.
119     fn get_free_substs(&self) -> Option<&Substs<'tcx>>;
120
121     /// What type should we use when a type is omitted?
122     fn ty_infer(&self, span: Span) -> Ty<'tcx>;
123
124     /// Same as ty_infer, but with a known type parameter definition.
125     fn ty_infer_for_def(&self,
126                         _def: &ty::TypeParameterDef<'tcx>,
127                         _substs: &Substs<'tcx>,
128                         span: Span) -> Ty<'tcx> {
129         self.ty_infer(span)
130     }
131
132     /// Projecting an associated type from a (potentially)
133     /// higher-ranked trait reference is more complicated, because of
134     /// the possibility of late-bound regions appearing in the
135     /// associated type binding. This is not legal in function
136     /// signatures for that reason. In a function body, we can always
137     /// handle it because we can use inference variables to remove the
138     /// late-bound regions.
139     fn projected_ty_from_poly_trait_ref(&self,
140                                         span: Span,
141                                         poly_trait_ref: ty::PolyTraitRef<'tcx>,
142                                         item_name: ast::Name)
143                                         -> Ty<'tcx>;
144
145     /// Project an associated type from a non-higher-ranked trait reference.
146     /// This is fairly straightforward and can be accommodated in any context.
147     fn projected_ty(&self,
148                     span: Span,
149                     _trait_ref: ty::TraitRef<'tcx>,
150                     _item_name: ast::Name)
151                     -> Ty<'tcx>;
152
153     /// Invoked when we encounter an error from some prior pass
154     /// (e.g. resolve) that is translated into a ty-error. This is
155     /// used to help suppress derived errors typeck might otherwise
156     /// report.
157     fn set_tainted_by_errors(&self);
158 }
159
160 #[derive(PartialEq, Eq)]
161 pub enum PathParamMode {
162     // Any path in a type context.
163     Explicit,
164     // The `module::Type` in `module::Type::method` in an expression.
165     Optional
166 }
167
168 struct ConvertedBinding<'tcx> {
169     item_name: ast::Name,
170     ty: Ty<'tcx>,
171     span: Span,
172 }
173
174 type TraitAndProjections<'tcx> = (ty::PolyTraitRef<'tcx>, Vec<ty::PolyProjectionPredicate<'tcx>>);
175
176 /// Dummy type used for the `Self` of a `TraitRef` created for converting
177 /// a trait object, and which gets removed in `ExistentialTraitRef`.
178 /// This type must not appear anywhere in other converted types.
179 const TRAIT_OBJECT_DUMMY_SELF: ty::TypeVariants<'static> = ty::TyInfer(ty::FreshTy(0));
180
181 pub fn ast_region_to_region<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
182                                             lifetime: &hir::Lifetime)
183                                             -> &'tcx ty::Region {
184     let r = match tcx.named_region_map.defs.get(&lifetime.id) {
185         None => {
186             // should have been recorded by the `resolve_lifetime` pass
187             span_bug!(lifetime.span, "unresolved lifetime");
188         }
189
190         Some(&rl::DefStaticRegion) => {
191             ty::ReStatic
192         }
193
194         Some(&rl::DefLateBoundRegion(debruijn, id)) => {
195             // If this region is declared on a function, it will have
196             // an entry in `late_bound`, but if it comes from
197             // `for<'a>` in some type or something, it won't
198             // necessarily have one. In that case though, we won't be
199             // changed from late to early bound, so we can just
200             // substitute false.
201             let issue_32330 = tcx.named_region_map
202                                  .late_bound
203                                  .get(&id)
204                                  .cloned()
205                                  .unwrap_or(ty::Issue32330::WontChange);
206             ty::ReLateBound(debruijn, ty::BrNamed(tcx.map.local_def_id(id),
207                                                   lifetime.name,
208                                                   issue_32330))
209         }
210
211         Some(&rl::DefEarlyBoundRegion(index, _)) => {
212             ty::ReEarlyBound(ty::EarlyBoundRegion {
213                 index: index,
214                 name: lifetime.name
215             })
216         }
217
218         Some(&rl::DefFreeRegion(scope, id)) => {
219             // As in DefLateBoundRegion above, could be missing for some late-bound
220             // regions, but also for early-bound regions.
221             let issue_32330 = tcx.named_region_map
222                                  .late_bound
223                                  .get(&id)
224                                  .cloned()
225                                  .unwrap_or(ty::Issue32330::WontChange);
226             ty::ReFree(ty::FreeRegion {
227                     scope: scope.to_code_extent(&tcx.region_maps),
228                     bound_region: ty::BrNamed(tcx.map.local_def_id(id),
229                                               lifetime.name,
230                                               issue_32330)
231             })
232
233                 // (*) -- not late-bound, won't change
234         }
235     };
236
237     debug!("ast_region_to_region(lifetime={:?} id={}) yields {:?}",
238            lifetime,
239            lifetime.id,
240            r);
241
242     tcx.mk_region(r)
243 }
244
245 fn report_elision_failure(
246     db: &mut DiagnosticBuilder,
247     params: Vec<ElisionFailureInfo>)
248 {
249     let mut m = String::new();
250     let len = params.len();
251
252     let elided_params: Vec<_> = params.into_iter()
253                                        .filter(|info| info.lifetime_count > 0)
254                                        .collect();
255
256     let elided_len = elided_params.len();
257
258     for (i, info) in elided_params.into_iter().enumerate() {
259         let ElisionFailureInfo {
260             name, lifetime_count: n, have_bound_regions
261         } = info;
262
263         let help_name = if name.is_empty() {
264             format!("argument {}", i + 1)
265         } else {
266             format!("`{}`", name)
267         };
268
269         m.push_str(&(if n == 1 {
270             help_name
271         } else {
272             format!("one of {}'s {} elided {}lifetimes", help_name, n,
273                     if have_bound_regions { "free " } else { "" } )
274         })[..]);
275
276         if elided_len == 2 && i == 0 {
277             m.push_str(" or ");
278         } else if i + 2 == elided_len {
279             m.push_str(", or ");
280         } else if i != elided_len - 1 {
281             m.push_str(", ");
282         }
283
284     }
285
286     if len == 0 {
287         help!(db,
288                    "this function's return type contains a borrowed value, but \
289                     there is no value for it to be borrowed from");
290         help!(db,
291                    "consider giving it a 'static lifetime");
292     } else if elided_len == 0 {
293         help!(db,
294                    "this function's return type contains a borrowed value with \
295                     an elided lifetime, but the lifetime cannot be derived from \
296                     the arguments");
297         help!(db,
298                    "consider giving it an explicit bounded or 'static \
299                     lifetime");
300     } else if elided_len == 1 {
301         help!(db,
302                    "this function's return type contains a borrowed value, but \
303                     the signature does not say which {} it is borrowed from",
304                    m);
305     } else {
306         help!(db,
307                    "this function's return type contains a borrowed value, but \
308                     the signature does not say whether it is borrowed from {}",
309                    m);
310     }
311 }
312
313 impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
314     pub fn opt_ast_region_to_region(&self,
315         rscope: &RegionScope,
316         default_span: Span,
317         opt_lifetime: &Option<hir::Lifetime>) -> &'tcx ty::Region
318     {
319         let r = match *opt_lifetime {
320             Some(ref lifetime) => {
321                 ast_region_to_region(self.tcx(), lifetime)
322             }
323
324             None => self.tcx().mk_region(match rscope.anon_regions(default_span, 1) {
325                 Ok(rs) => rs[0],
326                 Err(params) => {
327                     let ampersand_span = Span { hi: default_span.lo, ..default_span};
328
329                     let mut err = struct_span_err!(self.tcx().sess, ampersand_span, E0106,
330                                                  "missing lifetime specifier");
331                     err.span_label(ampersand_span, &format!("expected lifetime parameter"));
332
333                     if let Some(params) = params {
334                         report_elision_failure(&mut err, params);
335                     }
336                     err.emit();
337                     ty::ReStatic
338                 }
339             })
340         };
341
342         debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {:?}",
343                 opt_lifetime,
344                 r);
345
346         r
347     }
348
349     /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
350     /// returns an appropriate set of substitutions for this particular reference to `I`.
351     pub fn ast_path_substs_for_ty(&self,
352         rscope: &RegionScope,
353         span: Span,
354         param_mode: PathParamMode,
355         def_id: DefId,
356         item_segment: &hir::PathSegment)
357         -> &'tcx Substs<'tcx>
358     {
359         let tcx = self.tcx();
360
361         match item_segment.parameters {
362             hir::AngleBracketedParameters(_) => {}
363             hir::ParenthesizedParameters(..) => {
364                 struct_span_err!(tcx.sess, span, E0214,
365                           "parenthesized parameters may only be used with a trait")
366                     .span_label(span, &format!("only traits may use parentheses"))
367                     .emit();
368
369                 return Substs::for_item(tcx, def_id, |_, _| {
370                     tcx.mk_region(ty::ReStatic)
371                 }, |_, _| {
372                     tcx.types.err
373                 });
374             }
375         }
376
377         let (substs, assoc_bindings) =
378             self.create_substs_for_ast_path(rscope,
379                                             span,
380                                             param_mode,
381                                             def_id,
382                                             &item_segment.parameters,
383                                             None);
384
385         assoc_bindings.first().map(|b| self.tcx().prohibit_projection(b.span));
386
387         substs
388     }
389
390     /// Given the type/region arguments provided to some path (along with
391     /// an implicit Self, if this is a trait reference) returns the complete
392     /// set of substitutions. This may involve applying defaulted type parameters.
393     ///
394     /// Note that the type listing given here is *exactly* what the user provided.
395     fn create_substs_for_ast_path(&self,
396         rscope: &RegionScope,
397         span: Span,
398         param_mode: PathParamMode,
399         def_id: DefId,
400         parameters: &hir::PathParameters,
401         self_ty: Option<Ty<'tcx>>)
402         -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
403     {
404         let tcx = self.tcx();
405
406         debug!("create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
407                parameters={:?})",
408                def_id, self_ty, parameters);
409
410         let (lifetimes, num_types_provided) = match *parameters {
411             hir::AngleBracketedParameters(ref data) => {
412                 if param_mode == PathParamMode::Optional && data.types.is_empty() {
413                     (&data.lifetimes[..], None)
414                 } else {
415                     (&data.lifetimes[..], Some(data.types.len()))
416                 }
417             }
418             hir::ParenthesizedParameters(_) => (&[][..], Some(1))
419         };
420
421         // If the type is parameterized by this region, then replace this
422         // region with the current anon region binding (in other words,
423         // whatever & would get replaced with).
424         let decl_generics = match self.get_generics(span, def_id) {
425             Ok(generics) => generics,
426             Err(ErrorReported) => {
427                 // No convenient way to recover from a cycle here. Just bail. Sorry!
428                 self.tcx().sess.abort_if_errors();
429                 bug!("ErrorReported returned, but no errors reports?")
430             }
431         };
432         let expected_num_region_params = decl_generics.regions.len();
433         let supplied_num_region_params = lifetimes.len();
434         let regions = if expected_num_region_params == supplied_num_region_params {
435             lifetimes.iter().map(|l| *ast_region_to_region(tcx, l)).collect()
436         } else {
437             let anon_regions =
438                 rscope.anon_regions(span, expected_num_region_params);
439
440             if supplied_num_region_params != 0 || anon_regions.is_err() {
441                 report_lifetime_number_error(tcx, span,
442                                              supplied_num_region_params,
443                                              expected_num_region_params);
444             }
445
446             match anon_regions {
447                 Ok(anon_regions) => anon_regions,
448                 Err(_) => (0..expected_num_region_params).map(|_| ty::ReStatic).collect()
449             }
450         };
451
452         // If a self-type was declared, one should be provided.
453         assert_eq!(decl_generics.has_self, self_ty.is_some());
454
455         // Check the number of type parameters supplied by the user.
456         if let Some(num_provided) = num_types_provided {
457             let ty_param_defs = &decl_generics.types[self_ty.is_some() as usize..];
458             check_type_argument_count(tcx, span, num_provided, ty_param_defs);
459         }
460
461         let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
462         let default_needs_object_self = |p: &ty::TypeParameterDef<'tcx>| {
463             if let Some(ref default) = p.default {
464                 if is_object && default.has_self_ty() {
465                     // There is no suitable inference default for a type parameter
466                     // that references self, in an object type.
467                     return true;
468                 }
469             }
470
471             false
472         };
473
474         let mut output_assoc_binding = None;
475         let substs = Substs::for_item(tcx, def_id, |def, _| {
476             let i = def.index as usize - self_ty.is_some() as usize;
477             tcx.mk_region(regions[i])
478         }, |def, substs| {
479             let i = def.index as usize;
480
481             // Handle Self first, so we can adjust the index to match the AST.
482             if let (0, Some(ty)) = (i, self_ty) {
483                 return ty;
484             }
485
486             let i = i - self_ty.is_some() as usize - decl_generics.regions.len();
487             if num_types_provided.map_or(false, |n| i < n) {
488                 // A provided type parameter.
489                 match *parameters {
490                     hir::AngleBracketedParameters(ref data) => {
491                         self.ast_ty_arg_to_ty(rscope, Some(def), substs, &data.types[i])
492                     }
493                     hir::ParenthesizedParameters(ref data) => {
494                         assert_eq!(i, 0);
495                         let (ty, assoc) =
496                             self.convert_parenthesized_parameters(rscope, substs, data);
497                         output_assoc_binding = Some(assoc);
498                         ty
499                     }
500                 }
501             } else if num_types_provided.is_none() {
502                 // No type parameters were provided, we can infer all.
503                 let ty_var = if !default_needs_object_self(def) {
504                     self.ty_infer_for_def(def, substs, span)
505                 } else {
506                     self.ty_infer(span)
507                 };
508                 ty_var
509             } else if let Some(default) = def.default {
510                 // No type parameter provided, but a default exists.
511
512                 // If we are converting an object type, then the
513                 // `Self` parameter is unknown. However, some of the
514                 // other type parameters may reference `Self` in their
515                 // defaults. This will lead to an ICE if we are not
516                 // careful!
517                 if default_needs_object_self(def) {
518                     struct_span_err!(tcx.sess, span, E0393,
519                                      "the type parameter `{}` must be explicitly specified",
520                                      def.name)
521                         .span_label(span, &format!("missing reference to `{}`", def.name))
522                         .note(&format!("because of the default `Self` reference, \
523                                         type parameters must be specified on object types"))
524                         .emit();
525                     tcx.types.err
526                 } else {
527                     // This is a default type parameter.
528                     default.subst_spanned(tcx, substs, Some(span))
529                 }
530             } else {
531                 // We've already errored above about the mismatch.
532                 tcx.types.err
533             }
534         });
535
536         let assoc_bindings = match *parameters {
537             hir::AngleBracketedParameters(ref data) => {
538                 data.bindings.iter().map(|b| {
539                     ConvertedBinding {
540                         item_name: b.name,
541                         ty: self.ast_ty_to_ty(rscope, &b.ty),
542                         span: b.span
543                     }
544                 }).collect()
545             }
546             hir::ParenthesizedParameters(ref data) => {
547                 vec![output_assoc_binding.unwrap_or_else(|| {
548                     // This is an error condition, but we should
549                     // get the associated type binding anyway.
550                     self.convert_parenthesized_parameters(rscope, substs, data).1
551                 })]
552             }
553         };
554
555         debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}) -> {:?}",
556                decl_generics, self_ty, substs);
557
558         (substs, assoc_bindings)
559     }
560
561     /// Returns the appropriate lifetime to use for any output lifetimes
562     /// (if one exists) and a vector of the (pattern, number of lifetimes)
563     /// corresponding to each input type/pattern.
564     fn find_implied_output_region(&self,
565                                   input_tys: &[Ty<'tcx>],
566                                   input_pats: Vec<String>) -> ElidedLifetime
567     {
568         let tcx = self.tcx();
569         let mut lifetimes_for_params = Vec::new();
570         let mut possible_implied_output_region = None;
571
572         for (input_type, input_pat) in input_tys.iter().zip(input_pats) {
573             let mut regions = FnvHashSet();
574             let have_bound_regions = tcx.collect_regions(input_type, &mut regions);
575
576             debug!("find_implied_output_regions: collected {:?} from {:?} \
577                     have_bound_regions={:?}", &regions, input_type, have_bound_regions);
578
579             if regions.len() == 1 {
580                 // there's a chance that the unique lifetime of this
581                 // iteration will be the appropriate lifetime for output
582                 // parameters, so lets store it.
583                 possible_implied_output_region = regions.iter().cloned().next();
584             }
585
586             lifetimes_for_params.push(ElisionFailureInfo {
587                 name: input_pat,
588                 lifetime_count: regions.len(),
589                 have_bound_regions: have_bound_regions
590             });
591         }
592
593         if lifetimes_for_params.iter().map(|e| e.lifetime_count).sum::<usize>() == 1 {
594             Ok(*possible_implied_output_region.unwrap())
595         } else {
596             Err(Some(lifetimes_for_params))
597         }
598     }
599
600     fn convert_ty_with_lifetime_elision(&self,
601                                         elided_lifetime: ElidedLifetime,
602                                         ty: &hir::Ty,
603                                         anon_scope: Option<AnonTypeScope>)
604                                         -> Ty<'tcx>
605     {
606         match elided_lifetime {
607             Ok(implied_output_region) => {
608                 let rb = ElidableRscope::new(implied_output_region);
609                 self.ast_ty_to_ty(&MaybeWithAnonTypes::new(rb, anon_scope), ty)
610             }
611             Err(param_lifetimes) => {
612                 // All regions must be explicitly specified in the output
613                 // if the lifetime elision rules do not apply. This saves
614                 // the user from potentially-confusing errors.
615                 let rb = UnelidableRscope::new(param_lifetimes);
616                 self.ast_ty_to_ty(&MaybeWithAnonTypes::new(rb, anon_scope), ty)
617             }
618         }
619     }
620
621     fn convert_parenthesized_parameters(&self,
622                                         rscope: &RegionScope,
623                                         region_substs: &Substs<'tcx>,
624                                         data: &hir::ParenthesizedParameterData)
625                                         -> (Ty<'tcx>, ConvertedBinding<'tcx>)
626     {
627         let anon_scope = rscope.anon_type_scope();
628         let binding_rscope = MaybeWithAnonTypes::new(BindingRscope::new(), anon_scope);
629         let inputs: Vec<_> = data.inputs.iter().map(|a_t| {
630             self.ast_ty_arg_to_ty(&binding_rscope, None, region_substs, a_t)
631         }).collect();
632         let input_params = vec![String::new(); inputs.len()];
633         let implied_output_region = self.find_implied_output_region(&inputs, input_params);
634
635         let (output, output_span) = match data.output {
636             Some(ref output_ty) => {
637                 (self.convert_ty_with_lifetime_elision(implied_output_region,
638                                                        &output_ty,
639                                                        anon_scope),
640                  output_ty.span)
641             }
642             None => {
643                 (self.tcx().mk_nil(), data.span)
644             }
645         };
646
647         let output_binding = ConvertedBinding {
648             item_name: token::intern(FN_OUTPUT_NAME),
649             ty: output,
650             span: output_span
651         };
652
653         (self.tcx().mk_tup(inputs), output_binding)
654     }
655
656     pub fn instantiate_poly_trait_ref(&self,
657         rscope: &RegionScope,
658         ast_trait_ref: &hir::PolyTraitRef,
659         self_ty: Ty<'tcx>,
660         poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
661         -> ty::PolyTraitRef<'tcx>
662     {
663         let trait_ref = &ast_trait_ref.trait_ref;
664         let trait_def_id = self.trait_def_id(trait_ref);
665         self.ast_path_to_poly_trait_ref(rscope,
666                                         trait_ref.path.span,
667                                         PathParamMode::Explicit,
668                                         trait_def_id,
669                                         self_ty,
670                                         trait_ref.ref_id,
671                                         trait_ref.path.segments.last().unwrap(),
672                                         poly_projections)
673     }
674
675     /// Instantiates the path for the given trait reference, assuming that it's
676     /// bound to a valid trait type. Returns the def_id for the defining trait.
677     /// Fails if the type is a type other than a trait type.
678     ///
679     /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
680     /// are disallowed. Otherwise, they are pushed onto the vector given.
681     pub fn instantiate_mono_trait_ref(&self,
682         rscope: &RegionScope,
683         trait_ref: &hir::TraitRef,
684         self_ty: Ty<'tcx>)
685         -> ty::TraitRef<'tcx>
686     {
687         let trait_def_id = self.trait_def_id(trait_ref);
688         self.ast_path_to_mono_trait_ref(rscope,
689                                         trait_ref.path.span,
690                                         PathParamMode::Explicit,
691                                         trait_def_id,
692                                         self_ty,
693                                         trait_ref.path.segments.last().unwrap())
694     }
695
696     fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
697         let path = &trait_ref.path;
698         match self.tcx().expect_def(trait_ref.ref_id) {
699             Def::Trait(trait_def_id) => trait_def_id,
700             Def::Err => {
701                 self.tcx().sess.fatal("cannot continue compilation due to previous error");
702             }
703             _ => {
704                 span_fatal!(self.tcx().sess, path.span, E0245, "`{}` is not a trait",
705                             path);
706             }
707         }
708     }
709
710     fn ast_path_to_poly_trait_ref(&self,
711         rscope: &RegionScope,
712         span: Span,
713         param_mode: PathParamMode,
714         trait_def_id: DefId,
715         self_ty: Ty<'tcx>,
716         path_id: ast::NodeId,
717         trait_segment: &hir::PathSegment,
718         poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
719         -> ty::PolyTraitRef<'tcx>
720     {
721         debug!("ast_path_to_poly_trait_ref(trait_segment={:?})", trait_segment);
722         // The trait reference introduces a binding level here, so
723         // we need to shift the `rscope`. It'd be nice if we could
724         // do away with this rscope stuff and work this knowledge
725         // into resolve_lifetimes, as we do with non-omitted
726         // lifetimes. Oh well, not there yet.
727         let shifted_rscope = &ShiftedRscope::new(rscope);
728
729         let (substs, assoc_bindings) =
730             self.create_substs_for_ast_trait_ref(shifted_rscope,
731                                                  span,
732                                                  param_mode,
733                                                  trait_def_id,
734                                                  self_ty,
735                                                  trait_segment);
736         let poly_trait_ref = ty::Binder(ty::TraitRef::new(trait_def_id, substs));
737
738         poly_projections.extend(assoc_bindings.iter().filter_map(|binding| {
739             // specify type to assert that error was already reported in Err case:
740             let predicate: Result<_, ErrorReported> =
741                 self.ast_type_binding_to_poly_projection_predicate(path_id,
742                                                                    poly_trait_ref,
743                                                                    binding);
744             predicate.ok() // ok to ignore Err() because ErrorReported (see above)
745         }));
746
747         debug!("ast_path_to_poly_trait_ref(trait_segment={:?}, projections={:?}) -> {:?}",
748                trait_segment, poly_projections, poly_trait_ref);
749         poly_trait_ref
750     }
751
752     fn ast_path_to_mono_trait_ref(&self,
753                                   rscope: &RegionScope,
754                                   span: Span,
755                                   param_mode: PathParamMode,
756                                   trait_def_id: DefId,
757                                   self_ty: Ty<'tcx>,
758                                   trait_segment: &hir::PathSegment)
759                                   -> ty::TraitRef<'tcx>
760     {
761         let (substs, assoc_bindings) =
762             self.create_substs_for_ast_trait_ref(rscope,
763                                                  span,
764                                                  param_mode,
765                                                  trait_def_id,
766                                                  self_ty,
767                                                  trait_segment);
768         assoc_bindings.first().map(|b| self.tcx().prohibit_projection(b.span));
769         ty::TraitRef::new(trait_def_id, substs)
770     }
771
772     fn create_substs_for_ast_trait_ref(&self,
773                                        rscope: &RegionScope,
774                                        span: Span,
775                                        param_mode: PathParamMode,
776                                        trait_def_id: DefId,
777                                        self_ty: Ty<'tcx>,
778                                        trait_segment: &hir::PathSegment)
779                                        -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
780     {
781         debug!("create_substs_for_ast_trait_ref(trait_segment={:?})",
782                trait_segment);
783
784         let trait_def = match self.get_trait_def(span, trait_def_id) {
785             Ok(trait_def) => trait_def,
786             Err(ErrorReported) => {
787                 // No convenient way to recover from a cycle here. Just bail. Sorry!
788                 self.tcx().sess.abort_if_errors();
789                 bug!("ErrorReported returned, but no errors reports?")
790             }
791         };
792
793         match trait_segment.parameters {
794             hir::AngleBracketedParameters(_) => {
795                 // For now, require that parenthetical notation be used
796                 // only with `Fn()` etc.
797                 if !self.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
798                     emit_feature_err(&self.tcx().sess.parse_sess,
799                                      "unboxed_closures", span, GateIssue::Language,
800                                      "\
801                         the precise format of `Fn`-family traits' \
802                         type parameters is subject to change. \
803                         Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead");
804                 }
805             }
806             hir::ParenthesizedParameters(_) => {
807                 // For now, require that parenthetical notation be used
808                 // only with `Fn()` etc.
809                 if !self.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
810                     emit_feature_err(&self.tcx().sess.parse_sess,
811                                      "unboxed_closures", span, GateIssue::Language,
812                                      "\
813                         parenthetical notation is only stable when used with `Fn`-family traits");
814                 }
815             }
816         }
817
818         self.create_substs_for_ast_path(rscope,
819                                         span,
820                                         param_mode,
821                                         trait_def_id,
822                                         &trait_segment.parameters,
823                                         Some(self_ty))
824     }
825
826     fn ast_type_binding_to_poly_projection_predicate(
827         &self,
828         path_id: ast::NodeId,
829         trait_ref: ty::PolyTraitRef<'tcx>,
830         binding: &ConvertedBinding<'tcx>)
831         -> Result<ty::PolyProjectionPredicate<'tcx>, ErrorReported>
832     {
833         let tcx = self.tcx();
834
835         // Given something like `U : SomeTrait<T=X>`, we want to produce a
836         // predicate like `<U as SomeTrait>::T = X`. This is somewhat
837         // subtle in the event that `T` is defined in a supertrait of
838         // `SomeTrait`, because in that case we need to upcast.
839         //
840         // That is, consider this case:
841         //
842         // ```
843         // trait SubTrait : SuperTrait<int> { }
844         // trait SuperTrait<A> { type T; }
845         //
846         // ... B : SubTrait<T=foo> ...
847         // ```
848         //
849         // We want to produce `<B as SuperTrait<int>>::T == foo`.
850
851         // Find any late-bound regions declared in `ty` that are not
852         // declared in the trait-ref. These are not wellformed.
853         //
854         // Example:
855         //
856         //     for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
857         //     for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
858         let late_bound_in_trait_ref = tcx.collect_constrained_late_bound_regions(&trait_ref);
859         let late_bound_in_ty = tcx.collect_referenced_late_bound_regions(&ty::Binder(binding.ty));
860         debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
861         debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
862         for br in late_bound_in_ty.difference(&late_bound_in_trait_ref) {
863             let br_name = match *br {
864                 ty::BrNamed(_, name, _) => name,
865                 _ => {
866                     span_bug!(
867                         binding.span,
868                         "anonymous bound region {:?} in binding but not trait ref",
869                         br);
870                 }
871             };
872             tcx.sess.add_lint(
873                 lint::builtin::HR_LIFETIME_IN_ASSOC_TYPE,
874                 path_id,
875                 binding.span,
876                 format!("binding for associated type `{}` references lifetime `{}`, \
877                          which does not appear in the trait input types",
878                         binding.item_name, br_name));
879         }
880
881         // Simple case: X is defined in the current trait.
882         if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
883             return Ok(trait_ref.map_bound(|trait_ref| {
884                 ty::ProjectionPredicate {
885                     projection_ty: ty::ProjectionTy {
886                         trait_ref: trait_ref,
887                         item_name: binding.item_name,
888                     },
889                     ty: binding.ty,
890                 }
891             }));
892         }
893
894         // Otherwise, we have to walk through the supertraits to find
895         // those that do.
896         self.ensure_super_predicates(binding.span, trait_ref.def_id())?;
897
898         let candidates: Vec<ty::PolyTraitRef> =
899             traits::supertraits(tcx, trait_ref.clone())
900             .filter(|r| self.trait_defines_associated_type_named(r.def_id(), binding.item_name))
901             .collect();
902
903         let candidate = self.one_bound_for_assoc_type(candidates,
904                                                       &trait_ref.to_string(),
905                                                       &binding.item_name.as_str(),
906                                                       binding.span)?;
907
908         Ok(candidate.map_bound(|trait_ref| {
909             ty::ProjectionPredicate {
910                 projection_ty: ty::ProjectionTy {
911                     trait_ref: trait_ref,
912                     item_name: binding.item_name,
913                 },
914                 ty: binding.ty,
915             }
916         }))
917     }
918
919     fn ast_path_to_ty(&self,
920         rscope: &RegionScope,
921         span: Span,
922         param_mode: PathParamMode,
923         did: DefId,
924         item_segment: &hir::PathSegment)
925         -> Ty<'tcx>
926     {
927         let tcx = self.tcx();
928         let decl_ty = match self.get_item_type_scheme(span, did) {
929             Ok(type_scheme) => type_scheme.ty,
930             Err(ErrorReported) => {
931                 return tcx.types.err;
932             }
933         };
934
935         let substs = self.ast_path_substs_for_ty(rscope,
936                                                  span,
937                                                  param_mode,
938                                                  did,
939                                                  item_segment);
940
941         // FIXME(#12938): This is a hack until we have full support for DST.
942         if Some(did) == self.tcx().lang_items.owned_box() {
943             assert_eq!(substs.types().count(), 1);
944             return self.tcx().mk_box(substs.type_at(0));
945         }
946
947         decl_ty.subst(self.tcx(), substs)
948     }
949
950     fn ast_ty_to_object_trait_ref(&self,
951                                   rscope: &RegionScope,
952                                   span: Span,
953                                   ty: &hir::Ty,
954                                   bounds: &[hir::TyParamBound])
955                                   -> Ty<'tcx>
956     {
957         /*!
958          * In a type like `Foo + Send`, we want to wait to collect the
959          * full set of bounds before we make the object type, because we
960          * need them to infer a region bound.  (For example, if we tried
961          * made a type from just `Foo`, then it wouldn't be enough to
962          * infer a 'static bound, and hence the user would get an error.)
963          * So this function is used when we're dealing with a sum type to
964          * convert the LHS. It only accepts a type that refers to a trait
965          * name, and reports an error otherwise.
966          */
967
968         let tcx = self.tcx();
969         match ty.node {
970             hir::TyPath(None, ref path) => {
971                 let resolution = tcx.expect_resolution(ty.id);
972                 match resolution.base_def {
973                     Def::Trait(trait_def_id) if resolution.depth == 0 => {
974                         self.trait_path_to_object_type(rscope,
975                                                        path.span,
976                                                        PathParamMode::Explicit,
977                                                        trait_def_id,
978                                                        ty.id,
979                                                        path.segments.last().unwrap(),
980                                                        span,
981                                                        partition_bounds(tcx, span, bounds))
982                     }
983                     _ => {
984                         struct_span_err!(tcx.sess, ty.span, E0172,
985                                   "expected a reference to a trait")
986                             .span_label(ty.span, &format!("expected a trait"))
987                             .emit();
988                         tcx.types.err
989                     }
990                 }
991             }
992             _ => {
993                 let mut err = struct_span_err!(tcx.sess, ty.span, E0178,
994                                                "expected a path on the left-hand side \
995                                                 of `+`, not `{}`",
996                                                pprust::ty_to_string(ty));
997                 err.span_label(ty.span, &format!("expected a path"));
998                 let hi = bounds.iter().map(|x| match *x {
999                     hir::TraitTyParamBound(ref tr, _) => tr.span.hi,
1000                     hir::RegionTyParamBound(ref r) => r.span.hi,
1001                 }).max_by_key(|x| x.to_usize());
1002                 let full_span = hi.map(|hi| Span {
1003                     lo: ty.span.lo,
1004                     hi: hi,
1005                     expn_id: ty.span.expn_id,
1006                 });
1007                 match (&ty.node, full_span) {
1008                     (&hir::TyRptr(None, ref mut_ty), Some(full_span)) => {
1009                         let mutbl_str = if mut_ty.mutbl == hir::MutMutable { "mut " } else { "" };
1010                         err.span_suggestion(full_span, "try adding parentheses (per RFC 438):",
1011                                             format!("&{}({} +{})",
1012                                                     mutbl_str,
1013                                                     pprust::ty_to_string(&mut_ty.ty),
1014                                                     pprust::bounds_to_string(bounds)));
1015                     }
1016                     (&hir::TyRptr(Some(ref lt), ref mut_ty), Some(full_span)) => {
1017                         let mutbl_str = if mut_ty.mutbl == hir::MutMutable { "mut " } else { "" };
1018                         err.span_suggestion(full_span, "try adding parentheses (per RFC 438):",
1019                                             format!("&{} {}({} +{})",
1020                                                     pprust::lifetime_to_string(lt),
1021                                                     mutbl_str,
1022                                                     pprust::ty_to_string(&mut_ty.ty),
1023                                                     pprust::bounds_to_string(bounds)));
1024                     }
1025
1026                     _ => {
1027                         help!(&mut err,
1028                                    "perhaps you forgot parentheses? (per RFC 438)");
1029                     }
1030                 }
1031                 err.emit();
1032                 tcx.types.err
1033             }
1034         }
1035     }
1036
1037     /// Transform a PolyTraitRef into a PolyExistentialTraitRef by
1038     /// removing the dummy Self type (TRAIT_OBJECT_DUMMY_SELF).
1039     fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
1040                                 -> ty::ExistentialTraitRef<'tcx> {
1041         assert_eq!(trait_ref.self_ty().sty, TRAIT_OBJECT_DUMMY_SELF);
1042         ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref)
1043     }
1044
1045     fn trait_path_to_object_type(&self,
1046                                  rscope: &RegionScope,
1047                                  path_span: Span,
1048                                  param_mode: PathParamMode,
1049                                  trait_def_id: DefId,
1050                                  trait_path_ref_id: ast::NodeId,
1051                                  trait_segment: &hir::PathSegment,
1052                                  span: Span,
1053                                  partitioned_bounds: PartitionedBounds)
1054                                  -> Ty<'tcx> {
1055         let tcx = self.tcx();
1056
1057         let mut projection_bounds = vec![];
1058         let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF);
1059         let principal = self.ast_path_to_poly_trait_ref(rscope,
1060                                                         path_span,
1061                                                         param_mode,
1062                                                         trait_def_id,
1063                                                         dummy_self,
1064                                                         trait_path_ref_id,
1065                                                         trait_segment,
1066                                                         &mut projection_bounds);
1067
1068         let PartitionedBounds { builtin_bounds,
1069                                 trait_bounds,
1070                                 region_bounds } =
1071             partitioned_bounds;
1072
1073         if !trait_bounds.is_empty() {
1074             let b = &trait_bounds[0];
1075             let span = b.trait_ref.path.span;
1076             struct_span_err!(self.tcx().sess, span, E0225,
1077                              "only the builtin traits can be used as closure or object bounds")
1078                 .span_label(span, &format!("non-builtin trait used as bounds"))
1079                 .emit();
1080         }
1081
1082         // Erase the dummy_self (TRAIT_OBJECT_DUMMY_SELF) used above.
1083         let existential_principal = principal.map_bound(|trait_ref| {
1084             self.trait_ref_to_existential(trait_ref)
1085         });
1086         let existential_projections = projection_bounds.iter().map(|bound| {
1087             bound.map_bound(|b| {
1088                 let p = b.projection_ty;
1089                 ty::ExistentialProjection {
1090                     trait_ref: self.trait_ref_to_existential(p.trait_ref),
1091                     item_name: p.item_name,
1092                     ty: b.ty
1093                 }
1094             })
1095         }).collect();
1096
1097         let region_bound =
1098             self.compute_object_lifetime_bound(span,
1099                                                &region_bounds,
1100                                                existential_principal,
1101                                                builtin_bounds);
1102
1103         let region_bound = match region_bound {
1104             Some(r) => r,
1105             None => {
1106                 tcx.mk_region(match rscope.object_lifetime_default(span) {
1107                     Some(r) => r,
1108                     None => {
1109                         span_err!(self.tcx().sess, span, E0228,
1110                                   "the lifetime bound for this object type cannot be deduced \
1111                                    from context; please supply an explicit bound");
1112                         ty::ReStatic
1113                     }
1114                 })
1115             }
1116         };
1117
1118         debug!("region_bound: {:?}", region_bound);
1119
1120         // ensure the super predicates and stop if we encountered an error
1121         if self.ensure_super_predicates(span, principal.def_id()).is_err() {
1122             return tcx.types.err;
1123         }
1124
1125         // check that there are no gross object safety violations,
1126         // most importantly, that the supertraits don't contain Self,
1127         // to avoid ICE-s.
1128         let object_safety_violations =
1129             tcx.astconv_object_safety_violations(principal.def_id());
1130         if !object_safety_violations.is_empty() {
1131             tcx.report_object_safety_error(
1132                 span, principal.def_id(), object_safety_violations)
1133                 .emit();
1134             return tcx.types.err;
1135         }
1136
1137         let mut associated_types = FnvHashSet::default();
1138         for tr in traits::supertraits(tcx, principal) {
1139             if let Some(trait_id) = tcx.map.as_local_node_id(tr.def_id()) {
1140                 use collect::trait_associated_type_names;
1141
1142                 associated_types.extend(trait_associated_type_names(tcx, trait_id)
1143                     .map(|name| (tr.def_id(), name)))
1144             } else {
1145                 let trait_items = tcx.impl_or_trait_items(tr.def_id());
1146                 associated_types.extend(trait_items.iter().filter_map(|&def_id| {
1147                     match tcx.impl_or_trait_item(def_id) {
1148                         ty::TypeTraitItem(ref item) => Some(item.name),
1149                         _ => None
1150                     }
1151                 }).map(|name| (tr.def_id(), name)));
1152             }
1153         }
1154
1155         for projection_bound in &projection_bounds {
1156             let pair = (projection_bound.0.projection_ty.trait_ref.def_id,
1157                         projection_bound.0.projection_ty.item_name);
1158             associated_types.remove(&pair);
1159         }
1160
1161         for (trait_def_id, name) in associated_types {
1162             struct_span_err!(tcx.sess, span, E0191,
1163                 "the value of the associated type `{}` (from the trait `{}`) must be specified",
1164                         name,
1165                         tcx.item_path_str(trait_def_id))
1166                         .span_label(span, &format!(
1167                             "missing associated type `{}` value", name))
1168                         .emit();
1169         }
1170
1171         let ty = tcx.mk_trait(ty::TraitObject {
1172             principal: existential_principal,
1173             region_bound: region_bound,
1174             builtin_bounds: builtin_bounds,
1175             projection_bounds: existential_projections
1176         });
1177         debug!("trait_object_type: {:?}", ty);
1178         ty
1179     }
1180
1181     fn report_ambiguous_associated_type(&self,
1182                                         span: Span,
1183                                         type_str: &str,
1184                                         trait_str: &str,
1185                                         name: &str) {
1186         struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type")
1187             .span_label(span, &format!("ambiguous associated type"))
1188             .note(&format!("specify the type using the syntax `<{} as {}>::{}`",
1189                   type_str, trait_str, name))
1190             .emit();
1191
1192     }
1193
1194     // Search for a bound on a type parameter which includes the associated item
1195     // given by assoc_name. ty_param_node_id is the node id for the type parameter
1196     // (which might be `Self`, but only if it is the `Self` of a trait, not an
1197     // impl). This function will fail if there are no suitable bounds or there is
1198     // any ambiguity.
1199     fn find_bound_for_assoc_item(&self,
1200                                  ty_param_node_id: ast::NodeId,
1201                                  ty_param_name: ast::Name,
1202                                  assoc_name: ast::Name,
1203                                  span: Span)
1204                                  -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
1205     {
1206         let tcx = self.tcx();
1207
1208         let bounds = match self.get_type_parameter_bounds(span, ty_param_node_id) {
1209             Ok(v) => v,
1210             Err(ErrorReported) => {
1211                 return Err(ErrorReported);
1212             }
1213         };
1214
1215         // Ensure the super predicates and stop if we encountered an error.
1216         if bounds.iter().any(|b| self.ensure_super_predicates(span, b.def_id()).is_err()) {
1217             return Err(ErrorReported);
1218         }
1219
1220         // Check that there is exactly one way to find an associated type with the
1221         // correct name.
1222         let suitable_bounds: Vec<_> =
1223             traits::transitive_bounds(tcx, &bounds)
1224             .filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name))
1225             .collect();
1226
1227         self.one_bound_for_assoc_type(suitable_bounds,
1228                                       &ty_param_name.as_str(),
1229                                       &assoc_name.as_str(),
1230                                       span)
1231     }
1232
1233
1234     // Checks that bounds contains exactly one element and reports appropriate
1235     // errors otherwise.
1236     fn one_bound_for_assoc_type(&self,
1237                                 bounds: Vec<ty::PolyTraitRef<'tcx>>,
1238                                 ty_param_name: &str,
1239                                 assoc_name: &str,
1240                                 span: Span)
1241         -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
1242     {
1243         if bounds.is_empty() {
1244             struct_span_err!(self.tcx().sess, span, E0220,
1245                       "associated type `{}` not found for `{}`",
1246                       assoc_name,
1247                       ty_param_name)
1248               .span_label(span, &format!("associated type `{}` not found", assoc_name))
1249               .emit();
1250             return Err(ErrorReported);
1251         }
1252
1253         if bounds.len() > 1 {
1254             let mut err = struct_span_err!(
1255                 self.tcx().sess, span, E0221,
1256                 "ambiguous associated type `{}` in bounds of `{}`",
1257                 assoc_name,
1258                 ty_param_name);
1259             err.span_label(span, &format!("ambiguous associated type `{}`", assoc_name));
1260
1261             for bound in &bounds {
1262                 span_note!(&mut err, span,
1263                            "associated type `{}` could derive from `{}`",
1264                            ty_param_name,
1265                            bound);
1266             }
1267             err.emit();
1268         }
1269
1270         Ok(bounds[0].clone())
1271     }
1272
1273     // Create a type from a path to an associated type.
1274     // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
1275     // and item_segment is the path segment for D. We return a type and a def for
1276     // the whole path.
1277     // Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
1278     // parameter or Self.
1279     fn associated_path_def_to_ty(&self,
1280                                  span: Span,
1281                                  ty: Ty<'tcx>,
1282                                  ty_path_def: Def,
1283                                  item_segment: &hir::PathSegment)
1284                                  -> (Ty<'tcx>, Def)
1285     {
1286         let tcx = self.tcx();
1287         let assoc_name = item_segment.name;
1288
1289         debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
1290
1291         tcx.prohibit_type_params(slice::ref_slice(item_segment));
1292
1293         // Find the type of the associated item, and the trait where the associated
1294         // item is declared.
1295         let bound = match (&ty.sty, ty_path_def) {
1296             (_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
1297                 // `Self` in an impl of a trait - we have a concrete self type and a
1298                 // trait reference.
1299                 let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
1300                 let trait_ref = if let Some(free_substs) = self.get_free_substs() {
1301                     trait_ref.subst(tcx, free_substs)
1302                 } else {
1303                     trait_ref
1304                 };
1305
1306                 if self.ensure_super_predicates(span, trait_ref.def_id).is_err() {
1307                     return (tcx.types.err, Def::Err);
1308                 }
1309
1310                 let candidates: Vec<ty::PolyTraitRef> =
1311                     traits::supertraits(tcx, ty::Binder(trait_ref))
1312                     .filter(|r| self.trait_defines_associated_type_named(r.def_id(),
1313                                                                          assoc_name))
1314                     .collect();
1315
1316                 match self.one_bound_for_assoc_type(candidates,
1317                                                     "Self",
1318                                                     &assoc_name.as_str(),
1319                                                     span) {
1320                     Ok(bound) => bound,
1321                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
1322                 }
1323             }
1324             (&ty::TyParam(_), Def::SelfTy(Some(trait_did), None)) => {
1325                 let trait_node_id = tcx.map.as_local_node_id(trait_did).unwrap();
1326                 match self.find_bound_for_assoc_item(trait_node_id,
1327                                                      keywords::SelfType.name(),
1328                                                      assoc_name,
1329                                                      span) {
1330                     Ok(bound) => bound,
1331                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
1332                 }
1333             }
1334             (&ty::TyParam(_), Def::TyParam(param_did)) => {
1335                 let param_node_id = tcx.map.as_local_node_id(param_did).unwrap();
1336                 let param_name = tcx.type_parameter_def(param_node_id).name;
1337                 match self.find_bound_for_assoc_item(param_node_id,
1338                                                      param_name,
1339                                                      assoc_name,
1340                                                      span) {
1341                     Ok(bound) => bound,
1342                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
1343                 }
1344             }
1345             _ => {
1346                 // Don't print TyErr to the user.
1347                 if !ty.references_error() {
1348                     self.report_ambiguous_associated_type(span,
1349                                                           &ty.to_string(),
1350                                                           "Trait",
1351                                                           &assoc_name.as_str());
1352                 }
1353                 return (tcx.types.err, Def::Err);
1354             }
1355         };
1356
1357         let trait_did = bound.0.def_id;
1358         let ty = self.projected_ty_from_poly_trait_ref(span, bound, assoc_name);
1359
1360         let item_did = if let Some(trait_id) = tcx.map.as_local_node_id(trait_did) {
1361             // `ty::trait_items` used below requires information generated
1362             // by type collection, which may be in progress at this point.
1363             match tcx.map.expect_item(trait_id).node {
1364                 hir::ItemTrait(.., ref trait_items) => {
1365                     let item = trait_items.iter()
1366                                           .find(|i| i.name == assoc_name)
1367                                           .expect("missing associated type");
1368                     tcx.map.local_def_id(item.id)
1369                 }
1370                 _ => bug!()
1371             }
1372         } else {
1373             let trait_items = tcx.trait_items(trait_did);
1374             let item = trait_items.iter().find(|i| i.name() == assoc_name);
1375             item.expect("missing associated type").def_id()
1376         };
1377
1378         (ty, Def::AssociatedTy(item_did))
1379     }
1380
1381     fn qpath_to_ty(&self,
1382                    rscope: &RegionScope,
1383                    span: Span,
1384                    param_mode: PathParamMode,
1385                    opt_self_ty: Option<Ty<'tcx>>,
1386                    trait_def_id: DefId,
1387                    trait_segment: &hir::PathSegment,
1388                    item_segment: &hir::PathSegment)
1389                    -> Ty<'tcx>
1390     {
1391         let tcx = self.tcx();
1392
1393         tcx.prohibit_type_params(slice::ref_slice(item_segment));
1394
1395         let self_ty = if let Some(ty) = opt_self_ty {
1396             ty
1397         } else {
1398             let path_str = tcx.item_path_str(trait_def_id);
1399             self.report_ambiguous_associated_type(span,
1400                                                   "Type",
1401                                                   &path_str,
1402                                                   &item_segment.name.as_str());
1403             return tcx.types.err;
1404         };
1405
1406         debug!("qpath_to_ty: self_type={:?}", self_ty);
1407
1408         let trait_ref = self.ast_path_to_mono_trait_ref(rscope,
1409                                                         span,
1410                                                         param_mode,
1411                                                         trait_def_id,
1412                                                         self_ty,
1413                                                         trait_segment);
1414
1415         debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
1416
1417         self.projected_ty(span, trait_ref, item_segment.name)
1418     }
1419
1420     /// Convert a type supplied as value for a type argument from AST into our
1421     /// our internal representation. This is the same as `ast_ty_to_ty` but that
1422     /// it applies the object lifetime default.
1423     ///
1424     /// # Parameters
1425     ///
1426     /// * `this`, `rscope`: the surrounding context
1427     /// * `def`: the type parameter being instantiated (if available)
1428     /// * `region_substs`: a partial substitution consisting of
1429     ///   only the region type parameters being supplied to this type.
1430     /// * `ast_ty`: the ast representation of the type being supplied
1431     fn ast_ty_arg_to_ty(&self,
1432                         rscope: &RegionScope,
1433                         def: Option<&ty::TypeParameterDef<'tcx>>,
1434                         region_substs: &Substs<'tcx>,
1435                         ast_ty: &hir::Ty)
1436                         -> Ty<'tcx>
1437     {
1438         let tcx = self.tcx();
1439
1440         if let Some(def) = def {
1441             let object_lifetime_default = def.object_lifetime_default.subst(tcx, region_substs);
1442             let rscope1 = &ObjectLifetimeDefaultRscope::new(rscope, object_lifetime_default);
1443             self.ast_ty_to_ty(rscope1, ast_ty)
1444         } else {
1445             self.ast_ty_to_ty(rscope, ast_ty)
1446         }
1447     }
1448
1449     // Check the base def in a PathResolution and convert it to a Ty. If there are
1450     // associated types in the PathResolution, these will need to be separately
1451     // resolved.
1452     fn base_def_to_ty(&self,
1453                       rscope: &RegionScope,
1454                       span: Span,
1455                       param_mode: PathParamMode,
1456                       def: Def,
1457                       opt_self_ty: Option<Ty<'tcx>>,
1458                       base_path_ref_id: ast::NodeId,
1459                       base_segments: &[hir::PathSegment])
1460                       -> Ty<'tcx> {
1461         let tcx = self.tcx();
1462
1463         debug!("base_def_to_ty(def={:?}, opt_self_ty={:?}, base_segments={:?})",
1464                def, opt_self_ty, base_segments);
1465
1466         match def {
1467             Def::Trait(trait_def_id) => {
1468                 // N.B. this case overlaps somewhat with
1469                 // TyObjectSum, see that fn for details
1470
1471                 tcx.prohibit_type_params(base_segments.split_last().unwrap().1);
1472
1473                 self.trait_path_to_object_type(rscope,
1474                                                span,
1475                                                param_mode,
1476                                                trait_def_id,
1477                                                base_path_ref_id,
1478                                                base_segments.last().unwrap(),
1479                                                span,
1480                                                partition_bounds(tcx, span, &[]))
1481             }
1482             Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => {
1483                 tcx.prohibit_type_params(base_segments.split_last().unwrap().1);
1484                 self.ast_path_to_ty(rscope,
1485                                     span,
1486                                     param_mode,
1487                                     did,
1488                                     base_segments.last().unwrap())
1489             }
1490             Def::TyParam(did) => {
1491                 tcx.prohibit_type_params(base_segments);
1492
1493                 let node_id = tcx.map.as_local_node_id(did).unwrap();
1494                 let param = tcx.ty_param_defs.borrow().get(&node_id)
1495                                .map(ty::ParamTy::for_def);
1496                 if let Some(p) = param {
1497                     p.to_ty(tcx)
1498                 } else {
1499                     // Only while computing defaults of earlier type
1500                     // parameters can a type parameter be missing its def.
1501                     struct_span_err!(tcx.sess, span, E0128,
1502                                      "type parameters with a default cannot use \
1503                                       forward declared identifiers")
1504                         .span_label(span, &format!("defaulted type parameters \
1505                                                     cannot be forward declared"))
1506                         .emit();
1507                     tcx.types.err
1508                 }
1509             }
1510             Def::SelfTy(_, Some(def_id)) => {
1511                 // Self in impl (we know the concrete type).
1512
1513                 tcx.prohibit_type_params(base_segments);
1514                 let impl_id = tcx.map.as_local_node_id(def_id).unwrap();
1515                 let ty = tcx.node_id_to_type(impl_id);
1516                 if let Some(free_substs) = self.get_free_substs() {
1517                     ty.subst(tcx, free_substs)
1518                 } else {
1519                     ty
1520                 }
1521             }
1522             Def::SelfTy(Some(_), None) => {
1523                 // Self in trait.
1524                 tcx.prohibit_type_params(base_segments);
1525                 tcx.mk_self_type()
1526             }
1527             Def::AssociatedTy(def_id) => {
1528                 tcx.prohibit_type_params(&base_segments[..base_segments.len()-2]);
1529                 let trait_did = tcx.parent_def_id(def_id).unwrap();
1530                 self.qpath_to_ty(rscope,
1531                                  span,
1532                                  param_mode,
1533                                  opt_self_ty,
1534                                  trait_did,
1535                                  &base_segments[base_segments.len()-2],
1536                                  base_segments.last().unwrap())
1537             }
1538             Def::Mod(..) => {
1539                 // Used as sentinel by callers to indicate the `<T>::A::B::C` form.
1540                 // FIXME(#22519) This part of the resolution logic should be
1541                 // avoided entirely for that form, once we stop needed a Def
1542                 // for `associated_path_def_to_ty`.
1543                 // Fixing this will also let use resolve <Self>::Foo the same way we
1544                 // resolve Self::Foo, at the moment we can't resolve the former because
1545                 // we don't have the trait information around, which is just sad.
1546
1547                 assert!(base_segments.is_empty());
1548
1549                 opt_self_ty.expect("missing T in <T>::a::b::c")
1550             }
1551             Def::PrimTy(prim_ty) => {
1552                 tcx.prim_ty_to_ty(base_segments, prim_ty)
1553             }
1554             Def::Err => {
1555                 self.set_tainted_by_errors();
1556                 return self.tcx().types.err;
1557             }
1558             _ => {
1559                 struct_span_err!(tcx.sess, span, E0248,
1560                            "found value `{}` used as a type",
1561                             tcx.item_path_str(def.def_id()))
1562                            .span_label(span, &format!("value used as a type"))
1563                            .emit();
1564                 return self.tcx().types.err;
1565             }
1566         }
1567     }
1568
1569     // Resolve possibly associated type path into a type and final definition.
1570     // Note that both base_segments and assoc_segments may be empty, although not at same time.
1571     pub fn finish_resolving_def_to_ty(&self,
1572                                       rscope: &RegionScope,
1573                                       span: Span,
1574                                       param_mode: PathParamMode,
1575                                       base_def: Def,
1576                                       opt_self_ty: Option<Ty<'tcx>>,
1577                                       base_path_ref_id: ast::NodeId,
1578                                       base_segments: &[hir::PathSegment],
1579                                       assoc_segments: &[hir::PathSegment])
1580                                       -> (Ty<'tcx>, Def) {
1581         // Convert the base type.
1582         debug!("finish_resolving_def_to_ty(base_def={:?}, \
1583                 base_segments={:?}, \
1584                 assoc_segments={:?})",
1585                base_def,
1586                base_segments,
1587                assoc_segments);
1588         let base_ty = self.base_def_to_ty(rscope,
1589                                           span,
1590                                           param_mode,
1591                                           base_def,
1592                                           opt_self_ty,
1593                                           base_path_ref_id,
1594                                           base_segments);
1595         debug!("finish_resolving_def_to_ty: base_def_to_ty returned {:?}", base_ty);
1596
1597         // If any associated type segments remain, attempt to resolve them.
1598         let (mut ty, mut def) = (base_ty, base_def);
1599         for segment in assoc_segments {
1600             debug!("finish_resolving_def_to_ty: segment={:?}", segment);
1601             // This is pretty bad (it will fail except for T::A and Self::A).
1602             let (new_ty, new_def) = self.associated_path_def_to_ty(span, ty, def, segment);
1603             ty = new_ty;
1604             def = new_def;
1605
1606             if def == Def::Err {
1607                 break;
1608             }
1609         }
1610         (ty, def)
1611     }
1612
1613     /// Parses the programmer's textual representation of a type into our
1614     /// internal notion of a type.
1615     pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> {
1616         debug!("ast_ty_to_ty(id={:?}, ast_ty={:?})",
1617                ast_ty.id, ast_ty);
1618
1619         let tcx = self.tcx();
1620
1621         let cache = self.ast_ty_to_ty_cache();
1622         match cache.borrow().get(&ast_ty.id) {
1623             Some(ty) => { return ty; }
1624             None => { }
1625         }
1626
1627         let result_ty = match ast_ty.node {
1628             hir::TySlice(ref ty) => {
1629                 tcx.mk_slice(self.ast_ty_to_ty(rscope, &ty))
1630             }
1631             hir::TyObjectSum(ref ty, ref bounds) => {
1632                 self.ast_ty_to_object_trait_ref(rscope, ast_ty.span, ty, bounds)
1633             }
1634             hir::TyPtr(ref mt) => {
1635                 tcx.mk_ptr(ty::TypeAndMut {
1636                     ty: self.ast_ty_to_ty(rscope, &mt.ty),
1637                     mutbl: mt.mutbl
1638                 })
1639             }
1640             hir::TyRptr(ref region, ref mt) => {
1641                 let r = self.opt_ast_region_to_region(rscope, ast_ty.span, region);
1642                 debug!("TyRef r={:?}", r);
1643                 let rscope1 =
1644                     &ObjectLifetimeDefaultRscope::new(
1645                         rscope,
1646                         ty::ObjectLifetimeDefault::Specific(r));
1647                 let t = self.ast_ty_to_ty(rscope1, &mt.ty);
1648                 tcx.mk_ref(r, ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
1649             }
1650             hir::TyNever => {
1651                 tcx.types.never
1652             },
1653             hir::TyTup(ref fields) => {
1654                 let flds = fields.iter()
1655                                  .map(|t| self.ast_ty_to_ty(rscope, &t))
1656                                  .collect();
1657                 tcx.mk_tup(flds)
1658             }
1659             hir::TyBareFn(ref bf) => {
1660                 require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
1661                 let anon_scope = rscope.anon_type_scope();
1662                 let (bare_fn_ty, _) =
1663                     self.ty_of_method_or_bare_fn(bf.unsafety,
1664                                                  bf.abi,
1665                                                  None,
1666                                                  &bf.decl,
1667                                                  anon_scope,
1668                                                  anon_scope);
1669
1670                 // Find any late-bound regions declared in return type that do
1671                 // not appear in the arguments. These are not wellformed.
1672                 //
1673                 // Example:
1674                 //
1675                 //     for<'a> fn() -> &'a str <-- 'a is bad
1676                 //     for<'a> fn(&'a String) -> &'a str <-- 'a is ok
1677                 //
1678                 // Note that we do this check **here** and not in
1679                 // `ty_of_bare_fn` because the latter is also used to make
1680                 // the types for fn items, and we do not want to issue a
1681                 // warning then. (Once we fix #32330, the regions we are
1682                 // checking for here would be considered early bound
1683                 // anyway.)
1684                 let inputs = bare_fn_ty.sig.inputs();
1685                 let late_bound_in_args = tcx.collect_constrained_late_bound_regions(&inputs);
1686                 let output = bare_fn_ty.sig.output();
1687                 let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
1688                 for br in late_bound_in_ret.difference(&late_bound_in_args) {
1689                     let br_name = match *br {
1690                         ty::BrNamed(_, name, _) => name,
1691                         _ => {
1692                             span_bug!(
1693                                 bf.decl.output.span(),
1694                                 "anonymous bound region {:?} in return but not args",
1695                                 br);
1696                         }
1697                     };
1698                     tcx.sess.add_lint(
1699                         lint::builtin::HR_LIFETIME_IN_ASSOC_TYPE,
1700                         ast_ty.id,
1701                         ast_ty.span,
1702                         format!("return type references lifetime `{}`, \
1703                                  which does not appear in the trait input types",
1704                                 br_name));
1705                 }
1706                 tcx.mk_fn_ptr(bare_fn_ty)
1707             }
1708             hir::TyPolyTraitRef(ref bounds) => {
1709                 self.conv_object_ty_poly_trait_ref(rscope, ast_ty.span, bounds)
1710             }
1711             hir::TyImplTrait(ref bounds) => {
1712                 use collect::{compute_bounds, SizedByDefault};
1713
1714                 // Create the anonymized type.
1715                 let def_id = tcx.map.local_def_id(ast_ty.id);
1716                 if let Some(anon_scope) = rscope.anon_type_scope() {
1717                     let substs = anon_scope.fresh_substs(self, ast_ty.span);
1718                     let ty = tcx.mk_anon(tcx.map.local_def_id(ast_ty.id), substs);
1719
1720                     // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
1721                     let bounds = compute_bounds(self, ty, bounds,
1722                                                 SizedByDefault::Yes,
1723                                                 Some(anon_scope),
1724                                                 ast_ty.span);
1725                     let predicates = bounds.predicates(tcx, ty);
1726                     let predicates = tcx.lift_to_global(&predicates).unwrap();
1727                     tcx.predicates.borrow_mut().insert(def_id, ty::GenericPredicates {
1728                         parent: None,
1729                         predicates: predicates
1730                     });
1731
1732                     ty
1733                 } else {
1734                     span_err!(tcx.sess, ast_ty.span, E0562,
1735                               "`impl Trait` not allowed outside of function \
1736                                and inherent method return types");
1737                     tcx.types.err
1738                 }
1739             }
1740             hir::TyPath(ref maybe_qself, ref path) => {
1741                 debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
1742                 let path_res = tcx.expect_resolution(ast_ty.id);
1743                 let base_ty_end = path.segments.len() - path_res.depth;
1744                 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
1745                     self.ast_ty_to_ty(rscope, &qself.ty)
1746                 });
1747                 let (ty, def) = self.finish_resolving_def_to_ty(rscope,
1748                                                                 ast_ty.span,
1749                                                                 PathParamMode::Explicit,
1750                                                                 path_res.base_def,
1751                                                                 opt_self_ty,
1752                                                                 ast_ty.id,
1753                                                                 &path.segments[..base_ty_end],
1754                                                                 &path.segments[base_ty_end..]);
1755
1756                 // Write back the new resolution.
1757                 if path_res.depth != 0 {
1758                     tcx.def_map.borrow_mut().insert(ast_ty.id, PathResolution::new(def));
1759                 }
1760
1761                 ty
1762             }
1763             hir::TyArray(ref ty, ref e) => {
1764                 if let Ok(length) = eval_length(tcx.global_tcx(), &e, "array length") {
1765                     tcx.mk_array(self.ast_ty_to_ty(rscope, &ty), length)
1766                 } else {
1767                     self.tcx().types.err
1768                 }
1769             }
1770             hir::TyTypeof(ref _e) => {
1771                 struct_span_err!(tcx.sess, ast_ty.span, E0516,
1772                                  "`typeof` is a reserved keyword but unimplemented")
1773                     .span_label(ast_ty.span, &format!("reserved keyword"))
1774                     .emit();
1775
1776                 tcx.types.err
1777             }
1778             hir::TyInfer => {
1779                 // TyInfer also appears as the type of arguments or return
1780                 // values in a ExprClosure, or as
1781                 // the type of local variables. Both of these cases are
1782                 // handled specially and will not descend into this routine.
1783                 self.ty_infer(ast_ty.span)
1784             }
1785         };
1786
1787         cache.borrow_mut().insert(ast_ty.id, result_ty);
1788
1789         result_ty
1790     }
1791
1792     pub fn ty_of_arg(&self,
1793                      rscope: &RegionScope,
1794                      a: &hir::Arg,
1795                      expected_ty: Option<Ty<'tcx>>)
1796                      -> Ty<'tcx>
1797     {
1798         match a.ty.node {
1799             hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
1800             hir::TyInfer => self.ty_infer(a.ty.span),
1801             _ => self.ast_ty_to_ty(rscope, &a.ty),
1802         }
1803     }
1804
1805     pub fn ty_of_method(&self,
1806                         sig: &hir::MethodSig,
1807                         untransformed_self_ty: Ty<'tcx>,
1808                         anon_scope: Option<AnonTypeScope>)
1809                         -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory<'tcx>) {
1810         self.ty_of_method_or_bare_fn(sig.unsafety,
1811                                      sig.abi,
1812                                      Some(untransformed_self_ty),
1813                                      &sig.decl,
1814                                      None,
1815                                      anon_scope)
1816     }
1817
1818     pub fn ty_of_bare_fn(&self,
1819                          unsafety: hir::Unsafety,
1820                          abi: abi::Abi,
1821                          decl: &hir::FnDecl,
1822                          anon_scope: Option<AnonTypeScope>)
1823                          -> &'tcx ty::BareFnTy<'tcx> {
1824         self.ty_of_method_or_bare_fn(unsafety, abi, None, decl, None, anon_scope).0
1825     }
1826
1827     fn ty_of_method_or_bare_fn(&self,
1828                                unsafety: hir::Unsafety,
1829                                abi: abi::Abi,
1830                                opt_untransformed_self_ty: Option<Ty<'tcx>>,
1831                                decl: &hir::FnDecl,
1832                                arg_anon_scope: Option<AnonTypeScope>,
1833                                ret_anon_scope: Option<AnonTypeScope>)
1834                                -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory<'tcx>)
1835     {
1836         debug!("ty_of_method_or_bare_fn");
1837
1838         // New region names that appear inside of the arguments of the function
1839         // declaration are bound to that function type.
1840         let rb = MaybeWithAnonTypes::new(BindingRscope::new(), arg_anon_scope);
1841
1842         // `implied_output_region` is the region that will be assumed for any
1843         // region parameters in the return type. In accordance with the rules for
1844         // lifetime elision, we can determine it in two ways. First (determined
1845         // here), if self is by-reference, then the implied output region is the
1846         // region of the self parameter.
1847         let (self_ty, explicit_self_category) = match (opt_untransformed_self_ty, decl.get_self()) {
1848             (Some(untransformed_self_ty), Some(explicit_self)) => {
1849                 let self_type = self.determine_self_type(&rb, untransformed_self_ty,
1850                                                          &explicit_self);
1851                 (Some(self_type.0), self_type.1)
1852             }
1853             _ => (None, ty::ExplicitSelfCategory::Static),
1854         };
1855
1856         // HACK(eddyb) replace the fake self type in the AST with the actual type.
1857         let arg_params = if self_ty.is_some() {
1858             &decl.inputs[1..]
1859         } else {
1860             &decl.inputs[..]
1861         };
1862         let arg_tys: Vec<Ty> =
1863             arg_params.iter().map(|a| self.ty_of_arg(&rb, a, None)).collect();
1864         let arg_pats: Vec<String> =
1865             arg_params.iter().map(|a| pprust::pat_to_string(&a.pat)).collect();
1866
1867         // Second, if there was exactly one lifetime (either a substitution or a
1868         // reference) in the arguments, then any anonymous regions in the output
1869         // have that lifetime.
1870         let implied_output_region = match explicit_self_category {
1871             ty::ExplicitSelfCategory::ByReference(region, _) => Ok(*region),
1872             _ => self.find_implied_output_region(&arg_tys, arg_pats)
1873         };
1874
1875         let output_ty = match decl.output {
1876             hir::Return(ref output) =>
1877                 self.convert_ty_with_lifetime_elision(implied_output_region,
1878                                                       &output,
1879                                                       ret_anon_scope),
1880             hir::DefaultReturn(..) => self.tcx().mk_nil(),
1881         };
1882
1883         let input_tys = self_ty.into_iter().chain(arg_tys).collect();
1884
1885         debug!("ty_of_method_or_bare_fn: input_tys={:?}", input_tys);
1886         debug!("ty_of_method_or_bare_fn: output_ty={:?}", output_ty);
1887
1888         (self.tcx().mk_bare_fn(ty::BareFnTy {
1889             unsafety: unsafety,
1890             abi: abi,
1891             sig: ty::Binder(ty::FnSig {
1892                 inputs: input_tys,
1893                 output: output_ty,
1894                 variadic: decl.variadic
1895             }),
1896         }), explicit_self_category)
1897     }
1898
1899     fn determine_self_type<'a>(&self,
1900                                rscope: &RegionScope,
1901                                untransformed_self_ty: Ty<'tcx>,
1902                                explicit_self: &hir::ExplicitSelf)
1903                                -> (Ty<'tcx>, ty::ExplicitSelfCategory<'tcx>)
1904     {
1905         return match explicit_self.node {
1906             SelfKind::Value(..) => {
1907                 (untransformed_self_ty, ty::ExplicitSelfCategory::ByValue)
1908             }
1909             SelfKind::Region(ref lifetime, mutability) => {
1910                 let region =
1911                     self.opt_ast_region_to_region(
1912                                              rscope,
1913                                              explicit_self.span,
1914                                              lifetime);
1915                 (self.tcx().mk_ref(region,
1916                     ty::TypeAndMut {
1917                         ty: untransformed_self_ty,
1918                         mutbl: mutability
1919                     }),
1920                  ty::ExplicitSelfCategory::ByReference(region, mutability))
1921             }
1922             SelfKind::Explicit(ref ast_type, _) => {
1923                 let explicit_type = self.ast_ty_to_ty(rscope, &ast_type);
1924
1925                 // We wish to (for now) categorize an explicit self
1926                 // declaration like `self: SomeType` into either `self`,
1927                 // `&self`, `&mut self`, or `Box<self>`. We do this here
1928                 // by some simple pattern matching. A more precise check
1929                 // is done later in `check_method_self_type()`.
1930                 //
1931                 // Examples:
1932                 //
1933                 // ```
1934                 // impl Foo for &T {
1935                 //     // Legal declarations:
1936                 //     fn method1(self: &&T); // ExplicitSelfCategory::ByReference
1937                 //     fn method2(self: &T); // ExplicitSelfCategory::ByValue
1938                 //     fn method3(self: Box<&T>); // ExplicitSelfCategory::ByBox
1939                 //
1940                 //     // Invalid cases will be caught later by `check_method_self_type`:
1941                 //     fn method_err1(self: &mut T); // ExplicitSelfCategory::ByReference
1942                 // }
1943                 // ```
1944                 //
1945                 // To do the check we just count the number of "modifiers"
1946                 // on each type and compare them. If they are the same or
1947                 // the impl has more, we call it "by value". Otherwise, we
1948                 // look at the outermost modifier on the method decl and
1949                 // call it by-ref, by-box as appropriate. For method1, for
1950                 // example, the impl type has one modifier, but the method
1951                 // type has two, so we end up with
1952                 // ExplicitSelfCategory::ByReference.
1953
1954                 let impl_modifiers = count_modifiers(untransformed_self_ty);
1955                 let method_modifiers = count_modifiers(explicit_type);
1956
1957                 debug!("determine_explicit_self_category(self_info.untransformed_self_ty={:?} \
1958                        explicit_type={:?} \
1959                        modifiers=({},{})",
1960                        untransformed_self_ty,
1961                        explicit_type,
1962                        impl_modifiers,
1963                        method_modifiers);
1964
1965                 let category = if impl_modifiers >= method_modifiers {
1966                     ty::ExplicitSelfCategory::ByValue
1967                 } else {
1968                     match explicit_type.sty {
1969                         ty::TyRef(r, mt) => ty::ExplicitSelfCategory::ByReference(r, mt.mutbl),
1970                         ty::TyBox(_) => ty::ExplicitSelfCategory::ByBox,
1971                         _ => ty::ExplicitSelfCategory::ByValue,
1972                     }
1973                 };
1974
1975                 (explicit_type, category)
1976             }
1977         };
1978
1979         fn count_modifiers(ty: Ty) -> usize {
1980             match ty.sty {
1981                 ty::TyRef(_, mt) => count_modifiers(mt.ty) + 1,
1982                 ty::TyBox(t) => count_modifiers(t) + 1,
1983                 _ => 0,
1984             }
1985         }
1986     }
1987
1988     pub fn ty_of_closure(&self,
1989         unsafety: hir::Unsafety,
1990         decl: &hir::FnDecl,
1991         abi: abi::Abi,
1992         expected_sig: Option<ty::FnSig<'tcx>>)
1993         -> ty::ClosureTy<'tcx>
1994     {
1995         debug!("ty_of_closure(expected_sig={:?})",
1996                expected_sig);
1997
1998         // new region names that appear inside of the fn decl are bound to
1999         // that function type
2000         let rb = rscope::BindingRscope::new();
2001
2002         let input_tys: Vec<_> = decl.inputs.iter().enumerate().map(|(i, a)| {
2003             let expected_arg_ty = expected_sig.as_ref().and_then(|e| {
2004                 // no guarantee that the correct number of expected args
2005                 // were supplied
2006                 if i < e.inputs.len() {
2007                     Some(e.inputs[i])
2008                 } else {
2009                     None
2010                 }
2011             });
2012             self.ty_of_arg(&rb, a, expected_arg_ty)
2013         }).collect();
2014
2015         let expected_ret_ty = expected_sig.map(|e| e.output);
2016
2017         let is_infer = match decl.output {
2018             hir::Return(ref output) if output.node == hir::TyInfer => true,
2019             hir::DefaultReturn(..) => true,
2020             _ => false
2021         };
2022
2023         let output_ty = match decl.output {
2024             _ if is_infer && expected_ret_ty.is_some() =>
2025                 expected_ret_ty.unwrap(),
2026             _ if is_infer => self.ty_infer(decl.output.span()),
2027             hir::Return(ref output) =>
2028                 self.ast_ty_to_ty(&rb, &output),
2029             hir::DefaultReturn(..) => bug!(),
2030         };
2031
2032         debug!("ty_of_closure: input_tys={:?}", input_tys);
2033         debug!("ty_of_closure: output_ty={:?}", output_ty);
2034
2035         ty::ClosureTy {
2036             unsafety: unsafety,
2037             abi: abi,
2038             sig: ty::Binder(ty::FnSig {inputs: input_tys,
2039                                        output: output_ty,
2040                                        variadic: decl.variadic}),
2041         }
2042     }
2043
2044     fn conv_object_ty_poly_trait_ref(&self,
2045         rscope: &RegionScope,
2046         span: Span,
2047         ast_bounds: &[hir::TyParamBound])
2048         -> Ty<'tcx>
2049     {
2050         let mut partitioned_bounds = partition_bounds(self.tcx(), span, &ast_bounds[..]);
2051
2052         let trait_bound = if !partitioned_bounds.trait_bounds.is_empty() {
2053             partitioned_bounds.trait_bounds.remove(0)
2054         } else {
2055             span_err!(self.tcx().sess, span, E0224,
2056                       "at least one non-builtin trait is required for an object type");
2057             return self.tcx().types.err;
2058         };
2059
2060         let trait_ref = &trait_bound.trait_ref;
2061         let trait_def_id = self.trait_def_id(trait_ref);
2062         self.trait_path_to_object_type(rscope,
2063                                        trait_ref.path.span,
2064                                        PathParamMode::Explicit,
2065                                        trait_def_id,
2066                                        trait_ref.ref_id,
2067                                        trait_ref.path.segments.last().unwrap(),
2068                                        span,
2069                                        partitioned_bounds)
2070     }
2071
2072     /// Given the bounds on an object, determines what single region bound (if any) we can
2073     /// use to summarize this type. The basic idea is that we will use the bound the user
2074     /// provided, if they provided one, and otherwise search the supertypes of trait bounds
2075     /// for region bounds. It may be that we can derive no bound at all, in which case
2076     /// we return `None`.
2077     fn compute_object_lifetime_bound(&self,
2078         span: Span,
2079         explicit_region_bounds: &[&hir::Lifetime],
2080         principal_trait_ref: ty::PolyExistentialTraitRef<'tcx>,
2081         builtin_bounds: ty::BuiltinBounds)
2082         -> Option<&'tcx ty::Region> // if None, use the default
2083     {
2084         let tcx = self.tcx();
2085
2086         debug!("compute_opt_region_bound(explicit_region_bounds={:?}, \
2087                principal_trait_ref={:?}, builtin_bounds={:?})",
2088                explicit_region_bounds,
2089                principal_trait_ref,
2090                builtin_bounds);
2091
2092         if explicit_region_bounds.len() > 1 {
2093             span_err!(tcx.sess, explicit_region_bounds[1].span, E0226,
2094                 "only a single explicit lifetime bound is permitted");
2095         }
2096
2097         if !explicit_region_bounds.is_empty() {
2098             // Explicitly specified region bound. Use that.
2099             let r = explicit_region_bounds[0];
2100             return Some(ast_region_to_region(tcx, r));
2101         }
2102
2103         if let Err(ErrorReported) =
2104                 self.ensure_super_predicates(span, principal_trait_ref.def_id()) {
2105             return Some(tcx.mk_region(ty::ReStatic));
2106         }
2107
2108         // No explicit region bound specified. Therefore, examine trait
2109         // bounds and see if we can derive region bounds from those.
2110         let derived_region_bounds =
2111             object_region_bounds(tcx, principal_trait_ref, builtin_bounds);
2112
2113         // If there are no derived region bounds, then report back that we
2114         // can find no region bound. The caller will use the default.
2115         if derived_region_bounds.is_empty() {
2116             return None;
2117         }
2118
2119         // If any of the derived region bounds are 'static, that is always
2120         // the best choice.
2121         if derived_region_bounds.iter().any(|&r| ty::ReStatic == *r) {
2122             return Some(tcx.mk_region(ty::ReStatic));
2123         }
2124
2125         // Determine whether there is exactly one unique region in the set
2126         // of derived region bounds. If so, use that. Otherwise, report an
2127         // error.
2128         let r = derived_region_bounds[0];
2129         if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2130             span_err!(tcx.sess, span, E0227,
2131                       "ambiguous lifetime bound, explicit lifetime bound required");
2132         }
2133         return Some(r);
2134     }
2135 }
2136
2137 pub struct PartitionedBounds<'a> {
2138     pub builtin_bounds: ty::BuiltinBounds,
2139     pub trait_bounds: Vec<&'a hir::PolyTraitRef>,
2140     pub region_bounds: Vec<&'a hir::Lifetime>,
2141 }
2142
2143 /// Divides a list of bounds from the AST into three groups: builtin bounds (Copy, Sized etc),
2144 /// general trait bounds, and region bounds.
2145 pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
2146                                             _span: Span,
2147                                             ast_bounds: &'b [hir::TyParamBound])
2148                                             -> PartitionedBounds<'b>
2149 {
2150     let mut builtin_bounds = ty::BuiltinBounds::empty();
2151     let mut region_bounds = Vec::new();
2152     let mut trait_bounds = Vec::new();
2153     for ast_bound in ast_bounds {
2154         match *ast_bound {
2155             hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
2156                 match tcx.expect_def(b.trait_ref.ref_id) {
2157                     Def::Trait(trait_did) => {
2158                         if tcx.try_add_builtin_trait(trait_did,
2159                                                      &mut builtin_bounds) {
2160                             let segments = &b.trait_ref.path.segments;
2161                             let parameters = &segments[segments.len() - 1].parameters;
2162                             if !parameters.types().is_empty() {
2163                                 check_type_argument_count(tcx, b.trait_ref.path.span,
2164                                                           parameters.types().len(), &[]);
2165                             }
2166                             if !parameters.lifetimes().is_empty() {
2167                                 report_lifetime_number_error(tcx, b.trait_ref.path.span,
2168                                                              parameters.lifetimes().len(), 0);
2169                             }
2170                             continue; // success
2171                         }
2172                     }
2173                     _ => {
2174                         // Not a trait? that's an error, but it'll get
2175                         // reported later.
2176                     }
2177                 }
2178                 trait_bounds.push(b);
2179             }
2180             hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
2181             hir::RegionTyParamBound(ref l) => {
2182                 region_bounds.push(l);
2183             }
2184         }
2185     }
2186
2187     PartitionedBounds {
2188         builtin_bounds: builtin_bounds,
2189         trait_bounds: trait_bounds,
2190         region_bounds: region_bounds,
2191     }
2192 }
2193
2194 fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
2195                              ty_param_defs: &[ty::TypeParameterDef]) {
2196     let accepted = ty_param_defs.len();
2197     let required = ty_param_defs.iter().take_while(|x| x.default.is_none()) .count();
2198     if supplied < required {
2199         let expected = if required < accepted {
2200             "expected at least"
2201         } else {
2202             "expected"
2203         };
2204         struct_span_err!(tcx.sess, span, E0243, "wrong number of type arguments")
2205             .span_label(
2206                 span,
2207                 &format!("{} {} type arguments, found {}", expected, required, supplied)
2208             )
2209             .emit();
2210     } else if supplied > accepted {
2211         let expected = if required == 0 {
2212             "expected no".to_string()
2213         } else if required < accepted {
2214             format!("expected at most {}", accepted)
2215         } else {
2216             format!("expected {}", accepted)
2217         };
2218
2219         struct_span_err!(tcx.sess, span, E0244, "wrong number of type arguments")
2220             .span_label(
2221                 span,
2222                 &format!("{} type arguments, found {}", expected, supplied)
2223             )
2224             .emit();
2225     }
2226 }
2227
2228 fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected: usize) {
2229     let label = if number < expected {
2230         if expected == 1 {
2231             format!("expected {} lifetime parameter", expected)
2232         } else {
2233             format!("expected {} lifetime parameters", expected)
2234         }
2235     } else {
2236         let additional = number - expected;
2237         if additional == 1 {
2238             "unexpected lifetime parameter".to_string()
2239         } else {
2240             format!("{} unexpected lifetime parameters", additional)
2241         }
2242     };
2243     struct_span_err!(tcx.sess, span, E0107,
2244                      "wrong number of lifetime parameters: expected {}, found {}",
2245                      expected, number)
2246         .span_label(span, &label)
2247         .emit();
2248 }
2249
2250 // A helper struct for conveniently grouping a set of bounds which we pass to
2251 // and return from functions in multiple places.
2252 #[derive(PartialEq, Eq, Clone, Debug)]
2253 pub struct Bounds<'tcx> {
2254     pub region_bounds: Vec<&'tcx ty::Region>,
2255     pub builtin_bounds: ty::BuiltinBounds,
2256     pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
2257     pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
2258 }
2259
2260 impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
2261     pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
2262                       -> Vec<ty::Predicate<'tcx>>
2263     {
2264         let mut vec = Vec::new();
2265
2266         for builtin_bound in &self.builtin_bounds {
2267             match tcx.trait_ref_for_builtin_bound(builtin_bound, param_ty) {
2268                 Ok(trait_ref) => { vec.push(trait_ref.to_predicate()); }
2269                 Err(ErrorReported) => { }
2270             }
2271         }
2272
2273         for &region_bound in &self.region_bounds {
2274             // account for the binder being introduced below; no need to shift `param_ty`
2275             // because, at present at least, it can only refer to early-bound regions
2276             let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
2277             vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
2278         }
2279
2280         for bound_trait_ref in &self.trait_bounds {
2281             vec.push(bound_trait_ref.to_predicate());
2282         }
2283
2284         for projection in &self.projection_bounds {
2285             vec.push(projection.to_predicate());
2286         }
2287
2288         vec
2289     }
2290 }