Assert that various types have the right amount of generic args and fix the sites that used the wrong amount
This commit is contained in:
parent
d9a02b0fb7
commit
6f77c97b38
27 changed files with 153 additions and 144 deletions
|
@ -547,10 +547,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
|
|
||||||
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
|
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = tcx.mk_trait_ref(
|
||||||
def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
|
tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
|
||||||
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
|
place_ty.ty,
|
||||||
};
|
&[],
|
||||||
|
);
|
||||||
|
|
||||||
// To have a `Copy` operand, the type `T` of the
|
// To have a `Copy` operand, the type `T` of the
|
||||||
// value must be `Copy`. Note that we prove that `T: Copy`,
|
// value must be `Copy`. Note that we prove that `T: Copy`,
|
||||||
|
@ -1273,10 +1274,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
self.check_rvalue(body, rv, location);
|
self.check_rvalue(body, rv, location);
|
||||||
if !self.unsized_feature_enabled() {
|
if !self.unsized_feature_enabled() {
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = tcx.mk_trait_ref(
|
||||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||||
substs: tcx.mk_substs_trait(place_ty, &[]),
|
place_ty,
|
||||||
};
|
&[],
|
||||||
|
);
|
||||||
self.prove_trait_ref(
|
self.prove_trait_ref(
|
||||||
trait_ref,
|
trait_ref,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
|
@ -1865,9 +1867,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
// Make sure that repeated elements implement `Copy`.
|
// Make sure that repeated elements implement `Copy`.
|
||||||
let span = body.source_info(location).span;
|
let span = body.source_info(location).span;
|
||||||
let ty = place.ty(body, tcx).ty;
|
let ty = place.ty(body, tcx).ty;
|
||||||
let trait_ref = ty::TraitRef::new(
|
let trait_ref = tcx.mk_trait_ref(
|
||||||
tcx.require_lang_item(LangItem::Copy, Some(span)),
|
tcx.require_lang_item(LangItem::Copy, Some(span)),
|
||||||
tcx.mk_substs_trait(ty, &[]),
|
ty,
|
||||||
|
&[],
|
||||||
);
|
);
|
||||||
|
|
||||||
self.prove_trait_ref(
|
self.prove_trait_ref(
|
||||||
|
@ -1881,10 +1884,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
|
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = tcx.mk_trait_ref(
|
||||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||||
substs: tcx.mk_substs_trait(ty, &[]),
|
ty,
|
||||||
};
|
&[],
|
||||||
|
);
|
||||||
|
|
||||||
self.prove_trait_ref(
|
self.prove_trait_ref(
|
||||||
trait_ref,
|
trait_ref,
|
||||||
|
@ -1896,10 +1900,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
Rvalue::ShallowInitBox(operand, ty) => {
|
Rvalue::ShallowInitBox(operand, ty) => {
|
||||||
self.check_operand(operand, location);
|
self.check_operand(operand, location);
|
||||||
|
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = tcx.mk_trait_ref(
|
||||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||||
substs: tcx.mk_substs_trait(*ty, &[]),
|
*ty,
|
||||||
};
|
&[],
|
||||||
|
);
|
||||||
|
|
||||||
self.prove_trait_ref(
|
self.prove_trait_ref(
|
||||||
trait_ref,
|
trait_ref,
|
||||||
|
@ -1996,11 +2001,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
CastKind::Pointer(PointerCast::Unsize) => {
|
CastKind::Pointer(PointerCast::Unsize) => {
|
||||||
let &ty = ty;
|
let &ty = ty;
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = tcx.mk_trait_ref(
|
||||||
def_id: tcx
|
tcx.require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)),
|
||||||
.require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)),
|
op.ty(body, tcx),
|
||||||
substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]),
|
&[ty.into()],
|
||||||
};
|
);
|
||||||
|
|
||||||
self.prove_trait_ref(
|
self.prove_trait_ref(
|
||||||
trait_ref,
|
trait_ref,
|
||||||
|
|
|
@ -160,10 +160,7 @@ impl Qualif for NeedsNonConstDrop {
|
||||||
ObligationCause::dummy(),
|
ObligationCause::dummy(),
|
||||||
cx.param_env,
|
cx.param_env,
|
||||||
ty::Binder::dummy(ty::TraitPredicate {
|
ty::Binder::dummy(ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
trait_ref: cx.tcx.mk_trait_ref(destruct, ty, &[]),
|
||||||
def_id: destruct,
|
|
||||||
substs: cx.tcx.mk_substs_trait(ty, &[]),
|
|
||||||
},
|
|
||||||
constness: ty::BoundConstness::ConstIfConst,
|
constness: ty::BoundConstness::ConstIfConst,
|
||||||
polarity: ty::ImplPolarity::Positive,
|
polarity: ty::ImplPolarity::Positive,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -61,10 +61,7 @@ impl<'tcx> Bounds<'tcx> {
|
||||||
// If it could be sized, and is, add the `Sized` predicate.
|
// If it could be sized, and is, add the `Sized` predicate.
|
||||||
let sized_predicate = self.implicitly_sized.and_then(|span| {
|
let sized_predicate = self.implicitly_sized.and_then(|span| {
|
||||||
tcx.lang_items().sized_trait().map(move |sized| {
|
tcx.lang_items().sized_trait().map(move |sized| {
|
||||||
let trait_ref = ty::Binder::dummy(ty::TraitRef {
|
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, param_ty, &[]));
|
||||||
def_id: sized,
|
|
||||||
substs: tcx.mk_substs_trait(param_ty, &[]),
|
|
||||||
});
|
|
||||||
(trait_ref.without_const().to_predicate(tcx), span)
|
(trait_ref.without_const().to_predicate(tcx), span)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -1782,10 +1782,7 @@ fn receiver_is_implemented<'tcx>(
|
||||||
receiver_ty: Ty<'tcx>,
|
receiver_ty: Ty<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let tcx = wfcx.tcx();
|
let tcx = wfcx.tcx();
|
||||||
let trait_ref = ty::Binder::dummy(ty::TraitRef {
|
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(receiver_trait_def_id, receiver_ty, &[]));
|
||||||
def_id: receiver_trait_def_id,
|
|
||||||
substs: tcx.mk_substs_trait(receiver_ty, &[]),
|
|
||||||
});
|
|
||||||
|
|
||||||
let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref.without_const());
|
let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref.without_const());
|
||||||
|
|
||||||
|
|
|
@ -1093,10 +1093,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.tcx,
|
self.tcx,
|
||||||
self.misc(expr.span),
|
self.misc(expr.span),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ty::Binder::dummy(ty::TraitRef {
|
ty::Binder::dummy(self.tcx.mk_trait_ref(
|
||||||
def_id: into_def_id,
|
into_def_id,
|
||||||
substs: self.tcx.mk_substs_trait(expr_ty, &[expected_ty.into()]),
|
expr_ty, &[expected_ty.into()]
|
||||||
})
|
))
|
||||||
.to_poly_trait_predicate(),
|
.to_poly_trait_predicate(),
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,7 +68,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.autoderef(span, ty).any(|(ty, _)| {
|
self.autoderef(span, ty).any(|(ty, _)| {
|
||||||
info!("check deref {:?} impl FnOnce", ty);
|
info!("check deref {:?} impl FnOnce", ty);
|
||||||
self.probe(|_| {
|
self.probe(|_| {
|
||||||
let fn_once_substs = tcx.mk_substs_trait(
|
let trait_ref = tcx.mk_trait_ref(
|
||||||
|
fn_once,
|
||||||
ty,
|
ty,
|
||||||
&[self
|
&[self
|
||||||
.next_ty_var(TypeVariableOrigin {
|
.next_ty_var(TypeVariableOrigin {
|
||||||
|
@ -77,7 +78,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
.into()],
|
.into()],
|
||||||
);
|
);
|
||||||
let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
|
|
||||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
||||||
let obligation = Obligation::misc(
|
let obligation = Obligation::misc(
|
||||||
tcx,
|
tcx,
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
) {
|
) {
|
||||||
let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) };
|
let trait_ref = infcx.tcx.mk_trait_ref(def_id, ty, &[]);
|
||||||
self.register_predicate_obligation(
|
self.register_predicate_obligation(
|
||||||
infcx,
|
infcx,
|
||||||
Obligation {
|
Obligation {
|
||||||
|
|
|
@ -2532,6 +2532,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mk_fn_def(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
|
pub fn mk_fn_def(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
|
||||||
|
debug_assert_eq!(
|
||||||
|
self.generics_of(def_id).count(),
|
||||||
|
substs.len(),
|
||||||
|
"wrong number of generic parameters for {def_id:?}: {substs:?}",
|
||||||
|
);
|
||||||
self.mk_ty(FnDef(def_id, substs))
|
self.mk_ty(FnDef(def_id, substs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2552,6 +2557,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mk_projection(self, item_def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
|
pub fn mk_projection(self, item_def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
|
||||||
|
debug_assert_eq!(
|
||||||
|
self.generics_of(item_def_id).count(),
|
||||||
|
substs.len(),
|
||||||
|
"wrong number of generic parameters for {item_def_id:?}: {substs:?}",
|
||||||
|
);
|
||||||
self.mk_ty(Projection(ProjectionTy { item_def_id, substs }))
|
self.mk_ty(Projection(ProjectionTy { item_def_id, substs }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2803,6 +2813,21 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
|
self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mk_trait_ref(
|
||||||
|
self,
|
||||||
|
trait_def_id: DefId,
|
||||||
|
self_ty: Ty<'tcx>,
|
||||||
|
rest: &[GenericArg<'tcx>],
|
||||||
|
) -> ty::TraitRef<'tcx> {
|
||||||
|
debug_assert_eq!(
|
||||||
|
self.generics_of(trait_def_id).count() - 1,
|
||||||
|
rest.len(),
|
||||||
|
"wrong number of generic parameters for {trait_def_id:?} on self type {self_ty:?}: {rest:?} \nDid you accidentally include the self-type in the params list?"
|
||||||
|
);
|
||||||
|
let substs = self.mk_substs_trait(self_ty, rest);
|
||||||
|
ty::TraitRef::new(trait_def_id, substs)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mk_bound_variable_kinds<
|
pub fn mk_bound_variable_kinds<
|
||||||
I: InternAs<[ty::BoundVariableKind], &'tcx List<ty::BoundVariableKind>>,
|
I: InternAs<[ty::BoundVariableKind], &'tcx List<ty::BoundVariableKind>>,
|
||||||
>(
|
>(
|
||||||
|
|
|
@ -719,10 +719,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
|
||||||
self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
|
self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
|
||||||
}
|
}
|
||||||
ExistentialPredicate::AutoTrait(did) => {
|
ExistentialPredicate::AutoTrait(did) => {
|
||||||
let trait_ref = self.rebind(ty::TraitRef {
|
let trait_ref = self.rebind(tcx.mk_trait_ref(did, self_ty, &[]));
|
||||||
def_id: did,
|
|
||||||
substs: tcx.mk_substs_trait(self_ty, &[]),
|
|
||||||
});
|
|
||||||
trait_ref.without_const().to_predicate(tcx)
|
trait_ref.without_const().to_predicate(tcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -909,7 +906,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
|
||||||
// otherwise the escaping vars would be captured by the binder
|
// otherwise the escaping vars would be captured by the binder
|
||||||
// debug_assert!(!self_ty.has_escaping_bound_vars());
|
// debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||||
|
|
||||||
ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) }
|
tcx.mk_trait_ref(self.def_id, self_ty, self.substs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use rustc_errors::DelayDm;
|
use rustc_errors::DelayDm;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_middle::mir::{self, Field};
|
use rustc_middle::mir::{self, Field};
|
||||||
use rustc_middle::thir::{FieldPat, Pat, PatKind};
|
use rustc_middle::thir::{FieldPat, Pat, PatKind};
|
||||||
|
@ -226,6 +227,13 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// using `PartialEq::eq` in this scenario in the past.)
|
// using `PartialEq::eq` in this scenario in the past.)
|
||||||
let partial_eq_trait_id =
|
let partial_eq_trait_id =
|
||||||
self.tcx().require_lang_item(hir::LangItem::PartialEq, Some(self.span));
|
self.tcx().require_lang_item(hir::LangItem::PartialEq, Some(self.span));
|
||||||
|
let any_ty = self
|
||||||
|
.infcx
|
||||||
|
.next_ty_var(TypeVariableOrigin {
|
||||||
|
kind: TypeVariableOriginKind::MiscVariable,
|
||||||
|
span: self.span,
|
||||||
|
})
|
||||||
|
.into();
|
||||||
let obligation: PredicateObligation<'_> = predicate_for_trait_def(
|
let obligation: PredicateObligation<'_> = predicate_for_trait_def(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
|
@ -233,7 +241,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
partial_eq_trait_id,
|
partial_eq_trait_id,
|
||||||
0,
|
0,
|
||||||
ty,
|
ty,
|
||||||
&[],
|
&[any_ty],
|
||||||
);
|
);
|
||||||
// FIXME: should this call a `predicate_must_hold` variant instead?
|
// FIXME: should this call a `predicate_must_hold` variant instead?
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,7 @@ fn custom_coerce_unsize_info<'tcx>(
|
||||||
) -> CustomCoerceUnsized {
|
) -> CustomCoerceUnsized {
|
||||||
let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None);
|
let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None);
|
||||||
|
|
||||||
let trait_ref = ty::Binder::dummy(ty::TraitRef {
|
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(def_id, source_ty, &[target_ty.into()]));
|
||||||
def_id,
|
|
||||||
substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]),
|
|
||||||
});
|
|
||||||
|
|
||||||
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) {
|
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) {
|
||||||
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
|
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::traits::{self, TraitEngine, TraitEngineExt};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_infer::infer::InferCtxt;
|
use rustc_infer::infer::InferCtxt;
|
||||||
use rustc_middle::ty::TypeVisitable;
|
use rustc_middle::ty::TypeVisitable;
|
||||||
use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_session::Limit;
|
use rustc_session::Limit;
|
||||||
use rustc_span::def_id::LOCAL_CRATE;
|
use rustc_span::def_id::LOCAL_CRATE;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -122,10 +122,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
|
|
||||||
// <ty as Deref>
|
// <ty as Deref>
|
||||||
let trait_ref = TraitRef {
|
let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, ty, &[]);
|
||||||
def_id: tcx.lang_items().deref_trait()?,
|
|
||||||
substs: tcx.mk_substs_trait(ty, &[]),
|
|
||||||
};
|
|
||||||
|
|
||||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||||
|
|
||||||
|
|
|
@ -117,10 +117,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
params: SubstsRef<'tcx>,
|
params: SubstsRef<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> traits::EvaluationResult {
|
) -> traits::EvaluationResult {
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, self_ty, params);
|
||||||
def_id: trait_def_id,
|
|
||||||
substs: self.tcx.mk_substs_trait(self_ty, params),
|
|
||||||
};
|
|
||||||
|
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
self.tcx.generics_of(trait_def_id).count() - 1,
|
self.tcx.generics_of(trait_def_id).count() - 1,
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
) -> AutoTraitResult<A> {
|
) -> AutoTraitResult<A> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
|
|
||||||
let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) };
|
let trait_ref = tcx.mk_trait_ref(trait_did, ty, &[]);
|
||||||
|
|
||||||
let trait_pred = ty::Binder::dummy(trait_ref);
|
let trait_pred = ty::Binder::dummy(trait_ref);
|
||||||
|
|
||||||
|
@ -260,10 +260,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
let mut already_visited = FxHashSet::default();
|
let mut already_visited = FxHashSet::default();
|
||||||
let mut predicates = VecDeque::new();
|
let mut predicates = VecDeque::new();
|
||||||
predicates.push_back(ty::Binder::dummy(ty::TraitPredicate {
|
predicates.push_back(ty::Binder::dummy(ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
trait_ref: infcx.tcx.mk_trait_ref(trait_did, ty, &[]),
|
||||||
def_id: trait_did,
|
|
||||||
substs: infcx.tcx.mk_substs_trait(ty, &[]),
|
|
||||||
},
|
|
||||||
constness: ty::BoundConstness::NotConst,
|
constness: ty::BoundConstness::NotConst,
|
||||||
// Auto traits are positive
|
// Auto traits are positive
|
||||||
polarity: ty::ImplPolarity::Positive,
|
polarity: ty::ImplPolarity::Positive,
|
||||||
|
|
|
@ -93,7 +93,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) {
|
) {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
let trait_ref = ty::TraitRef { def_id, substs: tcx.mk_substs_trait(ty, &[]) };
|
let trait_ref = tcx.mk_trait_ref(def_id, ty, &[]);
|
||||||
self.register_obligation(Obligation {
|
self.register_obligation(Obligation {
|
||||||
cause,
|
cause,
|
||||||
recursion_depth: 0,
|
recursion_depth: 0,
|
||||||
|
|
|
@ -347,16 +347,13 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
kind: TypeVariableOriginKind::MiscVariable,
|
kind: TypeVariableOriginKind::MiscVariable,
|
||||||
});
|
});
|
||||||
let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()]);
|
let trait_ref =
|
||||||
|
self.tcx.mk_trait_ref(trait_def_id, ty.skip_binder(), &[var.into()]);
|
||||||
let obligation = Obligation::new(
|
let obligation = Obligation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ObligationCause::dummy(),
|
ObligationCause::dummy(),
|
||||||
param_env,
|
param_env,
|
||||||
ty.rebind(ty::TraitPredicate {
|
ty.rebind(ty::TraitPredicate { trait_ref, constness, polarity }),
|
||||||
trait_ref: ty::TraitRef::new(trait_def_id, substs),
|
|
||||||
constness,
|
|
||||||
polarity,
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(self.tcx);
|
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(self.tcx);
|
||||||
fulfill_cx.register_predicate_obligation(self, obligation);
|
fulfill_cx.register_predicate_obligation(self, obligation);
|
||||||
|
@ -1002,7 +999,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
&& self.fallback_has_occurred
|
&& self.fallback_has_occurred
|
||||||
{
|
{
|
||||||
let predicate = trait_predicate.map_bound(|mut trait_pred| {
|
let predicate = trait_predicate.map_bound(|mut trait_pred| {
|
||||||
trait_pred.trait_ref.substs = self.tcx.mk_substs_trait(
|
trait_pred.trait_ref = self.tcx.mk_trait_ref(
|
||||||
|
trait_pred.trait_ref.def_id,
|
||||||
self.tcx.mk_unit(),
|
self.tcx.mk_unit(),
|
||||||
&trait_pred.trait_ref.substs[1..],
|
&trait_pred.trait_ref.substs[1..],
|
||||||
);
|
);
|
||||||
|
@ -2029,10 +2027,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
|
trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
|
||||||
) -> PredicateObligation<'tcx> {
|
) -> PredicateObligation<'tcx> {
|
||||||
let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate {
|
let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
trait_ref: self.tcx.mk_trait_ref(
|
||||||
substs: self.tcx.mk_substs_trait(*new_self_ty, &tr.trait_ref.substs[1..]),
|
tr.trait_ref.def_id,
|
||||||
..tr.trait_ref
|
*new_self_ty,
|
||||||
},
|
&tr.trait_ref.substs[1..],
|
||||||
|
),
|
||||||
..*tr
|
..*tr
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3068,17 +3068,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
// Ensure all fields impl the trait.
|
// Ensure all fields impl the trait.
|
||||||
adt.all_fields().all(|field| {
|
adt.all_fields().all(|field| {
|
||||||
let field_ty = field.ty(self.tcx, substs);
|
let field_ty = field.ty(self.tcx, substs);
|
||||||
let trait_substs = match diagnostic_name {
|
let trait_substs;
|
||||||
|
let trait_substs: &[_] = match diagnostic_name {
|
||||||
sym::PartialEq | sym::PartialOrd => {
|
sym::PartialEq | sym::PartialOrd => {
|
||||||
self.tcx.mk_substs_trait(field_ty, &[field_ty.into()])
|
trait_substs = [field_ty.into()];
|
||||||
|
&trait_substs
|
||||||
}
|
}
|
||||||
_ => self.tcx.mk_substs_trait(field_ty, &[]),
|
_ => &[],
|
||||||
};
|
};
|
||||||
let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
|
let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
trait_ref: self.tcx.mk_trait_ref(
|
||||||
substs: trait_substs,
|
trait_pred.def_id(),
|
||||||
..trait_pred.skip_binder().trait_ref
|
field_ty,
|
||||||
},
|
trait_substs,
|
||||||
|
),
|
||||||
..*tr
|
..*tr
|
||||||
});
|
});
|
||||||
let field_obl = Obligation::new(
|
let field_obl = Obligation::new(
|
||||||
|
|
|
@ -143,8 +143,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let trait_ref =
|
let trait_ref = ty::Binder::dummy(infcx.tcx.mk_trait_ref(def_id, ty, &[]));
|
||||||
ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) });
|
|
||||||
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref.without_const(), span)
|
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref.without_const(), span)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,10 +902,7 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>(
|
||||||
// this has been typecked-before, so diagnostics is not really needed.
|
// this has been typecked-before, so diagnostics is not really needed.
|
||||||
let unsize_trait_did = tcx.require_lang_item(LangItem::Unsize, None);
|
let unsize_trait_did = tcx.require_lang_item(LangItem::Unsize, None);
|
||||||
|
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = tcx.mk_trait_ref(unsize_trait_did, source, &[target.into()]);
|
||||||
def_id: unsize_trait_did,
|
|
||||||
substs: tcx.mk_substs_trait(source, &[target.into()]),
|
|
||||||
};
|
|
||||||
|
|
||||||
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) {
|
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) {
|
||||||
Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => {
|
Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => {
|
||||||
|
|
|
@ -685,10 +685,11 @@ fn receiver_is_dispatchable<'tcx>(
|
||||||
let param_env = tcx.param_env(method.def_id);
|
let param_env = tcx.param_env(method.def_id);
|
||||||
|
|
||||||
// Self: Unsize<U>
|
// Self: Unsize<U>
|
||||||
let unsize_predicate = ty::Binder::dummy(ty::TraitRef {
|
let unsize_predicate = ty::Binder::dummy(tcx.mk_trait_ref(
|
||||||
def_id: unsize_did,
|
unsize_did,
|
||||||
substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]),
|
tcx.types.self_param,
|
||||||
})
|
&[unsized_self_ty.into()],
|
||||||
|
))
|
||||||
.without_const()
|
.without_const()
|
||||||
.to_predicate(tcx);
|
.to_predicate(tcx);
|
||||||
|
|
||||||
|
@ -720,10 +721,11 @@ fn receiver_is_dispatchable<'tcx>(
|
||||||
|
|
||||||
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
||||||
let obligation = {
|
let obligation = {
|
||||||
let predicate = ty::Binder::dummy(ty::TraitRef {
|
let predicate = ty::Binder::dummy(tcx.mk_trait_ref(
|
||||||
def_id: dispatch_from_dyn_did,
|
dispatch_from_dyn_did,
|
||||||
substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]),
|
receiver_ty,
|
||||||
})
|
&[unsized_receiver_ty.into()],
|
||||||
|
))
|
||||||
.without_const();
|
.without_const();
|
||||||
|
|
||||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
|
Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
|
||||||
|
|
|
@ -1710,9 +1710,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||||
if selcx.infcx().predicate_must_hold_modulo_regions(
|
if selcx.infcx().predicate_must_hold_modulo_regions(
|
||||||
&obligation.with(
|
&obligation.with(
|
||||||
selcx.tcx(),
|
selcx.tcx(),
|
||||||
ty::Binder::dummy(ty::TraitRef::new(
|
ty::Binder::dummy(selcx.tcx().mk_trait_ref(
|
||||||
selcx.tcx().require_lang_item(LangItem::Sized, None),
|
selcx.tcx().require_lang_item(LangItem::Sized, None),
|
||||||
selcx.tcx().mk_substs_trait(self_ty, &[]),
|
self_ty, &[],
|
||||||
))
|
))
|
||||||
.without_const(),
|
.without_const(),
|
||||||
),
|
),
|
||||||
|
@ -1966,9 +1966,10 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
if check_is_sized {
|
if check_is_sized {
|
||||||
let sized_predicate = ty::Binder::dummy(ty::TraitRef::new(
|
let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref(
|
||||||
tcx.require_lang_item(LangItem::Sized, None),
|
tcx.require_lang_item(LangItem::Sized, None),
|
||||||
tcx.mk_substs_trait(self_ty, &[]),
|
self_ty,
|
||||||
|
&[],
|
||||||
))
|
))
|
||||||
.without_const();
|
.without_const();
|
||||||
obligations.push(obligation.with(tcx, sized_predicate));
|
obligations.push(obligation.with(tcx, sized_predicate));
|
||||||
|
|
|
@ -18,10 +18,10 @@ pub(crate) fn update<'tcx, T>(
|
||||||
{
|
{
|
||||||
let new_self_ty = infcx.tcx.types.unit;
|
let new_self_ty = infcx.tcx.types.unit;
|
||||||
|
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = infcx.tcx.mk_trait_ref(
|
||||||
substs: infcx.tcx.mk_substs_trait(new_self_ty, &tpred.trait_ref.substs[1..]),
|
tpred.trait_ref.def_id,
|
||||||
..tpred.trait_ref
|
new_self_ty, &tpred.trait_ref.substs[1..],
|
||||||
};
|
);
|
||||||
|
|
||||||
// Then construct a new obligation with Self = () added
|
// Then construct a new obligation with Self = () added
|
||||||
// to the ParamEnv, and see if it holds.
|
// to the ParamEnv, and see if it holds.
|
||||||
|
|
|
@ -714,10 +714,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// <ty as Deref>
|
// <ty as Deref>
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, ty, &[]);
|
||||||
def_id: tcx.lang_items().deref_trait()?,
|
|
||||||
substs: tcx.mk_substs_trait(ty, &[]),
|
|
||||||
};
|
|
||||||
|
|
||||||
let obligation = traits::Obligation::new(
|
let obligation = traits::Obligation::new(
|
||||||
tcx,
|
tcx,
|
||||||
|
|
|
@ -632,9 +632,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
output_ty,
|
output_ty,
|
||||||
&mut nested,
|
&mut nested,
|
||||||
);
|
);
|
||||||
let tr = ty::Binder::dummy(ty::TraitRef::new(
|
let tr = ty::Binder::dummy(self.tcx().mk_trait_ref(
|
||||||
self.tcx().require_lang_item(LangItem::Sized, None),
|
self.tcx().require_lang_item(LangItem::Sized, None),
|
||||||
self.tcx().mk_substs_trait(output_ty, &[]),
|
output_ty,
|
||||||
|
&[],
|
||||||
));
|
));
|
||||||
nested.push(Obligation::new(
|
nested.push(Obligation::new(
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
|
@ -996,9 +997,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
|
|
||||||
// We can only make objects from sized types.
|
// We can only make objects from sized types.
|
||||||
let tr = ty::Binder::dummy(ty::TraitRef::new(
|
let tr = ty::Binder::dummy(tcx.mk_trait_ref(
|
||||||
tcx.require_lang_item(LangItem::Sized, None),
|
tcx.require_lang_item(LangItem::Sized, None),
|
||||||
tcx.mk_substs_trait(source, &[]),
|
source,
|
||||||
|
&[],
|
||||||
));
|
));
|
||||||
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
|
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
|
||||||
|
|
||||||
|
@ -1253,10 +1255,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
obligation.recursion_depth + 1,
|
obligation.recursion_depth + 1,
|
||||||
self_ty.rebind(ty::TraitPredicate {
|
self_ty.rebind(ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
trait_ref: self.tcx().mk_trait_ref(
|
||||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
nested_ty,
|
||||||
},
|
&[],
|
||||||
|
),
|
||||||
constness: ty::BoundConstness::ConstIfConst,
|
constness: ty::BoundConstness::ConstIfConst,
|
||||||
polarity: ty::ImplPolarity::Positive,
|
polarity: ty::ImplPolarity::Positive,
|
||||||
}),
|
}),
|
||||||
|
@ -1277,10 +1280,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// or it's an ADT (and we need to check for a custom impl during selection)
|
// or it's an ADT (and we need to check for a custom impl during selection)
|
||||||
_ => {
|
_ => {
|
||||||
let predicate = self_ty.rebind(ty::TraitPredicate {
|
let predicate = self_ty.rebind(ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
trait_ref: self.tcx().mk_trait_ref(
|
||||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
nested_ty,
|
||||||
},
|
&[],
|
||||||
|
),
|
||||||
constness: ty::BoundConstness::ConstIfConst,
|
constness: ty::BoundConstness::ConstIfConst,
|
||||||
polarity: ty::ImplPolarity::Positive,
|
polarity: ty::ImplPolarity::Positive,
|
||||||
});
|
});
|
||||||
|
|
|
@ -241,8 +241,7 @@ pub fn predicate_for_trait_def<'tcx>(
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
params: &[GenericArg<'tcx>],
|
params: &[GenericArg<'tcx>],
|
||||||
) -> PredicateObligation<'tcx> {
|
) -> PredicateObligation<'tcx> {
|
||||||
let trait_ref =
|
let trait_ref = tcx.mk_trait_ref(trait_def_id, self_ty, params);
|
||||||
ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(self_ty, params) };
|
|
||||||
predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth)
|
predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,10 +304,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>(
|
||||||
TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
|
TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
|
||||||
};
|
};
|
||||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, self_ty, &[arguments_tuple.into()]);
|
||||||
def_id: fn_trait_def_id,
|
|
||||||
substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]),
|
|
||||||
};
|
|
||||||
sig.map_bound(|sig| (trait_ref, sig.output()))
|
sig.map_bound(|sig| (trait_ref, sig.output()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,10 +315,8 @@ pub fn generator_trait_ref_and_outputs<'tcx>(
|
||||||
sig: ty::PolyGenSig<'tcx>,
|
sig: ty::PolyGenSig<'tcx>,
|
||||||
) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
|
) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
|
||||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref =
|
||||||
def_id: fn_trait_def_id,
|
tcx.mk_trait_ref(fn_trait_def_id, self_ty, &[sig.skip_binder().resume_ty.into()]);
|
||||||
substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]),
|
|
||||||
};
|
|
||||||
sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty))
|
sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -421,10 +421,11 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||||
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
|
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
|
||||||
if !subty.has_escaping_bound_vars() {
|
if !subty.has_escaping_bound_vars() {
|
||||||
let cause = self.cause(cause);
|
let cause = self.cause(cause);
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = self.tcx.mk_trait_ref(
|
||||||
def_id: self.tcx.require_lang_item(LangItem::Sized, None),
|
self.tcx.require_lang_item(LangItem::Sized, None),
|
||||||
substs: self.tcx.mk_substs_trait(subty, &[]),
|
subty,
|
||||||
};
|
&[],
|
||||||
|
);
|
||||||
self.out.push(traits::Obligation::with_depth(
|
self.out.push(traits::Obligation::with_depth(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
cause,
|
cause,
|
||||||
|
|
|
@ -49,12 +49,9 @@ fn sized_constraint_for_ty<'tcx>(
|
||||||
// it on the impl.
|
// it on the impl.
|
||||||
|
|
||||||
let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] };
|
let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] };
|
||||||
let sized_predicate = ty::Binder::dummy(ty::TraitRef {
|
let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref(sized_trait, ty, &[]))
|
||||||
def_id: sized_trait,
|
.without_const()
|
||||||
substs: tcx.mk_substs_trait(ty, &[]),
|
.to_predicate(tcx);
|
||||||
})
|
|
||||||
.without_const()
|
|
||||||
.to_predicate(tcx);
|
|
||||||
let predicates = tcx.predicates_of(adtdef.did()).predicates;
|
let predicates = tcx.predicates_of(adtdef.did()).predicates;
|
||||||
if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] }
|
if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] }
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ where
|
||||||
discard_positive_impl: bool,
|
discard_positive_impl: bool,
|
||||||
) -> Option<Item> {
|
) -> Option<Item> {
|
||||||
let tcx = self.cx.tcx;
|
let tcx = self.cx.tcx;
|
||||||
let trait_ref = ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, &[]) };
|
let trait_ref = tcx.mk_trait_ref(trait_def_id, ty, &[]);
|
||||||
if !self.cx.generated_synthetics.insert((ty, trait_def_id)) {
|
if !self.cx.generated_synthetics.insert((ty, trait_def_id)) {
|
||||||
debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref);
|
debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref);
|
||||||
return None;
|
return None;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue