Auto merge of #72114 - anyska:vtable-rename, r=nikomatsakis
Rename traits::Vtable to ImplSource. Originally suggested by @eddyb. r? @nikomatsakis
This commit is contained in:
commit
feb3536eba
@ -14,9 +14,9 @@ use rustc_middle::ty::{self, Const, Ty};
|
|||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
pub use self::FulfillmentErrorCode::*;
|
pub use self::FulfillmentErrorCode::*;
|
||||||
|
pub use self::ImplSource::*;
|
||||||
pub use self::ObligationCauseCode::*;
|
pub use self::ObligationCauseCode::*;
|
||||||
pub use self::SelectionError::*;
|
pub use self::SelectionError::*;
|
||||||
pub use self::Vtable::*;
|
|
||||||
|
|
||||||
pub use self::engine::{TraitEngine, TraitEngineExt};
|
pub use self::engine::{TraitEngine, TraitEngineExt};
|
||||||
pub use self::project::MismatchedProjectionTypes;
|
pub use self::project::MismatchedProjectionTypes;
|
||||||
@ -30,10 +30,10 @@ crate use self::util::elaborate_predicates;
|
|||||||
pub use rustc_middle::traits::*;
|
pub use rustc_middle::traits::*;
|
||||||
|
|
||||||
/// An `Obligation` represents some trait reference (e.g., `int: Eq`) for
|
/// An `Obligation` represents some trait reference (e.g., `int: Eq`) for
|
||||||
/// which the vtable must be found. The process of finding a vtable is
|
/// which the "impl_source" must be found. The process of finding a "impl_source" is
|
||||||
/// called "resolving" the `Obligation`. This process consists of
|
/// called "resolving" the `Obligation`. This process consists of
|
||||||
/// either identifying an `impl` (e.g., `impl Eq for int`) that
|
/// either identifying an `impl` (e.g., `impl Eq for int`) that
|
||||||
/// provides the required vtable, or else finding a bound that is in
|
/// satisfies the obligation, or else finding a bound that is in
|
||||||
/// scope. The eventual result is usually a `Selection` (defined below).
|
/// scope. The eventual result is usually a `Selection` (defined below).
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Obligation<'tcx, T> {
|
pub struct Obligation<'tcx, T> {
|
||||||
@ -65,7 +65,7 @@ pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
|
|||||||
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
|
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
|
||||||
pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;
|
pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;
|
||||||
|
|
||||||
pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
|
pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>;
|
||||||
|
|
||||||
pub struct FulfillmentError<'tcx> {
|
pub struct FulfillmentError<'tcx> {
|
||||||
pub obligation: PredicateObligation<'tcx>,
|
pub obligation: PredicateObligation<'tcx>,
|
||||||
|
@ -735,7 +735,7 @@ rustc_queries! {
|
|||||||
Codegen {
|
Codegen {
|
||||||
query codegen_fulfill_obligation(
|
query codegen_fulfill_obligation(
|
||||||
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
|
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
|
||||||
) -> Result<Vtable<'tcx, ()>, ErrorReported> {
|
) -> Result<ImplSource<'tcx, ()>, ErrorReported> {
|
||||||
cache_on_disk_if { true }
|
cache_on_disk_if { true }
|
||||||
desc { |tcx|
|
desc { |tcx|
|
||||||
"checking if `{}` fulfills its obligations",
|
"checking if `{}` fulfills its obligations",
|
||||||
|
@ -27,9 +27,9 @@ pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, Selecti
|
|||||||
|
|
||||||
pub type ChalkCanonicalGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>;
|
pub type ChalkCanonicalGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>;
|
||||||
|
|
||||||
|
pub use self::ImplSource::*;
|
||||||
pub use self::ObligationCauseCode::*;
|
pub use self::ObligationCauseCode::*;
|
||||||
pub use self::SelectionError::*;
|
pub use self::SelectionError::*;
|
||||||
pub use self::Vtable::*;
|
|
||||||
|
|
||||||
pub use self::chalk::{
|
pub use self::chalk::{
|
||||||
ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustDefId as ChalkRustDefId,
|
ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustDefId as ChalkRustDefId,
|
||||||
@ -343,15 +343,10 @@ pub enum SelectionError<'tcx> {
|
|||||||
/// - `Err(e)`: error `e` occurred
|
/// - `Err(e)`: error `e` occurred
|
||||||
pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
|
pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
|
||||||
|
|
||||||
/// Given the successful resolution of an obligation, the `Vtable`
|
/// Given the successful resolution of an obligation, the `ImplSource`
|
||||||
/// indicates where the vtable comes from. Note that while we call this
|
/// indicates where the impl comes from.
|
||||||
/// a "vtable", it does not necessarily indicate dynamic dispatch at
|
|
||||||
/// runtime. `Vtable` instances just tell the compiler where to find
|
|
||||||
/// methods, but in generic code those methods are typically statically
|
|
||||||
/// dispatched -- only when an object is constructed is a `Vtable`
|
|
||||||
/// instance reified into an actual vtable.
|
|
||||||
///
|
///
|
||||||
/// For example, the vtable may be tied to a specific impl (case A),
|
/// For example, the obligation may be satisfied by a specific impl (case A),
|
||||||
/// or it may be relative to some bound that is in scope (case B).
|
/// or it may be relative to some bound that is in scope (case B).
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -363,136 +358,136 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
|
|||||||
/// param: T,
|
/// param: T,
|
||||||
/// mixed: Option<T>) {
|
/// mixed: Option<T>) {
|
||||||
///
|
///
|
||||||
/// // Case A: Vtable points at a specific impl. Only possible when
|
/// // Case A: ImplSource points at a specific impl. Only possible when
|
||||||
/// // type is concretely known. If the impl itself has bounded
|
/// // type is concretely known. If the impl itself has bounded
|
||||||
/// // type parameters, Vtable will carry resolutions for those as well:
|
/// // type parameters, ImplSource will carry resolutions for those as well:
|
||||||
/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])])
|
/// concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])])
|
||||||
///
|
///
|
||||||
/// // Case B: Vtable must be provided by caller. This applies when
|
/// // Case B: ImplSource must be provided by caller. This applies when
|
||||||
/// // type is a type parameter.
|
/// // type is a type parameter.
|
||||||
/// param.clone(); // VtableParam
|
/// param.clone(); // ImplSourceParam
|
||||||
///
|
///
|
||||||
/// // Case C: A mix of cases A and B.
|
/// // Case C: A mix of cases A and B.
|
||||||
/// mixed.clone(); // Vtable(Impl_1, [VtableParam])
|
/// mixed.clone(); // ImplSource(Impl_1, [ImplSourceParam])
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ### The type parameter `N`
|
/// ### The type parameter `N`
|
||||||
///
|
///
|
||||||
/// See explanation on `VtableImplData`.
|
/// See explanation on `ImplSourceUserDefinedData`.
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub enum Vtable<'tcx, N> {
|
pub enum ImplSource<'tcx, N> {
|
||||||
/// Vtable identifying a particular impl.
|
/// ImplSource identifying a particular impl.
|
||||||
VtableImpl(VtableImplData<'tcx, N>),
|
ImplSourceUserDefined(ImplSourceUserDefinedData<'tcx, N>),
|
||||||
|
|
||||||
/// Vtable for auto trait implementations.
|
/// ImplSource for auto trait implementations.
|
||||||
/// This carries the information and nested obligations with regards
|
/// This carries the information and nested obligations with regards
|
||||||
/// to an auto implementation for a trait `Trait`. The nested obligations
|
/// to an auto implementation for a trait `Trait`. The nested obligations
|
||||||
/// ensure the trait implementation holds for all the constituent types.
|
/// ensure the trait implementation holds for all the constituent types.
|
||||||
VtableAutoImpl(VtableAutoImplData<N>),
|
ImplSourceAutoImpl(ImplSourceAutoImplData<N>),
|
||||||
|
|
||||||
/// Successful resolution to an obligation provided by the caller
|
/// Successful resolution to an obligation provided by the caller
|
||||||
/// for some type parameter. The `Vec<N>` represents the
|
/// for some type parameter. The `Vec<N>` represents the
|
||||||
/// obligations incurred from normalizing the where-clause (if
|
/// obligations incurred from normalizing the where-clause (if
|
||||||
/// any).
|
/// any).
|
||||||
VtableParam(Vec<N>),
|
ImplSourceParam(Vec<N>),
|
||||||
|
|
||||||
/// Virtual calls through an object.
|
/// Virtual calls through an object.
|
||||||
VtableObject(VtableObjectData<'tcx, N>),
|
ImplSourceObject(ImplSourceObjectData<'tcx, N>),
|
||||||
|
|
||||||
/// Successful resolution for a builtin trait.
|
/// Successful resolution for a builtin trait.
|
||||||
VtableBuiltin(VtableBuiltinData<N>),
|
ImplSourceBuiltin(ImplSourceBuiltinData<N>),
|
||||||
|
|
||||||
/// Vtable automatically generated for a closure. The `DefId` is the ID
|
/// ImplSource automatically generated for a closure. The `DefId` is the ID
|
||||||
/// of the closure expression. This is a `VtableImpl` in spirit, but the
|
/// of the closure expression. This is a `ImplSourceUserDefined` in spirit, but the
|
||||||
/// impl is generated by the compiler and does not appear in the source.
|
/// impl is generated by the compiler and does not appear in the source.
|
||||||
VtableClosure(VtableClosureData<'tcx, N>),
|
ImplSourceClosure(ImplSourceClosureData<'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.
|
||||||
VtableFnPointer(VtableFnPointerData<'tcx, N>),
|
ImplSourceFnPointer(ImplSourceFnPointerData<'tcx, N>),
|
||||||
|
|
||||||
/// Vtable for a builtin `DeterminantKind` trait implementation.
|
/// ImplSource for a builtin `DeterminantKind` trait implementation.
|
||||||
VtableDiscriminantKind(VtableDiscriminantKindData),
|
ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData),
|
||||||
|
|
||||||
/// Vtable automatically generated for a generator.
|
/// ImplSource automatically generated for a generator.
|
||||||
VtableGenerator(VtableGeneratorData<'tcx, N>),
|
ImplSourceGenerator(ImplSourceGeneratorData<'tcx, N>),
|
||||||
|
|
||||||
/// Vtable for a trait alias.
|
/// ImplSource for a trait alias.
|
||||||
VtableTraitAlias(VtableTraitAliasData<'tcx, N>),
|
ImplSourceTraitAlias(ImplSourceTraitAliasData<'tcx, N>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N> Vtable<'tcx, N> {
|
impl<'tcx, N> ImplSource<'tcx, N> {
|
||||||
pub fn nested_obligations(self) -> Vec<N> {
|
pub fn nested_obligations(self) -> Vec<N> {
|
||||||
match self {
|
match self {
|
||||||
VtableImpl(i) => i.nested,
|
ImplSourceUserDefined(i) => i.nested,
|
||||||
VtableParam(n) => n,
|
ImplSourceParam(n) => n,
|
||||||
VtableBuiltin(i) => i.nested,
|
ImplSourceBuiltin(i) => i.nested,
|
||||||
VtableAutoImpl(d) => d.nested,
|
ImplSourceAutoImpl(d) => d.nested,
|
||||||
VtableClosure(c) => c.nested,
|
ImplSourceClosure(c) => c.nested,
|
||||||
VtableGenerator(c) => c.nested,
|
ImplSourceGenerator(c) => c.nested,
|
||||||
VtableObject(d) => d.nested,
|
ImplSourceObject(d) => d.nested,
|
||||||
VtableFnPointer(d) => d.nested,
|
ImplSourceFnPointer(d) => d.nested,
|
||||||
VtableDiscriminantKind(VtableDiscriminantKindData) => Vec::new(),
|
ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) => Vec::new(),
|
||||||
VtableTraitAlias(d) => d.nested,
|
ImplSourceTraitAlias(d) => d.nested,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn borrow_nested_obligations(&self) -> &[N] {
|
pub fn borrow_nested_obligations(&self) -> &[N] {
|
||||||
match &self {
|
match &self {
|
||||||
VtableImpl(i) => &i.nested[..],
|
ImplSourceUserDefined(i) => &i.nested[..],
|
||||||
VtableParam(n) => &n[..],
|
ImplSourceParam(n) => &n[..],
|
||||||
VtableBuiltin(i) => &i.nested[..],
|
ImplSourceBuiltin(i) => &i.nested[..],
|
||||||
VtableAutoImpl(d) => &d.nested[..],
|
ImplSourceAutoImpl(d) => &d.nested[..],
|
||||||
VtableClosure(c) => &c.nested[..],
|
ImplSourceClosure(c) => &c.nested[..],
|
||||||
VtableGenerator(c) => &c.nested[..],
|
ImplSourceGenerator(c) => &c.nested[..],
|
||||||
VtableObject(d) => &d.nested[..],
|
ImplSourceObject(d) => &d.nested[..],
|
||||||
VtableFnPointer(d) => &d.nested[..],
|
ImplSourceFnPointer(d) => &d.nested[..],
|
||||||
VtableDiscriminantKind(VtableDiscriminantKindData) => &[],
|
ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) => &[],
|
||||||
VtableTraitAlias(d) => &d.nested[..],
|
ImplSourceTraitAlias(d) => &d.nested[..],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M>
|
pub fn map<M, F>(self, f: F) -> ImplSource<'tcx, M>
|
||||||
where
|
where
|
||||||
F: FnMut(N) -> M,
|
F: FnMut(N) -> M,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
VtableImpl(i) => VtableImpl(VtableImplData {
|
ImplSourceUserDefined(i) => ImplSourceUserDefined(ImplSourceUserDefinedData {
|
||||||
impl_def_id: i.impl_def_id,
|
impl_def_id: i.impl_def_id,
|
||||||
substs: i.substs,
|
substs: i.substs,
|
||||||
nested: i.nested.into_iter().map(f).collect(),
|
nested: i.nested.into_iter().map(f).collect(),
|
||||||
}),
|
}),
|
||||||
VtableParam(n) => VtableParam(n.into_iter().map(f).collect()),
|
ImplSourceParam(n) => ImplSourceParam(n.into_iter().map(f).collect()),
|
||||||
VtableBuiltin(i) => {
|
ImplSourceBuiltin(i) => ImplSourceBuiltin(ImplSourceBuiltinData {
|
||||||
VtableBuiltin(VtableBuiltinData { nested: i.nested.into_iter().map(f).collect() })
|
nested: i.nested.into_iter().map(f).collect(),
|
||||||
}
|
}),
|
||||||
VtableObject(o) => VtableObject(VtableObjectData {
|
ImplSourceObject(o) => ImplSourceObject(ImplSourceObjectData {
|
||||||
upcast_trait_ref: o.upcast_trait_ref,
|
upcast_trait_ref: o.upcast_trait_ref,
|
||||||
vtable_base: o.vtable_base,
|
vtable_base: o.vtable_base,
|
||||||
nested: o.nested.into_iter().map(f).collect(),
|
nested: o.nested.into_iter().map(f).collect(),
|
||||||
}),
|
}),
|
||||||
VtableAutoImpl(d) => VtableAutoImpl(VtableAutoImplData {
|
ImplSourceAutoImpl(d) => ImplSourceAutoImpl(ImplSourceAutoImplData {
|
||||||
trait_def_id: d.trait_def_id,
|
trait_def_id: d.trait_def_id,
|
||||||
nested: d.nested.into_iter().map(f).collect(),
|
nested: d.nested.into_iter().map(f).collect(),
|
||||||
}),
|
}),
|
||||||
VtableClosure(c) => VtableClosure(VtableClosureData {
|
ImplSourceClosure(c) => ImplSourceClosure(ImplSourceClosureData {
|
||||||
closure_def_id: c.closure_def_id,
|
closure_def_id: c.closure_def_id,
|
||||||
substs: c.substs,
|
substs: c.substs,
|
||||||
nested: c.nested.into_iter().map(f).collect(),
|
nested: c.nested.into_iter().map(f).collect(),
|
||||||
}),
|
}),
|
||||||
VtableGenerator(c) => VtableGenerator(VtableGeneratorData {
|
ImplSourceGenerator(c) => ImplSourceGenerator(ImplSourceGeneratorData {
|
||||||
generator_def_id: c.generator_def_id,
|
generator_def_id: c.generator_def_id,
|
||||||
substs: c.substs,
|
substs: c.substs,
|
||||||
nested: c.nested.into_iter().map(f).collect(),
|
nested: c.nested.into_iter().map(f).collect(),
|
||||||
}),
|
}),
|
||||||
VtableFnPointer(p) => VtableFnPointer(VtableFnPointerData {
|
ImplSourceFnPointer(p) => ImplSourceFnPointer(ImplSourceFnPointerData {
|
||||||
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(),
|
||||||
}),
|
}),
|
||||||
VtableDiscriminantKind(VtableDiscriminantKindData) => {
|
ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) => {
|
||||||
VtableDiscriminantKind(VtableDiscriminantKindData)
|
ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData)
|
||||||
}
|
}
|
||||||
VtableTraitAlias(d) => VtableTraitAlias(VtableTraitAliasData {
|
ImplSourceTraitAlias(d) => ImplSourceTraitAlias(ImplSourceTraitAliasData {
|
||||||
alias_def_id: d.alias_def_id,
|
alias_def_id: d.alias_def_id,
|
||||||
substs: d.substs,
|
substs: d.substs,
|
||||||
nested: d.nested.into_iter().map(f).collect(),
|
nested: d.nested.into_iter().map(f).collect(),
|
||||||
@ -512,14 +507,14 @@ impl<'tcx, N> Vtable<'tcx, N> {
|
|||||||
/// is `()`, because codegen only requires a shallow resolution of an
|
/// is `()`, because codegen only requires a shallow resolution of an
|
||||||
/// impl, and nested obligations are satisfied later.
|
/// impl, and nested obligations are satisfied later.
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub struct VtableImplData<'tcx, N> {
|
pub struct ImplSourceUserDefinedData<'tcx, N> {
|
||||||
pub impl_def_id: DefId,
|
pub impl_def_id: DefId,
|
||||||
pub substs: SubstsRef<'tcx>,
|
pub substs: SubstsRef<'tcx>,
|
||||||
pub nested: Vec<N>,
|
pub nested: Vec<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub struct VtableGeneratorData<'tcx, N> {
|
pub struct ImplSourceGeneratorData<'tcx, N> {
|
||||||
pub generator_def_id: DefId,
|
pub generator_def_id: DefId,
|
||||||
pub substs: SubstsRef<'tcx>,
|
pub substs: SubstsRef<'tcx>,
|
||||||
/// Nested obligations. This can be non-empty if the generator
|
/// Nested obligations. This can be non-empty if the generator
|
||||||
@ -528,7 +523,7 @@ pub struct VtableGeneratorData<'tcx, N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub struct VtableClosureData<'tcx, N> {
|
pub struct ImplSourceClosureData<'tcx, N> {
|
||||||
pub closure_def_id: DefId,
|
pub closure_def_id: DefId,
|
||||||
pub substs: SubstsRef<'tcx>,
|
pub substs: SubstsRef<'tcx>,
|
||||||
/// Nested obligations. This can be non-empty if the closure
|
/// Nested obligations. This can be non-empty if the closure
|
||||||
@ -537,20 +532,18 @@ pub struct VtableClosureData<'tcx, N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub struct VtableAutoImplData<N> {
|
pub struct ImplSourceAutoImplData<N> {
|
||||||
pub trait_def_id: DefId,
|
pub trait_def_id: DefId,
|
||||||
pub nested: Vec<N>,
|
pub nested: Vec<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub struct VtableBuiltinData<N> {
|
pub struct ImplSourceBuiltinData<N> {
|
||||||
pub nested: Vec<N>,
|
pub nested: Vec<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A vtable for some object-safe trait `Foo` automatically derived
|
|
||||||
/// for the object type `Foo`.
|
|
||||||
#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub struct VtableObjectData<'tcx, N> {
|
pub struct ImplSourceObjectData<'tcx, N> {
|
||||||
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
|
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
|
||||||
pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
|
pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
|
|
||||||
@ -563,17 +556,17 @@ pub struct VtableObjectData<'tcx, N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub struct VtableFnPointerData<'tcx, N> {
|
pub struct ImplSourceFnPointerData<'tcx, N> {
|
||||||
pub fn_ty: Ty<'tcx>,
|
pub fn_ty: Ty<'tcx>,
|
||||||
pub nested: Vec<N>,
|
pub nested: Vec<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(@lcnr): This should be refactored and merged with other builtin vtables.
|
// FIXME(@lcnr): This should be refactored and merged with other builtin vtables.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub struct VtableDiscriminantKindData;
|
pub struct ImplSourceDiscriminantKindData;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub struct VtableTraitAliasData<'tcx, N> {
|
pub struct ImplSourceTraitAliasData<'tcx, N> {
|
||||||
pub alias_def_id: DefId,
|
pub alias_def_id: DefId,
|
||||||
pub substs: SubstsRef<'tcx>,
|
pub substs: SubstsRef<'tcx>,
|
||||||
pub nested: Vec<N>,
|
pub nested: Vec<N>,
|
||||||
|
@ -6,99 +6,99 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
// Structural impls for the structs in `traits`.
|
// Structural impls for the structs in `traits`.
|
||||||
|
|
||||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::Vtable<'tcx, N> {
|
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
super::VtableImpl(ref v) => write!(f, "{:?}", v),
|
super::ImplSourceUserDefined(ref v) => write!(f, "{:?}", v),
|
||||||
|
|
||||||
super::VtableAutoImpl(ref t) => write!(f, "{:?}", t),
|
super::ImplSourceAutoImpl(ref t) => write!(f, "{:?}", t),
|
||||||
|
|
||||||
super::VtableClosure(ref d) => write!(f, "{:?}", d),
|
super::ImplSourceClosure(ref d) => write!(f, "{:?}", d),
|
||||||
|
|
||||||
super::VtableGenerator(ref d) => write!(f, "{:?}", d),
|
super::ImplSourceGenerator(ref d) => write!(f, "{:?}", d),
|
||||||
|
|
||||||
super::VtableFnPointer(ref d) => write!(f, "VtableFnPointer({:?})", d),
|
super::ImplSourceFnPointer(ref d) => write!(f, "ImplSourceFnPointer({:?})", d),
|
||||||
|
|
||||||
super::VtableDiscriminantKind(ref d) => write!(f, "{:?}", d),
|
super::ImplSourceDiscriminantKind(ref d) => write!(f, "{:?}", d),
|
||||||
|
|
||||||
super::VtableObject(ref d) => write!(f, "{:?}", d),
|
super::ImplSourceObject(ref d) => write!(f, "{:?}", d),
|
||||||
|
|
||||||
super::VtableParam(ref n) => write!(f, "VtableParam({:?})", n),
|
super::ImplSourceParam(ref n) => write!(f, "ImplSourceParam({:?})", n),
|
||||||
|
|
||||||
super::VtableBuiltin(ref d) => write!(f, "{:?}", d),
|
super::ImplSourceBuiltin(ref d) => write!(f, "{:?}", d),
|
||||||
|
|
||||||
super::VtableTraitAlias(ref d) => write!(f, "{:?}", d),
|
super::ImplSourceTraitAlias(ref d) => write!(f, "{:?}", d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> {
|
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceUserDefinedData<'tcx, N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"VtableImplData(impl_def_id={:?}, substs={:?}, nested={:?})",
|
"ImplSourceUserDefinedData(impl_def_id={:?}, substs={:?}, nested={:?})",
|
||||||
self.impl_def_id, self.substs, self.nested
|
self.impl_def_id, self.substs, self.nested
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> {
|
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceGeneratorData<'tcx, N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"VtableGeneratorData(generator_def_id={:?}, substs={:?}, nested={:?})",
|
"ImplSourceGeneratorData(generator_def_id={:?}, substs={:?}, nested={:?})",
|
||||||
self.generator_def_id, self.substs, self.nested
|
self.generator_def_id, self.substs, self.nested
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> {
|
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceClosureData<'tcx, N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"VtableClosureData(closure_def_id={:?}, substs={:?}, nested={:?})",
|
"ImplSourceClosureData(closure_def_id={:?}, substs={:?}, nested={:?})",
|
||||||
self.closure_def_id, self.substs, self.nested
|
self.closure_def_id, self.substs, self.nested
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> {
|
impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceBuiltinData<N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "VtableBuiltinData(nested={:?})", self.nested)
|
write!(f, "ImplSourceBuiltinData(nested={:?})", self.nested)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: fmt::Debug> fmt::Debug for traits::VtableAutoImplData<N> {
|
impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceAutoImplData<N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"VtableAutoImplData(trait_def_id={:?}, nested={:?})",
|
"ImplSourceAutoImplData(trait_def_id={:?}, nested={:?})",
|
||||||
self.trait_def_id, self.nested
|
self.trait_def_id, self.nested
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> {
|
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<'tcx, N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"VtableObjectData(upcast={:?}, vtable_base={}, nested={:?})",
|
"ImplSourceObjectData(upcast={:?}, vtable_base={}, nested={:?})",
|
||||||
self.upcast_trait_ref, self.vtable_base, self.nested
|
self.upcast_trait_ref, self.vtable_base, self.nested
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> {
|
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceFnPointerData<'tcx, N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "VtableFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested)
|
write!(f, "ImplSourceFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableTraitAliasData<'tcx, N> {
|
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx, N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"VtableTraitAlias(alias_def_id={:?}, substs={:?}, nested={:?})",
|
"ImplSourceTraitAlias(alias_def_id={:?}, substs={:?}, nested={:?})",
|
||||||
self.alias_def_id, self.substs, self.nested
|
self.alias_def_id, self.substs, self.nested
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -241,63 +241,71 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For codegen only.
|
// For codegen only.
|
||||||
impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
|
impl<'a, 'tcx> Lift<'tcx> for traits::ImplSource<'a, ()> {
|
||||||
type Lifted = traits::Vtable<'tcx, ()>;
|
type Lifted = traits::ImplSource<'tcx, ()>;
|
||||||
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||||
match self.clone() {
|
match self.clone() {
|
||||||
traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested }) => {
|
traits::ImplSourceUserDefined(traits::ImplSourceUserDefinedData {
|
||||||
tcx.lift(&substs).map(|substs| {
|
impl_def_id,
|
||||||
traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested })
|
substs,
|
||||||
|
nested,
|
||||||
|
}) => tcx.lift(&substs).map(|substs| {
|
||||||
|
traits::ImplSourceUserDefined(traits::ImplSourceUserDefinedData {
|
||||||
|
impl_def_id,
|
||||||
|
substs,
|
||||||
|
nested,
|
||||||
})
|
})
|
||||||
}
|
}),
|
||||||
traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
|
traits::ImplSourceAutoImpl(t) => Some(traits::ImplSourceAutoImpl(t)),
|
||||||
traits::VtableGenerator(traits::VtableGeneratorData {
|
traits::ImplSourceGenerator(traits::ImplSourceGeneratorData {
|
||||||
generator_def_id,
|
generator_def_id,
|
||||||
substs,
|
substs,
|
||||||
nested,
|
nested,
|
||||||
}) => tcx.lift(&substs).map(|substs| {
|
}) => tcx.lift(&substs).map(|substs| {
|
||||||
traits::VtableGenerator(traits::VtableGeneratorData {
|
traits::ImplSourceGenerator(traits::ImplSourceGeneratorData {
|
||||||
generator_def_id,
|
generator_def_id,
|
||||||
substs,
|
substs,
|
||||||
nested,
|
nested,
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
traits::VtableClosure(traits::VtableClosureData { closure_def_id, substs, nested }) => {
|
traits::ImplSourceClosure(traits::ImplSourceClosureData {
|
||||||
tcx.lift(&substs).map(|substs| {
|
closure_def_id,
|
||||||
traits::VtableClosure(traits::VtableClosureData {
|
substs,
|
||||||
closure_def_id,
|
nested,
|
||||||
substs,
|
}) => tcx.lift(&substs).map(|substs| {
|
||||||
nested,
|
traits::ImplSourceClosure(traits::ImplSourceClosureData {
|
||||||
})
|
closure_def_id,
|
||||||
|
substs,
|
||||||
|
nested,
|
||||||
})
|
})
|
||||||
}
|
}),
|
||||||
traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
|
traits::ImplSourceFnPointer(traits::ImplSourceFnPointerData { fn_ty, nested }) => {
|
||||||
tcx.lift(&fn_ty).map(|fn_ty| {
|
tcx.lift(&fn_ty).map(|fn_ty| {
|
||||||
traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested })
|
traits::ImplSourceFnPointer(traits::ImplSourceFnPointerData { fn_ty, nested })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
traits::VtableDiscriminantKind(traits::VtableDiscriminantKindData) => {
|
traits::ImplSourceDiscriminantKind(traits::ImplSourceDiscriminantKindData) => {
|
||||||
Some(traits::VtableDiscriminantKind(traits::VtableDiscriminantKindData))
|
Some(traits::ImplSourceDiscriminantKind(traits::ImplSourceDiscriminantKindData))
|
||||||
}
|
}
|
||||||
traits::VtableParam(n) => Some(traits::VtableParam(n)),
|
traits::ImplSourceParam(n) => Some(traits::ImplSourceParam(n)),
|
||||||
traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)),
|
traits::ImplSourceBuiltin(n) => Some(traits::ImplSourceBuiltin(n)),
|
||||||
traits::VtableObject(traits::VtableObjectData {
|
traits::ImplSourceObject(traits::ImplSourceObjectData {
|
||||||
upcast_trait_ref,
|
upcast_trait_ref,
|
||||||
vtable_base,
|
vtable_base,
|
||||||
nested,
|
nested,
|
||||||
}) => tcx.lift(&upcast_trait_ref).map(|trait_ref| {
|
}) => tcx.lift(&upcast_trait_ref).map(|trait_ref| {
|
||||||
traits::VtableObject(traits::VtableObjectData {
|
traits::ImplSourceObject(traits::ImplSourceObjectData {
|
||||||
upcast_trait_ref: trait_ref,
|
upcast_trait_ref: trait_ref,
|
||||||
vtable_base,
|
vtable_base,
|
||||||
nested,
|
nested,
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
traits::VtableTraitAlias(traits::VtableTraitAliasData {
|
traits::ImplSourceTraitAlias(traits::ImplSourceTraitAliasData {
|
||||||
alias_def_id,
|
alias_def_id,
|
||||||
substs,
|
substs,
|
||||||
nested,
|
nested,
|
||||||
}) => tcx.lift(&substs).map(|substs| {
|
}) => tcx.lift(&substs).map(|substs| {
|
||||||
traits::VtableTraitAlias(traits::VtableTraitAliasData {
|
traits::ImplSourceTraitAlias(traits::ImplSourceTraitAliasData {
|
||||||
alias_def_id,
|
alias_def_id,
|
||||||
substs,
|
substs,
|
||||||
nested,
|
nested,
|
||||||
|
@ -27,7 +27,7 @@ use crate::traits::query::{
|
|||||||
OutlivesBound,
|
OutlivesBound,
|
||||||
};
|
};
|
||||||
use crate::traits::specialization_graph;
|
use crate::traits::specialization_graph;
|
||||||
use crate::traits::{self, Vtable};
|
use crate::traits::{self, ImplSource};
|
||||||
use crate::ty::steal::Steal;
|
use crate::ty::steal::Steal;
|
||||||
use crate::ty::subst::{GenericArg, SubstsRef};
|
use crate::ty::subst::{GenericArg, SubstsRef};
|
||||||
use crate::ty::util::AlwaysRequiresDrop;
|
use crate::ty::util::AlwaysRequiresDrop;
|
||||||
|
@ -20,11 +20,12 @@ pub fn custom_coerce_unsize_info<'tcx>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) {
|
match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) {
|
||||||
Ok(traits::VtableImpl(traits::VtableImplData { impl_def_id, .. })) => {
|
Ok(traits::ImplSourceUserDefined(traits::ImplSourceUserDefinedData {
|
||||||
tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap()
|
impl_def_id,
|
||||||
}
|
..
|
||||||
vtable => {
|
})) => tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap(),
|
||||||
bug!("invalid `CoerceUnsized` vtable: {:?}", vtable);
|
impl_source => {
|
||||||
|
bug!("invalid `CoerceUnsized` impl_source: {:?}", impl_source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||||||
));
|
));
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(Some(Vtable::VtableImpl(_))) => {
|
Ok(Some(ImplSource::ImplSourceUserDefined(_))) => {
|
||||||
debug!(
|
debug!(
|
||||||
"find_auto_trait_generics({:?}): \
|
"find_auto_trait_generics({:?}): \
|
||||||
manual impl found, bailing out",
|
manual impl found, bailing out",
|
||||||
@ -304,11 +304,15 @@ impl AutoTraitFinder<'tcx> {
|
|||||||
let result = select.select(&obligation);
|
let result = select.select(&obligation);
|
||||||
|
|
||||||
match &result {
|
match &result {
|
||||||
&Ok(Some(ref vtable)) => {
|
&Ok(Some(ref impl_source)) => {
|
||||||
// If we see an explicit negative impl (e.g., `impl !Send for MyStruct`),
|
// If we see an explicit negative impl (e.g., `impl !Send for MyStruct`),
|
||||||
// we immediately bail out, since it's impossible for us to continue.
|
// we immediately bail out, since it's impossible for us to continue.
|
||||||
|
|
||||||
if let Vtable::VtableImpl(VtableImplData { impl_def_id, .. }) = vtable {
|
if let ImplSource::ImplSourceUserDefined(ImplSourceUserDefinedData {
|
||||||
|
impl_def_id,
|
||||||
|
..
|
||||||
|
}) = impl_source
|
||||||
|
{
|
||||||
// Blame 'tidy' for the weird bracket placement.
|
// Blame 'tidy' for the weird bracket placement.
|
||||||
if infcx.tcx.impl_polarity(*impl_def_id) == ty::ImplPolarity::Negative {
|
if infcx.tcx.impl_polarity(*impl_def_id) == ty::ImplPolarity::Negative {
|
||||||
debug!(
|
debug!(
|
||||||
@ -320,7 +324,7 @@ impl AutoTraitFinder<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let obligations = vtable.clone().nested_obligations().into_iter();
|
let obligations = impl_source.clone().nested_obligations().into_iter();
|
||||||
|
|
||||||
if !self.evaluate_nested_obligations(
|
if !self.evaluate_nested_obligations(
|
||||||
ty,
|
ty,
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
|
|
||||||
use crate::infer::{InferCtxt, TyCtxtInferExt};
|
use crate::infer::{InferCtxt, TyCtxtInferExt};
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
FulfillmentContext, Obligation, ObligationCause, SelectionContext, TraitEngine, Vtable,
|
FulfillmentContext, ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine,
|
||||||
};
|
};
|
||||||
use rustc_errors::ErrorReported;
|
use rustc_errors::ErrorReported;
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
|
|
||||||
/// Attempts to resolve an obligation to a vtable. The result is
|
/// Attempts to resolve an obligation to a `ImplSource`. The result is
|
||||||
/// a shallow vtable resolution, meaning that we do not
|
/// a shallow `ImplSource` resolution, meaning that we do not
|
||||||
/// (necessarily) resolve all nested obligations on the impl. Note
|
/// (necessarily) resolve all nested obligations on the impl. Note
|
||||||
/// that type check should guarantee to us that all nested
|
/// that type check should guarantee to us that all nested
|
||||||
/// obligations *could be* resolved if we wanted to.
|
/// obligations *could be* resolved if we wanted to.
|
||||||
@ -20,7 +20,7 @@ use rustc_middle::ty::{self, TyCtxt};
|
|||||||
pub fn codegen_fulfill_obligation<'tcx>(
|
pub fn codegen_fulfill_obligation<'tcx>(
|
||||||
ty: TyCtxt<'tcx>,
|
ty: TyCtxt<'tcx>,
|
||||||
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
|
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
|
||||||
) -> Result<Vtable<'tcx, ()>, ErrorReported> {
|
) -> Result<ImplSource<'tcx, ()>, ErrorReported> {
|
||||||
// Remove any references to regions; this helps improve caching.
|
// Remove any references to regions; this helps improve caching.
|
||||||
let trait_ref = ty.erase_regions(&trait_ref);
|
let trait_ref = ty.erase_regions(&trait_ref);
|
||||||
|
|
||||||
@ -69,14 +69,14 @@ pub fn codegen_fulfill_obligation<'tcx>(
|
|||||||
// all nested obligations. This is because they can inform the
|
// all nested obligations. This is because they can inform the
|
||||||
// inference of the impl's type parameters.
|
// inference of the impl's type parameters.
|
||||||
let mut fulfill_cx = FulfillmentContext::new();
|
let mut fulfill_cx = FulfillmentContext::new();
|
||||||
let vtable = selection.map(|predicate| {
|
let impl_source = selection.map(|predicate| {
|
||||||
debug!("fulfill_obligation: register_predicate_obligation {:?}", predicate);
|
debug!("fulfill_obligation: register_predicate_obligation {:?}", predicate);
|
||||||
fulfill_cx.register_predicate_obligation(&infcx, predicate);
|
fulfill_cx.register_predicate_obligation(&infcx, predicate);
|
||||||
});
|
});
|
||||||
let vtable = drain_fulfillment_cx_or_panic(&infcx, &mut fulfill_cx, &vtable);
|
let impl_source = drain_fulfillment_cx_or_panic(&infcx, &mut fulfill_cx, &impl_source);
|
||||||
|
|
||||||
info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
|
info!("Cache miss: {:?} => {:?}", trait_ref, impl_source);
|
||||||
Ok(vtable)
|
Ok(impl_source)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,12 +334,12 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self.selcx.select(&trait_obligation) {
|
match self.selcx.select(&trait_obligation) {
|
||||||
Ok(Some(vtable)) => {
|
Ok(Some(impl_source)) => {
|
||||||
debug!(
|
debug!(
|
||||||
"selecting trait `{:?}` at depth {} yielded Ok(Some)",
|
"selecting trait `{:?}` at depth {} yielded Ok(Some)",
|
||||||
data, obligation.recursion_depth
|
data, obligation.recursion_depth
|
||||||
);
|
);
|
||||||
ProcessResult::Changed(mk_pending(vtable.nested_obligations()))
|
ProcessResult::Changed(mk_pending(impl_source.nested_obligations()))
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -38,9 +38,9 @@ use rustc_span::Span;
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub use self::FulfillmentErrorCode::*;
|
pub use self::FulfillmentErrorCode::*;
|
||||||
|
pub use self::ImplSource::*;
|
||||||
pub use self::ObligationCauseCode::*;
|
pub use self::ObligationCauseCode::*;
|
||||||
pub use self::SelectionError::*;
|
pub use self::SelectionError::*;
|
||||||
pub use self::Vtable::*;
|
|
||||||
|
|
||||||
pub use self::coherence::{add_placeholder_note, orphan_check, overlapping_impls};
|
pub use self::coherence::{add_placeholder_note, orphan_check, overlapping_impls};
|
||||||
pub use self::coherence::{OrphanCheckErr, OverlapResult};
|
pub use self::coherence::{OrphanCheckErr, OverlapResult};
|
||||||
|
@ -11,11 +11,11 @@ use super::PredicateObligation;
|
|||||||
use super::Selection;
|
use super::Selection;
|
||||||
use super::SelectionContext;
|
use super::SelectionContext;
|
||||||
use super::SelectionError;
|
use super::SelectionError;
|
||||||
use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
|
|
||||||
use super::{
|
use super::{
|
||||||
VtableClosureData, VtableDiscriminantKindData, VtableFnPointerData, VtableGeneratorData,
|
ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
||||||
VtableImplData,
|
ImplSourceGeneratorData, ImplSourceUserDefinedData,
|
||||||
};
|
};
|
||||||
|
use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
|
||||||
|
|
||||||
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
|
use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
|
||||||
@ -974,8 +974,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||||||
let poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
|
let poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
|
||||||
let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
|
let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
|
||||||
let _ = selcx.infcx().commit_if_ok(|_| {
|
let _ = selcx.infcx().commit_if_ok(|_| {
|
||||||
let vtable = match selcx.select(&trait_obligation) {
|
let impl_source = match selcx.select(&trait_obligation) {
|
||||||
Ok(Some(vtable)) => vtable,
|
Ok(Some(impl_source)) => impl_source,
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
candidate_set.mark_ambiguous();
|
candidate_set.mark_ambiguous();
|
||||||
return Err(());
|
return Err(());
|
||||||
@ -987,16 +987,16 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let eligible = match &vtable {
|
let eligible = match &impl_source {
|
||||||
super::VtableClosure(_)
|
super::ImplSourceClosure(_)
|
||||||
| super::VtableGenerator(_)
|
| super::ImplSourceGenerator(_)
|
||||||
| super::VtableFnPointer(_)
|
| super::ImplSourceFnPointer(_)
|
||||||
| super::VtableObject(_)
|
| super::ImplSourceObject(_)
|
||||||
| super::VtableTraitAlias(_) => {
|
| super::ImplSourceTraitAlias(_) => {
|
||||||
debug!("assemble_candidates_from_impls: vtable={:?}", vtable);
|
debug!("assemble_candidates_from_impls: impl_source={:?}", impl_source);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
super::VtableImpl(impl_data) => {
|
super::ImplSourceUserDefined(impl_data) => {
|
||||||
// We have to be careful when projecting out of an
|
// We have to be careful when projecting out of an
|
||||||
// impl because of specialization. If we are not in
|
// impl because of specialization. If we are not in
|
||||||
// codegen (i.e., projection mode is not "any"), and the
|
// codegen (i.e., projection mode is not "any"), and the
|
||||||
@ -1048,7 +1048,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super::VtableDiscriminantKind(..) => {
|
super::ImplSourceDiscriminantKind(..) => {
|
||||||
// While `DiscriminantKind` is automatically implemented for every type,
|
// While `DiscriminantKind` is automatically implemented for every type,
|
||||||
// the concrete discriminant may not be known yet.
|
// the concrete discriminant may not be known yet.
|
||||||
//
|
//
|
||||||
@ -1088,7 +1088,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||||||
| ty::Error => false,
|
| ty::Error => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super::VtableParam(..) => {
|
super::ImplSourceParam(..) => {
|
||||||
// This case tell us nothing about the value of an
|
// This case tell us nothing about the value of an
|
||||||
// associated type. Consider:
|
// associated type. Consider:
|
||||||
//
|
//
|
||||||
@ -1116,18 +1116,18 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||||||
// in `assemble_candidates_from_param_env`.
|
// in `assemble_candidates_from_param_env`.
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
super::VtableAutoImpl(..) | super::VtableBuiltin(..) => {
|
super::ImplSourceAutoImpl(..) | super::ImplSourceBuiltin(..) => {
|
||||||
// These traits have no associated types.
|
// These traits have no associated types.
|
||||||
span_bug!(
|
span_bug!(
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
"Cannot project an associated type from `{:?}`",
|
"Cannot project an associated type from `{:?}`",
|
||||||
vtable
|
impl_source
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if eligible {
|
if eligible {
|
||||||
if candidate_set.push_candidate(ProjectionTyCandidate::Select(vtable)) {
|
if candidate_set.push_candidate(ProjectionTyCandidate::Select(impl_source)) {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
@ -1152,8 +1152,8 @@ fn confirm_candidate<'cx, 'tcx>(
|
|||||||
confirm_param_env_candidate(selcx, obligation, poly_projection)
|
confirm_param_env_candidate(selcx, obligation, poly_projection)
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectionTyCandidate::Select(vtable) => {
|
ProjectionTyCandidate::Select(impl_source) => {
|
||||||
confirm_select_candidate(selcx, obligation, obligation_trait_ref, vtable)
|
confirm_select_candidate(selcx, obligation, obligation_trait_ref, impl_source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1162,26 +1162,29 @@ fn confirm_select_candidate<'cx, 'tcx>(
|
|||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
obligation_trait_ref: &ty::TraitRef<'tcx>,
|
obligation_trait_ref: &ty::TraitRef<'tcx>,
|
||||||
vtable: Selection<'tcx>,
|
impl_source: Selection<'tcx>,
|
||||||
) -> Progress<'tcx> {
|
) -> Progress<'tcx> {
|
||||||
match vtable {
|
match impl_source {
|
||||||
super::VtableImpl(data) => confirm_impl_candidate(selcx, obligation, data),
|
super::ImplSourceUserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
|
||||||
super::VtableGenerator(data) => confirm_generator_candidate(selcx, obligation, data),
|
super::ImplSourceGenerator(data) => confirm_generator_candidate(selcx, obligation, data),
|
||||||
super::VtableClosure(data) => confirm_closure_candidate(selcx, obligation, data),
|
super::ImplSourceClosure(data) => confirm_closure_candidate(selcx, obligation, data),
|
||||||
super::VtableFnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
|
super::ImplSourceFnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
|
||||||
super::VtableDiscriminantKind(data) => {
|
super::ImplSourceDiscriminantKind(data) => {
|
||||||
confirm_discriminant_kind_candidate(selcx, obligation, data)
|
confirm_discriminant_kind_candidate(selcx, obligation, data)
|
||||||
}
|
}
|
||||||
super::VtableObject(_) => confirm_object_candidate(selcx, obligation, obligation_trait_ref),
|
super::ImplSourceObject(_) => {
|
||||||
super::VtableAutoImpl(..)
|
confirm_object_candidate(selcx, obligation, obligation_trait_ref)
|
||||||
| super::VtableParam(..)
|
}
|
||||||
| super::VtableBuiltin(..)
|
super::ImplSourceAutoImpl(..)
|
||||||
| super::VtableTraitAlias(..) => {
|
| super::ImplSourceParam(..)
|
||||||
// we don't create Select candidates with this kind of resolution
|
| super::ImplSourceBuiltin(..)
|
||||||
|
| super::ImplSourceTraitAlias(..) =>
|
||||||
|
// we don't create Select candidates with this kind of resolution
|
||||||
|
{
|
||||||
span_bug!(
|
span_bug!(
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
"Cannot project an associated type from `{:?}`",
|
"Cannot project an associated type from `{:?}`",
|
||||||
vtable
|
impl_source
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1255,9 +1258,9 @@ fn confirm_object_candidate<'cx, 'tcx>(
|
|||||||
fn confirm_generator_candidate<'cx, 'tcx>(
|
fn confirm_generator_candidate<'cx, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
vtable: VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
|
impl_source: ImplSourceGeneratorData<'tcx, PredicateObligation<'tcx>>,
|
||||||
) -> Progress<'tcx> {
|
) -> Progress<'tcx> {
|
||||||
let gen_sig = vtable.substs.as_generator().poly_sig();
|
let gen_sig = impl_source.substs.as_generator().poly_sig();
|
||||||
let Normalized { value: gen_sig, obligations } = normalize_with_depth(
|
let Normalized { value: gen_sig, obligations } = normalize_with_depth(
|
||||||
selcx,
|
selcx,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
@ -1301,14 +1304,14 @@ fn confirm_generator_candidate<'cx, 'tcx>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
confirm_param_env_candidate(selcx, obligation, predicate)
|
confirm_param_env_candidate(selcx, obligation, predicate)
|
||||||
.with_addl_obligations(vtable.nested)
|
.with_addl_obligations(impl_source.nested)
|
||||||
.with_addl_obligations(obligations)
|
.with_addl_obligations(obligations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
|
fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
_: VtableDiscriminantKindData,
|
_: ImplSourceDiscriminantKindData,
|
||||||
) -> Progress<'tcx> {
|
) -> Progress<'tcx> {
|
||||||
let tcx = selcx.tcx();
|
let tcx = selcx.tcx();
|
||||||
|
|
||||||
@ -1339,9 +1342,9 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
|
|||||||
fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
fn_pointer_vtable: VtableFnPointerData<'tcx, PredicateObligation<'tcx>>,
|
fn_pointer_impl_source: ImplSourceFnPointerData<'tcx, PredicateObligation<'tcx>>,
|
||||||
) -> Progress<'tcx> {
|
) -> Progress<'tcx> {
|
||||||
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
|
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_impl_source.fn_ty);
|
||||||
let sig = fn_type.fn_sig(selcx.tcx());
|
let sig = fn_type.fn_sig(selcx.tcx());
|
||||||
let Normalized { value: sig, obligations } = normalize_with_depth(
|
let Normalized { value: sig, obligations } = normalize_with_depth(
|
||||||
selcx,
|
selcx,
|
||||||
@ -1352,16 +1355,16 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
|
confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
|
||||||
.with_addl_obligations(fn_pointer_vtable.nested)
|
.with_addl_obligations(fn_pointer_impl_source.nested)
|
||||||
.with_addl_obligations(obligations)
|
.with_addl_obligations(obligations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_closure_candidate<'cx, 'tcx>(
|
fn confirm_closure_candidate<'cx, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>,
|
impl_source: ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>,
|
||||||
) -> Progress<'tcx> {
|
) -> Progress<'tcx> {
|
||||||
let closure_sig = vtable.substs.as_closure().sig();
|
let closure_sig = impl_source.substs.as_closure().sig();
|
||||||
let Normalized { value: closure_sig, obligations } = normalize_with_depth(
|
let Normalized { value: closure_sig, obligations } = normalize_with_depth(
|
||||||
selcx,
|
selcx,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
@ -1376,7 +1379,7 @@ fn confirm_closure_candidate<'cx, 'tcx>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No)
|
confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No)
|
||||||
.with_addl_obligations(vtable.nested)
|
.with_addl_obligations(impl_source.nested)
|
||||||
.with_addl_obligations(obligations)
|
.with_addl_obligations(obligations)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1446,11 +1449,11 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
|
|||||||
fn confirm_impl_candidate<'cx, 'tcx>(
|
fn confirm_impl_candidate<'cx, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
impl_vtable: VtableImplData<'tcx, PredicateObligation<'tcx>>,
|
impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
|
||||||
) -> Progress<'tcx> {
|
) -> Progress<'tcx> {
|
||||||
let tcx = selcx.tcx();
|
let tcx = selcx.tcx();
|
||||||
|
|
||||||
let VtableImplData { impl_def_id, substs, nested } = impl_vtable;
|
let ImplSourceUserDefinedData { impl_def_id, substs, nested } = impl_impl_source;
|
||||||
let assoc_item_id = obligation.predicate.item_def_id;
|
let assoc_item_id = obligation.predicate.item_def_id;
|
||||||
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
|
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
|
||||||
|
|
||||||
|
@ -24,18 +24,19 @@ use crate::traits::OutputTypeParameterMismatch;
|
|||||||
use crate::traits::Selection;
|
use crate::traits::Selection;
|
||||||
use crate::traits::TraitNotObjectSafe;
|
use crate::traits::TraitNotObjectSafe;
|
||||||
use crate::traits::{BuiltinDerivedObligation, ImplDerivedObligation};
|
use crate::traits::{BuiltinDerivedObligation, ImplDerivedObligation};
|
||||||
|
use crate::traits::{
|
||||||
|
ImplSourceAutoImpl, ImplSourceBuiltin, ImplSourceClosure, ImplSourceDiscriminantKind,
|
||||||
|
ImplSourceFnPointer, ImplSourceGenerator, ImplSourceObject, ImplSourceParam,
|
||||||
|
ImplSourceTraitAlias, ImplSourceUserDefined,
|
||||||
|
};
|
||||||
|
use crate::traits::{
|
||||||
|
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||||
|
ImplSourceDiscriminantKindData, ImplSourceFnPointerData, ImplSourceGeneratorData,
|
||||||
|
ImplSourceObjectData, ImplSourceTraitAliasData, ImplSourceUserDefinedData,
|
||||||
|
};
|
||||||
use crate::traits::{ObjectCastObligation, PredicateObligation, TraitObligation};
|
use crate::traits::{ObjectCastObligation, PredicateObligation, TraitObligation};
|
||||||
use crate::traits::{Obligation, ObligationCause};
|
use crate::traits::{Obligation, ObligationCause};
|
||||||
use crate::traits::{SelectionError, Unimplemented};
|
use crate::traits::{SelectionError, Unimplemented};
|
||||||
use crate::traits::{
|
|
||||||
VtableAutoImpl, VtableBuiltin, VtableClosure, VtableDiscriminantKind, VtableFnPointer,
|
|
||||||
VtableGenerator, VtableImpl, VtableObject, VtableParam, VtableTraitAlias,
|
|
||||||
};
|
|
||||||
use crate::traits::{
|
|
||||||
VtableAutoImplData, VtableBuiltinData, VtableClosureData, VtableDiscriminantKindData,
|
|
||||||
VtableFnPointerData, VtableGeneratorData, VtableImplData, VtableObjectData,
|
|
||||||
VtableTraitAliasData,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::BuiltinImplConditions;
|
use super::BuiltinImplConditions;
|
||||||
use super::SelectionCandidate::{self, *};
|
use super::SelectionCandidate::{self, *};
|
||||||
@ -54,65 +55,67 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
match candidate {
|
match candidate {
|
||||||
BuiltinCandidate { has_nested } => {
|
BuiltinCandidate { has_nested } => {
|
||||||
let data = self.confirm_builtin_candidate(obligation, has_nested);
|
let data = self.confirm_builtin_candidate(obligation, has_nested);
|
||||||
Ok(VtableBuiltin(data))
|
Ok(ImplSourceBuiltin(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamCandidate(param) => {
|
ParamCandidate(param) => {
|
||||||
let obligations = self.confirm_param_candidate(obligation, param);
|
let obligations = self.confirm_param_candidate(obligation, param);
|
||||||
Ok(VtableParam(obligations))
|
Ok(ImplSourceParam(obligations))
|
||||||
}
|
}
|
||||||
|
|
||||||
ImplCandidate(impl_def_id) => {
|
ImplCandidate(impl_def_id) => {
|
||||||
Ok(VtableImpl(self.confirm_impl_candidate(obligation, impl_def_id)))
|
Ok(ImplSourceUserDefined(self.confirm_impl_candidate(obligation, impl_def_id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoImplCandidate(trait_def_id) => {
|
AutoImplCandidate(trait_def_id) => {
|
||||||
let data = self.confirm_auto_impl_candidate(obligation, trait_def_id);
|
let data = self.confirm_auto_impl_candidate(obligation, trait_def_id);
|
||||||
Ok(VtableAutoImpl(data))
|
Ok(ImplSourceAutoImpl(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectionCandidate => {
|
ProjectionCandidate => {
|
||||||
self.confirm_projection_candidate(obligation);
|
self.confirm_projection_candidate(obligation);
|
||||||
Ok(VtableParam(Vec::new()))
|
Ok(ImplSourceParam(Vec::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
ClosureCandidate => {
|
ClosureCandidate => {
|
||||||
let vtable_closure = self.confirm_closure_candidate(obligation)?;
|
let vtable_closure = self.confirm_closure_candidate(obligation)?;
|
||||||
Ok(VtableClosure(vtable_closure))
|
Ok(ImplSourceClosure(vtable_closure))
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneratorCandidate => {
|
GeneratorCandidate => {
|
||||||
let vtable_generator = self.confirm_generator_candidate(obligation)?;
|
let vtable_generator = self.confirm_generator_candidate(obligation)?;
|
||||||
Ok(VtableGenerator(vtable_generator))
|
Ok(ImplSourceGenerator(vtable_generator))
|
||||||
}
|
}
|
||||||
|
|
||||||
FnPointerCandidate => {
|
FnPointerCandidate => {
|
||||||
let data = self.confirm_fn_pointer_candidate(obligation)?;
|
let data = self.confirm_fn_pointer_candidate(obligation)?;
|
||||||
Ok(VtableFnPointer(data))
|
Ok(ImplSourceFnPointer(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscriminantKindCandidate => Ok(VtableDiscriminantKind(VtableDiscriminantKindData)),
|
DiscriminantKindCandidate => {
|
||||||
|
Ok(ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData))
|
||||||
|
}
|
||||||
|
|
||||||
TraitAliasCandidate(alias_def_id) => {
|
TraitAliasCandidate(alias_def_id) => {
|
||||||
let data = self.confirm_trait_alias_candidate(obligation, alias_def_id);
|
let data = self.confirm_trait_alias_candidate(obligation, alias_def_id);
|
||||||
Ok(VtableTraitAlias(data))
|
Ok(ImplSourceTraitAlias(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectCandidate => {
|
ObjectCandidate => {
|
||||||
let data = self.confirm_object_candidate(obligation);
|
let data = self.confirm_object_candidate(obligation);
|
||||||
Ok(VtableObject(data))
|
Ok(ImplSourceObject(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
BuiltinObjectCandidate => {
|
BuiltinObjectCandidate => {
|
||||||
// This indicates something like `Trait + Send: Send`. In this case, we know that
|
// 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
|
// 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.
|
// no additional obligations to prove and no types in particular to unify, etc.
|
||||||
Ok(VtableParam(Vec::new()))
|
Ok(ImplSourceParam(Vec::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
BuiltinUnsizeCandidate => {
|
BuiltinUnsizeCandidate => {
|
||||||
let data = self.confirm_builtin_unsize_candidate(obligation)?;
|
let data = self.confirm_builtin_unsize_candidate(obligation)?;
|
||||||
Ok(VtableBuiltin(data))
|
Ok(ImplSourceBuiltin(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,7 +155,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
has_nested: bool,
|
has_nested: bool,
|
||||||
) -> VtableBuiltinData<PredicateObligation<'tcx>> {
|
) -> ImplSourceBuiltinData<PredicateObligation<'tcx>> {
|
||||||
debug!("confirm_builtin_candidate({:?}, {:?})", obligation, has_nested);
|
debug!("confirm_builtin_candidate({:?}, {:?})", obligation, has_nested);
|
||||||
|
|
||||||
let lang_items = self.tcx().lang_items();
|
let lang_items = self.tcx().lang_items();
|
||||||
@ -188,7 +191,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
|
|
||||||
debug!("confirm_builtin_candidate: obligations={:?}", obligations);
|
debug!("confirm_builtin_candidate: obligations={:?}", obligations);
|
||||||
|
|
||||||
VtableBuiltinData { nested: obligations }
|
ImplSourceBuiltinData { nested: obligations }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This handles the case where a `auto trait Foo` impl is being used.
|
/// This handles the case where a `auto trait Foo` impl is being used.
|
||||||
@ -200,7 +203,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
) -> VtableAutoImplData<PredicateObligation<'tcx>> {
|
) -> ImplSourceAutoImplData<PredicateObligation<'tcx>> {
|
||||||
debug!("confirm_auto_impl_candidate({:?}, {:?})", obligation, trait_def_id);
|
debug!("confirm_auto_impl_candidate({:?}, {:?})", obligation, trait_def_id);
|
||||||
|
|
||||||
let types = obligation.predicate.map_bound(|inner| {
|
let types = obligation.predicate.map_bound(|inner| {
|
||||||
@ -216,7 +219,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
nested: ty::Binder<Vec<Ty<'tcx>>>,
|
nested: ty::Binder<Vec<Ty<'tcx>>>,
|
||||||
) -> VtableAutoImplData<PredicateObligation<'tcx>> {
|
) -> ImplSourceAutoImplData<PredicateObligation<'tcx>> {
|
||||||
debug!("vtable_auto_impl: nested={:?}", nested);
|
debug!("vtable_auto_impl: nested={:?}", nested);
|
||||||
ensure_sufficient_stack(|| {
|
ensure_sufficient_stack(|| {
|
||||||
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
||||||
@ -249,7 +252,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
|
|
||||||
debug!("vtable_auto_impl: obligations={:?}", obligations);
|
debug!("vtable_auto_impl: obligations={:?}", obligations);
|
||||||
|
|
||||||
VtableAutoImplData { trait_def_id, nested: obligations }
|
ImplSourceAutoImplData { trait_def_id, nested: obligations }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +260,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
impl_def_id: DefId,
|
impl_def_id: DefId,
|
||||||
) -> VtableImplData<'tcx, PredicateObligation<'tcx>> {
|
) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
|
||||||
debug!("confirm_impl_candidate({:?},{:?})", obligation, impl_def_id);
|
debug!("confirm_impl_candidate({:?},{:?})", obligation, impl_def_id);
|
||||||
|
|
||||||
// First, create the substitutions by matching the impl again,
|
// First, create the substitutions by matching the impl again,
|
||||||
@ -285,7 +288,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
recursion_depth: usize,
|
recursion_depth: usize,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> VtableImplData<'tcx, PredicateObligation<'tcx>> {
|
) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
|
||||||
debug!(
|
debug!(
|
||||||
"vtable_impl(impl_def_id={:?}, substs={:?}, recursion_depth={})",
|
"vtable_impl(impl_def_id={:?}, substs={:?}, recursion_depth={})",
|
||||||
impl_def_id, substs, recursion_depth,
|
impl_def_id, substs, recursion_depth,
|
||||||
@ -311,13 +314,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// e.g., `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V`
|
// e.g., `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V`
|
||||||
impl_obligations.append(&mut substs.obligations);
|
impl_obligations.append(&mut substs.obligations);
|
||||||
|
|
||||||
VtableImplData { impl_def_id, substs: substs.value, nested: impl_obligations }
|
ImplSourceUserDefinedData { impl_def_id, substs: substs.value, nested: impl_obligations }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_object_candidate(
|
fn confirm_object_candidate(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
) -> VtableObjectData<'tcx, PredicateObligation<'tcx>> {
|
) -> ImplSourceObjectData<'tcx, PredicateObligation<'tcx>> {
|
||||||
debug!("confirm_object_candidate({:?})", obligation);
|
debug!("confirm_object_candidate({:?})", obligation);
|
||||||
|
|
||||||
// FIXME(nmatsakis) skipping binder here seems wrong -- we should
|
// FIXME(nmatsakis) skipping binder here seems wrong -- we should
|
||||||
@ -366,13 +369,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
vtable_base = nonmatching.map(|t| super::util::count_own_vtable_entries(tcx, t)).sum();
|
vtable_base = nonmatching.map(|t| super::util::count_own_vtable_entries(tcx, t)).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
VtableObjectData { upcast_trait_ref: upcast_trait_ref.unwrap(), vtable_base, nested }
|
ImplSourceObjectData { upcast_trait_ref: upcast_trait_ref.unwrap(), vtable_base, nested }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_fn_pointer_candidate(
|
fn confirm_fn_pointer_candidate(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
) -> Result<VtableFnPointerData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
) -> Result<ImplSourceFnPointerData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
|
||||||
|
{
|
||||||
debug!("confirm_fn_pointer_candidate({:?})", obligation);
|
debug!("confirm_fn_pointer_candidate({:?})", obligation);
|
||||||
|
|
||||||
// Okay to skip binder; it is reintroduced below.
|
// Okay to skip binder; it is reintroduced below.
|
||||||
@ -403,14 +407,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
obligation.predicate.to_poly_trait_ref(),
|
obligation.predicate.to_poly_trait_ref(),
|
||||||
trait_ref,
|
trait_ref,
|
||||||
)?;
|
)?;
|
||||||
Ok(VtableFnPointerData { fn_ty: self_ty, nested: obligations })
|
Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested: obligations })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_trait_alias_candidate(
|
fn confirm_trait_alias_candidate(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
alias_def_id: DefId,
|
alias_def_id: DefId,
|
||||||
) -> VtableTraitAliasData<'tcx, PredicateObligation<'tcx>> {
|
) -> ImplSourceTraitAliasData<'tcx, PredicateObligation<'tcx>> {
|
||||||
debug!("confirm_trait_alias_candidate({:?}, {:?})", obligation, alias_def_id);
|
debug!("confirm_trait_alias_candidate({:?}, {:?})", obligation, alias_def_id);
|
||||||
|
|
||||||
self.infcx.commit_unconditionally(|_| {
|
self.infcx.commit_unconditionally(|_| {
|
||||||
@ -433,14 +437,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
trait_def_id, trait_obligations
|
trait_def_id, trait_obligations
|
||||||
);
|
);
|
||||||
|
|
||||||
VtableTraitAliasData { alias_def_id, substs, nested: trait_obligations }
|
ImplSourceTraitAliasData { alias_def_id, substs, nested: trait_obligations }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_generator_candidate(
|
fn confirm_generator_candidate(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
) -> Result<VtableGeneratorData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
) -> Result<ImplSourceGeneratorData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
|
||||||
|
{
|
||||||
// Okay to skip binder because the substs on generator types never
|
// Okay to skip binder because the substs on generator types never
|
||||||
// touch bound regions, they just capture the in-scope
|
// touch bound regions, they just capture the in-scope
|
||||||
// type/region parameters.
|
// type/region parameters.
|
||||||
@ -476,13 +481,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
trait_ref,
|
trait_ref,
|
||||||
)?);
|
)?);
|
||||||
|
|
||||||
Ok(VtableGeneratorData { generator_def_id, substs, nested: obligations })
|
Ok(ImplSourceGeneratorData { generator_def_id, substs, nested: obligations })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_closure_candidate(
|
fn confirm_closure_candidate(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
) -> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
) -> Result<ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||||
debug!("confirm_closure_candidate({:?})", obligation);
|
debug!("confirm_closure_candidate({:?})", obligation);
|
||||||
|
|
||||||
let kind = self
|
let kind = self
|
||||||
@ -533,7 +538,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(VtableClosureData { closure_def_id, substs, nested: obligations })
|
Ok(ImplSourceClosureData { closure_def_id, substs, nested: obligations })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In the case of closure types and fn pointers,
|
/// In the case of closure types and fn pointers,
|
||||||
@ -578,7 +583,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
fn confirm_builtin_unsize_candidate(
|
fn confirm_builtin_unsize_candidate(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
) -> Result<VtableBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
) -> Result<ImplSourceBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
// `assemble_candidates_for_unsizing` should ensure there are no late-bound
|
// `assemble_candidates_for_unsizing` should ensure there are no late-bound
|
||||||
@ -815,6 +820,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(VtableBuiltinData { nested })
|
Ok(ImplSourceBuiltinData { nested })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ pub fn count_own_vtable_entries(tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'
|
|||||||
/// `object.upcast_trait_ref`) within the vtable for `object`.
|
/// `object.upcast_trait_ref`) within the vtable for `object`.
|
||||||
pub fn get_vtable_index_of_object_method<N>(
|
pub fn get_vtable_index_of_object_method<N>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
object: &super::VtableObjectData<'tcx, N>,
|
object: &super::ImplSourceObjectData<'tcx, N>,
|
||||||
method_def_id: DefId,
|
method_def_id: DefId,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
// Count number of methods preceding the one we are selecting and
|
// Count number of methods preceding the one we are selecting and
|
||||||
|
@ -84,9 +84,9 @@ fn resolve_associated_item<'tcx>(
|
|||||||
// Now that we know which impl is being used, we can dispatch to
|
// Now that we know which impl is being used, we can dispatch to
|
||||||
// the actual function:
|
// the actual function:
|
||||||
Ok(match vtbl {
|
Ok(match vtbl {
|
||||||
traits::VtableImpl(impl_data) => {
|
traits::ImplSourceUserDefined(impl_data) => {
|
||||||
debug!(
|
debug!(
|
||||||
"resolving VtableImpl: {:?}, {:?}, {:?}, {:?}",
|
"resolving ImplSourceUserDefined: {:?}, {:?}, {:?}, {:?}",
|
||||||
param_env, trait_item, rcvr_substs, impl_data
|
param_env, trait_item, rcvr_substs, impl_data
|
||||||
);
|
);
|
||||||
assert!(!rcvr_substs.needs_infer());
|
assert!(!rcvr_substs.needs_infer());
|
||||||
@ -181,11 +181,11 @@ fn resolve_associated_item<'tcx>(
|
|||||||
|
|
||||||
Some(ty::Instance::new(leaf_def.item.def_id, substs))
|
Some(ty::Instance::new(leaf_def.item.def_id, substs))
|
||||||
}
|
}
|
||||||
traits::VtableGenerator(generator_data) => Some(Instance {
|
traits::ImplSourceGenerator(generator_data) => Some(Instance {
|
||||||
def: ty::InstanceDef::Item(generator_data.generator_def_id),
|
def: ty::InstanceDef::Item(generator_data.generator_def_id),
|
||||||
substs: generator_data.substs,
|
substs: generator_data.substs,
|
||||||
}),
|
}),
|
||||||
traits::VtableClosure(closure_data) => {
|
traits::ImplSourceClosure(closure_data) => {
|
||||||
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
|
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
|
||||||
Some(Instance::resolve_closure(
|
Some(Instance::resolve_closure(
|
||||||
tcx,
|
tcx,
|
||||||
@ -194,7 +194,7 @@ fn resolve_associated_item<'tcx>(
|
|||||||
trait_closure_kind,
|
trait_closure_kind,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
traits::VtableFnPointer(ref data) => {
|
traits::ImplSourceFnPointer(ref data) => {
|
||||||
// `FnPtrShim` requires a monomorphic aka concrete type.
|
// `FnPtrShim` requires a monomorphic aka concrete type.
|
||||||
if data.fn_ty.needs_subst() {
|
if data.fn_ty.needs_subst() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
@ -205,11 +205,11 @@ fn resolve_associated_item<'tcx>(
|
|||||||
substs: rcvr_substs,
|
substs: rcvr_substs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
traits::VtableObject(ref data) => {
|
traits::ImplSourceObject(ref data) => {
|
||||||
let index = traits::get_vtable_index_of_object_method(tcx, data, def_id);
|
let index = traits::get_vtable_index_of_object_method(tcx, data, def_id);
|
||||||
Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
|
Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
|
||||||
}
|
}
|
||||||
traits::VtableBuiltin(..) => {
|
traits::ImplSourceBuiltin(..) => {
|
||||||
if Some(trait_ref.def_id) == tcx.lang_items().clone_trait() {
|
if Some(trait_ref.def_id) == tcx.lang_items().clone_trait() {
|
||||||
// FIXME(eddyb) use lang items for methods instead of names.
|
// FIXME(eddyb) use lang items for methods instead of names.
|
||||||
let name = tcx.item_name(def_id);
|
let name = tcx.item_name(def_id);
|
||||||
@ -236,10 +236,10 @@ fn resolve_associated_item<'tcx>(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
traits::VtableAutoImpl(..)
|
traits::ImplSourceAutoImpl(..)
|
||||||
| traits::VtableParam(..)
|
| traits::ImplSourceParam(..)
|
||||||
| traits::VtableTraitAlias(..)
|
| traits::ImplSourceTraitAlias(..)
|
||||||
| traits::VtableDiscriminantKind(..) => None,
|
| traits::ImplSourceDiscriminantKind(..) => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,7 +657,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
// be silent, as it causes a type mismatch later.
|
// be silent, as it causes a type mismatch later.
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(vtable)) => queue.extend(vtable.nested_obligations()),
|
Ok(Some(impl_source)) => queue.extend(impl_source.nested_obligations()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1303,7 +1303,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
.at(&ObligationCause::dummy(), self.param_env)
|
.at(&ObligationCause::dummy(), self.param_env)
|
||||||
.sup(candidate.xform_self_ty, self_ty);
|
.sup(candidate.xform_self_ty, self_ty);
|
||||||
match self.select_trait_candidate(trait_ref) {
|
match self.select_trait_candidate(trait_ref) {
|
||||||
Ok(Some(traits::Vtable::VtableImpl(ref impl_data))) => {
|
Ok(Some(traits::ImplSource::ImplSourceUserDefined(ref impl_data))) => {
|
||||||
// If only a single impl matches, make the error message point
|
// If only a single impl matches, make the error message point
|
||||||
// to that impl.
|
// to that impl.
|
||||||
ImplSource(impl_data.impl_def_id)
|
ImplSource(impl_data.impl_def_id)
|
||||||
@ -1384,10 +1384,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
if self.probe(|_| {
|
if self.probe(|_| {
|
||||||
match self.select_trait_candidate(trait_ref) {
|
match self.select_trait_candidate(trait_ref) {
|
||||||
Err(_) => return true,
|
Err(_) => return true,
|
||||||
Ok(Some(vtable))
|
Ok(Some(impl_source))
|
||||||
if !vtable.borrow_nested_obligations().is_empty() =>
|
if !impl_source.borrow_nested_obligations().is_empty() =>
|
||||||
{
|
{
|
||||||
for obligation in vtable.borrow_nested_obligations() {
|
for obligation in impl_source.borrow_nested_obligations() {
|
||||||
// Determine exactly which obligation wasn't met, so
|
// Determine exactly which obligation wasn't met, so
|
||||||
// that we can give more context in the error.
|
// that we can give more context in the error.
|
||||||
if !self.predicate_may_hold(&obligation) {
|
if !self.predicate_may_hold(&obligation) {
|
||||||
|
@ -31,9 +31,6 @@ can be broken down into several distinct phases:
|
|||||||
final assignments of the various region variables if there is some
|
final assignments of the various region variables if there is some
|
||||||
flexibility.
|
flexibility.
|
||||||
|
|
||||||
- vtable: find and records the impls to use for each trait bound that
|
|
||||||
appears on a type parameter.
|
|
||||||
|
|
||||||
- writeback: writes the final types within a function body, replacing
|
- writeback: writes the final types within a function body, replacing
|
||||||
type variables with their final inferred types. These final types
|
type variables with their final inferred types. These final types
|
||||||
are written into the `tcx.node_types` table, which should *never* contain
|
are written into the `tcx.node_types` table, which should *never* contain
|
||||||
@ -4070,7 +4067,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
debug!("check_closures={}", check_closures);
|
debug!("check_closures={}", check_closures);
|
||||||
|
|
||||||
// More awful hacks: before we check argument types, try to do
|
// More awful hacks: before we check argument types, try to do
|
||||||
// an "opportunistic" vtable resolution of any trait bounds on
|
// an "opportunistic" trait resolution of any trait bounds on
|
||||||
// the call. This helps coercions.
|
// the call. This helps coercions.
|
||||||
if check_closures {
|
if check_closures {
|
||||||
self.select_obligations_where_possible(false, |errors| {
|
self.select_obligations_where_possible(false, |errors| {
|
||||||
|
Loading…
Reference in New Issue
Block a user