about summary refs log tree commit diff
path: root/src/librustc/traits/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc/traits/mod.rs')
-rw-r--r--src/librustc/traits/mod.rs453
1 files changed, 232 insertions, 221 deletions
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 8baedfed9d6..e6ecf1b676e 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -5,73 +5,72 @@
 #[allow(dead_code)]
 pub mod auto_trait;
 mod chalk_fulfill;
+pub mod codegen;
 mod coherence;
-pub mod error_reporting;
 mod engine;
+pub mod error_reporting;
 mod fulfill;
-mod project;
 mod object_safety;
 mod on_unimplemented;
+mod project;
+pub mod query;
 mod select;
 mod specialize;
 mod structural_impls;
-pub mod codegen;
 mod util;
-pub mod query;
 
-use chalk_engine;
 use crate::hir;
 use crate::hir::def_id::DefId;
-use crate::infer::{InferCtxt, SuppressRegionErrors};
 use crate::infer::outlives::env::OutlivesEnvironment;
+use crate::infer::{InferCtxt, SuppressRegionErrors};
 use crate::middle::region;
 use crate::mir::interpret::ErrorHandled;
+use crate::ty::error::{ExpectedFound, TypeError};
+use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
+use crate::ty::subst::{InternalSubsts, SubstsRef};
+use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt};
+use crate::util::common::ErrorReported;
+use chalk_engine;
 use rustc_macros::HashStable;
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
-use crate::ty::subst::{InternalSubsts, SubstsRef};
-use crate::ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
-use crate::ty::error::{ExpectedFound, TypeError};
-use crate::ty::fold::{TypeFolder, TypeFoldable, TypeVisitor};
-use crate::util::common::ErrorReported;
 
 use std::fmt::Debug;
 use std::rc::Rc;
 
-pub use self::SelectionError::*;
 pub use self::FulfillmentErrorCode::*;
-pub use self::Vtable::*;
 pub use self::ObligationCauseCode::*;
+pub use self::SelectionError::*;
+pub use self::Vtable::*;
 
 pub use self::coherence::{add_placeholder_note, orphan_check, overlapping_impls};
 pub use self::coherence::{OrphanCheckErr, OverlapResult};
+pub use self::engine::{TraitEngine, TraitEngineExt};
 pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
-pub use self::project::MismatchedProjectionTypes;
-pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type};
-pub use self::project::{ProjectionCache, ProjectionCacheSnapshot, Reveal, Normalized};
-pub use self::object_safety::ObjectSafetyViolation;
 pub use self::object_safety::MethodViolationCode;
+pub use self::object_safety::ObjectSafetyViolation;
 pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote};
-pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
+pub use self::project::MismatchedProjectionTypes;
+pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type};
+pub use self::project::{Normalized, ProjectionCache, ProjectionCacheSnapshot, Reveal};
+pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
 pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
-pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
 pub use self::specialize::find_associated_item;
 pub use self::specialize::specialization_graph::FutureCompatOverlapError;
 pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
-pub use self::engine::{TraitEngine, TraitEngineExt};
+pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
 pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
+pub use self::util::{expand_trait_aliases, TraitAliasExpander};
 pub use self::util::{
-    supertraits, supertrait_def_ids, transitive_bounds, Supertraits, SupertraitDefIds,
+    supertrait_def_ids, supertraits, transitive_bounds, SupertraitDefIds, Supertraits,
 };
-pub use self::util::{expand_trait_aliases, TraitAliasExpander};
 
 pub use self::chalk_fulfill::{
-    CanonicalGoal as ChalkCanonicalGoal,
-    FulfillmentContext as ChalkFulfillmentContext
+    CanonicalGoal as ChalkCanonicalGoal, FulfillmentContext as ChalkFulfillmentContext,
 };
 
-pub use self::ObligationCauseCode::*;
 pub use self::FulfillmentErrorCode::*;
+pub use self::ObligationCauseCode::*;
 pub use self::SelectionError::*;
 pub use self::Vtable::*;
 
@@ -79,7 +78,7 @@ pub use self::Vtable::*;
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum IntercrateMode {
     Issue43355,
-    Fixed
+    Fixed,
 }
 
 /// The mode that trait queries run in.
@@ -140,19 +139,19 @@ pub struct ObligationCause<'tcx> {
     /// information.
     pub body_id: hir::HirId,
 
-    pub code: ObligationCauseCode<'tcx>
+    pub code: ObligationCauseCode<'tcx>,
 }
 
 impl<'tcx> ObligationCause<'tcx> {
     pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span {
         match self.code {
-            ObligationCauseCode::CompareImplMethodObligation { .. } |
-            ObligationCauseCode::MainFunctionType |
-            ObligationCauseCode::StartFunctionType => {
-                tcx.sess.source_map().def_span(self.span)
-            }
-            ObligationCauseCode::MatchExpressionArm(
-                box MatchExpressionArmCause { arm_span, .. }) => arm_span,
+            ObligationCauseCode::CompareImplMethodObligation { .. }
+            | ObligationCauseCode::MainFunctionType
+            | ObligationCauseCode::StartFunctionType => tcx.sess.source_map().def_span(self.span),
+            ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
+                arm_span,
+                ..
+            }) => arm_span,
             _ => self.span,
         }
     }
@@ -189,7 +188,10 @@ pub enum ObligationCauseCode<'tcx> {
     ObjectCastObligation(/* Object type */ Ty<'tcx>),
 
     /// Obligation incurred due to a coercion.
-    Coercion { source: Ty<'tcx>, target: Ty<'tcx> },
+    Coercion {
+        source: Ty<'tcx>,
+        target: Ty<'tcx>,
+    },
 
     /// Various cases where expressions must be `Sized` / `Copy` / etc.
     /// `L = X` implies that `L` is `Sized`.
@@ -211,7 +213,10 @@ pub enum ObligationCauseCode<'tcx> {
     RepeatVec(bool),
 
     /// Types of fields (other than the last, except for packed structs) in a struct must be sized.
-    FieldSized { adt_kind: AdtKind, last: bool },
+    FieldSized {
+        adt_kind: AdtKind,
+        last: bool,
+    },
 
     /// Constant expressions must be sized.
     ConstSized,
@@ -245,7 +250,10 @@ pub enum ObligationCauseCode<'tcx> {
     MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),
 
     /// Computing common supertype in the pattern guard for the arms of a match expression
-    MatchExpressionArmPattern { span: Span, ty: Ty<'tcx> },
+    MatchExpressionArmPattern {
+        span: Span,
+        ty: Ty<'tcx>,
+    },
 
     /// Constants in patterns must have `Structural` type.
     ConstPatternStructural,
@@ -322,7 +330,7 @@ pub struct DerivedObligationCause<'tcx> {
     parent_trait_ref: ty::PolyTraitRef<'tcx>,
 
     /// The parent trait had this cause.
-    parent_code: Rc<ObligationCauseCode<'tcx>>
+    parent_code: Rc<ObligationCauseCode<'tcx>>,
 }
 
 pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
@@ -415,7 +423,7 @@ impl<'tcx> GoalKind<'tcx> {
             Some(p) => p.into_goal(),
             None => GoalKind::Quantified(
                 QuantifierKind::Universal,
-                domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal()))
+                domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal())),
             ),
         }
     }
@@ -474,10 +482,7 @@ pub struct Environment<'tcx> {
 
 impl Environment<'tcx> {
     pub fn with<G>(self, goal: G) -> InEnvironment<'tcx, G> {
-        InEnvironment {
-            environment: self,
-            goal,
-        }
+        InEnvironment { environment: self, goal }
     }
 }
 
@@ -490,12 +495,14 @@ pub struct InEnvironment<'tcx, G> {
 
 pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
 
-#[derive(Clone,Debug,TypeFoldable)]
+#[derive(Clone, Debug, TypeFoldable)]
 pub enum SelectionError<'tcx> {
     Unimplemented,
-    OutputTypeParameterMismatch(ty::PolyTraitRef<'tcx>,
-                                ty::PolyTraitRef<'tcx>,
-                                ty::error::TypeError<'tcx>),
+    OutputTypeParameterMismatch(
+        ty::PolyTraitRef<'tcx>,
+        ty::PolyTraitRef<'tcx>,
+        ty::error::TypeError<'tcx>,
+    ),
     TraitNotObjectSafe(DefId),
     ConstEvalFailure(ErrorHandled),
     Overflow,
@@ -514,8 +521,7 @@ pub struct FulfillmentError<'tcx> {
 pub enum FulfillmentErrorCode<'tcx> {
     CodeSelectionError(SelectionError<'tcx>),
     CodeProjectionError(MismatchedProjectionTypes<'tcx>),
-    CodeSubtypeError(ExpectedFound<Ty<'tcx>>,
-                     TypeError<'tcx>), // always comes from a SubtypePredicate
+    CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
     CodeAmbiguity,
 }
 
@@ -617,7 +623,7 @@ pub enum Vtable<'tcx, N> {
 pub struct VtableImplData<'tcx, N> {
     pub impl_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
-    pub nested: Vec<N>
+    pub nested: Vec<N>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
@@ -626,7 +632,7 @@ pub struct VtableGeneratorData<'tcx, N> {
     pub substs: SubstsRef<'tcx>,
     /// Nested obligations. This can be non-empty if the generator
     /// signature contains associated types.
-    pub nested: Vec<N>
+    pub nested: Vec<N>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
@@ -635,18 +641,18 @@ pub struct VtableClosureData<'tcx, N> {
     pub substs: SubstsRef<'tcx>,
     /// Nested obligations. This can be non-empty if the closure
     /// signature contains associated types.
-    pub nested: Vec<N>
+    pub nested: Vec<N>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
 pub struct VtableAutoImplData<N> {
     pub trait_def_id: DefId,
-    pub nested: Vec<N>
+    pub nested: Vec<N>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
 pub struct VtableBuiltinData<N> {
-    pub nested: Vec<N>
+    pub nested: Vec<N>,
 }
 
 /// A vtable for some object-safe trait `Foo` automatically derived
@@ -667,7 +673,7 @@ pub struct VtableObjectData<'tcx, N> {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
 pub struct VtableFnPointerData<'tcx, N> {
     pub fn_ty: Ty<'tcx>,
-    pub nested: Vec<N>
+    pub nested: Vec<N>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
@@ -698,14 +704,13 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
     def_id: DefId,
     span: Span,
 ) -> bool {
-    debug!("type_known_to_meet_bound_modulo_regions(ty={:?}, bound={:?})",
-           ty,
-           infcx.tcx.def_path_str(def_id));
+    debug!(
+        "type_known_to_meet_bound_modulo_regions(ty={:?}, bound={:?})",
+        ty,
+        infcx.tcx.def_path_str(def_id)
+    );
 
-    let trait_ref = ty::TraitRef {
-        def_id,
-        substs: infcx.tcx.mk_substs_trait(ty, &[]),
-    };
+    let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) };
     let obligation = Obligation {
         param_env,
         cause: ObligationCause::misc(span, hir::DUMMY_HIR_ID),
@@ -714,8 +719,12 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
     };
 
     let result = infcx.predicate_must_hold_modulo_regions(&obligation);
-    debug!("type_known_to_meet_ty={:?} bound={} => {:?}",
-           ty, infcx.tcx.def_path_str(def_id), result);
+    debug!(
+        "type_known_to_meet_ty={:?} bound={} => {:?}",
+        ty,
+        infcx.tcx.def_path_str(def_id),
+        result
+    );
 
     if result && (ty.has_infer_types() || ty.has_closure_types()) {
         // Because of inference "guessing", selection can sometimes claim
@@ -740,16 +749,20 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
         // assume it is move; linear is always ok.
         match fulfill_cx.select_all_or_error(infcx) {
             Ok(()) => {
-                debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success",
-                       ty,
-                       infcx.tcx.def_path_str(def_id));
+                debug!(
+                    "type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success",
+                    ty,
+                    infcx.tcx.def_path_str(def_id)
+                );
                 true
             }
             Err(e) => {
-                debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} errors={:?}",
-                       ty,
-                       infcx.tcx.def_path_str(def_id),
-                       e);
+                debug!(
+                    "type_known_to_meet_bound_modulo_regions: ty={:?} bound={} errors={:?}",
+                    ty,
+                    infcx.tcx.def_path_str(def_id),
+                    e
+                );
                 false
             }
         }
@@ -767,9 +780,7 @@ fn do_normalize_predicates<'tcx>(
 ) -> Result<Vec<ty::Predicate<'tcx>>, ErrorReported> {
     debug!(
         "do_normalize_predicates(predicates={:?}, region_context={:?}, cause={:?})",
-        predicates,
-        region_context,
-        cause,
+        predicates, region_context, cause,
     );
     let span = cause.span;
     tcx.infer_ctxt().enter(|infcx| {
@@ -787,19 +798,14 @@ fn do_normalize_predicates<'tcx>(
         // them here too, and we will remove this function when
         // we move over to lazy normalization *anyway*.
         let fulfill_cx = FulfillmentContext::new_ignoring_regions();
-        let predicates = match fully_normalize(
-            &infcx,
-            fulfill_cx,
-            cause,
-            elaborated_env,
-            &predicates,
-        ) {
-            Ok(predicates) => predicates,
-            Err(errors) => {
-                infcx.report_fulfillment_errors(&errors, None, false);
-                return Err(ErrorReported)
-            }
-        };
+        let predicates =
+            match fully_normalize(&infcx, fulfill_cx, cause, elaborated_env, &predicates) {
+                Ok(predicates) => predicates,
+                Err(errors) => {
+                    infcx.report_fulfillment_errors(&errors, None, false);
+                    return Err(ErrorReported);
+                }
+            };
 
         debug!("do_normalize_predictes: normalized predicates = {:?}", predicates);
 
@@ -827,7 +833,7 @@ fn do_normalize_predicates<'tcx>(
                 // unconstrained variable, and it seems better not to ICE,
                 // all things considered.
                 tcx.sess.span_err(span, &fixup_err.to_string());
-                return Err(ErrorReported)
+                return Err(ErrorReported);
             }
         };
         if predicates.has_local_value() {
@@ -862,20 +868,20 @@ pub fn normalize_param_env_or_error<'tcx>(
     // and errors will get reported then; so after typeck we
     // can be sure that no errors should occur.
 
-    debug!("normalize_param_env_or_error(region_context={:?}, unnormalized_env={:?}, cause={:?})",
-           region_context, unnormalized_env, cause);
+    debug!(
+        "normalize_param_env_or_error(region_context={:?}, unnormalized_env={:?}, cause={:?})",
+        region_context, unnormalized_env, cause
+    );
 
     let mut predicates: Vec<_> =
-        util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.to_vec())
-            .collect();
+        util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.to_vec()).collect();
 
-    debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
-           predicates);
+    debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
 
     let elaborated_env = ty::ParamEnv::new(
         tcx.intern_predicates(&predicates),
         unnormalized_env.reveal,
-        unnormalized_env.def_id
+        unnormalized_env.def_id,
     );
 
     // HACK: we are trying to normalize the param-env inside *itself*. The problem is that
@@ -896,25 +902,31 @@ pub fn normalize_param_env_or_error<'tcx>(
     //
     // This works fairly well because trait matching  does not actually care about param-env
     // TypeOutlives predicates - these are normally used by regionck.
-    let outlives_predicates: Vec<_> = predicates.drain_filter(|predicate| {
-        match predicate {
+    let outlives_predicates: Vec<_> = predicates
+        .drain_filter(|predicate| match predicate {
             ty::Predicate::TypeOutlives(..) => true,
-            _ => false
-        }
-    }).collect();
+            _ => false,
+        })
+        .collect();
 
-    debug!("normalize_param_env_or_error: predicates=(non-outlives={:?}, outlives={:?})",
-           predicates, outlives_predicates);
-    let non_outlives_predicates =
-        match do_normalize_predicates(tcx, region_context, cause.clone(),
-                                      elaborated_env, predicates) {
-            Ok(predicates) => predicates,
-            // An unnormalized env is better than nothing.
-            Err(ErrorReported) => {
-                debug!("normalize_param_env_or_error: errored resolving non-outlives predicates");
-                return elaborated_env
-            }
-        };
+    debug!(
+        "normalize_param_env_or_error: predicates=(non-outlives={:?}, outlives={:?})",
+        predicates, outlives_predicates
+    );
+    let non_outlives_predicates = match do_normalize_predicates(
+        tcx,
+        region_context,
+        cause.clone(),
+        elaborated_env,
+        predicates,
+    ) {
+        Ok(predicates) => predicates,
+        // An unnormalized env is better than nothing.
+        Err(ErrorReported) => {
+            debug!("normalize_param_env_or_error: errored resolving non-outlives predicates");
+            return elaborated_env;
+        }
+    };
 
     debug!("normalize_param_env_or_error: non-outlives predicates={:?}", non_outlives_predicates);
 
@@ -923,21 +935,22 @@ pub fn normalize_param_env_or_error<'tcx>(
     // predicates here anyway. Keeping them here anyway because it seems safer.
     let outlives_env: Vec<_> =
         non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect();
-    let outlives_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&outlives_env),
-        unnormalized_env.reveal,
-        None
-    );
-    let outlives_predicates =
-        match do_normalize_predicates(tcx, region_context, cause,
-                                      outlives_env, outlives_predicates) {
-            Ok(predicates) => predicates,
-            // An unnormalized env is better than nothing.
-            Err(ErrorReported) => {
-                debug!("normalize_param_env_or_error: errored resolving outlives predicates");
-                return elaborated_env
-            }
-        };
+    let outlives_env =
+        ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal, None);
+    let outlives_predicates = match do_normalize_predicates(
+        tcx,
+        region_context,
+        cause,
+        outlives_env,
+        outlives_predicates,
+    ) {
+        Ok(predicates) => predicates,
+        // An unnormalized env is better than nothing.
+        Err(ErrorReported) => {
+            debug!("normalize_param_env_or_error: errored resolving outlives predicates");
+            return elaborated_env;
+        }
+    };
     debug!("normalize_param_env_or_error: outlives predicates={:?}", outlives_predicates);
 
     let mut predicates = non_outlives_predicates;
@@ -946,7 +959,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     ty::ParamEnv::new(
         tcx.intern_predicates(&predicates),
         unnormalized_env.reveal,
-        unnormalized_env.def_id
+        unnormalized_env.def_id,
     )
 }
 
@@ -964,9 +977,10 @@ where
     let selcx = &mut SelectionContext::new(infcx);
     let Normalized { value: normalized_value, obligations } =
         project::normalize(selcx, param_env, cause, value);
-    debug!("fully_normalize: normalized_value={:?} obligations={:?}",
-           normalized_value,
-           obligations);
+    debug!(
+        "fully_normalize: normalized_value={:?} obligations={:?}",
+        normalized_value, obligations
+    );
     for obligation in obligations {
         fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation);
     }
@@ -987,8 +1001,7 @@ fn normalize_and_test_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     predicates: Vec<ty::Predicate<'tcx>>,
 ) -> bool {
-    debug!("normalize_and_test_predicates(predicates={:?})",
-           predicates);
+    debug!("normalize_and_test_predicates(predicates={:?})", predicates);
 
     let result = tcx.infer_ctxt().enter(|infcx| {
         let param_env = ty::ParamEnv::reveal_all();
@@ -1007,8 +1020,7 @@ fn normalize_and_test_predicates<'tcx>(
 
         fulfill_cx.select_all_or_error(&infcx).is_ok()
     });
-    debug!("normalize_and_test_predicates(predicates={:?}) = {:?}",
-           predicates, result);
+    debug!("normalize_and_test_predicates(predicates={:?}) = {:?}", predicates, result);
     result
 }
 
@@ -1016,14 +1028,12 @@ fn substitute_normalize_and_test_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: (DefId, SubstsRef<'tcx>),
 ) -> bool {
-    debug!("substitute_normalize_and_test_predicates(key={:?})",
-           key);
+    debug!("substitute_normalize_and_test_predicates(key={:?})", key);
 
     let predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates;
     let result = normalize_and_test_predicates(tcx, predicates);
 
-    debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}",
-           key, result);
+    debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", key, result);
     result
 }
 
@@ -1036,100 +1046,98 @@ fn vtable_methods<'tcx>(
 ) -> &'tcx [Option<(DefId, SubstsRef<'tcx>)>] {
     debug!("vtable_methods({:?})", trait_ref);
 
-    tcx.arena.alloc_from_iter(
-        supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
-            let trait_methods = tcx.associated_items(trait_ref.def_id())
-                .filter(|item| item.kind == ty::AssocKind::Method);
-
-            // Now list each method's DefId and InternalSubsts (for within its trait).
-            // If the method can never be called from this object, produce None.
-            trait_methods.map(move |trait_method| {
-                debug!("vtable_methods: trait_method={:?}", trait_method);
-                let def_id = trait_method.def_id;
-
-                // Some methods cannot be called on an object; skip those.
-                if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) {
-                    debug!("vtable_methods: not vtable safe");
-                    return None;
-                }
-
-                // The method may have some early-bound lifetimes; add regions for those.
-                let substs = trait_ref.map_bound(|trait_ref|
-                    InternalSubsts::for_item(tcx, def_id, |param, _|
-                        match param.kind {
-                            GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
-                            GenericParamDefKind::Type { .. } |
-                            GenericParamDefKind::Const => {
-                                trait_ref.substs[param.index as usize]
-                            }
-                        }
-                    )
-                );
-
-                // The trait type may have higher-ranked lifetimes in it;
-                // erase them if they appear, so that we get the type
-                // at some particular call site.
-                let substs = tcx.normalize_erasing_late_bound_regions(
-                    ty::ParamEnv::reveal_all(),
-                    &substs
-                );
+    tcx.arena.alloc_from_iter(supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
+        let trait_methods = tcx
+            .associated_items(trait_ref.def_id())
+            .filter(|item| item.kind == ty::AssocKind::Method);
+
+        // Now list each method's DefId and InternalSubsts (for within its trait).
+        // If the method can never be called from this object, produce None.
+        trait_methods.map(move |trait_method| {
+            debug!("vtable_methods: trait_method={:?}", trait_method);
+            let def_id = trait_method.def_id;
+
+            // Some methods cannot be called on an object; skip those.
+            if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) {
+                debug!("vtable_methods: not vtable safe");
+                return None;
+            }
 
-                // It's possible that the method relies on where-clauses that
-                // do not hold for this particular set of type parameters.
-                // Note that this method could then never be called, so we
-                // do not want to try and codegen it, in that case (see #23435).
-                let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
-                if !normalize_and_test_predicates(tcx, predicates.predicates) {
-                    debug!("vtable_methods: predicates do not hold");
-                    return None;
-                }
+            // The method may have some early-bound lifetimes; add regions for those.
+            let substs = trait_ref.map_bound(|trait_ref| {
+                InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind {
+                    GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
+                    GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => {
+                        trait_ref.substs[param.index as usize]
+                    }
+                })
+            });
+
+            // The trait type may have higher-ranked lifetimes in it;
+            // erase them if they appear, so that we get the type
+            // at some particular call site.
+            let substs =
+                tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &substs);
+
+            // It's possible that the method relies on where-clauses that
+            // do not hold for this particular set of type parameters.
+            // Note that this method could then never be called, so we
+            // do not want to try and codegen it, in that case (see #23435).
+            let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
+            if !normalize_and_test_predicates(tcx, predicates.predicates) {
+                debug!("vtable_methods: predicates do not hold");
+                return None;
+            }
 
-                Some((def_id, substs))
-            })
+            Some((def_id, substs))
         })
-    )
+    }))
 }
 
 impl<'tcx, O> Obligation<'tcx, O> {
-    pub fn new(cause: ObligationCause<'tcx>,
-               param_env: ty::ParamEnv<'tcx>,
-               predicate: O)
-               -> Obligation<'tcx, O>
-    {
+    pub fn new(
+        cause: ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        predicate: O,
+    ) -> Obligation<'tcx, O> {
         Obligation { cause, param_env, recursion_depth: 0, predicate }
     }
 
-    fn with_depth(cause: ObligationCause<'tcx>,
-                  recursion_depth: usize,
-                  param_env: ty::ParamEnv<'tcx>,
-                  predicate: O)
-                  -> Obligation<'tcx, O>
-    {
+    fn with_depth(
+        cause: ObligationCause<'tcx>,
+        recursion_depth: usize,
+        param_env: ty::ParamEnv<'tcx>,
+        predicate: O,
+    ) -> Obligation<'tcx, O> {
         Obligation { cause, param_env, recursion_depth, predicate }
     }
 
-    pub fn misc(span: Span,
-                body_id: hir::HirId,
-                param_env: ty::ParamEnv<'tcx>,
-                trait_ref: O)
-                -> Obligation<'tcx, O> {
+    pub fn misc(
+        span: Span,
+        body_id: hir::HirId,
+        param_env: ty::ParamEnv<'tcx>,
+        trait_ref: O,
+    ) -> Obligation<'tcx, O> {
         Obligation::new(ObligationCause::misc(span, body_id), param_env, trait_ref)
     }
 
-    pub fn with<P>(&self, value: P) -> Obligation<'tcx,P> {
-        Obligation { cause: self.cause.clone(),
-                     param_env: self.param_env,
-                     recursion_depth: self.recursion_depth,
-                     predicate: value }
+    pub fn with<P>(&self, value: P) -> Obligation<'tcx, P> {
+        Obligation {
+            cause: self.cause.clone(),
+            param_env: self.param_env,
+            recursion_depth: self.recursion_depth,
+            predicate: value,
+        }
     }
 }
 
 impl<'tcx> ObligationCause<'tcx> {
     #[inline]
-    pub fn new(span: Span,
-               body_id: hir::HirId,
-               code: ObligationCauseCode<'tcx>)
-               -> ObligationCause<'tcx> {
+    pub fn new(
+        span: Span,
+        body_id: hir::HirId,
+        code: ObligationCauseCode<'tcx>,
+    ) -> ObligationCause<'tcx> {
         ObligationCause { span, body_id, code }
     }
 
@@ -1157,7 +1165,10 @@ impl<'tcx, N> Vtable<'tcx, N> {
         }
     }
 
-    pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M {
+    pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M>
+    where
+        F: FnMut(N) -> M,
+    {
         match self {
             VtableImpl(i) => VtableImpl(VtableImplData {
                 impl_def_id: i.impl_def_id,
@@ -1165,9 +1176,9 @@ impl<'tcx, N> Vtable<'tcx, N> {
                 nested: i.nested.into_iter().map(f).collect(),
             }),
             VtableParam(n) => VtableParam(n.into_iter().map(f).collect()),
-            VtableBuiltin(i) => VtableBuiltin(VtableBuiltinData {
-                nested: i.nested.into_iter().map(f).collect(),
-            }),
+            VtableBuiltin(i) => {
+                VtableBuiltin(VtableBuiltinData { nested: i.nested.into_iter().map(f).collect() })
+            }
             VtableObject(o) => VtableObject(VtableObjectData {
                 upcast_trait_ref: o.upcast_trait_ref,
                 vtable_base: o.vtable_base,
@@ -1201,10 +1212,10 @@ impl<'tcx, N> Vtable<'tcx, N> {
 }
 
 impl<'tcx> FulfillmentError<'tcx> {
-    fn new(obligation: PredicateObligation<'tcx>,
-           code: FulfillmentErrorCode<'tcx>)
-           -> FulfillmentError<'tcx>
-    {
+    fn new(
+        obligation: PredicateObligation<'tcx>,
+        code: FulfillmentErrorCode<'tcx>,
+    ) -> FulfillmentError<'tcx> {
         FulfillmentError { obligation: obligation, code: code, points_at_arg_span: false }
     }
 }