mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Rollup merge of #104716 - lcnr:selection-candidate, r=jackh726
move 2 candidates into builtin candidate having separate candidates for these isn't too helpful i think r? types
This commit is contained in:
commit
9c7dc3e30b
@ -651,12 +651,6 @@ pub enum ImplSource<'tcx, N> {
|
||||
/// Same as above, but for a function pointer type with the given signature.
|
||||
FnPointer(ImplSourceFnPointerData<'tcx, N>),
|
||||
|
||||
/// ImplSource for a builtin `DeterminantKind` trait implementation.
|
||||
DiscriminantKind(ImplSourceDiscriminantKindData),
|
||||
|
||||
/// ImplSource for a builtin `Pointee` trait implementation.
|
||||
Pointee(ImplSourcePointeeData),
|
||||
|
||||
/// ImplSource automatically generated for a generator.
|
||||
Generator(ImplSourceGeneratorData<'tcx, N>),
|
||||
|
||||
@ -682,8 +676,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
||||
ImplSource::Future(c) => c.nested,
|
||||
ImplSource::Object(d) => d.nested,
|
||||
ImplSource::FnPointer(d) => d.nested,
|
||||
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
|
||||
| ImplSource::Pointee(ImplSourcePointeeData) => vec![],
|
||||
ImplSource::TraitAlias(d) => d.nested,
|
||||
ImplSource::TraitUpcasting(d) => d.nested,
|
||||
ImplSource::ConstDestruct(i) => i.nested,
|
||||
@ -701,8 +693,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
||||
ImplSource::Future(c) => &c.nested,
|
||||
ImplSource::Object(d) => &d.nested,
|
||||
ImplSource::FnPointer(d) => &d.nested,
|
||||
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
|
||||
| ImplSource::Pointee(ImplSourcePointeeData) => &[],
|
||||
ImplSource::TraitAlias(d) => &d.nested,
|
||||
ImplSource::TraitUpcasting(d) => &d.nested,
|
||||
ImplSource::ConstDestruct(i) => &i.nested,
|
||||
@ -751,12 +741,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
||||
fn_ty: p.fn_ty,
|
||||
nested: p.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => {
|
||||
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
|
||||
}
|
||||
ImplSource::Pointee(ImplSourcePointeeData) => {
|
||||
ImplSource::Pointee(ImplSourcePointeeData)
|
||||
}
|
||||
ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
|
||||
alias_def_id: d.alias_def_id,
|
||||
substs: d.substs,
|
||||
@ -876,13 +860,6 @@ pub struct ImplSourceFnPointerData<'tcx, N> {
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
// FIXME(@lcnr): This should be refactored and merged with other builtin vtables.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
|
||||
pub struct ImplSourceDiscriminantKindData;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
|
||||
pub struct ImplSourcePointeeData;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceConstDestructData<N> {
|
||||
|
@ -105,6 +105,12 @@ pub type EvaluationCache<'tcx> = Cache<
|
||||
/// parameter environment.
|
||||
#[derive(PartialEq, Eq, Debug, Clone, TypeFoldable, TypeVisitable)]
|
||||
pub enum SelectionCandidate<'tcx> {
|
||||
/// A builtin implementation for some specific traits, used in cases
|
||||
/// where we cannot rely an ordinary library implementations.
|
||||
///
|
||||
/// The most notable examples are `sized`, `Copy` and `Clone`. This is also
|
||||
/// used for the `DiscriminantKind` and `Pointee` trait, both of which have
|
||||
/// an associated type.
|
||||
BuiltinCandidate {
|
||||
/// `false` if there are no *further* obligations.
|
||||
has_nested: bool,
|
||||
@ -141,12 +147,6 @@ pub enum SelectionCandidate<'tcx> {
|
||||
is_const: bool,
|
||||
},
|
||||
|
||||
/// Builtin implementation of `DiscriminantKind`.
|
||||
DiscriminantKindCandidate,
|
||||
|
||||
/// Builtin implementation of `Pointee`.
|
||||
PointeeCandidate,
|
||||
|
||||
TraitAliasCandidate,
|
||||
|
||||
/// Matching `dyn Trait` with a supertrait of `Trait`. The index is the
|
||||
|
@ -19,10 +19,6 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
|
||||
|
||||
super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d),
|
||||
|
||||
super::ImplSource::DiscriminantKind(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::Pointee(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::Param(ref n, ct) => {
|
||||
@ -137,11 +133,3 @@ impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceConstDestructData<N> {
|
||||
write!(f, "ImplSourceConstDestructData(nested={:?})", self.nested)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Lift implementations
|
||||
|
||||
TrivialTypeTraversalAndLiftImpls! {
|
||||
super::ImplSourceDiscriminantKindData,
|
||||
super::ImplSourcePointeeData,
|
||||
}
|
||||
|
@ -11,8 +11,7 @@ use super::Selection;
|
||||
use super::SelectionContext;
|
||||
use super::SelectionError;
|
||||
use super::{
|
||||
ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
||||
ImplSourceFutureData, ImplSourceGeneratorData, ImplSourcePointeeData,
|
||||
ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData,
|
||||
ImplSourceUserDefinedData,
|
||||
};
|
||||
use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
|
||||
@ -29,6 +28,7 @@ use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
||||
use rustc_infer::traits::ImplSourceBuiltinData;
|
||||
use rustc_middle::traits::select::OverflowError;
|
||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
|
||||
@ -1598,13 +1598,14 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
}
|
||||
}
|
||||
}
|
||||
super::ImplSource::DiscriminantKind(..) => {
|
||||
// While `DiscriminantKind` is automatically implemented for every type,
|
||||
// the concrete discriminant may not be known yet.
|
||||
//
|
||||
// Any type with multiple potential discriminant types is therefore not eligible.
|
||||
super::ImplSource::Builtin(..) => {
|
||||
// While a builtin impl may be known to exist, the associated type may not yet
|
||||
// be known. Any type with multiple potential associated types is therefore
|
||||
// not eligible.
|
||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
|
||||
let lang_items = selcx.tcx().lang_items();
|
||||
if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) {
|
||||
match self_ty.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
@ -1629,22 +1630,17 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
// Integers and floats always have `u8` as their discriminant.
|
||||
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
|
||||
|
||||
ty::Projection(..)
|
||||
// type parameters, opaques, and unnormalized projections have pointer
|
||||
// metadata if they're known (e.g. by the param_env) to be sized
|
||||
ty::Param(_)
|
||||
| ty::Projection(..)
|
||||
| ty::Opaque(..)
|
||||
| ty::Param(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(..)
|
||||
| ty::Error(_) => false,
|
||||
}
|
||||
}
|
||||
super::ImplSource::Pointee(..) => {
|
||||
// While `Pointee` is automatically implemented for every type,
|
||||
// the concrete metadata type may not be known yet.
|
||||
//
|
||||
// Any type with multiple potential metadata types is therefore not eligible.
|
||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
|
||||
} else if lang_items.pointee_trait() == Some(poly_trait_ref.def_id()) {
|
||||
let tail = selcx.tcx().struct_tail_with_normalize(
|
||||
self_ty,
|
||||
|ty| {
|
||||
@ -1696,10 +1692,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
if selcx.infcx().predicate_must_hold_modulo_regions(
|
||||
&obligation.with(
|
||||
selcx.tcx(),
|
||||
ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref(
|
||||
LangItem::Sized,
|
||||
[self_ty],
|
||||
))
|
||||
ty::Binder::dummy(
|
||||
selcx.tcx().at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]),
|
||||
)
|
||||
.without_const(),
|
||||
),
|
||||
) =>
|
||||
@ -1721,6 +1716,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bug!("unexpected builtin trait with associated type: {poly_trait_ref:?}")
|
||||
}
|
||||
}
|
||||
super::ImplSource::Param(..) => {
|
||||
// This case tell us nothing about the value of an
|
||||
@ -1757,7 +1755,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
false
|
||||
}
|
||||
super::ImplSource::AutoImpl(..)
|
||||
| super::ImplSource::Builtin(..)
|
||||
| super::ImplSource::TraitUpcasting(_)
|
||||
| super::ImplSource::ConstDestruct(_) => {
|
||||
// These traits have no associated types.
|
||||
@ -1837,14 +1834,10 @@ fn confirm_select_candidate<'cx, 'tcx>(
|
||||
super::ImplSource::Future(data) => confirm_future_candidate(selcx, obligation, data),
|
||||
super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data),
|
||||
super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
|
||||
super::ImplSource::DiscriminantKind(data) => {
|
||||
confirm_discriminant_kind_candidate(selcx, obligation, data)
|
||||
}
|
||||
super::ImplSource::Pointee(data) => confirm_pointee_candidate(selcx, obligation, data),
|
||||
super::ImplSource::Builtin(data) => confirm_builtin_candidate(selcx, obligation, data),
|
||||
super::ImplSource::Object(_)
|
||||
| super::ImplSource::AutoImpl(..)
|
||||
| super::ImplSource::Param(..)
|
||||
| super::ImplSource::Builtin(..)
|
||||
| super::ImplSource::TraitUpcasting(_)
|
||||
| super::ImplSource::TraitAlias(..)
|
||||
| super::ImplSource::ConstDestruct(_) => {
|
||||
@ -1950,40 +1943,27 @@ fn confirm_future_candidate<'cx, 'tcx>(
|
||||
.with_addl_obligations(obligations)
|
||||
}
|
||||
|
||||
fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
|
||||
fn confirm_builtin_candidate<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
_: ImplSourceDiscriminantKindData,
|
||||
data: ImplSourceBuiltinData<PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let tcx = selcx.tcx();
|
||||
|
||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
// We get here from `poly_project_and_unify_type` which replaces bound vars
|
||||
// with placeholders
|
||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
let self_ty = obligation.predicate.self_ty();
|
||||
let substs = tcx.mk_substs([self_ty.into()].iter());
|
||||
|
||||
let lang_items = tcx.lang_items();
|
||||
let item_def_id = obligation.predicate.item_def_id;
|
||||
let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
|
||||
let (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
|
||||
let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
|
||||
assert_eq!(discriminant_def_id, item_def_id);
|
||||
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
|
||||
term: self_ty.discriminant_ty(tcx).into(),
|
||||
};
|
||||
(self_ty.discriminant_ty(tcx).into(), Vec::new())
|
||||
} else if lang_items.pointee_trait() == Some(trait_def_id) {
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
|
||||
assert_eq!(metadata_def_id, item_def_id);
|
||||
|
||||
// We get here from `poly_project_and_unify_type` which replaces bound vars
|
||||
// with placeholders, so dummy is okay here.
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
||||
}
|
||||
|
||||
fn confirm_pointee_candidate<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
_: ImplSourcePointeeData,
|
||||
) -> Progress<'tcx> {
|
||||
let tcx = selcx.tcx();
|
||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
|
||||
let mut obligations = vec![];
|
||||
let mut obligations = Vec::new();
|
||||
let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
|
||||
normalize_with_depth_to(
|
||||
selcx,
|
||||
@ -1996,22 +1976,22 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
|
||||
});
|
||||
if check_is_sized {
|
||||
let sized_predicate = ty::Binder::dummy(
|
||||
tcx.at(obligation.cause.span).mk_trait_ref(LangItem::Sized, [self_ty]),
|
||||
tcx.at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]),
|
||||
)
|
||||
.without_const();
|
||||
obligations.push(obligation.with(tcx, sized_predicate));
|
||||
}
|
||||
|
||||
let substs = tcx.mk_substs([self_ty.into()].iter());
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, Some(obligation.cause.span));
|
||||
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id },
|
||||
term: metadata_ty.into(),
|
||||
(metadata_ty.into(), obligations)
|
||||
} else {
|
||||
bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
|
||||
};
|
||||
|
||||
let predicate =
|
||||
ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id }, term };
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
||||
.with_addl_obligations(obligations)
|
||||
.with_addl_obligations(data.nested)
|
||||
}
|
||||
|
||||
fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
||||
|
@ -282,10 +282,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
|
||||
} else if lang_items.discriminant_kind_trait() == Some(def_id) {
|
||||
// `DiscriminantKind` is automatically implemented for every type.
|
||||
candidates.vec.push(DiscriminantKindCandidate);
|
||||
candidates.vec.push(BuiltinCandidate { has_nested: false });
|
||||
} else if lang_items.pointee_trait() == Some(def_id) {
|
||||
// `Pointee` is automatically implemented for every type.
|
||||
candidates.vec.push(PointeeCandidate);
|
||||
candidates.vec.push(BuiltinCandidate { has_nested: false });
|
||||
} else if lang_items.sized_trait() == Some(def_id) {
|
||||
// Sized is never implementable by end-users, it is
|
||||
// always automatically computed.
|
||||
|
@ -22,12 +22,11 @@ use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for
|
||||
use crate::traits::{
|
||||
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
|
||||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||
ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
||||
ImplSourceFutureData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData,
|
||||
ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
|
||||
ObjectCastObligation, Obligation, ObligationCause, OutputTypeParameterMismatch,
|
||||
PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, TraitObligation,
|
||||
Unimplemented, VtblSegment,
|
||||
ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
|
||||
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
|
||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
|
||||
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
|
||||
SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment,
|
||||
};
|
||||
|
||||
use super::BuiltinImplConditions;
|
||||
@ -100,12 +99,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
ImplSource::FnPointer(data)
|
||||
}
|
||||
|
||||
DiscriminantKindCandidate => {
|
||||
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
|
||||
}
|
||||
|
||||
PointeeCandidate => ImplSource::Pointee(ImplSourcePointeeData),
|
||||
|
||||
TraitAliasCandidate => {
|
||||
let data = self.confirm_trait_alias_candidate(obligation);
|
||||
ImplSource::TraitAlias(data)
|
||||
|
@ -1569,20 +1569,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
(TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => false,
|
||||
|
||||
// (*)
|
||||
(
|
||||
BuiltinCandidate { has_nested: false }
|
||||
| DiscriminantKindCandidate
|
||||
| PointeeCandidate
|
||||
| ConstDestructCandidate(_),
|
||||
_,
|
||||
) => true,
|
||||
(
|
||||
_,
|
||||
BuiltinCandidate { has_nested: false }
|
||||
| DiscriminantKindCandidate
|
||||
| PointeeCandidate
|
||||
| ConstDestructCandidate(_),
|
||||
) => false,
|
||||
(BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => true,
|
||||
(_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => false,
|
||||
|
||||
(ParamCandidate(other), ParamCandidate(victim)) => {
|
||||
let same_except_bound_vars = other.skip_binder().trait_ref
|
||||
|
@ -270,8 +270,6 @@ fn resolve_associated_item<'tcx>(
|
||||
traits::ImplSource::AutoImpl(..)
|
||||
| traits::ImplSource::Param(..)
|
||||
| traits::ImplSource::TraitAlias(..)
|
||||
| traits::ImplSource::DiscriminantKind(..)
|
||||
| traits::ImplSource::Pointee(..)
|
||||
| traits::ImplSource::TraitUpcasting(_)
|
||||
| traits::ImplSource::ConstDestruct(_) => None,
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user