mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 09:14:20 +00:00
Auto merge of #112687 - compiler-errors:simplify-impl-source, r=lcnr
Simplify `ImplSource` candidates a bit Reduce the number of impl source candidates, which will hopefully make our life easier when trying to adapt things like `SelectionContext::select` and `codegen_select_candidate` for the new solver. r? `@lcnr` but feel free to reassign
This commit is contained in:
commit
f90d57d06e
@ -781,8 +781,17 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
);
|
||||
return;
|
||||
}
|
||||
Ok(Some(ImplSource::Closure(data))) => {
|
||||
if !tcx.is_const_fn_raw(data.closure_def_id) {
|
||||
// Closure: Fn{Once|Mut}
|
||||
Ok(Some(ImplSource::Builtin(_)))
|
||||
if poly_trait_pred.self_ty().skip_binder().is_closure()
|
||||
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
|
||||
{
|
||||
let ty::Closure(closure_def_id, substs) =
|
||||
*poly_trait_pred.self_ty().no_bound_vars().unwrap().kind()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
if !tcx.is_const_fn_raw(closure_def_id) {
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
|
@ -172,7 +172,7 @@ impl Qualif for NeedsNonConstDrop {
|
||||
|
||||
if !matches!(
|
||||
impl_src,
|
||||
ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
|
||||
ImplSource::Builtin(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
|
||||
) {
|
||||
// If our const destruct candidate is not ConstDestruct or implied by the param env,
|
||||
// then it's bad
|
||||
|
@ -646,12 +646,6 @@ pub enum ImplSource<'tcx, N> {
|
||||
/// ImplSource identifying a particular impl.
|
||||
UserDefined(ImplSourceUserDefinedData<'tcx, N>),
|
||||
|
||||
/// ImplSource for auto trait implementations.
|
||||
/// This carries the information and nested obligations with regards
|
||||
/// to an auto implementation for a trait `Trait`. The nested obligations
|
||||
/// ensure the trait implementation holds for all the constituent types.
|
||||
AutoImpl(ImplSourceAutoImplData<N>),
|
||||
|
||||
/// Successful resolution to an obligation provided by the caller
|
||||
/// for some type parameter. The `Vec<N>` represents the
|
||||
/// obligations incurred from normalizing the where-clause (if
|
||||
@ -659,84 +653,46 @@ pub enum ImplSource<'tcx, N> {
|
||||
Param(Vec<N>, ty::BoundConstness),
|
||||
|
||||
/// Virtual calls through an object.
|
||||
Object(ImplSourceObjectData<'tcx, N>),
|
||||
Object(ImplSourceObjectData<N>),
|
||||
|
||||
/// Successful resolution for a builtin trait.
|
||||
Builtin(ImplSourceBuiltinData<N>),
|
||||
Builtin(Vec<N>),
|
||||
|
||||
/// ImplSource for trait upcasting coercion
|
||||
TraitUpcasting(ImplSourceTraitUpcastingData<'tcx, N>),
|
||||
|
||||
/// ImplSource automatically generated for a closure. The `DefId` is the ID
|
||||
/// of the closure expression. This is an `ImplSource::UserDefined` in spirit, but the
|
||||
/// impl is generated by the compiler and does not appear in the source.
|
||||
Closure(ImplSourceClosureData<'tcx, N>),
|
||||
|
||||
/// Same as above, but for a function pointer type with the given signature.
|
||||
FnPointer(ImplSourceFnPointerData<'tcx, N>),
|
||||
|
||||
/// ImplSource automatically generated for a generator.
|
||||
Generator(ImplSourceGeneratorData<'tcx, N>),
|
||||
|
||||
/// ImplSource automatically generated for a generator backing an async future.
|
||||
Future(ImplSourceFutureData<'tcx, N>),
|
||||
TraitUpcasting(ImplSourceTraitUpcastingData<N>),
|
||||
|
||||
/// ImplSource for a trait alias.
|
||||
TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
|
||||
|
||||
/// ImplSource for a `const Drop` implementation.
|
||||
ConstDestruct(ImplSourceConstDestructData<N>),
|
||||
}
|
||||
|
||||
impl<'tcx, N> ImplSource<'tcx, N> {
|
||||
pub fn nested_obligations(self) -> Vec<N> {
|
||||
match self {
|
||||
ImplSource::UserDefined(i) => i.nested,
|
||||
ImplSource::Param(n, _) => n,
|
||||
ImplSource::Builtin(i) => i.nested,
|
||||
ImplSource::AutoImpl(d) => d.nested,
|
||||
ImplSource::Closure(c) => c.nested,
|
||||
ImplSource::Generator(c) => c.nested,
|
||||
ImplSource::Future(c) => c.nested,
|
||||
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
|
||||
ImplSource::Object(d) => d.nested,
|
||||
ImplSource::FnPointer(d) => d.nested,
|
||||
ImplSource::TraitAlias(d) => d.nested,
|
||||
ImplSource::TraitUpcasting(d) => d.nested,
|
||||
ImplSource::ConstDestruct(i) => i.nested,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow_nested_obligations(&self) -> &[N] {
|
||||
match self {
|
||||
ImplSource::UserDefined(i) => &i.nested,
|
||||
ImplSource::Param(n, _) => n,
|
||||
ImplSource::Builtin(i) => &i.nested,
|
||||
ImplSource::AutoImpl(d) => &d.nested,
|
||||
ImplSource::Closure(c) => &c.nested,
|
||||
ImplSource::Generator(c) => &c.nested,
|
||||
ImplSource::Future(c) => &c.nested,
|
||||
ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n,
|
||||
ImplSource::Object(d) => &d.nested,
|
||||
ImplSource::FnPointer(d) => &d.nested,
|
||||
ImplSource::TraitAlias(d) => &d.nested,
|
||||
ImplSource::TraitUpcasting(d) => &d.nested,
|
||||
ImplSource::ConstDestruct(i) => &i.nested,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
|
||||
match self {
|
||||
ImplSource::UserDefined(i) => &mut i.nested,
|
||||
ImplSource::Param(n, _) => n,
|
||||
ImplSource::Builtin(i) => &mut i.nested,
|
||||
ImplSource::AutoImpl(d) => &mut d.nested,
|
||||
ImplSource::Closure(c) => &mut c.nested,
|
||||
ImplSource::Generator(c) => &mut c.nested,
|
||||
ImplSource::Future(c) => &mut c.nested,
|
||||
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
|
||||
ImplSource::Object(d) => &mut d.nested,
|
||||
ImplSource::FnPointer(d) => &mut d.nested,
|
||||
ImplSource::TraitAlias(d) => &mut d.nested,
|
||||
ImplSource::TraitUpcasting(d) => &mut d.nested,
|
||||
ImplSource::ConstDestruct(i) => &mut i.nested,
|
||||
}
|
||||
}
|
||||
|
||||
@ -751,37 +707,12 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
||||
nested: i.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
|
||||
ImplSource::Builtin(i) => ImplSource::Builtin(ImplSourceBuiltinData {
|
||||
nested: i.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()),
|
||||
ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
|
||||
upcast_trait_ref: o.upcast_trait_ref,
|
||||
upcast_trait_def_id: o.upcast_trait_def_id,
|
||||
vtable_base: o.vtable_base,
|
||||
nested: o.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::AutoImpl(d) => ImplSource::AutoImpl(ImplSourceAutoImplData {
|
||||
trait_def_id: d.trait_def_id,
|
||||
nested: d.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::Closure(c) => ImplSource::Closure(ImplSourceClosureData {
|
||||
closure_def_id: c.closure_def_id,
|
||||
substs: c.substs,
|
||||
nested: c.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::Generator(c) => ImplSource::Generator(ImplSourceGeneratorData {
|
||||
generator_def_id: c.generator_def_id,
|
||||
substs: c.substs,
|
||||
nested: c.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::Future(c) => ImplSource::Future(ImplSourceFutureData {
|
||||
generator_def_id: c.generator_def_id,
|
||||
substs: c.substs,
|
||||
nested: c.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::FnPointer(p) => ImplSource::FnPointer(ImplSourceFnPointerData {
|
||||
fn_ty: p.fn_ty,
|
||||
nested: p.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
|
||||
alias_def_id: d.alias_def_id,
|
||||
substs: d.substs,
|
||||
@ -789,16 +720,10 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
||||
}),
|
||||
ImplSource::TraitUpcasting(d) => {
|
||||
ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData {
|
||||
upcast_trait_ref: d.upcast_trait_ref,
|
||||
vtable_vptr_slot: d.vtable_vptr_slot,
|
||||
nested: d.nested.into_iter().map(f).collect(),
|
||||
})
|
||||
}
|
||||
ImplSource::ConstDestruct(i) => {
|
||||
ImplSource::ConstDestruct(ImplSourceConstDestructData {
|
||||
nested: i.nested.into_iter().map(f).collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -823,47 +748,7 @@ pub struct ImplSourceUserDefinedData<'tcx, N> {
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceGeneratorData<'tcx, N> {
|
||||
pub generator_def_id: DefId,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
/// Nested obligations. This can be non-empty if the generator
|
||||
/// signature contains associated types.
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceFutureData<'tcx, N> {
|
||||
pub generator_def_id: DefId,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
/// Nested obligations. This can be non-empty if the generator
|
||||
/// signature contains associated types.
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceClosureData<'tcx, N> {
|
||||
pub closure_def_id: DefId,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
/// Nested obligations. This can be non-empty if the closure
|
||||
/// signature contains associated types.
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceAutoImplData<N> {
|
||||
pub trait_def_id: DefId,
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceTraitUpcastingData<'tcx, N> {
|
||||
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
|
||||
pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
|
||||
pub struct ImplSourceTraitUpcastingData<N> {
|
||||
/// The vtable is formed by concatenating together the method lists of
|
||||
/// the base object trait and all supertraits, pointers to supertrait vtable will
|
||||
/// be provided when necessary; this is the position of `upcast_trait_ref`'s vtable
|
||||
@ -873,17 +758,11 @@ pub struct ImplSourceTraitUpcastingData<'tcx, N> {
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceBuiltinData<N> {
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceObjectData<'tcx, N> {
|
||||
pub struct ImplSourceObjectData<N> {
|
||||
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
|
||||
pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
pub upcast_trait_def_id: DefId,
|
||||
|
||||
/// The vtable is formed by concatenating together the method lists of
|
||||
/// the base object trait and all supertraits, pointers to supertrait vtable will
|
||||
@ -894,19 +773,6 @@ pub struct ImplSourceObjectData<'tcx, N> {
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceFnPointerData<'tcx, N> {
|
||||
pub fn_ty: Ty<'tcx>,
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceConstDestructData<N> {
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct ImplSourceTraitAliasData<'tcx, N> {
|
||||
|
@ -9,15 +9,7 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
|
||||
match *self {
|
||||
super::ImplSource::UserDefined(ref v) => write!(f, "{:?}", v),
|
||||
|
||||
super::ImplSource::AutoImpl(ref t) => write!(f, "{:?}", t),
|
||||
|
||||
super::ImplSource::Closure(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::Generator(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::Future(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d),
|
||||
super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
@ -25,13 +17,9 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
|
||||
write!(f, "ImplSourceParamData({:?}, {:?})", n, ct)
|
||||
}
|
||||
|
||||
super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::TraitAlias(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::ConstDestruct(ref d) => write!(f, "{:?}", d),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,78 +34,26 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceUserDefinedData<'tcx,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceGeneratorData<'tcx, N> {
|
||||
impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitUpcastingData<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"ImplSourceGeneratorData(generator_def_id={:?}, substs={:?}, nested={:?})",
|
||||
self.generator_def_id, self.substs, self.nested
|
||||
"ImplSourceTraitUpcastingData(vtable_vptr_slot={:?}, nested={:?})",
|
||||
self.vtable_vptr_slot, self.nested
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceFutureData<'tcx, N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"ImplSourceFutureData(generator_def_id={:?}, substs={:?}, nested={:?})",
|
||||
self.generator_def_id, self.substs, self.nested
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceClosureData<'tcx, N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"ImplSourceClosureData(closure_def_id={:?}, substs={:?}, nested={:?})",
|
||||
self.closure_def_id, self.substs, self.nested
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceBuiltinData<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "ImplSourceBuiltinData(nested={:?})", self.nested)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitUpcastingData<'tcx, N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"ImplSourceTraitUpcastingData(upcast={:?}, vtable_vptr_slot={:?}, nested={:?})",
|
||||
self.upcast_trait_ref, self.vtable_vptr_slot, self.nested
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceAutoImplData<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"ImplSourceAutoImplData(trait_def_id={:?}, nested={:?})",
|
||||
self.trait_def_id, self.nested
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<'tcx, N> {
|
||||
impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"ImplSourceObjectData(upcast={:?}, vtable_base={}, nested={:?})",
|
||||
self.upcast_trait_ref, self.vtable_base, self.nested
|
||||
self.upcast_trait_def_id, self.vtable_base, self.nested
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceFnPointerData<'tcx, N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "ImplSourceFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx, N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
@ -127,9 +63,3 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceConstDestructData<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "ImplSourceConstDestructData(nested={:?})", self.nested)
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
use super::specialization_graph;
|
||||
use super::translate_substs;
|
||||
use super::util;
|
||||
use super::ImplSourceUserDefinedData;
|
||||
use super::MismatchedProjectionTypes;
|
||||
use super::Obligation;
|
||||
use super::ObligationCause;
|
||||
@ -10,10 +11,6 @@ use super::PredicateObligation;
|
||||
use super::Selection;
|
||||
use super::SelectionContext;
|
||||
use super::SelectionError;
|
||||
use super::{
|
||||
ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData,
|
||||
ImplSourceUserDefinedData,
|
||||
};
|
||||
use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
|
||||
|
||||
use crate::errors::InherentProjectionNormalizationOverflow;
|
||||
@ -30,7 +27,6 @@ use rustc_hir::lang_items::LangItem;
|
||||
use rustc_infer::infer::at::At;
|
||||
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::traits::ImplSourceBuiltinData;
|
||||
use rustc_infer::traits::ObligationCauseCode;
|
||||
use rustc_middle::traits::select::OverflowError;
|
||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
@ -1721,11 +1717,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
};
|
||||
|
||||
let eligible = match &impl_source {
|
||||
super::ImplSource::Closure(_)
|
||||
| super::ImplSource::Generator(_)
|
||||
| super::ImplSource::Future(_)
|
||||
| super::ImplSource::FnPointer(_)
|
||||
| super::ImplSource::TraitAlias(_) => true,
|
||||
super::ImplSource::TraitAlias(_) => true,
|
||||
super::ImplSource::UserDefined(impl_data) => {
|
||||
// We have to be careful when projecting out of an
|
||||
// impl because of specialization. If we are not in
|
||||
@ -1783,7 +1775,11 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
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()) {
|
||||
if [lang_items.gen_trait(), lang_items.future_trait()].contains(&Some(poly_trait_ref.def_id()))
|
||||
|| selcx.tcx().fn_trait_kind_from_def_id(poly_trait_ref.def_id()).is_some()
|
||||
{
|
||||
true
|
||||
} else if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) {
|
||||
match self_ty.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
@ -1930,9 +1926,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
// why we special case object types.
|
||||
false
|
||||
}
|
||||
super::ImplSource::AutoImpl(..)
|
||||
| super::ImplSource::TraitUpcasting(_)
|
||||
| super::ImplSource::ConstDestruct(_) => {
|
||||
| super::ImplSource::TraitUpcasting(_) => {
|
||||
// These traits have no associated types.
|
||||
selcx.tcx().sess.delay_span_bug(
|
||||
obligation.cause.span,
|
||||
@ -1996,17 +1990,27 @@ fn confirm_select_candidate<'cx, 'tcx>(
|
||||
) -> Progress<'tcx> {
|
||||
match impl_source {
|
||||
super::ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
|
||||
super::ImplSource::Generator(data) => confirm_generator_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::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
|
||||
super::ImplSource::Builtin(data) => confirm_builtin_candidate(selcx, obligation, data),
|
||||
super::ImplSource::Builtin(data) => {
|
||||
let trait_def_id = obligation.predicate.trait_def_id(selcx.tcx());
|
||||
let lang_items = selcx.tcx().lang_items();
|
||||
if lang_items.gen_trait() == Some(trait_def_id) {
|
||||
confirm_generator_candidate(selcx, obligation, data)
|
||||
} else if lang_items.future_trait() == Some(trait_def_id) {
|
||||
confirm_future_candidate(selcx, obligation, data)
|
||||
} else if selcx.tcx().fn_trait_kind_from_def_id(trait_def_id).is_some() {
|
||||
if obligation.predicate.self_ty().is_closure() {
|
||||
confirm_closure_candidate(selcx, obligation, data)
|
||||
} else {
|
||||
confirm_fn_pointer_candidate(selcx, obligation, data)
|
||||
}
|
||||
} else {
|
||||
confirm_builtin_candidate(selcx, obligation, data)
|
||||
}
|
||||
}
|
||||
super::ImplSource::Object(_)
|
||||
| super::ImplSource::AutoImpl(..)
|
||||
| super::ImplSource::Param(..)
|
||||
| super::ImplSource::TraitUpcasting(_)
|
||||
| super::ImplSource::TraitAlias(..)
|
||||
| super::ImplSource::ConstDestruct(_) => {
|
||||
| super::ImplSource::TraitAlias(..) => {
|
||||
// we don't create Select candidates with this kind of resolution
|
||||
span_bug!(
|
||||
obligation.cause.span,
|
||||
@ -2020,9 +2024,14 @@ fn confirm_select_candidate<'cx, 'tcx>(
|
||||
fn confirm_generator_candidate<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
impl_source: ImplSourceGeneratorData<'tcx, PredicateObligation<'tcx>>,
|
||||
nested: Vec<PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let gen_sig = impl_source.substs.as_generator().poly_sig();
|
||||
let ty::Generator(_, substs, _) =
|
||||
selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
let gen_sig = substs.as_generator().poly_sig();
|
||||
let Normalized { value: gen_sig, obligations } = normalize_with_depth(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
@ -2060,16 +2069,21 @@ fn confirm_generator_candidate<'cx, 'tcx>(
|
||||
});
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, predicate, false)
|
||||
.with_addl_obligations(impl_source.nested)
|
||||
.with_addl_obligations(nested)
|
||||
.with_addl_obligations(obligations)
|
||||
}
|
||||
|
||||
fn confirm_future_candidate<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
impl_source: ImplSourceFutureData<'tcx, PredicateObligation<'tcx>>,
|
||||
nested: Vec<PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let gen_sig = impl_source.substs.as_generator().poly_sig();
|
||||
let ty::Generator(_, substs, _) =
|
||||
selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
let gen_sig = substs.as_generator().poly_sig();
|
||||
let Normalized { value: gen_sig, obligations } = normalize_with_depth(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
@ -2099,14 +2113,14 @@ fn confirm_future_candidate<'cx, 'tcx>(
|
||||
});
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, predicate, false)
|
||||
.with_addl_obligations(impl_source.nested)
|
||||
.with_addl_obligations(nested)
|
||||
.with_addl_obligations(obligations)
|
||||
}
|
||||
|
||||
fn confirm_builtin_candidate<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
data: ImplSourceBuiltinData<PredicateObligation<'tcx>>,
|
||||
data: Vec<PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let tcx = selcx.tcx();
|
||||
let self_ty = obligation.predicate.self_ty();
|
||||
@ -2154,15 +2168,15 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
||||
.with_addl_obligations(obligations)
|
||||
.with_addl_obligations(data.nested)
|
||||
.with_addl_obligations(data)
|
||||
}
|
||||
|
||||
fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
fn_pointer_impl_source: ImplSourceFnPointerData<'tcx, PredicateObligation<'tcx>>,
|
||||
nested: Vec<PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let fn_type = selcx.infcx.shallow_resolve(fn_pointer_impl_source.fn_ty);
|
||||
let fn_type = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
|
||||
let sig = fn_type.fn_sig(selcx.tcx());
|
||||
let Normalized { value: sig, obligations } = normalize_with_depth(
|
||||
selcx,
|
||||
@ -2173,16 +2187,21 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
||||
);
|
||||
|
||||
confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
|
||||
.with_addl_obligations(fn_pointer_impl_source.nested)
|
||||
.with_addl_obligations(nested)
|
||||
.with_addl_obligations(obligations)
|
||||
}
|
||||
|
||||
fn confirm_closure_candidate<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
impl_source: ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>,
|
||||
nested: Vec<PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let closure_sig = impl_source.substs.as_closure().sig();
|
||||
let ty::Closure(_, substs) =
|
||||
selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
let closure_sig = substs.as_closure().sig();
|
||||
let Normalized { value: closure_sig, obligations } = normalize_with_depth(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
@ -2194,7 +2213,7 @@ fn confirm_closure_candidate<'cx, 'tcx>(
|
||||
debug!(?obligation, ?closure_sig, ?obligations, "confirm_closure_candidate");
|
||||
|
||||
confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No)
|
||||
.with_addl_obligations(impl_source.nested)
|
||||
.with_addl_obligations(nested)
|
||||
.with_addl_obligations(obligations)
|
||||
}
|
||||
|
||||
|
@ -27,11 +27,9 @@ use crate::traits::vtable::{
|
||||
};
|
||||
use crate::traits::{
|
||||
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
|
||||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||
ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
|
||||
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
|
||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation,
|
||||
ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
|
||||
ImplSourceObjectData, ImplSourceTraitAliasData, ImplSourceTraitUpcastingData,
|
||||
ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause,
|
||||
OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
|
||||
TraitNotObjectSafe, TraitObligation, Unimplemented,
|
||||
};
|
||||
|
||||
@ -72,7 +70,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
AutoImplCandidate => {
|
||||
let data = self.confirm_auto_impl_candidate(obligation);
|
||||
ImplSource::AutoImpl(data)
|
||||
ImplSource::Builtin(data)
|
||||
}
|
||||
|
||||
ProjectionCandidate(idx, constness) => {
|
||||
@ -87,22 +85,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
ClosureCandidate { .. } => {
|
||||
let vtable_closure = self.confirm_closure_candidate(obligation)?;
|
||||
ImplSource::Closure(vtable_closure)
|
||||
ImplSource::Builtin(vtable_closure)
|
||||
}
|
||||
|
||||
GeneratorCandidate => {
|
||||
let vtable_generator = self.confirm_generator_candidate(obligation)?;
|
||||
ImplSource::Generator(vtable_generator)
|
||||
ImplSource::Builtin(vtable_generator)
|
||||
}
|
||||
|
||||
FutureCandidate => {
|
||||
let vtable_future = self.confirm_future_candidate(obligation)?;
|
||||
ImplSource::Future(vtable_future)
|
||||
ImplSource::Builtin(vtable_future)
|
||||
}
|
||||
|
||||
FnPointerCandidate { is_const } => {
|
||||
let data = self.confirm_fn_pointer_candidate(obligation, is_const)?;
|
||||
ImplSource::FnPointer(data)
|
||||
ImplSource::Builtin(data)
|
||||
}
|
||||
|
||||
TraitAliasCandidate => {
|
||||
@ -114,7 +112,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// This indicates something like `Trait + Send: Send`. In this case, we know that
|
||||
// this holds because that's what the object type is telling us, and there's really
|
||||
// no additional obligations to prove and no types in particular to unify, etc.
|
||||
ImplSource::Param(Vec::new(), ty::BoundConstness::NotConst)
|
||||
ImplSource::Builtin(Vec::new())
|
||||
}
|
||||
|
||||
BuiltinUnsizeCandidate => {
|
||||
@ -129,7 +127,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
ConstDestructCandidate(def_id) => {
|
||||
let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
|
||||
ImplSource::ConstDestruct(data)
|
||||
ImplSource::Builtin(data)
|
||||
}
|
||||
};
|
||||
|
||||
@ -244,7 +242,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
has_nested: bool,
|
||||
) -> ImplSourceBuiltinData<PredicateObligation<'tcx>> {
|
||||
) -> Vec<PredicateObligation<'tcx>> {
|
||||
debug!(?obligation, ?has_nested, "confirm_builtin_candidate");
|
||||
|
||||
let lang_items = self.tcx().lang_items();
|
||||
@ -277,14 +275,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
debug!(?obligations);
|
||||
|
||||
ImplSourceBuiltinData { nested: obligations }
|
||||
obligations
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn confirm_transmutability_candidate(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> Result<ImplSourceBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
use rustc_transmute::{Answer, Condition};
|
||||
#[instrument(level = "debug", skip(tcx, obligation, predicate))]
|
||||
fn flatten_answer_tree<'tcx>(
|
||||
@ -369,7 +367,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
};
|
||||
|
||||
debug!(?fully_flattened);
|
||||
Ok(ImplSourceBuiltinData { nested: fully_flattened })
|
||||
Ok(fully_flattened)
|
||||
}
|
||||
|
||||
/// This handles the case where an `auto trait Foo` impl is being used.
|
||||
@ -380,7 +378,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
fn confirm_auto_impl_candidate(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> ImplSourceAutoImplData<PredicateObligation<'tcx>> {
|
||||
) -> Vec<PredicateObligation<'tcx>> {
|
||||
debug!(?obligation, "confirm_auto_impl_candidate");
|
||||
|
||||
let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty());
|
||||
@ -394,7 +392,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
|
||||
) -> ImplSourceAutoImplData<PredicateObligation<'tcx>> {
|
||||
) -> Vec<PredicateObligation<'tcx>> {
|
||||
debug!(?nested, "vtable_auto_impl");
|
||||
ensure_sufficient_stack(|| {
|
||||
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
||||
@ -424,7 +422,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
debug!(?obligations, "vtable_auto_impl");
|
||||
|
||||
ImplSourceAutoImplData { trait_def_id, nested: obligations }
|
||||
obligations
|
||||
})
|
||||
}
|
||||
|
||||
@ -487,7 +485,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
index: usize,
|
||||
) -> Result<ImplSourceObjectData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
) -> Result<ImplSourceObjectData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
let tcx = self.tcx();
|
||||
debug!(?obligation, ?index, "confirm_object_candidate");
|
||||
|
||||
@ -654,15 +652,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
(unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)),
|
||||
);
|
||||
|
||||
Ok(ImplSourceObjectData { upcast_trait_ref, vtable_base, nested })
|
||||
Ok(ImplSourceObjectData {
|
||||
upcast_trait_def_id: upcast_trait_ref.def_id(),
|
||||
vtable_base,
|
||||
nested,
|
||||
})
|
||||
}
|
||||
|
||||
fn confirm_fn_pointer_candidate(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
is_const: bool,
|
||||
) -> Result<ImplSourceFnPointerData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
|
||||
{
|
||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
debug!(?obligation, "confirm_fn_pointer_candidate");
|
||||
|
||||
let tcx = self.tcx();
|
||||
@ -714,7 +715,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let tr = ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [output_ty]);
|
||||
nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
|
||||
|
||||
Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested })
|
||||
Ok(nested)
|
||||
}
|
||||
|
||||
fn confirm_trait_alias_candidate(
|
||||
@ -746,8 +747,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
fn confirm_generator_candidate(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> Result<ImplSourceGeneratorData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
|
||||
{
|
||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
// Okay to skip binder because the substs on generator types never
|
||||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters.
|
||||
@ -780,13 +780,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
|
||||
debug!(?trait_ref, ?nested, "generator candidate obligations");
|
||||
|
||||
Ok(ImplSourceGeneratorData { generator_def_id, substs, nested })
|
||||
Ok(nested)
|
||||
}
|
||||
|
||||
fn confirm_future_candidate(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> Result<ImplSourceFutureData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
// Okay to skip binder because the substs on generator types never
|
||||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters.
|
||||
@ -810,14 +810,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
|
||||
debug!(?trait_ref, ?nested, "future candidate obligations");
|
||||
|
||||
Ok(ImplSourceFutureData { generator_def_id, substs, nested })
|
||||
Ok(nested)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn confirm_closure_candidate(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> Result<ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
let kind = self
|
||||
.tcx()
|
||||
.fn_trait_kind_from_def_id(obligation.predicate.def_id())
|
||||
@ -844,7 +844,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
));
|
||||
}
|
||||
|
||||
Ok(ImplSourceClosureData { closure_def_id, substs, nested })
|
||||
Ok(nested)
|
||||
}
|
||||
|
||||
/// In the case of closure types and fn pointers,
|
||||
@ -912,8 +912,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
idx: usize,
|
||||
) -> Result<ImplSourceTraitUpcastingData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
|
||||
{
|
||||
) -> Result<ImplSourceTraitUpcastingData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
// `assemble_candidates_for_unsizing` should ensure there are no late-bound
|
||||
@ -1010,13 +1009,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let vtable_vptr_slot =
|
||||
prepare_vtable_segments(tcx, source_trait_ref, vtable_segment_callback).unwrap();
|
||||
|
||||
Ok(ImplSourceTraitUpcastingData { upcast_trait_ref, vtable_vptr_slot, nested })
|
||||
Ok(ImplSourceTraitUpcastingData { vtable_vptr_slot, nested })
|
||||
}
|
||||
|
||||
fn confirm_builtin_unsize_candidate(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> Result<ImplSourceBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
// `assemble_candidates_for_unsizing` should ensure there are no late-bound
|
||||
@ -1217,17 +1216,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
_ => bug!("source: {source}, target: {target}"),
|
||||
};
|
||||
|
||||
Ok(ImplSourceBuiltinData { nested })
|
||||
Ok(nested)
|
||||
}
|
||||
|
||||
fn confirm_const_destruct_candidate(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
impl_def_id: Option<DefId>,
|
||||
) -> Result<ImplSourceConstDestructData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
// `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
|
||||
if !obligation.is_const() {
|
||||
return Ok(ImplSourceConstDestructData { nested: vec![] });
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None);
|
||||
@ -1381,6 +1380,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ImplSourceConstDestructData { nested })
|
||||
Ok(nested)
|
||||
}
|
||||
}
|
||||
|
@ -243,12 +243,12 @@ pub fn upcast_choices<'tcx>(
|
||||
/// `object.upcast_trait_ref`) within the vtable for `object`.
|
||||
pub fn get_vtable_index_of_object_method<'tcx, N>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
object: &super::ImplSourceObjectData<'tcx, N>,
|
||||
object: &super::ImplSourceObjectData<N>,
|
||||
method_def_id: DefId,
|
||||
) -> Option<usize> {
|
||||
// Count number of methods preceding the one we are selecting and
|
||||
// add them to the total offset.
|
||||
tcx.own_existential_vtable_entries(object.upcast_trait_ref.def_id())
|
||||
tcx.own_existential_vtable_entries(object.upcast_trait_def_id)
|
||||
.iter()
|
||||
.copied()
|
||||
.position(|def_id| def_id == method_def_id)
|
||||
|
@ -177,85 +177,6 @@ fn resolve_associated_item<'tcx>(
|
||||
|
||||
Some(ty::Instance::new(leaf_def.item.def_id, substs))
|
||||
}
|
||||
traits::ImplSource::Generator(generator_data) => {
|
||||
if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
|
||||
// For compiler developers who'd like to add new items to `Generator`,
|
||||
// you either need to generate a shim body, or perhaps return
|
||||
// `InstanceDef::Item` pointing to a trait default method body if
|
||||
// it is given a default implementation by the trait.
|
||||
span_bug!(
|
||||
tcx.def_span(generator_data.generator_def_id),
|
||||
"no definition for `{trait_ref}::{}` for built-in generator type",
|
||||
tcx.item_name(trait_item_id)
|
||||
)
|
||||
}
|
||||
Some(Instance {
|
||||
def: ty::InstanceDef::Item(generator_data.generator_def_id),
|
||||
substs: generator_data.substs,
|
||||
})
|
||||
}
|
||||
traits::ImplSource::Future(future_data) => {
|
||||
if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
|
||||
// `Future::poll` is generated by the compiler.
|
||||
Some(Instance {
|
||||
def: ty::InstanceDef::Item(future_data.generator_def_id),
|
||||
substs: future_data.substs,
|
||||
})
|
||||
} else {
|
||||
// All other methods are default methods of the `Future` trait.
|
||||
// (this assumes that `ImplSource::Future` is only used for methods on `Future`)
|
||||
debug_assert!(tcx.defaultness(trait_item_id).has_value());
|
||||
Some(Instance::new(trait_item_id, rcvr_substs))
|
||||
}
|
||||
}
|
||||
traits::ImplSource::Closure(closure_data) => {
|
||||
if cfg!(debug_assertions)
|
||||
&& ![sym::call, sym::call_mut, sym::call_once]
|
||||
.contains(&tcx.item_name(trait_item_id))
|
||||
{
|
||||
// For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
|
||||
// you either need to generate a shim body, or perhaps return
|
||||
// `InstanceDef::Item` pointing to a trait default method body if
|
||||
// it is given a default implementation by the trait.
|
||||
span_bug!(
|
||||
tcx.def_span(closure_data.closure_def_id),
|
||||
"no definition for `{trait_ref}::{}` for built-in closure type",
|
||||
tcx.item_name(trait_item_id)
|
||||
)
|
||||
}
|
||||
let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
|
||||
Instance::resolve_closure(
|
||||
tcx,
|
||||
closure_data.closure_def_id,
|
||||
closure_data.substs,
|
||||
trait_closure_kind,
|
||||
)
|
||||
}
|
||||
traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
if cfg!(debug_assertions)
|
||||
&& ![sym::call, sym::call_mut, sym::call_once]
|
||||
.contains(&tcx.item_name(trait_item_id))
|
||||
{
|
||||
// For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
|
||||
// you either need to generate a shim body, or perhaps return
|
||||
// `InstanceDef::Item` pointing to a trait default method body if
|
||||
// it is given a default implementation by the trait.
|
||||
bug!(
|
||||
"no definition for `{trait_ref}::{}` for built-in fn type",
|
||||
tcx.item_name(trait_item_id)
|
||||
)
|
||||
}
|
||||
Some(Instance {
|
||||
def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty),
|
||||
substs: rcvr_substs,
|
||||
})
|
||||
}
|
||||
_ => bug!(
|
||||
"no built-in definition for `{trait_ref}::{}` for non-fn type",
|
||||
tcx.item_name(trait_item_id)
|
||||
),
|
||||
},
|
||||
traits::ImplSource::Object(ref data) => {
|
||||
traits::get_vtable_index_of_object_method(tcx, data, trait_item_id).map(|index| {
|
||||
Instance {
|
||||
@ -308,15 +229,73 @@ fn resolve_associated_item<'tcx>(
|
||||
span: tcx.def_span(trait_item_id),
|
||||
})
|
||||
}
|
||||
} else if Some(trait_ref.def_id) == lang_items.future_trait() {
|
||||
let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
|
||||
bug!()
|
||||
};
|
||||
if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
|
||||
// `Future::poll` is generated by the compiler.
|
||||
Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs: substs })
|
||||
} else {
|
||||
// All other methods are default methods of the `Future` trait.
|
||||
// (this assumes that `ImplSource::Builtin` is only used for methods on `Future`)
|
||||
debug_assert!(tcx.defaultness(trait_item_id).has_value());
|
||||
Some(Instance::new(trait_item_id, rcvr_substs))
|
||||
}
|
||||
} else if Some(trait_ref.def_id) == lang_items.gen_trait() {
|
||||
let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
|
||||
bug!()
|
||||
};
|
||||
if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
|
||||
// For compiler developers who'd like to add new items to `Generator`,
|
||||
// you either need to generate a shim body, or perhaps return
|
||||
// `InstanceDef::Item` pointing to a trait default method body if
|
||||
// it is given a default implementation by the trait.
|
||||
span_bug!(
|
||||
tcx.def_span(generator_def_id),
|
||||
"no definition for `{trait_ref}::{}` for built-in generator type",
|
||||
tcx.item_name(trait_item_id)
|
||||
)
|
||||
}
|
||||
Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs })
|
||||
} else if tcx.fn_trait_kind_from_def_id(trait_ref.def_id).is_some() {
|
||||
// FIXME: This doesn't check for malformed libcore that defines, e.g.,
|
||||
// `trait Fn { fn call_once(&self) { .. } }`. This is mostly for extension
|
||||
// methods.
|
||||
if cfg!(debug_assertions)
|
||||
&& ![sym::call, sym::call_mut, sym::call_once]
|
||||
.contains(&tcx.item_name(trait_item_id))
|
||||
{
|
||||
// For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
|
||||
// you either need to generate a shim body, or perhaps return
|
||||
// `InstanceDef::Item` pointing to a trait default method body if
|
||||
// it is given a default implementation by the trait.
|
||||
bug!(
|
||||
"no definition for `{trait_ref}::{}` for built-in callable type",
|
||||
tcx.item_name(trait_item_id)
|
||||
)
|
||||
}
|
||||
match *rcvr_substs.type_at(0).kind() {
|
||||
ty::Closure(closure_def_id, substs) => {
|
||||
let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
|
||||
Instance::resolve_closure(tcx, closure_def_id, substs, trait_closure_kind)
|
||||
}
|
||||
ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
|
||||
def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_substs.type_at(0)),
|
||||
substs: rcvr_substs,
|
||||
}),
|
||||
_ => bug!(
|
||||
"no built-in definition for `{trait_ref}::{}` for non-fn type",
|
||||
tcx.item_name(trait_item_id)
|
||||
),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
traits::ImplSource::AutoImpl(..)
|
||||
| traits::ImplSource::Param(..)
|
||||
traits::ImplSource::Param(..)
|
||||
| traits::ImplSource::TraitAlias(..)
|
||||
| traits::ImplSource::TraitUpcasting(_)
|
||||
| traits::ImplSource::ConstDestruct(_) => None,
|
||||
| traits::ImplSource::TraitUpcasting(_) => None,
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user