diff options
| author | Jack Huey <31162821+jackh726@users.noreply.github.com> | 2022-05-08 01:17:58 -0400 |
|---|---|---|
| committer | Jack Huey <31162821+jackh726@users.noreply.github.com> | 2022-05-10 22:47:18 -0400 |
| commit | 319575ae8c3f6ea5db1c850c8f4c786c8cc203fe (patch) | |
| tree | 3ae4430bed06270beb9e8eae4dfde2a8be7e90f3 /compiler/rustc_trait_selection/src/traits | |
| parent | ecd44958e0a21110d09862ee080d95a4ca6c52f8 (diff) | |
Introduce EarlyBinder
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits')
10 files changed, 62 insertions, 58 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 24110d30a84..e584cac57f1 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 5daa9796d12..27ce08ea045 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 9e9c230aebb..86c93867c75 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 e1b6ed92269..e3e384798d3 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 be4d734b964..058308420ed 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 ed0ad5601aa..10e64eed3b8 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 771a3072af5..e6f9fbc6c03 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<Item = str>`. 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<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`. - 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 6584d33032a..8bab8353ab6 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 49c8c56083f..b6a4d100341 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 d101f69096f..f2e31c068a0 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<Item = PredicateObligation<'tcx>>) { 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); |
