]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/collect.rs
Turn `#[allocator]` into a built-in attribute and rename it to `#[rustc_allocator]`
[rust.git] / src / librustc_typeck / collect.rs
index 3806fd0998b5e8785c16f3b1c77d44a61d4c14f4..f738f90b31eb6320a47357939ef8bcbfe82edf19 100644 (file)
@@ -1,6 +1,6 @@
 //! "Collection" is the process of determining the type and other external
 //! details of each item in Rust. Collection is specifically concerned
-//! with *interprocedural* things -- for example, for a function
+//! with *inter-procedural* things -- for example, for a function
 //! definition, collection will figure out the type and signature of the
 //! function, but it will not visit the *body* of the function in any way,
 //! nor examine type annotations on local variables (that's the job of
 //! At present, however, we do run collection across all items in the
 //! crate as a kind of pass. This should eventually be factored away.
 
-use crate::astconv::{AstConv, Bounds};
+use crate::astconv::{AstConv, Bounds, SizedByDefault};
 use crate::constrained_generic_params as cgp;
 use crate::check::intrinsic::intrisic_operation_unsafety;
 use crate::lint;
-use crate::middle::lang_items::SizedTraitLangItem;
 use crate::middle::resolve_lifetime as rl;
 use crate::middle::weak_lang_items;
 use rustc::mir::mono::Linkage;
@@ -233,7 +232,7 @@ fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
     }
 
     fn set_tainted_by_errors(&self) {
-        // no obvious place to track this, just let it go
+        // no obvious place to track this, so just let it go
     }
 
     fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
@@ -447,7 +446,7 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: hir::HirId) {
             }
         }
 
-        // Desugared from `impl Trait` -> visited by the function's return type
+        // Desugared from `impl Trait`, so visited by the function's return type.
         hir::ItemKind::Existential(hir::ExistTy {
             impl_trait_fn: Some(_),
             ..
@@ -704,7 +703,8 @@ fn super_predicates_of<'a, 'tcx>(
 
     // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
     let self_param_ty = tcx.mk_self_type();
-    let superbounds1 = compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span);
+    let superbounds1 = AstConv::compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No,
+        item.span);
 
     let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
 
@@ -763,7 +763,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::
     let is_marker = tcx.has_attr(def_id, sym::marker);
     let def_path_hash = tcx.def_path_hash(def_id);
     let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, is_auto, is_marker, def_path_hash);
-    tcx.alloc_trait_def(def)
+    tcx.arena.alloc(def)
 }
 
 fn has_late_bound_regions<'a, 'tcx>(
@@ -1110,7 +1110,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
         .map(|param| (param.def_id, param.index))
         .collect();
 
-    tcx.alloc_generics(ty::Generics {
+    tcx.arena.alloc(ty::Generics {
         parent: parent_def_id,
         parent_count,
         params,
@@ -1218,7 +1218,7 @@ pub fn checked_type_of<'a, 'tcx>(
                     impl_trait_fn: None,
                     ..
                 }) => find_existential_constraints(tcx, def_id),
-                // existential types desugared from impl Trait
+                // Existential types desugared from `impl Trait`.
                 ItemKind::Existential(hir::ExistTy {
                     impl_trait_fn: Some(owner),
                     ..
@@ -1335,88 +1335,97 @@ pub fn checked_type_of<'a, 'tcx>(
 
                 Node::Ty(&hir::Ty { node: hir::TyKind::Path(_), .. }) |
                 Node::Expr(&hir::Expr { node: ExprKind::Struct(..), .. }) |
-                Node::Expr(&hir::Expr { node: ExprKind::Path(_), .. }) => {
+                Node::Expr(&hir::Expr { node: ExprKind::Path(_), .. }) |
+                Node::TraitRef(..) => {
                     let path = match parent_node {
-                        Node::Ty(&hir::Ty { node: hir::TyKind::Path(ref path), .. }) |
-                        Node::Expr(&hir::Expr { node: ExprKind::Path(ref path), .. }) => {
-                            path
+                        Node::Ty(&hir::Ty {
+                            node: hir::TyKind::Path(QPath::Resolved(_, ref path)),
+                            ..
+                        })
+                        | Node::Expr(&hir::Expr {
+                            node: ExprKind::Path(QPath::Resolved(_, ref path)),
+                            ..
+                        }) => {
+                            Some(&**path)
                         }
                         Node::Expr(&hir::Expr { node: ExprKind::Struct(ref path, ..), .. }) => {
-                            &*path
+                            if let QPath::Resolved(_, ref path) = **path {
+                                Some(&**path)
+                            } else {
+                                None
+                            }
                         }
-                        _ => unreachable!(),
+                        Node::TraitRef(&hir::TraitRef { ref path, .. }) => Some(path),
+                        _ => None,
                     };
 
-                    match path {
-                        QPath::Resolved(_, ref path) => {
-                            let arg_index = path.segments.iter()
-                                .filter_map(|seg| seg.args.as_ref())
-                                .map(|generic_args| generic_args.args.as_ref())
-                                .find_map(|args| {
-                                    args.iter()
-                                        .filter(|arg| arg.is_const())
-                                        .enumerate()
-                                        .filter(|(_, arg)| arg.id() == hir_id)
-                                        .map(|(index, _)| index)
-                                        .next()
-                                })
-                                .or_else(|| {
-                                    if !fail {
-                                        None
-                                    } else {
-                                        bug!("no arg matching AnonConst in path")
-                                    }
-                                })?;
-
-                            // We've encountered an `AnonConst` in some path, so we need to
-                            // figure out which generic parameter it corresponds to and return
-                            // the relevant type.
-                            let generics = match path.res {
-                                Res::Def(DefKind::Ctor(..), def_id) =>
-                                    tcx.generics_of(tcx.parent(def_id).unwrap()),
-                                Res::Def(_, def_id) =>
-                                    tcx.generics_of(def_id),
-                                Res::Err =>
-                                    return Some(tcx.types.err),
-                                _ if !fail =>
-                                    return None,
-                                x => {
-                                    tcx.sess.delay_span_bug(
-                                        DUMMY_SP,
-                                        &format!(
-                                            "unexpected const parent path def {:?}", x
-                                        ),
-                                    );
-                                    return Some(tcx.types.err);
+                    if let Some(path) = path {
+                        let arg_index = path.segments.iter()
+                            .filter_map(|seg| seg.args.as_ref())
+                            .map(|generic_args| generic_args.args.as_ref())
+                            .find_map(|args| {
+                                args.iter()
+                                    .filter(|arg| arg.is_const())
+                                    .enumerate()
+                                    .filter(|(_, arg)| arg.id() == hir_id)
+                                    .map(|(index, _)| index)
+                                    .next()
+                            })
+                            .or_else(|| {
+                                if !fail {
+                                    None
+                                } else {
+                                    bug!("no arg matching AnonConst in path")
                                 }
-                            };
-
-                            generics.params.iter()
-                                .filter(|param| {
-                                    if let ty::GenericParamDefKind::Const = param.kind {
-                                        true
-                                    } else {
-                                        false
-                                    }
-                                })
-                                .nth(arg_index)
-                                .map(|param| tcx.type_of(param.def_id))
-                                // This is no generic parameter associated with the arg. This is
-                                // probably from an extra arg where one is not needed.
-                                .unwrap_or(tcx.types.err)
-                        }
-                        x => {
-                            if !fail {
-                                return None;
+                            })?;
+
+                        // We've encountered an `AnonConst` in some path, so we need to
+                        // figure out which generic parameter it corresponds to and return
+                        // the relevant type.
+                        let generics = match path.res {
+                            Res::Def(DefKind::Ctor(..), def_id) => {
+                                tcx.generics_of(tcx.parent(def_id).unwrap())
                             }
-                            tcx.sess.delay_span_bug(
-                                DUMMY_SP,
-                                &format!(
-                                    "unexpected const parent path {:?}", x
-                                ),
-                            );
-                            tcx.types.err
+                            Res::Def(_, def_id) => tcx.generics_of(def_id),
+                            Res::Err => return Some(tcx.types.err),
+                            _ if !fail => return None,
+                            res => {
+                                tcx.sess.delay_span_bug(
+                                    DUMMY_SP,
+                                    &format!(
+                                        "unexpected const parent path def {:?}",
+                                        res,
+                                    ),
+                                );
+                                return Some(tcx.types.err);
+                            }
+                        };
+
+                        generics.params.iter()
+                            .filter(|param| {
+                                if let ty::GenericParamDefKind::Const = param.kind {
+                                    true
+                                } else {
+                                    false
+                                }
+                            })
+                            .nth(arg_index)
+                            .map(|param| tcx.type_of(param.def_id))
+                            // This is no generic parameter associated with the arg. This is
+                            // probably from an extra arg where one is not needed.
+                            .unwrap_or(tcx.types.err)
+                    } else {
+                        if !fail {
+                            return None;
                         }
+                        tcx.sess.delay_span_bug(
+                            DUMMY_SP,
+                            &format!(
+                                "unexpected const parent path {:?}",
+                                parent_node,
+                            ),
+                        );
+                        return Some(tcx.types.err);
                     }
                 }
 
@@ -1463,11 +1472,13 @@ fn find_existential_constraints<'a, 'tcx>(
 ) -> Ty<'tcx> {
     use rustc::hir::{ImplItem, Item, TraitItem};
 
+    debug!("find_existential_constraints({:?})", def_id);
+
     struct ConstraintLocator<'a, 'tcx: 'a> {
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
         def_id: DefId,
-        // First found type span, actual type, mapping from the existential type's generic
-        // parameters to the concrete type's generic parameters
+        // (first found type span, actual type, mapping from the existential type's generic
+        // parameters to the concrete type's generic parameters)
         //
         // The mapping is an index for each use site of a generic parameter in the concrete type
         //
@@ -1477,10 +1488,13 @@ struct ConstraintLocator<'a, 'tcx: 'a> {
 
     impl<'a, 'tcx> ConstraintLocator<'a, 'tcx> {
         fn check(&mut self, def_id: DefId) {
-            trace!("checking {:?}", def_id);
-            // don't try to check items that cannot possibly constrain the type
+            // Don't try to check items that cannot possibly constrain the type.
             if !self.tcx.has_typeck_tables(def_id) {
-                trace!("no typeck tables for {:?}", def_id);
+                debug!(
+                    "find_existential_constraints: no constraint for `{:?}` at `{:?}`: no tables",
+                    self.def_id,
+                    def_id,
+                );
                 return;
             }
             let ty = self
@@ -1489,22 +1503,32 @@ fn check(&mut self, def_id: DefId) {
                 .concrete_existential_types
                 .get(&self.def_id);
             if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty {
-                // FIXME(oli-obk): trace the actual span from inference to improve errors
+                debug!(
+                    "find_existential_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
+                    self.def_id,
+                    def_id,
+                    ty,
+                );
+
+                // FIXME(oli-obk): trace the actual span from inference to improve errors.
                 let span = self.tcx.def_span(def_id);
                 // used to quickly look up the position of a generic parameter
                 let mut index_map: FxHashMap<ty::ParamTy, usize> = FxHashMap::default();
-                // skip binder is ok, since we only use this to find generic parameters and their
-                // positions.
+                // Skipping binder is ok, since we only use this to find generic parameters and
+                // their positions.
                 for (idx, subst) in substs.iter().enumerate() {
                     if let UnpackedKind::Type(ty) = subst.unpack() {
                         if let ty::Param(p) = ty.sty {
                             if index_map.insert(p, idx).is_some() {
-                                // there was already an entry for `p`, meaning a generic parameter
-                                // was used twice
+                                // There was already an entry for `p`, meaning a generic parameter
+                                // was used twice.
                                 self.tcx.sess.span_err(
                                     span,
-                                    &format!("defining existential type use restricts existential \
-                                    type by using the generic parameter `{}` twice", p.name),
+                                    &format!(
+                                        "defining existential type use restricts existential \
+                                         type by using the generic parameter `{}` twice",
+                                        p.name
+                                    ),
                                 );
                                 return;
                             }
@@ -1519,8 +1543,8 @@ fn check(&mut self, def_id: DefId) {
                         }
                     }
                 }
-                // compute the index within the existential type for each generic parameter used in
-                // the concrete type
+                // Compute the index within the existential type for each generic parameter used in
+                // the concrete type.
                 let indices = concrete_type
                     .subst(self.tcx, substs)
                     .walk()
@@ -1541,14 +1565,15 @@ fn check(&mut self, def_id: DefId) {
                     let mut ty = concrete_type.walk().fuse();
                     let mut p_ty = prev_ty.walk().fuse();
                     let iter_eq = (&mut ty).zip(&mut p_ty).all(|(t, p)| match (&t.sty, &p.sty) {
-                        // type parameters are equal to any other type parameter for the purpose of
+                        // Type parameters are equal to any other type parameter for the purpose of
                         // concrete type equality, as it is possible to obtain the same type just
                         // by passing matching parameters to a function.
                         (ty::Param(_), ty::Param(_)) => true,
                         _ => t == p,
                     });
                     if !iter_eq || ty.next().is_some() || p_ty.next().is_some() {
-                        // found different concrete types for the existential type
+                        debug!("find_existential_constraints: span={:?}", span);
+                        // Found different concrete types for the existential type.
                         let mut err = self.tcx.sess.struct_span_err(
                             span,
                             "concrete type differs from previous defining existential type use",
@@ -1560,7 +1585,7 @@ fn check(&mut self, def_id: DefId) {
                         err.span_note(prev_span, "previous use here");
                         err.emit();
                     } else if indices != *prev_indices {
-                        // found "same" concrete types, but the generic parameter order differs
+                        // Found "same" concrete types, but the generic parameter order differs.
                         let mut err = self.tcx.sess.struct_span_err(
                             span,
                             "concrete type's generic parameters differ from previous defining use",
@@ -1588,6 +1613,12 @@ fn check(&mut self, def_id: DefId) {
                 } else {
                     self.found = Some((span, concrete_type, indices));
                 }
+            } else {
+                debug!(
+                    "find_existential_constraints: no constraint for `{:?}` at `{:?}`",
+                    self.def_id,
+                    def_id,
+                );
             }
         }
     }
@@ -1598,7 +1629,7 @@ fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'thi
         }
         fn visit_item(&mut self, it: &'tcx Item) {
             let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id);
-            // the existential type itself or its children are not within its reveal scope
+            // The existential type itself or its children are not within its reveal scope.
             if def_id != self.def_id {
                 self.check(def_id);
                 intravisit::walk_item(self, it);
@@ -1606,7 +1637,7 @@ fn visit_item(&mut self, it: &'tcx Item) {
         }
         fn visit_impl_item(&mut self, it: &'tcx ImplItem) {
             let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id);
-            // the existential type itself or its children are not within its reveal scope
+            // The existential type itself or its children are not within its reveal scope.
             if def_id != self.def_id {
                 self.check(def_id);
                 intravisit::walk_impl_item(self, it);
@@ -1619,26 +1650,28 @@ fn visit_trait_item(&mut self, it: &'tcx TraitItem) {
         }
     }
 
+    let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
+    let scope = tcx.hir()
+        .get_defining_scope(hir_id)
+        .expect("could not get defining scope");
     let mut locator = ConstraintLocator {
         def_id,
         tcx,
         found: None,
     };
-    let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
-    let parent = tcx.hir().get_parent_item(hir_id);
 
-    trace!("parent_id: {:?}", parent);
+    debug!("find_existential_constraints: scope={:?}", scope);
 
-    if parent == hir::CRATE_HIR_ID {
+    if scope == hir::CRATE_HIR_ID {
         intravisit::walk_crate(&mut locator, tcx.hir().krate());
     } else {
-        trace!("parent: {:?}", tcx.hir().get_by_hir_id(parent));
-        match tcx.hir().get_by_hir_id(parent) {
+        debug!("find_existential_constraints: scope={:?}", tcx.hir().get_by_hir_id(scope));
+        match tcx.hir().get_by_hir_id(scope) {
             Node::Item(ref it) => intravisit::walk_item(&mut locator, it),
             Node::ImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it),
             Node::TraitItem(ref it) => intravisit::walk_trait_item(&mut locator, it),
             other => bug!(
-                "{:?} is not a valid parent of an existential type item",
+                "{:?} is not a valid scope for an existential type item",
                 other
             ),
         }
@@ -1756,57 +1789,6 @@ fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> hir::I
     }
 }
 
-// Is it marked with ?Sized
-fn is_unsized<'gcx: 'tcx, 'tcx>(
-    astconv: &dyn AstConv<'gcx, 'tcx>,
-    ast_bounds: &[hir::GenericBound],
-    span: Span,
-) -> bool {
-    let tcx = astconv.tcx();
-
-    // Try to find an unbound in bounds.
-    let mut unbound = None;
-    for ab in ast_bounds {
-        if let &hir::GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
-            if unbound.is_none() {
-                unbound = Some(ptr.trait_ref.clone());
-            } else {
-                span_err!(
-                    tcx.sess,
-                    span,
-                    E0203,
-                    "type parameter has more than one relaxed default \
-                     bound, only one is supported"
-                );
-            }
-        }
-    }
-
-    let kind_id = tcx.lang_items().require(SizedTraitLangItem);
-    match unbound {
-        Some(ref tpb) => {
-            // FIXME(#8559) currently requires the unbound to be built-in.
-            if let Ok(kind_id) = kind_id {
-                if tpb.path.res != Res::Def(DefKind::Trait, kind_id) {
-                    tcx.sess.span_warn(
-                        span,
-                        "default bound relaxed for a type parameter, but \
-                         this does nothing because the given bound is not \
-                         a default. Only `?Sized` is supported",
-                    );
-                }
-            }
-        }
-        _ if kind_id.is_ok() => {
-            return false;
-        }
-        // No lang item for Sized, so we can't add it as a bound.
-        None => {}
-    }
-
-    true
-}
-
 /// Returns the early-bound lifetimes declared in this generics
 /// listing. For anything other than fns/methods, this is just all
 /// the lifetimes that are declared. For fns or methods, we have to
@@ -1951,8 +1933,8 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
                 let substs = InternalSubsts::identity_for_item(tcx, def_id);
                 let opaque_ty = tcx.mk_opaque(def_id, substs);
 
-                // Collect the bounds, i.e., the `A+B+'c` in `impl A+B+'c`.
-                let bounds = compute_bounds(
+                // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`.
+                let bounds = AstConv::compute_bounds(
                     &icx,
                     opaque_ty,
                     bounds,
@@ -1997,8 +1979,8 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
                     let substs = InternalSubsts::identity_for_item(tcx, def_id);
                     let opaque_ty = tcx.mk_opaque(def_id, substs);
 
-                    // Collect the bounds, i.e., the `A+B+'c` in `impl A+B+'c`.
-                    let bounds = compute_bounds(
+                    // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`.
+                    let bounds = AstConv::compute_bounds(
                         &icx,
                         opaque_ty,
                         bounds,
@@ -2006,15 +1988,16 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
                         tcx.def_span(def_id),
                     );
 
+                    let bounds_predicates = bounds.predicates(tcx, opaque_ty);
                     if impl_trait_fn.is_some() {
-                        // impl Trait
+                        // opaque types
                         return tcx.arena.alloc(ty::GenericPredicates {
                             parent: None,
-                            predicates: bounds.predicates(tcx, opaque_ty),
+                            predicates: bounds_predicates,
                         });
                     } else {
                         // named existential types
-                        predicates.extend(bounds.predicates(tcx, opaque_ty));
+                        predicates.extend(bounds_predicates);
                         generics
                     }
                 }
@@ -2084,7 +2067,7 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
     }
 
     // Collect the predicates that were written inline by the user on each
-    // type parameter (e.g., `<T:Foo>`).
+    // type parameter (e.g., `<T: Foo>`).
     for param in &ast_generics.params {
         if let GenericParamKind::Type { .. } = param.kind {
             let name = param.name.ident().as_interned_str();
@@ -2092,12 +2075,12 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
             index += 1;
 
             let sized = SizedByDefault::Yes;
-            let bounds = compute_bounds(&icx, param_ty, &param.bounds, sized, param.span);
+            let bounds = AstConv::compute_bounds(&icx, param_ty, &param.bounds, sized, param.span);
             predicates.extend(bounds.predicates(tcx, param_ty));
         }
     }
 
-    // Add in the bounds that appear in the where-clause
+    // Add in the bounds that appear in the where-clause.
     let where_clause = &ast_generics.where_clause;
     for predicate in &where_clause.predicates {
         match predicate {
@@ -2127,19 +2110,17 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
                 for bound in bound_pred.bounds.iter() {
                     match bound {
                         &hir::GenericBound::Trait(ref poly_trait_ref, _) => {
-                            let mut projections = Vec::new();
+                            let mut bounds = Bounds::default();
 
                             let (trait_ref, _) = AstConv::instantiate_poly_trait_ref(
                                 &icx,
                                 poly_trait_ref,
                                 ty,
-                                &mut projections,
+                                &mut bounds,
                             );
 
-                            predicates.extend(
-                                iter::once((trait_ref.to_predicate(), poly_trait_ref.span)).chain(
-                                    projections.iter().map(|&(p, span)| (p.to_predicate(), span)
-                            )));
+                            predicates.push((trait_ref.to_predicate(), poly_trait_ref.span));
+                            predicates.extend(bounds.predicates(tcx, ty));
                         }
 
                         &hir::GenericBound::Outlives(ref lifetime) => {
@@ -2178,14 +2159,14 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
             let trait_item = tcx.hir().trait_item(trait_item_ref.id);
             let bounds = match trait_item.node {
                 hir::TraitItemKind::Type(ref bounds, _) => bounds,
-                _ => return vec![].into_iter()
+                _ => return Vec::new().into_iter()
             };
 
             let assoc_ty =
                 tcx.mk_projection(tcx.hir().local_def_id_from_hir_id(trait_item.hir_id),
                     self_trait_ref.substs);
 
-            let bounds = compute_bounds(
+            let bounds = AstConv::compute_bounds(
                 &ItemCtxt::new(tcx, def_id),
                 assoc_ty,
                 bounds,
@@ -2227,68 +2208,6 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
     result
 }
 
-pub enum SizedByDefault {
-    Yes,
-    No,
-}
-
-/// Translate 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 `Send`.
-pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
-    astconv: &dyn AstConv<'gcx, 'tcx>,
-    param_ty: Ty<'tcx>,
-    ast_bounds: &[hir::GenericBound],
-    sized_by_default: SizedByDefault,
-    span: Span,
-) -> Bounds<'tcx> {
-    let mut region_bounds = Vec::new();
-    let mut trait_bounds = Vec::new();
-
-    for ast_bound in ast_bounds {
-        match *ast_bound {
-            hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => trait_bounds.push(b),
-            hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
-            hir::GenericBound::Outlives(ref l) => region_bounds.push(l),
-        }
-    }
-
-    let mut projection_bounds = Vec::new();
-
-    let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
-        let (poly_trait_ref, _) = astconv.instantiate_poly_trait_ref(
-            bound,
-            param_ty,
-            &mut projection_bounds,
-        );
-        (poly_trait_ref, bound.span)
-    }).collect();
-
-    let region_bounds = region_bounds
-        .into_iter()
-        .map(|r| (astconv.ast_region_to_region(r, None), r.span))
-        .collect();
-
-    trait_bounds.sort_by_key(|(t, _)| t.def_id());
-
-    let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
-        if !is_unsized(astconv, ast_bounds, span) {
-            Some(span)
-        } else {
-            None
-        }
-    } else {
-        None
-    };
-
-    Bounds {
-        region_bounds,
-        implicitly_sized,
-        trait_bounds,
-        projection_bounds,
-    }
-}
-
 /// Converts a specific `GenericBound` from the AST into a set of
 /// predicates that apply to the self type. A vector is returned
 /// because this can be anywhere from zero predicates (`T: ?Sized` adds no
@@ -2301,13 +2220,11 @@ fn predicates_from_bound<'tcx>(
 ) -> Vec<(ty::Predicate<'tcx>, Span)> {
     match *bound {
         hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => {
-            let mut projections = Vec::new();
-            let (pred, _) = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections);
-            iter::once((pred.to_predicate(), tr.span)).chain(
-                projections
-                    .into_iter()
-                    .map(|(p, span)| (p.to_predicate(), span))
-            ).collect()
+            let mut bounds = Bounds::default();
+            let (pred, _) = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut bounds);
+            iter::once((pred.to_predicate(), tr.span))
+                .chain(bounds.predicates(astconv.tcx(), param_ty))
+                .collect()
         }
         hir::GenericBound::Outlives(ref lifetime) => {
             let region = astconv.ast_region_to_region(lifetime, None);
@@ -2331,8 +2248,8 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
     };
     let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), unsafety, abi, decl);
 
-    // feature gate SIMD types in FFI, since I (huonw) am not sure the
-    // ABIs are handled at all correctly.
+    // Feature gate SIMD types in FFI, since I am not sure that the
+    // ABIs are handled at all correctly. -huonw
     if abi != abi::Abi::RustIntrinsic
         && abi != abi::Abi::PlatformIntrinsic
         && !tcx.features().simd_ffi
@@ -2407,13 +2324,13 @@ fn from_target_feature(
     };
     let rust_features = tcx.features();
     for item in list {
-        // Only `enable = ...` is accepted in the meta item list
+        // Only `enable = ...` is accepted in the meta-item list.
         if !item.check_name(sym::enable) {
             bad_item(item.span());
             continue;
         }
 
-        // Must be of the form `enable = "..."` ( a string)
+        // Must be of the form `enable = "..."` (a string).
         let value = match item.value_str() {
             Some(value) => value,
             None => {
@@ -2422,9 +2339,9 @@ fn from_target_feature(
             }
         };
 
-        // We allow comma separation to enable multiple features
+        // We allow comma separation to enable multiple features.
         target_features.extend(value.as_str().split(',').filter_map(|feature| {
-            // Only allow whitelisted features per platform
+            // Only allow whitelisted features per platform.
             let feature_gate = match whitelist.get(feature) {
                 Some(g) => g,
                 None => {
@@ -2448,7 +2365,7 @@ fn from_target_feature(
                 }
             };
 
-            // Only allow features whose feature gates have been enabled
+            // Only allow features whose feature gates have been enabled.
             let allowed = match feature_gate.as_ref().map(|s| *s) {
                 Some(sym::arm_target_feature) => rust_features.arm_target_feature,
                 Some(sym::aarch64_target_feature) => rust_features.aarch64_target_feature,
@@ -2528,7 +2445,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
     for attr in attrs.iter() {
         if attr.check_name(sym::cold) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
-        } else if attr.check_name(sym::allocator) {
+        } else if attr.check_name(sym::rustc_allocator) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR;
         } else if attr.check_name(sym::unwind) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::UNWIND;
@@ -2536,7 +2453,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
             if tcx.is_foreign_item(id) {
                 codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE;
             } else {
-                // `#[ffi_returns_twice]` is only allowed `extern fn`s
+                // `#[ffi_returns_twice]` is only allowed `extern fn`s.
                 struct_span_err!(
                     tcx.sess,
                     attr.span,