Make traits::util::* free functions.
This commit is contained in:
parent
56a0aec07f
commit
787cd5493a
@ -64,6 +64,10 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
|
|||||||
pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
|
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::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
|
||||||
pub use self::util::{expand_trait_aliases, TraitAliasExpander};
|
pub use self::util::{expand_trait_aliases, TraitAliasExpander};
|
||||||
|
pub use self::util::{
|
||||||
|
get_vtable_index_of_object_method, impl_is_default, impl_item_is_final,
|
||||||
|
predicate_for_trait_def, upcast_choices,
|
||||||
|
};
|
||||||
pub use self::util::{
|
pub use self::util::{
|
||||||
supertrait_def_ids, supertraits, transitive_bounds, SupertraitDefIds, Supertraits,
|
supertrait_def_ids, supertraits, transitive_bounds, SupertraitDefIds, Supertraits,
|
||||||
};
|
};
|
||||||
|
@ -1057,7 +1057,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||||||
node_item.item.defaultness.has_value()
|
node_item.item.defaultness.has_value()
|
||||||
} else {
|
} else {
|
||||||
node_item.item.defaultness.is_default()
|
node_item.item.defaultness.is_default()
|
||||||
|| selcx.tcx().impl_is_default(node_item.node.def_id())
|
|| super::util::impl_is_default(selcx.tcx(), node_item.node.def_id())
|
||||||
};
|
};
|
||||||
|
|
||||||
// Only reveal a specializable default if we're past type-checking
|
// Only reveal a specializable default if we're past type-checking
|
||||||
@ -1263,26 +1263,30 @@ fn confirm_generator_candidate<'cx, 'tcx>(
|
|||||||
|
|
||||||
let gen_def_id = tcx.lang_items().gen_trait().unwrap();
|
let gen_def_id = tcx.lang_items().gen_trait().unwrap();
|
||||||
|
|
||||||
let predicate = tcx
|
let predicate = super::util::generator_trait_ref_and_outputs(
|
||||||
.generator_trait_ref_and_outputs(gen_def_id, obligation.predicate.self_ty(), gen_sig)
|
tcx,
|
||||||
.map_bound(|(trait_ref, yield_ty, return_ty)| {
|
gen_def_id,
|
||||||
let name = tcx.associated_item(obligation.predicate.item_def_id).ident.name;
|
obligation.predicate.self_ty(),
|
||||||
let ty = if name == sym::Return {
|
gen_sig,
|
||||||
return_ty
|
)
|
||||||
} else if name == sym::Yield {
|
.map_bound(|(trait_ref, yield_ty, return_ty)| {
|
||||||
yield_ty
|
let name = tcx.associated_item(obligation.predicate.item_def_id).ident.name;
|
||||||
} else {
|
let ty = if name == sym::Return {
|
||||||
bug!()
|
return_ty
|
||||||
};
|
} else if name == sym::Yield {
|
||||||
|
yield_ty
|
||||||
|
} else {
|
||||||
|
bug!()
|
||||||
|
};
|
||||||
|
|
||||||
ty::ProjectionPredicate {
|
ty::ProjectionPredicate {
|
||||||
projection_ty: ty::ProjectionTy {
|
projection_ty: ty::ProjectionTy {
|
||||||
substs: trait_ref.substs,
|
substs: trait_ref.substs,
|
||||||
item_def_id: obligation.predicate.item_def_id,
|
item_def_id: obligation.predicate.item_def_id,
|
||||||
},
|
},
|
||||||
ty: ty,
|
ty: ty,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
confirm_param_env_candidate(selcx, obligation, predicate)
|
confirm_param_env_candidate(selcx, obligation, predicate)
|
||||||
.with_addl_obligations(vtable.nested)
|
.with_addl_obligations(vtable.nested)
|
||||||
@ -1349,21 +1353,21 @@ fn confirm_callable_candidate<'cx, 'tcx>(
|
|||||||
// the `Output` associated type is declared on `FnOnce`
|
// the `Output` associated type is declared on `FnOnce`
|
||||||
let fn_once_def_id = tcx.lang_items().fn_once_trait().unwrap();
|
let fn_once_def_id = tcx.lang_items().fn_once_trait().unwrap();
|
||||||
|
|
||||||
let predicate = tcx
|
let predicate = super::util::closure_trait_ref_and_return_type(
|
||||||
.closure_trait_ref_and_return_type(
|
tcx,
|
||||||
fn_once_def_id,
|
fn_once_def_id,
|
||||||
obligation.predicate.self_ty(),
|
obligation.predicate.self_ty(),
|
||||||
fn_sig,
|
fn_sig,
|
||||||
flag,
|
flag,
|
||||||
)
|
)
|
||||||
.map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
|
.map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
|
||||||
projection_ty: ty::ProjectionTy::from_ref_and_name(
|
projection_ty: ty::ProjectionTy::from_ref_and_name(
|
||||||
tcx,
|
tcx,
|
||||||
trait_ref,
|
trait_ref,
|
||||||
Ident::with_dummy_span(FN_OUTPUT_NAME),
|
Ident::with_dummy_span(FN_OUTPUT_NAME),
|
||||||
),
|
),
|
||||||
ty: ret_type,
|
ty: ret_type,
|
||||||
});
|
});
|
||||||
|
|
||||||
confirm_param_env_candidate(selcx, obligation, predicate)
|
confirm_param_env_candidate(selcx, obligation, predicate)
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ use super::coherence::{self, Conflict};
|
|||||||
use super::project;
|
use super::project;
|
||||||
use super::project::{normalize_with_depth, Normalized, ProjectionCacheKey};
|
use super::project::{normalize_with_depth, Normalized, ProjectionCacheKey};
|
||||||
use super::util;
|
use super::util;
|
||||||
|
use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
|
||||||
use super::DerivedObligationCause;
|
use super::DerivedObligationCause;
|
||||||
use super::Selection;
|
use super::Selection;
|
||||||
use super::SelectionResult;
|
use super::SelectionResult;
|
||||||
@ -2651,7 +2652,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
recursion_depth,
|
recursion_depth,
|
||||||
&skol_ty,
|
&skol_ty,
|
||||||
);
|
);
|
||||||
let skol_obligation = self.tcx().predicate_for_trait_def(
|
let skol_obligation = predicate_for_trait_def(
|
||||||
|
self.tcx(),
|
||||||
param_env,
|
param_env,
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
@ -2988,7 +2990,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// we pass over, we sum up the set of number of vtable
|
// we pass over, we sum up the set of number of vtable
|
||||||
// entries, so that we can compute the offset for the selected
|
// entries, so that we can compute the offset for the selected
|
||||||
// trait.
|
// trait.
|
||||||
vtable_base = nonmatching.map(|t| tcx.count_own_vtable_entries(t)).sum();
|
vtable_base = nonmatching.map(|t| super::util::count_own_vtable_entries(tcx, t)).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
VtableObjectData { upcast_trait_ref: upcast_trait_ref.unwrap(), vtable_base, nested }
|
VtableObjectData { upcast_trait_ref: upcast_trait_ref.unwrap(), vtable_base, nested }
|
||||||
@ -3003,15 +3005,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// Okay to skip binder; it is reintroduced below.
|
// Okay to skip binder; it is reintroduced below.
|
||||||
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
|
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
|
||||||
let sig = self_ty.fn_sig(self.tcx());
|
let sig = self_ty.fn_sig(self.tcx());
|
||||||
let trait_ref = self
|
let trait_ref = closure_trait_ref_and_return_type(
|
||||||
.tcx()
|
self.tcx(),
|
||||||
.closure_trait_ref_and_return_type(
|
obligation.predicate.def_id(),
|
||||||
obligation.predicate.def_id(),
|
self_ty,
|
||||||
self_ty,
|
sig,
|
||||||
sig,
|
util::TupleArgumentsFlag::Yes,
|
||||||
util::TupleArgumentsFlag::Yes,
|
)
|
||||||
)
|
.map_bound(|(trait_ref, _)| trait_ref);
|
||||||
.map_bound(|(trait_ref, _)| trait_ref);
|
|
||||||
|
|
||||||
let Normalized { value: trait_ref, obligations } = project::normalize_with_depth(
|
let Normalized { value: trait_ref, obligations } = project::normalize_with_depth(
|
||||||
self,
|
self,
|
||||||
@ -3381,7 +3382,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
nested.extend(obligations);
|
nested.extend(obligations);
|
||||||
|
|
||||||
// Construct the nested `Field<T>: Unsize<Field<U>>` predicate.
|
// Construct the nested `Field<T>: Unsize<Field<U>>` predicate.
|
||||||
nested.push(tcx.predicate_for_trait_def(
|
nested.push(predicate_for_trait_def(
|
||||||
|
tcx,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
obligation.cause.clone(),
|
obligation.cause.clone(),
|
||||||
obligation.predicate.def_id(),
|
obligation.predicate.def_id(),
|
||||||
@ -3416,7 +3418,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
nested.extend(obligations);
|
nested.extend(obligations);
|
||||||
|
|
||||||
// Construct the nested `T: Unsize<U>` predicate.
|
// Construct the nested `T: Unsize<U>` predicate.
|
||||||
nested.push(tcx.predicate_for_trait_def(
|
nested.push(predicate_for_trait_def(
|
||||||
|
tcx,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
obligation.cause.clone(),
|
obligation.cause.clone(),
|
||||||
obligation.predicate.def_id(),
|
obligation.predicate.def_id(),
|
||||||
@ -3627,14 +3630,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// in fact unparameterized (or at least does not reference any
|
// in fact unparameterized (or at least does not reference any
|
||||||
// regions bound in the obligation). Still probably some
|
// regions bound in the obligation). Still probably some
|
||||||
// refactoring could make this nicer.
|
// refactoring could make this nicer.
|
||||||
self.tcx()
|
closure_trait_ref_and_return_type(
|
||||||
.closure_trait_ref_and_return_type(
|
self.tcx(),
|
||||||
obligation.predicate.def_id(),
|
obligation.predicate.def_id(),
|
||||||
obligation.predicate.skip_binder().self_ty(), // (1)
|
obligation.predicate.skip_binder().self_ty(), // (1)
|
||||||
closure_type,
|
closure_type,
|
||||||
util::TupleArgumentsFlag::No,
|
util::TupleArgumentsFlag::No,
|
||||||
)
|
)
|
||||||
.map_bound(|(trait_ref, _)| trait_ref)
|
.map_bound(|(trait_ref, _)| trait_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generator_trait_ref_unnormalized(
|
fn generator_trait_ref_unnormalized(
|
||||||
@ -3651,13 +3654,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// regions bound in the obligation). Still probably some
|
// regions bound in the obligation). Still probably some
|
||||||
// refactoring could make this nicer.
|
// refactoring could make this nicer.
|
||||||
|
|
||||||
self.tcx()
|
super::util::generator_trait_ref_and_outputs(
|
||||||
.generator_trait_ref_and_outputs(
|
self.tcx(),
|
||||||
obligation.predicate.def_id(),
|
obligation.predicate.def_id(),
|
||||||
obligation.predicate.skip_binder().self_ty(), // (1)
|
obligation.predicate.skip_binder().self_ty(), // (1)
|
||||||
gen_sig,
|
gen_sig,
|
||||||
)
|
)
|
||||||
.map_bound(|(trait_ref, ..)| trait_ref)
|
.map_bound(|(trait_ref, ..)| trait_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the obligations that are implied by instantiating an
|
/// Returns the obligations that are implied by instantiating an
|
||||||
|
@ -548,125 +548,123 @@ pub fn predicate_for_trait_ref<'tcx>(
|
|||||||
Obligation { cause, param_env, recursion_depth, predicate: trait_ref.to_predicate() }
|
Obligation { cause, param_env, recursion_depth, predicate: trait_ref.to_predicate() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
pub fn predicate_for_trait_def(
|
||||||
pub fn predicate_for_trait_def(
|
tcx: TyCtxt<'tcx>,
|
||||||
self,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
cause: ObligationCause<'tcx>,
|
trait_def_id: DefId,
|
||||||
trait_def_id: DefId,
|
recursion_depth: usize,
|
||||||
recursion_depth: usize,
|
self_ty: Ty<'tcx>,
|
||||||
self_ty: Ty<'tcx>,
|
params: &[GenericArg<'tcx>],
|
||||||
params: &[GenericArg<'tcx>],
|
) -> PredicateObligation<'tcx> {
|
||||||
) -> PredicateObligation<'tcx> {
|
let trait_ref =
|
||||||
let trait_ref =
|
ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(self_ty, params) };
|
||||||
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)
|
||||||
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(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
source_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
|
target_trait_def_id: DefId,
|
||||||
|
) -> Vec<ty::PolyTraitRef<'tcx>> {
|
||||||
|
if source_trait_ref.def_id() == target_trait_def_id {
|
||||||
|
return vec![source_trait_ref]; // Shortcut the most common case.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Casts a trait reference into a reference to one of its super
|
supertraits(tcx, source_trait_ref).filter(|r| r.def_id() == target_trait_def_id).collect()
|
||||||
/// traits; returns `None` if `target_trait_def_id` is not a
|
}
|
||||||
/// supertrait.
|
|
||||||
pub fn upcast_choices(
|
/// Given a trait `trait_ref`, returns the number of vtable entries
|
||||||
self,
|
/// that come from `trait_ref`, excluding its supertraits. Used in
|
||||||
source_trait_ref: ty::PolyTraitRef<'tcx>,
|
/// computing the vtable base for an upcast trait of a trait object.
|
||||||
target_trait_def_id: DefId,
|
pub fn count_own_vtable_entries(tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> usize {
|
||||||
) -> Vec<ty::PolyTraitRef<'tcx>> {
|
let mut entries = 0;
|
||||||
if source_trait_ref.def_id() == target_trait_def_id {
|
// Count number of methods and add them to the total offset.
|
||||||
return vec![source_trait_ref]; // Shortcut the most common case.
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
supertraits(self, source_trait_ref).filter(|r| r.def_id() == target_trait_def_id).collect()
|
|
||||||
}
|
}
|
||||||
|
entries
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a trait `trait_ref`, returns the number of vtable entries
|
/// Given an upcast trait object described by `object`, returns the
|
||||||
/// that come from `trait_ref`, excluding its supertraits. Used in
|
/// index of the method `method_def_id` (which should be part of
|
||||||
/// computing the vtable base for an upcast trait of a trait object.
|
/// `object.upcast_trait_ref`) within the vtable for `object`.
|
||||||
pub fn count_own_vtable_entries(self, trait_ref: ty::PolyTraitRef<'tcx>) -> usize {
|
pub fn get_vtable_index_of_object_method<N>(
|
||||||
let mut entries = 0;
|
tcx: TyCtxt<'tcx>,
|
||||||
// Count number of methods and add them to the total offset.
|
object: &super::VtableObjectData<'tcx, N>,
|
||||||
// Skip over associated types and constants.
|
method_def_id: DefId,
|
||||||
for trait_item in self.associated_items(trait_ref.def_id()) {
|
) -> usize {
|
||||||
if trait_item.kind == ty::AssocKind::Method {
|
// Count number of methods preceding the one we are selecting and
|
||||||
entries += 1;
|
// 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;
|
||||||
}
|
}
|
||||||
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<N>(
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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()))
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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 impl_item_is_final(self, assoc_item: &ty::AssocItem) -> bool {
|
bug!("get_vtable_index_of_object_method: {:?} was not found", method_def_id);
|
||||||
assoc_item.defaultness.is_final() && !self.impl_is_default(assoc_item.container.id())
|
}
|
||||||
|
|
||||||
|
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 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(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool {
|
||||||
|
assoc_item.defaultness.is_final() && !impl_is_default(tcx, assoc_item.container.id())
|
||||||
|
}
|
||||||
|
|
||||||
pub enum TupleArgumentsFlag {
|
pub enum TupleArgumentsFlag {
|
||||||
Yes,
|
Yes,
|
||||||
No,
|
No,
|
||||||
|
@ -411,7 +411,7 @@ fn resolve_associated_item<'tcx>(
|
|||||||
substs: rcvr_substs,
|
substs: rcvr_substs,
|
||||||
}),
|
}),
|
||||||
traits::VtableObject(ref data) => {
|
traits::VtableObject(ref data) => {
|
||||||
let index = tcx.get_vtable_index_of_object_method(data, def_id);
|
let index = traits::get_vtable_index_of_object_method(tcx, data, def_id);
|
||||||
Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
|
Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
|
||||||
}
|
}
|
||||||
traits::VtableBuiltin(..) => {
|
traits::VtableBuiltin(..) => {
|
||||||
|
@ -3,6 +3,7 @@ use crate::const_eval::const_variant_index;
|
|||||||
use rustc::infer::InferCtxt;
|
use rustc::infer::InferCtxt;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::mir::Field;
|
use rustc::mir::Field;
|
||||||
|
use rustc::traits::predicate_for_trait_def;
|
||||||
use rustc::traits::{ObligationCause, PredicateObligation};
|
use rustc::traits::{ObligationCause, PredicateObligation};
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -129,7 +130,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
|||||||
// not *yet* implement `PartialEq`. So for now we leave this here.
|
// not *yet* implement `PartialEq`. So for now we leave this here.
|
||||||
let ty_is_partial_eq: bool = {
|
let ty_is_partial_eq: bool = {
|
||||||
let partial_eq_trait_id = self.tcx().lang_items().eq_trait().unwrap();
|
let partial_eq_trait_id = self.tcx().lang_items().eq_trait().unwrap();
|
||||||
let obligation: PredicateObligation<'_> = self.tcx().predicate_for_trait_def(
|
let obligation: PredicateObligation<'_> = predicate_for_trait_def(
|
||||||
|
self.tcx(),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ObligationCause::misc(self.span, self.id),
|
ObligationCause::misc(self.span, self.id),
|
||||||
partial_eq_trait_id,
|
partial_eq_trait_id,
|
||||||
|
@ -544,7 +544,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
// and almost never more than 3. By using a SmallVec we avoid an
|
// and almost never more than 3. By using a SmallVec we avoid an
|
||||||
// allocation, at the (very small) cost of (occasionally) having to
|
// allocation, at the (very small) cost of (occasionally) having to
|
||||||
// shift subsequent elements down when removing the front element.
|
// shift subsequent elements down when removing the front element.
|
||||||
let mut queue: SmallVec<[_; 4]> = smallvec![self.tcx.predicate_for_trait_def(
|
let mut queue: SmallVec<[_; 4]> = smallvec![traits::predicate_for_trait_def(
|
||||||
|
self.tcx,
|
||||||
self.fcx.param_env,
|
self.fcx.param_env,
|
||||||
cause,
|
cause,
|
||||||
coerce_unsized_did,
|
coerce_unsized_did,
|
||||||
|
@ -596,7 +596,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||||||
target_trait_def_id: DefId,
|
target_trait_def_id: DefId,
|
||||||
) -> ty::PolyTraitRef<'tcx> {
|
) -> ty::PolyTraitRef<'tcx> {
|
||||||
let upcast_trait_refs =
|
let upcast_trait_refs =
|
||||||
self.tcx.upcast_choices(source_trait_ref.clone(), target_trait_def_id);
|
traits::upcast_choices(self.tcx, source_trait_ref.clone(), target_trait_def_id);
|
||||||
|
|
||||||
// must be exactly one trait ref or we'd get an ambig error etc
|
// must be exactly one trait ref or we'd get an ambig error etc
|
||||||
if upcast_trait_refs.len() != 1 {
|
if upcast_trait_refs.len() != 1 {
|
||||||
|
@ -1901,7 +1901,7 @@ fn check_specialization_validity<'tcx>(
|
|||||||
match parent_item {
|
match parent_item {
|
||||||
// Parent impl exists, and contains the parent item we're trying to specialize, but
|
// Parent impl exists, and contains the parent item we're trying to specialize, but
|
||||||
// doesn't mark it `default`.
|
// doesn't mark it `default`.
|
||||||
Some(parent_item) if tcx.impl_item_is_final(&parent_item) => {
|
Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
|
||||||
Some(Err(parent_impl.def_id()))
|
Some(Err(parent_impl.def_id()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1912,7 +1912,7 @@ fn check_specialization_validity<'tcx>(
|
|||||||
// grandparent. In that case, if parent is a `default impl`, inherited items use the
|
// grandparent. In that case, if parent is a `default impl`, inherited items use the
|
||||||
// "defaultness" from the grandparent, else they are final.
|
// "defaultness" from the grandparent, else they are final.
|
||||||
None => {
|
None => {
|
||||||
if tcx.impl_is_default(parent_impl.def_id()) {
|
if traits::impl_is_default(tcx, parent_impl.def_id()) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Err(parent_impl.def_id()))
|
Some(Err(parent_impl.def_id()))
|
||||||
@ -2076,7 +2076,7 @@ fn check_impl_items_against_trait<'tcx>(
|
|||||||
.map(|node_item| !node_item.node.is_from_trait())
|
.map(|node_item| !node_item.node.is_from_trait())
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
|
|
||||||
if !is_implemented && !tcx.impl_is_default(impl_id) {
|
if !is_implemented && !traits::impl_is_default(tcx, impl_id) {
|
||||||
if !trait_item.defaultness.has_value() {
|
if !trait_item.defaultness.has_value() {
|
||||||
missing_items.push(trait_item);
|
missing_items.push(trait_item);
|
||||||
} else if associated_type_overridden {
|
} else if associated_type_overridden {
|
||||||
|
@ -7,6 +7,7 @@ use rustc::middle::lang_items::UnsizeTraitLangItem;
|
|||||||
use rustc::middle::region;
|
use rustc::middle::region;
|
||||||
|
|
||||||
use rustc::infer;
|
use rustc::infer;
|
||||||
|
use rustc::traits::predicate_for_trait_def;
|
||||||
use rustc::traits::{self, ObligationCause, TraitEngine};
|
use rustc::traits::{self, ObligationCause, TraitEngine};
|
||||||
use rustc::ty::adjustment::CoerceUnsizedInfo;
|
use rustc::ty::adjustment::CoerceUnsizedInfo;
|
||||||
use rustc::ty::util::CopyImplementationError;
|
use rustc::ty::util::CopyImplementationError;
|
||||||
@ -284,7 +285,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: DefId) {
|
|||||||
let mut fulfill_cx = TraitEngine::new(infcx.tcx);
|
let mut fulfill_cx = TraitEngine::new(infcx.tcx);
|
||||||
|
|
||||||
for field in coerced_fields {
|
for field in coerced_fields {
|
||||||
let predicate = tcx.predicate_for_trait_def(
|
let predicate = predicate_for_trait_def(
|
||||||
|
tcx,
|
||||||
param_env,
|
param_env,
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
dispatch_from_dyn_trait,
|
dispatch_from_dyn_trait,
|
||||||
@ -543,7 +545,8 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
|
|||||||
|
|
||||||
// Register an obligation for `A: Trait<B>`.
|
// Register an obligation for `A: Trait<B>`.
|
||||||
let cause = traits::ObligationCause::misc(span, impl_hir_id);
|
let cause = traits::ObligationCause::misc(span, impl_hir_id);
|
||||||
let predicate = tcx.predicate_for_trait_def(
|
let predicate = predicate_for_trait_def(
|
||||||
|
tcx,
|
||||||
param_env,
|
param_env,
|
||||||
cause,
|
cause,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
|
Loading…
Reference in New Issue
Block a user