]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/astconv.rs
Run `rustfmt --file-lines ...` for changes from previous commits.
[rust.git] / src / librustc_typeck / astconv.rs
index fe17d902c617c8c78f7ed7f8453c95a29a4e9092..2c9309a1696cfd65210643a491bcb1470caffac1 100644 (file)
@@ -13,7 +13,7 @@
 use crate::namespace::Namespace;
 use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
 use rustc::traits;
-use rustc::ty::{self, DefIdTree, Ty, TyCtxt, ToPredicate, TypeFoldable};
+use rustc::ty::{self, DefIdTree, Ty, TyCtxt, Const, ToPredicate, TypeFoldable};
 use rustc::ty::{GenericParamDef, GenericParamDefKind};
 use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
 use rustc::ty::wf::object_region_bounds;
@@ -41,7 +41,7 @@
 pub struct PathSeg(pub DefId, pub usize);
 
 pub trait AstConv<'gcx, 'tcx> {
-    fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
+    fn tcx<'a>(&'a self) -> TyCtxt<'gcx, 'tcx>;
 
     /// Returns the set of bounds in scope for the type parameter with
     /// the given id.
@@ -49,18 +49,23 @@ fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
                                  -> &'tcx ty::GenericPredicates<'tcx>;
 
     /// Returns the lifetime to use when a lifetime is omitted (and not elided).
-    fn re_infer(&self, span: Span, _def: Option<&ty::GenericParamDef>)
+    fn re_infer(
+        &self,
+        param: Option<&ty::GenericParamDef>,
+        span: Span,
+    )
                 -> Option<ty::Region<'tcx>>;
 
     /// Returns the type to use when a type is omitted.
-    fn ty_infer(&self, span: Span) -> Ty<'tcx>;
+    fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
 
-    /// Same as `ty_infer`, but with a known type parameter definition.
-    fn ty_infer_for_def(&self,
-                        _def: &ty::GenericParamDef,
-                        span: Span) -> Ty<'tcx> {
-        self.ty_infer(span)
-    }
+    /// Returns the const to use when a const is omitted.
+    fn ct_infer(
+        &self,
+        ty: Ty<'tcx>,
+        param: Option<&ty::GenericParamDef>,
+        span: Span,
+    ) -> &'tcx Const<'tcx>;
 
     /// Projecting an associated type from a (potentially)
     /// higher-ranked trait reference is more complicated, because of
@@ -156,7 +161,7 @@ pub fn ast_region_to_region(&self,
             }
 
             None => {
-                self.re_infer(lifetime.span, def)
+                self.re_infer(def, lifetime.span)
                     .unwrap_or_else(|| {
                         // This indicates an illegal lifetime
                         // elision. `resolve_lifetime` should have
@@ -191,7 +196,7 @@ pub fn ast_path_substs_for_ty(&self,
                 span,
                 def_id,
                 generic_args,
-                item_segment.infer_types,
+                item_segment.infer_args,
                 None,
             )
         });
@@ -203,12 +208,12 @@ pub fn ast_path_substs_for_ty(&self,
 
     /// Report error if there is an explicit type parameter when using `impl Trait`.
     fn check_impl_trait(
-        tcx: TyCtxt<'_, '_, '_>,
+        tcx: TyCtxt<'_, '_>,
         span: Span,
         seg: &hir::PathSegment,
         generics: &ty::Generics,
     ) -> bool {
-        let explicit = !seg.infer_types;
+        let explicit = !seg.infer_args;
         let impl_trait = generics.params.iter().any(|param| match param.kind {
             ty::GenericParamDefKind::Type {
                 synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
@@ -234,7 +239,7 @@ fn check_impl_trait(
     /// Checks that the correct number of generic arguments have been provided.
     /// Used specifically for function calls.
     pub fn check_generic_arg_count_for_call(
-        tcx: TyCtxt<'_, '_, '_>,
+        tcx: TyCtxt<'_, '_>,
         span: Span,
         def: &ty::Generics,
         seg: &hir::PathSegment,
@@ -259,20 +264,20 @@ pub fn check_generic_arg_count_for_call(
                 GenericArgPosition::Value
             },
             def.parent.is_none() && def.has_self, // `has_self`
-            seg.infer_types || suppress_mismatch, // `infer_types`
+            seg.infer_args || suppress_mismatch, // `infer_args`
         ).0
     }
 
     /// Checks that the correct number of generic arguments have been provided.
     /// This is used both for datatypes and function calls.
     fn check_generic_arg_count(
-        tcx: TyCtxt<'_, '_, '_>,
+        tcx: TyCtxt<'_, '_>,
         span: Span,
         def: &ty::Generics,
         args: &hir::GenericArgs,
         position: GenericArgPosition,
         has_self: bool,
-        infer_types: bool,
+        infer_args: bool,
     ) -> (bool, Option<Vec<Span>>) {
         // At this stage we are guaranteed that the generic arguments are in the correct order, e.g.
         // that lifetimes will proceed types. So it suffices to check the number of each generic
@@ -280,7 +285,6 @@ fn check_generic_arg_count(
         let param_counts = def.own_counts();
         let arg_counts = args.own_counts();
         let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
-        let infer_consts = position != GenericArgPosition::Type && arg_counts.consts == 0;
 
         let mut defaults: ty::GenericParamCount = Default::default();
         for param in &def.params {
@@ -333,7 +337,7 @@ fn check_generic_arg_count(
                 offset
             );
             // We enforce the following: `required` <= `provided` <= `permitted`.
-            // For kinds without defaults (i.e., lifetimes), `required == permitted`.
+            // For kinds without defaults (e.g.., lifetimes), `required == permitted`.
             // For other kinds (i.e., types), `permitted` may be greater than `required`.
             if required <= provided && provided <= permitted {
                 return (reported_late_bound_region_err.unwrap_or(false), None);
@@ -404,7 +408,7 @@ fn check_generic_arg_count(
             );
         }
         // FIXME(const_generics:defaults)
-        if !infer_consts || arg_counts.consts > param_counts.consts {
+        if !infer_args || arg_counts.consts > param_counts.consts {
             check_kind_count(
                 "const",
                 param_counts.consts,
@@ -414,7 +418,7 @@ fn check_generic_arg_count(
             );
         }
         // Note that type errors are currently be emitted *after* const errors.
-        if !infer_types
+        if !infer_args
             || arg_counts.types > param_counts.types - defaults.types - has_self as usize {
             check_kind_count(
                 "type",
@@ -457,8 +461,8 @@ fn check_generic_arg_count(
     ///   instantiate a `Kind`.
     /// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
     ///   creates a suitable inference variable.
-    pub fn create_substs_for_generic_args<'a, 'b>(
-        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    pub fn create_substs_for_generic_args<'b>(
+        tcx: TyCtxt<'gcx, 'tcx>,
         def_id: DefId,
         parent_substs: &[Kind<'tcx>],
         has_self: bool,
@@ -511,7 +515,7 @@ pub fn create_substs_for_generic_args<'a, 'b>(
             }
 
             // Check whether this segment takes generic arguments and the user has provided any.
-            let (generic_args, infer_types) = args_for_def_id(def_id);
+            let (generic_args, infer_args) = args_for_def_id(def_id);
 
             let mut args = generic_args.iter().flat_map(|generic_args| generic_args.args.iter())
                 .peekable();
@@ -535,7 +539,7 @@ pub fn create_substs_for_generic_args<'a, 'b>(
                             | (GenericArg::Const(_), GenericParamDefKind::Lifetime) => {
                                 // We expected a lifetime argument, but got a type or const
                                 // argument. That means we're inferring the lifetimes.
-                                substs.push(inferred_kind(None, param, infer_types));
+                                substs.push(inferred_kind(None, param, infer_args));
                                 params.next();
                             }
                             (_, _) => {
@@ -556,7 +560,7 @@ pub fn create_substs_for_generic_args<'a, 'b>(
                     (None, Some(&param)) => {
                         // If there are fewer arguments than parameters, it means
                         // we're inferring the remaining arguments.
-                        substs.push(inferred_kind(Some(&substs), param, infer_types));
+                        substs.push(inferred_kind(Some(&substs), param, infer_args));
                         args.next();
                         params.next();
                     }
@@ -571,13 +575,28 @@ pub fn create_substs_for_generic_args<'a, 'b>(
     /// Given the type/lifetime/const arguments provided to some path (along with
     /// an implicit `Self`, if this is a trait reference), returns the complete
     /// set of substitutions. This may involve applying defaulted type parameters.
+    /// Also returns back constriants on associated types.
+    ///
+    /// Example:
+    ///
+    /// ```
+    /// T: std::ops::Index<usize, Output = u32>
+    /// ^1 ^^^^^^^^^^^^^^2 ^^^^3  ^^^^^^^^^^^4
+    /// ```
+    ///
+    /// 1. The `self_ty` here would refer to the type `T`.
+    /// 2. The path in question is the path to the trait `std::ops::Index`,
+    ///    which will have been resolved to a `def_id`
+    /// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
+    ///    parameters are returned in the `SubstsRef`, the associated type bindings like
+    ///    `Output = u32` are returned in the `Vec<ConvertedBinding...>` result.
     ///
     /// Note that the type listing given here is *exactly* what the user provided.
     fn create_substs_for_ast_path<'a>(&self,
         span: Span,
         def_id: DefId,
         generic_args: &'a hir::GenericArgs,
-        infer_types: bool,
+        infer_args: bool,
         self_ty: Option<Ty<'tcx>>)
         -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'tcx>>, Option<Vec<Span>>)
     {
@@ -602,7 +621,7 @@ fn create_substs_for_ast_path<'a>(&self,
             &generic_args,
             GenericArgPosition::Type,
             has_self,
-            infer_types,
+            infer_args,
         );
 
         let is_object = self_ty.map_or(false, |ty| {
@@ -629,7 +648,7 @@ fn create_substs_for_ast_path<'a>(&self,
             self_ty.is_some(),
             self_ty,
             // Provide the generic args, and whether types should be inferred.
-            |_| (Some(generic_args), infer_types),
+            |_| (Some(generic_args), infer_args),
             // Provide substitutions for parameters for which (valid) arguments have been provided.
             |param, arg| {
                 match (&param.kind, arg) {
@@ -646,11 +665,11 @@ fn create_substs_for_ast_path<'a>(&self,
                 }
             },
             // Provide substitutions for parameters for which arguments are inferred.
-            |substs, param, infer_types| {
+            |substs, param, infer_args| {
                 match param.kind {
                     GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(),
                     GenericParamDefKind::Type { has_default, .. } => {
-                        if !infer_types && has_default {
+                        if !infer_args && has_default {
                             // No type parameter provided, but a default exists.
 
                             // If we are converting an object type, then the
@@ -678,13 +697,14 @@ fn create_substs_for_ast_path<'a>(&self,
                                        .subst_spanned(tcx, substs.unwrap(), Some(span))
                                 ).into()
                             }
-                        } else if infer_types {
+                        } else if infer_args {
                             // No type parameters were provided, we can infer all.
-                            if !default_needs_object_self(param) {
-                                self.ty_infer_for_def(param, span).into()
+                            let param = if !default_needs_object_self(param) {
+                                Some(param)
                             } else {
-                                self.ty_infer(span).into()
-                            }
+                                None
+                            };
+                            self.ty_infer(param, span).into()
                         } else {
                             // We've already errored above about the mismatch.
                             tcx.types.err.into()
@@ -692,8 +712,14 @@ fn create_substs_for_ast_path<'a>(&self,
                     }
                     GenericParamDefKind::Const => {
                         // FIXME(const_generics:defaults)
-                        // We've already errored above about the mismatch.
-                        tcx.consts.err.into()
+                        if infer_args {
+                            // No const parameters were provided, we can infer all.
+                            let ty = tcx.at(span).type_of(param.def_id);
+                            self.ct_infer(ty, Some(param), span).into()
+                        } else {
+                            // We've already errored above about the mismatch.
+                            tcx.consts.err.into()
+                        }
                     }
                 }
             },
@@ -710,10 +736,11 @@ fn create_substs_for_ast_path<'a>(&self,
         // back separately.
         let assoc_bindings = generic_args.bindings.iter()
             .map(|binding| {
-                let kind = if let hir::TyKind::AssocTyExistential(ref bounds) = binding.ty.node {
-                    ConvertedBindingKind::Constraint(bounds.clone())
-                } else {
-                    ConvertedBindingKind::Equality(self.ast_ty_to_ty(&binding.ty))
+                let kind = match binding.kind {
+                    hir::TypeBindingKind::Equality { ref ty } =>
+                        ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty)),
+                    hir::TypeBindingKind::Constraint { ref bounds } =>
+                        ConvertedBindingKind::Constraint(bounds.clone()),
                 };
                 ConvertedBinding {
                     item_name: binding.ident,
@@ -790,6 +817,25 @@ pub(super) fn instantiate_poly_trait_ref_inner(&self,
         (poly_trait_ref, potential_assoc_types)
     }
 
+    /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
+    /// a full trait reference. The resulting trait reference is returned. This may also generate
+    /// auxiliary bounds, which are added to `bounds`.
+    ///
+    /// Example:
+    ///
+    /// ```
+    /// poly_trait_ref = Iterator<Item = u32>
+    /// self_ty = Foo
+    /// ```
+    ///
+    /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
+    ///
+    /// **A note on binders:** against our usual convention, there is an implied bounder around
+    /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
+    /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
+    /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
+    /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
+    /// however.
     pub fn instantiate_poly_trait_ref(&self,
         poly_trait_ref: &hir::PolyTraitRef,
         self_ty: Ty<'tcx>,
@@ -845,7 +891,7 @@ fn create_substs_for_ast_trait_ref(
             self.create_substs_for_ast_path(span,
                                             trait_def_id,
                                             generic_args,
-                                            trait_segment.infer_types,
+                                            trait_segment.infer_args,
                                             Some(self_ty))
         })
     }
@@ -908,6 +954,21 @@ pub fn is_unsized(&self, ast_bounds: &[hir::GenericBound], span: Span) -> bool {
         true
     }
 
+    /// This helper takes a *converted* parameter type (`param_ty`)
+    /// and an *unconverted* list of bounds:
+    ///
+    /// ```
+    /// fn foo<T: Debug>
+    ///        ^  ^^^^^ `ast_bounds` parameter, in HIR form
+    ///        |
+    ///        `param_ty`, in ty form
+    /// ```
+    ///
+    /// It adds these `ast_bounds` into the `bounds` structure.
+    ///
+    /// **A note on binders:** there is an implied binder around
+    /// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
+    /// for more details.
     fn add_bounds(&self,
         param_ty: Ty<'tcx>,
         ast_bounds: &[hir::GenericBound],
@@ -941,9 +1002,22 @@ fn add_bounds(&self,
         );
     }
 
-    /// Translates the AST's notion of ty param bounds (which are an enum consisting of a newtyped
-    /// `Ty` or a region) to ty's notion of ty param bounds (which can either be user-defined traits
-    /// or the built-in trait `Sized`).
+    /// Translates a list of bounds from the HIR into the `Bounds` data structure.
+    /// The self-type for the bounds is given by `param_ty`.
+    ///
+    /// Example:
+    ///
+    /// ```
+    /// fn foo<T: Bar + Baz>() { }
+    ///        ^  ^^^^^^^^^ ast_bounds
+    ///        param_ty
+    /// ```
+    ///
+    /// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be
+    /// considered `Sized` unless there is an explicit `?Sized` bound.  This would be true in the
+    /// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
+    ///
+    /// `span` should be the declaration size of the parameter.
     pub fn compute_bounds(&self,
         param_ty: Ty<'tcx>,
         ast_bounds: &[hir::GenericBound],
@@ -968,6 +1042,12 @@ pub fn compute_bounds(&self,
         bounds
     }
 
+    /// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates
+    /// onto `bounds`.
+    ///
+    /// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the
+    /// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside*
+    /// the binder (e.g., `&'a u32`) and hence may reference bound regions.
     fn add_predicates_for_ast_type_binding(
         &self,
         hir_ref_id: hir::HirId,
@@ -1090,8 +1170,12 @@ fn add_predicates_for_ast_type_binding(
                 }), binding.span));
             }
             ConvertedBindingKind::Constraint(ref ast_bounds) => {
-                // Calling `skip_binder` is okay, because the predicates are re-bound later by
-                // `instantiate_poly_trait_ref`.
+                // "Desugar" a constraint like `T: Iterator<Item: Debug>` to
+                //
+                // `<T as Iterator>::Item: Debug`
+                //
+                // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
+                // parameter to have a skipped binder.
                 let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs);
                 self.add_bounds(
                     param_ty,
@@ -1355,7 +1439,7 @@ fn conv_object_ty_poly_trait_ref(&self,
                 if tcx.named_region(lifetime.hir_id).is_some() {
                     self.ast_region_to_region(lifetime, None)
                 } else {
-                    self.re_infer(span, None).unwrap_or_else(|| {
+                    self.re_infer(None, span).unwrap_or_else(|| {
                         span_err!(tcx.sess, span, E0228,
                             "the lifetime bound for this object type cannot be deduced \
                              from context; please supply an explicit bound");
@@ -1726,7 +1810,7 @@ pub fn prohibit_generics<'a, T: IntoIterator<Item = &'a hir::PathSegment>>(
         has_err
     }
 
-    pub fn prohibit_assoc_ty_binding(tcx: TyCtxt<'_, '_, '_>, span: Span) {
+    pub fn prohibit_assoc_ty_binding(tcx: TyCtxt<'_, '_>, span: Span) {
         let mut err = struct_span_err!(tcx.sess, span, E0229,
                                        "associated type bindings are not allowed here");
         err.span_label(span, "associated type not allowed here").emit();
@@ -2049,7 +2133,7 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
                 // values in a ExprKind::Closure, or as
                 // the type of local variables. Both of these cases are
                 // handled specially and will not descend into this routine.
-                self.ty_infer(ast_ty.span)
+                self.ty_infer(None, ast_ty.span)
             }
             hir::TyKind::CVarArgs(lt) => {
                 let va_list_did = match tcx.lang_items().va_list() {
@@ -2060,10 +2144,6 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
                 let region = self.ast_region_to_region(&lt, None);
                 tcx.type_of(va_list_did).subst(tcx, &[region.into()])
             }
-            hir::TyKind::AssocTyExistential(..) => {
-                // Type is never actually used.
-                tcx.types.err
-            }
             hir::TyKind::Err => {
                 tcx.types.err
             }
@@ -2075,6 +2155,17 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
         result_ty
     }
 
+    /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
+    pub fn const_param_def_id(&self, expr: &hir::Expr) -> Option<DefId> {
+        match &expr.node {
+            ExprKind::Path(hir::QPath::Resolved(_, path)) => match path.res {
+                Res::Def(DefKind::ConstParam, did) => Some(did),
+                _ => None,
+            },
+            _ => None,
+        }
+    }
+
     pub fn ast_const_to_const(
         &self,
         ast_const: &hir::AnonConst,
@@ -2105,19 +2196,17 @@ pub fn ast_const_to_const(
             }
         }
 
-        if let ExprKind::Path(ref qpath) = expr.node {
-            if let hir::QPath::Resolved(_, ref path) = qpath {
-                if let Res::Def(DefKind::ConstParam, def_id) = path.res {
-                    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
-                    let item_id = tcx.hir().get_parent_node(node_id);
-                    let item_def_id = tcx.hir().local_def_id(item_id);
-                    let generics = tcx.generics_of(item_def_id);
-                    let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
-                    let name = tcx.hir().name(node_id).as_interned_str();
-                    const_.val = ConstValue::Param(ty::ParamConst::new(index, name));
-                }
-            }
-        };
+        if let Some(def_id) = self.const_param_def_id(expr) {
+            // Find the name and index of the const parameter by indexing the generics of the
+            // parent item and construct a `ParamConst`.
+            let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+            let item_id = tcx.hir().get_parent_node(node_id);
+            let item_def_id = tcx.hir().local_def_id(item_id);
+            let generics = tcx.generics_of(item_def_id);
+            let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
+            let name = tcx.hir().name(node_id).as_interned_str();
+            const_.val = ConstValue::Param(ty::ParamConst::new(index, name));
+        }
 
         tcx.mk_const(const_)
     }
@@ -2285,20 +2374,57 @@ fn compute_object_lifetime_bound(&self,
     }
 }
 
-// A helper struct for conveniently grouping a set of bounds which we pass to
-// and return from functions in multiple places.
+/// Collects together a list of bounds that are applied to some type,
+/// after they've been converted into `ty` form (from the HIR
+/// representations). These lists of bounds occur in many places in
+/// Rust's syntax:
+///
+/// ```
+/// trait Foo: Bar + Baz { }
+///            ^^^^^^^^^ supertrait list bounding the `Self` type parameter
+///
+/// fn foo<T: Bar + Baz>() { }
+///           ^^^^^^^^^ bounding the type parameter `T`
+///
+/// impl dyn Bar + Baz
+///          ^^^^^^^^^ bounding the forgotten dynamic type
+/// ```
+///
+/// Our representation is a bit mixed here -- in some cases, we
+/// include the self type (e.g., `trait_bounds`) but in others we do
 #[derive(Default, PartialEq, Eq, Clone, Debug)]
 pub struct Bounds<'tcx> {
+    /// A list of region bounds on the (implicit) self type. So if you
+    /// had `T: 'a + 'b` this might would be a list `['a, 'b]` (but
+    /// the `T` is not explicitly included).
     pub region_bounds: Vec<(ty::Region<'tcx>, Span)>,
+
+    /// A list of trait bounds. So if you had `T: Debug` this would be
+    /// `T: Debug`. Note that the self-type is explicit here.
     pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span)>,
+
+    /// A list of projection equality bounds. So if you had `T:
+    /// Iterator<Item = u32>` this would include `<T as
+    /// Iterator>::Item => u32`. Note that the self-type is explicit
+    /// here.
     pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>,
+
+    /// `Some` if there is *no* `?Sized` predicate. The `span`
+    /// is the location in the source of the `T` declaration which can
+    /// be cited as the source of the `T: Sized` requirement.
     pub implicitly_sized: Option<Span>,
 }
 
-impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
-    pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
-                      -> Vec<(ty::Predicate<'tcx>, Span)>
-    {
+impl<'gcx, 'tcx> Bounds<'tcx> {
+    /// Converts a bounds list into a flat set of predicates (like
+    /// where-clauses). Because some of our bounds listings (e.g.,
+    /// regions) don't include the self-type, you must supply the
+    /// self-type here (the `param_ty` parameter).
+    pub fn predicates(
+        &self,
+        tcx: TyCtxt<'gcx, 'tcx>,
+        param_ty: Ty<'tcx>,
+    ) -> Vec<(ty::Predicate<'tcx>, Span)> {
         // If it could be sized, and is, add the `Sized` predicate.
         let sized_predicate = self.implicitly_sized.and_then(|span| {
             tcx.lang_items().sized_trait().map(|sized| {