]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/astconv.rs
f5e289c33028e3010044b751c8ee4499cf5a9a3e
[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             span_err!(self.tcx().sess, span, E0220,
1245                       "associated type `{}` not found for `{}`",
1246                       assoc_name,
1247                       ty_param_name);
1248             return Err(ErrorReported);
1249         }
1250
1251         if bounds.len() > 1 {
1252             let mut err = struct_span_err!(
1253                 self.tcx().sess, span, E0221,
1254                 "ambiguous associated type `{}` in bounds of `{}`",
1255                 assoc_name,
1256                 ty_param_name);
1257             err.span_label(span, &format!("ambiguous associated type `{}`", assoc_name));
1258
1259             for bound in &bounds {
1260                 span_note!(&mut err, span,
1261                            "associated type `{}` could derive from `{}`",
1262                            ty_param_name,
1263                            bound);
1264             }
1265             err.emit();
1266         }
1267
1268         Ok(bounds[0].clone())
1269     }
1270
1271     // Create a type from a path to an associated type.
1272     // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
1273     // and item_segment is the path segment for D. We return a type and a def for
1274     // the whole path.
1275     // Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
1276     // parameter or Self.
1277     fn associated_path_def_to_ty(&self,
1278                                  span: Span,
1279                                  ty: Ty<'tcx>,
1280                                  ty_path_def: Def,
1281                                  item_segment: &hir::PathSegment)
1282                                  -> (Ty<'tcx>, Def)
1283     {
1284         let tcx = self.tcx();
1285         let assoc_name = item_segment.name;
1286
1287         debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
1288
1289         tcx.prohibit_type_params(slice::ref_slice(item_segment));
1290
1291         // Find the type of the associated item, and the trait where the associated
1292         // item is declared.
1293         let bound = match (&ty.sty, ty_path_def) {
1294             (_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
1295                 // `Self` in an impl of a trait - we have a concrete self type and a
1296                 // trait reference.
1297                 let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
1298                 let trait_ref = if let Some(free_substs) = self.get_free_substs() {
1299                     trait_ref.subst(tcx, free_substs)
1300                 } else {
1301                     trait_ref
1302                 };
1303
1304                 if self.ensure_super_predicates(span, trait_ref.def_id).is_err() {
1305                     return (tcx.types.err, Def::Err);
1306                 }
1307
1308                 let candidates: Vec<ty::PolyTraitRef> =
1309                     traits::supertraits(tcx, ty::Binder(trait_ref))
1310                     .filter(|r| self.trait_defines_associated_type_named(r.def_id(),
1311                                                                          assoc_name))
1312                     .collect();
1313
1314                 match self.one_bound_for_assoc_type(candidates,
1315                                                     "Self",
1316                                                     &assoc_name.as_str(),
1317                                                     span) {
1318                     Ok(bound) => bound,
1319                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
1320                 }
1321             }
1322             (&ty::TyParam(_), Def::SelfTy(Some(trait_did), None)) => {
1323                 let trait_node_id = tcx.map.as_local_node_id(trait_did).unwrap();
1324                 match self.find_bound_for_assoc_item(trait_node_id,
1325                                                      keywords::SelfType.name(),
1326                                                      assoc_name,
1327                                                      span) {
1328                     Ok(bound) => bound,
1329                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
1330                 }
1331             }
1332             (&ty::TyParam(_), Def::TyParam(param_did)) => {
1333                 let param_node_id = tcx.map.as_local_node_id(param_did).unwrap();
1334                 let param_name = tcx.type_parameter_def(param_node_id).name;
1335                 match self.find_bound_for_assoc_item(param_node_id,
1336                                                      param_name,
1337                                                      assoc_name,
1338                                                      span) {
1339                     Ok(bound) => bound,
1340                     Err(ErrorReported) => return (tcx.types.err, Def::Err),
1341                 }
1342             }
1343             _ => {
1344                 // Don't print TyErr to the user.
1345                 if !ty.references_error() {
1346                     self.report_ambiguous_associated_type(span,
1347                                                           &ty.to_string(),
1348                                                           "Trait",
1349                                                           &assoc_name.as_str());
1350                 }
1351                 return (tcx.types.err, Def::Err);
1352             }
1353         };
1354
1355         let trait_did = bound.0.def_id;
1356         let ty = self.projected_ty_from_poly_trait_ref(span, bound, assoc_name);
1357
1358         let item_did = if let Some(trait_id) = tcx.map.as_local_node_id(trait_did) {
1359             // `ty::trait_items` used below requires information generated
1360             // by type collection, which may be in progress at this point.
1361             match tcx.map.expect_item(trait_id).node {
1362                 hir::ItemTrait(.., ref trait_items) => {
1363                     let item = trait_items.iter()
1364                                           .find(|i| i.name == assoc_name)
1365                                           .expect("missing associated type");
1366                     tcx.map.local_def_id(item.id)
1367                 }
1368                 _ => bug!()
1369             }
1370         } else {
1371             let trait_items = tcx.trait_items(trait_did);
1372             let item = trait_items.iter().find(|i| i.name() == assoc_name);
1373             item.expect("missing associated type").def_id()
1374         };
1375
1376         (ty, Def::AssociatedTy(item_did))
1377     }
1378
1379     fn qpath_to_ty(&self,
1380                    rscope: &RegionScope,
1381                    span: Span,
1382                    param_mode: PathParamMode,
1383                    opt_self_ty: Option<Ty<'tcx>>,
1384                    trait_def_id: DefId,
1385                    trait_segment: &hir::PathSegment,
1386                    item_segment: &hir::PathSegment)
1387                    -> Ty<'tcx>
1388     {
1389         let tcx = self.tcx();
1390
1391         tcx.prohibit_type_params(slice::ref_slice(item_segment));
1392
1393         let self_ty = if let Some(ty) = opt_self_ty {
1394             ty
1395         } else {
1396             let path_str = tcx.item_path_str(trait_def_id);
1397             self.report_ambiguous_associated_type(span,
1398                                                   "Type",
1399                                                   &path_str,
1400                                                   &item_segment.name.as_str());
1401             return tcx.types.err;
1402         };
1403
1404         debug!("qpath_to_ty: self_type={:?}", self_ty);
1405
1406         let trait_ref = self.ast_path_to_mono_trait_ref(rscope,
1407                                                         span,
1408                                                         param_mode,
1409                                                         trait_def_id,
1410                                                         self_ty,
1411                                                         trait_segment);
1412
1413         debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
1414
1415         self.projected_ty(span, trait_ref, item_segment.name)
1416     }
1417
1418     /// Convert a type supplied as value for a type argument from AST into our
1419     /// our internal representation. This is the same as `ast_ty_to_ty` but that
1420     /// it applies the object lifetime default.
1421     ///
1422     /// # Parameters
1423     ///
1424     /// * `this`, `rscope`: the surrounding context
1425     /// * `def`: the type parameter being instantiated (if available)
1426     /// * `region_substs`: a partial substitution consisting of
1427     ///   only the region type parameters being supplied to this type.
1428     /// * `ast_ty`: the ast representation of the type being supplied
1429     fn ast_ty_arg_to_ty(&self,
1430                         rscope: &RegionScope,
1431                         def: Option<&ty::TypeParameterDef<'tcx>>,
1432                         region_substs: &Substs<'tcx>,
1433                         ast_ty: &hir::Ty)
1434                         -> Ty<'tcx>
1435     {
1436         let tcx = self.tcx();
1437
1438         if let Some(def) = def {
1439             let object_lifetime_default = def.object_lifetime_default.subst(tcx, region_substs);
1440             let rscope1 = &ObjectLifetimeDefaultRscope::new(rscope, object_lifetime_default);
1441             self.ast_ty_to_ty(rscope1, ast_ty)
1442         } else {
1443             self.ast_ty_to_ty(rscope, ast_ty)
1444         }
1445     }
1446
1447     // Check the base def in a PathResolution and convert it to a Ty. If there are
1448     // associated types in the PathResolution, these will need to be separately
1449     // resolved.
1450     fn base_def_to_ty(&self,
1451                       rscope: &RegionScope,
1452                       span: Span,
1453                       param_mode: PathParamMode,
1454                       def: Def,
1455                       opt_self_ty: Option<Ty<'tcx>>,
1456                       base_path_ref_id: ast::NodeId,
1457                       base_segments: &[hir::PathSegment])
1458                       -> Ty<'tcx> {
1459         let tcx = self.tcx();
1460
1461         debug!("base_def_to_ty(def={:?}, opt_self_ty={:?}, base_segments={:?})",
1462                def, opt_self_ty, base_segments);
1463
1464         match def {
1465             Def::Trait(trait_def_id) => {
1466                 // N.B. this case overlaps somewhat with
1467                 // TyObjectSum, see that fn for details
1468
1469                 tcx.prohibit_type_params(base_segments.split_last().unwrap().1);
1470
1471                 self.trait_path_to_object_type(rscope,
1472                                                span,
1473                                                param_mode,
1474                                                trait_def_id,
1475                                                base_path_ref_id,
1476                                                base_segments.last().unwrap(),
1477                                                span,
1478                                                partition_bounds(tcx, span, &[]))
1479             }
1480             Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => {
1481                 tcx.prohibit_type_params(base_segments.split_last().unwrap().1);
1482                 self.ast_path_to_ty(rscope,
1483                                     span,
1484                                     param_mode,
1485                                     did,
1486                                     base_segments.last().unwrap())
1487             }
1488             Def::TyParam(did) => {
1489                 tcx.prohibit_type_params(base_segments);
1490
1491                 let node_id = tcx.map.as_local_node_id(did).unwrap();
1492                 let param = tcx.ty_param_defs.borrow().get(&node_id)
1493                                .map(ty::ParamTy::for_def);
1494                 if let Some(p) = param {
1495                     p.to_ty(tcx)
1496                 } else {
1497                     // Only while computing defaults of earlier type
1498                     // parameters can a type parameter be missing its def.
1499                     struct_span_err!(tcx.sess, span, E0128,
1500                                      "type parameters with a default cannot use \
1501                                       forward declared identifiers")
1502                         .span_label(span, &format!("defaulted type parameters \
1503                                                     cannot be forward declared"))
1504                         .emit();
1505                     tcx.types.err
1506                 }
1507             }
1508             Def::SelfTy(_, Some(def_id)) => {
1509                 // Self in impl (we know the concrete type).
1510
1511                 tcx.prohibit_type_params(base_segments);
1512                 let impl_id = tcx.map.as_local_node_id(def_id).unwrap();
1513                 let ty = tcx.node_id_to_type(impl_id);
1514                 if let Some(free_substs) = self.get_free_substs() {
1515                     ty.subst(tcx, free_substs)
1516                 } else {
1517                     ty
1518                 }
1519             }
1520             Def::SelfTy(Some(_), None) => {
1521                 // Self in trait.
1522                 tcx.prohibit_type_params(base_segments);
1523                 tcx.mk_self_type()
1524             }
1525             Def::AssociatedTy(def_id) => {
1526                 tcx.prohibit_type_params(&base_segments[..base_segments.len()-2]);
1527                 let trait_did = tcx.parent_def_id(def_id).unwrap();
1528                 self.qpath_to_ty(rscope,
1529                                  span,
1530                                  param_mode,
1531                                  opt_self_ty,
1532                                  trait_did,
1533                                  &base_segments[base_segments.len()-2],
1534                                  base_segments.last().unwrap())
1535             }
1536             Def::Mod(..) => {
1537                 // Used as sentinel by callers to indicate the `<T>::A::B::C` form.
1538                 // FIXME(#22519) This part of the resolution logic should be
1539                 // avoided entirely for that form, once we stop needed a Def
1540                 // for `associated_path_def_to_ty`.
1541                 // Fixing this will also let use resolve <Self>::Foo the same way we
1542                 // resolve Self::Foo, at the moment we can't resolve the former because
1543                 // we don't have the trait information around, which is just sad.
1544
1545                 assert!(base_segments.is_empty());
1546
1547                 opt_self_ty.expect("missing T in <T>::a::b::c")
1548             }
1549             Def::PrimTy(prim_ty) => {
1550                 tcx.prim_ty_to_ty(base_segments, prim_ty)
1551             }
1552             Def::Err => {
1553                 self.set_tainted_by_errors();
1554                 return self.tcx().types.err;
1555             }
1556             _ => {
1557                 struct_span_err!(tcx.sess, span, E0248,
1558                            "found value `{}` used as a type",
1559                             tcx.item_path_str(def.def_id()))
1560                            .span_label(span, &format!("value used as a type"))
1561                            .emit();
1562                 return self.tcx().types.err;
1563             }
1564         }
1565     }
1566
1567     // Resolve possibly associated type path into a type and final definition.
1568     // Note that both base_segments and assoc_segments may be empty, although not at same time.
1569     pub fn finish_resolving_def_to_ty(&self,
1570                                       rscope: &RegionScope,
1571                                       span: Span,
1572                                       param_mode: PathParamMode,
1573                                       base_def: Def,
1574                                       opt_self_ty: Option<Ty<'tcx>>,
1575                                       base_path_ref_id: ast::NodeId,
1576                                       base_segments: &[hir::PathSegment],
1577                                       assoc_segments: &[hir::PathSegment])
1578                                       -> (Ty<'tcx>, Def) {
1579         // Convert the base type.
1580         debug!("finish_resolving_def_to_ty(base_def={:?}, \
1581                 base_segments={:?}, \
1582                 assoc_segments={:?})",
1583                base_def,
1584                base_segments,
1585                assoc_segments);
1586         let base_ty = self.base_def_to_ty(rscope,
1587                                           span,
1588                                           param_mode,
1589                                           base_def,
1590                                           opt_self_ty,
1591                                           base_path_ref_id,
1592                                           base_segments);
1593         debug!("finish_resolving_def_to_ty: base_def_to_ty returned {:?}", base_ty);
1594
1595         // If any associated type segments remain, attempt to resolve them.
1596         let (mut ty, mut def) = (base_ty, base_def);
1597         for segment in assoc_segments {
1598             debug!("finish_resolving_def_to_ty: segment={:?}", segment);
1599             // This is pretty bad (it will fail except for T::A and Self::A).
1600             let (new_ty, new_def) = self.associated_path_def_to_ty(span, ty, def, segment);
1601             ty = new_ty;
1602             def = new_def;
1603
1604             if def == Def::Err {
1605                 break;
1606             }
1607         }
1608         (ty, def)
1609     }
1610
1611     /// Parses the programmer's textual representation of a type into our
1612     /// internal notion of a type.
1613     pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> {
1614         debug!("ast_ty_to_ty(id={:?}, ast_ty={:?})",
1615                ast_ty.id, ast_ty);
1616
1617         let tcx = self.tcx();
1618
1619         let cache = self.ast_ty_to_ty_cache();
1620         match cache.borrow().get(&ast_ty.id) {
1621             Some(ty) => { return ty; }
1622             None => { }
1623         }
1624
1625         let result_ty = match ast_ty.node {
1626             hir::TyVec(ref ty) => {
1627                 tcx.mk_slice(self.ast_ty_to_ty(rscope, &ty))
1628             }
1629             hir::TyObjectSum(ref ty, ref bounds) => {
1630                 self.ast_ty_to_object_trait_ref(rscope, ast_ty.span, ty, bounds)
1631             }
1632             hir::TyPtr(ref mt) => {
1633                 tcx.mk_ptr(ty::TypeAndMut {
1634                     ty: self.ast_ty_to_ty(rscope, &mt.ty),
1635                     mutbl: mt.mutbl
1636                 })
1637             }
1638             hir::TyRptr(ref region, ref mt) => {
1639                 let r = self.opt_ast_region_to_region(rscope, ast_ty.span, region);
1640                 debug!("TyRef r={:?}", r);
1641                 let rscope1 =
1642                     &ObjectLifetimeDefaultRscope::new(
1643                         rscope,
1644                         ty::ObjectLifetimeDefault::Specific(r));
1645                 let t = self.ast_ty_to_ty(rscope1, &mt.ty);
1646                 tcx.mk_ref(r, ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
1647             }
1648             hir::TyNever => {
1649                 tcx.types.never
1650             },
1651             hir::TyTup(ref fields) => {
1652                 let flds = fields.iter()
1653                                  .map(|t| self.ast_ty_to_ty(rscope, &t))
1654                                  .collect();
1655                 tcx.mk_tup(flds)
1656             }
1657             hir::TyBareFn(ref bf) => {
1658                 require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
1659                 let anon_scope = rscope.anon_type_scope();
1660                 let (bare_fn_ty, _) =
1661                     self.ty_of_method_or_bare_fn(bf.unsafety,
1662                                                  bf.abi,
1663                                                  None,
1664                                                  &bf.decl,
1665                                                  anon_scope,
1666                                                  anon_scope);
1667
1668                 // Find any late-bound regions declared in return type that do
1669                 // not appear in the arguments. These are not wellformed.
1670                 //
1671                 // Example:
1672                 //
1673                 //     for<'a> fn() -> &'a str <-- 'a is bad
1674                 //     for<'a> fn(&'a String) -> &'a str <-- 'a is ok
1675                 //
1676                 // Note that we do this check **here** and not in
1677                 // `ty_of_bare_fn` because the latter is also used to make
1678                 // the types for fn items, and we do not want to issue a
1679                 // warning then. (Once we fix #32330, the regions we are
1680                 // checking for here would be considered early bound
1681                 // anyway.)
1682                 let inputs = bare_fn_ty.sig.inputs();
1683                 let late_bound_in_args = tcx.collect_constrained_late_bound_regions(&inputs);
1684                 let output = bare_fn_ty.sig.output();
1685                 let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
1686                 for br in late_bound_in_ret.difference(&late_bound_in_args) {
1687                     let br_name = match *br {
1688                         ty::BrNamed(_, name, _) => name,
1689                         _ => {
1690                             span_bug!(
1691                                 bf.decl.output.span(),
1692                                 "anonymous bound region {:?} in return but not args",
1693                                 br);
1694                         }
1695                     };
1696                     tcx.sess.add_lint(
1697                         lint::builtin::HR_LIFETIME_IN_ASSOC_TYPE,
1698                         ast_ty.id,
1699                         ast_ty.span,
1700                         format!("return type references lifetime `{}`, \
1701                                  which does not appear in the trait input types",
1702                                 br_name));
1703                 }
1704                 tcx.mk_fn_ptr(bare_fn_ty)
1705             }
1706             hir::TyPolyTraitRef(ref bounds) => {
1707                 self.conv_object_ty_poly_trait_ref(rscope, ast_ty.span, bounds)
1708             }
1709             hir::TyImplTrait(ref bounds) => {
1710                 use collect::{compute_bounds, SizedByDefault};
1711
1712                 // Create the anonymized type.
1713                 let def_id = tcx.map.local_def_id(ast_ty.id);
1714                 if let Some(anon_scope) = rscope.anon_type_scope() {
1715                     let substs = anon_scope.fresh_substs(self, ast_ty.span);
1716                     let ty = tcx.mk_anon(tcx.map.local_def_id(ast_ty.id), substs);
1717
1718                     // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
1719                     let bounds = compute_bounds(self, ty, bounds,
1720                                                 SizedByDefault::Yes,
1721                                                 Some(anon_scope),
1722                                                 ast_ty.span);
1723                     let predicates = bounds.predicates(tcx, ty);
1724                     let predicates = tcx.lift_to_global(&predicates).unwrap();
1725                     tcx.predicates.borrow_mut().insert(def_id, ty::GenericPredicates {
1726                         parent: None,
1727                         predicates: predicates
1728                     });
1729
1730                     ty
1731                 } else {
1732                     span_err!(tcx.sess, ast_ty.span, E0562,
1733                               "`impl Trait` not allowed outside of function \
1734                                and inherent method return types");
1735                     tcx.types.err
1736                 }
1737             }
1738             hir::TyPath(ref maybe_qself, ref path) => {
1739                 debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
1740                 let path_res = tcx.expect_resolution(ast_ty.id);
1741                 let base_ty_end = path.segments.len() - path_res.depth;
1742                 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
1743                     self.ast_ty_to_ty(rscope, &qself.ty)
1744                 });
1745                 let (ty, def) = self.finish_resolving_def_to_ty(rscope,
1746                                                                 ast_ty.span,
1747                                                                 PathParamMode::Explicit,
1748                                                                 path_res.base_def,
1749                                                                 opt_self_ty,
1750                                                                 ast_ty.id,
1751                                                                 &path.segments[..base_ty_end],
1752                                                                 &path.segments[base_ty_end..]);
1753
1754                 // Write back the new resolution.
1755                 if path_res.depth != 0 {
1756                     tcx.def_map.borrow_mut().insert(ast_ty.id, PathResolution::new(def));
1757                 }
1758
1759                 ty
1760             }
1761             hir::TyFixedLengthVec(ref ty, ref e) => {
1762                 if let Ok(length) = eval_length(tcx.global_tcx(), &e, "array length") {
1763                     tcx.mk_array(self.ast_ty_to_ty(rscope, &ty), length)
1764                 } else {
1765                     self.tcx().types.err
1766                 }
1767             }
1768             hir::TyTypeof(ref _e) => {
1769                 struct_span_err!(tcx.sess, ast_ty.span, E0516,
1770                                  "`typeof` is a reserved keyword but unimplemented")
1771                     .span_label(ast_ty.span, &format!("reserved keyword"))
1772                     .emit();
1773
1774                 tcx.types.err
1775             }
1776             hir::TyInfer => {
1777                 // TyInfer also appears as the type of arguments or return
1778                 // values in a ExprClosure, or as
1779                 // the type of local variables. Both of these cases are
1780                 // handled specially and will not descend into this routine.
1781                 self.ty_infer(ast_ty.span)
1782             }
1783         };
1784
1785         cache.borrow_mut().insert(ast_ty.id, result_ty);
1786
1787         result_ty
1788     }
1789
1790     pub fn ty_of_arg(&self,
1791                      rscope: &RegionScope,
1792                      a: &hir::Arg,
1793                      expected_ty: Option<Ty<'tcx>>)
1794                      -> Ty<'tcx>
1795     {
1796         match a.ty.node {
1797             hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
1798             hir::TyInfer => self.ty_infer(a.ty.span),
1799             _ => self.ast_ty_to_ty(rscope, &a.ty),
1800         }
1801     }
1802
1803     pub fn ty_of_method(&self,
1804                         sig: &hir::MethodSig,
1805                         untransformed_self_ty: Ty<'tcx>,
1806                         anon_scope: Option<AnonTypeScope>)
1807                         -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory<'tcx>) {
1808         self.ty_of_method_or_bare_fn(sig.unsafety,
1809                                      sig.abi,
1810                                      Some(untransformed_self_ty),
1811                                      &sig.decl,
1812                                      None,
1813                                      anon_scope)
1814     }
1815
1816     pub fn ty_of_bare_fn(&self,
1817                          unsafety: hir::Unsafety,
1818                          abi: abi::Abi,
1819                          decl: &hir::FnDecl,
1820                          anon_scope: Option<AnonTypeScope>)
1821                          -> &'tcx ty::BareFnTy<'tcx> {
1822         self.ty_of_method_or_bare_fn(unsafety, abi, None, decl, None, anon_scope).0
1823     }
1824
1825     fn ty_of_method_or_bare_fn(&self,
1826                                unsafety: hir::Unsafety,
1827                                abi: abi::Abi,
1828                                opt_untransformed_self_ty: Option<Ty<'tcx>>,
1829                                decl: &hir::FnDecl,
1830                                arg_anon_scope: Option<AnonTypeScope>,
1831                                ret_anon_scope: Option<AnonTypeScope>)
1832                                -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory<'tcx>)
1833     {
1834         debug!("ty_of_method_or_bare_fn");
1835
1836         // New region names that appear inside of the arguments of the function
1837         // declaration are bound to that function type.
1838         let rb = MaybeWithAnonTypes::new(BindingRscope::new(), arg_anon_scope);
1839
1840         // `implied_output_region` is the region that will be assumed for any
1841         // region parameters in the return type. In accordance with the rules for
1842         // lifetime elision, we can determine it in two ways. First (determined
1843         // here), if self is by-reference, then the implied output region is the
1844         // region of the self parameter.
1845         let (self_ty, explicit_self_category) = match (opt_untransformed_self_ty, decl.get_self()) {
1846             (Some(untransformed_self_ty), Some(explicit_self)) => {
1847                 let self_type = self.determine_self_type(&rb, untransformed_self_ty,
1848                                                          &explicit_self);
1849                 (Some(self_type.0), self_type.1)
1850             }
1851             _ => (None, ty::ExplicitSelfCategory::Static),
1852         };
1853
1854         // HACK(eddyb) replace the fake self type in the AST with the actual type.
1855         let arg_params = if self_ty.is_some() {
1856             &decl.inputs[1..]
1857         } else {
1858             &decl.inputs[..]
1859         };
1860         let arg_tys: Vec<Ty> =
1861             arg_params.iter().map(|a| self.ty_of_arg(&rb, a, None)).collect();
1862         let arg_pats: Vec<String> =
1863             arg_params.iter().map(|a| pprust::pat_to_string(&a.pat)).collect();
1864
1865         // Second, if there was exactly one lifetime (either a substitution or a
1866         // reference) in the arguments, then any anonymous regions in the output
1867         // have that lifetime.
1868         let implied_output_region = match explicit_self_category {
1869             ty::ExplicitSelfCategory::ByReference(region, _) => Ok(*region),
1870             _ => self.find_implied_output_region(&arg_tys, arg_pats)
1871         };
1872
1873         let output_ty = match decl.output {
1874             hir::Return(ref output) =>
1875                 self.convert_ty_with_lifetime_elision(implied_output_region,
1876                                                       &output,
1877                                                       ret_anon_scope),
1878             hir::DefaultReturn(..) => self.tcx().mk_nil(),
1879         };
1880
1881         let input_tys = self_ty.into_iter().chain(arg_tys).collect();
1882
1883         debug!("ty_of_method_or_bare_fn: input_tys={:?}", input_tys);
1884         debug!("ty_of_method_or_bare_fn: output_ty={:?}", output_ty);
1885
1886         (self.tcx().mk_bare_fn(ty::BareFnTy {
1887             unsafety: unsafety,
1888             abi: abi,
1889             sig: ty::Binder(ty::FnSig {
1890                 inputs: input_tys,
1891                 output: output_ty,
1892                 variadic: decl.variadic
1893             }),
1894         }), explicit_self_category)
1895     }
1896
1897     fn determine_self_type<'a>(&self,
1898                                rscope: &RegionScope,
1899                                untransformed_self_ty: Ty<'tcx>,
1900                                explicit_self: &hir::ExplicitSelf)
1901                                -> (Ty<'tcx>, ty::ExplicitSelfCategory<'tcx>)
1902     {
1903         return match explicit_self.node {
1904             SelfKind::Value(..) => {
1905                 (untransformed_self_ty, ty::ExplicitSelfCategory::ByValue)
1906             }
1907             SelfKind::Region(ref lifetime, mutability) => {
1908                 let region =
1909                     self.opt_ast_region_to_region(
1910                                              rscope,
1911                                              explicit_self.span,
1912                                              lifetime);
1913                 (self.tcx().mk_ref(region,
1914                     ty::TypeAndMut {
1915                         ty: untransformed_self_ty,
1916                         mutbl: mutability
1917                     }),
1918                  ty::ExplicitSelfCategory::ByReference(region, mutability))
1919             }
1920             SelfKind::Explicit(ref ast_type, _) => {
1921                 let explicit_type = self.ast_ty_to_ty(rscope, &ast_type);
1922
1923                 // We wish to (for now) categorize an explicit self
1924                 // declaration like `self: SomeType` into either `self`,
1925                 // `&self`, `&mut self`, or `Box<self>`. We do this here
1926                 // by some simple pattern matching. A more precise check
1927                 // is done later in `check_method_self_type()`.
1928                 //
1929                 // Examples:
1930                 //
1931                 // ```
1932                 // impl Foo for &T {
1933                 //     // Legal declarations:
1934                 //     fn method1(self: &&T); // ExplicitSelfCategory::ByReference
1935                 //     fn method2(self: &T); // ExplicitSelfCategory::ByValue
1936                 //     fn method3(self: Box<&T>); // ExplicitSelfCategory::ByBox
1937                 //
1938                 //     // Invalid cases will be caught later by `check_method_self_type`:
1939                 //     fn method_err1(self: &mut T); // ExplicitSelfCategory::ByReference
1940                 // }
1941                 // ```
1942                 //
1943                 // To do the check we just count the number of "modifiers"
1944                 // on each type and compare them. If they are the same or
1945                 // the impl has more, we call it "by value". Otherwise, we
1946                 // look at the outermost modifier on the method decl and
1947                 // call it by-ref, by-box as appropriate. For method1, for
1948                 // example, the impl type has one modifier, but the method
1949                 // type has two, so we end up with
1950                 // ExplicitSelfCategory::ByReference.
1951
1952                 let impl_modifiers = count_modifiers(untransformed_self_ty);
1953                 let method_modifiers = count_modifiers(explicit_type);
1954
1955                 debug!("determine_explicit_self_category(self_info.untransformed_self_ty={:?} \
1956                        explicit_type={:?} \
1957                        modifiers=({},{})",
1958                        untransformed_self_ty,
1959                        explicit_type,
1960                        impl_modifiers,
1961                        method_modifiers);
1962
1963                 let category = if impl_modifiers >= method_modifiers {
1964                     ty::ExplicitSelfCategory::ByValue
1965                 } else {
1966                     match explicit_type.sty {
1967                         ty::TyRef(r, mt) => ty::ExplicitSelfCategory::ByReference(r, mt.mutbl),
1968                         ty::TyBox(_) => ty::ExplicitSelfCategory::ByBox,
1969                         _ => ty::ExplicitSelfCategory::ByValue,
1970                     }
1971                 };
1972
1973                 (explicit_type, category)
1974             }
1975         };
1976
1977         fn count_modifiers(ty: Ty) -> usize {
1978             match ty.sty {
1979                 ty::TyRef(_, mt) => count_modifiers(mt.ty) + 1,
1980                 ty::TyBox(t) => count_modifiers(t) + 1,
1981                 _ => 0,
1982             }
1983         }
1984     }
1985
1986     pub fn ty_of_closure(&self,
1987         unsafety: hir::Unsafety,
1988         decl: &hir::FnDecl,
1989         abi: abi::Abi,
1990         expected_sig: Option<ty::FnSig<'tcx>>)
1991         -> ty::ClosureTy<'tcx>
1992     {
1993         debug!("ty_of_closure(expected_sig={:?})",
1994                expected_sig);
1995
1996         // new region names that appear inside of the fn decl are bound to
1997         // that function type
1998         let rb = rscope::BindingRscope::new();
1999
2000         let input_tys: Vec<_> = decl.inputs.iter().enumerate().map(|(i, a)| {
2001             let expected_arg_ty = expected_sig.as_ref().and_then(|e| {
2002                 // no guarantee that the correct number of expected args
2003                 // were supplied
2004                 if i < e.inputs.len() {
2005                     Some(e.inputs[i])
2006                 } else {
2007                     None
2008                 }
2009             });
2010             self.ty_of_arg(&rb, a, expected_arg_ty)
2011         }).collect();
2012
2013         let expected_ret_ty = expected_sig.map(|e| e.output);
2014
2015         let is_infer = match decl.output {
2016             hir::Return(ref output) if output.node == hir::TyInfer => true,
2017             hir::DefaultReturn(..) => true,
2018             _ => false
2019         };
2020
2021         let output_ty = match decl.output {
2022             _ if is_infer && expected_ret_ty.is_some() =>
2023                 expected_ret_ty.unwrap(),
2024             _ if is_infer => self.ty_infer(decl.output.span()),
2025             hir::Return(ref output) =>
2026                 self.ast_ty_to_ty(&rb, &output),
2027             hir::DefaultReturn(..) => bug!(),
2028         };
2029
2030         debug!("ty_of_closure: input_tys={:?}", input_tys);
2031         debug!("ty_of_closure: output_ty={:?}", output_ty);
2032
2033         ty::ClosureTy {
2034             unsafety: unsafety,
2035             abi: abi,
2036             sig: ty::Binder(ty::FnSig {inputs: input_tys,
2037                                        output: output_ty,
2038                                        variadic: decl.variadic}),
2039         }
2040     }
2041
2042     fn conv_object_ty_poly_trait_ref(&self,
2043         rscope: &RegionScope,
2044         span: Span,
2045         ast_bounds: &[hir::TyParamBound])
2046         -> Ty<'tcx>
2047     {
2048         let mut partitioned_bounds = partition_bounds(self.tcx(), span, &ast_bounds[..]);
2049
2050         let trait_bound = if !partitioned_bounds.trait_bounds.is_empty() {
2051             partitioned_bounds.trait_bounds.remove(0)
2052         } else {
2053             span_err!(self.tcx().sess, span, E0224,
2054                       "at least one non-builtin trait is required for an object type");
2055             return self.tcx().types.err;
2056         };
2057
2058         let trait_ref = &trait_bound.trait_ref;
2059         let trait_def_id = self.trait_def_id(trait_ref);
2060         self.trait_path_to_object_type(rscope,
2061                                        trait_ref.path.span,
2062                                        PathParamMode::Explicit,
2063                                        trait_def_id,
2064                                        trait_ref.ref_id,
2065                                        trait_ref.path.segments.last().unwrap(),
2066                                        span,
2067                                        partitioned_bounds)
2068     }
2069
2070     /// Given the bounds on an object, determines what single region bound (if any) we can
2071     /// use to summarize this type. The basic idea is that we will use the bound the user
2072     /// provided, if they provided one, and otherwise search the supertypes of trait bounds
2073     /// for region bounds. It may be that we can derive no bound at all, in which case
2074     /// we return `None`.
2075     fn compute_object_lifetime_bound(&self,
2076         span: Span,
2077         explicit_region_bounds: &[&hir::Lifetime],
2078         principal_trait_ref: ty::PolyExistentialTraitRef<'tcx>,
2079         builtin_bounds: ty::BuiltinBounds)
2080         -> Option<&'tcx ty::Region> // if None, use the default
2081     {
2082         let tcx = self.tcx();
2083
2084         debug!("compute_opt_region_bound(explicit_region_bounds={:?}, \
2085                principal_trait_ref={:?}, builtin_bounds={:?})",
2086                explicit_region_bounds,
2087                principal_trait_ref,
2088                builtin_bounds);
2089
2090         if explicit_region_bounds.len() > 1 {
2091             span_err!(tcx.sess, explicit_region_bounds[1].span, E0226,
2092                 "only a single explicit lifetime bound is permitted");
2093         }
2094
2095         if !explicit_region_bounds.is_empty() {
2096             // Explicitly specified region bound. Use that.
2097             let r = explicit_region_bounds[0];
2098             return Some(ast_region_to_region(tcx, r));
2099         }
2100
2101         if let Err(ErrorReported) =
2102                 self.ensure_super_predicates(span, principal_trait_ref.def_id()) {
2103             return Some(tcx.mk_region(ty::ReStatic));
2104         }
2105
2106         // No explicit region bound specified. Therefore, examine trait
2107         // bounds and see if we can derive region bounds from those.
2108         let derived_region_bounds =
2109             object_region_bounds(tcx, principal_trait_ref, builtin_bounds);
2110
2111         // If there are no derived region bounds, then report back that we
2112         // can find no region bound. The caller will use the default.
2113         if derived_region_bounds.is_empty() {
2114             return None;
2115         }
2116
2117         // If any of the derived region bounds are 'static, that is always
2118         // the best choice.
2119         if derived_region_bounds.iter().any(|&r| ty::ReStatic == *r) {
2120             return Some(tcx.mk_region(ty::ReStatic));
2121         }
2122
2123         // Determine whether there is exactly one unique region in the set
2124         // of derived region bounds. If so, use that. Otherwise, report an
2125         // error.
2126         let r = derived_region_bounds[0];
2127         if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2128             span_err!(tcx.sess, span, E0227,
2129                       "ambiguous lifetime bound, explicit lifetime bound required");
2130         }
2131         return Some(r);
2132     }
2133 }
2134
2135 pub struct PartitionedBounds<'a> {
2136     pub builtin_bounds: ty::BuiltinBounds,
2137     pub trait_bounds: Vec<&'a hir::PolyTraitRef>,
2138     pub region_bounds: Vec<&'a hir::Lifetime>,
2139 }
2140
2141 /// Divides a list of bounds from the AST into three groups: builtin bounds (Copy, Sized etc),
2142 /// general trait bounds, and region bounds.
2143 pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
2144                                             _span: Span,
2145                                             ast_bounds: &'b [hir::TyParamBound])
2146                                             -> PartitionedBounds<'b>
2147 {
2148     let mut builtin_bounds = ty::BuiltinBounds::empty();
2149     let mut region_bounds = Vec::new();
2150     let mut trait_bounds = Vec::new();
2151     for ast_bound in ast_bounds {
2152         match *ast_bound {
2153             hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
2154                 match tcx.expect_def(b.trait_ref.ref_id) {
2155                     Def::Trait(trait_did) => {
2156                         if tcx.try_add_builtin_trait(trait_did,
2157                                                      &mut builtin_bounds) {
2158                             let segments = &b.trait_ref.path.segments;
2159                             let parameters = &segments[segments.len() - 1].parameters;
2160                             if !parameters.types().is_empty() {
2161                                 check_type_argument_count(tcx, b.trait_ref.path.span,
2162                                                           parameters.types().len(), &[]);
2163                             }
2164                             if !parameters.lifetimes().is_empty() {
2165                                 report_lifetime_number_error(tcx, b.trait_ref.path.span,
2166                                                              parameters.lifetimes().len(), 0);
2167                             }
2168                             continue; // success
2169                         }
2170                     }
2171                     _ => {
2172                         // Not a trait? that's an error, but it'll get
2173                         // reported later.
2174                     }
2175                 }
2176                 trait_bounds.push(b);
2177             }
2178             hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
2179             hir::RegionTyParamBound(ref l) => {
2180                 region_bounds.push(l);
2181             }
2182         }
2183     }
2184
2185     PartitionedBounds {
2186         builtin_bounds: builtin_bounds,
2187         trait_bounds: trait_bounds,
2188         region_bounds: region_bounds,
2189     }
2190 }
2191
2192 fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
2193                              ty_param_defs: &[ty::TypeParameterDef]) {
2194     let accepted = ty_param_defs.len();
2195     let required = ty_param_defs.iter().take_while(|x| x.default.is_none()) .count();
2196     if supplied < required {
2197         let expected = if required < accepted {
2198             "expected at least"
2199         } else {
2200             "expected"
2201         };
2202         struct_span_err!(tcx.sess, span, E0243, "wrong number of type arguments")
2203             .span_label(
2204                 span,
2205                 &format!("{} {} type arguments, found {}", expected, required, supplied)
2206             )
2207             .emit();
2208     } else if supplied > accepted {
2209         let expected = if required == 0 {
2210             "expected no".to_string()
2211         } else if required < accepted {
2212             format!("expected at most {}", accepted)
2213         } else {
2214             format!("expected {}", accepted)
2215         };
2216
2217         struct_span_err!(tcx.sess, span, E0244, "wrong number of type arguments")
2218             .span_label(
2219                 span,
2220                 &format!("{} type arguments, found {}", expected, supplied)
2221             )
2222             .emit();
2223     }
2224 }
2225
2226 fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected: usize) {
2227     let label = if number < expected {
2228         if expected == 1 {
2229             format!("expected {} lifetime parameter", expected)
2230         } else {
2231             format!("expected {} lifetime parameters", expected)
2232         }
2233     } else {
2234         let additional = number - expected;
2235         if additional == 1 {
2236             "unexpected lifetime parameter".to_string()
2237         } else {
2238             format!("{} unexpected lifetime parameters", additional)
2239         }
2240     };
2241     struct_span_err!(tcx.sess, span, E0107,
2242                      "wrong number of lifetime parameters: expected {}, found {}",
2243                      expected, number)
2244         .span_label(span, &label)
2245         .emit();
2246 }
2247
2248 // A helper struct for conveniently grouping a set of bounds which we pass to
2249 // and return from functions in multiple places.
2250 #[derive(PartialEq, Eq, Clone, Debug)]
2251 pub struct Bounds<'tcx> {
2252     pub region_bounds: Vec<&'tcx ty::Region>,
2253     pub builtin_bounds: ty::BuiltinBounds,
2254     pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
2255     pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
2256 }
2257
2258 impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
2259     pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
2260                       -> Vec<ty::Predicate<'tcx>>
2261     {
2262         let mut vec = Vec::new();
2263
2264         for builtin_bound in &self.builtin_bounds {
2265             match tcx.trait_ref_for_builtin_bound(builtin_bound, param_ty) {
2266                 Ok(trait_ref) => { vec.push(trait_ref.to_predicate()); }
2267                 Err(ErrorReported) => { }
2268             }
2269         }
2270
2271         for &region_bound in &self.region_bounds {
2272             // account for the binder being introduced below; no need to shift `param_ty`
2273             // because, at present at least, it can only refer to early-bound regions
2274             let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
2275             vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
2276         }
2277
2278         for bound_trait_ref in &self.trait_bounds {
2279             vec.push(bound_trait_ref.to_predicate());
2280         }
2281
2282         for projection in &self.projection_bounds {
2283             vec.push(projection.to_predicate());
2284         }
2285
2286         vec
2287     }
2288 }