Pack Term in the same way as GenericArg.

This shrinks the `PredicateS` type, which is instanted frequently.
This commit is contained in:
Nicholas Nethercote 2022-09-05 14:03:53 +10:00
parent d565d51071
commit 79db32b64e
20 changed files with 191 additions and 108 deletions

View File

@ -1586,28 +1586,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
Some(values) => {
let values = self.resolve_vars_if_possible(values);
let (is_simple_error, exp_found) = match values {
ValuePairs::Terms(infer::ExpectedFound {
expected: ty::Term::Ty(expected),
found: ty::Term::Ty(found),
}) => {
let is_simple_err = expected.is_simple_text() && found.is_simple_text();
OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
.report(diag);
ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
match (expected.unpack(), found.unpack()) {
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
let is_simple_err =
expected.is_simple_text() && found.is_simple_text();
OpaqueTypesVisitor::visit_expected_found(
self.tcx, expected, found, span,
)
.report(diag);
(
is_simple_err,
Mismatch::Variable(infer::ExpectedFound { expected, found }),
)
(
is_simple_err,
Mismatch::Variable(infer::ExpectedFound { expected, found }),
)
}
(ty::TermKind::Const(_), ty::TermKind::Const(_)) => {
(false, Mismatch::Fixed("constant"))
}
_ => (false, Mismatch::Fixed("type")),
}
}
ValuePairs::Terms(infer::ExpectedFound {
expected: ty::Term::Const(_),
found: ty::Term::Const(_),
}) => (false, Mismatch::Fixed("constant")),
ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
(false, Mismatch::Fixed("trait"))
}
ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")),
_ => (false, Mismatch::Fixed("type")),
};
let vals = match self.values_str(values) {
Some((expected, found)) => Some((expected, found)),
@ -2273,11 +2276,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
return None;
}
Some(match (exp_found.expected, exp_found.found) {
(ty::Term::Ty(expected), ty::Term::Ty(found)) => self.cmp(expected, found),
(expected, found) => (
DiagnosticStyledString::highlighted(expected.to_string()),
DiagnosticStyledString::highlighted(found.to_string()),
Some(match (exp_found.expected.unpack(), exp_found.found.unpack()) {
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => self.cmp(expected, found),
_ => (
DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
DiagnosticStyledString::highlighted(exp_found.found.to_string()),
),
})
}

View File

@ -353,12 +353,11 @@ pub enum ValuePairs<'tcx> {
impl<'tcx> ValuePairs<'tcx> {
pub fn ty(&self) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
if let ValuePairs::Terms(ExpectedFound {
expected: ty::Term::Ty(expected),
found: ty::Term::Ty(found),
}) = self
if let ValuePairs::Terms(ExpectedFound { expected, found }) = self
&& let Some(expected) = expected.ty()
&& let Some(found) = found.ty()
{
Some((*expected, *found))
Some((expected, found))
} else {
None
}

View File

@ -1,5 +1,5 @@
use crate::ty::subst::{GenericArg, GenericArgKind};
use crate::ty::{self, InferConst, Term, Ty, TypeFlags};
use crate::ty::{self, InferConst, Ty, TypeFlags};
use std::slice;
#[derive(Debug)]
@ -243,9 +243,9 @@ impl FlagComputation {
}
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
self.add_projection_ty(projection_ty);
match term {
Term::Ty(ty) => self.add_ty(ty),
Term::Const(c) => self.add_const(c),
match term.unpack() {
ty::TermKind::Ty(ty) => self.add_ty(ty),
ty::TermKind::Const(c) => self.add_const(c),
}
}
ty::PredicateKind::WellFormed(arg) => {
@ -320,9 +320,9 @@ impl FlagComputation {
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
self.add_substs(projection.substs);
match projection.term {
ty::Term::Ty(ty) => self.add_ty(ty),
ty::Term::Const(ct) => self.add_const(ct),
match projection.term.unpack() {
ty::TermKind::Ty(ty) => self.add_ty(ty),
ty::TermKind::Const(ct) => self.add_const(ct),
}
}

View File

@ -40,6 +40,7 @@ use rustc_hir::Node;
use rustc_index::vec::IndexVec;
use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext;
use rustc_serialize::{Decodable, Encodable};
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{ExpnId, Span};
@ -49,6 +50,9 @@ pub use vtable::*;
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::mem;
use std::num::NonZeroUsize;
use std::ops::ControlFlow;
use std::{fmt, str};
@ -902,42 +906,122 @@ pub struct CoercePredicate<'tcx> {
}
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)]
pub enum Term<'tcx> {
Ty(Ty<'tcx>),
Const(Const<'tcx>),
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Term<'tcx> {
ptr: NonZeroUsize,
marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
}
impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
fn from(ty: Ty<'tcx>) -> Self {
Term::Ty(ty)
TermKind::Ty(ty).pack()
}
}
impl<'tcx> From<Const<'tcx>> for Term<'tcx> {
fn from(c: Const<'tcx>) -> Self {
Term::Const(c)
TermKind::Const(c).pack()
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
self.unpack().hash_stable(hcx, hasher);
}
}
impl<'tcx> TypeFoldable<'tcx> for Term<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
Ok(self.unpack().try_fold_with(folder)?.pack())
}
}
impl<'tcx> TypeVisitable<'tcx> for Term<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.unpack().visit_with(visitor)
}
}
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for Term<'tcx> {
fn encode(&self, e: &mut E) {
self.unpack().encode(e)
}
}
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Term<'tcx> {
fn decode(d: &mut D) -> Self {
let res: TermKind<'tcx> = Decodable::decode(d);
res.pack()
}
}
impl<'tcx> Term<'tcx> {
#[inline]
pub fn unpack(self) -> TermKind<'tcx> {
let ptr = self.ptr.get();
// SAFETY: use of `Interned::new_unchecked` here is ok because these
// pointers were originally created from `Interned` types in `pack()`,
// and this is just going in the other direction.
unsafe {
match ptr & TAG_MASK {
TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const WithStableHash<ty::TyS<'tcx>>),
))),
CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),
))),
_ => core::intrinsics::unreachable(),
}
}
}
pub fn ty(&self) -> Option<Ty<'tcx>> {
if let Term::Ty(ty) = self { Some(*ty) } else { None }
if let TermKind::Ty(ty) = self.unpack() { Some(ty) } else { None }
}
pub fn ct(&self) -> Option<Const<'tcx>> {
if let Term::Const(c) = self { Some(*c) } else { None }
if let TermKind::Const(c) = self.unpack() { Some(c) } else { None }
}
pub fn into_arg(self) -> GenericArg<'tcx> {
match self {
Term::Ty(ty) => ty.into(),
Term::Const(c) => c.into(),
match self.unpack() {
TermKind::Ty(ty) => ty.into(),
TermKind::Const(c) => c.into(),
}
}
}
const TAG_MASK: usize = 0b11;
const TYPE_TAG: usize = 0b00;
const CONST_TAG: usize = 0b01;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)]
pub enum TermKind<'tcx> {
Ty(Ty<'tcx>),
Const(Const<'tcx>),
}
impl<'tcx> TermKind<'tcx> {
#[inline]
fn pack(self) -> Term<'tcx> {
let (tag, ptr) = match self {
TermKind::Ty(ty) => {
// Ensure we can use the tag bits.
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
(TYPE_TAG, ty.0.0 as *const WithStableHash<ty::TyS<'tcx>> as usize)
}
TermKind::Const(ct) => {
// Ensure we can use the tag bits.
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
(CONST_TAG, ct.0.0 as *const ty::ConstS<'tcx> as usize)
}
};
Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
}
}
/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///
@ -2528,7 +2612,7 @@ mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain.
static_assert_size!(PredicateS<'_>, 56);
static_assert_size!(PredicateS<'_>, 48);
static_assert_size!(TyS<'_>, 40);
static_assert_size!(WithStableHash<TyS<'_>>, 56);
}

View File

@ -1,7 +1,7 @@
use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
use crate::ty::{
self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable,
self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
};
use rustc_apfloat::ieee::{Double, Single};
@ -855,7 +855,7 @@ pub trait PrettyPrinter<'tcx>:
}
p!(")");
if let Term::Ty(ty) = return_ty.skip_binder() {
if let Some(ty) = return_ty.skip_binder().ty() {
if !ty.is_unit() {
p!(" -> ", print(return_ty));
}
@ -942,13 +942,9 @@ pub trait PrettyPrinter<'tcx>:
p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name));
match term {
Term::Ty(ty) => {
p!(print(ty))
}
Term::Const(c) => {
p!(print(c));
}
match term.unpack() {
TermKind::Ty(ty) => p!(print(ty)),
TermKind::Const(c) => p!(print(c)),
};
}
@ -2608,9 +2604,9 @@ define_print_and_forward_display! {
}
ty::Term<'tcx> {
match self {
ty::Term::Ty(ty) => p!(print(ty)),
ty::Term::Const(c) => p!(print(c)),
match self.unpack() {
ty::TermKind::Ty(ty) => p!(print(ty)),
ty::TermKind::Const(c) => p!(print(c)),
}
}

View File

@ -6,7 +6,7 @@
use crate::ty::error::{ExpectedFound, TypeError};
use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
use crate::ty::{self, ImplSubject, Term, Ty, TyCtxt, TypeFoldable};
use crate::ty::{self, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable};
use rustc_hir as ast;
use rustc_hir::def_id::DefId;
use rustc_span::DUMMY_SP;
@ -803,15 +803,15 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
}
}
impl<'tcx> Relate<'tcx> for ty::Term<'tcx> {
impl<'tcx> Relate<'tcx> for Term<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: Self,
b: Self,
) -> RelateResult<'tcx, Self> {
Ok(match (a, b) {
(Term::Ty(a), Term::Ty(b)) => relation.relate(a, b)?.into(),
(Term::Const(a), Term::Const(b)) => relation.relate(a, b)?.into(),
Ok(match (a.unpack(), b.unpack()) {
(TermKind::Ty(a), TermKind::Ty(b)) => relation.relate(a, b)?.into(),
(TermKind::Const(a), TermKind::Const(b)) => relation.relate(a, b)?.into(),
_ => return Err(TypeError::Mismatch),
})
}

View File

@ -7,7 +7,7 @@ use crate::mir::ProjectionKind;
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt};
use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
use rustc_data_structures::functor::IdFunctor;
use rustc_hir as hir;
use rustc_hir::def::Namespace;
@ -344,10 +344,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
type Lifted = ty::Term<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
Some(match self {
Term::Ty(ty) => Term::Ty(tcx.lift(ty)?),
Term::Const(c) => Term::Const(tcx.lift(c)?),
})
Some(
match self.unpack() {
TermKind::Ty(ty) => TermKind::Ty(tcx.lift(ty)?),
TermKind::Const(c) => TermKind::Const(tcx.lift(c)?),
}
.pack(),
)
}
}

View File

@ -165,9 +165,9 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
}
};
substs.iter().rev().chain(opt_ty.map(|term| match term {
ty::Term::Ty(ty) => ty.into(),
ty::Term::Const(ct) => ct.into(),
substs.iter().rev().chain(opt_ty.map(|term| match term.unpack() {
ty::TermKind::Ty(ty) => ty.into(),
ty::TermKind::Const(ct) => ct.into(),
}))
}));
}

View File

@ -13,7 +13,7 @@ use rustc_hir as hir;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use rustc_middle::ty::{
self, Binder, Const, ExistentialPredicate, FloatTy, FnSig, IntTy, List, Region, RegionKind,
Term, Ty, TyCtxt, UintTy,
TermKind, Ty, TyCtxt, UintTy,
};
use rustc_span::def_id::DefId;
use rustc_span::symbol::sym;
@ -243,13 +243,9 @@ fn encode_predicate<'tcx>(
let name = encode_ty_name(tcx, projection.item_def_id);
let _ = write!(s, "u{}{}", name.len(), &name);
s.push_str(&encode_substs(tcx, projection.substs, dict, options));
match projection.term {
Term::Ty(ty) => {
s.push_str(&encode_ty(tcx, ty, dict, options));
}
Term::Const(c) => {
s.push_str(&encode_const(tcx, c, dict, options));
}
match projection.term.unpack() {
TermKind::Ty(ty) => s.push_str(&encode_ty(tcx, ty, dict, options)),
TermKind::Const(c) => s.push_str(&encode_const(tcx, c, dict, options)),
}
}
ty::ExistentialPredicate::AutoTrait(def_id) => {

View File

@ -543,9 +543,9 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
let name = cx.tcx.associated_item(projection.item_def_id).name;
cx.push("p");
cx.push_ident(name.as_str());
cx = match projection.term {
ty::Term::Ty(ty) => ty.print(cx),
ty::Term::Const(c) => c.print(cx),
cx = match projection.term.unpack() {
ty::TermKind::Ty(ty) => ty.print(cx),
ty::TermKind::Const(c) => c.print(cx),
}?;
}
ty::ExistentialPredicate::AutoTrait(def_id) => {

View File

@ -10,7 +10,7 @@ use crate::traits::project::ProjectAndUnifyResult;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{Region, RegionVid, Term};
use rustc_middle::ty::{Region, RegionVid};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@ -612,7 +612,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}
fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
if let Term::Ty(ty) = p.term().skip_binder() {
if let Some(ty) = p.term().skip_binder().ty() {
matches!(ty.kind(), ty::Projection(proj) if proj == &p.skip_binder().projection_ty)
} else {
false

View File

@ -552,7 +552,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
)
.ok()
.flatten()
.unwrap_or_else(|| ty::Term::Ty(ty.super_fold_with(self)))
.unwrap_or_else(|| ty.super_fold_with(self).into())
};
// For cases like #95134 we would like to catch overflows early
// otherwise they slip away away and cause ICE.

View File

@ -129,9 +129,9 @@ pub fn predicate_obligations<'a, 'tcx>(
}
ty::PredicateKind::Projection(t) => {
wf.compute_projection(t.projection_ty);
wf.compute(match t.term {
ty::Term::Ty(ty) => ty.into(),
ty::Term::Const(c) => c.into(),
wf.compute(match t.term.unpack() {
ty::TermKind::Ty(ty) => ty.into(),
ty::TermKind::Const(c) => c.into(),
})
}
ty::PredicateKind::WellFormed(arg) => {

View File

@ -1183,11 +1183,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// `<T as Iterator>::Item = u32`
let assoc_item_def_id = projection_ty.skip_binder().item_def_id;
let def_kind = tcx.def_kind(assoc_item_def_id);
match (def_kind, term) {
(hir::def::DefKind::AssocTy, ty::Term::Ty(_))
| (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
match (def_kind, term.unpack()) {
(hir::def::DefKind::AssocTy, ty::TermKind::Ty(_))
| (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (),
(_, _) => {
let got = if let ty::Term::Ty(_) = term { "type" } else { "constant" };
let got = if let Some(_) = term.ty() { "type" } else { "constant" };
let expected = def_kind.descr(assoc_item_def_id);
tcx.sess
.struct_span_err(
@ -1375,9 +1375,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let pred = bound_predicate.rebind(pred);
// A `Self` within the original bound will be substituted with a
// `trait_object_dummy_self`, so check for that.
let references_self = match pred.skip_binder().term {
ty::Term::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),
ty::Term::Const(c) => c.ty().walk().any(|arg| arg == dummy_self.into()),
let references_self = match pred.skip_binder().term.unpack() {
ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),
ty::TermKind::Const(c) => {
c.ty().walk().any(|arg| arg == dummy_self.into())
}
};
// If the projection output contains `Self`, force the user to

View File

@ -21,7 +21,7 @@ use rustc_infer::infer::{self, InferOk};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::{
self, AssocKind, DefIdTree, GenericParamDefKind, ProjectionPredicate, ProjectionTy, Term,
self, AssocKind, DefIdTree, GenericParamDefKind, ProjectionPredicate, ProjectionTy,
ToPredicate, Ty, TypeVisitable,
};
use rustc_span::symbol::Ident;
@ -349,7 +349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
opt_output_ty.zip(opt_output_assoc_item).map(|(output_ty, output_assoc_item)| {
ty::Binder::dummy(ty::PredicateKind::Projection(ProjectionPredicate {
projection_ty: ProjectionTy { substs, item_def_id: output_assoc_item.def_id },
term: Term::Ty(output_ty),
term: output_ty.into(),
}))
.to_predicate(self.tcx)
});

View File

@ -271,11 +271,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
for projection in data.projection_bounds() {
match projection.skip_binder().term {
ty::Term::Ty(ty) => {
match projection.skip_binder().term.unpack() {
ty::TermKind::Ty(ty) => {
self.add_constraints_from_ty(current, ty, self.invariant);
}
ty::Term::Const(c) => {
ty::TermKind::Const(c) => {
self.add_constraints_from_const(current, c, self.invariant)
}
}

View File

@ -370,9 +370,9 @@ fn clean_type_outlives_predicate<'tcx>(
}
fn clean_middle_term<'tcx>(term: ty::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
match term {
ty::Term::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
ty::Term::Const(c) => Term::Constant(clean_middle_const(c, cx)),
match term.unpack() {
ty::TermKind::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
ty::TermKind::Const(c) => Term::Constant(clean_middle_const(c, cx)),
}
}

View File

@ -1174,7 +1174,7 @@ fn replace_types<'tcx>(
if replaced.insert(param_ty.index) {
for projection_predicate in projection_predicates {
if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx)
&& let ty::Term::Ty(term_ty) = projection_predicate.term
&& let Some(term_ty) = projection_predicate.term.ty()
&& let ty::Param(term_param_ty) = term_ty.kind()
{
let item_def_id = projection_predicate.projection_ty.item_def_id;

View File

@ -3302,9 +3302,9 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
// one of the associated types must be Self
for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) {
if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
let assoc_ty = match projection_predicate.term {
ty::Term::Ty(ty) => ty,
ty::Term::Const(_c) => continue,
let assoc_ty = match projection_predicate.term.unpack() {
ty::TermKind::Ty(ty) => ty,
ty::TermKind::Const(_c) => continue,
};
// walk the associated type and check for Self
if let Some(self_adt) = self_ty.ty_adt_def() {

View File

@ -268,7 +268,7 @@ fn check_other_call_arg<'tcx>(
.subst_and_normalize_erasing_regions(call_substs, cx.param_env, projection_predicate.term);
implements_trait(cx, receiver_ty, deref_trait_id, &[])
&& get_associated_type(cx, receiver_ty, deref_trait_id, "Target")
.map_or(false, |ty| ty::Term::Ty(ty) == normalized_ty)
.map_or(false, |ty| ty::TermKind::Ty(ty) == normalized_ty.unpack())
} else {
false
}