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.
|
/// Same as above, but for a function pointer type with the given signature.
|
||||||
FnPointer(ImplSourceFnPointerData<'tcx, N>),
|
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.
|
/// ImplSource automatically generated for a generator.
|
||||||
Generator(ImplSourceGeneratorData<'tcx, N>),
|
Generator(ImplSourceGeneratorData<'tcx, N>),
|
||||||
|
|
||||||
@ -682,8 +676,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
|||||||
ImplSource::Future(c) => c.nested,
|
ImplSource::Future(c) => c.nested,
|
||||||
ImplSource::Object(d) => d.nested,
|
ImplSource::Object(d) => d.nested,
|
||||||
ImplSource::FnPointer(d) => d.nested,
|
ImplSource::FnPointer(d) => d.nested,
|
||||||
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
|
|
||||||
| ImplSource::Pointee(ImplSourcePointeeData) => vec![],
|
|
||||||
ImplSource::TraitAlias(d) => d.nested,
|
ImplSource::TraitAlias(d) => d.nested,
|
||||||
ImplSource::TraitUpcasting(d) => d.nested,
|
ImplSource::TraitUpcasting(d) => d.nested,
|
||||||
ImplSource::ConstDestruct(i) => i.nested,
|
ImplSource::ConstDestruct(i) => i.nested,
|
||||||
@ -701,8 +693,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
|||||||
ImplSource::Future(c) => &c.nested,
|
ImplSource::Future(c) => &c.nested,
|
||||||
ImplSource::Object(d) => &d.nested,
|
ImplSource::Object(d) => &d.nested,
|
||||||
ImplSource::FnPointer(d) => &d.nested,
|
ImplSource::FnPointer(d) => &d.nested,
|
||||||
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
|
|
||||||
| ImplSource::Pointee(ImplSourcePointeeData) => &[],
|
|
||||||
ImplSource::TraitAlias(d) => &d.nested,
|
ImplSource::TraitAlias(d) => &d.nested,
|
||||||
ImplSource::TraitUpcasting(d) => &d.nested,
|
ImplSource::TraitUpcasting(d) => &d.nested,
|
||||||
ImplSource::ConstDestruct(i) => &i.nested,
|
ImplSource::ConstDestruct(i) => &i.nested,
|
||||||
@ -751,12 +741,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
|||||||
fn_ty: p.fn_ty,
|
fn_ty: p.fn_ty,
|
||||||
nested: p.nested.into_iter().map(f).collect(),
|
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 {
|
ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
|
||||||
alias_def_id: d.alias_def_id,
|
alias_def_id: d.alias_def_id,
|
||||||
substs: d.substs,
|
substs: d.substs,
|
||||||
@ -876,13 +860,6 @@ pub struct ImplSourceFnPointerData<'tcx, N> {
|
|||||||
pub nested: Vec<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(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||||
#[derive(TypeFoldable, TypeVisitable)]
|
#[derive(TypeFoldable, TypeVisitable)]
|
||||||
pub struct ImplSourceConstDestructData<N> {
|
pub struct ImplSourceConstDestructData<N> {
|
||||||
|
@ -105,6 +105,12 @@ pub type EvaluationCache<'tcx> = Cache<
|
|||||||
/// parameter environment.
|
/// parameter environment.
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, TypeFoldable, TypeVisitable)]
|
#[derive(PartialEq, Eq, Debug, Clone, TypeFoldable, TypeVisitable)]
|
||||||
pub enum SelectionCandidate<'tcx> {
|
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 {
|
BuiltinCandidate {
|
||||||
/// `false` if there are no *further* obligations.
|
/// `false` if there are no *further* obligations.
|
||||||
has_nested: bool,
|
has_nested: bool,
|
||||||
@ -141,12 +147,6 @@ pub enum SelectionCandidate<'tcx> {
|
|||||||
is_const: bool,
|
is_const: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Builtin implementation of `DiscriminantKind`.
|
|
||||||
DiscriminantKindCandidate,
|
|
||||||
|
|
||||||
/// Builtin implementation of `Pointee`.
|
|
||||||
PointeeCandidate,
|
|
||||||
|
|
||||||
TraitAliasCandidate,
|
TraitAliasCandidate,
|
||||||
|
|
||||||
/// Matching `dyn Trait` with a supertrait of `Trait`. The index is the
|
/// 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::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::Object(ref d) => write!(f, "{:?}", d),
|
||||||
|
|
||||||
super::ImplSource::Param(ref n, ct) => {
|
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)
|
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::SelectionContext;
|
||||||
use super::SelectionError;
|
use super::SelectionError;
|
||||||
use super::{
|
use super::{
|
||||||
ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData,
|
||||||
ImplSourceFutureData, ImplSourceGeneratorData, ImplSourcePointeeData,
|
|
||||||
ImplSourceUserDefinedData,
|
ImplSourceUserDefinedData,
|
||||||
};
|
};
|
||||||
use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
|
use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
|
||||||
@ -29,6 +28,7 @@ use rustc_hir::def::DefKind;
|
|||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
||||||
|
use rustc_infer::traits::ImplSourceBuiltinData;
|
||||||
use rustc_middle::traits::select::OverflowError;
|
use rustc_middle::traits::select::OverflowError;
|
||||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||||
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
|
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
|
||||||
@ -1598,128 +1598,126 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super::ImplSource::DiscriminantKind(..) => {
|
super::ImplSource::Builtin(..) => {
|
||||||
// While `DiscriminantKind` is automatically implemented for every type,
|
// While a builtin impl may be known to exist, the associated type may not yet
|
||||||
// the concrete discriminant may not be known yet.
|
// be known. Any type with multiple potential associated types is therefore
|
||||||
//
|
// not eligible.
|
||||||
// Any type with multiple potential discriminant types is therefore not eligible.
|
|
||||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||||
|
|
||||||
match self_ty.kind() {
|
let lang_items = selcx.tcx().lang_items();
|
||||||
ty::Bool
|
if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) {
|
||||||
| ty::Char
|
match self_ty.kind() {
|
||||||
| ty::Int(_)
|
ty::Bool
|
||||||
| ty::Uint(_)
|
| ty::Char
|
||||||
| ty::Float(_)
|
| ty::Int(_)
|
||||||
| ty::Adt(..)
|
| ty::Uint(_)
|
||||||
| ty::Foreign(_)
|
| ty::Float(_)
|
||||||
| ty::Str
|
| ty::Adt(..)
|
||||||
| ty::Array(..)
|
| ty::Foreign(_)
|
||||||
| ty::Slice(_)
|
| ty::Str
|
||||||
| ty::RawPtr(..)
|
| ty::Array(..)
|
||||||
| ty::Ref(..)
|
| ty::Slice(_)
|
||||||
| ty::FnDef(..)
|
| ty::RawPtr(..)
|
||||||
| ty::FnPtr(..)
|
| ty::Ref(..)
|
||||||
| ty::Dynamic(..)
|
| ty::FnDef(..)
|
||||||
| ty::Closure(..)
|
| ty::FnPtr(..)
|
||||||
| ty::Generator(..)
|
| ty::Dynamic(..)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::Closure(..)
|
||||||
| ty::Never
|
| ty::Generator(..)
|
||||||
| ty::Tuple(..)
|
| ty::GeneratorWitness(..)
|
||||||
// Integers and floats always have `u8` as their discriminant.
|
| ty::Never
|
||||||
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
|
| ty::Tuple(..)
|
||||||
|
// 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
|
||||||
| ty::Opaque(..)
|
// metadata if they're known (e.g. by the param_env) to be sized
|
||||||
| ty::Param(..)
|
ty::Param(_)
|
||||||
| ty::Bound(..)
|
| ty::Projection(..)
|
||||||
| ty::Placeholder(..)
|
| ty::Opaque(..)
|
||||||
| ty::Infer(..)
|
| ty::Bound(..)
|
||||||
| ty::Error(_) => false,
|
| 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());
|
|
||||||
|
|
||||||
let tail = selcx.tcx().struct_tail_with_normalize(
|
|
||||||
self_ty,
|
|
||||||
|ty| {
|
|
||||||
// We throw away any obligations we get from this, since we normalize
|
|
||||||
// and confirm these obligations once again during confirmation
|
|
||||||
normalize_with_depth(
|
|
||||||
selcx,
|
|
||||||
obligation.param_env,
|
|
||||||
obligation.cause.clone(),
|
|
||||||
obligation.recursion_depth + 1,
|
|
||||||
ty,
|
|
||||||
)
|
|
||||||
.value
|
|
||||||
},
|
|
||||||
|| {},
|
|
||||||
);
|
|
||||||
|
|
||||||
match tail.kind() {
|
|
||||||
ty::Bool
|
|
||||||
| ty::Char
|
|
||||||
| ty::Int(_)
|
|
||||||
| ty::Uint(_)
|
|
||||||
| ty::Float(_)
|
|
||||||
| ty::Str
|
|
||||||
| ty::Array(..)
|
|
||||||
| ty::Slice(_)
|
|
||||||
| ty::RawPtr(..)
|
|
||||||
| ty::Ref(..)
|
|
||||||
| ty::FnDef(..)
|
|
||||||
| ty::FnPtr(..)
|
|
||||||
| ty::Dynamic(..)
|
|
||||||
| ty::Closure(..)
|
|
||||||
| ty::Generator(..)
|
|
||||||
| ty::GeneratorWitness(..)
|
|
||||||
| ty::Never
|
|
||||||
// Extern types have unit metadata, according to RFC 2850
|
|
||||||
| ty::Foreign(_)
|
|
||||||
// If returned by `struct_tail_without_normalization` this is a unit struct
|
|
||||||
// without any fields, or not a struct, and therefore is Sized.
|
|
||||||
| ty::Adt(..)
|
|
||||||
// If returned by `struct_tail_without_normalization` this is the empty tuple.
|
|
||||||
| ty::Tuple(..)
|
|
||||||
// Integers and floats are always Sized, and so have unit type metadata.
|
|
||||||
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
|
|
||||||
|
|
||||||
// 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(..)
|
|
||||||
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],
|
|
||||||
))
|
|
||||||
.without_const(),
|
|
||||||
),
|
|
||||||
) =>
|
|
||||||
{
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
} else if lang_items.pointee_trait() == Some(poly_trait_ref.def_id()) {
|
||||||
|
let tail = selcx.tcx().struct_tail_with_normalize(
|
||||||
|
self_ty,
|
||||||
|
|ty| {
|
||||||
|
// We throw away any obligations we get from this, since we normalize
|
||||||
|
// and confirm these obligations once again during confirmation
|
||||||
|
normalize_with_depth(
|
||||||
|
selcx,
|
||||||
|
obligation.param_env,
|
||||||
|
obligation.cause.clone(),
|
||||||
|
obligation.recursion_depth + 1,
|
||||||
|
ty,
|
||||||
|
)
|
||||||
|
.value
|
||||||
|
},
|
||||||
|
|| {},
|
||||||
|
);
|
||||||
|
|
||||||
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
|
match tail.kind() {
|
||||||
ty::Param(_)
|
ty::Bool
|
||||||
| ty::Projection(..)
|
| ty::Char
|
||||||
| ty::Opaque(..)
|
| ty::Int(_)
|
||||||
| ty::Bound(..)
|
| ty::Uint(_)
|
||||||
| ty::Placeholder(..)
|
| ty::Float(_)
|
||||||
| ty::Infer(..)
|
| ty::Str
|
||||||
| ty::Error(_) => {
|
| ty::Array(..)
|
||||||
if tail.has_infer_types() {
|
| ty::Slice(_)
|
||||||
candidate_set.mark_ambiguous();
|
| ty::RawPtr(..)
|
||||||
|
| ty::Ref(..)
|
||||||
|
| ty::FnDef(..)
|
||||||
|
| ty::FnPtr(..)
|
||||||
|
| ty::Dynamic(..)
|
||||||
|
| ty::Closure(..)
|
||||||
|
| ty::Generator(..)
|
||||||
|
| ty::GeneratorWitness(..)
|
||||||
|
| ty::Never
|
||||||
|
// Extern types have unit metadata, according to RFC 2850
|
||||||
|
| ty::Foreign(_)
|
||||||
|
// If returned by `struct_tail_without_normalization` this is a unit struct
|
||||||
|
// without any fields, or not a struct, and therefore is Sized.
|
||||||
|
| ty::Adt(..)
|
||||||
|
// If returned by `struct_tail_without_normalization` this is the empty tuple.
|
||||||
|
| ty::Tuple(..)
|
||||||
|
// Integers and floats are always Sized, and so have unit type metadata.
|
||||||
|
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
|
||||||
|
|
||||||
|
// 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(..)
|
||||||
|
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]),
|
||||||
|
)
|
||||||
|
.without_const(),
|
||||||
|
),
|
||||||
|
) =>
|
||||||
|
{
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
|
||||||
|
ty::Param(_)
|
||||||
|
| ty::Projection(..)
|
||||||
|
| ty::Opaque(..)
|
||||||
|
| ty::Bound(..)
|
||||||
|
| ty::Placeholder(..)
|
||||||
|
| ty::Infer(..)
|
||||||
|
| ty::Error(_) => {
|
||||||
|
if tail.has_infer_types() {
|
||||||
|
candidate_set.mark_ambiguous();
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
bug!("unexpected builtin trait with associated type: {poly_trait_ref:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super::ImplSource::Param(..) => {
|
super::ImplSource::Param(..) => {
|
||||||
@ -1757,7 +1755,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
super::ImplSource::AutoImpl(..)
|
super::ImplSource::AutoImpl(..)
|
||||||
| super::ImplSource::Builtin(..)
|
|
||||||
| super::ImplSource::TraitUpcasting(_)
|
| super::ImplSource::TraitUpcasting(_)
|
||||||
| super::ImplSource::ConstDestruct(_) => {
|
| super::ImplSource::ConstDestruct(_) => {
|
||||||
// These traits have no associated types.
|
// 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::Future(data) => confirm_future_candidate(selcx, obligation, data),
|
||||||
super::ImplSource::Closure(data) => confirm_closure_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::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
|
||||||
super::ImplSource::DiscriminantKind(data) => {
|
super::ImplSource::Builtin(data) => confirm_builtin_candidate(selcx, obligation, data),
|
||||||
confirm_discriminant_kind_candidate(selcx, obligation, data)
|
|
||||||
}
|
|
||||||
super::ImplSource::Pointee(data) => confirm_pointee_candidate(selcx, obligation, data),
|
|
||||||
super::ImplSource::Object(_)
|
super::ImplSource::Object(_)
|
||||||
| super::ImplSource::AutoImpl(..)
|
| super::ImplSource::AutoImpl(..)
|
||||||
| super::ImplSource::Param(..)
|
| super::ImplSource::Param(..)
|
||||||
| super::ImplSource::Builtin(..)
|
|
||||||
| super::ImplSource::TraitUpcasting(_)
|
| super::ImplSource::TraitUpcasting(_)
|
||||||
| super::ImplSource::TraitAlias(..)
|
| super::ImplSource::TraitAlias(..)
|
||||||
| super::ImplSource::ConstDestruct(_) => {
|
| super::ImplSource::ConstDestruct(_) => {
|
||||||
@ -1950,68 +1943,55 @@ fn confirm_future_candidate<'cx, 'tcx>(
|
|||||||
.with_addl_obligations(obligations)
|
.with_addl_obligations(obligations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
|
fn confirm_builtin_candidate<'cx, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
_: ImplSourceDiscriminantKindData,
|
data: ImplSourceBuiltinData<PredicateObligation<'tcx>>,
|
||||||
) -> Progress<'tcx> {
|
) -> Progress<'tcx> {
|
||||||
let tcx = selcx.tcx();
|
let tcx = selcx.tcx();
|
||||||
|
let self_ty = obligation.predicate.self_ty();
|
||||||
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 substs = tcx.mk_substs([self_ty.into()].iter());
|
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 discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
|
(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);
|
||||||
|
|
||||||
let predicate = ty::ProjectionPredicate {
|
let mut obligations = Vec::new();
|
||||||
projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
|
let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
|
||||||
term: self_ty.discriminant_ty(tcx).into(),
|
normalize_with_depth_to(
|
||||||
|
selcx,
|
||||||
|
obligation.param_env,
|
||||||
|
obligation.cause.clone(),
|
||||||
|
obligation.recursion_depth + 1,
|
||||||
|
ty,
|
||||||
|
&mut obligations,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
if check_is_sized {
|
||||||
|
let sized_predicate = ty::Binder::dummy(
|
||||||
|
tcx.at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]),
|
||||||
|
)
|
||||||
|
.without_const();
|
||||||
|
obligations.push(obligation.with(tcx, sized_predicate));
|
||||||
|
}
|
||||||
|
(metadata_ty.into(), obligations)
|
||||||
|
} else {
|
||||||
|
bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
|
||||||
};
|
};
|
||||||
|
|
||||||
// We get here from `poly_project_and_unify_type` which replaces bound vars
|
let predicate =
|
||||||
// with placeholders, so dummy is okay here.
|
ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id }, term };
|
||||||
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 (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
|
|
||||||
normalize_with_depth_to(
|
|
||||||
selcx,
|
|
||||||
obligation.param_env,
|
|
||||||
obligation.cause.clone(),
|
|
||||||
obligation.recursion_depth + 1,
|
|
||||||
ty,
|
|
||||||
&mut obligations,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
if check_is_sized {
|
|
||||||
let sized_predicate = ty::Binder::dummy(
|
|
||||||
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(),
|
|
||||||
};
|
|
||||||
|
|
||||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
||||||
.with_addl_obligations(obligations)
|
.with_addl_obligations(obligations)
|
||||||
|
.with_addl_obligations(data.nested)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
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);
|
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
|
||||||
} else if lang_items.discriminant_kind_trait() == Some(def_id) {
|
} else if lang_items.discriminant_kind_trait() == Some(def_id) {
|
||||||
// `DiscriminantKind` is automatically implemented for every type.
|
// `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) {
|
} else if lang_items.pointee_trait() == Some(def_id) {
|
||||||
// `Pointee` is automatically implemented for every type.
|
// `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) {
|
} else if lang_items.sized_trait() == Some(def_id) {
|
||||||
// Sized is never implementable by end-users, it is
|
// Sized is never implementable by end-users, it is
|
||||||
// always automatically computed.
|
// always automatically computed.
|
||||||
|
@ -22,12 +22,11 @@ use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for
|
|||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
|
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
|
||||||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||||
ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
|
||||||
ImplSourceFutureData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData,
|
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
|
||||||
ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
|
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
|
||||||
ObjectCastObligation, Obligation, ObligationCause, OutputTypeParameterMismatch,
|
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
|
||||||
PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, TraitObligation,
|
SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment,
|
||||||
Unimplemented, VtblSegment,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::BuiltinImplConditions;
|
use super::BuiltinImplConditions;
|
||||||
@ -100,12 +99,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
ImplSource::FnPointer(data)
|
ImplSource::FnPointer(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscriminantKindCandidate => {
|
|
||||||
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
|
|
||||||
}
|
|
||||||
|
|
||||||
PointeeCandidate => ImplSource::Pointee(ImplSourcePointeeData),
|
|
||||||
|
|
||||||
TraitAliasCandidate => {
|
TraitAliasCandidate => {
|
||||||
let data = self.confirm_trait_alias_candidate(obligation);
|
let data = self.confirm_trait_alias_candidate(obligation);
|
||||||
ImplSource::TraitAlias(data)
|
ImplSource::TraitAlias(data)
|
||||||
|
@ -1569,20 +1569,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
(TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => false,
|
(TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => false,
|
||||||
|
|
||||||
// (*)
|
// (*)
|
||||||
(
|
(BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => true,
|
||||||
BuiltinCandidate { has_nested: false }
|
(_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => false,
|
||||||
| DiscriminantKindCandidate
|
|
||||||
| PointeeCandidate
|
|
||||||
| ConstDestructCandidate(_),
|
|
||||||
_,
|
|
||||||
) => true,
|
|
||||||
(
|
|
||||||
_,
|
|
||||||
BuiltinCandidate { has_nested: false }
|
|
||||||
| DiscriminantKindCandidate
|
|
||||||
| PointeeCandidate
|
|
||||||
| ConstDestructCandidate(_),
|
|
||||||
) => false,
|
|
||||||
|
|
||||||
(ParamCandidate(other), ParamCandidate(victim)) => {
|
(ParamCandidate(other), ParamCandidate(victim)) => {
|
||||||
let same_except_bound_vars = other.skip_binder().trait_ref
|
let same_except_bound_vars = other.skip_binder().trait_ref
|
||||||
|
@ -270,8 +270,6 @@ fn resolve_associated_item<'tcx>(
|
|||||||
traits::ImplSource::AutoImpl(..)
|
traits::ImplSource::AutoImpl(..)
|
||||||
| traits::ImplSource::Param(..)
|
| traits::ImplSource::Param(..)
|
||||||
| traits::ImplSource::TraitAlias(..)
|
| traits::ImplSource::TraitAlias(..)
|
||||||
| traits::ImplSource::DiscriminantKind(..)
|
|
||||||
| traits::ImplSource::Pointee(..)
|
|
||||||
| traits::ImplSource::TraitUpcasting(_)
|
| traits::ImplSource::TraitUpcasting(_)
|
||||||
| traits::ImplSource::ConstDestruct(_) => None,
|
| traits::ImplSource::ConstDestruct(_) => None,
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user