From 319575ae8c3f6ea5db1c850c8f4c786c8cc203fe Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Sun, 8 May 2022 01:17:58 -0400 Subject: [PATCH 1/6] Introduce EarlyBinder --- .../src/diagnostics/conflict_errors.rs | 6 ++- .../rustc_borrowck/src/universal_regions.rs | 8 +-- .../src/const_eval/eval_queries.rs | 4 +- .../interpret/intrinsics/caller_location.rs | 9 ++-- .../src/infer/error_reporting/mod.rs | 18 ++++--- .../rustc_infer/src/infer/opaque_types.rs | 4 +- .../rustc_infer/src/infer/outlives/verify.rs | 4 +- compiler/rustc_middle/src/mir/mod.rs | 4 +- compiler/rustc_middle/src/mir/tcx.rs | 6 ++- compiler/rustc_middle/src/ty/context.rs | 13 ++--- compiler/rustc_middle/src/ty/generics.rs | 11 +++- compiler/rustc_middle/src/ty/instance.rs | 8 ++- compiler/rustc_middle/src/ty/layout.rs | 11 ++-- compiler/rustc_middle/src/ty/mod.rs | 6 +-- .../src/ty/normalize_erasing_regions.rs | 6 +-- compiler/rustc_middle/src/ty/print/mod.rs | 9 ++-- compiler/rustc_middle/src/ty/print/pretty.rs | 8 +-- compiler/rustc_middle/src/ty/relate.rs | 5 +- compiler/rustc_middle/src/ty/sty.rs | 47 ++++++++++++++-- compiler/rustc_middle/src/ty/subst.rs | 14 +++-- compiler/rustc_middle/src/ty/util.rs | 5 +- .../rustc_mir_build/src/build/matches/test.rs | 4 +- compiler/rustc_mir_build/src/build/mod.rs | 5 +- .../rustc_mir_transform/src/const_prop.rs | 6 ++- .../src/const_prop_lint.rs | 4 +- .../src/function_item_references.rs | 4 +- compiler/rustc_mir_transform/src/generator.rs | 6 +-- compiler/rustc_mir_transform/src/inline.rs | 4 +- compiler/rustc_mir_transform/src/shim.rs | 10 ++-- compiler/rustc_symbol_mangling/src/v0.rs | 6 ++- .../src/traits/coherence.rs | 6 +-- .../src/traits/const_evaluatable.rs | 8 +-- .../error_reporting/on_unimplemented.rs | 5 +- .../src/traits/object_safety.rs | 4 +- .../src/traits/project.rs | 12 +++-- .../src/traits/query/normalize.rs | 4 +- .../src/traits/select/confirmation.rs | 53 ++++++++++--------- .../src/traits/select/mod.rs | 18 +++---- .../src/traits/specialize/mod.rs | 6 +-- .../rustc_trait_selection/src/traits/util.rs | 4 +- compiler/rustc_traits/src/chalk/db.rs | 27 +++++----- compiler/rustc_traits/src/dropck_outlives.rs | 14 +++-- compiler/rustc_traits/src/type_op.rs | 6 ++- compiler/rustc_ty_utils/src/needs_drop.rs | 6 +-- compiler/rustc_ty_utils/src/ty.rs | 8 +-- compiler/rustc_typeck/src/astconv/mod.rs | 21 +++++--- compiler/rustc_typeck/src/check/callee.rs | 4 +- compiler/rustc_typeck/src/check/check.rs | 6 +-- compiler/rustc_typeck/src/check/closure.rs | 6 +-- .../rustc_typeck/src/check/compare_method.rs | 8 +-- compiler/rustc_typeck/src/check/dropck.rs | 4 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 23 ++++---- compiler/rustc_typeck/src/check/intrinsic.rs | 4 +- .../rustc_typeck/src/check/method/confirm.rs | 4 +- compiler/rustc_typeck/src/check/method/mod.rs | 4 +- .../rustc_typeck/src/check/method/probe.rs | 10 ++-- compiler/rustc_typeck/src/check/wfcheck.rs | 5 +- .../src/outlives/implicit_infer.rs | 6 +-- src/librustdoc/clean/blanket_impl.rs | 6 +-- src/librustdoc/clean/mod.rs | 4 +- .../clippy/clippy_lints/src/eta_reduction.rs | 4 +- .../clippy_lints/src/future_not_send.rs | 4 +- .../clippy/clippy_lints/src/mut_reference.rs | 4 +- .../src/transmute/transmute_undefined_repr.rs | 4 +- src/tools/clippy/clippy_utils/src/consts.rs | 4 +- src/tools/clippy/clippy_utils/src/ty.rs | 4 +- 66 files changed, 340 insertions(+), 235 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index bbb631730d346..a3c9da3021204 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -13,7 +13,9 @@ use rustc_middle::mir::{ FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, }; -use rustc_middle::ty::{self, subst::Subst, suggest_constraining_type_params, PredicateKind, Ty}; +use rustc_middle::ty::{ + self, subst::Subst, suggest_constraining_type_params, EarlyBinder, PredicateKind, Ty, +}; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_span::symbol::sym; use rustc_span::{BytePos, Span}; @@ -336,7 +338,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let find_fn_kind_from_did = |predicates: &[(ty::Predicate<'tcx>, Span)], substs| { predicates.iter().find_map(|(pred, _)| { let pred = if let Some(substs) = substs { - pred.subst(tcx, substs).kind().skip_binder() + EarlyBinder(*pred).subst(tcx, substs).kind().skip_binder() } else { pred.kind().skip_binder() }; diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index c06fe881410ae..585ea226997a6 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -23,7 +23,9 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt}; +use rustc_middle::ty::{ + self, EarlyBinder, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt, +}; use std::iter; use crate::nll::ToRegionVid; @@ -477,8 +479,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { .infcx .tcx .mk_region(ty::ReVar(self.infcx.next_nll_region_var(FR).to_region_vid())); - let va_list_ty = - self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]); + let va_list_ty = EarlyBinder(self.infcx.tcx.type_of(va_list_did)) + .subst(self.infcx.tcx, &[region.into()]); unnormalized_input_tys = self.infcx.tcx.mk_type_list( unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)), diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 38fecf7232ebc..5c56e6ee5f5b7 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -13,7 +13,7 @@ use rustc_middle::mir::pretty::display_allocation; use rustc_middle::traits::Reveal; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, subst::Subst, TyCtxt}; +use rustc_middle::ty::{self, subst::Subst, EarlyBinder, TyCtxt}; use rustc_span::source_map::Span; use rustc_target::abi::{self, Abi}; use std::borrow::Cow; @@ -47,7 +47,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( "Unexpected DefKind: {:?}", ecx.tcx.def_kind(cid.instance.def_id()) ); - let layout = ecx.layout_of(body.return_ty().subst(tcx, cid.instance.substs))?; + let layout = ecx.layout_of(EarlyBinder(body.return_ty()).subst(tcx, cid.instance.substs))?; assert!(!layout.is_unsized()); let ret = ecx.allocate(layout, MemoryKind::Stack)?; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 058903dcdee55..43133b03ad1a3 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -5,6 +5,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::mir::TerminatorKind; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::subst::Subst; +use rustc_middle::ty::EarlyBinder; use rustc_span::{Span, Symbol}; use crate::interpret::{ @@ -93,10 +94,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let col = if loc_details.column { Scalar::from_u32(col) } else { Scalar::from_u32(0) }; // Allocate memory for `CallerLocation` struct. - let loc_ty = self - .tcx - .type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None)) - .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); + let loc_ty = EarlyBinder( + self.tcx.type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None)), + ) + .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); let loc_layout = self.layout_of(loc_ty).unwrap(); // This can fail if rustc runs out of memory right here. Trying to emit an error would be // pointless, since that would require allocating more memory than a Location. diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index af81f5cde2c41..8fc41ba5365d8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -70,7 +70,7 @@ use rustc_middle::ty::{ self, error::TypeError, subst::{GenericArgKind, Subst, SubstsRef}, - Binder, List, Region, Ty, TyCtxt, TypeFoldable, + Binder, EarlyBinder, List, Region, Ty, TyCtxt, TypeFoldable, }; use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; @@ -961,12 +961,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { for (def_id, actual) in iter::zip(default_params, substs.iter().rev()) { match actual.unpack() { GenericArgKind::Const(c) => { - if self.tcx.const_param_default(def_id).subst(self.tcx, substs) != c { + if EarlyBinder(self.tcx.const_param_default(def_id)).subst(self.tcx, substs) + != c + { break; } } GenericArgKind::Type(ty) => { - if self.tcx.type_of(def_id).subst(self.tcx, substs) != ty { + if EarlyBinder(self.tcx.type_of(def_id)).subst(self.tcx, substs) != ty { break; } } @@ -1383,8 +1385,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => { - let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1); - let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2); + let sig1 = EarlyBinder(self.tcx.fn_sig(*did1)).subst(self.tcx, substs1); + let sig2 = EarlyBinder(self.tcx.fn_sig(*did2)).subst(self.tcx, substs2); let mut values = self.cmp_fn_sig(&sig1, &sig2); let path1 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did1, substs1)); let path2 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did2, substs2)); @@ -1395,7 +1397,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } (ty::FnDef(did1, substs1), ty::FnPtr(sig2)) => { - let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1); + let sig1 = EarlyBinder(self.tcx.fn_sig(*did1)).subst(self.tcx, substs1); let mut values = self.cmp_fn_sig(&sig1, sig2); values.0.push_highlighted(format!( " {{{}}}", @@ -1405,7 +1407,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } (ty::FnPtr(sig1), ty::FnDef(did2, substs2)) => { - let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2); + let sig2 = EarlyBinder(self.tcx.fn_sig(*did2)).subst(self.tcx, substs2); let mut values = self.cmp_fn_sig(sig1, &sig2); values.1.push_normal(format!( " {{{}}}", @@ -1850,7 +1852,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let bounds = self.tcx.explicit_item_bounds(*def_id); for (predicate, _) in bounds { - let predicate = predicate.subst(self.tcx, substs); + let predicate = EarlyBinder(*predicate).subst(self.tcx, substs); let output = predicate .kind() .map_bound(|kind| match kind { diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index d25484efabc5f..6b2c599864c7d 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -9,7 +9,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::subst::{GenericArgKind, Subst}; use rustc_middle::ty::{ - self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor, + self, EarlyBinder, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor, }; use rustc_span::Span; @@ -565,7 +565,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { for (predicate, _) in item_bounds { debug!(?predicate); - let predicate = predicate.subst(tcx, substs); + let predicate = EarlyBinder(*predicate).subst(tcx, substs); let predicate = predicate.fold_with(&mut BottomUpFolder { tcx, diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index ab565d4396191..1c521c90686d6 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -4,7 +4,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::sso::SsoHashSet; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; /// The `TypeOutlives` struct has the job of "lowering" a `T: 'a` /// obligation into a series of `'a: 'b` constraints and "verifys", as @@ -290,7 +290,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { debug!("projection_bounds(projection_ty={:?})", projection_ty); let tcx = self.tcx; self.region_bounds_declared_on_associated_item(projection_ty.item_def_id) - .map(move |r| r.subst(tcx, projection_ty.substs)) + .map(move |r| EarlyBinder(r).subst(tcx, projection_ty.substs)) } /// Given the `DefId` of an associated item, returns any region diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 2c97c7704e77d..5b064759d5886 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -10,7 +10,7 @@ use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; -use crate::ty::{self, List, Ty, TyCtxt}; +use crate::ty::{self, EarlyBinder, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, Region, ScalarInt, UserTypeAnnotationIndex}; use rustc_errors::ErrorGuaranteed; @@ -2387,7 +2387,7 @@ impl<'tcx> Operand<'tcx> { substs: SubstsRef<'tcx>, span: Span, ) -> Self { - let ty = tcx.type_of(def_id).subst(tcx, substs); + let ty = EarlyBinder(tcx.type_of(def_id)).subst(tcx, substs); Operand::Constant(Box::new(Constant { span, user_ty: None, diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index f1d5201454d69..99a4822bc9ac9 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -5,7 +5,7 @@ use crate::mir::*; use crate::ty::subst::Subst; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, EarlyBinder, Ty, TyCtxt}; use rustc_hir as hir; use rustc_target::abi::VariantIdx; @@ -202,7 +202,9 @@ impl<'tcx> Rvalue<'tcx> { Rvalue::Aggregate(ref ak, ref ops) => match **ak { AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64), AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))), - AggregateKind::Adt(did, _, substs, _, _) => tcx.type_of(did).subst(tcx, substs), + AggregateKind::Adt(did, _, substs, _, _) => { + EarlyBinder(tcx.type_of(did)).subst(tcx, substs) + } AggregateKind::Closure(did, substs) => tcx.mk_closure(did, substs), AggregateKind::Generator(did, substs, movability) => { tcx.mk_generator(did, substs, movability) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9d3d509eb216b..0932bfefc86e4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -19,10 +19,11 @@ use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, Substs use crate::ty::TyKind::*; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, - ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, - FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, - ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, - RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, + ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, EarlyBinder, ExistentialPredicate, + FloatTy, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, + List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, + Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, + UintTy, }; use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; @@ -1604,7 +1605,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn caller_location_ty(self) -> Ty<'tcx> { self.mk_imm_ref( self.lifetimes.re_static, - self.type_of(self.require_lang_item(LangItem::PanicLocation, None)) + EarlyBinder(self.type_of(self.require_lang_item(LangItem::PanicLocation, None))) .subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())), ) } @@ -2333,7 +2334,7 @@ impl<'tcx> TyCtxt<'tcx> { ty_param.into() } else { assert!(has_default); - self.type_of(param.def_id).subst(self, substs).into() + EarlyBinder(self.type_of(param.def_id)).subst(self, substs).into() } } }); diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 0bd96f8f865fc..d9b82ee0a7680 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -1,6 +1,7 @@ use crate::middle::resolve_lifetime::ObjectLifetimeDefault; use crate::ty; use crate::ty::subst::{Subst, SubstsRef}; +use crate::ty::EarlyBinder; use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; @@ -229,7 +230,11 @@ impl<'tcx> GenericPredicates<'tcx> { substs: SubstsRef<'tcx>, ) -> InstantiatedPredicates<'tcx> { InstantiatedPredicates { - predicates: self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)).collect(), + predicates: self + .predicates + .iter() + .map(|(p, _)| EarlyBinder(*p).subst(tcx, substs)) + .collect(), spans: self.predicates.iter().map(|(_, sp)| *sp).collect(), } } @@ -243,7 +248,9 @@ impl<'tcx> GenericPredicates<'tcx> { if let Some(def_id) = self.parent { tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs); } - instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p.subst(tcx, substs))); + instantiated + .predicates + .extend(self.predicates.iter().map(|(p, _)| EarlyBinder(*p).subst(tcx, substs))); instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp)); } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 7cf7f8973475d..81404bf712def 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -1,7 +1,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::subst::{InternalSubsts, Subst}; -use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt, TypeFoldable}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::Namespace; use rustc_hir::def_id::{CrateNum, DefId}; @@ -557,7 +557,11 @@ impl<'tcx> Instance<'tcx> { where T: TypeFoldable<'tcx> + Copy, { - if let Some(substs) = self.substs_for_mir_body() { v.subst(tcx, substs) } else { *v } + if let Some(substs) = self.substs_for_mir_body() { + EarlyBinder(*v).subst(tcx, substs) + } else { + *v + } } #[inline(always)] diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index c8055100d3096..28652bdd22817 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2,7 +2,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir::{GeneratorLayout, GeneratorSavedLocal}; use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::subst::Subst; -use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, subst::SubstsRef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeFoldable}; use rustc_ast as ast; use rustc_attr as attr; use rustc_hir as hir; @@ -1706,7 +1706,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { ) -> Result, LayoutError<'tcx>> { use SavedLocalEligibility::*; let tcx = self.tcx; - let subst_field = |ty: Ty<'tcx>| ty.subst(tcx, substs); + let subst_field = |ty: Ty<'tcx>| EarlyBinder(ty).subst(tcx, substs); let Some(info) = tcx.generator_layout(def_id) else { return Err(LayoutError::Unknown(ty)); @@ -2749,9 +2749,10 @@ impl<'tcx> ty::Instance<'tcx> { // `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping // track of a polymorphization `ParamEnv` to allow normalizing later. let mut sig = match *ty.kind() { - ty::FnDef(def_id, substs) => tcx - .normalize_erasing_regions(tcx.param_env(def_id), tcx.fn_sig(def_id)) - .subst(tcx, substs), + ty::FnDef(def_id, substs) => EarlyBinder( + tcx.normalize_erasing_regions(tcx.param_env(def_id), tcx.fn_sig(def_id)), + ) + .subst(tcx, substs), _ => unreachable!(), }; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d847068b5bfb3..9a04b06a7df34 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -78,7 +78,7 @@ pub use self::sty::RegionKind::*; pub use self::sty::TyKind::*; pub use self::sty::{ Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, BoundVariableKind, - CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBoundRegion, + CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBinder, EarlyBoundRegion, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig, GeneratorSubsts, GeneratorSubstsParts, InlineConstSubsts, InlineConstSubstsParts, ParamConst, ParamTy, PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, @@ -736,7 +736,7 @@ impl<'tcx> Predicate<'tcx> { let shifted_pred = tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder()); // 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1> - let new = shifted_pred.subst(tcx, trait_ref.skip_binder().substs); + let new = EarlyBinder(shifted_pred).subst(tcx, trait_ref.skip_binder().substs); // 3) ['x] + ['b] -> ['x, 'b] let bound_vars = tcx.mk_bound_variable_kinds(trait_bound_vars.iter().chain(pred_bound_vars)); @@ -1932,7 +1932,7 @@ impl<'tcx> FieldDef { /// Returns the type of this field. The resulting type is not normalized. The `subst` is /// typically obtained via the second field of [`TyKind::Adt`]. pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> { - tcx.type_of(self.did).subst(tcx, subst) + EarlyBinder(tcx.type_of(self.did)).subst(tcx, subst) } /// Computes the `Ident` of this variant by looking up the `Span` diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 808be446b2af6..9bbbd7e2f7c5e 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -11,7 +11,7 @@ use crate::mir; use crate::traits::query::NoSolution; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; use crate::ty::subst::{Subst, SubstsRef}; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, EarlyBinder, Ty, TyCtxt}; #[derive(Debug, Copy, Clone, HashStable, TyEncodable, TyDecodable)] pub enum NormalizationError<'tcx> { @@ -133,7 +133,7 @@ impl<'tcx> TyCtxt<'tcx> { param_env={:?})", param_substs, value, param_env, ); - let substituted = value.subst(self, param_substs); + let substituted = EarlyBinder(value).subst(self, param_substs); self.normalize_erasing_regions(param_env, substituted) } @@ -157,7 +157,7 @@ impl<'tcx> TyCtxt<'tcx> { param_env={:?})", param_substs, value, param_env, ); - let substituted = value.subst(self, param_substs); + let substituted = EarlyBinder(value).subst(self, param_substs); self.try_normalize_erasing_regions(param_env, substituted) } } diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index a1d1b6b3a785b..0262caddec562 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -1,5 +1,5 @@ use crate::ty::subst::{GenericArg, Subst}; -use crate::ty::{self, DefIdTree, Ty, TyCtxt}; +use crate::ty::{self, DefIdTree, EarlyBinder, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; @@ -118,8 +118,8 @@ pub trait Printer<'tcx>: Sized { let mut self_ty = self.tcx().type_of(def_id); let mut impl_trait_ref = self.tcx().impl_trait_ref(def_id); if substs.len() >= generics.count() { - self_ty = self_ty.subst(self.tcx(), substs); - impl_trait_ref = impl_trait_ref.subst(self.tcx(), substs); + self_ty = EarlyBinder(self_ty).subst(self.tcx(), substs); + impl_trait_ref = EarlyBinder(impl_trait_ref).subst(self.tcx(), substs); } self.print_impl_path(def_id, substs, self_ty, impl_trait_ref) } @@ -203,7 +203,8 @@ pub trait Printer<'tcx>: Sized { has_default && substs[param.index as usize] == GenericArg::from( - self.tcx().type_of(param.def_id).subst(self.tcx(), substs), + EarlyBinder(self.tcx().type_of(param.def_id)) + .subst(self.tcx(), substs), ) } ty::GenericParamDefKind::Const { has_default } => { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index eed90337c0a50..8a7f1e68a3528 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,6 +1,8 @@ use crate::mir::interpret::{AllocRange, ConstValue, GlobalAlloc, Pointer, Provenance, Scalar}; use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; -use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{ + self, ConstInt, DefIdTree, EarlyBinder, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable, +}; use rustc_apfloat::ieee::{Double, Single}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sso::SsoHashSet; @@ -587,7 +589,7 @@ pub trait PrettyPrinter<'tcx>: p!(")") } ty::FnDef(def_id, substs) => { - let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs); + let sig = EarlyBinder(self.tcx().fn_sig(def_id)).subst(self.tcx(), substs); p!(print(sig), " {{", print_value_path(def_id, substs), "}}"); } ty::FnPtr(ref bare_fn) => p!(print(bare_fn)), @@ -781,7 +783,7 @@ pub trait PrettyPrinter<'tcx>: let mut is_sized = false; for (predicate, _) in bounds { - let predicate = predicate.subst(self.tcx(), substs); + let predicate = EarlyBinder(*predicate).subst(self.tcx(), substs); let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 4c1160e21fec2..65f07f177ebf9 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -7,7 +7,7 @@ use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar}; use crate::ty::error::{ExpectedFound, TypeError}; use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef}; -use crate::ty::{self, ImplSubject, Term, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, EarlyBinder, ImplSubject, Term, Ty, TyCtxt, TypeFoldable}; use rustc_hir as ast; use rustc_hir::def_id::DefId; use rustc_span::DUMMY_SP; @@ -159,7 +159,8 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>( let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| { let variance = variances[i]; let variance_info = if variance == ty::Invariant { - let ty = *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst)); + let ty = *cached_ty + .get_or_insert_with(|| EarlyBinder(tcx.type_of(ty_def_id)).subst(tcx, a_subst)); ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } } else { ty::VarianceDiagInfo::default() diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 7969e7aa151df..8ceefd3e2b83e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -713,7 +713,9 @@ impl<'tcx> GeneratorSubsts<'tcx> { ) -> impl Iterator> + Captures<'tcx>> { let layout = tcx.generator_layout(def_id).unwrap(); layout.variant_fields.iter().map(move |variant| { - variant.iter().map(move |field| layout.field_tys[*field].subst(tcx, self.substs)) + variant + .iter() + .map(move |field| EarlyBinder(layout.field_tys[*field]).subst(tcx, self.substs)) }) } @@ -1068,6 +1070,45 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { } } +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Encodable, Decodable, HashStable)] +pub struct EarlyBinder(pub T); + +impl EarlyBinder { + pub fn as_ref(&self) -> EarlyBinder<&T> { + EarlyBinder(&self.0) + } + + pub fn map_bound_ref(&self, f: F) -> EarlyBinder + where + F: FnOnce(&T) -> U, + { + self.as_ref().map_bound(f) + } + + pub fn map_bound(self, f: F) -> EarlyBinder + where + F: FnOnce(T) -> U, + { + let value = f(self.0); + EarlyBinder(value) + } + + pub fn try_map_bound(self, f: F) -> Result, E> + where + F: FnOnce(T) -> Result, + { + let value = f(self.0)?; + Ok(EarlyBinder(value)) + } +} + +impl EarlyBinder> { + pub fn transpose(self) -> Option> { + self.0.map(|v| EarlyBinder(v)) + } +} + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(HashStable)] pub enum BoundVariableKind { @@ -2139,7 +2180,7 @@ impl<'tcx> Ty<'tcx> { pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> { match self.kind() { - FnDef(def_id, substs) => tcx.fn_sig(*def_id).subst(tcx, substs), + FnDef(def_id, substs) => EarlyBinder(tcx.fn_sig(*def_id)).subst(tcx, substs), FnPtr(f) => *f, Error(_) => { // ignore errors (#54954) @@ -2306,7 +2347,7 @@ impl<'tcx> Ty<'tcx> { ty::Str | ty::Slice(_) => (tcx.types.usize, false), ty::Dynamic(..) => { let dyn_metadata = tcx.lang_items().dyn_metadata().unwrap(); - (tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()]), false) + (EarlyBinder(tcx.type_of(dyn_metadata)).subst(tcx, &[tail.into()]), false) }, // type parameters only have unit metadata if they're sized, so return true diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 5b1fb70872988..9053d74441560 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -4,7 +4,7 @@ use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; -use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; +use crate::ty::{self, EarlyBinder, Lift, List, ParamConst, Ty, TyCtxt}; use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_hir::def_id::DefId; @@ -500,13 +500,17 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { // Just call `foo.subst(tcx, substs)` to perform a substitution across `foo`. pub trait Subst<'tcx>: Sized { - fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self; + type Inner; + + fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self::Inner; } -impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T { - fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T { +impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for EarlyBinder { + type Inner = T; + + fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self::Inner { let mut folder = SubstFolder { tcx, substs, binders_passed: 0 }; - self.fold_with(&mut folder) + self.0.fold_with(&mut folder) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 1c8af13ce9ca1..6efa8555bf0e3 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -6,7 +6,8 @@ use crate::ty::layout::IntegerExt; use crate::ty::query::TyCtxtAt; use crate::ty::subst::{GenericArgKind, Subst, SubstsRef}; use crate::ty::{ - self, Const, DebruijnIndex, DefIdTree, List, ReEarlyBound, Ty, TyCtxt, TyKind::*, TypeFoldable, + self, Const, DebruijnIndex, DefIdTree, EarlyBinder, List, ReEarlyBound, Ty, TyCtxt, TyKind::*, + TypeFoldable, }; use rustc_apfloat::Float as _; use rustc_ast as ast; @@ -623,7 +624,7 @@ impl<'tcx> OpaqueTypeExpander<'tcx> { Some(expanded_ty) => *expanded_ty, None => { let generic_ty = self.tcx.type_of(def_id); - let concrete_ty = generic_ty.subst(self.tcx, substs); + let concrete_ty = EarlyBinder(generic_ty).subst(self.tcx, substs); let expanded_ty = self.fold_ty(concrete_ty); self.expanded_cache.insert((def_id, substs), expanded_ty); expanded_ty diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 0e9e986937660..3444de612a444 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -16,7 +16,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::subst::{GenericArg, Subst}; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt}; +use rustc_middle::ty::{self, adjustment::PointerCast, EarlyBinder, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; @@ -835,7 +835,7 @@ fn trait_method<'tcx>( .expect("trait method not found"); let method_ty = tcx.type_of(item.def_id); - let method_ty = method_ty.subst(tcx, substs); + let method_ty = EarlyBinder(method_ty).subst(tcx, substs); ConstantKind::zero_sized(method_ty) } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index ce57e5fe846eb..3e9143b563fe2 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -14,7 +14,7 @@ use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, PatKind, Thir}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeckResults}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeckResults}; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::spec::abi::Abi; @@ -177,7 +177,8 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ let ty = if fn_sig.c_variadic && index == fn_sig.inputs().len() { let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(arg.span)); - tcx.type_of(va_list_did).subst(tcx, &[tcx.lifetimes.re_erased.into()]) + EarlyBinder(tcx.type_of(va_list_did)) + .subst(tcx, &[tcx.lifetimes.re_erased.into()]) } else { fn_sig.inputs()[index] }; diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index f7535d338da40..ef8eccf269815 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -18,7 +18,9 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; -use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{ + self, ConstKind, EarlyBinder, Instance, ParamEnv, Ty, TyCtxt, TypeFoldable, +}; use rustc_span::{def_id::DefId, Span}; use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; use rustc_target::spec::abi::Abi; @@ -374,7 +376,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ); let ret = ecx - .layout_of(body.return_ty().subst(tcx, substs)) + .layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs)) .ok() // Don't bother allocating memory for ZST types which have no values // or for large values. diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index aa898cfd3ba5e..03eda59308813 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{ - self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeFoldable, + self, ConstInt, ConstKind, EarlyBinder, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeFoldable, }; use rustc_session::lint; use rustc_span::{def_id::DefId, Span}; @@ -370,7 +370,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ); let ret = ecx - .layout_of(body.return_ty().subst(tcx, substs)) + .layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs)) .ok() // Don't bother allocating memory for ZST types which have no values // or for large values. diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 2ed14b917781d..1f9bd90d11f68 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -6,7 +6,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{ self, subst::{GenericArgKind, Subst, SubstsRef}, - PredicateKind, Ty, TyCtxt, + EarlyBinder, PredicateKind, Ty, TyCtxt, }; use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES; use rustc_span::{symbol::sym, Span}; @@ -90,7 +90,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { // If the inner type matches the type bound by `Pointer` if inner_ty == bound_ty { // Do a substitution using the parameters from the callsite - let subst_ty = inner_ty.subst(self.tcx, substs_ref); + let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref); if let Some((fn_id, fn_substs)) = FunctionItemRefChecker::is_fn_ref(subst_ty) { diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index d5d4bfa255bd9..fd27aa85904e3 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -62,7 +62,7 @@ use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::subst::{Subst, SubstsRef}; use rustc_middle::ty::GeneratorSubsts; -use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtDef, EarlyBinder, Ty, TyCtxt}; use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, }; @@ -245,9 +245,7 @@ impl<'tcx> TransformVisitor<'tcx> { ) -> impl Iterator> { let kind = AggregateKind::Adt(self.state_adt_ref.did(), idx, self.state_substs, None, None); assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 1); - let ty = self - .tcx - .type_of(self.state_adt_ref.variant(idx).fields[0].did) + let ty = EarlyBinder(self.tcx.type_of(self.state_adt_ref.variant(idx).fields[0].did)) .subst(self.tcx, self.state_substs); expand_aggregate( Place::return_place(), diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 5e6dabeba6da2..fdb5f600f1840 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -8,7 +8,7 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, ConstKind, EarlyBinder, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; use rustc_target::spec::abi::Abi; @@ -260,7 +260,7 @@ impl<'tcx> Inliner<'tcx> { return None; } - let fn_sig = self.tcx.fn_sig(def_id).subst(self.tcx, substs); + let fn_sig = EarlyBinder(self.tcx.fn_sig(def_id)).subst(self.tcx, substs); return Some(CallSite { callee, diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index d10cac2ac7635..066e22cb4e59c 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -4,7 +4,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::mir::*; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::{InternalSubsts, Subst}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; use rustc_target::abi::VariantIdx; use rustc_index::vec::{Idx, IndexVec}; @@ -70,7 +70,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' // of this function. Is this intentional? if let Some(ty::Generator(gen_def_id, substs, _)) = ty.map(Ty::kind) { let body = tcx.optimized_mir(*gen_def_id).generator_drop().unwrap(); - let body = body.clone().subst(tcx, substs); + let body = EarlyBinder(body.clone()).subst(tcx, substs); debug!("make_shim({:?}) = {:?}", instance, body); return body; } @@ -151,7 +151,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) } else { InternalSubsts::identity_for_item(tcx, def_id) }; - let sig = tcx.fn_sig(def_id).subst(tcx, substs); + let sig = EarlyBinder(tcx.fn_sig(def_id)).subst(tcx, substs); let sig = tcx.erase_late_bound_regions(sig); let span = tcx.def_span(def_id); @@ -343,7 +343,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // 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 sig = tcx.fn_sig(def_id).subst(tcx, substs); + let sig = EarlyBinder(tcx.fn_sig(def_id)).subst(tcx, substs); let sig = tcx.erase_late_bound_regions(sig); let span = tcx.def_span(def_id); @@ -541,7 +541,7 @@ fn build_call_shim<'tcx>( assert_eq!(sig_substs.is_some(), !instance.has_polymorphic_mir_body()); if let Some(sig_substs) = sig_substs { - sig = sig.subst(tcx, sig_substs); + sig = EarlyBinder(sig).subst(tcx, sig_substs); } if let CallKind::Indirect(fnty) = call_kind { diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index c8fdf363f053e..a38bf9f0cae9a 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -9,7 +9,9 @@ use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::print::{Print, Printer}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; -use rustc_middle::ty::{self, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeFoldable, UintTy}; +use rustc_middle::ty::{ + self, EarlyBinder, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeFoldable, UintTy, +}; use rustc_span::symbol::kw; use rustc_target::abi::call::FnAbi; use rustc_target::abi::Integer; @@ -297,7 +299,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { let mut param_env = self.tcx.param_env_reveal_all_normalized(impl_def_id); if !substs.is_empty() { - param_env = param_env.subst(self.tcx, substs); + param_env = EarlyBinder(param_env).subst(self.tcx, substs); } match &mut impl_trait_ref { diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 24110d30a8456..e584cac57f1f8 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -23,7 +23,7 @@ use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{self, TreatParams}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, ImplSubject, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::fmt::Debug; @@ -135,8 +135,8 @@ fn with_fresh_ty_vars<'cx, 'tcx>( let header = ty::ImplHeader { impl_def_id, - self_ty: tcx.type_of(impl_def_id).subst(tcx, impl_substs), - trait_ref: tcx.impl_trait_ref(impl_def_id).subst(tcx, impl_substs), + self_ty: EarlyBinder(tcx.type_of(impl_def_id)).subst(tcx, impl_substs), + trait_ref: EarlyBinder(tcx.impl_trait_ref(impl_def_id)).subst(tcx, impl_substs), predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates, }; diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 5daa9796d12e4..27ce08ea0453f 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -19,7 +19,7 @@ use rustc_middle::mir::interpret::{ use rustc_middle::thir; use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable}; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, DelaySpanBugEmitted, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, DelaySpanBugEmitted, EarlyBinder, TyCtxt, TypeFoldable}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::Span; @@ -263,8 +263,10 @@ impl<'tcx> AbstractConst<'tcx> { pub fn root(self, tcx: TyCtxt<'tcx>) -> Node<'tcx> { let node = self.inner.last().copied().unwrap(); match node { - Node::Leaf(leaf) => Node::Leaf(leaf.subst(tcx, self.substs)), - Node::Cast(kind, operand, ty) => Node::Cast(kind, operand, ty.subst(tcx, self.substs)), + Node::Leaf(leaf) => Node::Leaf(EarlyBinder(leaf).subst(tcx, self.substs)), + Node::Cast(kind, operand, ty) => { + Node::Cast(kind, operand, EarlyBinder(ty).subst(tcx, self.substs)) + } // Don't perform substitution on the following as they can't directly contain generic params Node::Binop(_, _, _) | Node::UnaryOp(_, _) | Node::FunctionCall(_, _) => node, } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 9e9c230aebb85..86c93867c759e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -5,7 +5,7 @@ use crate::infer::InferCtxt; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, GenericParamDefKind}; +use rustc_middle::ty::{self, EarlyBinder, GenericParamDefKind}; use rustc_span::symbol::sym; use std::iter; @@ -45,7 +45,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| { let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id); - let impl_trait_ref = tcx.impl_trait_ref(def_id).unwrap().subst(tcx, impl_substs); + let impl_trait_ref = + EarlyBinder(tcx.impl_trait_ref(def_id).unwrap()).subst(tcx, impl_substs); let impl_self_ty = impl_trait_ref.self_ty(); diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index e1b6ed92269ca..e3e384798d301 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -18,7 +18,7 @@ use rustc_errors::{FatalError, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, InternalSubsts, Subst}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{Predicate, ToPredicate}; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_span::symbol::Symbol; @@ -531,7 +531,7 @@ fn receiver_for_self_ty<'tcx>( if param.index == 0 { self_ty.into() } else { tcx.mk_param_from_def(param) } }); - let result = receiver_ty.subst(tcx, substs); + let result = EarlyBinder(receiver_ty).subst(tcx, substs); debug!( "receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}", receiver_ty, self_ty, method_def_id, result diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index be4d734b964b8..058308420ed09 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -31,7 +31,7 @@ use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::fold::{MaxUniverse, TypeFoldable, TypeFolder}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, Term, ToPredicate, Ty, TyCtxt}; use rustc_span::symbol::sym; use std::collections::BTreeMap; @@ -516,7 +516,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { let substs = substs.super_fold_with(self); let generic_ty = self.tcx().type_of(def_id); - let concrete_ty = generic_ty.subst(self.tcx(), substs); + let concrete_ty = EarlyBinder(generic_ty).subst(self.tcx(), substs); self.depth += 1; let folded_ty = self.fold_ty(concrete_ty); self.depth -= 1; @@ -1276,8 +1276,10 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( // Check whether the self-type is itself a projection. // If so, extract what we know from the trait and try to come up with a good answer. let bounds = match *obligation.predicate.self_ty().kind() { - ty::Projection(ref data) => tcx.item_bounds(data.item_def_id).subst(tcx, data.substs), - ty::Opaque(def_id, substs) => tcx.item_bounds(def_id).subst(tcx, substs), + ty::Projection(ref data) => { + EarlyBinder(tcx.item_bounds(data.item_def_id)).subst(tcx, data.substs) + } + ty::Opaque(def_id, substs) => EarlyBinder(tcx.item_bounds(def_id)).subst(tcx, substs), ty::Infer(ty::TyVar(_)) => { // If the self-type is an inference variable, then it MAY wind up // being a projected type, so induce an ambiguity. @@ -2032,7 +2034,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( Progress { term: err.into(), obligations: nested } } else { assoc_ty_own_obligations(selcx, obligation, &mut nested); - Progress { term: term.subst(tcx, substs), obligations: nested } + Progress { term: EarlyBinder(term).subst(tcx, substs), obligations: nested } } } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index ed0ad5601aa40..10e64eed3b8c7 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -14,7 +14,7 @@ use rustc_infer::traits::Normalized; use rustc_middle::mir; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitor}; use std::ops::ControlFlow; @@ -218,7 +218,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { } let generic_ty = self.tcx().type_of(def_id); - let concrete_ty = generic_ty.subst(self.tcx(), substs); + let concrete_ty = EarlyBinder(generic_ty).subst(self.tcx(), substs); self.anon_depth += 1; if concrete_ty == ty { bug!( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 771a3072af5d9..e6f9fbc6c03be 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -12,7 +12,7 @@ use rustc_index::bit_set::GrowableBitSet; use rustc_infer::infer::InferOk; use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{self, GenericParamDefKind, Ty}; +use rustc_middle::ty::{self, EarlyBinder, GenericParamDefKind, Ty}; use rustc_middle::ty::{ToPolyTraitRef, ToPredicate}; use rustc_span::def_id::DefId; @@ -174,7 +174,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), }; - let candidate_predicate = tcx.item_bounds(def_id)[idx].subst(tcx, substs); + let candidate_predicate = EarlyBinder(tcx.item_bounds(def_id)[idx]).subst(tcx, substs); let candidate = candidate_predicate .to_opt_poly_trait_pred() .expect("projection candidate is not a trait predicate") @@ -501,20 +501,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // higher-ranked things. // Prevent, e.g., `dyn Iterator`. for bound in self.tcx().item_bounds(assoc_type) { - let subst_bound = - if defs.count() == 0 { - bound.subst(tcx, trait_predicate.trait_ref.substs) - } else { - let mut substs = smallvec::SmallVec::with_capacity(defs.count()); - substs.extend(trait_predicate.trait_ref.substs.iter()); - let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = - smallvec::SmallVec::with_capacity( - bound.kind().bound_vars().len() + defs.count(), - ); - bound_vars.extend(bound.kind().bound_vars().into_iter()); - InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param - .kind - { + let subst_bound = if defs.count() == 0 { + EarlyBinder(bound).subst(tcx, trait_predicate.trait_ref.substs) + } else { + let mut substs = smallvec::SmallVec::with_capacity(defs.count()); + substs.extend(trait_predicate.trait_ref.substs.iter()); + let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = + smallvec::SmallVec::with_capacity( + bound.kind().bound_vars().len() + defs.count(), + ); + bound_vars.extend(bound.kind().bound_vars().into_iter()); + InternalSubsts::fill_single( + &mut substs, + defs, + &mut |param, _| match param.kind { GenericParamDefKind::Type { .. } => { let kind = ty::BoundTyKind::Param(param.name); let bound_var = ty::BoundVariableKind::Ty(kind); @@ -553,14 +553,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) .into() } - }); - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); - let assoc_ty_substs = tcx.intern_substs(&substs); - - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); - let bound = bound.kind().skip_binder().subst(tcx, assoc_ty_substs); - tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars)) - }; + }, + ); + let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let assoc_ty_substs = tcx.intern_substs(&substs); + + let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let bound = EarlyBinder(bound.kind().skip_binder()).subst(tcx, assoc_ty_substs); + tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars)) + }; let normalized_bound = normalize_with_depth_to( self, obligation.param_env, @@ -1029,8 +1030,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } // Extract `TailField` and `TailField` from `Struct` and `Struct`. - let source_tail = tail_field_ty.subst(tcx, substs_a); - let target_tail = tail_field_ty.subst(tcx, substs_b); + let source_tail = EarlyBinder(tail_field_ty).subst(tcx, substs_a); + let target_tail = EarlyBinder(tail_field_ty).subst(tcx, substs_b); // Check that the source struct with the target's // unsizing parameters is equal to the target. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6584d33032a46..8bab8353ab68d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -38,7 +38,7 @@ use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef}; -use rustc_middle::ty::{self, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate}; +use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate}; use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable}; use rustc_span::symbol::sym; @@ -1341,7 +1341,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); } }; - let bounds = tcx.item_bounds(def_id).subst(tcx, substs); + let bounds = EarlyBinder(tcx.item_bounds(def_id)).subst(tcx, substs); // The bounds returned by `item_bounds` may contain duplicates after // normalization, so try to deduplicate when possible to avoid @@ -1795,11 +1795,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::Adt(def, substs) => { let sized_crit = def.sized_constraint(self.tcx()); // (*) binder moved here - Where( - obligation.predicate.rebind({ - sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect() - }), - ) + Where(obligation.predicate.rebind({ + sized_crit.iter().map(|ty| EarlyBinder(*ty).subst(self.tcx(), substs)).collect() + })) } ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None, @@ -1962,7 +1960,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - t.rebind(vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)]) + t.rebind(vec![EarlyBinder(self.tcx().type_of(def_id)).subst(self.tcx(), substs)]) } } } @@ -2083,7 +2081,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); - let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); + let impl_trait_ref = EarlyBinder(impl_trait_ref).subst(self.tcx(), impl_substs); debug!(?impl_trait_ref); @@ -2332,7 +2330,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { param_env, cause.clone(), recursion_depth, - predicate.subst(tcx, substs), + EarlyBinder(*predicate).subst(tcx, substs), &mut obligations, ); obligations.push(Obligation { cause, recursion_depth, param_env, predicate }); diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 49c8c56083f08..b6a4d100341dd 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -20,7 +20,7 @@ use rustc_errors::{struct_span_err, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{self, ImplSubject, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, ImplSubject, TyCtxt}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; use rustc_span::{Span, DUMMY_SP}; @@ -84,8 +84,8 @@ pub fn translate_substs<'a, 'tcx>( "translate_substs({:?}, {:?}, {:?}, {:?})", param_env, source_impl, source_substs, target_node ); - let source_trait_ref = - infcx.tcx.impl_trait_ref(source_impl).unwrap().subst(infcx.tcx, &source_substs); + let source_trait_ref = EarlyBinder(infcx.tcx.impl_trait_ref(source_impl).unwrap()) + .subst(infcx.tcx, &source_substs); // translate the Self and Param parts of the substitution, since those // vary across impls diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index d101f69096fe8..f2e31c068a0d3 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -6,7 +6,7 @@ use smallvec::SmallVec; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef}; -use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, EarlyBinder, ImplSubject, ToPredicate, Ty, TyCtxt, TypeFoldable}; use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; pub use rustc_infer::traits::{self, util::*}; @@ -201,7 +201,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( impl_substs: SubstsRef<'tcx>, ) -> (ImplSubject<'tcx>, impl Iterator>) { let subject = selcx.tcx().impl_subject(impl_def_id); - let subject = subject.subst(selcx.tcx(), impl_substs); + let subject = EarlyBinder(subject).subst(selcx.tcx(), impl_substs); let Normalized { value: subject, obligations: normalization_obligations1 } = super::normalize(selcx, param_env, ObligationCause::dummy(), subject); diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 6424b90747876..4288ddeaed003 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -8,7 +8,9 @@ use rustc_middle::traits::ChalkRustInterner as RustInterner; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{self, AssocItemContainer, AssocKind, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{ + self, AssocItemContainer, AssocKind, EarlyBinder, Ty, TyCtxt, TypeFoldable, +}; use rustc_ast::ast; use rustc_attr as attr; @@ -41,7 +43,7 @@ impl<'tcx> RustIrDatabase<'tcx> { let predicates = self.interner.tcx.predicates_defined_on(def_id).predicates; predicates .iter() - .map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars)) + .map(|(wc, _)| EarlyBinder(*wc).subst(self.interner.tcx, bound_vars)) .filter_map(|wc| LowerInto::< Option>> >::lower_into(wc, self.interner)).collect() @@ -55,7 +57,7 @@ impl<'tcx> RustIrDatabase<'tcx> { .tcx .explicit_item_bounds(def_id) .iter() - .map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars)) + .map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars)) .filter_map(|bound| LowerInto::>::lower_into(bound, self.interner)) .collect() } @@ -272,15 +274,17 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars( self.interner, self.interner.tcx, - sig.inputs_and_output().subst(self.interner.tcx, bound_vars), + EarlyBinder(sig.inputs_and_output()).subst(self.interner.tcx, bound_vars), ); let argument_types = inputs_and_output[..inputs_and_output.len() - 1] .iter() - .map(|t| t.subst(self.interner.tcx, &bound_vars).lower_into(self.interner)) + .map(|t| { + EarlyBinder(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner) + }) .collect(); - let return_type = inputs_and_output[inputs_and_output.len() - 1] + let return_type = EarlyBinder(inputs_and_output[inputs_and_output.len() - 1]) .subst(self.interner.tcx, &bound_vars) .lower_into(self.interner); @@ -307,7 +311,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let binders = binders_for(self.interner, bound_vars); let trait_ref = self.interner.tcx.impl_trait_ref(def_id).expect("not an impl"); - let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars); + let trait_ref = EarlyBinder(trait_ref).subst(self.interner.tcx, bound_vars); let where_clauses = self.where_clauses_for(def_id, bound_vars); @@ -352,7 +356,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let bound_vars = bound_vars_for_item(self.interner.tcx, *impl_def_id); let self_ty = trait_ref.self_ty(); - let self_ty = self_ty.subst(self.interner.tcx, bound_vars); + let self_ty = EarlyBinder(self_ty).subst(self.interner.tcx, bound_vars); let lowered_ty = self_ty.lower_into(self.interner); parameters[0].assert_ty_ref(self.interner).could_match( @@ -460,10 +464,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let trait_item_id = assoc_item.trait_item_def_id.expect("assoc_ty with no trait version"); let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(self.interner, bound_vars); - let ty = self - .interner - .tcx - .type_of(def_id) + let ty = EarlyBinder(self.interner.tcx.type_of(def_id)) .subst(self.interner.tcx, bound_vars) .lower_into(self.interner); @@ -506,7 +507,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .tcx .explicit_item_bounds(opaque_ty_id.0) .iter() - .map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars)) + .map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars)) .map(|bound| { bound.fold_with(&mut ReplaceOpaqueTyFolder { tcx: self.interner.tcx, diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index e4c22a354232b..3fd0bb1814a65 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -5,7 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::{InternalSubsts, Subst}; -use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt}; use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_trait_selection::traits::query::dropck_outlives::trivial_dropck_outlives; use rustc_trait_selection::traits::query::dropck_outlives::{ @@ -271,9 +271,15 @@ fn dtorck_constraint_for_ty<'tcx>( tcx.at(span).adt_dtorck_constraint(def.did())?; // FIXME: we can try to recursively `dtorck_constraint_on_ty` // there, but that needs some way to handle cycles. - constraints.dtorck_types.extend(dtorck_types.iter().map(|t| t.subst(tcx, substs))); - constraints.outlives.extend(outlives.iter().map(|t| t.subst(tcx, substs))); - constraints.overflows.extend(overflows.iter().map(|t| t.subst(tcx, substs))); + constraints + .dtorck_types + .extend(dtorck_types.iter().map(|t| EarlyBinder(*t).subst(tcx, substs))); + constraints + .outlives + .extend(outlives.iter().map(|t| EarlyBinder(*t).subst(tcx, substs))); + constraints + .overflows + .extend(overflows.iter().map(|t| EarlyBinder(*t).subst(tcx, substs))); } // Objects must be alive in order for their destructor diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 6fcac9fcdc622..861d3bc564fca 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -6,7 +6,9 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::{GenericArg, Subst, UserSelfTy, UserSubsts}; -use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable, Variance}; +use rustc_middle::ty::{ + self, EarlyBinder, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable, Variance, +}; use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Predicate, ToPredicate}; use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtBuilderExt; @@ -115,7 +117,7 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { where T: TypeFoldable<'tcx>, { - value.subst(self.tcx(), substs) + EarlyBinder(value).subst(self.tcx(), substs) } fn relate_mir_and_user_ty( diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index c5fc4e4c66105..d2d6386806b1c 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; use rustc_session::Limit; use rustc_span::{sym, DUMMY_SP}; @@ -204,7 +204,7 @@ fn drop_tys_helper<'tcx>( match subty.kind() { ty::Adt(adt_id, subst) => { for subty in tcx.adt_drop_tys(adt_id.did())? { - vec.push(subty.subst(tcx, subst)); + vec.push(EarlyBinder(subty).subst(tcx, subst)); } } _ => vec.push(subty), @@ -237,7 +237,7 @@ fn drop_tys_helper<'tcx>( Ok(Vec::new()) } else { let field_tys = adt_def.all_fields().map(|field| { - let r = tcx.type_of(field.did).subst(tcx, substs); + let r = EarlyBinder(tcx.type_of(field.did)).subst(tcx, substs); debug!("drop_tys_helper: Subst into {:?} with {:?} gettng {:?}", field, substs, r); r }); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 6ad71bdb48169..a8aac5da09cc1 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -2,7 +2,9 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{ + self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, +}; use rustc_span::{sym, Span}; use rustc_trait_selection::traits; @@ -33,7 +35,7 @@ fn sized_constraint_for_ty<'tcx>( debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); adt_tys .iter() - .map(|ty| ty.subst(tcx, substs)) + .map(|ty| EarlyBinder(*ty).subst(tcx, substs)) .flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty)) .collect() } @@ -442,7 +444,7 @@ pub fn conservative_is_privately_uninhabited_raw<'tcx>( // one uninhabited field. def.variants().iter().all(|var| { var.fields.iter().any(|field| { - let ty = tcx.type_of(field.did).subst(tcx, substs); + let ty = EarlyBinder(tcx.type_of(field.did)).subst(tcx, substs); tcx.conservative_is_privately_uninhabited(param_env.and(ty)) }) }) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index e940d065a9994..aa7346129f287 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -26,7 +26,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{GenericArg, GenericArgs}; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, Const, DefIdTree, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, Const, DefIdTree, EarlyBinder, Ty, TyCtxt, TypeFoldable}; use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS}; use rustc_span::edition::Edition; use rustc_span::lev_distance::find_best_match_for_name; @@ -523,7 +523,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.astconv .normalize_ty( self.span, - tcx.at(self.span).type_of(param.def_id).subst(tcx, substs), + EarlyBinder(tcx.at(self.span).type_of(param.def_id)) + .subst(tcx, substs), ) .into() } @@ -543,7 +544,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { GenericParamDefKind::Const { has_default } => { let ty = tcx.at(self.span).type_of(param.def_id); if !infer_args && has_default { - tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into() + EarlyBinder(tcx.const_param_default(param.def_id)) + .subst(tcx, substs.unwrap()) + .into() } else { if infer_args { self.astconv.ct_infer(ty, Some(param), self.span).into() @@ -1292,7 +1295,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment: &hir::PathSegment<'_>, ) -> Ty<'tcx> { let substs = self.ast_path_substs_for_ty(span, did, item_segment); - self.normalize_ty(span, self.tcx().at(span).type_of(did).subst(self.tcx(), substs)) + self.normalize_ty( + span, + EarlyBinder(self.tcx().at(span).type_of(did)).subst(self.tcx(), substs), + ) } fn conv_object_ty_poly_trait_ref( @@ -2441,7 +2447,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { true, None, ); - self.normalize_ty(span, tcx.at(span).type_of(def_id).subst(tcx, substs)) + self.normalize_ty( + span, + EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs), + ) } hir::TyKind::Array(ref ty, ref length) => { let length = match length { @@ -2684,7 +2693,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_ref.def_id, )?; - let fn_sig = tcx.fn_sig(assoc.def_id).subst( + let fn_sig = EarlyBinder(tcx.fn_sig(assoc.def_id)).subst( tcx, trait_ref.substs.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)), ); diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index 90b59df472cad..f8e82647b2144 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, }; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFoldable}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_target::spec::abi; @@ -339,7 +339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { let (fn_sig, def_id) = match *callee_ty.kind() { ty::FnDef(def_id, subst) => { - let fn_sig = self.tcx.fn_sig(def_id).subst(self.tcx, subst); + let fn_sig = EarlyBinder(self.tcx.fn_sig(def_id)).subst(self.tcx, subst); // Unit testing: function items annotated with // `#[rustc_evaluate_where_clauses]` trigger special output diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 4627b58c9bcd3..1d962064bd934 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{self, ParamEnv, ToPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, ParamEnv, ToPredicate, Ty, TyCtxt}; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; use rustc_span::{self, Span}; @@ -171,7 +171,7 @@ pub(super) fn check_fn<'a, 'tcx>( let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span)); let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span)); - Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()])) + Some(EarlyBinder(tcx.type_of(va_list_did)).subst(tcx, &[region.into()])) } else { None }; @@ -655,7 +655,7 @@ fn check_opaque_meets_bounds<'tcx>( span: Span, origin: &hir::OpaqueTyOrigin, ) { - let hidden_type = tcx.type_of(def_id).subst(tcx, substs); + let hidden_type = EarlyBinder(tcx.type_of(def_id)).subst(tcx, substs); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let defining_use_anchor = match *origin { diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 50e55bdc4af30..df10853bf5038 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -12,7 +12,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::{InferOk, InferResult}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, EarlyBinder, Ty}; use rustc_span::source_map::Span; use rustc_span::DUMMY_SP; use rustc_target::spec::abi::Abi; @@ -180,7 +180,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Projection(proj_predicate) => self .deduce_sig_from_projection( Some(*span), - pred.kind().rebind(proj_predicate.subst(self.tcx, substs)), + pred.kind().rebind(EarlyBinder(proj_predicate).subst(self.tcx, substs)), ), _ => None, }); @@ -677,7 +677,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // where R is the return type we are expecting. This type `T` // will be our output. let output_ty = item_bounds.iter().find_map(|&(predicate, span)| { - let bound_predicate = predicate.subst(self.tcx, substs).kind(); + let bound_predicate = EarlyBinder(predicate).subst(self.tcx, substs).kind(); if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() { self.deduce_future_output_from_projection( span, diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index a83924d4636c5..eff009d0e8ba7 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -10,7 +10,7 @@ use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::util::ExplicitSelf; -use rustc_middle::ty::{self, DefIdTree}; +use rustc_middle::ty::{self, DefIdTree, EarlyBinder}; use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::InferCtxtExt; @@ -267,7 +267,7 @@ fn compare_predicate_entailment<'tcx>( // First liberate late bound regions and subst placeholders let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(trait_m.def_id)); - let trait_sig = trait_sig.subst(tcx, trait_to_placeholder_substs); + let trait_sig = EarlyBinder(trait_sig).subst(tcx, trait_to_placeholder_substs); let trait_sig = inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, trait_sig); // Add the resulting inputs and output as well-formed. @@ -1066,7 +1066,7 @@ crate fn compare_const_impl<'tcx>( // Compute placeholder form of impl and trait const tys. let impl_ty = tcx.type_of(impl_c.def_id); - let trait_ty = tcx.type_of(trait_c.def_id).subst(tcx, trait_to_impl_substs); + let trait_ty = EarlyBinder(tcx.type_of(trait_c.def_id)).subst(tcx, trait_to_impl_substs); let mut cause = ObligationCause::new( impl_c_span, impl_c_hir_id, @@ -1456,7 +1456,7 @@ pub fn check_type_bounds<'tcx>( .iter() .map(|&(bound, span)| { debug!(?bound); - let concrete_ty_bound = bound.subst(tcx, rebased_substs); + let concrete_ty_bound = EarlyBinder(bound).subst(tcx, rebased_substs); debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound) diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 3bc92166543d4..9caa4a40df71f 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -8,7 +8,7 @@ use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, Predicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, Predicate, Ty, TyCtxt}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::InferCtxtExt; use rustc_trait_selection::traits::query::dropck_outlives::AtExt; @@ -84,7 +84,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( let drop_impl_span = tcx.def_span(drop_impl_did); let fresh_impl_substs = infcx.fresh_substs_for_item(drop_impl_span, drop_impl_did.to_def_id()); - let fresh_impl_self_ty = drop_impl_ty.subst(tcx, fresh_impl_substs); + let fresh_impl_self_ty = EarlyBinder(drop_impl_ty).subst(tcx, fresh_impl_substs); let cause = &ObligationCause::misc(drop_impl_span, drop_impl_hir_id); match infcx.at(cause, impl_param_env).eq(named_type, fresh_impl_self_ty) { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index d824c1d7cf252..e1cfa9bd6e7d1 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -23,8 +23,8 @@ use rustc_middle::ty::subst::{ self, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts, }; use rustc_middle::ty::{ - self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, ToPolyTraitRef, ToPredicate, - Ty, UserType, + self, AdtKind, CanonicalUserType, DefIdTree, EarlyBinder, GenericParamDefKind, ToPolyTraitRef, + ToPredicate, Ty, UserType, }; use rustc_session::lint; use rustc_span::hygiene::DesugaringKind; @@ -347,7 +347,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { T: TypeFoldable<'tcx>, { debug!("instantiate_type_scheme(value={:?}, substs={:?})", value, substs); - let value = value.subst(self.tcx, substs); + let value = EarlyBinder(value).subst(self.tcx, substs); let result = self.normalize_associated_types_in(span, value); debug!("instantiate_type_scheme = {:?}", result); result @@ -843,7 +843,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.type_of(def_id) }; let substs = self.infcx.fresh_substs_for_item(span, def_id); - let ty = item_ty.subst(self.tcx, substs); + let ty = EarlyBinder(item_ty).subst(self.tcx, substs); self.write_resolution(hir_id, Ok((def_kind, def_id))); self.add_required_obligations_with_code( @@ -1044,8 +1044,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let (sig, did, substs) = match (&expected.kind(), &found.kind()) { (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => { - let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1); - let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2); + let sig1 = EarlyBinder(self.tcx.fn_sig(*did1)).subst(self.tcx, substs1); + let sig2 = EarlyBinder(self.tcx.fn_sig(*did2)).subst(self.tcx, substs2); if sig1 != sig2 { return; } @@ -1056,7 +1056,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (sig1, *did1, substs1) } (ty::FnDef(did, substs), ty::FnPtr(sig2)) => { - let sig1 = self.tcx.fn_sig(*did).subst(self.tcx, substs); + let sig1 = EarlyBinder(self.tcx.fn_sig(*did)).subst(self.tcx, substs); if sig1 != *sig2 { return; } @@ -1403,7 +1403,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // is missing. let default = tcx.type_of(param.def_id); self.fcx - .normalize_ty(self.span, default.subst(tcx, substs.unwrap())) + .normalize_ty( + self.span, + EarlyBinder(default).subst(tcx, substs.unwrap()), + ) .into() } else { // If no type arguments were provided, we have to infer them. @@ -1415,7 +1418,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } GenericParamDefKind::Const { has_default } => { if !infer_args && has_default { - tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into() + EarlyBinder(tcx.const_param_default(param.def_id)) + .subst(tcx, substs.unwrap()) + .into() } else { self.fcx.var_for_def(self.span, param) } diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 0dd8ee88ca2ad..2cca899c8e4ef 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -11,7 +11,7 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; @@ -129,7 +129,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ty::INNERMOST, ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv }, )); - let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]); + let va_list_ty = EarlyBinder(tcx.type_of(did)).subst(tcx, &[region.into()]); (tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty) }) }; diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 1b619776b857c..edd4cf91c2467 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::{self, Subst, SubstsRef}; -use rustc_middle::ty::{self, GenericParamDefKind, Ty}; +use rustc_middle::ty::{self, EarlyBinder, GenericParamDefKind, Ty}; use rustc_span::Span; use rustc_trait_selection::traits; @@ -462,7 +462,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let sig = self.tcx.fn_sig(def_id); - let sig = sig.subst(self.tcx, all_substs); + let sig = EarlyBinder(sig).subst(self.tcx, all_substs); debug!("type scheme substituted, sig={:?}", sig); let sig = self.replace_bound_vars_with_fresh_vars(sig); diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 1dd5e45fdc174..a5194e4c135ce 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -21,7 +21,7 @@ use rustc_infer::infer::{self, InferOk}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable}; +use rustc_middle::ty::{self, EarlyBinder, ToPredicate, Ty, TypeFoldable}; use rustc_span::symbol::Ident; use rustc_span::Span; use rustc_trait_selection::traits; @@ -461,7 +461,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // `instantiate_type_scheme` can normalize associated types that // may reference those regions. let fn_sig = tcx.fn_sig(def_id); - let fn_sig = fn_sig.subst(self.tcx, substs); + let fn_sig = EarlyBinder(fn_sig).subst(self.tcx, substs); let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig).0; let InferOk { value, obligations: o } = if is_op { diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index c28ab9fa1ee40..5edd9a5b8d645 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -21,7 +21,7 @@ use rustc_middle::middle::stability; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::lev_distance::{ @@ -711,7 +711,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id); - let impl_ty = impl_ty.subst(self.tcx, impl_substs); + let impl_ty = EarlyBinder(impl_ty).subst(self.tcx, impl_substs); debug!("impl_ty: {:?}", impl_ty); @@ -904,7 +904,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let fty = self.tcx.fn_sig(method.def_id); self.probe(|_| { let substs = self.fresh_substs_for_item(self.span, method.def_id); - let fty = fty.subst(self.tcx, substs); + let fty = EarlyBinder(fty).subst(self.tcx, substs); let (fty, _) = self.replace_bound_vars_with_fresh_vars(self.span, infer::FnCall, fty); @@ -1785,7 +1785,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { assert_eq!(substs.len(), generics.parent_count as usize); let xform_fn_sig = if generics.params.is_empty() { - fn_sig.subst(self.tcx, substs) + EarlyBinder(fn_sig).subst(self.tcx, substs) } else { let substs = InternalSubsts::for_item(self.tcx, method, |param, _| { let i = param.index as usize; @@ -1803,7 +1803,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } }); - fn_sig.subst(self.tcx, substs) + EarlyBinder(fn_sig).subst(self.tcx, substs) }; self.erase_late_bound_regions(xform_fn_sig) diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 829485367e0a4..50966868ec7d9 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -21,7 +21,8 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst}; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ - self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitor, + self, AdtKind, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, + TypeVisitor, }; use rustc_session::parse::feature_err; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -1388,7 +1389,7 @@ fn check_where_clauses<'tcx, 'fcx>( } let mut param_count = CountParams::default(); let has_region = pred.visit_with(&mut param_count).is_break(); - let substituted_pred = pred.subst(tcx, substs); + let substituted_pred = EarlyBinder(pred).subst(tcx, substs); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. if substituted_pred.has_param_types_or_consts() diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 13d22b13ed4f1..52f9e386441a4 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; use rustc_span::Span; use super::explicit::ExplicitPredicatesMap; @@ -137,7 +137,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( // `unsubstituted_predicate` is `U: 'b` in the // example above. So apply the substitution to // get `T: 'a` (or `predicate`): - let predicate = unsubstituted_predicate.subst(tcx, substs); + let predicate = EarlyBinder(*unsubstituted_predicate).subst(tcx, substs); insert_outlives_predicate( tcx, predicate.0, @@ -287,7 +287,7 @@ pub fn check_explicit_predicates<'tcx>( continue; } - let predicate = outlives_predicate.subst(tcx, substs); + let predicate = EarlyBinder(*outlives_predicate).subst(tcx, substs); debug!("predicate = {:?}", &predicate); insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates); } diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index f0d87f7ce4cd5..c8cd0931c3ff8 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -38,11 +38,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { let is_param = matches!(trait_ref.self_ty().kind(), ty::Param(_)); let may_apply = is_param && cx.tcx.infer_ctxt().enter(|infcx| { let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id); - let ty = ty.subst(infcx.tcx, substs); - let param_env = param_env.subst(infcx.tcx, substs); + let ty = EarlyBinder(ty).subst(infcx.tcx, substs); + let param_env = EarlyBinder(param_env).subst(infcx.tcx, substs); let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); - let trait_ref = trait_ref.subst(infcx.tcx, impl_substs); + let trait_ref = EarlyBinder(trait_ref).subst(infcx.tcx, impl_substs); // Require the type the impl is implemented on to match // our type, and ignore the impl if there was a mismatch. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7cc96183d6da4..6e18f381c59a4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -21,7 +21,7 @@ use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_middle::middle::resolve_lifetime as rl; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::subst::{InternalSubsts, Subst}; -use rustc_middle::ty::{self, AdtKind, DefIdTree, Lift, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtKind, DefIdTree, EarlyBinder, Lift, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::hygiene::{AstPass, MacroKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1634,7 +1634,7 @@ impl<'tcx> Clean for Ty<'tcx> { .tcx .explicit_item_bounds(def_id) .iter() - .map(|(bound, _)| bound.subst(cx.tcx, substs)) + .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, substs)) .collect::>(); let mut regions = vec![]; let mut has_sized = false; diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 1b19868e4c70f..b7776b3f0c38b 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -12,7 +12,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::binding::BindingMode; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, ClosureKind, Ty, TypeFoldable}; +use rustc_middle::ty::{self, ClosureKind, EarlyBinder, Ty, TypeFoldable}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; @@ -150,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { if check_inputs(cx, body.params, args); let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap(); let substs = cx.typeck_results().node_substs(body.value.hir_id); - let call_ty = cx.tcx.type_of(method_def_id).subst(cx.tcx, substs); + let call_ty = EarlyBinder(cx.tcx.type_of(method_def_id)).subst(cx.tcx, substs); if check_sig(cx, closure_ty, call_ty); then { span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure", |diag| { diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 43911a313d5a6..5c46d6c7df705 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -5,7 +5,7 @@ use rustc_hir::{Body, FnDecl, HirId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{Opaque, PredicateKind::Trait}; +use rustc_middle::ty::{EarlyBinder, Opaque, PredicateKind::Trait}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, Span}; use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt; @@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { let preds = cx.tcx.explicit_item_bounds(id); let mut is_future = false; for &(p, _span) in preds { - let p = p.subst(cx.tcx, subst); + let p = EarlyBinder(p).subst(cx.tcx, subst); if let Some(trait_pred) = p.to_opt_poly_trait_pred() { if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() { is_future = true; diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index 5c3e505c06c47..a323737ae404e 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, EarlyBinder, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::iter; @@ -48,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { ExprKind::MethodCall(path, arguments, _) => { let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap(); let substs = cx.typeck_results().node_substs(e.hir_id); - let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); + let method_type = EarlyBinder(cx.tcx.type_of(def_id)).subst(cx.tcx, substs); check_arguments(cx, arguments, method_type, path.ident.as_str(), "method"); }, _ => (), diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index f5e21267a8976..0bb577b7620b1 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -4,7 +4,7 @@ use clippy_utils::ty::is_c_void; use rustc_hir::Expr; use rustc_lint::LateContext; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, IntTy, Ty, TypeAndMut, UintTy}; +use rustc_middle::ty::{self, EarlyBinder, IntTy, Ty, TypeAndMut, UintTy}; use rustc_span::Span; #[allow(clippy::too_many_lines)] @@ -307,7 +307,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> .non_enum_variant() .fields .iter() - .map(|f| cx.tcx.type_of(f.did).subst(cx.tcx, substs)); + .map(|f| EarlyBinder(cx.tcx.type_of(f.did)).subst(cx.tcx, substs)); let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else { return ReducedTy::TypeErasure; }; diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index fdb822c3e5b6d..a80c7ee492958 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -9,7 +9,7 @@ use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, Item, ItemKind, use rustc_lint::LateContext; use rustc_middle::mir::interpret::Scalar; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, FloatTy, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Symbol; use std::cmp::Ordering::{self, Equal}; @@ -420,7 +420,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { let substs = if self.substs.is_empty() { substs } else { - substs.subst(self.lcx.tcx, self.substs) + EarlyBinder(substs).subst(self.lcx.tcx, self.substs) }; let result = self diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 901e3e5390c5d..b46a7b86a7590 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -13,7 +13,7 @@ use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; use rustc_middle::ty::{ - self, AdtDef, Binder, FnSig, IntTy, Predicate, PredicateKind, Ty, TyCtxt, TypeFoldable, UintTy, VariantDiscr, + self, AdtDef, Binder, EarlyBinder, FnSig, IntTy, Predicate, PredicateKind, Ty, TyCtxt, TypeFoldable, UintTy, VariantDiscr, }; use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; @@ -520,7 +520,7 @@ pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option Some(ExprFnSig::Closure(subs.as_closure().sig())), - ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).subst(cx.tcx, subs))), + ty::FnDef(id, subs) => Some(ExprFnSig::Sig(EarlyBinder(cx.tcx.fn_sig(id)).subst(cx.tcx, subs))), ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig)), ty::Dynamic(bounds, _) => { let lang_items = cx.tcx.lang_items(); From c92248ab9f2045c5a85700b59176bc850caaa3ef Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Sun, 8 May 2022 15:12:56 -0400 Subject: [PATCH 2/6] Add bound_type_of --- .../rustc_borrowck/src/universal_regions.rs | 9 +++++---- .../interpret/intrinsics/caller_location.rs | 9 ++++----- .../src/infer/error_reporting/mod.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 4 ++-- compiler/rustc_middle/src/mir/tcx.rs | 4 ++-- compiler/rustc_middle/src/ty/context.rs | 13 ++++++------- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/mod.rs | 19 +++++++++++-------- compiler/rustc_middle/src/ty/relate.rs | 6 +++--- compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 8 ++++++-- .../rustc_mir_build/src/build/matches/test.rs | 6 +++--- compiler/rustc_mir_build/src/build/mod.rs | 5 ++--- compiler/rustc_mir_transform/src/generator.rs | 6 ++++-- .../src/traits/coherence.rs | 2 +- .../src/traits/project.rs | 4 ++-- .../src/traits/query/normalize.rs | 6 +++--- .../src/traits/select/confirmation.rs | 8 ++++---- .../src/traits/select/mod.rs | 2 +- compiler/rustc_traits/src/chalk/db.rs | 5 ++++- compiler/rustc_ty_utils/src/needs_drop.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- compiler/rustc_typeck/src/check/check.rs | 6 +++--- .../rustc_typeck/src/check/compare_method.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 13 +++++-------- compiler/rustc_typeck/src/check/intrinsic.rs | 4 ++-- src/librustdoc/clean/blanket_impl.rs | 10 +++++----- .../clippy/clippy_lints/src/eta_reduction.rs | 4 ++-- .../clippy/clippy_lints/src/mut_reference.rs | 4 ++-- .../src/transmute/transmute_undefined_repr.rs | 4 ++-- 30 files changed, 90 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 585ea226997a6..0fcac9a1c6c7b 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -23,9 +23,7 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{ - self, EarlyBinder, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt, -}; +use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt}; use std::iter; use crate::nll::ToRegionVid; @@ -479,7 +477,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { .infcx .tcx .mk_region(ty::ReVar(self.infcx.next_nll_region_var(FR).to_region_vid())); - let va_list_ty = EarlyBinder(self.infcx.tcx.type_of(va_list_did)) + let va_list_ty = self + .infcx + .tcx + .bound_type_of(va_list_did) .subst(self.infcx.tcx, &[region.into()]); unnormalized_input_tys = self.infcx.tcx.mk_type_list( diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 43133b03ad1a3..5ece19d7fb3d3 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -5,7 +5,6 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::mir::TerminatorKind; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::EarlyBinder; use rustc_span::{Span, Symbol}; use crate::interpret::{ @@ -94,10 +93,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let col = if loc_details.column { Scalar::from_u32(col) } else { Scalar::from_u32(0) }; // Allocate memory for `CallerLocation` struct. - let loc_ty = EarlyBinder( - self.tcx.type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None)), - ) - .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); + let loc_ty = self + .tcx + .bound_type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None)) + .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); let loc_layout = self.layout_of(loc_ty).unwrap(); // This can fail if rustc runs out of memory right here. Trying to emit an error would be // pointless, since that would require allocating more memory than a Location. diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 8fc41ba5365d8..4e6404035f427 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -968,7 +968,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } GenericArgKind::Type(ty) => { - if EarlyBinder(self.tcx.type_of(def_id)).subst(self.tcx, substs) != ty { + if self.tcx.bound_type_of(def_id).subst(self.tcx, substs) != ty { break; } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 5b064759d5886..6ea831f255aba 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -10,7 +10,7 @@ use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; -use crate::ty::{self, EarlyBinder, List, Ty, TyCtxt}; +use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, Region, ScalarInt, UserTypeAnnotationIndex}; use rustc_errors::ErrorGuaranteed; @@ -2387,7 +2387,7 @@ impl<'tcx> Operand<'tcx> { substs: SubstsRef<'tcx>, span: Span, ) -> Self { - let ty = EarlyBinder(tcx.type_of(def_id)).subst(tcx, substs); + let ty = tcx.bound_type_of(def_id).subst(tcx, substs); Operand::Constant(Box::new(Constant { span, user_ty: None, diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 99a4822bc9ac9..c93b7a9550229 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -5,7 +5,7 @@ use crate::mir::*; use crate::ty::subst::Subst; -use crate::ty::{self, EarlyBinder, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt}; use rustc_hir as hir; use rustc_target::abi::VariantIdx; @@ -203,7 +203,7 @@ impl<'tcx> Rvalue<'tcx> { AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64), AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))), AggregateKind::Adt(did, _, substs, _, _) => { - EarlyBinder(tcx.type_of(did)).subst(tcx, substs) + tcx.bound_type_of(did).subst(tcx, substs) } AggregateKind::Closure(did, substs) => tcx.mk_closure(did, substs), AggregateKind::Generator(did, substs, movability) => { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0932bfefc86e4..4821109ca45a5 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -19,11 +19,10 @@ use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, Substs use crate::ty::TyKind::*; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, - ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, EarlyBinder, ExistentialPredicate, - FloatTy, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, - List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, - Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, - UintTy, + ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, + FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, + ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, + RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, }; use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; @@ -1605,7 +1604,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn caller_location_ty(self) -> Ty<'tcx> { self.mk_imm_ref( self.lifetimes.re_static, - EarlyBinder(self.type_of(self.require_lang_item(LangItem::PanicLocation, None))) + self.bound_type_of(self.require_lang_item(LangItem::PanicLocation, None)) .subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())), ) } @@ -2334,7 +2333,7 @@ impl<'tcx> TyCtxt<'tcx> { ty_param.into() } else { assert!(has_default); - EarlyBinder(self.type_of(param.def_id)).subst(self, substs).into() + self.bound_type_of(param.def_id).subst(self, substs).into() } } }); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9a04b06a7df34..7b31abea44959 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1932,7 +1932,7 @@ impl<'tcx> FieldDef { /// Returns the type of this field. The resulting type is not normalized. The `subst` is /// typically obtained via the second field of [`TyKind::Adt`]. pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> { - EarlyBinder(tcx.type_of(self.did)).subst(tcx, subst) + tcx.bound_type_of(self.did).subst(tcx, subst) } /// Computes the `Ident` of this variant by looking up the `Span` diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 0262caddec562..51cdd9c2d4780 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -115,12 +115,16 @@ pub trait Printer<'tcx>: Sized { DefPathData::Impl => { let generics = self.tcx().generics_of(def_id); - let mut self_ty = self.tcx().type_of(def_id); - let mut impl_trait_ref = self.tcx().impl_trait_ref(def_id); - if substs.len() >= generics.count() { - self_ty = EarlyBinder(self_ty).subst(self.tcx(), substs); - impl_trait_ref = EarlyBinder(impl_trait_ref).subst(self.tcx(), substs); - } + let self_ty = self.tcx().bound_type_of(def_id); + let impl_trait_ref = self.tcx().impl_trait_ref(def_id); + let (self_ty, impl_trait_ref) = if substs.len() >= generics.count() { + ( + self_ty.subst(self.tcx(), substs), + EarlyBinder(impl_trait_ref).subst(self.tcx(), substs), + ) + } else { + (self_ty.0, impl_trait_ref) + }; self.print_impl_path(def_id, substs, self_ty, impl_trait_ref) } @@ -203,8 +207,7 @@ pub trait Printer<'tcx>: Sized { has_default && substs[param.index as usize] == GenericArg::from( - EarlyBinder(self.tcx().type_of(param.def_id)) - .subst(self.tcx(), substs), + self.tcx().bound_type_of(param.def_id).subst(self.tcx(), substs), ) } ty::GenericParamDefKind::Const { has_default } => { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 65f07f177ebf9..8677405eebeda 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -7,7 +7,7 @@ use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar}; use crate::ty::error::{ExpectedFound, TypeError}; use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef}; -use crate::ty::{self, EarlyBinder, ImplSubject, Term, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, ImplSubject, Term, Ty, TyCtxt, TypeFoldable}; use rustc_hir as ast; use rustc_hir::def_id::DefId; use rustc_span::DUMMY_SP; @@ -159,8 +159,8 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>( let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| { let variance = variances[i]; let variance_info = if variance == ty::Invariant { - let ty = *cached_ty - .get_or_insert_with(|| EarlyBinder(tcx.type_of(ty_def_id)).subst(tcx, a_subst)); + let ty = + *cached_ty.get_or_insert_with(|| tcx.bound_type_of(ty_def_id).subst(tcx, a_subst)); ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } } else { ty::VarianceDiagInfo::default() diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8ceefd3e2b83e..e93620f3510ff 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2347,7 +2347,7 @@ impl<'tcx> Ty<'tcx> { ty::Str | ty::Slice(_) => (tcx.types.usize, false), ty::Dynamic(..) => { let dyn_metadata = tcx.lang_items().dyn_metadata().unwrap(); - (EarlyBinder(tcx.type_of(dyn_metadata)).subst(tcx, &[tail.into()]), false) + (tcx.bound_type_of(dyn_metadata).subst(tcx, &[tail.into()]), false) }, // type parameters only have unit metadata if they're sized, so return true diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 6efa8555bf0e3..b5162e3a93593 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -592,6 +592,10 @@ impl<'tcx> TyCtxt<'tcx> { trace!(?expanded_type); if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) } } + + pub fn bound_type_of(self, def_id: DefId) -> EarlyBinder> { + EarlyBinder(self.type_of(def_id)) + } } struct OpaqueTypeExpander<'tcx> { @@ -623,8 +627,8 @@ impl<'tcx> OpaqueTypeExpander<'tcx> { let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) { Some(expanded_ty) => *expanded_ty, None => { - let generic_ty = self.tcx.type_of(def_id); - let concrete_ty = EarlyBinder(generic_ty).subst(self.tcx, substs); + let generic_ty = self.tcx.bound_type_of(def_id); + let concrete_ty = generic_ty.subst(self.tcx, substs); let expanded_ty = self.fold_ty(concrete_ty); self.expanded_cache.insert((def_id, substs), expanded_ty); expanded_ty diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 3444de612a444..d7993ce1cf4fa 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -16,7 +16,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::subst::{GenericArg, Subst}; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, adjustment::PointerCast, EarlyBinder, Ty, TyCtxt}; +use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; @@ -834,8 +834,8 @@ fn trait_method<'tcx>( .find(|item| item.kind == ty::AssocKind::Fn) .expect("trait method not found"); - let method_ty = tcx.type_of(item.def_id); - let method_ty = EarlyBinder(method_ty).subst(tcx, substs); + let method_ty = tcx.bound_type_of(item.def_id); + let method_ty = method_ty.subst(tcx, substs); ConstantKind::zero_sized(method_ty) } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 3e9143b563fe2..b7e6180fc782f 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -14,7 +14,7 @@ use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, PatKind, Thir}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeckResults}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeckResults}; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::spec::abi::Abi; @@ -177,8 +177,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ let ty = if fn_sig.c_variadic && index == fn_sig.inputs().len() { let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(arg.span)); - EarlyBinder(tcx.type_of(va_list_did)) - .subst(tcx, &[tcx.lifetimes.re_erased.into()]) + tcx.bound_type_of(va_list_did).subst(tcx, &[tcx.lifetimes.re_erased.into()]) } else { fn_sig.inputs()[index] }; diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index fd27aa85904e3..b7dec57b75768 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -62,7 +62,7 @@ use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::subst::{Subst, SubstsRef}; use rustc_middle::ty::GeneratorSubsts; -use rustc_middle::ty::{self, AdtDef, EarlyBinder, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, }; @@ -245,7 +245,9 @@ impl<'tcx> TransformVisitor<'tcx> { ) -> impl Iterator> { let kind = AggregateKind::Adt(self.state_adt_ref.did(), idx, self.state_substs, None, None); assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 1); - let ty = EarlyBinder(self.tcx.type_of(self.state_adt_ref.variant(idx).fields[0].did)) + let ty = self + .tcx + .bound_type_of(self.state_adt_ref.variant(idx).fields[0].did) .subst(self.tcx, self.state_substs); expand_aggregate( Place::return_place(), diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index e584cac57f1f8..f434b3e7c160a 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -135,7 +135,7 @@ fn with_fresh_ty_vars<'cx, 'tcx>( let header = ty::ImplHeader { impl_def_id, - self_ty: EarlyBinder(tcx.type_of(impl_def_id)).subst(tcx, impl_substs), + self_ty: tcx.bound_type_of(impl_def_id).subst(tcx, impl_substs), trait_ref: EarlyBinder(tcx.impl_trait_ref(impl_def_id)).subst(tcx, impl_substs), predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates, }; diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 058308420ed09..004091661fa8c 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -515,8 +515,8 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { } let substs = substs.super_fold_with(self); - let generic_ty = self.tcx().type_of(def_id); - let concrete_ty = EarlyBinder(generic_ty).subst(self.tcx(), substs); + let generic_ty = self.tcx().bound_type_of(def_id); + let concrete_ty = generic_ty.subst(self.tcx(), substs); self.depth += 1; let folded_ty = self.fold_ty(concrete_ty); self.depth -= 1; diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 10e64eed3b8c7..6a81a7764afd9 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -14,7 +14,7 @@ use rustc_infer::traits::Normalized; use rustc_middle::mir; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; use std::ops::ControlFlow; @@ -217,8 +217,8 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { self.infcx.report_overflow_error(&obligation, true); } - let generic_ty = self.tcx().type_of(def_id); - let concrete_ty = EarlyBinder(generic_ty).subst(self.tcx(), substs); + let generic_ty = self.tcx().bound_type_of(def_id); + let concrete_ty = generic_ty.subst(self.tcx(), substs); self.anon_depth += 1; if concrete_ty == ty { bug!( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index e6f9fbc6c03be..fe80d02595a53 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1006,10 +1006,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // The last field of the structure has to exist and contain type/const parameters. let (tail_field, prefix_fields) = def.non_enum_variant().fields.split_last().ok_or(Unimplemented)?; - let tail_field_ty = tcx.type_of(tail_field.did); + let tail_field_ty = tcx.bound_type_of(tail_field.did); let mut unsizing_params = GrowableBitSet::new_empty(); - for arg in tail_field_ty.walk() { + for arg in tail_field_ty.0.walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.insert(i); } @@ -1030,8 +1030,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } // Extract `TailField` and `TailField` from `Struct` and `Struct`. - let source_tail = EarlyBinder(tail_field_ty).subst(tcx, substs_a); - let target_tail = EarlyBinder(tail_field_ty).subst(tcx, substs_b); + let source_tail = tail_field_ty.subst(tcx, substs_a); + let target_tail = tail_field_ty.subst(tcx, substs_b); // Check that the source struct with the target's // unsizing parameters is equal to the target. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8bab8353ab68d..70cb208b616ba 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1960,7 +1960,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - t.rebind(vec![EarlyBinder(self.tcx().type_of(def_id)).subst(self.tcx(), substs)]) + t.rebind(vec![self.tcx().bound_type_of(def_id).subst(self.tcx(), substs)]) } } } diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 4288ddeaed003..31934c97168d6 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -464,7 +464,10 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let trait_item_id = assoc_item.trait_item_def_id.expect("assoc_ty with no trait version"); let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(self.interner, bound_vars); - let ty = EarlyBinder(self.interner.tcx.type_of(def_id)) + let ty = self + .interner + .tcx + .bound_type_of(def_id) .subst(self.interner.tcx, bound_vars) .lower_into(self.interner); diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index d2d6386806b1c..9ad44d14d6180 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -237,7 +237,7 @@ fn drop_tys_helper<'tcx>( Ok(Vec::new()) } else { let field_tys = adt_def.all_fields().map(|field| { - let r = EarlyBinder(tcx.type_of(field.did)).subst(tcx, substs); + let r = tcx.bound_type_of(field.did).subst(tcx, substs); debug!("drop_tys_helper: Subst into {:?} with {:?} gettng {:?}", field, substs, r); r }); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index a8aac5da09cc1..23700e653e36a 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -444,7 +444,7 @@ pub fn conservative_is_privately_uninhabited_raw<'tcx>( // one uninhabited field. def.variants().iter().all(|var| { var.fields.iter().any(|field| { - let ty = EarlyBinder(tcx.type_of(field.did)).subst(tcx, substs); + let ty = tcx.bound_type_of(field.did).subst(tcx, substs); tcx.conservative_is_privately_uninhabited(param_env.and(ty)) }) }) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 1d962064bd934..36a0e29736008 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{self, EarlyBinder, ParamEnv, ToPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, ParamEnv, ToPredicate, Ty, TyCtxt}; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; use rustc_span::{self, Span}; @@ -171,7 +171,7 @@ pub(super) fn check_fn<'a, 'tcx>( let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span)); let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span)); - Some(EarlyBinder(tcx.type_of(va_list_did)).subst(tcx, &[region.into()])) + Some(tcx.bound_type_of(va_list_did).subst(tcx, &[region.into()])) } else { None }; @@ -655,7 +655,7 @@ fn check_opaque_meets_bounds<'tcx>( span: Span, origin: &hir::OpaqueTyOrigin, ) { - let hidden_type = EarlyBinder(tcx.type_of(def_id)).subst(tcx, substs); + let hidden_type = tcx.bound_type_of(def_id.to_def_id()).subst(tcx, substs); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let defining_use_anchor = match *origin { diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index eff009d0e8ba7..4b6c36e9dde7e 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -1066,7 +1066,7 @@ crate fn compare_const_impl<'tcx>( // Compute placeholder form of impl and trait const tys. let impl_ty = tcx.type_of(impl_c.def_id); - let trait_ty = EarlyBinder(tcx.type_of(trait_c.def_id)).subst(tcx, trait_to_impl_substs); + let trait_ty = tcx.bound_type_of(trait_c.def_id).subst(tcx, trait_to_impl_substs); let mut cause = ObligationCause::new( impl_c_span, impl_c_hir_id, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index e1cfa9bd6e7d1..6207a61ca95f7 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -838,12 +838,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let def_kind = self.tcx.def_kind(def_id); let item_ty = if let DefKind::Variant = def_kind { - self.tcx.type_of(self.tcx.parent(def_id)) + self.tcx.bound_type_of(self.tcx.parent(def_id)) } else { - self.tcx.type_of(def_id) + self.tcx.bound_type_of(def_id) }; let substs = self.infcx.fresh_substs_for_item(span, def_id); - let ty = EarlyBinder(item_ty).subst(self.tcx, substs); + let ty = item_ty.subst(self.tcx, substs); self.write_resolution(hir_id, Ok((def_kind, def_id))); self.add_required_obligations_with_code( @@ -1401,12 +1401,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If we have a default, then we it doesn't matter that we're not // inferring the type arguments: we provide the default where any // is missing. - let default = tcx.type_of(param.def_id); + let default = tcx.bound_type_of(param.def_id); self.fcx - .normalize_ty( - self.span, - EarlyBinder(default).subst(tcx, substs.unwrap()), - ) + .normalize_ty(self.span, default.subst(tcx, substs.unwrap())) .into() } else { // If no type arguments were provided, we have to infer them. diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 2cca899c8e4ef..c291d841211d5 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -11,7 +11,7 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, EarlyBinder, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; @@ -129,7 +129,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ty::INNERMOST, ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv }, )); - let va_list_ty = EarlyBinder(tcx.type_of(did)).subst(tcx, &[region.into()]); + let va_list_ty = tcx.bound_type_of(did).subst(tcx, &[region.into()]); (tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty) }) }; diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index c8cd0931c3ff8..60f55b02fdfd0 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -15,14 +15,14 @@ crate struct BlanketImplFinder<'a, 'tcx> { impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { crate fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec { let param_env = self.cx.tcx.param_env(item_def_id); - let ty = self.cx.tcx.type_of(item_def_id); + let ty = self.cx.tcx.bound_type_of(item_def_id); trace!("get_blanket_impls({:?})", ty); let mut impls = Vec::new(); self.cx.with_all_traits(|cx, all_traits| { for &trait_def_id in all_traits { if !cx.cache.access_levels.is_public(trait_def_id) - || cx.generated_synthetics.get(&(ty, trait_def_id)).is_some() + || cx.generated_synthetics.get(&(ty.0, trait_def_id)).is_some() { continue; } @@ -38,7 +38,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { let is_param = matches!(trait_ref.self_ty().kind(), ty::Param(_)); let may_apply = is_param && cx.tcx.infer_ctxt().enter(|infcx| { let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id); - let ty = EarlyBinder(ty).subst(infcx.tcx, substs); + let ty = ty.subst(infcx.tcx, substs); let param_env = EarlyBinder(param_env).subst(infcx.tcx, substs); let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); @@ -99,7 +99,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { continue; } - cx.generated_synthetics.insert((ty, trait_def_id)); + cx.generated_synthetics.insert((ty.0, trait_def_id)); impls.push(Item { name: None, @@ -116,7 +116,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { // FIXME(eddyb) compute both `trait_` and `for_` from // the post-inference `trait_ref`, as it's more accurate. trait_: Some(trait_ref.clean(cx)), - for_: ty.clean(cx), + for_: ty.0.clean(cx), items: cx.tcx .associated_items(impl_def_id) .in_definition_order() diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index b7776b3f0c38b..530d6d4de35f1 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -12,7 +12,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::binding::BindingMode; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, ClosureKind, EarlyBinder, Ty, TypeFoldable}; +use rustc_middle::ty::{self, ClosureKind, Ty, TypeFoldable}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; @@ -150,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { if check_inputs(cx, body.params, args); let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap(); let substs = cx.typeck_results().node_substs(body.value.hir_id); - let call_ty = EarlyBinder(cx.tcx.type_of(method_def_id)).subst(cx.tcx, substs); + let call_ty = cx.tcx.bound_type_of(method_def_id).subst(cx.tcx, substs); if check_sig(cx, closure_ty, call_ty); then { span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure", |diag| { diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index a323737ae404e..9d8f8999ce409 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, EarlyBinder, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::iter; @@ -48,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { ExprKind::MethodCall(path, arguments, _) => { let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap(); let substs = cx.typeck_results().node_substs(e.hir_id); - let method_type = EarlyBinder(cx.tcx.type_of(def_id)).subst(cx.tcx, substs); + let method_type = cx.tcx.bound_type_of(def_id).subst(cx.tcx, substs); check_arguments(cx, arguments, method_type, path.ident.as_str(), "method"); }, _ => (), diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index 0bb577b7620b1..be6277332db4d 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -4,7 +4,7 @@ use clippy_utils::ty::is_c_void; use rustc_hir::Expr; use rustc_lint::LateContext; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, EarlyBinder, IntTy, Ty, TypeAndMut, UintTy}; +use rustc_middle::ty::{self, IntTy, Ty, TypeAndMut, UintTy}; use rustc_span::Span; #[allow(clippy::too_many_lines)] @@ -307,7 +307,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> .non_enum_variant() .fields .iter() - .map(|f| EarlyBinder(cx.tcx.type_of(f.did)).subst(cx.tcx, substs)); + .map(|f| cx.tcx.bound_type_of(f.did).subst(cx.tcx, substs)); let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else { return ReducedTy::TypeErasure; }; From 6c05e8d009a864238681157189c93740911bfa14 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Sun, 8 May 2022 15:43:18 -0400 Subject: [PATCH 3/6] Add bound_fn_sig --- .../src/infer/error_reporting/mod.rs | 8 +++---- compiler/rustc_middle/src/ty/layout.rs | 7 +++---- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- .../rustc_middle/src/ty/structural_impls.rs | 21 +++++++++++++++++++ compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 4 ++++ compiler/rustc_mir_transform/src/inline.rs | 4 ++-- compiler/rustc_mir_transform/src/shim.rs | 4 ++-- compiler/rustc_typeck/src/astconv/mod.rs | 2 +- compiler/rustc_typeck/src/check/callee.rs | 4 ++-- .../rustc_typeck/src/check/compare_method.rs | 5 ++--- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 6 +++--- .../rustc_typeck/src/check/method/confirm.rs | 6 +++--- compiler/rustc_typeck/src/check/method/mod.rs | 6 +++--- .../rustc_typeck/src/check/method/probe.rs | 10 ++++----- src/tools/clippy/clippy_utils/src/ty.rs | 4 ++-- 16 files changed, 59 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 4e6404035f427..2a5b7e936ca78 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1385,8 +1385,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => { - let sig1 = EarlyBinder(self.tcx.fn_sig(*did1)).subst(self.tcx, substs1); - let sig2 = EarlyBinder(self.tcx.fn_sig(*did2)).subst(self.tcx, substs2); + let sig1 = self.tcx.bound_fn_sig(*did1).subst(self.tcx, substs1); + let sig2 = self.tcx.bound_fn_sig(*did2).subst(self.tcx, substs2); let mut values = self.cmp_fn_sig(&sig1, &sig2); let path1 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did1, substs1)); let path2 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did2, substs2)); @@ -1397,7 +1397,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } (ty::FnDef(did1, substs1), ty::FnPtr(sig2)) => { - let sig1 = EarlyBinder(self.tcx.fn_sig(*did1)).subst(self.tcx, substs1); + let sig1 = self.tcx.bound_fn_sig(*did1).subst(self.tcx, substs1); let mut values = self.cmp_fn_sig(&sig1, sig2); values.0.push_highlighted(format!( " {{{}}}", @@ -1407,7 +1407,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } (ty::FnPtr(sig1), ty::FnDef(did2, substs2)) => { - let sig2 = EarlyBinder(self.tcx.fn_sig(*did2)).subst(self.tcx, substs2); + let sig2 = self.tcx.bound_fn_sig(*did2).subst(self.tcx, substs2); let mut values = self.cmp_fn_sig(sig1, &sig2); values.1.push_normal(format!( " {{{}}}", diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 28652bdd22817..d187146476ab4 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2749,10 +2749,9 @@ impl<'tcx> ty::Instance<'tcx> { // `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping // track of a polymorphization `ParamEnv` to allow normalizing later. let mut sig = match *ty.kind() { - ty::FnDef(def_id, substs) => EarlyBinder( - tcx.normalize_erasing_regions(tcx.param_env(def_id), tcx.fn_sig(def_id)), - ) - .subst(tcx, substs), + ty::FnDef(def_id, substs) => tcx + .normalize_erasing_regions(tcx.param_env(def_id), tcx.bound_fn_sig(def_id)) + .subst(tcx, substs), _ => unreachable!(), }; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 8a7f1e68a3528..e680250e7b109 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -589,7 +589,7 @@ pub trait PrettyPrinter<'tcx>: p!(")") } ty::FnDef(def_id, substs) => { - let sig = EarlyBinder(self.tcx().fn_sig(def_id)).subst(self.tcx(), substs); + let sig = self.tcx().bound_fn_sig(def_id).subst(self.tcx(), substs); p!(print(sig), " {{", print_value_path(def_id, substs), "}}"); } ty::FnPtr(ref bare_fn) => p!(print(bare_fn)), diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 4ef6ff1835ffd..2c8cd4f933d04 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -860,6 +860,27 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { } } +impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::EarlyBinder { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + self.try_map_bound(|ty| ty.try_fold_with(folder)) + } + + fn try_fold_with>(self, folder: &mut F) -> Result { + self.try_map_bound(|ty| ty.try_fold_with(folder)) + } + + fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.as_ref().0.visit_with(visitor) + } + + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.as_ref().0.visit_with(visitor) + } +} + impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { fn try_super_fold_with>( self, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index e93620f3510ff..ca8528b3350d2 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2180,7 +2180,7 @@ impl<'tcx> Ty<'tcx> { pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> { match self.kind() { - FnDef(def_id, substs) => EarlyBinder(tcx.fn_sig(*def_id)).subst(tcx, substs), + FnDef(def_id, substs) => tcx.bound_fn_sig(*def_id).subst(tcx, substs), FnPtr(f) => *f, Error(_) => { // ignore errors (#54954) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b5162e3a93593..344ae963c14fa 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -596,6 +596,10 @@ impl<'tcx> TyCtxt<'tcx> { pub fn bound_type_of(self, def_id: DefId) -> EarlyBinder> { EarlyBinder(self.type_of(def_id)) } + + pub fn bound_fn_sig(self, def_id: DefId) -> EarlyBinder> { + EarlyBinder(self.fn_sig(def_id)) + } } struct OpaqueTypeExpander<'tcx> { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index fdb5f600f1840..012ce73075575 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -8,7 +8,7 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, ConstKind, EarlyBinder, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; use rustc_target::spec::abi::Abi; @@ -260,7 +260,7 @@ impl<'tcx> Inliner<'tcx> { return None; } - let fn_sig = EarlyBinder(self.tcx.fn_sig(def_id)).subst(self.tcx, substs); + let fn_sig = self.tcx.bound_fn_sig(def_id).subst(self.tcx, substs); return Some(CallSite { callee, diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 066e22cb4e59c..016b3bc098073 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -151,7 +151,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) } else { InternalSubsts::identity_for_item(tcx, def_id) }; - let sig = EarlyBinder(tcx.fn_sig(def_id)).subst(tcx, substs); + 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); @@ -343,7 +343,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // 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 sig = EarlyBinder(tcx.fn_sig(def_id)).subst(tcx, substs); + 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); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index aa7346129f287..663a644a9e727 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2693,7 +2693,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_ref.def_id, )?; - let fn_sig = EarlyBinder(tcx.fn_sig(assoc.def_id)).subst( + let fn_sig = tcx.bound_fn_sig(assoc.def_id).subst( tcx, trait_ref.substs.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)), ); diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index f8e82647b2144..0a84d41b4f31c 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, }; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_target::spec::abi; @@ -339,7 +339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { let (fn_sig, def_id) = match *callee_ty.kind() { ty::FnDef(def_id, subst) => { - let fn_sig = EarlyBinder(self.tcx.fn_sig(def_id)).subst(self.tcx, subst); + let fn_sig = self.tcx.bound_fn_sig(def_id).subst(self.tcx, subst); // Unit testing: function items annotated with // `#[rustc_evaluate_where_clauses]` trigger special output diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 4b6c36e9dde7e..06304d8d7e72d 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -265,9 +265,8 @@ fn compare_predicate_entailment<'tcx>( let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig)); debug!("compare_impl_method: impl_fty={:?}", impl_fty); - // First liberate late bound regions and subst placeholders - let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(trait_m.def_id)); - let trait_sig = EarlyBinder(trait_sig).subst(tcx, trait_to_placeholder_substs); + let trait_sig = tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs); + let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig); let trait_sig = inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, trait_sig); // Add the resulting inputs and output as well-formed. diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 6207a61ca95f7..501ce31557dda 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1044,8 +1044,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let (sig, did, substs) = match (&expected.kind(), &found.kind()) { (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => { - let sig1 = EarlyBinder(self.tcx.fn_sig(*did1)).subst(self.tcx, substs1); - let sig2 = EarlyBinder(self.tcx.fn_sig(*did2)).subst(self.tcx, substs2); + let sig1 = self.tcx.bound_fn_sig(*did1).subst(self.tcx, substs1); + let sig2 = self.tcx.bound_fn_sig(*did2).subst(self.tcx, substs2); if sig1 != sig2 { return; } @@ -1056,7 +1056,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (sig1, *did1, substs1) } (ty::FnDef(did, substs), ty::FnPtr(sig2)) => { - let sig1 = EarlyBinder(self.tcx.fn_sig(*did)).subst(self.tcx, substs); + let sig1 = self.tcx.bound_fn_sig(*did).subst(self.tcx, substs); if sig1 != *sig2 { return; } diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index edd4cf91c2467..7992460f5464e 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::{self, Subst, SubstsRef}; -use rustc_middle::ty::{self, EarlyBinder, GenericParamDefKind, Ty}; +use rustc_middle::ty::{self, GenericParamDefKind, Ty}; use rustc_span::Span; use rustc_trait_selection::traits; @@ -460,9 +460,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { debug!("method_predicates after subst = {:?}", method_predicates); - let sig = self.tcx.fn_sig(def_id); + let sig = self.tcx.bound_fn_sig(def_id); - let sig = EarlyBinder(sig).subst(self.tcx, all_substs); + let sig = sig.subst(self.tcx, all_substs); debug!("type scheme substituted, sig={:?}", sig); let sig = self.replace_bound_vars_with_fresh_vars(sig); diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index a5194e4c135ce..cb359434fdb9a 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -21,7 +21,7 @@ use rustc_infer::infer::{self, InferOk}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, EarlyBinder, ToPredicate, Ty, TypeFoldable}; +use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable}; use rustc_span::symbol::Ident; use rustc_span::Span; use rustc_trait_selection::traits; @@ -460,8 +460,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // N.B., instantiate late-bound regions first so that // `instantiate_type_scheme` can normalize associated types that // may reference those regions. - let fn_sig = tcx.fn_sig(def_id); - let fn_sig = EarlyBinder(fn_sig).subst(self.tcx, substs); + let fn_sig = tcx.bound_fn_sig(def_id); + let fn_sig = fn_sig.subst(self.tcx, substs); let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig).0; let InferOk { value, obligations: o } = if is_op { diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 5edd9a5b8d645..0861d121a1f0e 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -901,10 +901,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ) -> bool { match method.kind { ty::AssocKind::Fn => { - let fty = self.tcx.fn_sig(method.def_id); + let fty = self.tcx.bound_fn_sig(method.def_id); self.probe(|_| { let substs = self.fresh_substs_for_item(self.span, method.def_id); - let fty = EarlyBinder(fty).subst(self.tcx, substs); + let fty = fty.subst(self.tcx, substs); let (fty, _) = self.replace_bound_vars_with_fresh_vars(self.span, infer::FnCall, fty); @@ -1771,7 +1771,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn xform_method_sig(&self, method: DefId, substs: SubstsRef<'tcx>) -> ty::FnSig<'tcx> { - let fn_sig = self.tcx.fn_sig(method); + let fn_sig = self.tcx.bound_fn_sig(method); debug!(?fn_sig); assert!(!substs.has_escaping_bound_vars()); @@ -1785,7 +1785,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { assert_eq!(substs.len(), generics.parent_count as usize); let xform_fn_sig = if generics.params.is_empty() { - EarlyBinder(fn_sig).subst(self.tcx, substs) + fn_sig.subst(self.tcx, substs) } else { let substs = InternalSubsts::for_item(self.tcx, method, |param, _| { let i = param.index as usize; @@ -1803,7 +1803,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } }); - EarlyBinder(fn_sig).subst(self.tcx, substs) + fn_sig.subst(self.tcx, substs) }; self.erase_late_bound_regions(xform_fn_sig) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index b46a7b86a7590..8d99f3002b879 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -13,7 +13,7 @@ use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; use rustc_middle::ty::{ - self, AdtDef, Binder, EarlyBinder, FnSig, IntTy, Predicate, PredicateKind, Ty, TyCtxt, TypeFoldable, UintTy, VariantDiscr, + self, AdtDef, Binder, FnSig, IntTy, Predicate, PredicateKind, Ty, TyCtxt, TypeFoldable, UintTy, VariantDiscr, }; use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; @@ -520,7 +520,7 @@ pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option Some(ExprFnSig::Closure(subs.as_closure().sig())), - ty::FnDef(id, subs) => Some(ExprFnSig::Sig(EarlyBinder(cx.tcx.fn_sig(id)).subst(cx.tcx, subs))), + ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.bound_fn_sig(id).subst(cx.tcx, subs))), ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig)), ty::Dynamic(bounds, _) => { let lang_items = cx.tcx.lang_items(); From 0247faed2980a858e04fa57f78d585c8b066948d Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Sun, 8 May 2022 20:53:36 -0400 Subject: [PATCH 4/6] Add bound_impl_trait_ref --- compiler/rustc_middle/src/ty/print/mod.rs | 8 ++++---- compiler/rustc_middle/src/ty/util.rs | 4 ++++ compiler/rustc_trait_selection/src/traits/coherence.rs | 4 ++-- .../src/traits/error_reporting/on_unimplemented.rs | 5 ++--- .../rustc_trait_selection/src/traits/select/mod.rs | 6 +++--- .../rustc_trait_selection/src/traits/specialize/mod.rs | 6 +++--- compiler/rustc_traits/src/chalk/db.rs | 10 +++++----- src/librustdoc/clean/blanket_impl.rs | 10 +++++----- 8 files changed, 28 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 51cdd9c2d4780..9d8124eb25db1 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -1,5 +1,5 @@ use crate::ty::subst::{GenericArg, Subst}; -use crate::ty::{self, DefIdTree, EarlyBinder, Ty, TyCtxt}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; @@ -116,14 +116,14 @@ pub trait Printer<'tcx>: Sized { DefPathData::Impl => { let generics = self.tcx().generics_of(def_id); let self_ty = self.tcx().bound_type_of(def_id); - let impl_trait_ref = self.tcx().impl_trait_ref(def_id); + let impl_trait_ref = self.tcx().bound_impl_trait_ref(def_id); let (self_ty, impl_trait_ref) = if substs.len() >= generics.count() { ( self_ty.subst(self.tcx(), substs), - EarlyBinder(impl_trait_ref).subst(self.tcx(), substs), + impl_trait_ref.map(|i| i.subst(self.tcx(), substs)), ) } else { - (self_ty.0, impl_trait_ref) + (self_ty.0, impl_trait_ref.map(|i| i.0)) }; self.print_impl_path(def_id, substs, self_ty, impl_trait_ref) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 344ae963c14fa..ed0f6a7ccd108 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -600,6 +600,10 @@ impl<'tcx> TyCtxt<'tcx> { pub fn bound_fn_sig(self, def_id: DefId) -> EarlyBinder> { EarlyBinder(self.fn_sig(def_id)) } + + pub fn bound_impl_trait_ref(self, def_id: DefId) -> Option>> { + self.impl_trait_ref(def_id).map(|i| EarlyBinder(i)) + } } struct OpaqueTypeExpander<'tcx> { diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index f434b3e7c160a..d09cc4fb62f3f 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -23,7 +23,7 @@ use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{self, TreatParams}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, EarlyBinder, ImplSubject, Ty, TyCtxt}; +use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::fmt::Debug; @@ -136,7 +136,7 @@ fn with_fresh_ty_vars<'cx, 'tcx>( let header = ty::ImplHeader { impl_def_id, self_ty: tcx.bound_type_of(impl_def_id).subst(tcx, impl_substs), - trait_ref: EarlyBinder(tcx.impl_trait_ref(impl_def_id)).subst(tcx, impl_substs), + trait_ref: tcx.bound_impl_trait_ref(impl_def_id).map(|i| i.subst(tcx, impl_substs)), predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates, }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 86c93867c759e..4263a6fdf1841 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -5,7 +5,7 @@ use crate::infer::InferCtxt; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, EarlyBinder, GenericParamDefKind}; +use rustc_middle::ty::{self, GenericParamDefKind}; use rustc_span::symbol::sym; use std::iter; @@ -45,8 +45,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| { let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id); - let impl_trait_ref = - EarlyBinder(tcx.impl_trait_ref(def_id).unwrap()).subst(tcx, impl_substs); + let impl_trait_ref = tcx.bound_impl_trait_ref(def_id).unwrap().subst(tcx, impl_substs); let impl_self_ty = impl_trait_ref.self_ty(); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 70cb208b616ba..ab617d16cc4f7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2066,12 +2066,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl_def_id: DefId, obligation: &TraitObligation<'tcx>, ) -> Result>, ()> { - let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); + let impl_trait_ref = self.tcx().bound_impl_trait_ref(impl_def_id).unwrap(); // Before we create the substitutions and everything, first // consider a "quick reject". This avoids creating more types // and so forth that we need to. - if self.fast_reject_trait_refs(obligation, &impl_trait_ref) { + if self.fast_reject_trait_refs(obligation, &impl_trait_ref.0) { return Err(()); } @@ -2081,7 +2081,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); - let impl_trait_ref = EarlyBinder(impl_trait_ref).subst(self.tcx(), impl_substs); + let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); debug!(?impl_trait_ref); diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index b6a4d100341dd..bca1d15ada90f 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -20,7 +20,7 @@ use rustc_errors::{struct_span_err, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{self, EarlyBinder, ImplSubject, TyCtxt}; +use rustc_middle::ty::{self, ImplSubject, TyCtxt}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; use rustc_span::{Span, DUMMY_SP}; @@ -84,8 +84,8 @@ pub fn translate_substs<'a, 'tcx>( "translate_substs({:?}, {:?}, {:?}, {:?})", param_env, source_impl, source_substs, target_node ); - let source_trait_ref = EarlyBinder(infcx.tcx.impl_trait_ref(source_impl).unwrap()) - .subst(infcx.tcx, &source_substs); + let source_trait_ref = + infcx.tcx.bound_impl_trait_ref(source_impl).unwrap().subst(infcx.tcx, &source_substs); // translate the Self and Param parts of the substitution, since those // vary across impls diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 31934c97168d6..5b5b849919188 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -310,8 +310,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(self.interner, bound_vars); - let trait_ref = self.interner.tcx.impl_trait_ref(def_id).expect("not an impl"); - let trait_ref = EarlyBinder(trait_ref).subst(self.interner.tcx, bound_vars); + let trait_ref = self.interner.tcx.bound_impl_trait_ref(def_id).expect("not an impl"); + let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars); let where_clauses = self.where_clauses_for(def_id, bound_vars); @@ -352,11 +352,11 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let all_impls = self.interner.tcx.all_impls(def_id); let matched_impls = all_impls.filter(|impl_def_id| { use chalk_ir::could_match::CouldMatch; - let trait_ref = self.interner.tcx.impl_trait_ref(*impl_def_id).unwrap(); + let trait_ref = self.interner.tcx.bound_impl_trait_ref(*impl_def_id).unwrap(); let bound_vars = bound_vars_for_item(self.interner.tcx, *impl_def_id); - let self_ty = trait_ref.self_ty(); - let self_ty = EarlyBinder(self_ty).subst(self.interner.tcx, bound_vars); + let self_ty = trait_ref.map_bound(|t| t.self_ty()); + let self_ty = self_ty.subst(self.interner.tcx, bound_vars); let lowered_ty = self_ty.lower_into(self.interner); parameters[0].assert_ty_ref(self.interner).could_match( diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 60f55b02fdfd0..805cc5c71d83a 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -34,15 +34,15 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { trait_def_id, impl_def_id ); - let trait_ref = cx.tcx.impl_trait_ref(impl_def_id).unwrap(); - let is_param = matches!(trait_ref.self_ty().kind(), ty::Param(_)); + let trait_ref = cx.tcx.bound_impl_trait_ref(impl_def_id).unwrap(); + let is_param = matches!(trait_ref.0.self_ty().kind(), ty::Param(_)); let may_apply = is_param && cx.tcx.infer_ctxt().enter(|infcx| { let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id); let ty = ty.subst(infcx.tcx, substs); let param_env = EarlyBinder(param_env).subst(infcx.tcx, substs); let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); - let trait_ref = EarlyBinder(trait_ref).subst(infcx.tcx, impl_substs); + let trait_ref = trait_ref.subst(infcx.tcx, impl_substs); // Require the type the impl is implemented on to match // our type, and ignore the impl if there was a mismatch. @@ -115,7 +115,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { ), // FIXME(eddyb) compute both `trait_` and `for_` from // the post-inference `trait_ref`, as it's more accurate. - trait_: Some(trait_ref.clean(cx)), + trait_: Some(trait_ref.0.clean(cx)), for_: ty.0.clean(cx), items: cx.tcx .associated_items(impl_def_id) @@ -123,7 +123,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { .map(|x| x.clean(cx)) .collect::>(), polarity: ty::ImplPolarity::Positive, - kind: ImplKind::Blanket(box trait_ref.self_ty().clean(cx)), + kind: ImplKind::Blanket(box trait_ref.0.self_ty().clean(cx)), }), cfg: None, }); From 91afd0263269c44d57fe127f4c20748b5747113b Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Tue, 10 May 2022 22:28:50 -0400 Subject: [PATCH 5/6] Add bound_explicit_item_bounds and bound_item_bounds --- .../src/infer/error_reporting/mod.rs | 6 +- .../rustc_infer/src/infer/opaque_types.rs | 8 +-- compiler/rustc_middle/src/ty/print/pretty.rs | 10 ++-- compiler/rustc_middle/src/ty/sty.rs | 24 ++++++++ compiler/rustc_middle/src/ty/util.rs | 14 +++++ .../src/traits/project.rs | 6 +- .../src/traits/select/confirmation.rs | 51 ++++++++-------- .../src/traits/select/mod.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 6 +- compiler/rustc_typeck/src/check/closure.rs | 58 +++++++++++-------- .../rustc_typeck/src/check/compare_method.rs | 13 +++-- 11 files changed, 121 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 2a5b7e936ca78..02caae7a90a91 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1849,10 +1849,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Future::Output let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; - let bounds = self.tcx.explicit_item_bounds(*def_id); + let bounds = self.tcx.bound_explicit_item_bounds(*def_id); - for (predicate, _) in bounds { - let predicate = EarlyBinder(*predicate).subst(self.tcx, substs); + for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) { + let predicate = predicate.subst(self.tcx, substs); let output = predicate .kind() .map_bound(|kind| match kind { diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 6b2c599864c7d..92c0ed84057a6 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -9,7 +9,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::subst::{GenericArgKind, Subst}; use rustc_middle::ty::{ - self, EarlyBinder, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor, + self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor, }; use rustc_span::Span; @@ -561,11 +561,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { obligations = self.at(&cause, param_env).eq(prev, hidden_ty)?.obligations; } - let item_bounds = tcx.explicit_item_bounds(def_id); + let item_bounds = tcx.bound_explicit_item_bounds(def_id); - for (predicate, _) in item_bounds { + for predicate in item_bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) { debug!(?predicate); - let predicate = EarlyBinder(*predicate).subst(tcx, substs); + let predicate = predicate.subst(tcx, substs); let predicate = predicate.fold_with(&mut BottomUpFolder { tcx, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index e680250e7b109..4c0bc2e4337c7 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,8 +1,6 @@ use crate::mir::interpret::{AllocRange, ConstValue, GlobalAlloc, Pointer, Provenance, Scalar}; use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; -use crate::ty::{ - self, ConstInt, DefIdTree, EarlyBinder, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable, -}; +use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::ieee::{Double, Single}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sso::SsoHashSet; @@ -776,14 +774,14 @@ pub trait PrettyPrinter<'tcx>: // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. - let bounds = self.tcx().explicit_item_bounds(def_id); + let bounds = self.tcx().bound_explicit_item_bounds(def_id); let mut traits = BTreeMap::new(); let mut fn_traits = BTreeMap::new(); let mut is_sized = false; - for (predicate, _) in bounds { - let predicate = EarlyBinder(*predicate).subst(self.tcx(), substs); + for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) { + let predicate = predicate.subst(self.tcx(), substs); let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index ca8528b3350d2..a973a5c9b5053 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1109,6 +1109,30 @@ impl EarlyBinder> { } } +impl EarlyBinder<(T, U)> { + pub fn transpose_tuple2(self) -> (EarlyBinder, EarlyBinder) { + (EarlyBinder(self.0.0), EarlyBinder(self.0.1)) + } +} + +pub struct EarlyBinderIter { + t: T, +} + +impl EarlyBinder { + pub fn transpose_iter(self) -> EarlyBinderIter { + EarlyBinderIter { t: self.0.into_iter() } + } +} + +impl Iterator for EarlyBinderIter { + type Item = EarlyBinder; + + fn next(&mut self) -> Option { + self.t.next().map(|i| EarlyBinder(i)) + } +} + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(HashStable)] pub enum BoundVariableKind { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index ed0f6a7ccd108..9c345c76d0e30 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -604,6 +604,20 @@ impl<'tcx> TyCtxt<'tcx> { pub fn bound_impl_trait_ref(self, def_id: DefId) -> Option>> { self.impl_trait_ref(def_id).map(|i| EarlyBinder(i)) } + + pub fn bound_explicit_item_bounds( + self, + def_id: DefId, + ) -> EarlyBinder<&'tcx [(ty::Predicate<'tcx>, rustc_span::Span)]> { + EarlyBinder(self.explicit_item_bounds(def_id)) + } + + pub fn bound_item_bounds( + self, + def_id: DefId, + ) -> EarlyBinder<&'tcx ty::List>> { + EarlyBinder(self.item_bounds(def_id)) + } } struct OpaqueTypeExpander<'tcx> { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 004091661fa8c..beaa56e1c1ca7 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1276,10 +1276,8 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( // Check whether the self-type is itself a projection. // If so, extract what we know from the trait and try to come up with a good answer. let bounds = match *obligation.predicate.self_ty().kind() { - ty::Projection(ref data) => { - EarlyBinder(tcx.item_bounds(data.item_def_id)).subst(tcx, data.substs) - } - ty::Opaque(def_id, substs) => EarlyBinder(tcx.item_bounds(def_id)).subst(tcx, substs), + ty::Projection(ref data) => tcx.bound_item_bounds(data.item_def_id).subst(tcx, data.substs), + ty::Opaque(def_id, substs) => tcx.bound_item_bounds(def_id).subst(tcx, substs), ty::Infer(ty::TyVar(_)) => { // If the self-type is an inference variable, then it MAY wind up // being a projected type, so induce an ambiguity. diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index fe80d02595a53..b9025c98fe7b7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -174,7 +174,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), }; - let candidate_predicate = EarlyBinder(tcx.item_bounds(def_id)[idx]).subst(tcx, substs); + let candidate_predicate = + tcx.bound_item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs); let candidate = candidate_predicate .to_opt_poly_trait_pred() .expect("projection candidate is not a trait predicate") @@ -500,21 +501,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // This maybe belongs in wf, but that can't (doesn't) handle // higher-ranked things. // Prevent, e.g., `dyn Iterator`. - for bound in self.tcx().item_bounds(assoc_type) { - let subst_bound = if defs.count() == 0 { - EarlyBinder(bound).subst(tcx, trait_predicate.trait_ref.substs) - } else { - let mut substs = smallvec::SmallVec::with_capacity(defs.count()); - substs.extend(trait_predicate.trait_ref.substs.iter()); - let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = - smallvec::SmallVec::with_capacity( - bound.kind().bound_vars().len() + defs.count(), - ); - bound_vars.extend(bound.kind().bound_vars().into_iter()); - InternalSubsts::fill_single( - &mut substs, - defs, - &mut |param, _| match param.kind { + for bound in self.tcx().bound_item_bounds(assoc_type).transpose_iter() { + let subst_bound = + if defs.count() == 0 { + bound.subst(tcx, trait_predicate.trait_ref.substs) + } else { + let mut substs = smallvec::SmallVec::with_capacity(defs.count()); + substs.extend(trait_predicate.trait_ref.substs.iter()); + let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = + smallvec::SmallVec::with_capacity( + bound.0.kind().bound_vars().len() + defs.count(), + ); + bound_vars.extend(bound.0.kind().bound_vars().into_iter()); + InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param + .kind + { GenericParamDefKind::Type { .. } => { let kind = ty::BoundTyKind::Param(param.name); let bound_var = ty::BoundVariableKind::Ty(kind); @@ -553,15 +554,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) .into() } - }, - ); - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); - let assoc_ty_substs = tcx.intern_substs(&substs); - - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); - let bound = EarlyBinder(bound.kind().skip_binder()).subst(tcx, assoc_ty_substs); - tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars)) - }; + }); + let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let assoc_ty_substs = tcx.intern_substs(&substs); + + let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let bound = + EarlyBinder(bound.0.kind().skip_binder()).subst(tcx, assoc_ty_substs); + tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars)) + }; let normalized_bound = normalize_with_depth_to( self, obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ab617d16cc4f7..4f797b182c0b3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1341,7 +1341,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); } }; - let bounds = EarlyBinder(tcx.item_bounds(def_id)).subst(tcx, substs); + let bounds = tcx.bound_item_bounds(def_id).subst(tcx, substs); // The bounds returned by `item_bounds` may contain duplicates after // normalization, so try to deduplicate when possible to avoid diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 663a644a9e727..2ff32bdf97805 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2447,10 +2447,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { true, None, ); - self.normalize_ty( - span, - EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs), - ) + EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id))) + .subst(tcx, substs) } hir::TyKind::Array(ref ty, ref length) => { let length = match length { diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index df10853bf5038..c8fe046873603 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -12,7 +12,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::{InferOk, InferResult}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{self, EarlyBinder, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_span::source_map::Span; use rustc_span::DUMMY_SP; use rustc_target::spec::abi::Abi; @@ -175,19 +175,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> (Option>, Option) { match *expected_ty.kind() { ty::Opaque(def_id, substs) => { - let bounds = self.tcx.explicit_item_bounds(def_id); - let sig = bounds.iter().find_map(|(pred, span)| match pred.kind().skip_binder() { - ty::PredicateKind::Projection(proj_predicate) => self - .deduce_sig_from_projection( - Some(*span), - pred.kind().rebind(EarlyBinder(proj_predicate).subst(self.tcx, substs)), - ), - _ => None, - }); + let bounds = self.tcx.bound_explicit_item_bounds(def_id); + let sig = bounds + .transpose_iter() + .map(|e| e.map_bound(|e| *e).transpose_tuple2()) + .find_map(|(pred, span)| match pred.0.kind().skip_binder() { + ty::PredicateKind::Projection(proj_predicate) => self + .deduce_sig_from_projection( + Some(span.0), + pred.0.kind().rebind( + pred.map_bound(|_| proj_predicate).subst(self.tcx, substs), + ), + ), + _ => None, + }); let kind = bounds - .iter() - .filter_map(|(pred, _)| match pred.kind().skip_binder() { + .transpose_iter() + .map(|e| e.map_bound(|e| *e).transpose_tuple2()) + .filter_map(|(pred, _)| match pred.0.kind().skip_binder() { ty::PredicateKind::Trait(tp) => { self.tcx.fn_trait_kind_from_lang_item(tp.def_id()) } @@ -668,7 +674,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), }; - let item_bounds = self.tcx.explicit_item_bounds(def_id); + let item_bounds = self.tcx.bound_explicit_item_bounds(def_id); // Search for a pending obligation like // @@ -676,17 +682,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // where R is the return type we are expecting. This type `T` // will be our output. - let output_ty = item_bounds.iter().find_map(|&(predicate, span)| { - let bound_predicate = EarlyBinder(predicate).subst(self.tcx, substs).kind(); - if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() { - self.deduce_future_output_from_projection( - span, - bound_predicate.rebind(proj_predicate), - ) - } else { - None - } - }); + let output_ty = item_bounds + .transpose_iter() + .map(|e| e.map_bound(|e| *e).transpose_tuple2()) + .find_map(|(predicate, span)| { + let bound_predicate = predicate.subst(self.tcx, substs).kind(); + if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() + { + self.deduce_future_output_from_projection( + span.0, + bound_predicate.rebind(proj_predicate), + ) + } else { + None + } + }); debug!("deduce_future_output_from_obligations: output_ty={:?}", output_ty); output_ty diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 06304d8d7e72d..b857679520b89 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -10,7 +10,7 @@ use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::util::ExplicitSelf; -use rustc_middle::ty::{self, DefIdTree, EarlyBinder}; +use rustc_middle::ty::{self, DefIdTree}; use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::InferCtxtExt; @@ -1451,14 +1451,15 @@ pub fn check_type_bounds<'tcx>( }; let obligations = tcx - .explicit_item_bounds(trait_ty.def_id) - .iter() - .map(|&(bound, span)| { + .bound_explicit_item_bounds(trait_ty.def_id) + .transpose_iter() + .map(|e| e.map_bound(|e| *e).transpose_tuple2()) + .map(|(bound, span)| { debug!(?bound); - let concrete_ty_bound = EarlyBinder(bound).subst(tcx, rebased_substs); + let concrete_ty_bound = bound.subst(tcx, rebased_substs); debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); - traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound) + traits::Obligation::new(mk_cause(span.0), param_env, concrete_ty_bound) }) .collect(); debug!("check_type_bounds: item_bounds={:?}", obligations); From 06a1e8854c95d5be5db0bebe4630c691b604e792 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Tue, 10 May 2022 22:40:43 -0400 Subject: [PATCH 6/6] Add rustc_on_unimplemented to Subst --- compiler/rustc_middle/src/ty/subst.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 9053d74441560..48c71113d5032 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -499,6 +499,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } // Just call `foo.subst(tcx, substs)` to perform a substitution across `foo`. +#[rustc_on_unimplemented(message = "Calling `subst` must now be done through an `EarlyBinder`")] pub trait Subst<'tcx>: Sized { type Inner;