From 0c47deed9fa7ef3c59453cf7a88159b36ff67b95 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 09:03:27 +0000 Subject: [PATCH 01/21] Reduce the amount of passed-around arguments that will get merged into one later anyway --- compiler/rustc_middle/src/ty/adjustment.rs | 7 +++---- compiler/rustc_mir_build/src/thir/cx/expr.rs | 17 +++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 4682ac96b5297..458cbfa6e35cf 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -1,7 +1,5 @@ -use crate::ty::subst::SubstsRef; use crate::ty::{self, Ty, TyCtxt}; use rustc_hir as hir; -use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_macros::HashStable; use rustc_span::Span; @@ -121,7 +119,8 @@ pub struct OverloadedDeref<'tcx> { } impl<'tcx> OverloadedDeref<'tcx> { - pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> (DefId, SubstsRef<'tcx>) { + /// Get the zst function item type for this method call. + pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> Ty<'tcx> { let trait_def_id = match self.mutbl { hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None), hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None), @@ -132,7 +131,7 @@ impl<'tcx> OverloadedDeref<'tcx> { .find(|m| m.kind == ty::AssocKind::Fn) .unwrap() .def_id; - (method_def_id, tcx.mk_substs_trait(source, &[])) + tcx.mk_fn_def(method_def_id, tcx.mk_substs_trait(source, &[])) } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 57382f5e1bdb2..60e64b45963c3 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -14,11 +14,10 @@ use rustc_middle::thir::*; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast, }; -use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; +use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{ self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType, }; -use rustc_span::def_id::DefId; use rustc_span::Span; use rustc_target::abi::VariantIdx; @@ -806,12 +805,12 @@ impl<'tcx> Cx<'tcx> { &mut self, expr: &hir::Expr<'_>, span: Span, - overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>, + overloaded_callee: Option>, ) -> Expr<'tcx> { let temp_lifetime = self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id); - let (def_id, substs, user_ty) = match overloaded_callee { - Some((def_id, substs)) => (def_id, substs, None), + let (ty, user_ty) = match overloaded_callee { + Some(fn_def) => (fn_def, None), None => { let (kind, def_id) = self.typeck_results().type_dependent_def(expr.hir_id).unwrap_or_else(|| { @@ -819,10 +818,12 @@ impl<'tcx> Cx<'tcx> { }); let user_ty = self.user_substs_applied_to_res(expr.hir_id, Res::Def(kind, def_id)); debug!("method_callee: user_ty={:?}", user_ty); - (def_id, self.typeck_results().node_substs(expr.hir_id), user_ty) + ( + self.tcx().mk_fn_def(def_id, self.typeck_results().node_substs(expr.hir_id)), + user_ty, + ) } }; - let ty = self.tcx().mk_fn_def(def_id, substs); Expr { temp_lifetime, ty, span, kind: ExprKind::ZstLiteral { user_ty } } } @@ -957,7 +958,7 @@ impl<'tcx> Cx<'tcx> { &mut self, expr: &'tcx hir::Expr<'tcx>, place_ty: Ty<'tcx>, - overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>, + overloaded_callee: Option>, args: Box<[ExprId]>, span: Span, ) -> ExprKind<'tcx> { From 250dcf421a6db36f85f69c481eab27a0b45887af Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 10:22:44 +0000 Subject: [PATCH 02/21] Check that type_implements_trait actually is passed the right amount of generic params --- compiler/rustc_hir_typeck/src/cast.rs | 2 +- .../rustc_hir_typeck/src/method/prelude2021.rs | 15 ++++++++------- compiler/rustc_hir_typeck/src/upvar.rs | 7 +++---- compiler/rustc_trait_selection/src/infer.rs | 14 +++++++++++--- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index e5dc4b06c0ba6..50fd4fd2a8f89 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -498,7 +498,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { let ty = fcx.tcx.erase_regions(ty); let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); let expr_ty = fcx.tcx.erase_regions(expr_ty); - let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]); + let ty_params = fcx.tcx.mk_substs(std::iter::once(ty::GenericArg::from(expr_ty))); if fcx .infcx .type_implements_trait(from_trait, ty, ty_params, fcx.param_env) diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 3c98a2aa3aba3..1a5383ea245ea 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -8,7 +8,8 @@ use hir::ItemKind; use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_middle::ty::subst::InternalSubsts; +use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_middle::ty; use rustc_middle::ty::{Adt, Array, Ref, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::{Empty, Underscore}; @@ -227,14 +228,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If we know it does not, we don't need to warn. if method_name.name == sym::from_iter { if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) { + let any_type = self.infcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span, + }); + let params = self.tcx.mk_substs(std::iter::once(ty::GenericArg::from(any_type))); if !self .infcx - .type_implements_trait( - trait_def_id, - self_ty, - InternalSubsts::empty(), - self.param_env, - ) + .type_implements_trait(trait_def_id, self_ty, params, self.param_env) .may_apply() { return; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 4dea40829f622..090c73d1638a6 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -973,7 +973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .type_implements_trait( check_trait, ty, - self.tcx.mk_substs_trait(ty, &[]), + ty::List::empty(), self.param_env, ) .must_apply_modulo_regions() @@ -1002,7 +1002,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .type_implements_trait( check_trait, ty, - self.tcx.mk_substs_trait(ty, &[]), + ty::List::empty(), self.param_env, ) .must_apply_modulo_regions() @@ -1347,12 +1347,11 @@ impl<'a, 'tcx> FnCtxt<'a, '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 ty_params = self.tcx.mk_substs_trait(base_path_ty, &[]); self.infcx .type_implements_trait( drop_trait, ty, - ty_params, + ty::List::empty(), self.tcx.param_env(closure_def_id), ) .must_apply_modulo_regions() diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 0f2e22604dc7e..73e220dc7af13 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -113,12 +113,20 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { fn type_implements_trait( &self, trait_def_id: DefId, - ty: Ty<'tcx>, + self_ty: Ty<'tcx>, params: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult { - let trait_ref = - ty::TraitRef { def_id: trait_def_id, substs: self.tcx.mk_substs_trait(ty, params) }; + let trait_ref = ty::TraitRef { + def_id: trait_def_id, + substs: self.tcx.mk_substs_trait(self_ty, params), + }; + + debug_assert_eq!( + self.tcx.generics_of(trait_def_id).count() - 1, + params.len(), + "wrong number of generic parameters for {trait_def_id:?}, did you accidentally include the self-type in the params list?" + ); let obligation = traits::Obligation { cause: traits::ObligationCause::dummy(), From 48ff6a95b559e0c293f4c118145964332994dcc0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 10:24:55 +0000 Subject: [PATCH 03/21] Use ty::List instead of InternalSubsts --- compiler/rustc_lint/src/non_fmt_panic.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 83e6f4e33bed8..d733eebcad6c5 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -5,7 +5,6 @@ use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::lint::in_external_macro; use rustc_middle::ty; -use rustc_middle::ty::subst::InternalSubsts; use rustc_parse_format::{ParseMode, Parser, Piece}; use rustc_session::lint::FutureIncompatibilityReason; use rustc_span::edition::Edition; @@ -154,15 +153,11 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc let infcx = cx.tcx.infer_ctxt().build(); let suggest_display = is_str || cx.tcx.get_diagnostic_item(sym::Display).map(|t| { - infcx - .type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env) - .may_apply() + infcx.type_implements_trait(t, ty, ty::List::empty(), cx.param_env).may_apply() }) == Some(true); let suggest_debug = !suggest_display && cx.tcx.get_diagnostic_item(sym::Debug).map(|t| { - infcx - .type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env) - .may_apply() + infcx.type_implements_trait(t, ty, ty::List::empty(), cx.param_env).may_apply() }) == Some(true); let suggest_panic_any = !is_str && panic == sym::std_panic_macro; From d9a02b0fb728ac994883845b1c53630c2dec4657 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 10:36:18 +0000 Subject: [PATCH 04/21] Split out the actual predicate solving code into a separate function --- .../rustc_trait_selection/src/traits/mod.rs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index ddc9b768f07e0..4da19bb4a6a8c 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -136,7 +136,6 @@ pub fn predicates_for_generics<'tcx>( /// `bound` or is not known to meet bound (note that this is /// conservative towards *no impl*, which is the opposite of the /// `evaluate` methods). -#[instrument(level = "debug", skip(infcx, param_env, span), ret)] pub fn type_known_to_meet_bound_modulo_regions<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -146,31 +145,40 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( ) -> bool { let trait_ref = 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) +} + +#[instrument(level = "debug", skip(infcx, param_env, span, pred), ret)] +fn pred_known_to_hold_modulo_regions<'tcx>( + infcx: &InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + pred: impl ToPredicate<'tcx, ty::Predicate<'tcx>> + TypeVisitable<'tcx>, + span: Span, +) -> bool { + let has_non_region_infer = pred.has_non_region_infer(); let obligation = Obligation { param_env, + // We can use a dummy node-id here because we won't pay any mind + // to region obligations that arise (there shouldn't really be any + // anyhow). cause: ObligationCause::misc(span, hir::CRATE_HIR_ID), recursion_depth: 0, - predicate: trait_ref.without_const().to_predicate(infcx.tcx), + predicate: pred.to_predicate(infcx.tcx), }; let result = infcx.predicate_must_hold_modulo_regions(&obligation); debug!(?result); - if result && ty.has_non_region_infer() { + if result && has_non_region_infer { // Because of inference "guessing", selection can sometimes claim // to succeed while the success requires a guess. To ensure // this function's result remains infallible, we must confirm // that guess. While imperfect, I believe this is sound. - // We can use a dummy node-id here because we won't pay any mind - // to region obligations that arise (there shouldn't really be any - // anyhow). - let cause = ObligationCause::misc(span, hir::CRATE_HIR_ID); - // The handling of regions in this area of the code is terrible, // see issue #29149. We should be able to improve on this with // NLL. - let errors = fully_solve_bound(infcx, cause, param_env, ty, def_id); + let errors = fully_solve_obligation(infcx, obligation); // Note: we only assume something is `Copy` if we can // *definitively* show that it implements `Copy`. Otherwise, From 6f77c97b386f05083f039f0130146addf99eefd9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 11:21:39 +0000 Subject: [PATCH 05/21] Assert that various types have the right amount of generic args and fix the sites that used the wrong amount --- compiler/rustc_borrowck/src/type_check/mod.rs | 51 ++++++++++--------- .../src/transform/check_consts/qualifs.rs | 5 +- compiler/rustc_hir_analysis/src/bounds.rs | 5 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 5 +- .../src/fn_ctxt/suggestions.rs | 8 +-- .../rustc_hir_typeck/src/method/suggest.rs | 4 +- compiler/rustc_infer/src/traits/engine.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 25 +++++++++ compiler/rustc_middle/src/ty/sty.rs | 7 +-- .../src/thir/pattern/const_to_pat.rs | 10 +++- compiler/rustc_monomorphize/src/lib.rs | 5 +- .../rustc_trait_selection/src/autoderef.rs | 7 +-- compiler/rustc_trait_selection/src/infer.rs | 5 +- .../src/traits/auto_trait.rs | 8 ++- .../src/traits/engine.rs | 2 +- .../src/traits/error_reporting/mod.rs | 21 ++++---- .../src/traits/error_reporting/suggestions.rs | 17 ++++--- .../rustc_trait_selection/src/traits/mod.rs | 8 +-- .../src/traits/object_safety.rs | 18 ++++--- .../src/traits/project.rs | 9 ++-- .../src/traits/relationships.rs | 8 +-- .../src/traits/select/candidate_assembly.rs | 5 +- .../src/traits/select/confirmation.rs | 28 +++++----- .../rustc_trait_selection/src/traits/util.rs | 14 ++--- .../rustc_trait_selection/src/traits/wf.rs | 9 ++-- compiler/rustc_ty_utils/src/ty.rs | 9 ++-- src/librustdoc/clean/auto_trait.rs | 2 +- 27 files changed, 153 insertions(+), 144 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 9b6c7d27c791b..e63c0699d40b7 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -547,10 +547,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { let tcx = self.tcx(); - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty.ty, &[]), - }; + let trait_ref = tcx.mk_trait_ref( + tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), + place_ty.ty, + &[], + ); // To have a `Copy` operand, the type `T` of the // 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); if !self.unsized_feature_enabled() { - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty, &[]), - }; + let trait_ref = tcx.mk_trait_ref( + tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), + place_ty, + &[], + ); self.prove_trait_ref( trait_ref, location.to_locations(), @@ -1865,9 +1867,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // Make sure that repeated elements implement `Copy`. let span = body.source_info(location).span; 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.mk_substs_trait(ty, &[]), + ty, + &[], ); self.prove_trait_ref( @@ -1881,10 +1884,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(ty, &[]), - }; + let trait_ref = tcx.mk_trait_ref( + tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), + ty, + &[], + ); self.prove_trait_ref( trait_ref, @@ -1896,10 +1900,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::ShallowInitBox(operand, ty) => { self.check_operand(operand, location); - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(*ty, &[]), - }; + let trait_ref = tcx.mk_trait_ref( + tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), + *ty, + &[], + ); self.prove_trait_ref( trait_ref, @@ -1996,11 +2001,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { CastKind::Pointer(PointerCast::Unsize) => { let &ty = ty; - let trait_ref = ty::TraitRef { - def_id: tcx - .require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)), - substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]), - }; + let trait_ref = tcx.mk_trait_ref( + tcx.require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)), + op.ty(body, tcx), + &[ty.into()], + ); self.prove_trait_ref( trait_ref, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 6fd12985170e6..8c43f93a91752 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -160,10 +160,7 @@ impl Qualif for NeedsNonConstDrop { ObligationCause::dummy(), cx.param_env, ty::Binder::dummy(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: destruct, - substs: cx.tcx.mk_substs_trait(ty, &[]), - }, + trait_ref: cx.tcx.mk_trait_ref(destruct, ty, &[]), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }), diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 6a28bb16a20ac..9944114f495b8 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -61,10 +61,7 @@ impl<'tcx> Bounds<'tcx> { // If it could be sized, and is, add the `Sized` predicate. let sized_predicate = self.implicitly_sized.and_then(|span| { tcx.lang_items().sized_trait().map(move |sized| { - let trait_ref = ty::Binder::dummy(ty::TraitRef { - def_id: sized, - substs: tcx.mk_substs_trait(param_ty, &[]), - }); + let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, param_ty, &[])); (trait_ref.without_const().to_predicate(tcx), span) }) }); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b81f9d7a6d2c1..3246397d82f0e 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1782,10 +1782,7 @@ fn receiver_is_implemented<'tcx>( receiver_ty: Ty<'tcx>, ) -> bool { let tcx = wfcx.tcx(); - let trait_ref = ty::Binder::dummy(ty::TraitRef { - def_id: receiver_trait_def_id, - substs: tcx.mk_substs_trait(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()); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 9f5aadca967bd..2c5a88225e90c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1093,10 +1093,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx, self.misc(expr.span), self.param_env, - ty::Binder::dummy(ty::TraitRef { - def_id: into_def_id, - substs: self.tcx.mk_substs_trait(expr_ty, &[expected_ty.into()]), - }) + ty::Binder::dummy(self.tcx.mk_trait_ref( + into_def_id, + expr_ty, &[expected_ty.into()] + )) .to_poly_trait_predicate(), )) { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 8190163cba15b..b55e3a114d330 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -68,7 +68,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.autoderef(span, ty).any(|(ty, _)| { info!("check deref {:?} impl FnOnce", ty); self.probe(|_| { - let fn_once_substs = tcx.mk_substs_trait( + let trait_ref = tcx.mk_trait_ref( + fn_once, ty, &[self .next_ty_var(TypeVariableOrigin { @@ -77,7 +78,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .into()], ); - let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); let poly_trait_ref = ty::Binder::dummy(trait_ref); let obligation = Obligation::misc( tcx, diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index b2b985a22ac01..d26f0cf385147 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -27,7 +27,7 @@ pub trait TraitEngine<'tcx>: 'tcx { def_id: DefId, 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( infcx, Obligation { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 13695089eb828..cf0d201cbb724 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2532,6 +2532,11 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] 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)) } @@ -2552,6 +2557,11 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] 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 })) } @@ -2803,6 +2813,21 @@ impl<'tcx> TyCtxt<'tcx> { 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< I: InternAs<[ty::BoundVariableKind], &'tcx List>, >( diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index e2a7b09de6ab4..b9717f2b37e05 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -719,10 +719,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> { self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) } ExistentialPredicate::AutoTrait(did) => { - let trait_ref = self.rebind(ty::TraitRef { - def_id: did, - substs: tcx.mk_substs_trait(self_ty, &[]), - }); + let trait_ref = self.rebind(tcx.mk_trait_ref(did, self_ty, &[])); 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 // 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) } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index ad12e01162117..80c250f044d97 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,6 +1,7 @@ use rustc_errors::DelayDm; use rustc_hir as hir; use rustc_index::vec::Idx; +use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::mir::{self, Field}; use rustc_middle::thir::{FieldPat, Pat, PatKind}; @@ -226,6 +227,13 @@ impl<'tcx> ConstToPat<'tcx> { // using `PartialEq::eq` in this scenario in the past.) let partial_eq_trait_id = 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( self.tcx(), self.param_env, @@ -233,7 +241,7 @@ impl<'tcx> ConstToPat<'tcx> { partial_eq_trait_id, 0, ty, - &[], + &[any_ty], ); // FIXME: should this call a `predicate_must_hold` variant instead? diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 42781bd25f05b..669599a424ab2 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -29,10 +29,7 @@ fn custom_coerce_unsize_info<'tcx>( ) -> CustomCoerceUnsized { let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None); - let trait_ref = ty::Binder::dummy(ty::TraitRef { - def_id, - substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]), - }); + let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(def_id, source_ty, &[target_ty.into()])); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index b7240a8289730..adef967b0a1a1 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -4,7 +4,7 @@ use crate::traits::{self, TraitEngine, TraitEngineExt}; use rustc_hir as hir; use rustc_infer::infer::InferCtxt; 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_span::def_id::LOCAL_CRATE; use rustc_span::Span; @@ -122,10 +122,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { let tcx = self.infcx.tcx; // - let trait_ref = TraitRef { - def_id: tcx.lang_items().deref_trait()?, - substs: tcx.mk_substs_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); diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 73e220dc7af13..5be49996a0b2d 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -117,10 +117,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { params: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult { - let trait_ref = ty::TraitRef { - def_id: trait_def_id, - substs: self.tcx.mk_substs_trait(self_ty, params), - }; + let trait_ref = self.tcx.mk_trait_ref(trait_def_id, self_ty, params); debug_assert_eq!( self.tcx.generics_of(trait_def_id).count() - 1, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 5869bc76b596c..3dab34747f7d2 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -86,7 +86,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult { 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); @@ -260,10 +260,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new(); predicates.push_back(ty::Binder::dummy(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: trait_did, - substs: infcx.tcx.mk_substs_trait(ty, &[]), - }, + trait_ref: infcx.tcx.mk_trait_ref(trait_did, ty, &[]), + constness: ty::BoundConstness::NotConst, // Auto traits are positive polarity: ty::ImplPolarity::Positive, diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index f8346e515d70c..97f4f7d795d6f 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -93,7 +93,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { def_id: DefId, ) { 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 { cause, recursion_depth: 0, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c3547f64b5c9c..cf9ba1d8421cd 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -347,16 +347,13 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { span: DUMMY_SP, 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( self.tcx, ObligationCause::dummy(), param_env, - ty.rebind(ty::TraitPredicate { - trait_ref: ty::TraitRef::new(trait_def_id, substs), - constness, - polarity, - }), + ty.rebind(ty::TraitPredicate { trait_ref, constness, polarity }), ); let mut fulfill_cx = >::new_in_snapshot(self.tcx); fulfill_cx.register_predicate_obligation(self, obligation); @@ -1002,7 +999,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && self.fallback_has_occurred { 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(), &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>)>, ) -> PredicateObligation<'tcx> { let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate { - trait_ref: ty::TraitRef { - substs: self.tcx.mk_substs_trait(*new_self_ty, &tr.trait_ref.substs[1..]), - ..tr.trait_ref - }, + trait_ref: self.tcx.mk_trait_ref( + tr.trait_ref.def_id, + *new_self_ty, + &tr.trait_ref.substs[1..], + ), ..*tr }); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 757977ac5d508..445b5696d20b3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3068,17 +3068,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Ensure all fields impl the trait. adt.all_fields().all(|field| { 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 => { - 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 { - trait_ref: ty::TraitRef { - substs: trait_substs, - ..trait_pred.skip_binder().trait_ref - }, + trait_ref: self.tcx.mk_trait_ref( + trait_pred.def_id(), + field_ty, + trait_substs, + ), ..*tr }); let field_obl = Obligation::new( diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 4da19bb4a6a8c..227a7f0a1124a 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -143,8 +143,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( def_id: DefId, span: Span, ) -> bool { - let trait_ref = - ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(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) } @@ -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. let unsize_trait_did = tcx.require_lang_item(LangItem::Unsize, None); - let trait_ref = ty::TraitRef { - def_id: unsize_trait_did, - substs: tcx.mk_substs_trait(source, &[target.into()]), - }; + let trait_ref = tcx.mk_trait_ref(unsize_trait_did, source, &[target.into()]); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) { Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 9745e0137ee9f..20826f2c54141 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -685,10 +685,11 @@ fn receiver_is_dispatchable<'tcx>( let param_env = tcx.param_env(method.def_id); // Self: Unsize - let unsize_predicate = ty::Binder::dummy(ty::TraitRef { - def_id: unsize_did, - substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]), - }) + let unsize_predicate = ty::Binder::dummy(tcx.mk_trait_ref( + unsize_did, + tcx.types.self_param, + &[unsized_self_ty.into()], + )) .without_const() .to_predicate(tcx); @@ -720,10 +721,11 @@ fn receiver_is_dispatchable<'tcx>( // Receiver: DispatchFromDyn U]> let obligation = { - let predicate = ty::Binder::dummy(ty::TraitRef { - def_id: dispatch_from_dyn_did, - substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]), - }) + let predicate = ty::Binder::dummy(tcx.mk_trait_ref( + dispatch_from_dyn_did, + receiver_ty, + &[unsized_receiver_ty.into()], + )) .without_const(); Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 528b98cf4a1c0..e1b30112e39b5 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1710,9 +1710,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( if selcx.infcx().predicate_must_hold_modulo_regions( &obligation.with( 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().mk_substs_trait(self_ty, &[]), + self_ty, &[], )) .without_const(), ), @@ -1966,9 +1966,10 @@ fn confirm_pointee_candidate<'cx, 'tcx>( ) }); 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.mk_substs_trait(self_ty, &[]), + self_ty, + &[], )) .without_const(); obligations.push(obligation.with(tcx, sized_predicate)); diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs index dfe19a5a86d3b..78f0807bd95b5 100644 --- a/compiler/rustc_trait_selection/src/traits/relationships.rs +++ b/compiler/rustc_trait_selection/src/traits/relationships.rs @@ -18,10 +18,10 @@ pub(crate) fn update<'tcx, T>( { let new_self_ty = infcx.tcx.types.unit; - let trait_ref = ty::TraitRef { - substs: infcx.tcx.mk_substs_trait(new_self_ty, &tpred.trait_ref.substs[1..]), - ..tpred.trait_ref - }; + let trait_ref = infcx.tcx.mk_trait_ref( + tpred.trait_ref.def_id, + new_self_ty, &tpred.trait_ref.substs[1..], + ); // Then construct a new obligation with Self = () added // to the ParamEnv, and see if it holds. diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 8183f34bb3c93..6b19b9297c515 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -714,10 +714,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } // - let trait_ref = ty::TraitRef { - def_id: tcx.lang_items().deref_trait()?, - substs: tcx.mk_substs_trait(ty, &[]), - }; + let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, ty, &[]); let obligation = traits::Obligation::new( tcx, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a496aed38ac17..6d737b455bf20 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -632,9 +632,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { output_ty, &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().mk_substs_trait(output_ty, &[]), + output_ty, + &[], )); nested.push(Obligation::new( self.infcx.tcx, @@ -996,9 +997,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); // 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.mk_substs_trait(source, &[]), + source, + &[], )); nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); @@ -1253,10 +1255,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause.clone(), obligation.recursion_depth + 1, self_ty.rebind(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: self.tcx().require_lang_item(LangItem::Destruct, None), - substs: self.tcx().mk_substs_trait(nested_ty, &[]), - }, + trait_ref: self.tcx().mk_trait_ref( + self.tcx().require_lang_item(LangItem::Destruct, None), + nested_ty, + &[], + ), constness: ty::BoundConstness::ConstIfConst, 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) _ => { let predicate = self_ty.rebind(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: self.tcx().require_lang_item(LangItem::Destruct, None), - substs: self.tcx().mk_substs_trait(nested_ty, &[]), - }, + trait_ref: self.tcx().mk_trait_ref( + self.tcx().require_lang_item(LangItem::Destruct, None), + nested_ty, + &[], + ), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index ed47d2f83df65..21c79461edaf3 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -241,8 +241,7 @@ pub fn predicate_for_trait_def<'tcx>( self_ty: Ty<'tcx>, params: &[GenericArg<'tcx>], ) -> PredicateObligation<'tcx> { - let trait_ref = - ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(self_ty, params) }; + let trait_ref = tcx.mk_trait_ref(trait_def_id, self_ty, params); 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()), }; debug_assert!(!self_ty.has_escaping_bound_vars()); - let trait_ref = ty::TraitRef { - def_id: fn_trait_def_id, - substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]), - }; + let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, self_ty, &[arguments_tuple.into()]); sig.map_bound(|sig| (trait_ref, sig.output())) } @@ -319,10 +315,8 @@ pub fn generator_trait_ref_and_outputs<'tcx>( sig: ty::PolyGenSig<'tcx>, ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { debug_assert!(!self_ty.has_escaping_bound_vars()); - let trait_ref = ty::TraitRef { - def_id: fn_trait_def_id, - substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]), - }; + let trait_ref = + 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)) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index fce92c66ee8c7..3fe019cb7de69 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -421,10 +421,11 @@ impl<'tcx> WfPredicates<'tcx> { fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { if !subty.has_escaping_bound_vars() { let cause = self.cause(cause); - let trait_ref = ty::TraitRef { - def_id: self.tcx.require_lang_item(LangItem::Sized, None), - substs: self.tcx.mk_substs_trait(subty, &[]), - }; + let trait_ref = self.tcx.mk_trait_ref( + self.tcx.require_lang_item(LangItem::Sized, None), + subty, + &[], + ); self.out.push(traits::Obligation::with_depth( self.tcx, cause, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index bd7b64ad7c1ea..e88d39cd2715d 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -49,12 +49,9 @@ fn sized_constraint_for_ty<'tcx>( // it on the impl. let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] }; - let sized_predicate = ty::Binder::dummy(ty::TraitRef { - def_id: sized_trait, - substs: tcx.mk_substs_trait(ty, &[]), - }) - .without_const() - .to_predicate(tcx); + let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref(sized_trait, ty, &[])) + .without_const() + .to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } } diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 85bd8446640dd..03ac2f14f7a6b 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -44,7 +44,7 @@ where discard_positive_impl: bool, ) -> Option { 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)) { debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref); return None; From 19a1192d426656fcb8d71cdb510f6920d9ba70ee Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 11:55:27 +0000 Subject: [PATCH 06/21] Add a helper for replacing the self type in trait refs --- compiler/rustc_hir_typeck/src/_match.rs | 6 ++---- compiler/rustc_middle/src/ty/mod.rs | 4 ++++ compiler/rustc_middle/src/ty/sty.rs | 4 ++++ .../src/traits/error_reporting/mod.rs | 19 ++++--------------- .../src/traits/relationships.rs | 11 +---------- 5 files changed, 15 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 139f2e8413662..7d081bac3bda6 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -539,11 +539,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .subst_iter_copied(self.tcx, substs) { let pred = pred.kind().rebind(match pred.kind().skip_binder() { - ty::PredicateKind::Trait(mut trait_pred) => { + ty::PredicateKind::Trait(trait_pred) => { assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty); - trait_pred.trait_ref.substs = - self.tcx.mk_substs_trait(ty, &trait_pred.trait_ref.substs[1..]); - ty::PredicateKind::Trait(trait_pred) + ty::PredicateKind::Trait(trait_pred.with_self_type(self.tcx, ty)) } ty::PredicateKind::Projection(mut proj_pred) => { assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b4779655252f9..8bac76d559f24 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -852,6 +852,10 @@ impl<'tcx> TraitPredicate<'tcx> { } } + pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { + Self { trait_ref: self.trait_ref.with_self_type(tcx, self_ty), ..self } + } + pub fn def_id(self) -> DefId { self.trait_ref.def_id } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index b9717f2b37e05..47cdabb5f8195 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -811,6 +811,10 @@ impl<'tcx> TraitRef<'tcx> { TraitRef { def_id, substs } } + 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[1..]) + } + /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` /// are the parameters defined on trait. pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index cf9ba1d8421cd..cb9902bed546b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -998,13 +998,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if trait_predicate.skip_binder().self_ty().is_never() && self.fallback_has_occurred { - let predicate = trait_predicate.map_bound(|mut trait_pred| { - trait_pred.trait_ref = self.tcx.mk_trait_ref( - trait_pred.trait_ref.def_id, - self.tcx.mk_unit(), - &trait_pred.trait_ref.substs[1..], - ); - trait_pred + let predicate = trait_predicate.map_bound(|trait_pred| { + trait_pred.with_self_type(self.tcx, self.tcx.mk_unit()) }); let unit_obligation = obligation.with(tcx, predicate); if self.predicate_may_hold(&unit_obligation) { @@ -2026,14 +2021,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { param_env: ty::ParamEnv<'tcx>, trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>, ) -> PredicateObligation<'tcx> { - let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate { - trait_ref: self.tcx.mk_trait_ref( - tr.trait_ref.def_id, - *new_self_ty, - &tr.trait_ref.substs[1..], - ), - ..*tr - }); + let trait_pred = trait_ref_and_ty + .map_bound(|(tr, new_self_ty)| tr.with_self_type(self.tcx, new_self_ty)); Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred) } diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs index 78f0807bd95b5..f844da500328e 100644 --- a/compiler/rustc_trait_selection/src/traits/relationships.rs +++ b/compiler/rustc_trait_selection/src/traits/relationships.rs @@ -18,11 +18,6 @@ pub(crate) fn update<'tcx, T>( { let new_self_ty = infcx.tcx.types.unit; - let trait_ref = infcx.tcx.mk_trait_ref( - tpred.trait_ref.def_id, - new_self_ty, &tpred.trait_ref.substs[1..], - ); - // Then construct a new obligation with Self = () added // to the ParamEnv, and see if it holds. let o = obligation.with(infcx.tcx, @@ -31,11 +26,7 @@ pub(crate) fn update<'tcx, T>( .kind() .rebind( // (*) binder moved here - ty::PredicateKind::Trait(ty::TraitPredicate { - trait_ref, - constness: tpred.constness, - polarity: tpred.polarity, - }) + ty::PredicateKind::Trait(tpred.with_self_type(infcx.tcx, new_self_ty)) ), ); // Don't report overflow errors. Otherwise equivalent to may_hold. From bd40c10751baf6c0c5fc52c99900c0b9066ed11b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 12:07:31 +0000 Subject: [PATCH 07/21] Remove an unnecessary query + subst round --- compiler/rustc_middle/src/mir/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index e0a786e201a16..8b70eabb105c8 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1884,7 +1884,7 @@ impl<'tcx> Operand<'tcx> { substs: SubstsRef<'tcx>, span: Span, ) -> Self { - let ty = tcx.bound_type_of(def_id).subst(tcx, substs); + let ty = tcx.mk_fn_def(def_id, substs); Operand::Constant(Box::new(Constant { span, user_ty: None, From ec8d01fdccbe68d9a2ad6f2c2fbe000a9a6da530 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 13:00:35 +0000 Subject: [PATCH 08/21] Allow iterators instead of requiring slices that will get turned into iterators --- compiler/rustc_borrowck/src/type_check/mod.rs | 12 ++++++------ .../src/transform/check_consts/qualifs.rs | 2 +- compiler/rustc_hir_analysis/src/bounds.rs | 2 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_hir_typeck/src/_match.rs | 7 ++++--- compiler/rustc_hir_typeck/src/coercion.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_infer/src/traits/engine.rs | 2 +- compiler/rustc_middle/src/ty/adjustment.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 14 ++++++++++---- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 6 +++--- compiler/rustc_mir_build/src/build/matches/test.rs | 2 +- compiler/rustc_mir_dataflow/src/elaborate_drops.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 6 +++--- compiler/rustc_monomorphize/src/lib.rs | 2 +- compiler/rustc_trait_selection/src/autoderef.rs | 2 +- .../rustc_trait_selection/src/traits/auto_trait.rs | 4 ++-- .../rustc_trait_selection/src/traits/engine.rs | 2 +- .../src/traits/error_reporting/mod.rs | 3 +-- .../src/traits/error_reporting/suggestions.rs | 10 ++++------ compiler/rustc_trait_selection/src/traits/mod.rs | 4 ++-- .../src/traits/object_safety.rs | 4 ++-- .../rustc_trait_selection/src/traits/project.rs | 4 ++-- .../src/traits/select/candidate_assembly.rs | 2 +- .../src/traits/select/confirmation.rs | 8 ++++---- compiler/rustc_trait_selection/src/traits/util.rs | 6 +++--- compiler/rustc_trait_selection/src/traits/wf.rs | 7 ++----- compiler/rustc_traits/src/chalk/lowering.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/librustdoc/clean/auto_trait.rs | 2 +- .../clippy_lints/src/bool_assert_comparison.rs | 2 +- src/tools/clippy/clippy_lints/src/dereference.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 35 files changed, 69 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index e63c0699d40b7..750d57b9c8c43 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -550,7 +550,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let trait_ref = tcx.mk_trait_ref( tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), place_ty.ty, - &[], + [], ); // To have a `Copy` operand, the type `T` of the @@ -1277,7 +1277,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let trait_ref = tcx.mk_trait_ref( tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), place_ty, - &[], + [], ); self.prove_trait_ref( trait_ref, @@ -1870,7 +1870,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let trait_ref = tcx.mk_trait_ref( tcx.require_lang_item(LangItem::Copy, Some(span)), ty, - &[], + [], ); self.prove_trait_ref( @@ -1887,7 +1887,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let trait_ref = tcx.mk_trait_ref( tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), ty, - &[], + [], ); self.prove_trait_ref( @@ -1903,7 +1903,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let trait_ref = tcx.mk_trait_ref( tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), *ty, - &[], + [], ); self.prove_trait_ref( @@ -2004,7 +2004,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let trait_ref = tcx.mk_trait_ref( tcx.require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)), op.ty(body, tcx), - &[ty.into()], + [ty.into()], ); self.prove_trait_ref( diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 8c43f93a91752..4f1878a3f2586 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -160,7 +160,7 @@ impl Qualif for NeedsNonConstDrop { ObligationCause::dummy(), cx.param_env, ty::Binder::dummy(ty::TraitPredicate { - trait_ref: cx.tcx.mk_trait_ref(destruct, ty, &[]), + trait_ref: cx.tcx.mk_trait_ref(destruct, ty, []), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }), diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 9944114f495b8..17cdbdb70fbe9 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -61,7 +61,7 @@ impl<'tcx> Bounds<'tcx> { // If it could be sized, and is, add the `Sized` predicate. let sized_predicate = self.implicitly_sized.and_then(|span| { tcx.lang_items().sized_trait().map(move |sized| { - 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, [])); (trait_ref.without_const().to_predicate(tcx), span) }) }); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3246397d82f0e..1538d0a1bbb96 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1782,7 +1782,7 @@ fn receiver_is_implemented<'tcx>( receiver_ty: Ty<'tcx>, ) -> bool { 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()); diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 7d081bac3bda6..31432bb6e4170 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -545,9 +545,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::PredicateKind::Projection(mut proj_pred) => { assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty); - proj_pred.projection_ty.substs = self - .tcx - .mk_substs_trait(ty, &proj_pred.projection_ty.substs[1..]); + proj_pred.projection_ty.substs = self.tcx.mk_substs_trait( + ty, + proj_pred.projection_ty.substs.iter().skip(1), + ); ty::PredicateKind::Projection(proj_pred) } _ => continue, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index cf3b37f0a2508..12cbc743bf941 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -807,7 +807,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { self.param_env, ty::Binder::dummy(ty::TraitRef::new( self.tcx.require_lang_item(hir::LangItem::PointerSized, Some(self.cause.span)), - self.tcx.mk_substs_trait(a, &[]), + self.tcx.mk_substs_trait(a, []), )) .to_poly_trait_predicate(), )); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 2c5a88225e90c..fcef6f32e1097 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1095,7 +1095,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.param_env, ty::Binder::dummy(self.tcx.mk_trait_ref( into_def_id, - expr_ty, &[expected_ty.into()] + expr_ty, [expected_ty.into()] )) .to_poly_trait_predicate(), )) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index b55e3a114d330..6b228377ed004 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -71,7 +71,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_ref = tcx.mk_trait_ref( fn_once, ty, - &[self + [self .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span, diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index d26f0cf385147..a25929330f8b8 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -27,7 +27,7 @@ pub trait TraitEngine<'tcx>: 'tcx { def_id: DefId, 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( infcx, Obligation { diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 458cbfa6e35cf..b8e6f0258d019 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -131,7 +131,7 @@ impl<'tcx> OverloadedDeref<'tcx> { .find(|m| m.kind == ty::AssocKind::Fn) .unwrap() .def_id; - tcx.mk_fn_def(method_def_id, tcx.mk_substs_trait(source, &[])) + tcx.mk_fn_def(method_def_id, tcx.mk_substs_trait(source, [])) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index cf0d201cbb724..c43447ae05db4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2809,20 +2809,26 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_place_elems(xs)) } - pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> SubstsRef<'tcx> { - self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned())) + pub fn mk_substs_trait( + self, + self_ty: Ty<'tcx>, + rest: impl IntoIterator>, + ) -> SubstsRef<'tcx> { + self.mk_substs(iter::once(self_ty.into()).chain(rest)) } pub fn mk_trait_ref( self, trait_def_id: DefId, self_ty: Ty<'tcx>, - rest: &[GenericArg<'tcx>], + rest: impl IntoIterator, IntoIter: ExactSizeIterator>, ) -> ty::TraitRef<'tcx> { + let rest = rest.into_iter(); 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?" + "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?", + rest.collect::>(), ); let substs = self.mk_substs_trait(self_ty, rest); ty::TraitRef::new(trait_def_id, substs) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index a792d2694b3b9..586460986dd73 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -551,7 +551,7 @@ impl<'tcx> Instance<'tcx> { let sig = tcx.try_normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig).ok()?; assert_eq!(sig.inputs().len(), 1); - let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); + let substs = tcx.mk_substs_trait(self_ty, [sig.inputs()[0].into()]); debug!(?self_ty, ?sig); Some(Instance { def, substs }) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 47cdabb5f8195..35ab8b2af6b54 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -719,7 +719,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> { self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) } 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) } } @@ -812,7 +812,7 @@ impl<'tcx> TraitRef<'tcx> { } 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[1..]) + tcx.mk_trait_ref(self.def_id, self_ty, self.substs.iter().skip(1)) } /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` @@ -910,7 +910,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); - tcx.mk_trait_ref(self.def_id, self_ty, self.substs) + tcx.mk_trait_ref(self.def_id, self_ty, self.substs.iter()) } } diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index af0d7879c576a..0a6a8859d2f86 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -840,7 +840,7 @@ fn trait_method<'tcx>( self_ty: Ty<'tcx>, params: &[GenericArg<'tcx>], ) -> ConstantKind<'tcx> { - let substs = tcx.mk_substs_trait(self_ty, params); + let substs = tcx.mk_substs_trait(self_ty, params.iter().copied()); // The unhygienic comparison here is acceptable because this is only // used on known traits. diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 14d265a402ef8..ce87a1916b465 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -615,7 +615,7 @@ where let drop_trait = tcx.require_lang_item(LangItem::Drop, None); let drop_fn = tcx.associated_item_def_ids(drop_trait)[0]; let ty = self.place_ty(self.place); - let substs = tcx.mk_substs_trait(ty, &[]); + let substs = tcx.mk_substs_trait(ty, []); let ref_ty = tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index a0ff7550faeb8..68703eb0a232e 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -346,7 +346,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // we must subst the self_ty because it's // otherwise going to be TySelf and we can't index // or access fields of a Place of type TySelf. - let substs = tcx.mk_substs_trait(self_ty, &[]); + let substs = tcx.mk_substs_trait(self_ty, []); let sig = tcx.bound_fn_sig(def_id).subst(tcx, substs); let sig = tcx.erase_late_bound_regions(sig); let span = tcx.def_span(def_id); @@ -427,7 +427,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { ) { let tcx = self.tcx; - let substs = tcx.mk_substs_trait(ty, &[]); + let substs = tcx.mk_substs_trait(ty, []); // `func == Clone::clone(&ty) -> ty` let func_ty = tcx.mk_fn_def(self.def_id, substs); @@ -586,7 +586,7 @@ fn build_call_shim<'tcx>( // Create substitutions for the `Self` and `Args` generic parameters of the shim body. let arg_tup = tcx.mk_tup(untuple_args.iter()); - let sig_substs = tcx.mk_substs_trait(ty, &[ty::subst::GenericArg::from(arg_tup)]); + let sig_substs = tcx.mk_substs_trait(ty, [ty::subst::GenericArg::from(arg_tup)]); (Some(sig_substs), Some(untuple_args)) } else { diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 669599a424ab2..8eb489bb5962b 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -29,7 +29,7 @@ fn custom_coerce_unsize_info<'tcx>( ) -> CustomCoerceUnsized { let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None); - let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(def_id, source_ty, &[target_ty.into()])); + let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(def_id, source_ty, [target_ty.into()])); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index adef967b0a1a1..415bd8de145ac 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -122,7 +122,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { let tcx = self.infcx.tcx; // - 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); diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 3dab34747f7d2..c7dc7b1049c69 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -86,7 +86,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult { 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); @@ -260,7 +260,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new(); 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, // Auto traits are positive diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 97f4f7d795d6f..09c2449bdaeec 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -93,7 +93,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { def_id: DefId, ) { 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 { cause, recursion_depth: 0, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index cb9902bed546b..3d0f87942c33a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -347,8 +347,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { span: DUMMY_SP, 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.into()]); let obligation = Obligation::new( self.tcx, ObligationCause::dummy(), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 445b5696d20b3..4b6d8177381a9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2985,7 +2985,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.tcx.mk_projection( item_def_id, // Future::Output has no substs - self.tcx.mk_substs_trait(trait_pred.self_ty(), &[]), + self.tcx.mk_substs_trait(trait_pred.self_ty(), []), ) }); let projection_ty = normalize_to( @@ -3068,13 +3068,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Ensure all fields impl the trait. adt.all_fields().all(|field| { let field_ty = field.ty(self.tcx, substs); - let trait_substs; - let trait_substs: &[_] = match diagnostic_name { + let trait_substs = match diagnostic_name { sym::PartialEq | sym::PartialOrd => { - trait_substs = [field_ty.into()]; - &trait_substs + Some(field_ty.into()) } - _ => &[], + _ => None, }; let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate { trait_ref: self.tcx.mk_trait_ref( diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 227a7f0a1124a..7eb21e156fd2e 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -143,7 +143,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( def_id: DefId, span: Span, ) -> 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) } @@ -902,7 +902,7 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( // this has been typecked-before, so diagnostics is not really needed. 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.into()]); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) { Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 20826f2c54141..29b315bff16d9 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -688,7 +688,7 @@ fn receiver_is_dispatchable<'tcx>( let unsize_predicate = ty::Binder::dummy(tcx.mk_trait_ref( unsize_did, tcx.types.self_param, - &[unsized_self_ty.into()], + [unsized_self_ty.into()], )) .without_const() .to_predicate(tcx); @@ -724,7 +724,7 @@ fn receiver_is_dispatchable<'tcx>( let predicate = ty::Binder::dummy(tcx.mk_trait_ref( dispatch_from_dyn_did, receiver_ty, - &[unsized_receiver_ty.into()], + [unsized_receiver_ty.into()], )) .without_const(); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e1b30112e39b5..b8fe4c8640542 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1712,7 +1712,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( selcx.tcx(), ty::Binder::dummy(selcx.tcx().mk_trait_ref( selcx.tcx().require_lang_item(LangItem::Sized, None), - self_ty, &[], + self_ty, [], )) .without_const(), ), @@ -1969,7 +1969,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>( let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref( tcx.require_lang_item(LangItem::Sized, None), self_ty, - &[], + [], )) .without_const(); obligations.push(obligation.with(tcx, sized_predicate)); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 6b19b9297c515..b11f2c8e6a467 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -714,7 +714,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } // - 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( tcx, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 6d737b455bf20..5c3a132bb5ceb 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -635,7 +635,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tr = ty::Binder::dummy(self.tcx().mk_trait_ref( self.tcx().require_lang_item(LangItem::Sized, None), output_ty, - &[], + [], )); nested.push(Obligation::new( self.infcx.tcx, @@ -1000,7 +1000,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tr = ty::Binder::dummy(tcx.mk_trait_ref( tcx.require_lang_item(LangItem::Sized, None), source, - &[], + [], )); nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); @@ -1258,7 +1258,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { trait_ref: self.tcx().mk_trait_ref( self.tcx().require_lang_item(LangItem::Destruct, None), nested_ty, - &[], + [], ), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, @@ -1283,7 +1283,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { trait_ref: self.tcx().mk_trait_ref( self.tcx().require_lang_item(LangItem::Destruct, None), nested_ty, - &[], + [], ), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 21c79461edaf3..41798e00caaa7 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -241,7 +241,7 @@ pub fn predicate_for_trait_def<'tcx>( self_ty: Ty<'tcx>, params: &[GenericArg<'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, self_ty, params.iter().copied()); predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth) } @@ -304,7 +304,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>( TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), }; 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.into()]); sig.map_bound(|sig| (trait_ref, sig.output())) } @@ -316,7 +316,7 @@ pub fn generator_trait_ref_and_outputs<'tcx>( ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = - tcx.mk_trait_ref(fn_trait_def_id, self_ty, &[sig.skip_binder().resume_ty.into()]); + 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)) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 3fe019cb7de69..378e673879522 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -421,11 +421,8 @@ impl<'tcx> WfPredicates<'tcx> { fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { if !subty.has_escaping_bound_vars() { let cause = self.cause(cause); - let trait_ref = self.tcx.mk_trait_ref( - self.tcx.require_lang_item(LangItem::Sized, None), - subty, - &[], - ); + let trait_ref = + self.tcx.mk_trait_ref(self.tcx.require_lang_item(LangItem::Sized, None), subty, []); self.out.push(traits::Obligation::with_depth( self.tcx, cause, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 36bd466496e12..06a42a95d6061 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -689,7 +689,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders( // it on the impl. 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() .to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 03ac2f14f7a6b..bd55517311d7e 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -44,7 +44,7 @@ where discard_positive_impl: bool, ) -> Option { 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)) { debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref); return None; diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index 4bd55c1429c3b..82d368bb8bc2c 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -59,7 +59,7 @@ fn is_impl_not_trait_with_bool_out(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { ) }) .map_or(false, |assoc_item| { - let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, &[])); + let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, [])); let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj); nty.is_bool() diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 218dbeaddcade..03d865af374a2 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -1263,7 +1263,7 @@ fn replace_types<'tcx>( let item_def_id = projection_predicate.projection_ty.item_def_id; let assoc_item = cx.tcx.associated_item(item_def_id); let projection = cx.tcx - .mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(new_ty, &[])); + .mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(new_ty, [])); if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection) && substs[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 3a144c2bb2239..a1698a61e6014 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -79,7 +79,7 @@ pub fn get_associated_type<'tcx>( .associated_items(trait_id) .find_by_name_and_kind(cx.tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id) .and_then(|assoc| { - let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, &[])); + let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, [])); cx.tcx.try_normalize_erasing_regions(cx.param_env, proj).ok() }) } From 9e4c3f41c105a93178a6962bfc2e416f520134a9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 13:06:37 +0000 Subject: [PATCH 09/21] Use iterators instead of slices at more sites --- compiler/rustc_hir_analysis/src/coherence/builtin.rs | 4 ++-- compiler/rustc_hir_typeck/src/coercion.rs | 2 +- compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 2 +- compiler/rustc_trait_selection/src/lib.rs | 1 + .../rustc_trait_selection/src/traits/select/confirmation.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- compiler/rustc_trait_selection/src/traits/util.rs | 4 ++-- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 6f74ef3ccad6d..558c9789cf099 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -316,7 +316,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did: dispatch_from_dyn_trait, 0, field.ty(tcx, substs_a), - &[field.ty(tcx, substs_b).into()], + [field.ty(tcx, substs_b).into()], ) }), ); @@ -558,7 +558,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn // Register an obligation for `A: Trait`. let cause = traits::ObligationCause::misc(span, impl_hir_id); 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.into()]); let errors = traits::fully_solve_obligation(&infcx, predicate); if !errors.is_empty() { infcx.err_ctxt().report_fulfillment_errors(&errors, None); diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 12cbc743bf941..30cc7de07ac71 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -631,7 +631,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { coerce_unsized_did, 0, coerce_source, - &[coerce_target.into()] + [coerce_target.into()] )]; let mut has_unsized_tuple_coercion = false; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 80c250f044d97..1ed954bdd46aa 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -241,7 +241,7 @@ impl<'tcx> ConstToPat<'tcx> { partial_eq_trait_id, 0, ty, - &[any_ty], + [any_ty], ); // FIXME: should this call a `predicate_must_hold` variant instead? diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 2dce18e2d3cad..975ff31a60788 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -11,6 +11,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(drain_filter)] diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 5c3a132bb5ceb..32683eb9822dd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1108,7 +1108,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.predicate.def_id(), obligation.recursion_depth + 1, source_tail, - &[target_tail.into()], + [target_tail.into()], )); } @@ -1139,7 +1139,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.predicate.def_id(), obligation.recursion_depth + 1, a_last, - &[b_last.into()], + [b_last.into()], ) })); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a9314b1b85e66..06e507eb72912 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2101,7 +2101,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { trait_def_id, recursion_depth, normalized_ty, - &[], + [], ); obligations.push(placeholder_obligation); obligations diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 41798e00caaa7..87c534bad96a9 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -239,9 +239,9 @@ pub fn predicate_for_trait_def<'tcx>( trait_def_id: DefId, recursion_depth: usize, self_ty: Ty<'tcx>, - params: &[GenericArg<'tcx>], + params: impl IntoIterator, IntoIter: ExactSizeIterator>, ) -> PredicateObligation<'tcx> { - let trait_ref = tcx.mk_trait_ref(trait_def_id, self_ty, params.iter().copied()); + let trait_ref = tcx.mk_trait_ref(trait_def_id, self_ty, params); predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth) } From 25c4760b5db54d55f9512d69edbb214cbca20372 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 13:28:32 +0000 Subject: [PATCH 10/21] Some cleanup around trait_method lookup --- compiler/rustc_mir_build/src/build/matches/test.rs | 13 ++++++------- compiler/rustc_mir_build/src/lib.rs | 1 + 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 0a6a8859d2f86..8ff7296c7b662 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let ref_str_ty = tcx.mk_imm_ref(re_erased, tcx.types.str_); let ref_str = self.temp(ref_str_ty, test.span); let deref = tcx.require_lang_item(LangItem::Deref, None); - let method = trait_method(tcx, deref, sym::deref, ty, &[]); + let method = trait_method(tcx, deref, sym::deref, ty, []); let eq_block = self.cfg.start_new_block(); self.cfg.push_assign(block, source_info, ref_string, Rvalue::Ref(re_erased, BorrowKind::Shared, place)); self.cfg.terminate( @@ -444,8 +444,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { bug!("non_scalar_compare called on non-reference type: {}", ty); }; - let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, None); - let method = trait_method(self.tcx, eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]); + let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); + let method = trait_method(self.tcx, eq_def_id, sym::eq, deref_ty, [deref_ty.into()]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); @@ -838,9 +838,9 @@ fn trait_method<'tcx>( trait_def_id: DefId, method_name: Symbol, self_ty: Ty<'tcx>, - params: &[GenericArg<'tcx>], + params: impl IntoIterator, IntoIter: ExactSizeIterator>, ) -> ConstantKind<'tcx> { - let substs = tcx.mk_substs_trait(self_ty, params.iter().copied()); + let substs = tcx.mk_substs_trait(self_ty, params); // The unhygienic comparison here is acceptable because this is only // used on known traits. @@ -850,8 +850,7 @@ fn trait_method<'tcx>( .find(|item| item.kind == ty::AssocKind::Fn) .expect("trait method not found"); - let method_ty = tcx.bound_type_of(item.def_id); - let method_ty = method_ty.subst(tcx, substs); + let method_ty = tcx.mk_fn_def(item.def_id, substs); ConstantKind::zero_sized(method_ty) } diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index b53bd3d0710a6..8797529459534 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -3,6 +3,7 @@ //! This crate also contains the match exhaustiveness and usefulness checking. #![allow(rustc::potential_query_instability)] #![feature(assert_matches)] +#![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(if_let_guard)] From ad57f88d3f48afe26940b4cc78b10adcf416ab3f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 14:39:19 +0000 Subject: [PATCH 11/21] Add helper to create the trait ref for a lang item --- compiler/rustc_borrowck/src/type_check/mod.rs | 37 +++++-------------- .../src/transform/check_consts/qualifs.rs | 6 +-- compiler/rustc_hir_analysis/src/bounds.rs | 8 ++-- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 10 +++++ compiler/rustc_monomorphize/src/collector.rs | 11 +++--- compiler/rustc_monomorphize/src/lib.rs | 11 +++--- .../src/traits/project.rs | 10 ++--- .../src/traits/select/confirmation.rs | 19 ++++------ .../rustc_trait_selection/src/traits/wf.rs | 3 +- 10 files changed, 51 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 750d57b9c8c43..5bf371290ba95 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -547,11 +547,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { let tcx = self.tcx(); - let trait_ref = tcx.mk_trait_ref( - tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), - 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 // value must be `Copy`. Note that we prove that `T: Copy`, @@ -1274,11 +1270,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_rvalue(body, rv, location); if !self.unsized_feature_enabled() { - let trait_ref = tcx.mk_trait_ref( - tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - place_ty, - [], - ); + let trait_ref = + tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, place_ty, []); self.prove_trait_ref( trait_ref, location.to_locations(), @@ -1842,6 +1835,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { #[instrument(skip(self, body), level = "debug")] fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { let tcx = self.tcx(); + let span = body.source_info(location).span; match rvalue { Rvalue::Aggregate(ak, ops) => { @@ -1865,13 +1859,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } Operand::Move(place) => { // Make sure that repeated elements implement `Copy`. - let span = body.source_info(location).span; let ty = place.ty(body, tcx).ty; - let trait_ref = tcx.mk_trait_ref( - tcx.require_lang_item(LangItem::Copy, Some(span)), - ty, - [], - ); + let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, ty, []); self.prove_trait_ref( trait_ref, @@ -1884,11 +1873,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { - let trait_ref = tcx.mk_trait_ref( - tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - ty, - [], - ); + let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, ty, []); self.prove_trait_ref( trait_ref, @@ -1900,11 +1885,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::ShallowInitBox(operand, ty) => { self.check_operand(operand, location); - let trait_ref = tcx.mk_trait_ref( - tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - *ty, - [], - ); + let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, *ty, []); self.prove_trait_ref( trait_ref, @@ -2001,8 +1982,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { CastKind::Pointer(PointerCast::Unsize) => { let &ty = ty; - let trait_ref = tcx.mk_trait_ref( - tcx.require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)), + let trait_ref = tcx.at(span).mk_trait_ref( + LangItem::CoerceUnsized, op.ty(body, tcx), [ty.into()], ); diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 4f1878a3f2586..6dcada67ca40b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -153,14 +153,12 @@ impl Qualif for NeedsNonConstDrop { return false; } - let destruct = cx.tcx.require_lang_item(LangItem::Destruct, None); - let obligation = Obligation::new( cx.tcx, - ObligationCause::dummy(), + ObligationCause::dummy_with_span(cx.body.span), cx.param_env, ty::Binder::dummy(ty::TraitPredicate { - trait_ref: cx.tcx.mk_trait_ref(destruct, ty, []), + trait_ref: cx.tcx.at(cx.body.span).mk_trait_ref(LangItem::Destruct, ty, []), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }), diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 17cdbdb70fbe9..0f9311f4b7eff 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -60,10 +60,10 @@ impl<'tcx> Bounds<'tcx> { { // If it could be sized, and is, add the `Sized` predicate. let sized_predicate = self.implicitly_sized.and_then(|span| { - tcx.lang_items().sized_trait().map(move |sized| { - let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, param_ty, [])); - (trait_ref.without_const().to_predicate(tcx), span) - }) + // 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 trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, param_ty, [])); + Some((trait_ref.without_const().to_predicate(tcx), span)) }); let region_preds = self.region_bounds.iter().map(move |&(region_bound, span)| { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 1538d0a1bbb96..724e6261365dc 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1722,7 +1722,7 @@ fn receiver_is_valid<'tcx>( // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it. autoderef.next(); - let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, None); + let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span)); // Keep dereferencing `receiver_ty` until we get to `self_ty`. loop { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c43447ae05db4..73e07dcd592dd 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2990,6 +2990,16 @@ impl<'tcx> TyCtxtAt<'tcx> { pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> { self.tcx.ty_error_with_message(self.span, msg) } + + pub fn mk_trait_ref( + self, + trait_lang_item: LangItem, + self_ty: Ty<'tcx>, + rest: impl IntoIterator, IntoIter: ExactSizeIterator>, + ) -> ty::TraitRef<'tcx> { + 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) + } } /// Parameter attributes that can only be determined by examining the body of a function instead diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index d74893bf0f0e3..559ce227454de 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -187,6 +187,7 @@ use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Local, Location}; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{ self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitable, VtblEntry, @@ -688,7 +689,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { let source_ty = operand.ty(self.body, self.tcx); let source_ty = self.monomorphize(source_ty); let (source_ty, target_ty) = - find_vtable_types_for_unsizing(self.tcx, source_ty, target_ty); + find_vtable_types_for_unsizing(self.tcx.at(span), source_ty, target_ty); // This could also be a different Unsize instruction, like // from a fixed sized array to a slice. But we are only // interested in things that produce a vtable. @@ -1053,14 +1054,14 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> /// Finally, there is also the case of custom unsizing coercions, e.g., for /// smart pointers such as `Rc` and `Arc`. fn find_vtable_types_for_unsizing<'tcx>( - tcx: TyCtxt<'tcx>, + tcx: TyCtxtAt<'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> (Ty<'tcx>, Ty<'tcx>) { let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { let param_env = ty::ParamEnv::reveal_all(); let type_has_metadata = |ty: Ty<'tcx>| -> bool { - if ty.is_sized(tcx, param_env) { + if ty.is_sized(tcx.tcx, param_env) { return false; } let tail = tcx.struct_tail_erasing_lifetimes(ty, param_env); @@ -1104,8 +1105,8 @@ fn find_vtable_types_for_unsizing<'tcx>( find_vtable_types_for_unsizing( tcx, - source_fields[coerce_index].ty(tcx, source_substs), - target_fields[coerce_index].ty(tcx, target_substs), + source_fields[coerce_index].ty(*tcx, source_substs), + target_fields[coerce_index].ty(*tcx, target_substs), ) } _ => bug!( diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 8eb489bb5962b..616620edc09fb 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -13,8 +13,8 @@ extern crate rustc_middle; use rustc_hir::lang_items::LangItem; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; -use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::query::{Providers, TyCtxtAt}; +use rustc_middle::ty::{self, Ty}; mod collector; mod errors; @@ -23,13 +23,12 @@ mod polymorphize; mod util; fn custom_coerce_unsize_info<'tcx>( - tcx: TyCtxt<'tcx>, + tcx: TyCtxtAt<'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> CustomCoerceUnsized { - let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None); - - let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(def_id, source_ty, [target_ty.into()])); + let trait_ref = + ty::Binder::dummy(tcx.mk_trait_ref(LangItem::CoerceUnsized, source_ty, [target_ty.into()])); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index b8fe4c8640542..4b1e8f18e34b1 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1710,8 +1710,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( if selcx.infcx().predicate_must_hold_modulo_regions( &obligation.with( selcx.tcx(), - ty::Binder::dummy(selcx.tcx().mk_trait_ref( - selcx.tcx().require_lang_item(LangItem::Sized, None), + ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref( + LangItem::Sized, self_ty, [], )) .without_const(), @@ -1966,8 +1966,8 @@ fn confirm_pointee_candidate<'cx, 'tcx>( ) }); if check_is_sized { - let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref( - tcx.require_lang_item(LangItem::Sized, None), + let sized_predicate = ty::Binder::dummy(tcx.at(obligation.cause.span).mk_trait_ref( + LangItem::Sized, self_ty, [], )) @@ -1976,7 +1976,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>( } let substs = tcx.mk_substs([self_ty.into()].iter()); - let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); + let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, Some(obligation.cause.span)); let predicate = ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id }, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 32683eb9822dd..19d69e9dfaa05 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -632,8 +632,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { output_ty, &mut nested, ); - let tr = ty::Binder::dummy(self.tcx().mk_trait_ref( - self.tcx().require_lang_item(LangItem::Sized, None), + let tr = ty::Binder::dummy(self.tcx().at(cause.span).mk_trait_ref( + LangItem::Sized, output_ty, [], )); @@ -997,11 +997,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); // We can only make objects from sized types. - let tr = ty::Binder::dummy(tcx.mk_trait_ref( - tcx.require_lang_item(LangItem::Sized, None), - source, - [], - )); + let tr = + ty::Binder::dummy(tcx.at(cause.span).mk_trait_ref(LangItem::Sized, source, [])); nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); // If the type is `Foo + 'a`, ensure that the type @@ -1255,8 +1252,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause.clone(), obligation.recursion_depth + 1, self_ty.rebind(ty::TraitPredicate { - trait_ref: self.tcx().mk_trait_ref( - self.tcx().require_lang_item(LangItem::Destruct, None), + trait_ref: self.tcx().at(cause.span).mk_trait_ref( + LangItem::Destruct, nested_ty, [], ), @@ -1280,8 +1277,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // or it's an ADT (and we need to check for a custom impl during selection) _ => { let predicate = self_ty.rebind(ty::TraitPredicate { - trait_ref: self.tcx().mk_trait_ref( - self.tcx().require_lang_item(LangItem::Destruct, None), + trait_ref: self.tcx().at(cause.span).mk_trait_ref( + LangItem::Destruct, nested_ty, [], ), diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 378e673879522..de72c6618d4f5 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -421,8 +421,7 @@ impl<'tcx> WfPredicates<'tcx> { fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { if !subty.has_escaping_bound_vars() { let cause = self.cause(cause); - let trait_ref = - self.tcx.mk_trait_ref(self.tcx.require_lang_item(LangItem::Sized, None), subty, []); + let trait_ref = self.tcx.at(cause.span).mk_trait_ref(LangItem::Sized, subty, []); self.out.push(traits::Obligation::with_depth( self.tcx, cause, From a9f3c2209c6ac4ff36df1816b842d0a1c1540624 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 15:23:07 +0000 Subject: [PATCH 12/21] For lcnr --- compiler/rustc_trait_selection/src/traits/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 7eb21e156fd2e..eb5cd9a2d06a4 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -174,6 +174,7 @@ fn pred_known_to_hold_modulo_regions<'tcx>( // this function's result remains infallible, we must confirm // that guess. While imperfect, I believe this is sound. + // FIXME(@lcnr): this function doesn't seem right. // The handling of regions in this area of the code is terrible, // see issue #29149. We should be able to improve on this with // NLL. From 4d9451b1d1e334e90e6725d5577545eae4e28545 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 15:30:42 +0000 Subject: [PATCH 13/21] Fix an ICE that I just made worse --- .../src/thir/pattern/const_to_pat.rs | 10 +--------- .../const-partial_eq-fallback-ice.rs | 20 +++++++++++++++++++ .../const-partial_eq-fallback-ice.stderr | 8 ++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs create mode 100644 src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 1ed954bdd46aa..4364fca9739c7 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,7 +1,6 @@ use rustc_errors::DelayDm; use rustc_hir as hir; use rustc_index::vec::Idx; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::mir::{self, Field}; use rustc_middle::thir::{FieldPat, Pat, PatKind}; @@ -227,13 +226,6 @@ impl<'tcx> ConstToPat<'tcx> { // using `PartialEq::eq` in this scenario in the past.) let partial_eq_trait_id = 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( self.tcx(), self.param_env, @@ -241,7 +233,7 @@ impl<'tcx> ConstToPat<'tcx> { partial_eq_trait_id, 0, ty, - [any_ty], + [ty.into()], ); // FIXME: should this call a `predicate_must_hold` variant instead? diff --git a/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs new file mode 100644 index 0000000000000..daa432d9ae5d1 --- /dev/null +++ b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs @@ -0,0 +1,20 @@ +#![allow(warnings)] + +struct MyType; + +impl PartialEq for MyType { + fn eq(&self, y: &usize) -> bool { + true + } +} + +const CONSTANT: &&MyType = &&MyType; + +fn main() { + if let CONSTANT = &&MyType { + //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + println!("semantic!"); + } else { + println!("structural!"); + } +} diff --git a/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr new file mode 100644 index 0000000000000..358421cd6d24c --- /dev/null +++ b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr @@ -0,0 +1,8 @@ +error: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/const-partial_eq-fallback-ice.rs:14:12 + | +LL | if let CONSTANT = &&MyType { + | ^^^^^^^^ + +error: aborting due to previous error + From 48ea298abfbab541c34c95481a0466ab91b08e55 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 15:39:11 +0000 Subject: [PATCH 14/21] Remove a redundant assert --- compiler/rustc_trait_selection/src/infer.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 5be49996a0b2d..af17c86e1a5f1 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -119,12 +119,6 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { ) -> traits::EvaluationResult { let trait_ref = self.tcx.mk_trait_ref(trait_def_id, self_ty, params); - debug_assert_eq!( - self.tcx.generics_of(trait_def_id).count() - 1, - params.len(), - "wrong number of generic parameters for {trait_def_id:?}, did you accidentally include the self-type in the params list?" - ); - let obligation = traits::Obligation { cause: traits::ObligationCause::dummy(), param_env, From 472444bc64db894b414db5b6ead5e8ff4c1774b0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Nov 2022 16:05:41 +0000 Subject: [PATCH 15/21] Remove some unnecessary slicing --- compiler/rustc_middle/src/ty/context.rs | 14 +++++++------- compiler/rustc_type_ir/src/lib.rs | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 73e07dcd592dd..0ee190302ac91 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2516,7 +2516,7 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Tuple(self.intern_type_list(&ts))) } - pub fn mk_tup], Ty<'tcx>>>(self, iter: I) -> I::Output { + pub fn mk_tup, Ty<'tcx>>>(self, iter: I) -> I::Output { iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(&ts)))) } @@ -2776,7 +2776,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn mk_poly_existential_predicates< - I: InternAs<[PolyExistentialPredicate<'tcx>], &'tcx List>>, + I: InternAs, &'tcx List>>, >( self, iter: I, @@ -2784,25 +2784,25 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_poly_existential_predicates(xs)) } - pub fn mk_predicates], &'tcx List>>>( + pub fn mk_predicates, &'tcx List>>>( self, iter: I, ) -> I::Output { iter.intern_with(|xs| self.intern_predicates(xs)) } - pub fn mk_type_list], &'tcx List>>>(self, iter: I) -> I::Output { + pub fn mk_type_list, &'tcx List>>>(self, iter: I) -> I::Output { iter.intern_with(|xs| self.intern_type_list(xs)) } - pub fn mk_substs], &'tcx List>>>( + pub fn mk_substs, &'tcx List>>>( self, iter: I, ) -> I::Output { iter.intern_with(|xs| self.intern_substs(xs)) } - pub fn mk_place_elems], &'tcx List>>>( + pub fn mk_place_elems, &'tcx List>>>( self, iter: I, ) -> I::Output { @@ -2835,7 +2835,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn mk_bound_variable_kinds< - I: InternAs<[ty::BoundVariableKind], &'tcx List>, + I: InternAs>, >( self, iter: I, diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 7c3eb4efbc984..581993ba7d863 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -60,10 +60,10 @@ pub trait InternAs { type Output; fn intern_with(self, f: F) -> Self::Output where - F: FnOnce(&T) -> R; + F: FnOnce(&[T]) -> R; } -impl InternAs<[T], R> for I +impl InternAs for I where E: InternIteratorElement, I: Iterator, From a4da3f8863852b49195a83758693942e338cb05e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 18 Nov 2022 19:58:07 +0000 Subject: [PATCH 16/21] Fix clippy's missing substs --- src/tools/clippy/clippy_lints/src/derive.rs | 4 ++-- src/tools/clippy/clippy_lints/src/eta_reduction.rs | 4 +++- .../src/methods/unnecessary_to_owned.rs | 4 ++-- .../clippy_lints/src/needless_pass_by_value.rs | 4 ++-- .../clippy_lints/src/neg_cmp_op_on_partial_ord.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 14 +++++++++----- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 102a02138bc87..1d9af7cdbd358 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -466,12 +466,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r if let Some(def_id) = trait_ref.trait_def_id(); if cx.tcx.is_diagnostic_item(sym::PartialEq, def_id); let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id); - if !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[]); + if !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, []); // If all of our fields implement `Eq`, we can implement `Eq` too if adt .all_fields() .map(|f| f.ty(cx.tcx, substs)) - .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[])); + .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, [])); then { span_lint_and_sugg( cx, diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 7b9786d7e570f..ea4e5e052d029 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -119,11 +119,13 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs(); if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc); if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc); + if let ty::Closure(_, substs) = *closure_ty.kind(); then { span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { if let Some(mut snippet) = snippet_opt(cx, callee.span) { if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait() - && implements_trait(cx, callee_ty.peel_refs(), fn_mut_id, &[]) + && let args = cx.tcx.erase_late_bound_regions(ty::ClosureSubsts { substs }.sig()).inputs() + && implements_trait(cx, callee_ty.peel_refs(), fn_mut_id, &args.iter().copied().map(Into::into).collect::>()) && path_to_local(callee).map_or(false, |l| local_used_after_expr(cx, l, expr)) { // Mutable closure is used after current expr; we cannot consume it. diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index c7775313ecd02..375ebc903b400 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -474,7 +474,7 @@ fn is_cow_into_owned(cx: &LateContext<'_>, method_name: Symbol, method_def_id: D } /// Returns true if the named method is `ToString::to_string` and it's called on a type that -/// is string-like i.e. implements `AsRef` or `Deref`. +/// is string-like i.e. implements `AsRef` or `Deref`. fn is_to_string_on_string_like<'a>( cx: &LateContext<'_>, call_expr: &'a Expr<'a>, @@ -490,7 +490,7 @@ fn is_to_string_on_string_like<'a>( && let GenericArgKind::Type(ty) = generic_arg.unpack() && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) - && (implements_trait(cx, ty, deref_trait_id, &[cx.tcx.types.str_.into()]) || + && (get_associated_type(cx, ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) || implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) { true } else { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 79aa15b06ef4d..eeff15bbfb422 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; use clippy_utils::ptr::get_spans; use clippy_utils::source::{snippet, snippet_opt}; -use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item}; +use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy, is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::{get_trait_def_id, is_self, paths}; use if_chain::if_chain; use rustc_ast::ast::Attribute; @@ -185,7 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { if !ty.is_mutable_ptr(); if !is_copy(cx, ty); if ty.is_sized(cx.tcx, cx.param_env); - if !allowed_traits.iter().any(|&t| implements_trait(cx, ty, t, &[])); + if !allowed_traits.iter().any(|&t| implements_trait_with_env(cx.tcx, cx.param_env, ty, t, [None])); if !implements_borrow_trait; if !all_borrowable_trait; diff --git a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs index 5c2b96f5b2ce6..a022fc156fca2 100644 --- a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs +++ b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs @@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd { let implements_partial_ord = { if let Some(id) = cx.tcx.lang_items().partial_ord_trait() { - implements_trait(cx, ty, id, &[]) + implements_trait(cx, ty, id, &[ty.into()]) } else { return; } diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index a1698a61e6014..a8047fe9e5ea1 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety}; -use rustc_infer::infer::TyCtxtInferExt; +use rustc_infer::infer::{TyCtxtInferExt, type_variable::{TypeVariableOrigin, TypeVariableOriginKind}}; use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::{ @@ -18,7 +18,7 @@ use rustc_middle::ty::{ }; use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::symbol::Ident; -use rustc_span::{sym, Span, Symbol}; +use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_target::abi::{Size, VariantIdx}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::query::normalize::AtExt; @@ -153,7 +153,7 @@ pub fn implements_trait<'tcx>( trait_id: DefId, ty_params: &[GenericArg<'tcx>], ) -> bool { - implements_trait_with_env(cx.tcx, cx.param_env, ty, trait_id, ty_params) + implements_trait_with_env(cx.tcx, cx.param_env, ty, trait_id, ty_params.iter().map(|&arg| Some(arg))) } /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context. @@ -162,7 +162,7 @@ pub fn implements_trait_with_env<'tcx>( param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, trait_id: DefId, - ty_params: &[GenericArg<'tcx>], + ty_params: impl IntoIterator>>, ) -> bool { // Clippy shouldn't have infer types assert!(!ty.needs_infer()); @@ -171,8 +171,12 @@ pub fn implements_trait_with_env<'tcx>( if ty.has_escaping_bound_vars() { return false; } - let ty_params = tcx.mk_substs(ty_params.iter()); let infcx = tcx.infer_ctxt().build(); + let orig = TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span: DUMMY_SP, + }; + let ty_params = tcx.mk_substs(ty_params.into_iter().map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into()))); infcx .type_implements_trait(trait_id, ty, ty_params, param_env) .must_apply_modulo_regions() From 7658e0fccf5e01c3950b2f9d7b1fc30a236efcdc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 21 Nov 2022 12:24:53 +0000 Subject: [PATCH 17/21] Stop passing the self-type as a separate argument. --- .../src/diagnostics/conflict_errors.rs | 10 ++---- compiler/rustc_borrowck/src/type_check/mod.rs | 18 +++++----- .../src/transform/check_consts/qualifs.rs | 2 +- compiler/rustc_hir_analysis/src/bounds.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/coherence/builtin.rs | 5 ++- compiler/rustc_hir_typeck/src/cast.rs | 3 +- compiler/rustc_hir_typeck/src/coercion.rs | 6 ++-- compiler/rustc_hir_typeck/src/expr.rs | 3 +- .../src/fn_ctxt/suggestions.rs | 2 +- .../src/method/prelude2021.rs | 4 +-- .../rustc_hir_typeck/src/method/suggest.rs | 10 +++--- compiler/rustc_hir_typeck/src/upvar.rs | 21 ++---------- compiler/rustc_infer/src/traits/engine.rs | 2 +- compiler/rustc_lint/src/non_fmt_panic.rs | 16 +++++---- compiler/rustc_middle/src/ty/context.rs | 21 ++++++------ compiler/rustc_middle/src/ty/sty.rs | 9 +++-- .../src/thir/pattern/const_to_pat.rs | 3 +- compiler/rustc_monomorphize/src/lib.rs | 2 +- .../rustc_trait_selection/src/autoderef.rs | 2 +- compiler/rustc_trait_selection/src/infer.rs | 16 ++++----- .../src/traits/auto_trait.rs | 4 +-- .../src/traits/engine.rs | 2 +- .../src/traits/error_reporting/mod.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 8 ++--- .../rustc_trait_selection/src/traits/mod.rs | 4 +-- .../src/traits/object_safety.rs | 16 ++++----- .../src/traits/project.rs | 10 +++--- .../src/traits/select/candidate_assembly.rs | 2 +- .../src/traits/select/confirmation.rs | 33 ++++++++----------- .../src/traits/select/mod.rs | 3 +- .../rustc_trait_selection/src/traits/util.rs | 10 +++--- .../rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/librustdoc/clean/auto_trait.rs | 2 +- .../clippy/clippy_lints/src/dereference.rs | 12 +++---- src/tools/clippy/clippy_lints/src/ptr.rs | 4 +-- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 38 files changed, 113 insertions(+), 164 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 9e0aa57b2553f..8f1ae594a9247 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -489,12 +489,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // but the type has region variables, so erase those. tcx.infer_ctxt() .build() - .type_implements_trait( - default_trait, - tcx.erase_regions(ty), - ty::List::empty(), - param_env, - ) + .type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env) .must_apply_modulo_regions() }; @@ -1707,7 +1702,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_label(borrow_span, note); let tcx = self.infcx.tcx; - let ty_params = ty::List::empty(); let return_ty = self.regioncx.universal_regions().unnormalized_output_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) && self .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() { err.span_suggestion_hidden( diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 5bf371290ba95..7467212bed883 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -547,7 +547,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { 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 // 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); if !self.unsized_feature_enabled() { 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( trait_ref, location.to_locations(), @@ -1860,7 +1860,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Operand::Move(place) => { // Make sure that repeated elements implement `Copy`. 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( trait_ref, @@ -1873,7 +1873,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } &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( trait_ref, @@ -1885,7 +1885,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::ShallowInitBox(operand, ty) => { 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( trait_ref, @@ -1982,11 +1982,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { CastKind::Pointer(PointerCast::Unsize) => { let &ty = ty; - let trait_ref = tcx.at(span).mk_trait_ref( - LangItem::CoerceUnsized, - op.ty(body, tcx), - [ty.into()], - ); + let trait_ref = tcx + .at(span) + .mk_trait_ref(LangItem::CoerceUnsized, [op.ty(body, tcx), ty]); self.prove_trait_ref( trait_ref, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 6dcada67ca40b..e7b3df9b7288b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -158,7 +158,7 @@ impl Qualif for NeedsNonConstDrop { ObligationCause::dummy_with_span(cx.body.span), cx.param_env, 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, polarity: ty::ImplPolarity::Positive, }), diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 0f9311f4b7eff..3e3544ce666e3 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -62,7 +62,7 @@ impl<'tcx> Bounds<'tcx> { 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. 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)) }); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 724e6261365dc..7119f3a238697 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1782,7 +1782,7 @@ fn receiver_is_implemented<'tcx>( receiver_ty: Ty<'tcx>, ) -> bool { 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()); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 558c9789cf099..b2c9e7389b047 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -315,8 +315,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did: cause.clone(), dispatch_from_dyn_trait, 0, - field.ty(tcx, substs_a), - [field.ty(tcx, substs_b).into()], + [field.ty(tcx, substs_a), field.ty(tcx, substs_b)], ) }), ); @@ -558,7 +557,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn // Register an obligation for `A: Trait`. let cause = traits::ObligationCause::misc(span, impl_hir_id); 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); if !errors.is_empty() { infcx.err_ctxt().report_fulfillment_errors(&errors, None); diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 50fd4fd2a8f89..5e1e44dcb6d15 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -498,10 +498,9 @@ impl<'a, 'tcx> CastCheck<'tcx> { let ty = fcx.tcx.erase_regions(ty); let expr_ty = fcx.resolve_vars_if_possible(self.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 .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() { label = false; diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 30cc7de07ac71..5062926106942 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -630,8 +630,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { cause, coerce_unsized_did, 0, - coerce_source, - [coerce_target.into()] + [coerce_source, coerce_target] )]; let mut has_unsized_tuple_coercion = false; @@ -1086,8 +1085,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.infcx .type_implements_trait( self.tcx.lang_items().deref_mut_trait()?, - expr_ty, - ty::List::empty(), + [expr_ty], self.param_env, ) .may_apply() diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 2764de751b08b..de30bfe6923a7 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1119,8 +1119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .infcx .type_implements_trait( self.tcx.lang_items().sized_trait().unwrap(), - lhs_deref_ty, - ty::List::empty(), + [lhs_deref_ty], self.param_env, ) .may_apply(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index fcef6f32e1097..b5aa8cd6e7c5b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1095,7 +1095,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.param_env, ty::Binder::dummy(self.tcx.mk_trait_ref( into_def_id, - expr_ty, [expected_ty.into()] + [expr_ty, expected_ty] )) .to_poly_trait_predicate(), )) diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 1a5383ea245ea..89746ce54a643 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -9,7 +9,6 @@ use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_middle::ty; use rustc_middle::ty::{Adt, Array, Ref, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::{Empty, Underscore}; @@ -232,10 +231,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind: TypeVariableOriginKind::MiscVariable, span, }); - let params = self.tcx.mk_substs(std::iter::once(ty::GenericArg::from(any_type))); if !self .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() { return; diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 6b228377ed004..d0ea2b0e66475 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -70,13 +70,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.probe(|_| { let trait_ref = tcx.mk_trait_ref( fn_once, - ty, - [self - .next_ty_var(TypeVariableOrigin { + [ + ty, + self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span, - }) - .into()], + }), + ], ); let poly_trait_ref = ty::Binder::dummy(trait_ref); let obligation = Obligation::misc( diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 090c73d1638a6..68f119adc7a7c 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -970,12 +970,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { check_trait .map(|check_trait| { self.infcx - .type_implements_trait( - check_trait, - ty, - ty::List::empty(), - self.param_env, - ) + .type_implements_trait(check_trait, [ty], self.param_env) .must_apply_modulo_regions() }) .unwrap_or(false), @@ -999,12 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { check_trait .map(|check_trait| { self.infcx - .type_implements_trait( - check_trait, - ty, - ty::List::empty(), - self.param_env, - ) + .type_implements_trait(check_trait, [ty], self.param_env) .must_apply_modulo_regions() }) .unwrap_or(false), @@ -1348,12 +1338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let is_drop_defined_for_ty = |ty: Ty<'tcx>| { let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); self.infcx - .type_implements_trait( - drop_trait, - ty, - ty::List::empty(), - self.tcx.param_env(closure_def_id), - ) + .type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id)) .must_apply_modulo_regions() }; diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index a25929330f8b8..54224c9b5de22 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -27,7 +27,7 @@ pub trait TraitEngine<'tcx>: 'tcx { def_id: DefId, 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( infcx, Obligation { diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index d733eebcad6c5..c1820ac4d1eab 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -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 suggest_display = is_str - || cx.tcx.get_diagnostic_item(sym::Display).map(|t| { - infcx.type_implements_trait(t, ty, ty::List::empty(), cx.param_env).may_apply() - }) == Some(true); + || cx + .tcx + .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 - && cx.tcx.get_diagnostic_item(sym::Debug).map(|t| { - infcx.type_implements_trait(t, ty, ty::List::empty(), cx.param_env).may_apply() - }) == Some(true); + && cx + .tcx + .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; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0ee190302ac91..8d6ae14231457 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2820,17 +2820,17 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_trait_ref( self, trait_def_id: DefId, - self_ty: Ty<'tcx>, - rest: impl IntoIterator, IntoIter: ExactSizeIterator>, + substs: impl IntoIterator>>, ) -> 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!( - self.generics_of(trait_def_id).count() - 1, - rest.len(), - "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?", - rest.collect::>(), + (n, Some(n)), + substs.size_hint(), + "wrong number of generic parameters for {trait_def_id:?}: {:?} \nDid you accidentally include the self-type in the params list?", + substs.collect::>(), ); - let substs = self.mk_substs_trait(self_ty, rest); + let substs = self.mk_substs(substs); ty::TraitRef::new(trait_def_id, substs) } @@ -2994,11 +2994,10 @@ impl<'tcx> TyCtxtAt<'tcx> { pub fn mk_trait_ref( self, trait_lang_item: LangItem, - self_ty: Ty<'tcx>, - rest: impl IntoIterator, IntoIter: ExactSizeIterator>, + substs: impl IntoIterator>>, ) -> ty::TraitRef<'tcx> { 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) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 35ab8b2af6b54..db18558e947a3 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -719,7 +719,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> { self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) } 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) } } @@ -812,7 +812,10 @@ impl<'tcx> TraitRef<'tcx> { } 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` where `Pi` @@ -910,7 +913,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> { // otherwise the escaping vars would be captured by the binder // 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())) } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 4364fca9739c7..a21f6cd39f014 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -232,8 +232,7 @@ impl<'tcx> ConstToPat<'tcx> { ObligationCause::misc(self.span, self.id), partial_eq_trait_id, 0, - ty, - [ty.into()], + [ty, ty], ); // FIXME: should this call a `predicate_must_hold` variant instead? diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 616620edc09fb..b616ed35d99d7 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -28,7 +28,7 @@ fn custom_coerce_unsize_info<'tcx>( target_ty: Ty<'tcx>, ) -> CustomCoerceUnsized { 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)) { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index 415bd8de145ac..9b39a9401149a 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -122,7 +122,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { let tcx = self.infcx.tcx; // - 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); diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index af17c86e1a5f1..25a9c29caa7ab 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -7,9 +7,8 @@ use rustc_infer::traits::ObligationCause; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse}; 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::{GenericArg, ToPredicate}; use rustc_span::{Span, DUMMY_SP}; use std::fmt::Debug; @@ -44,8 +43,7 @@ pub trait InferCtxtExt<'tcx> { /// The inputs are: /// /// - the def-id of the trait - /// - the self type - /// - the *other* type parameters of the trait, excluding the self-type + /// - the type parameters of the trait, including the self-type /// - the parameter environment /// /// Invokes `evaluate_obligation`, so in the event that evaluating @@ -54,8 +52,7 @@ pub trait InferCtxtExt<'tcx> { fn type_implements_trait( &self, trait_def_id: DefId, - ty: Ty<'tcx>, - params: SubstsRef<'tcx>, + params: impl IntoIterator>>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult; } @@ -109,15 +106,14 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { InferOk { value, obligations } } - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "debug", skip(self, params), ret)] fn type_implements_trait( &self, trait_def_id: DefId, - self_ty: Ty<'tcx>, - params: SubstsRef<'tcx>, + params: impl IntoIterator>>, param_env: ty::ParamEnv<'tcx>, ) -> 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 { cause: traits::ObligationCause::dummy(), diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index c7dc7b1049c69..a057e45ad6af4 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -86,7 +86,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult { 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); @@ -260,7 +260,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new(); 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, // Auto traits are positive diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 09c2449bdaeec..3a05708aebc6c 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -93,7 +93,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { def_id: DefId, ) { 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 { cause, recursion_depth: 0, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 3d0f87942c33a..946e6e77a3da0 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -347,7 +347,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { span: DUMMY_SP, 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( self.tcx, ObligationCause::dummy(), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 4b6d8177381a9..8086cac0d551a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2971,8 +2971,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); let impls_future = self.type_implements_trait( future_trait, - self.tcx.erase_late_bound_regions(self_ty), - ty::List::empty(), + [self.tcx.erase_late_bound_regions(self_ty)], obligation.param_env, ); 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 trait_substs = match diagnostic_name { sym::PartialEq | sym::PartialOrd => { - Some(field_ty.into()) + Some(field_ty) } _ => None, }; let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate { trait_ref: self.tcx.mk_trait_ref( trait_pred.def_id(), - field_ty, - trait_substs, + [field_ty].into_iter().chain(trait_substs), ), ..*tr }); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index eb5cd9a2d06a4..ff18aa1f9e909 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -143,7 +143,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( def_id: DefId, span: Span, ) -> 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) } @@ -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. 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))) { Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 29b315bff16d9..90f48658113af 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -685,11 +685,9 @@ fn receiver_is_dispatchable<'tcx>( let param_env = tcx.param_env(method.def_id); // Self: Unsize - let unsize_predicate = ty::Binder::dummy(tcx.mk_trait_ref( - unsize_did, - tcx.types.self_param, - [unsized_self_ty.into()], - )) + let unsize_predicate = ty::Binder::dummy( + tcx.mk_trait_ref(unsize_did, [tcx.types.self_param, unsized_self_ty]), + ) .without_const() .to_predicate(tcx); @@ -721,11 +719,9 @@ fn receiver_is_dispatchable<'tcx>( // Receiver: DispatchFromDyn U]> let obligation = { - let predicate = ty::Binder::dummy(tcx.mk_trait_ref( - dispatch_from_dyn_did, - receiver_ty, - [unsized_receiver_ty.into()], - )) + let predicate = ty::Binder::dummy( + tcx.mk_trait_ref(dispatch_from_dyn_did, [receiver_ty, unsized_receiver_ty]), + ) .without_const(); Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 4b1e8f18e34b1..9f19b0092c00f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1712,7 +1712,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( selcx.tcx(), ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref( LangItem::Sized, - self_ty, [], + [self_ty], )) .without_const(), ), @@ -1966,11 +1966,9 @@ fn confirm_pointee_candidate<'cx, 'tcx>( ) }); if check_is_sized { - let sized_predicate = ty::Binder::dummy(tcx.at(obligation.cause.span).mk_trait_ref( - LangItem::Sized, - self_ty, - [], - )) + let sized_predicate = ty::Binder::dummy( + tcx.at(obligation.cause.span).mk_trait_ref(LangItem::Sized, [self_ty]), + ) .without_const(); obligations.push(obligation.with(tcx, sized_predicate)); } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index b11f2c8e6a467..99d4e47ffc16f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -714,7 +714,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } // - 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( tcx, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 19d69e9dfaa05..2ec5d925b6900 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -632,11 +632,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { output_ty, &mut nested, ); - let tr = ty::Binder::dummy(self.tcx().at(cause.span).mk_trait_ref( - LangItem::Sized, - output_ty, - [], - )); + let tr = + ty::Binder::dummy(self.tcx().at(cause.span).mk_trait_ref(LangItem::Sized, [output_ty])); nested.push(Obligation::new( self.infcx.tcx, cause, @@ -998,7 +995,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We can only make objects from sized types. 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))); // If the type is `Foo + 'a`, ensure that the type @@ -1104,8 +1101,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.cause.clone(), obligation.predicate.def_id(), obligation.recursion_depth + 1, - source_tail, - [target_tail.into()], + [source_tail, target_tail], )); } @@ -1135,8 +1131,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.cause.clone(), obligation.predicate.def_id(), obligation.recursion_depth + 1, - a_last, - [b_last.into()], + [a_last, b_last], ) })); } @@ -1252,11 +1247,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause.clone(), obligation.recursion_depth + 1, self_ty.rebind(ty::TraitPredicate { - trait_ref: self.tcx().at(cause.span).mk_trait_ref( - LangItem::Destruct, - nested_ty, - [], - ), + trait_ref: self + .tcx() + .at(cause.span) + .mk_trait_ref(LangItem::Destruct, [nested_ty]), constness: ty::BoundConstness::ConstIfConst, 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) _ => { let predicate = self_ty.rebind(ty::TraitPredicate { - trait_ref: self.tcx().at(cause.span).mk_trait_ref( - LangItem::Destruct, - nested_ty, - [], - ), + trait_ref: self + .tcx() + .at(cause.span) + .mk_trait_ref(LangItem::Destruct, [nested_ty]), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 06e507eb72912..e54e290fb4b11 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2100,8 +2100,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause.clone(), trait_def_id, recursion_depth, - normalized_ty, - [], + [normalized_ty], ); obligations.push(placeholder_obligation); obligations diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 87c534bad96a9..895b84fd7e9df 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -238,10 +238,9 @@ pub fn predicate_for_trait_def<'tcx>( cause: ObligationCause<'tcx>, trait_def_id: DefId, recursion_depth: usize, - self_ty: Ty<'tcx>, - params: impl IntoIterator, IntoIter: ExactSizeIterator>, + params: impl IntoIterator>>, ) -> 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) } @@ -304,7 +303,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>( TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), }; 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())) } @@ -315,8 +314,7 @@ pub fn generator_trait_ref_and_outputs<'tcx>( sig: ty::PolyGenSig<'tcx>, ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { debug_assert!(!self_ty.has_escaping_bound_vars()); - let trait_ref = - tcx.mk_trait_ref(fn_trait_def_id, self_ty, [sig.skip_binder().resume_ty.into()]); + let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, sig.skip_binder().resume_ty]); sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty)) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index de72c6618d4f5..53783e1bc4b2c 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -421,7 +421,7 @@ impl<'tcx> WfPredicates<'tcx> { fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { if !subty.has_escaping_bound_vars() { 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.tcx, cause, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 26db976820653..5fc9bcac1b19e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -49,7 +49,7 @@ fn sized_constraint_for_ty<'tcx>( // it on the impl. 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() .to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index bd55517311d7e..05607d05ecf23 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -44,7 +44,7 @@ where discard_positive_impl: bool, ) -> Option { 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)) { debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref); return None; diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 03d865af374a2..c4e7f8bfe1e20 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -842,14 +842,10 @@ fn walk_parents<'tcx>( } 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 ty::Ref(_, sub_ty, _) = *arg_ty.kind() - && let subs = match cx + && let subs = cx .typeck_results() - .node_substs_opt(parent.hir_id) - .and_then(|subs| subs.get(1..)) - { - Some(subs) => cx.tcx.mk_substs(subs.iter().copied()), - None => cx.tcx.mk_substs(std::iter::empty::>()), - } && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() { + .node_substs_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default() + && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() { // Trait methods taking `&self` sub_ty } else { @@ -858,7 +854,7 @@ fn walk_parents<'tcx>( } && impl_ty.is_ref() && let infcx = cx.tcx.infer_ctxt().build() && 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() { return Some(Position::MethodReceiverRefImpl) diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index ea00650d42aa1..5420a0e782ea8 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -692,7 +692,7 @@ fn matches_preds<'tcx>( let infcx = cx.tcx.infer_ctxt().build(); preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) { 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(), ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new( cx.tcx, @@ -704,7 +704,7 @@ fn matches_preds<'tcx>( )), )), 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(), }) } diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index a8047fe9e5ea1..5ec6f29fe9163 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -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()))); 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() } From 24cdb72445a9ebd545fc5101a6aa8802b5d33c92 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 21 Nov 2022 16:52:01 +0100 Subject: [PATCH 18/21] Use `as_closure` helper method Co-authored-by: lcnr --- src/tools/clippy/clippy_lints/src/eta_reduction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index ea4e5e052d029..f34cbee03558b 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -124,7 +124,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { if let Some(mut snippet) = snippet_opt(cx, callee.span) { if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait() - && let args = cx.tcx.erase_late_bound_regions(ty::ClosureSubsts { substs }.sig()).inputs() + && let args = cx.tcx.erase_late_bound_regions(substs.as_closure().sig()).inputs() && implements_trait(cx, callee_ty.peel_refs(), fn_mut_id, &args.iter().copied().map(Into::into).collect::>()) && path_to_local(callee).map_or(false, |l| local_used_after_expr(cx, l, expr)) { From 5316378e55598a2976e853810f6278bf5b94a383 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 21 Nov 2022 16:52:18 +0100 Subject: [PATCH 19/21] Simplify test Co-authored-by: lcnr --- .../ui/pattern/usefulness/const-partial_eq-fallback-ice.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs index daa432d9ae5d1..02599d7c05b59 100644 --- a/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs +++ b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs @@ -13,8 +13,6 @@ const CONSTANT: &&MyType = &&MyType; fn main() { if let CONSTANT = &&MyType { //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` - println!("semantic!"); - } else { - println!("structural!"); + println!("did match!"); } } From a6c5212f1357345d7bd90ca799b74869f3406b19 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 21 Nov 2022 15:55:37 +0000 Subject: [PATCH 20/21] Simplify one more `TraitRef::new` site --- compiler/rustc_hir_typeck/src/coercion.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 5062926106942..43c7127b0d4c5 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -804,10 +804,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { self.tcx, self.cause.clone(), self.param_env, - ty::Binder::dummy(ty::TraitRef::new( - self.tcx.require_lang_item(hir::LangItem::PointerSized, Some(self.cause.span)), - self.tcx.mk_substs_trait(a, []), - )) + ty::Binder::dummy( + self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]), + ) .to_poly_trait_predicate(), )); } From c2ecd8f1f6e634e08081d00cbd90e0026d81e623 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 21 Nov 2022 15:59:15 +0000 Subject: [PATCH 21/21] merge self type and substs in `trait_method` --- compiler/rustc_mir_build/src/build/matches/test.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 8ff7296c7b662..a62cfecf78b78 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let ref_str_ty = tcx.mk_imm_ref(re_erased, tcx.types.str_); let ref_str = self.temp(ref_str_ty, test.span); let deref = tcx.require_lang_item(LangItem::Deref, None); - let method = trait_method(tcx, deref, sym::deref, ty, []); + let method = trait_method(tcx, deref, sym::deref, [ty]); let eq_block = self.cfg.start_new_block(); self.cfg.push_assign(block, source_info, ref_string, Rvalue::Ref(re_erased, BorrowKind::Shared, place)); self.cfg.terminate( @@ -445,7 +445,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); - let method = trait_method(self.tcx, eq_def_id, sym::eq, deref_ty, [deref_ty.into()]); + let method = trait_method(self.tcx, eq_def_id, sym::eq, [deref_ty, deref_ty]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); @@ -837,10 +837,9 @@ fn trait_method<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, method_name: Symbol, - self_ty: Ty<'tcx>, - params: impl IntoIterator, IntoIter: ExactSizeIterator>, + substs: impl IntoIterator>>, ) -> ConstantKind<'tcx> { - let substs = tcx.mk_substs_trait(self_ty, params); + let substs = tcx.mk_substs(substs.into_iter().map(Into::into)); // The unhygienic comparison here is acceptable because this is only // used on known traits.