X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc%2Ftraits%2Futil.rs;h=65fd809657bd08fec282c73130cc6d86e9a017b0;hb=7ae0618e0af852c3e777272a29419f85eaf033cc;hp=c15915a9d561fb572807605afba6511dc1c5bc5e;hpb=c4f130493564b23e78628af25201e7e2260849f6;p=rust.git diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index c15915a9d56..65fd809657b 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -1,44 +1,49 @@ -use errors::DiagnosticBuilder; +use rustc_errors::DiagnosticBuilder; +use rustc_span::Span; use smallvec::SmallVec; -use syntax_pos::Span; -use crate::hir; -use crate::hir::def_id::DefId; -use crate::ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef}; use crate::ty::outlives::Component; use crate::ty::subst::{GenericArg, Subst, SubstsRef}; -use crate::util::nodemap::FxHashSet; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt}; +use rustc_data_structures::fx::FxHashSet; +use rustc_hir as hir; +use rustc_hir::def_id::DefId; -use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized}; +use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { match *pred { - ty::Predicate::Trait(ref data) => - ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::Trait(ref data) => { + ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::RegionOutlives(ref data) => - ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::RegionOutlives(ref data) => { + ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::TypeOutlives(ref data) => - ty::Predicate::TypeOutlives(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::TypeOutlives(ref data) => { + ty::Predicate::TypeOutlives(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::Projection(ref data) => - ty::Predicate::Projection(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::Projection(ref data) => { + ty::Predicate::Projection(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::WellFormed(data) => - ty::Predicate::WellFormed(data), + ty::Predicate::WellFormed(data) => ty::Predicate::WellFormed(data), - ty::Predicate::ObjectSafe(data) => - ty::Predicate::ObjectSafe(data), + ty::Predicate::ObjectSafe(data) => ty::Predicate::ObjectSafe(data), - ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => - ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind), + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) + } - ty::Predicate::Subtype(ref data) => - ty::Predicate::Subtype(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::Subtype(ref data) => { + ty::Predicate::Subtype(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::ConstEvaluatable(def_id, substs) => - ty::Predicate::ConstEvaluatable(def_id, substs), + ty::Predicate::ConstEvaluatable(def_id, substs) => { + ty::Predicate::ConstEvaluatable(def_id, substs) + } } } @@ -126,11 +131,11 @@ fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) { // Get predicates declared on the trait. let predicates = tcx.super_predicates_of(data.def_id()); - let predicates = predicates.predicates + let predicates = predicates + .predicates .iter() .map(|(pred, _)| pred.subst_supertrait(tcx, &data.to_poly_trait_ref())); - debug!("super_predicates: data={:?} predicates={:?}", - data, predicates.clone()); + debug!("super_predicates: data={:?} predicates={:?}", data, predicates.clone()); // Only keep those bounds that we haven't already seen. // This is necessary to prevent infinite recursion in some @@ -194,32 +199,33 @@ fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) { components .into_iter() .filter_map(|component| match component { - Component::Region(r) => if r.is_late_bound() { - None - } else { - Some(ty::Predicate::RegionOutlives( - ty::Binder::dummy(ty::OutlivesPredicate(r, r_min)))) + Component::Region(r) => { + if r.is_late_bound() { + None + } else { + Some(ty::Predicate::RegionOutlives(ty::Binder::dummy( + ty::OutlivesPredicate(r, r_min), + ))) + } } Component::Param(p) => { let ty = tcx.mk_ty_param(p.index, p.name); - Some(ty::Predicate::TypeOutlives( - ty::Binder::dummy(ty::OutlivesPredicate(ty, r_min)))) + Some(ty::Predicate::TypeOutlives(ty::Binder::dummy( + ty::OutlivesPredicate(ty, r_min), + ))) } - Component::UnresolvedInferenceVariable(_) => { - None - } + Component::UnresolvedInferenceVariable(_) => None, - Component::Projection(_) | - Component::EscapingProjection(_) => { + Component::Projection(_) | Component::EscapingProjection(_) => { // We can probably do more here. This // corresponds to a case like `>::U: 'b`. None } }) - .filter(|p| visited.insert(p)) + .filter(|p| visited.insert(p)), ); } } @@ -289,17 +295,16 @@ pub struct TraitAliasExpansionInfo<'tcx> { impl<'tcx> TraitAliasExpansionInfo<'tcx> { fn new(trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self { - Self { - path: smallvec![(trait_ref, span)] - } + Self { path: smallvec![(trait_ref, span)] } } /// Adds diagnostic labels to `diag` for the expansion path of a trait through all intermediate /// trait aliases. - pub fn label_with_exp_info(&self, + pub fn label_with_exp_info( + &self, diag: &mut DiagnosticBuilder<'_>, top_label: &str, - use_desc: &str + use_desc: &str, ) { diag.span_label(self.top().1, top_label); if self.path.len() > 1 { @@ -307,8 +312,10 @@ pub fn label_with_exp_info(&self, diag.span_label(*sp, format!("referenced here ({})", use_desc)); } } - diag.span_label(self.bottom().1, - format!("trait alias used in trait object type ({})", use_desc)); + diag.span_label( + self.bottom().1, + format!("trait alias used in trait object type ({})", use_desc), + ); } pub fn trait_ref(&self) -> &ty::PolyTraitRef<'tcx> { @@ -327,9 +334,7 @@ fn clone_and_push(&self, trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self let mut path = self.path.clone(); path.push((trait_ref, span)); - Self { - path - } + Self { path } } } @@ -365,22 +370,24 @@ fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool { // Don't recurse if this trait alias is already on the stack for the DFS search. let anon_pred = anonymize_predicate(tcx, &pred); - if item.path.iter().rev().skip(1) - .any(|(tr, _)| anonymize_predicate(tcx, &tr.to_predicate()) == anon_pred) { + if item + .path + .iter() + .rev() + .skip(1) + .any(|(tr, _)| anonymize_predicate(tcx, &tr.to_predicate()) == anon_pred) + { return false; } // Get components of trait alias. let predicates = tcx.super_predicates_of(trait_ref.def_id()); - let items = predicates.predicates - .iter() - .rev() - .filter_map(|(pred, span)| { - pred.subst_supertrait(tcx, &trait_ref) - .to_opt_poly_trait_ref() - .map(|trait_ref| item.clone_and_push(trait_ref, *span)) - }); + let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| { + pred.subst_supertrait(tcx, &trait_ref) + .to_opt_poly_trait_ref() + .map(|trait_ref| item.clone_and_push(trait_ref, *span)) + }); debug!("expand_trait_aliases: items={:?}", items.clone()); self.stack.extend(items); @@ -432,11 +439,13 @@ fn next(&mut self) -> Option { let predicates = self.tcx.super_predicates_of(def_id); let visited = &mut self.visited; self.stack.extend( - predicates.predicates - .iter() - .filter_map(|(pred, _)| pred.to_opt_poly_trait_ref()) - .map(|trait_ref| trait_ref.def_id()) - .filter(|&super_def_id| visited.insert(super_def_id))); + predicates + .predicates + .iter() + .filter_map(|(pred, _)| pred.to_opt_poly_trait_ref()) + .map(|trait_ref| trait_ref.def_id()) + .filter(|&super_def_id| visited.insert(super_def_id)), + ); Some(def_id) } } @@ -448,7 +457,7 @@ fn next(&mut self) -> Option { /// A filter around an iterator of predicates that makes it yield up /// just trait references. pub struct FilterToTraits { - base_iterator: I + base_iterator: I, } impl FilterToTraits { @@ -488,10 +497,8 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>( impl_def_id: DefId, impl_substs: SubstsRef<'tcx>, ) -> (ty::TraitRef<'tcx>, Vec>) { - let impl_trait_ref = - selcx.tcx().impl_trait_ref(impl_def_id).unwrap(); - let impl_trait_ref = - impl_trait_ref.subst(selcx.tcx(), impl_substs); + let impl_trait_ref = selcx.tcx().impl_trait_ref(impl_def_id).unwrap(); + let impl_trait_ref = impl_trait_ref.subst(selcx.tcx(), impl_substs); let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } = super::normalize(selcx, param_env, ObligationCause::dummy(), &impl_trait_ref); @@ -502,8 +509,8 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>( let impl_obligations = predicates_for_generics(ObligationCause::dummy(), 0, param_env, &predicates); - let impl_obligations: Vec<_> = - impl_obligations.into_iter() + let impl_obligations: Vec<_> = impl_obligations + .into_iter() .chain(normalization_obligations1) .chain(normalization_obligations2) .collect(); @@ -520,155 +527,145 @@ pub fn predicates_for_generics<'tcx>( ) -> Vec> { debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds); - generic_bounds.predicates.iter().map(|predicate| Obligation { - cause: cause.clone(), - recursion_depth, - param_env, - predicate: predicate.clone(), - }).collect() + generic_bounds + .predicates + .iter() + .map(|predicate| Obligation { + cause: cause.clone(), + recursion_depth, + param_env, + predicate: predicate.clone(), + }) + .collect() } pub fn predicate_for_trait_ref<'tcx>( cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, trait_ref: ty::TraitRef<'tcx>, - recursion_depth: usize) - -> PredicateObligation<'tcx> -{ - Obligation { - cause, - param_env, - recursion_depth, - predicate: trait_ref.to_predicate(), - } + recursion_depth: usize, +) -> PredicateObligation<'tcx> { + Obligation { cause, param_env, recursion_depth, predicate: trait_ref.to_predicate() } } -impl<'tcx> TyCtxt<'tcx> { - pub fn predicate_for_trait_def(self, - param_env: ty::ParamEnv<'tcx>, - cause: ObligationCause<'tcx>, - trait_def_id: DefId, - recursion_depth: usize, - self_ty: Ty<'tcx>, - params: &[GenericArg<'tcx>]) - -> PredicateObligation<'tcx> - { - let trait_ref = ty::TraitRef { - def_id: trait_def_id, - substs: self.mk_substs_trait(self_ty, params) - }; - predicate_for_trait_ref(cause, param_env, trait_ref, recursion_depth) - } - - /// Casts a trait reference into a reference to one of its super - /// traits; returns `None` if `target_trait_def_id` is not a - /// supertrait. - pub fn upcast_choices(self, - source_trait_ref: ty::PolyTraitRef<'tcx>, - target_trait_def_id: DefId) - -> Vec> - { - if source_trait_ref.def_id() == target_trait_def_id { - return vec![source_trait_ref]; // Shortcut the most common case. - } +pub fn predicate_for_trait_def( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + cause: ObligationCause<'tcx>, + trait_def_id: DefId, + recursion_depth: usize, + self_ty: Ty<'tcx>, + params: &[GenericArg<'tcx>], +) -> PredicateObligation<'tcx> { + let trait_ref = + ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(self_ty, params) }; + predicate_for_trait_ref(cause, param_env, trait_ref, recursion_depth) +} - supertraits(self, source_trait_ref) - .filter(|r| r.def_id() == target_trait_def_id) - .collect() +/// Casts a trait reference into a reference to one of its super +/// traits; returns `None` if `target_trait_def_id` is not a +/// supertrait. +pub fn upcast_choices( + tcx: TyCtxt<'tcx>, + source_trait_ref: ty::PolyTraitRef<'tcx>, + target_trait_def_id: DefId, +) -> Vec> { + if source_trait_ref.def_id() == target_trait_def_id { + return vec![source_trait_ref]; // Shortcut the most common case. } - /// Given a trait `trait_ref`, returns the number of vtable entries - /// that come from `trait_ref`, excluding its supertraits. Used in - /// computing the vtable base for an upcast trait of a trait object. - pub fn count_own_vtable_entries(self, trait_ref: ty::PolyTraitRef<'tcx>) -> usize { - let mut entries = 0; - // Count number of methods and add them to the total offset. - // Skip over associated types and constants. - for trait_item in self.associated_items(trait_ref.def_id()) { - if trait_item.kind == ty::AssocKind::Method { - entries += 1; - } + supertraits(tcx, source_trait_ref).filter(|r| r.def_id() == target_trait_def_id).collect() +} + +/// Given a trait `trait_ref`, returns the number of vtable entries +/// that come from `trait_ref`, excluding its supertraits. Used in +/// computing the vtable base for an upcast trait of a trait object. +pub fn count_own_vtable_entries(tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> usize { + let mut entries = 0; + // Count number of methods and add them to the total offset. + // Skip over associated types and constants. + for trait_item in tcx.associated_items(trait_ref.def_id()) { + if trait_item.kind == ty::AssocKind::Method { + entries += 1; } - entries } + entries +} - /// Given an upcast trait object described by `object`, returns the - /// index of the method `method_def_id` (which should be part of - /// `object.upcast_trait_ref`) within the vtable for `object`. - pub fn get_vtable_index_of_object_method(self, - object: &super::VtableObjectData<'tcx, N>, - method_def_id: DefId) -> usize { - // Count number of methods preceding the one we are selecting and - // add them to the total offset. - // Skip over associated types and constants. - let mut entries = object.vtable_base; - for trait_item in self.associated_items(object.upcast_trait_ref.def_id()) { - if trait_item.def_id == method_def_id { - // The item with the ID we were given really ought to be a method. - assert_eq!(trait_item.kind, ty::AssocKind::Method); - return entries; - } - if trait_item.kind == ty::AssocKind::Method { - entries += 1; - } +/// Given an upcast trait object described by `object`, returns the +/// index of the method `method_def_id` (which should be part of +/// `object.upcast_trait_ref`) within the vtable for `object`. +pub fn get_vtable_index_of_object_method( + tcx: TyCtxt<'tcx>, + object: &super::VtableObjectData<'tcx, N>, + method_def_id: DefId, +) -> usize { + // Count number of methods preceding the one we are selecting and + // add them to the total offset. + // Skip over associated types and constants. + let mut entries = object.vtable_base; + for trait_item in tcx.associated_items(object.upcast_trait_ref.def_id()) { + if trait_item.def_id == method_def_id { + // The item with the ID we were given really ought to be a method. + assert_eq!(trait_item.kind, ty::AssocKind::Method); + return entries; + } + if trait_item.kind == ty::AssocKind::Method { + entries += 1; } - - bug!("get_vtable_index_of_object_method: {:?} was not found", - method_def_id); } - pub fn closure_trait_ref_and_return_type(self, - fn_trait_def_id: DefId, - self_ty: Ty<'tcx>, - sig: ty::PolyFnSig<'tcx>, - tuple_arguments: TupleArgumentsFlag) - -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)> - { - let arguments_tuple = match tuple_arguments { - TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], - TupleArgumentsFlag::Yes => - self.intern_tup(sig.skip_binder().inputs()), - }; - let trait_ref = ty::TraitRef { - def_id: fn_trait_def_id, - substs: self.mk_substs_trait(self_ty, &[arguments_tuple.into()]), - }; - ty::Binder::bind((trait_ref, sig.skip_binder().output())) - } + bug!("get_vtable_index_of_object_method: {:?} was not found", method_def_id); +} - pub fn generator_trait_ref_and_outputs(self, - fn_trait_def_id: DefId, - self_ty: Ty<'tcx>, - sig: ty::PolyGenSig<'tcx>) - -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> - { - let trait_ref = ty::TraitRef { - def_id: fn_trait_def_id, - substs: self.mk_substs_trait(self_ty, &[]), - }; - ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty)) - } +pub fn closure_trait_ref_and_return_type( + tcx: TyCtxt<'tcx>, + fn_trait_def_id: DefId, + self_ty: Ty<'tcx>, + sig: ty::PolyFnSig<'tcx>, + tuple_arguments: TupleArgumentsFlag, +) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)> { + let arguments_tuple = match tuple_arguments { + TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], + TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), + }; + let trait_ref = ty::TraitRef { + def_id: fn_trait_def_id, + substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]), + }; + ty::Binder::bind((trait_ref, sig.skip_binder().output())) +} - pub fn impl_is_default(self, node_item_def_id: DefId) -> bool { - match self.hir().as_local_hir_id(node_item_def_id) { - Some(hir_id) => { - let item = self.hir().expect_item(hir_id); - if let hir::ItemKind::Impl(_, _, defaultness, ..) = item.kind { - defaultness.is_default() - } else { - false - } - } - None => { - self.impl_defaultness(node_item_def_id) - .is_default() +pub fn generator_trait_ref_and_outputs( + tcx: TyCtxt<'tcx>, + fn_trait_def_id: DefId, + self_ty: Ty<'tcx>, + sig: ty::PolyGenSig<'tcx>, +) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { + let trait_ref = + ty::TraitRef { def_id: fn_trait_def_id, substs: tcx.mk_substs_trait(self_ty, &[]) }; + ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty)) +} + +pub fn impl_is_default(tcx: TyCtxt<'_>, node_item_def_id: DefId) -> bool { + match tcx.hir().as_local_hir_id(node_item_def_id) { + Some(hir_id) => { + let item = tcx.hir().expect_item(hir_id); + if let hir::ItemKind::Impl(_, _, defaultness, ..) = item.kind { + defaultness.is_default() + } else { + false } } + None => tcx.impl_defaultness(node_item_def_id).is_default(), } +} - pub fn impl_item_is_final(self, assoc_item: &ty::AssocItem) -> bool { - assoc_item.defaultness.is_final() && !self.impl_is_default(assoc_item.container.id()) - } +pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool { + assoc_item.defaultness.is_final() && !impl_is_default(tcx, assoc_item.container.id()) } -pub enum TupleArgumentsFlag { Yes, No } +pub enum TupleArgumentsFlag { + Yes, + No, +}