diff options
Diffstat (limited to 'src/librustc/traits/mod.rs')
| -rw-r--r-- | src/librustc/traits/mod.rs | 453 |
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 } } } |
