diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 8c23756db33..8bc8964bbd7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -16,9 +16,7 @@ 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, EarlyBinder, PredicateKind, Ty, -}; +use rustc_middle::ty::{self, subst::Subst, suggest_constraining_type_params, PredicateKind, Ty}; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; @@ -461,23 +459,24 @@ fn suggest_borrow_fn_like( let tcx = self.infcx.tcx; // Find out if the predicates show that the type is a Fn or FnMut - let find_fn_kind_from_did = |predicates: &[(ty::Predicate<'tcx>, Span)], substs| { - predicates.iter().find_map(|(pred, _)| { - let pred = if let Some(substs) = substs { - EarlyBinder(*pred).subst(tcx, substs).kind().skip_binder() - } else { - pred.kind().skip_binder() - }; - if let ty::PredicateKind::Trait(pred) = pred && pred.self_ty() == ty { + let find_fn_kind_from_did = + |predicates: ty::EarlyBinder<&[(ty::Predicate<'tcx>, Span)]>, substs| { + predicates.0.iter().find_map(|(pred, _)| { + let pred = if let Some(substs) = substs { + predicates.rebind(*pred).subst(tcx, substs).kind().skip_binder() + } else { + pred.kind().skip_binder() + }; + if let ty::PredicateKind::Trait(pred) = pred && pred.self_ty() == ty { if Some(pred.def_id()) == tcx.lang_items().fn_trait() { return Some(hir::Mutability::Not); } else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() { return Some(hir::Mutability::Mut); } } - None - }) - }; + None + }) + }; // If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably) // borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`. @@ -485,11 +484,12 @@ fn suggest_borrow_fn_like( // borrowed variants in a function body when we see a move error. let borrow_level = match ty.kind() { ty::Param(_) => find_fn_kind_from_did( - tcx.explicit_predicates_of(self.mir_def_id().to_def_id()).predicates, + tcx.bound_explicit_predicates_of(self.mir_def_id().to_def_id()) + .map_bound(|p| p.predicates), None, ), ty::Opaque(did, substs) => { - find_fn_kind_from_did(tcx.explicit_item_bounds(*did), Some(*substs)) + find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*did), Some(*substs)) } ty::Closure(_, substs) => match substs.as_closure().kind() { ty::ClosureKind::Fn => Some(hir::Mutability::Not), 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 ba8222dc152..936044fbe24 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::traits::Reveal; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, subst::Subst, EarlyBinder, TyCtxt}; +use rustc_middle::ty::{self, subst::Subst, TyCtxt}; use rustc_span::source_map::Span; use rustc_target::abi::{self, Abi}; use std::borrow::Cow; @@ -45,7 +45,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( "Unexpected DefKind: {:?}", ecx.tcx.def_kind(cid.instance.def_id()) ); - let layout = ecx.layout_of(EarlyBinder(body.return_ty()).subst(tcx, cid.instance.substs))?; + let layout = ecx.layout_of(body.bound_return_ty().subst(tcx, cid.instance.substs))?; assert!(!layout.is_unsized()); let ret = ecx.allocate(layout, MemoryKind::Stack)?; diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 64e158ba348..7ab71f9009d 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -431,6 +431,12 @@ pub fn return_ty(&self) -> Ty<'tcx> { self.local_decls[RETURN_PLACE].ty } + /// Returns the return type; it always return first element from `local_decls` array. + #[inline] + pub fn bound_return_ty(&self) -> ty::EarlyBinder> { + ty::EarlyBinder(self.local_decls[RETURN_PLACE].ty) + } + /// Gets the location of the terminator for the given block. #[inline] pub fn terminator_loc(&self, bb: BasicBlock) -> Location { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 809406aff18..2e596b27527 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -563,7 +563,7 @@ pub fn destructor(self, tcx: TyCtxt<'tcx>) -> Option { /// /// Due to normalization being eager, this applies even if /// the associated type is behind a pointer (e.g., issue #31299). - pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] { - tcx.adt_sized_constraint(self.did()).0 + pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> { + ty::EarlyBinder(tcx.adt_sized_constraint(self.did()).0) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index fb0a4b4e8f4..52c3a38861e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2191,7 +2191,7 @@ pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool { ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)), - ty::Adt(def, _substs) => def.sized_constraint(tcx).is_empty(), + ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(), ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 4b5bf80c071..591bb7831b5 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -680,6 +680,24 @@ pub fn bound_item_bounds( pub fn bound_const_param_default(self, def_id: DefId) -> ty::EarlyBinder> { ty::EarlyBinder(self.const_param_default(def_id)) } + + pub fn bound_predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder> { + ty::EarlyBinder(self.predicates_of(def_id)) + } + + pub fn bound_explicit_predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder> { + ty::EarlyBinder(self.explicit_predicates_of(def_id)) + } + + pub fn bound_impl_subject(self, def_id: DefId) -> ty::EarlyBinder> { + ty::EarlyBinder(self.impl_subject(def_id)) + } } struct OpaqueTypeExpander<'tcx> { diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 85ad6b8f2fe..fbc0a767f07 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -18,9 +18,7 @@ }; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; -use rustc_middle::ty::{ - self, ConstKind, EarlyBinder, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable, -}; +use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable}; use rustc_span::{def_id::DefId, Span}; use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout}; use rustc_target::spec::abi::Abi as CallAbi; @@ -387,7 +385,7 @@ fn new( ); let ret_layout = ecx - .layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs)) + .layout_of(body.bound_return_ty().subst(tcx, substs)) .ok() // Don't bother allocating memory for large values. // I don't know how return types can seem to be unsized but this happens in the diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 3ae6a88a140..c2ea55af48a 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -23,8 +23,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{ - self, ConstInt, ConstKind, EarlyBinder, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, - TypeVisitable, + self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable, }; use rustc_session::lint; use rustc_span::Span; @@ -196,7 +195,7 @@ fn new( ); let ret_layout = ecx - .layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs)) + .layout_of(body.bound_return_ty().subst(tcx, substs)) .ok() // Don't bother allocating memory for large values. // I don't know how return types can seem to be unsized but this happens in the diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 6a4f582ac50..adf47ece69d 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -32,7 +32,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable}; -use rustc_middle::ty::{self, EarlyBinder, Term, ToPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt}; use rustc_span::symbol::sym; use std::collections::BTreeMap; @@ -2005,16 +2005,16 @@ fn confirm_impl_candidate<'cx, 'tcx>( let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs); let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node); - let ty = tcx.type_of(assoc_ty.item.def_id); + let ty = tcx.bound_type_of(assoc_ty.item.def_id); let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst); - let term: ty::Term<'tcx> = if is_const { + let term: ty::EarlyBinder> = if is_const { let identity_substs = crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id); let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id); let kind = ty::ConstKind::Unevaluated(ty::Unevaluated::new(did, identity_substs)); - tcx.mk_const(ty::ConstS { ty, kind }).into() + ty.map_bound(|ty| tcx.mk_const(ty::ConstS { ty, kind }).into()) } else { - ty.into() + ty.map_bound(|ty| ty.into()) }; if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() { let err = tcx.ty_error_with_message( @@ -2024,7 +2024,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( Progress { term: err.into(), obligations: nested } } else { assoc_ty_own_obligations(selcx, obligation, &mut nested); - Progress { term: EarlyBinder(term).subst(tcx, substs), obligations: nested } + Progress { term: term.subst(tcx, substs), obligations: nested } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index d7d29005f80..c01ac197991 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1886,7 +1886,11 @@ fn sized_conditions( let sized_crit = def.sized_constraint(self.tcx()); // (*) binder moved here Where(obligation.predicate.rebind({ - sized_crit.iter().map(|ty| EarlyBinder(*ty).subst(self.tcx(), substs)).collect() + sized_crit + .0 + .iter() + .map(|ty| sized_crit.rebind(*ty).subst(self.tcx(), substs)) + .collect() })) } @@ -2357,11 +2361,11 @@ fn impl_or_trait_obligations( // obligation will normalize to `<$0 as Iterator>::Item = $1` and // `$1: Copy`, so we must ensure the obligations are emitted in // that order. - let predicates = tcx.predicates_of(def_id); + let predicates = tcx.bound_predicates_of(def_id); debug!(?predicates); - assert_eq!(predicates.parent, None); - let mut obligations = Vec::with_capacity(predicates.predicates.len()); - for (predicate, span) in predicates.predicates { + assert_eq!(predicates.0.parent, None); + let mut obligations = Vec::with_capacity(predicates.0.predicates.len()); + for (predicate, span) in predicates.0.predicates { let span = *span; let cause = cause.clone().derived_cause(parent_trait_pred, |derived| { ImplDerivedObligation(Box::new(ImplDerivedObligationCause { @@ -2375,7 +2379,7 @@ fn impl_or_trait_obligations( param_env, cause.clone(), recursion_depth, - EarlyBinder(*predicate).subst(tcx, substs), + predicates.rebind(*predicate).subst(tcx, substs), &mut obligations, ); obligations.push(Obligation { cause, recursion_depth, param_env, predicate }); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index b9259196c48..d2500601662 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -6,7 +6,7 @@ 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, EarlyBinder, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable}; use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; pub use rustc_infer::traits::{self, util::*}; @@ -200,8 +200,8 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( impl_def_id: DefId, impl_substs: SubstsRef<'tcx>, ) -> (ImplSubject<'tcx>, impl Iterator>) { - let subject = selcx.tcx().impl_subject(impl_def_id); - let subject = EarlyBinder(subject).subst(selcx.tcx(), impl_substs); + let subject = selcx.tcx().bound_impl_subject(impl_def_id); + let subject = 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 14a60ace441..ff5ca0cbcb7 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -51,11 +51,11 @@ fn bounds_for(&self, def_id: DefId, bound_vars: SubstsRef<'tcx>) -> Vec where ty::Predicate<'tcx>: LowerInto<'tcx, std::option::Option>, { - self.interner - .tcx - .explicit_item_bounds(def_id) + let bounds = self.interner.tcx.bound_explicit_item_bounds(def_id); + bounds + .0 .iter() - .map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars)) + .map(|(bound, _)| bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars)) .filter_map(|bound| LowerInto::>::lower_into(bound, self.interner)) .collect() } @@ -268,21 +268,20 @@ fn fn_def_datum( let where_clauses = self.where_clauses_for(def_id, bound_vars); - let sig = self.interner.tcx.fn_sig(def_id); + let sig = self.interner.tcx.bound_fn_sig(def_id); let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars( self.interner, self.interner.tcx, - EarlyBinder(sig.inputs_and_output()).subst(self.interner.tcx, bound_vars), + sig.map_bound(|s| s.inputs_and_output()).subst(self.interner.tcx, bound_vars), ); let argument_types = inputs_and_output[..inputs_and_output.len() - 1] .iter() - .map(|t| { - EarlyBinder(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner) - }) + .map(|t| sig.rebind(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner)) .collect(); - let return_type = EarlyBinder(inputs_and_output[inputs_and_output.len() - 1]) + let return_type = sig + .rebind(inputs_and_output[inputs_and_output.len() - 1]) .subst(self.interner.tcx, &bound_vars) .lower_into(self.interner); @@ -295,7 +294,7 @@ fn fn_def_datum( }; Arc::new(chalk_solve::rust_ir::FnDefDatum { id: fn_def_id, - sig: sig.lower_into(self.interner), + sig: sig.0.lower_into(self.interner), binders: chalk_ir::Binders::new(binders, bound), }) } @@ -503,12 +502,14 @@ fn opaque_ty_data( let identity_substs = InternalSubsts::identity_for_item(self.interner.tcx, opaque_ty_id.0); + let explicit_item_bounds = self.interner.tcx.bound_explicit_item_bounds(opaque_ty_id.0); let bounds = - self.interner - .tcx - .explicit_item_bounds(opaque_ty_id.0) + explicit_item_bounds + .0 .iter() - .map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars)) + .map(|(bound, _)| { + explicit_item_bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars) + }) .map(|bound| { bound.fold_with(&mut ReplaceOpaqueTyFolder { tcx: self.interner.tcx, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 7007e76b86e..db0d45b86fc 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -2,9 +2,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{ - self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, -}; +use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt}; use rustc_trait_selection::traits; fn sized_constraint_for_ty<'tcx>( @@ -33,8 +31,9 @@ fn sized_constraint_for_ty<'tcx>( let adt_tys = adt.sized_constraint(tcx); debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); adt_tys + .0 .iter() - .map(|ty| EarlyBinder(*ty).subst(tcx, substs)) + .map(|ty| adt_tys.rebind(*ty).subst(tcx, substs)) .flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty)) .collect() } diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 95f32711225..d0334cd0df7 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -15,8 +15,8 @@ use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst}; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ - self, AdtKind, DefIdTree, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, TyCtxt, - TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, AdtKind, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use rustc_session::parse::feature_err; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -1295,7 +1295,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let infcx = wfcx.infcx; let tcx = wfcx.tcx(); - let predicates = tcx.predicates_of(def_id); + let predicates = tcx.bound_predicates_of(def_id.to_def_id()); let generics = tcx.generics_of(def_id); let is_our_default = |def: &ty::GenericParamDef| match def.kind { @@ -1392,6 +1392,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id // Now we build the substituted predicates. let default_obligations = predicates + .0 .predicates .iter() .flat_map(|&(pred, sp)| { @@ -1422,7 +1423,7 @@ fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow { } let mut param_count = CountParams::default(); let has_region = pred.visit_with(&mut param_count).is_break(); - let substituted_pred = EarlyBinder(pred).subst(tcx, substs); + let substituted_pred = predicates.rebind(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() @@ -1430,7 +1431,7 @@ fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow { || has_region { None - } else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { + } else if predicates.0.predicates.iter().any(|&(p, _)| p == substituted_pred) { // Avoid duplication of predicates that contain no parameters, for example. None } else { @@ -1456,7 +1457,7 @@ fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow { traits::Obligation::new(cause, wfcx.param_env, pred) }); - let predicates = predicates.instantiate_identity(tcx); + let predicates = predicates.0.instantiate_identity(tcx); let predicates = wfcx.normalize(span, None, predicates);