Stop passing the self-type as a separate argument.

This commit is contained in:
Oli Scherer 2022-11-21 12:24:53 +00:00
parent a4da3f8863
commit 7658e0fccf
38 changed files with 113 additions and 164 deletions

View file

@ -489,12 +489,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// but the type has region variables, so erase those. // but the type has region variables, so erase those.
tcx.infer_ctxt() tcx.infer_ctxt()
.build() .build()
.type_implements_trait( .type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env)
default_trait,
tcx.erase_regions(ty),
ty::List::empty(),
param_env,
)
.must_apply_modulo_regions() .must_apply_modulo_regions()
}; };
@ -1707,7 +1702,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
err.span_label(borrow_span, note); err.span_label(borrow_span, note);
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let ty_params = ty::List::empty();
let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
let return_ty = tcx.erase_regions(return_ty); let return_ty = tcx.erase_regions(return_ty);
@ -1716,7 +1710,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator)
&& self && self
.infcx .infcx
.type_implements_trait(iter_trait, return_ty, ty_params, self.param_env) .type_implements_trait(iter_trait, [return_ty], self.param_env)
.must_apply_modulo_regions() .must_apply_modulo_regions()
{ {
err.span_suggestion_hidden( err.span_suggestion_hidden(

View file

@ -547,7 +547,7 @@ 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 = tcx.at(self.last_span).mk_trait_ref(LangItem::Copy, place_ty.ty, []); let trait_ref = tcx.at(self.last_span).mk_trait_ref(LangItem::Copy, [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`,
@ -1271,7 +1271,7 @@ 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 = let trait_ref =
tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, place_ty, []); tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, [place_ty]);
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,
location.to_locations(), location.to_locations(),
@ -1860,7 +1860,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Operand::Move(place) => { Operand::Move(place) => {
// Make sure that repeated elements implement `Copy`. // Make sure that repeated elements implement `Copy`.
let ty = place.ty(body, tcx).ty; let ty = place.ty(body, tcx).ty;
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, ty, []); let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, [ty]);
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,
@ -1873,7 +1873,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, ty, []); let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [ty]);
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,
@ -1885,7 +1885,7 @@ 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 = tcx.at(span).mk_trait_ref(LangItem::Sized, *ty, []); let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [*ty]);
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,
@ -1982,11 +1982,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
CastKind::Pointer(PointerCast::Unsize) => { CastKind::Pointer(PointerCast::Unsize) => {
let &ty = ty; let &ty = ty;
let trait_ref = tcx.at(span).mk_trait_ref( let trait_ref = tcx
LangItem::CoerceUnsized, .at(span)
op.ty(body, tcx), .mk_trait_ref(LangItem::CoerceUnsized, [op.ty(body, tcx), ty]);
[ty.into()],
);
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,

View file

@ -158,7 +158,7 @@ impl Qualif for NeedsNonConstDrop {
ObligationCause::dummy_with_span(cx.body.span), ObligationCause::dummy_with_span(cx.body.span),
cx.param_env, cx.param_env,
ty::Binder::dummy(ty::TraitPredicate { ty::Binder::dummy(ty::TraitPredicate {
trait_ref: cx.tcx.at(cx.body.span).mk_trait_ref(LangItem::Destruct, ty, []), trait_ref: cx.tcx.at(cx.body.span).mk_trait_ref(LangItem::Destruct, [ty]),
constness: ty::BoundConstness::ConstIfConst, constness: ty::BoundConstness::ConstIfConst,
polarity: ty::ImplPolarity::Positive, polarity: ty::ImplPolarity::Positive,
}), }),

View file

@ -62,7 +62,7 @@ impl<'tcx> Bounds<'tcx> {
let sized_predicate = self.implicitly_sized.and_then(|span| { let sized_predicate = self.implicitly_sized.and_then(|span| {
// FIXME: use tcx.at(span).mk_trait_ref(LangItem::Sized) here? This may make no-core code harder to write. // FIXME: use tcx.at(span).mk_trait_ref(LangItem::Sized) here? This may make no-core code harder to write.
let sized = tcx.lang_items().sized_trait()?; let sized = tcx.lang_items().sized_trait()?;
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, param_ty, [])); let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, [param_ty]));
Some((trait_ref.without_const().to_predicate(tcx), span)) Some((trait_ref.without_const().to_predicate(tcx), span))
}); });

View file

@ -1782,7 +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(tcx.mk_trait_ref(receiver_trait_def_id, receiver_ty, [])); let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(receiver_trait_def_id, [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());

View file

@ -315,8 +315,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
cause.clone(), cause.clone(),
dispatch_from_dyn_trait, dispatch_from_dyn_trait,
0, 0,
field.ty(tcx, substs_a), [field.ty(tcx, substs_a), field.ty(tcx, substs_b)],
[field.ty(tcx, substs_b).into()],
) )
}), }),
); );
@ -558,7 +557,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
// Register an obligation for `A: Trait<B>`. // Register an obligation for `A: Trait<B>`.
let cause = traits::ObligationCause::misc(span, impl_hir_id); let cause = traits::ObligationCause::misc(span, impl_hir_id);
let predicate = let predicate =
predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, source, [target.into()]); predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, [source, target]);
let errors = traits::fully_solve_obligation(&infcx, predicate); let errors = traits::fully_solve_obligation(&infcx, predicate);
if !errors.is_empty() { if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors, None); infcx.err_ctxt().report_fulfillment_errors(&errors, None);

View file

@ -498,10 +498,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
let ty = fcx.tcx.erase_regions(ty); let ty = fcx.tcx.erase_regions(ty);
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let expr_ty = fcx.tcx.erase_regions(expr_ty); let expr_ty = fcx.tcx.erase_regions(expr_ty);
let ty_params = fcx.tcx.mk_substs(std::iter::once(ty::GenericArg::from(expr_ty)));
if fcx if fcx
.infcx .infcx
.type_implements_trait(from_trait, ty, ty_params, fcx.param_env) .type_implements_trait(from_trait, [ty, expr_ty], fcx.param_env)
.must_apply_modulo_regions() .must_apply_modulo_regions()
{ {
label = false; label = false;

View file

@ -630,8 +630,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
cause, cause,
coerce_unsized_did, coerce_unsized_did,
0, 0,
coerce_source, [coerce_source, coerce_target]
[coerce_target.into()]
)]; )];
let mut has_unsized_tuple_coercion = false; let mut has_unsized_tuple_coercion = false;
@ -1086,8 +1085,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.infcx self.infcx
.type_implements_trait( .type_implements_trait(
self.tcx.lang_items().deref_mut_trait()?, self.tcx.lang_items().deref_mut_trait()?,
expr_ty, [expr_ty],
ty::List::empty(),
self.param_env, self.param_env,
) )
.may_apply() .may_apply()

View file

@ -1119,8 +1119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.infcx .infcx
.type_implements_trait( .type_implements_trait(
self.tcx.lang_items().sized_trait().unwrap(), self.tcx.lang_items().sized_trait().unwrap(),
lhs_deref_ty, [lhs_deref_ty],
ty::List::empty(),
self.param_env, self.param_env,
) )
.may_apply(); .may_apply();

View file

@ -1095,7 +1095,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.param_env, self.param_env,
ty::Binder::dummy(self.tcx.mk_trait_ref( ty::Binder::dummy(self.tcx.mk_trait_ref(
into_def_id, into_def_id,
expr_ty, [expected_ty.into()] [expr_ty, expected_ty]
)) ))
.to_poly_trait_predicate(), .to_poly_trait_predicate(),
)) ))

View file

@ -9,7 +9,6 @@ use rustc_ast::Mutability;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::ty;
use rustc_middle::ty::{Adt, Array, Ref, Ty}; use rustc_middle::ty::{Adt, Array, Ref, Ty};
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
use rustc_span::symbol::kw::{Empty, Underscore}; use rustc_span::symbol::kw::{Empty, Underscore};
@ -232,10 +231,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: TypeVariableOriginKind::MiscVariable, kind: TypeVariableOriginKind::MiscVariable,
span, span,
}); });
let params = self.tcx.mk_substs(std::iter::once(ty::GenericArg::from(any_type)));
if !self if !self
.infcx .infcx
.type_implements_trait(trait_def_id, self_ty, params, self.param_env) .type_implements_trait(trait_def_id, [self_ty, any_type], self.param_env)
.may_apply() .may_apply()
{ {
return; return;

View file

@ -70,13 +70,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.probe(|_| { self.probe(|_| {
let trait_ref = tcx.mk_trait_ref( let trait_ref = tcx.mk_trait_ref(
fn_once, fn_once,
ty, [
[self ty,
.next_ty_var(TypeVariableOrigin { self.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable, kind: TypeVariableOriginKind::MiscVariable,
span, span,
}) }),
.into()], ],
); );
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(

View file

@ -970,12 +970,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
check_trait check_trait
.map(|check_trait| { .map(|check_trait| {
self.infcx self.infcx
.type_implements_trait( .type_implements_trait(check_trait, [ty], self.param_env)
check_trait,
ty,
ty::List::empty(),
self.param_env,
)
.must_apply_modulo_regions() .must_apply_modulo_regions()
}) })
.unwrap_or(false), .unwrap_or(false),
@ -999,12 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
check_trait check_trait
.map(|check_trait| { .map(|check_trait| {
self.infcx self.infcx
.type_implements_trait( .type_implements_trait(check_trait, [ty], self.param_env)
check_trait,
ty,
ty::List::empty(),
self.param_env,
)
.must_apply_modulo_regions() .must_apply_modulo_regions()
}) })
.unwrap_or(false), .unwrap_or(false),
@ -1348,12 +1338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let is_drop_defined_for_ty = |ty: Ty<'tcx>| { let is_drop_defined_for_ty = |ty: Ty<'tcx>| {
let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span));
self.infcx self.infcx
.type_implements_trait( .type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id))
drop_trait,
ty,
ty::List::empty(),
self.tcx.param_env(closure_def_id),
)
.must_apply_modulo_regions() .must_apply_modulo_regions()
}; };

View file

@ -27,7 +27,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
def_id: DefId, def_id: DefId,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
) { ) {
let trait_ref = infcx.tcx.mk_trait_ref(def_id, ty, []); let trait_ref = infcx.tcx.mk_trait_ref(def_id, [ty]);
self.register_predicate_obligation( self.register_predicate_obligation(
infcx, infcx,
Obligation { Obligation {

View file

@ -152,13 +152,17 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
let infcx = cx.tcx.infer_ctxt().build(); let infcx = cx.tcx.infer_ctxt().build();
let suggest_display = is_str let suggest_display = is_str
|| cx.tcx.get_diagnostic_item(sym::Display).map(|t| { || cx
infcx.type_implements_trait(t, ty, ty::List::empty(), cx.param_env).may_apply() .tcx
}) == Some(true); .get_diagnostic_item(sym::Display)
.map(|t| infcx.type_implements_trait(t, [ty], cx.param_env).may_apply())
== Some(true);
let suggest_debug = !suggest_display let suggest_debug = !suggest_display
&& cx.tcx.get_diagnostic_item(sym::Debug).map(|t| { && cx
infcx.type_implements_trait(t, ty, ty::List::empty(), cx.param_env).may_apply() .tcx
}) == Some(true); .get_diagnostic_item(sym::Debug)
.map(|t| infcx.type_implements_trait(t, [ty], cx.param_env).may_apply())
== Some(true);
let suggest_panic_any = !is_str && panic == sym::std_panic_macro; let suggest_panic_any = !is_str && panic == sym::std_panic_macro;

View file

@ -2820,17 +2820,17 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn mk_trait_ref( pub fn mk_trait_ref(
self, self,
trait_def_id: DefId, trait_def_id: DefId,
self_ty: Ty<'tcx>, substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
rest: impl IntoIterator<Item = GenericArg<'tcx>, IntoIter: ExactSizeIterator>,
) -> ty::TraitRef<'tcx> { ) -> ty::TraitRef<'tcx> {
let rest = rest.into_iter(); let substs = substs.into_iter().map(Into::into);
let n = self.generics_of(trait_def_id).count();
debug_assert_eq!( debug_assert_eq!(
self.generics_of(trait_def_id).count() - 1, (n, Some(n)),
rest.len(), substs.size_hint(),
"wrong number of generic parameters for {trait_def_id:?} on self type {self_ty:?}: {:?} \nDid you accidentally include the self-type in the params list?", "wrong number of generic parameters for {trait_def_id:?}: {:?} \nDid you accidentally include the self-type in the params list?",
rest.collect::<Vec<_>>(), substs.collect::<Vec<_>>(),
); );
let substs = self.mk_substs_trait(self_ty, rest); let substs = self.mk_substs(substs);
ty::TraitRef::new(trait_def_id, substs) ty::TraitRef::new(trait_def_id, substs)
} }
@ -2994,11 +2994,10 @@ impl<'tcx> TyCtxtAt<'tcx> {
pub fn mk_trait_ref( pub fn mk_trait_ref(
self, self,
trait_lang_item: LangItem, trait_lang_item: LangItem,
self_ty: Ty<'tcx>, substs: impl IntoIterator<Item = impl Into<ty::GenericArg<'tcx>>>,
rest: impl IntoIterator<Item = ty::GenericArg<'tcx>, IntoIter: ExactSizeIterator>,
) -> ty::TraitRef<'tcx> { ) -> ty::TraitRef<'tcx> {
let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span)); let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span));
self.tcx.mk_trait_ref(trait_def_id, self_ty, rest) self.tcx.mk_trait_ref(trait_def_id, substs)
} }
} }

View file

@ -719,7 +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(tcx.mk_trait_ref(did, self_ty, [])); let trait_ref = self.rebind(tcx.mk_trait_ref(did, [self_ty]));
trait_ref.without_const().to_predicate(tcx) trait_ref.without_const().to_predicate(tcx)
} }
} }
@ -812,7 +812,10 @@ impl<'tcx> TraitRef<'tcx> {
} }
pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
tcx.mk_trait_ref(self.def_id, self_ty, self.substs.iter().skip(1)) tcx.mk_trait_ref(
self.def_id,
[self_ty.into()].into_iter().chain(self.substs.iter().skip(1)),
)
} }
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi` /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
@ -910,7 +913,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());
tcx.mk_trait_ref(self.def_id, self_ty, self.substs.iter()) tcx.mk_trait_ref(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter()))
} }
} }

View file

@ -232,8 +232,7 @@ impl<'tcx> ConstToPat<'tcx> {
ObligationCause::misc(self.span, self.id), ObligationCause::misc(self.span, self.id),
partial_eq_trait_id, partial_eq_trait_id,
0, 0,
ty, [ty, ty],
[ty.into()],
); );
// FIXME: should this call a `predicate_must_hold` variant instead? // FIXME: should this call a `predicate_must_hold` variant instead?

View file

@ -28,7 +28,7 @@ fn custom_coerce_unsize_info<'tcx>(
target_ty: Ty<'tcx>, target_ty: Ty<'tcx>,
) -> CustomCoerceUnsized { ) -> CustomCoerceUnsized {
let trait_ref = let trait_ref =
ty::Binder::dummy(tcx.mk_trait_ref(LangItem::CoerceUnsized, source_ty, [target_ty.into()])); ty::Binder::dummy(tcx.mk_trait_ref(LangItem::CoerceUnsized, [source_ty, target_ty]));
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 {

View file

@ -122,7 +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 = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, ty, []); let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, [ty]);
let cause = traits::ObligationCause::misc(self.span, self.body_id); let cause = traits::ObligationCause::misc(self.span, self.body_id);

View file

@ -7,9 +7,8 @@ use rustc_infer::traits::ObligationCause;
use rustc_middle::arena::ArenaAllocatable; use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse}; use rustc_middle::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse};
use rustc_middle::traits::query::Fallible; use rustc_middle::traits::query::Fallible;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::ToPredicate;
use rustc_middle::ty::{self, Ty, TypeFoldable, TypeVisitable}; use rustc_middle::ty::{self, Ty, TypeFoldable, TypeVisitable};
use rustc_middle::ty::{GenericArg, ToPredicate};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
use std::fmt::Debug; use std::fmt::Debug;
@ -44,8 +43,7 @@ pub trait InferCtxtExt<'tcx> {
/// The inputs are: /// The inputs are:
/// ///
/// - the def-id of the trait /// - the def-id of the trait
/// - the self type /// - the type parameters of the trait, including the self-type
/// - the *other* type parameters of the trait, excluding the self-type
/// - the parameter environment /// - the parameter environment
/// ///
/// Invokes `evaluate_obligation`, so in the event that evaluating /// Invokes `evaluate_obligation`, so in the event that evaluating
@ -54,8 +52,7 @@ pub trait InferCtxtExt<'tcx> {
fn type_implements_trait( fn type_implements_trait(
&self, &self,
trait_def_id: DefId, trait_def_id: DefId,
ty: Ty<'tcx>, params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
params: SubstsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> traits::EvaluationResult; ) -> traits::EvaluationResult;
} }
@ -109,15 +106,14 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
InferOk { value, obligations } InferOk { value, obligations }
} }
#[instrument(level = "debug", skip(self), ret)] #[instrument(level = "debug", skip(self, params), ret)]
fn type_implements_trait( fn type_implements_trait(
&self, &self,
trait_def_id: DefId, trait_def_id: DefId,
self_ty: Ty<'tcx>, params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
params: SubstsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> traits::EvaluationResult { ) -> traits::EvaluationResult {
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, self_ty, params); let trait_ref = self.tcx.mk_trait_ref(trait_def_id, params);
let obligation = traits::Obligation { let obligation = traits::Obligation {
cause: traits::ObligationCause::dummy(), cause: traits::ObligationCause::dummy(),

View file

@ -86,7 +86,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
) -> AutoTraitResult<A> { ) -> AutoTraitResult<A> {
let tcx = self.tcx; let tcx = self.tcx;
let trait_ref = tcx.mk_trait_ref(trait_did, 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,7 +260,7 @@ 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: infcx.tcx.mk_trait_ref(trait_did, ty, []), trait_ref: infcx.tcx.mk_trait_ref(trait_did, [ty]),
constness: ty::BoundConstness::NotConst, constness: ty::BoundConstness::NotConst,
// Auto traits are positive // Auto traits are positive

View file

@ -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 = tcx.mk_trait_ref(def_id, 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,

View file

@ -347,7 +347,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
span: DUMMY_SP, span: DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable, kind: TypeVariableOriginKind::MiscVariable,
}); });
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, ty.skip_binder(), [var.into()]); let trait_ref = self.tcx.mk_trait_ref(trait_def_id, [ty.skip_binder(), var]);
let obligation = Obligation::new( let obligation = Obligation::new(
self.tcx, self.tcx,
ObligationCause::dummy(), ObligationCause::dummy(),

View file

@ -2971,8 +2971,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
let impls_future = self.type_implements_trait( let impls_future = self.type_implements_trait(
future_trait, future_trait,
self.tcx.erase_late_bound_regions(self_ty), [self.tcx.erase_late_bound_regions(self_ty)],
ty::List::empty(),
obligation.param_env, obligation.param_env,
); );
if !impls_future.must_apply_modulo_regions() { if !impls_future.must_apply_modulo_regions() {
@ -3070,15 +3069,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
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 = match diagnostic_name {
sym::PartialEq | sym::PartialOrd => { sym::PartialEq | sym::PartialOrd => {
Some(field_ty.into()) Some(field_ty)
} }
_ => None, _ => None,
}; };
let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate { let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
trait_ref: self.tcx.mk_trait_ref( trait_ref: self.tcx.mk_trait_ref(
trait_pred.def_id(), trait_pred.def_id(),
field_ty, [field_ty].into_iter().chain(trait_substs),
trait_substs,
), ),
..*tr ..*tr
}); });

View file

@ -143,7 +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 = ty::Binder::dummy(infcx.tcx.mk_trait_ref(def_id, ty, [])); let trait_ref = ty::Binder::dummy(infcx.tcx.mk_trait_ref(def_id, [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,7 +903,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 = tcx.mk_trait_ref(unsize_trait_did, source, [target.into()]); let trait_ref = tcx.mk_trait_ref(unsize_trait_did, [source, target]);
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)) => {

View file

@ -685,11 +685,9 @@ 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(tcx.mk_trait_ref( let unsize_predicate = ty::Binder::dummy(
unsize_did, tcx.mk_trait_ref(unsize_did, [tcx.types.self_param, unsized_self_ty]),
tcx.types.self_param, )
[unsized_self_ty.into()],
))
.without_const() .without_const()
.to_predicate(tcx); .to_predicate(tcx);
@ -721,11 +719,9 @@ fn receiver_is_dispatchable<'tcx>(
// Receiver: DispatchFromDyn<Receiver[Self => U]> // Receiver: DispatchFromDyn<Receiver[Self => U]>
let obligation = { let obligation = {
let predicate = ty::Binder::dummy(tcx.mk_trait_ref( let predicate = ty::Binder::dummy(
dispatch_from_dyn_did, tcx.mk_trait_ref(dispatch_from_dyn_did, [receiver_ty, unsized_receiver_ty]),
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)

View file

@ -1712,7 +1712,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
selcx.tcx(), selcx.tcx(),
ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref( ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref(
LangItem::Sized, LangItem::Sized,
self_ty, [], [self_ty],
)) ))
.without_const(), .without_const(),
), ),
@ -1966,11 +1966,9 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
) )
}); });
if check_is_sized { if check_is_sized {
let sized_predicate = ty::Binder::dummy(tcx.at(obligation.cause.span).mk_trait_ref( let sized_predicate = ty::Binder::dummy(
LangItem::Sized, tcx.at(obligation.cause.span).mk_trait_ref(LangItem::Sized, [self_ty]),
self_ty, )
[],
))
.without_const(); .without_const();
obligations.push(obligation.with(tcx, sized_predicate)); obligations.push(obligation.with(tcx, sized_predicate));
} }

View file

@ -714,7 +714,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
// <ty as Deref> // <ty as Deref>
let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, ty, []); let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, [ty]);
let obligation = traits::Obligation::new( let obligation = traits::Obligation::new(
tcx, tcx,

View file

@ -632,11 +632,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
output_ty, output_ty,
&mut nested, &mut nested,
); );
let tr = ty::Binder::dummy(self.tcx().at(cause.span).mk_trait_ref( let tr =
LangItem::Sized, ty::Binder::dummy(self.tcx().at(cause.span).mk_trait_ref(LangItem::Sized, [output_ty]));
output_ty,
[],
));
nested.push(Obligation::new( nested.push(Obligation::new(
self.infcx.tcx, self.infcx.tcx,
cause, cause,
@ -998,7 +995,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// We can only make objects from sized types. // We can only make objects from sized types.
let tr = let tr =
ty::Binder::dummy(tcx.at(cause.span).mk_trait_ref(LangItem::Sized, source, [])); ty::Binder::dummy(tcx.at(cause.span).mk_trait_ref(LangItem::Sized, [source]));
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
// If the type is `Foo + 'a`, ensure that the type // If the type is `Foo + 'a`, ensure that the type
@ -1104,8 +1101,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.cause.clone(), obligation.cause.clone(),
obligation.predicate.def_id(), obligation.predicate.def_id(),
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
source_tail, [source_tail, target_tail],
[target_tail.into()],
)); ));
} }
@ -1135,8 +1131,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.cause.clone(), obligation.cause.clone(),
obligation.predicate.def_id(), obligation.predicate.def_id(),
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
a_last, [a_last, b_last],
[b_last.into()],
) )
})); }));
} }
@ -1252,11 +1247,10 @@ 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: self.tcx().at(cause.span).mk_trait_ref( trait_ref: self
LangItem::Destruct, .tcx()
nested_ty, .at(cause.span)
[], .mk_trait_ref(LangItem::Destruct, [nested_ty]),
),
constness: ty::BoundConstness::ConstIfConst, constness: ty::BoundConstness::ConstIfConst,
polarity: ty::ImplPolarity::Positive, polarity: ty::ImplPolarity::Positive,
}), }),
@ -1277,11 +1271,10 @@ 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: self.tcx().at(cause.span).mk_trait_ref( trait_ref: self
LangItem::Destruct, .tcx()
nested_ty, .at(cause.span)
[], .mk_trait_ref(LangItem::Destruct, [nested_ty]),
),
constness: ty::BoundConstness::ConstIfConst, constness: ty::BoundConstness::ConstIfConst,
polarity: ty::ImplPolarity::Positive, polarity: ty::ImplPolarity::Positive,
}); });

View file

@ -2100,8 +2100,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
cause.clone(), cause.clone(),
trait_def_id, trait_def_id,
recursion_depth, recursion_depth,
normalized_ty, [normalized_ty],
[],
); );
obligations.push(placeholder_obligation); obligations.push(placeholder_obligation);
obligations obligations

View file

@ -238,10 +238,9 @@ pub fn predicate_for_trait_def<'tcx>(
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
trait_def_id: DefId, trait_def_id: DefId,
recursion_depth: usize, recursion_depth: usize,
self_ty: Ty<'tcx>, params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
params: impl IntoIterator<Item = GenericArg<'tcx>, IntoIter: ExactSizeIterator>,
) -> PredicateObligation<'tcx> { ) -> PredicateObligation<'tcx> {
let trait_ref = tcx.mk_trait_ref(trait_def_id, self_ty, params); let trait_ref = tcx.mk_trait_ref(trait_def_id, 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)
} }
@ -304,7 +303,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 = tcx.mk_trait_ref(fn_trait_def_id, self_ty, [arguments_tuple.into()]); let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]);
sig.map_bound(|sig| (trait_ref, sig.output())) sig.map_bound(|sig| (trait_ref, sig.output()))
} }
@ -315,8 +314,7 @@ 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 = let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, sig.skip_binder().resume_ty]);
tcx.mk_trait_ref(fn_trait_def_id, 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))
} }

View file

@ -421,7 +421,7 @@ 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 = self.tcx.at(cause.span).mk_trait_ref(LangItem::Sized, subty, []); let trait_ref = self.tcx.at(cause.span).mk_trait_ref(LangItem::Sized, [subty]);
self.out.push(traits::Obligation::with_depth( self.out.push(traits::Obligation::with_depth(
self.tcx, self.tcx,
cause, cause,

View file

@ -49,7 +49,7 @@ 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(tcx.mk_trait_ref(sized_trait, ty, [])) let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref(sized_trait, [ty]))
.without_const() .without_const()
.to_predicate(tcx); .to_predicate(tcx);
let predicates = tcx.predicates_of(adtdef.did()).predicates; let predicates = tcx.predicates_of(adtdef.did()).predicates;

View file

@ -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 = tcx.mk_trait_ref(trait_def_id, 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;

View file

@ -842,14 +842,10 @@ fn walk_parents<'tcx>(
} else if let Some(trait_id) = cx.tcx.trait_of_item(id) } else if let Some(trait_id) = cx.tcx.trait_of_item(id)
&& let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e)) && let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind() && let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
&& let subs = match cx && let subs = cx
.typeck_results() .typeck_results()
.node_substs_opt(parent.hir_id) .node_substs_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default()
.and_then(|subs| subs.get(1..)) && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
{
Some(subs) => cx.tcx.mk_substs(subs.iter().copied()),
None => cx.tcx.mk_substs(std::iter::empty::<ty::subst::GenericArg<'_>>()),
} && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
// Trait methods taking `&self` // Trait methods taking `&self`
sub_ty sub_ty
} else { } else {
@ -858,7 +854,7 @@ fn walk_parents<'tcx>(
} && impl_ty.is_ref() } && impl_ty.is_ref()
&& let infcx = cx.tcx.infer_ctxt().build() && let infcx = cx.tcx.infer_ctxt().build()
&& infcx && infcx
.type_implements_trait(trait_id, impl_ty, subs, cx.param_env) .type_implements_trait(trait_id, [impl_ty.into()].into_iter().chain(subs.iter().copied()), cx.param_env)
.must_apply_modulo_regions() .must_apply_modulo_regions()
{ {
return Some(Position::MethodReceiverRefImpl) return Some(Position::MethodReceiverRefImpl)

View file

@ -692,7 +692,7 @@ fn matches_preds<'tcx>(
let infcx = cx.tcx.infer_ctxt().build(); let infcx = cx.tcx.infer_ctxt().build();
preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) { preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) {
ExistentialPredicate::Trait(p) => infcx ExistentialPredicate::Trait(p) => infcx
.type_implements_trait(p.def_id, ty, p.substs, cx.param_env) .type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.substs.iter()), cx.param_env)
.must_apply_modulo_regions(), .must_apply_modulo_regions(),
ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new( ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new(
cx.tcx, cx.tcx,
@ -704,7 +704,7 @@ fn matches_preds<'tcx>(
)), )),
)), )),
ExistentialPredicate::AutoTrait(p) => infcx ExistentialPredicate::AutoTrait(p) => infcx
.type_implements_trait(p, ty, List::empty(), cx.param_env) .type_implements_trait(p, [ty], cx.param_env)
.must_apply_modulo_regions(), .must_apply_modulo_regions(),
}) })
} }

View file

@ -178,7 +178,7 @@ pub fn implements_trait_with_env<'tcx>(
}; };
let ty_params = tcx.mk_substs(ty_params.into_iter().map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into()))); let ty_params = tcx.mk_substs(ty_params.into_iter().map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())));
infcx infcx
.type_implements_trait(trait_id, ty, ty_params, param_env) .type_implements_trait(trait_id, [ty.into()].into_iter().chain(ty_params), param_env)
.must_apply_modulo_regions() .must_apply_modulo_regions()
} }