diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index c8d66cbb695d8..71ce50f745372 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -525,10 +525,10 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { result_subst: &'a CanonicalVarValues<'tcx>, ) -> impl Iterator> + 'a + Captures<'tcx> { unsubstituted_region_constraints.iter().map(move |&constraint| { - let ty::OutlivesPredicate(k1, r2) = - substitute_value(self.tcx, result_subst, constraint).skip_binder(); + let predicate = substitute_value(self.tcx, result_subst, constraint); + let ty::OutlivesPredicate(k1, r2) = predicate.skip_binder(); - let predicate = match k1.unpack() { + let atom = match k1.unpack() { GenericArgKind::Lifetime(r1) => { ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2)) } @@ -540,8 +540,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // encounter this branch. span_bug!(cause.span, "unexpected const outlives {:?}", constraint); } - } - .potentially_quantified(self.tcx, ty::PredicateKind::ForAll); + }; + let predicate = + predicate.rebind(atom).potentially_quantified(self.tcx, ty::PredicateKind::ForAll); Obligation::new(cause.clone(), param_env, predicate) }) diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 6a1715ef81899..7770f2bd91155 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -551,7 +551,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { where T: Relate<'tcx>, { - Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) + Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } fn relate_item_substs( @@ -833,7 +833,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { where T: Relate<'tcx>, { - Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) + Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 0b2847658f71e..b9bd66e4b929f 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -1008,6 +1008,6 @@ where self.first_free_index.shift_in(1); let result = self.relate(a.skip_binder(), a.skip_binder())?; self.first_free_index.shift_out(1); - Ok(ty::Binder::bind(result)) + Ok(a.rebind(result)) } } diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index 27bccc0bcafa4..a5962e3b3ba57 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -118,6 +118,6 @@ impl TypeRelation<'tcx> for Match<'tcx> { where T: Relate<'tcx>, { - Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) + Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index adf02412b96d3..615972ae45c92 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -299,6 +299,7 @@ pub struct ResolvedOpaqueTy<'tcx> { /// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for /// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`. #[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)] +#[derive(TypeFoldable)] pub struct GeneratorInteriorTypeCause<'tcx> { /// Type of the captured binding. pub ty: Ty<'tcx>, @@ -423,7 +424,7 @@ pub struct TypeckResults<'tcx> { /// Stores the type, expression, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). - pub generator_interior_types: Vec>, + pub generator_interior_types: ty::Binder>>, /// We sometimes treat byte string literals (which are of type `&[u8; N]`) /// as `&[u8]`, depending on the pattern in which they are used. @@ -455,7 +456,7 @@ impl<'tcx> TypeckResults<'tcx> { concrete_opaque_types: Default::default(), closure_captures: Default::default(), closure_min_captures: Default::default(), - generator_interior_types: Default::default(), + generator_interior_types: ty::Binder::dummy(Default::default()), treat_byte_string_as_slice: Default::default(), } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7428f34153c87..98602d6a459b2 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1149,17 +1149,16 @@ pub enum PredicateAtom<'tcx> { TypeWellFormedFromEnv(Ty<'tcx>), } -impl<'tcx> PredicateAtom<'tcx> { +impl<'tcx> Binder> { /// Wraps `self` with the given qualifier if this predicate has any unbound variables. pub fn potentially_quantified( self, tcx: TyCtxt<'tcx>, qualifier: impl FnOnce(Binder>) -> PredicateKind<'tcx>, ) -> Predicate<'tcx> { - if self.has_escaping_bound_vars() { - qualifier(Binder::bind(self)) - } else { - PredicateKind::Atom(self) + match self.no_bound_vars() { + Some(atom) => PredicateKind::Atom(atom), + None => qualifier(self), } .to_predicate(tcx) } @@ -1252,7 +1251,11 @@ impl<'tcx> Predicate<'tcx> { let substs = trait_ref.skip_binder().substs; let pred = self.skip_binders(); let new = pred.subst(tcx, substs); - if new != pred { new.potentially_quantified(tcx, PredicateKind::ForAll) } else { self } + if new != pred { + ty::Binder::bind(new).potentially_quantified(tcx, PredicateKind::ForAll) + } else { + self + } } } @@ -1279,6 +1282,10 @@ impl<'tcx> PolyTraitPredicate<'tcx> { // Ok to skip binder since trait `DefId` does not care about regions. self.skip_binder().def_id() } + + pub fn self_ty(self) -> ty::Binder> { + self.map_bound(|trait_ref| trait_ref.self_ty()) + } } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] @@ -1403,37 +1410,39 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateAtom::Trait(self.value.skip_binder(), self.constness) + self.value + .map_bound(|value| PredicateAtom::Trait(value, self.constness)) .potentially_quantified(tcx, PredicateKind::ForAll) } } impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateAtom::RegionOutlives(self.skip_binder()) + self.map_bound(|value| PredicateAtom::RegionOutlives(value)) .potentially_quantified(tcx, PredicateKind::ForAll) } } impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateAtom::TypeOutlives(self.skip_binder()) + self.map_bound(|value| PredicateAtom::TypeOutlives(value)) .potentially_quantified(tcx, PredicateKind::ForAll) } } impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateAtom::Projection(self.skip_binder()) + self.map_bound(|value| PredicateAtom::Projection(value)) .potentially_quantified(tcx, PredicateKind::ForAll) } } impl<'tcx> Predicate<'tcx> { pub fn to_opt_poly_trait_ref(self) -> Option>> { - match self.skip_binders() { + let predicate = self.bound_atom(); + match predicate.skip_binder() { PredicateAtom::Trait(t, constness) => { - Some(ConstnessAnd { constness, value: ty::Binder::bind(t.trait_ref) }) + Some(ConstnessAnd { constness, value: predicate.rebind(t.trait_ref) }) } PredicateAtom::Projection(..) | PredicateAtom::Subtype(..) @@ -1449,8 +1458,9 @@ impl<'tcx> Predicate<'tcx> { } pub fn to_opt_type_outlives(self) -> Option> { - match self.skip_binders() { - PredicateAtom::TypeOutlives(data) => Some(ty::Binder::bind(data)), + let predicate = self.bound_atom(); + match predicate.skip_binder() { + PredicateAtom::TypeOutlives(data) => Some(predicate.rebind(data)), PredicateAtom::Trait(..) | PredicateAtom::Projection(..) | PredicateAtom::Subtype(..) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 5c185dc4a9f1a..b4b71a48ce9d2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1151,9 +1151,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ) -> DiagnosticBuilder<'tcx> { crate fn build_fn_sig_string<'tcx>( tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, ) -> String { - let inputs = trait_ref.substs.type_at(1); + let inputs = trait_ref.skip_binder().substs.type_at(1); let sig = if let ty::Tuple(inputs) = inputs.kind() { tcx.mk_fn_sig( inputs.iter().map(|k| k.expect_ty()), @@ -1171,7 +1171,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { abi::Abi::Rust, ) }; - ty::Binder::bind(sig).to_string() + trait_ref.rebind(sig).to_string() } let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure(); @@ -1183,17 +1183,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if argument_is_closure { "closure" } else { "function" } ); - let found_str = format!( - "expected signature of `{}`", - build_fn_sig_string(self.tcx, found.skip_binder()) - ); + let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found)); err.span_label(span, found_str); let found_span = found_span.unwrap_or(span); - let expected_str = format!( - "found signature of `{}`", - build_fn_sig_string(self.tcx, expected_ref.skip_binder()) - ); + let expected_str = + format!("found signature of `{}`", build_fn_sig_string(self.tcx, expected_ref)); err.span_label(found_span, expected_str); err @@ -1422,7 +1417,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // generator frame. Bound regions are preserved by // `erase_regions` and so we must also call // `erase_late_bound_regions`. - let ty_erased = self.tcx.erase_late_bound_regions(ty::Binder::bind(ty)); + let ty_erased = self.tcx.erase_late_bound_regions(ty); let ty_erased = self.tcx.erase_regions(ty_erased); let eq = ty::TyS::same_type(ty_erased, target_ty_erased); debug!( @@ -1440,7 +1435,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { interior_or_upvar_span = upvars.iter().find_map(|(upvar_id, upvar)| { let upvar_ty = typeck_results.node_type(*upvar_id); let upvar_ty = self.resolve_vars_if_possible(upvar_ty); - if ty_matches(&upvar_ty) { + if ty_matches(ty::Binder::dummy(upvar_ty)) { Some(GeneratorInteriorOrUpvar::Upvar(upvar.span)) } else { None @@ -1448,10 +1443,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }); }; - if let Some(cause) = typeck_results - .generator_interior_types - .iter() - .find(|ty::GeneratorInteriorTypeCause { ty, .. }| ty_matches(ty)) + // The generator interior types share the same binders + if let Some(cause) = + typeck_results.generator_interior_types.as_ref().skip_binder().iter().find( + |ty::GeneratorInteriorTypeCause { ty, .. }| { + ty_matches(typeck_results.generator_interior_types.rebind(ty)) + }, + ) { // Check to see if any awaited expressions have the target type. let from_awaited_ty = visitor @@ -1464,7 +1462,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { "maybe_note_obligation_cause_for_async_await: await_expr={:?}", await_expr ); - ty_matches(ty) + ty_matches(ty::Binder::dummy(ty)) }) .map(|expr| expr.span); let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause; diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 8b275db89f191..8b6e30f34fd4a 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -418,11 +418,11 @@ fn virtual_call_violation_for_method<'tcx>( } for (i, &input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() { - if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) { + if contains_illegal_self_type_reference(tcx, trait_def_id, sig.rebind(input_ty)) { return Some(MethodViolationCode::ReferencesSelfInput(i)); } } - if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output().skip_binder()) { + if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) { return Some(MethodViolationCode::ReferencesSelfOutput); } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index df472e6ed7e9d..a11499e43209f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -951,7 +951,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // If we are resolving `>::Item == Type`, // start out by selecting the predicate `T as TraitRef<...>`: - let poly_trait_ref = obligation_trait_ref.to_poly_trait_ref(); + let poly_trait_ref = ty::Binder::dummy(*obligation_trait_ref); let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate()); let _ = selcx.infcx().commit_if_ok(|_| { let impl_source = match selcx.select(&trait_obligation) { @@ -1247,7 +1247,9 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>( ty: self_ty.discriminant_ty(tcx), }; - confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate), false) + // We get here from `poly_project_and_unify_type` which replaces bound vars + // with placeholders, so dummy is okay here. + confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false) } fn confirm_fn_pointer_candidate<'cx, 'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index ab09fcfd8cc7b..81de6dc71f466 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -259,10 +259,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> ImplSourceAutoImplData> { debug!(?obligation, ?trait_def_id, "confirm_auto_impl_candidate"); - let types = obligation.predicate.map_bound(|inner| { - let self_ty = self.infcx.shallow_resolve(inner.self_ty()); - self.constituent_types_for_ty(self_ty) - }); + let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty()); + let types = self.constituent_types_for_ty(self_ty); self.vtable_auto_impl(obligation, trait_def_id, types) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 74b6652981a8b..f1c86eab0956e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1276,7 +1276,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // FIXME(generic_associated_types): Compare the whole projections let data_poly_trait_ref = projection_ty.map_bound(|proj| proj.trait_ref(self.tcx())); - let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref(); + let obligation_poly_trait_ref = ty::Binder::dummy(*obligation_trait_ref); self.infcx .at(&obligation.cause, obligation.param_env) .sup(obligation_poly_trait_ref, data_poly_trait_ref) @@ -1648,8 +1648,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Bar where struct Bar { x: T, y: u32 } -> [i32, u32] /// Zed where enum Zed { A(T), B(u32) } -> [i32, u32] /// ``` - fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec> { - match *t.kind() { + fn constituent_types_for_ty(&self, t: ty::Binder>) -> ty::Binder>> { + match *t.skip_binder().kind() { ty::Uint(_) | ty::Int(_) | ty::Bool @@ -1660,7 +1660,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Error(_) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Never - | ty::Char => Vec::new(), + | ty::Char => ty::Binder::dummy(Vec::new()), ty::Placeholder(..) | ty::Dynamic(..) @@ -1673,44 +1673,44 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::RawPtr(ty::TypeAndMut { ty: element_ty, .. }) | ty::Ref(_, element_ty, _) => { - vec![element_ty] + t.rebind(vec![element_ty]) } - ty::Array(element_ty, _) | ty::Slice(element_ty) => vec![element_ty], + ty::Array(element_ty, _) | ty::Slice(element_ty) => t.rebind(vec![element_ty]), ty::Tuple(ref tys) => { // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet - tys.iter().map(|k| k.expect_ty()).collect() + t.rebind(tys.iter().map(|k| k.expect_ty()).collect()) } ty::Closure(_, ref substs) => { let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty()); - vec![ty] + t.rebind(vec![ty]) } ty::Generator(_, ref substs, _) => { let ty = self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty()); let witness = substs.as_generator().witness(); - vec![ty].into_iter().chain(iter::once(witness)).collect() + t.rebind(vec![ty].into_iter().chain(iter::once(witness)).collect()) } ty::GeneratorWitness(types) => { - // This is sound because no regions in the witness can refer to - // the binder outside the witness. So we'll effectivly reuse - // the implicit binder around the witness. - types.skip_binder().to_vec() + debug_assert!(!types.has_escaping_bound_vars()); + types.map_bound(|types| types.to_vec()) } // For `PhantomData`, we pass `T`. - ty::Adt(def, substs) if def.is_phantom_data() => substs.types().collect(), + ty::Adt(def, substs) if def.is_phantom_data() => t.rebind(substs.types().collect()), - ty::Adt(def, substs) => def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect(), + ty::Adt(def, substs) => { + t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect()) + } ty::Opaque(def_id, substs) => { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)] + t.rebind(vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)]) } } } @@ -1738,10 +1738,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // 3. Re-bind the regions back to `for<'a> &'a i32 : Copy` types + .as_ref() .skip_binder() // binder moved -\ .iter() .flat_map(|ty| { - let ty: ty::Binder> = ty::Binder::bind(ty); // <----/ + let ty: ty::Binder> = types.rebind(ty); // <----/ self.infcx.commit_unconditionally(|_| { let placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index ab4a81c7d152e..8888ea2c8490c 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, ToPredicate, Ty, TyCtxt, WithConstness}; +use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; pub use rustc_infer::traits::util::*; @@ -333,11 +333,12 @@ pub fn closure_trait_ref_and_return_type( TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), }; + debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]), }; - ty::Binder::bind((trait_ref, sig.skip_binder().output())) + sig.map_bound(|sig| (trait_ref, sig.output())) } pub fn generator_trait_ref_and_outputs( @@ -346,11 +347,12 @@ pub fn generator_trait_ref_and_outputs( self_ty: Ty<'tcx>, sig: ty::PolyGenSig<'tcx>, ) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { + debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]), }; - ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty)) + sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty)) } pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool { diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 693cd236299a8..c470659e18a45 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -837,9 +837,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .instantiate_lang_item_trait_ref( lang_item, span, hir_id, args, param_ty, bounds, ), - hir::GenericBound::Outlives(ref l) => { - bounds.region_bounds.push((self.ast_region_to_region(l, None), l.span)) - } + hir::GenericBound::Outlives(ref l) => bounds + .region_bounds + .push((ty::Binder::bind(self.ast_region_to_region(l, None)), l.span)), } } } diff --git a/compiler/rustc_typeck/src/bounds.rs b/compiler/rustc_typeck/src/bounds.rs index 497754f20e4c5..7ba90ad88193f 100644 --- a/compiler/rustc_typeck/src/bounds.rs +++ b/compiler/rustc_typeck/src/bounds.rs @@ -26,7 +26,7 @@ pub struct Bounds<'tcx> { /// A list of region bounds on the (implicit) self type. So if you /// had `T: 'a + 'b` this might would be a list `['a, 'b]` (but /// the `T` is not explicitly included). - pub region_bounds: Vec<(ty::Region<'tcx>, Span)>, + pub region_bounds: Vec<(ty::Binder>, Span)>, /// A list of trait bounds. So if you had `T: Debug` this would be /// `T: Debug`. Note that the self-type is explicit here. @@ -68,8 +68,12 @@ impl<'tcx> Bounds<'tcx> { sized_predicate .into_iter() .chain(self.region_bounds.iter().map(|&(region_bound, span)| { - let outlives = ty::OutlivesPredicate(param_ty, region_bound); - (ty::Binder::bind(outlives).to_predicate(tcx), span) + ( + region_bound + .map_bound(|region_bound| ty::OutlivesPredicate(param_ty, region_bound)) + .to_predicate(tcx), + span, + ) })) .chain(self.trait_bounds.iter().map(|&(bound_trait_ref, span, constness)| { let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx); diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index ebfb401fcf3ad..22e287320d842 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -389,7 +389,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // In that case, we check each argument against "error" in order to // set up all the node type bindings. ( - ty::Binder::bind(self.tcx.mk_fn_sig( + ty::Binder::dummy(self.tcx.mk_fn_sig( self.err_args(arg_exprs.len()).into_iter(), self.tcx.ty_error(), false, diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 8082a230216e2..7470c1a76a943 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -24,7 +24,7 @@ use std::iter; struct ExpectedSig<'tcx> { /// Span that gave us this expectation, if we know that. cause_span: Option, - sig: ty::FnSig<'tcx>, + sig: ty::PolyFnSig<'tcx>, } struct ClosureSignatures<'tcx> { @@ -174,7 +174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), ty::FnPtr(sig) => { - let expected_sig = ExpectedSig { cause_span: None, sig: sig.skip_binder() }; + let expected_sig = ExpectedSig { cause_span: None, sig }; (Some(expected_sig), Some(ty::ClosureKind::Fn)) } _ => (None, None), @@ -274,13 +274,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty); debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty); - let sig = self.tcx.mk_fn_sig( + let sig = projection.rebind(self.tcx.mk_fn_sig( input_tys.iter(), &ret_param_ty, false, hir::Unsafety::Normal, Abi::Rust, - ); + )); debug!("deduce_sig_from_projection: sig={:?}", sig); Some(ExpectedSig { cause_span, sig }) @@ -374,9 +374,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Watch out for some surprises and just ignore the // expectation if things don't see to match up with what we // expect. - if expected_sig.sig.c_variadic != decl.c_variadic { + if expected_sig.sig.c_variadic() != decl.c_variadic { return self.sig_of_closure_no_expectation(expr_def_id, decl, body); - } else if expected_sig.sig.inputs_and_output.len() != decl.inputs.len() + 1 { + } else if expected_sig.sig.skip_binder().inputs_and_output.len() != decl.inputs.len() + 1 { return self.sig_of_closure_with_mismatched_number_of_arguments( expr_def_id, decl, @@ -388,14 +388,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Create a `PolyFnSig`. Note the oddity that late bound // regions appearing free in `expected_sig` are now bound up // in this binder we are creating. - assert!(!expected_sig.sig.has_vars_bound_above(ty::INNERMOST)); - let bound_sig = ty::Binder::bind(self.tcx.mk_fn_sig( - expected_sig.sig.inputs().iter().cloned(), - expected_sig.sig.output(), - decl.c_variadic, - hir::Unsafety::Normal, - Abi::RustCall, - )); + assert!(!expected_sig.sig.skip_binder().has_vars_bound_above(ty::INNERMOST)); + let bound_sig = expected_sig.sig.map_bound(|sig| { + self.tcx.mk_fn_sig( + sig.inputs().iter().cloned(), + sig.output(), + sig.c_variadic, + hir::Unsafety::Normal, + Abi::RustCall, + ) + }); // `deduce_expectations_from_expected_type` introduces // late-bound lifetimes defined elsewhere, which we now @@ -428,6 +430,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_map_node = hir.get_if_local(expr_def_id).unwrap(); let expected_args: Vec<_> = expected_sig .sig + .skip_binder() .inputs() .iter() .map(|ty| ArgKind::from_expected_ty(ty, None)) @@ -500,7 +503,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (supplied_ty, _) = self.infcx.replace_bound_vars_with_fresh_vars( hir_ty.span, LateBoundRegionConversionTime::FnCall, - ty::Binder::bind(supplied_ty), + supplied_sig.inputs().rebind(supplied_ty), ); // recreated from (*) above // Check that E' = S'. @@ -619,12 +622,11 @@ 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 = self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| { - if let ty::PredicateAtom::Projection(proj_predicate) = - obligation.predicate.skip_binders() - { + let bound_predicate = obligation.predicate.bound_atom(); + if let ty::PredicateAtom::Projection(proj_predicate) = bound_predicate.skip_binder() { self.deduce_future_output_from_projection( obligation.cause.span, - ty::Binder::bind(proj_predicate), + bound_predicate.rebind(proj_predicate), ) } else { None @@ -704,7 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { astconv.ast_ty_to_ty(&output); } - let result = ty::Binder::bind(self.tcx.mk_fn_sig( + let result = ty::Binder::dummy(self.tcx.mk_fn_sig( supplied_arguments, self.tcx.ty_error(), decl.c_variadic, diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 20090d3760600..bb324d0d8bc1e 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -494,12 +494,11 @@ fn compare_self_type<'tcx>( ty::ImplContainer(_) => impl_trait_ref.self_ty(), ty::TraitContainer(_) => tcx.types.self_param, }; - let self_arg_ty = tcx.fn_sig(method.def_id).input(0).skip_binder(); + let self_arg_ty = tcx.fn_sig(method.def_id).input(0); let param_env = ty::ParamEnv::reveal_all(); tcx.infer_ctxt().enter(|infcx| { - let self_arg_ty = - tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(self_arg_ty)); + let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty); let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok(); match ExplicitSelf::determine(self_arg_ty, can_eq_self) { ExplicitSelf::ByValue => "self".to_owned(), diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index e1a2f593b8d9b..41a403a010ee6 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -764,12 +764,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .pending_obligations() .into_iter() .filter_map(move |obligation| { - match obligation.predicate.skip_binders() { + let bound_predicate = obligation.predicate.bound_atom(); + match bound_predicate.skip_binder() { ty::PredicateAtom::Projection(data) => { - Some((ty::Binder::bind(data).to_poly_trait_ref(self.tcx), obligation)) + Some((bound_predicate.rebind(data).to_poly_trait_ref(self.tcx), obligation)) } ty::PredicateAtom::Trait(data, _) => { - Some((ty::Binder::bind(data).to_poly_trait_ref(), obligation)) + Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation)) } ty::PredicateAtom::Subtype(..) => None, ty::PredicateAtom::RegionOutlives(..) => None, diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 5bc40d617d044..54710e12a746d 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -204,7 +204,8 @@ pub fn resolve_interior<'a, 'tcx>( let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list)); // Store the generator types and spans into the typeck results for this generator. - visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types = type_causes; + visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types = + ty::Binder::bind(type_causes); debug!( "types in generator after region replacement {:?}, span = {:?}", diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index e2712a3033995..dd629980ab4db 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -12,7 +12,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; @@ -23,10 +23,7 @@ fn equate_intrinsic_type<'tcx>( it: &hir::ForeignItem<'_>, def_id: DefId, n_tps: usize, - abi: Abi, - safety: hir::Unsafety, - inputs: Vec>, - output: Ty<'tcx>, + sig: ty::PolyFnSig<'tcx>, ) { match it.kind { hir::ForeignItemKind::Fn(..) => {} @@ -53,13 +50,7 @@ fn equate_intrinsic_type<'tcx>( return; } - let fty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig( - inputs.into_iter(), - output, - false, - safety, - abi, - ))); + let fty = tcx.mk_fn_ptr(sig); let cause = ObligationCause::new(it.span, it.hir_id, ObligationCauseCode::IntrinsicType); require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(def_id)), fty); } @@ -380,7 +371,9 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }; (n_tps, inputs, output, unsafety) }; - equate_intrinsic_type(tcx, it, def_id, n_tps, Abi::RustIntrinsic, unsafety, inputs, output) + let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic); + let sig = ty::Binder::bind(sig); + equate_intrinsic_type(tcx, it, def_id, n_tps, sig) } /// Type-check `extern "platform-intrinsic" { ... }` functions. @@ -466,14 +459,13 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) } }; - equate_intrinsic_type( - tcx, - it, - def_id, - n_tps, - Abi::PlatformIntrinsic, - hir::Unsafety::Unsafe, - inputs, + let sig = tcx.mk_fn_sig( + inputs.into_iter(), output, - ) + false, + hir::Unsafety::Unsafe, + Abi::PlatformIntrinsic, + ); + let sig = ty::Binder::dummy(sig); + equate_intrinsic_type(tcx, it, def_id, n_tps, sig) } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index c70554cc62725..543e39af66944 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1919,10 +1919,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP } else { let span = bound_pred.bounded_ty.span; let re_root_empty = tcx.lifetimes.re_root_empty; - let predicate = ty::OutlivesPredicate(ty, re_root_empty); + let predicate = ty::Binder::bind(ty::PredicateAtom::TypeOutlives( + ty::OutlivesPredicate(ty, re_root_empty), + )); predicates.insert(( - ty::PredicateAtom::TypeOutlives(predicate) - .potentially_quantified(tcx, ty::PredicateKind::ForAll), + predicate.potentially_quantified(tcx, ty::PredicateKind::ForAll), span, )); } @@ -1965,8 +1966,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP &hir::GenericBound::Outlives(ref lifetime) => { let region = AstConv::ast_region_to_region(&icx, lifetime, None); predicates.insert(( - ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty, region)) - .potentially_quantified(tcx, ty::PredicateKind::ForAll), + ty::Binder::bind(ty::PredicateAtom::TypeOutlives( + ty::OutlivesPredicate(ty, region), + )) + .potentially_quantified(tcx, ty::PredicateKind::ForAll), lifetime.span, )); } @@ -1983,9 +1986,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP } _ => bug!(), }; - let pred = ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2)); + let pred = ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2)) + .to_predicate(icx.tcx); - (pred.potentially_quantified(icx.tcx, ty::PredicateKind::ForAll), span) + (pred, span) })) } @@ -2234,7 +2238,7 @@ fn predicates_from_bound<'tcx>( hir::GenericBound::Outlives(ref lifetime) => { let region = astconv.ast_region_to_region(lifetime, None); let pred = ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(param_ty, region)) - .potentially_quantified(astconv.tcx(), ty::PredicateKind::ForAll); + .to_predicate(astconv.tcx()); vec![(pred, lifetime.span)] } } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 929c88455f041..dde4a62ffbf3d 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -226,19 +226,21 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: LocalDefId) { let expected_return_type = if tcx.lang_items().termination().is_some() { // we take the return type of the given main function, the real check is done // in `check_fn` - actual.output().skip_binder() + actual.output() } else { // standard () main return type - tcx.mk_unit() + ty::Binder::dummy(tcx.mk_unit()) }; - let se_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig( - iter::empty(), - expected_return_type, - false, - hir::Unsafety::Normal, - Abi::Rust, - ))); + let se_ty = tcx.mk_fn_ptr(expected_return_type.map_bound(|expected_return_type| { + tcx.mk_fn_sig( + iter::empty(), + expected_return_type, + false, + hir::Unsafety::Normal, + Abi::Rust, + ) + })); require_same_types( tcx, diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs index 94926f480e23e..b1f79331d5f62 100644 --- a/compiler/rustc_typeck/src/outlives/mod.rs +++ b/compiler/rustc_typeck/src/outlives/mod.rs @@ -3,7 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt}; +use rustc_middle::ty::{self, CratePredicatesMap, ToPredicate, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -90,14 +90,14 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CratePredica match kind1.unpack() { GenericArgKind::Type(ty1) => Some(( ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty1, region2)) - .potentially_quantified(tcx, ty::PredicateKind::ForAll), + .to_predicate(tcx), span, )), GenericArgKind::Lifetime(region1) => Some(( ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate( region1, region2, )) - .potentially_quantified(tcx, ty::PredicateKind::ForAll), + .to_predicate(tcx), span, )), GenericArgKind::Const(_) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2809e85761d41..a5f23dac04477 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -469,8 +469,9 @@ impl Clean for hir::WherePredicate<'_> { impl<'a> Clean> for ty::Predicate<'a> { fn clean(&self, cx: &DocContext<'_>) -> Option { - match self.skip_binders() { - ty::PredicateAtom::Trait(pred, _) => Some(ty::Binder::bind(pred).clean(cx)), + let bound_predicate = self.bound_atom(); + match bound_predicate.skip_binder() { + ty::PredicateAtom::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)), ty::PredicateAtom::RegionOutlives(pred) => pred.clean(cx), ty::PredicateAtom::TypeOutlives(pred) => pred.clean(cx), ty::PredicateAtom::Projection(pred) => Some(pred.clean(cx)), @@ -733,7 +734,8 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx .flat_map(|(p, _)| { let mut projection = None; let param_idx = (|| { - match p.skip_binders() { + let bound_p = p.bound_atom(); + match bound_p.skip_binder() { ty::PredicateAtom::Trait(pred, _constness) => { if let ty::Param(param) = pred.self_ty().kind() { return Some(param.index); @@ -746,7 +748,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx } ty::PredicateAtom::Projection(p) => { if let ty::Param(param) = p.projection_ty.self_ty().kind() { - projection = Some(ty::Binder::bind(p)); + projection = Some(bound_p.rebind(p)); return Some(param.index); } } @@ -1659,12 +1661,10 @@ impl<'tcx> Clean for Ty<'tcx> { .filter_map(|bound| { // Note: The substs of opaque types can contain unbound variables, // meaning that we have to use `ignore_quantifiers_with_unbound_vars` here. - let trait_ref = match bound - .bound_atom_with_opt_escaping(cx.tcx) - .skip_binder() - { + let bound_predicate = bound.bound_atom_with_opt_escaping(cx.tcx); + let trait_ref = match bound_predicate.skip_binder() { ty::PredicateAtom::Trait(tr, _constness) => { - ty::Binder::bind(tr.trait_ref) + bound_predicate.rebind(tr.trait_ref) } ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => { if let Some(r) = reg.clean(cx) { diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs index 58892024ce243..cfade9cbc469a 100644 --- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs +++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs @@ -99,7 +99,7 @@ impl LateLintPass<'_> for AwaitHolding { }; let def_id = cx.tcx.hir().body_owner_def_id(body_id); let typeck_results = cx.tcx.typeck(def_id); - check_interior_types(cx, &typeck_results.generator_interior_types, body.value.span); + check_interior_types(cx, &typeck_results.generator_interior_types.as_ref().skip_binder(), body.value.span); } } }