diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index a4be3d02d1935..1f1f80ed61828 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -1122,6 +1122,7 @@ impl<'tcx> TypeVisitable<'tcx> for ty::Predicate<'tcx> { visitor.visit_predicate(*self) } + #[inline] fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool { self.outer_exclusive_binder() > binder } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 3a524d7b0f307..b4fa9837aed91 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -11,7 +11,6 @@ use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_serialize::{self, Decodable, Encodable}; -use rustc_span::DUMMY_SP; use smallvec::SmallVec; use core::intrinsics; @@ -525,6 +524,7 @@ struct SubstFolder<'a, 'tcx> { } impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { + #[inline] fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } @@ -540,6 +540,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + #[cold] + #[inline(never)] + fn region_param_out_of_range(data: ty::EarlyBoundRegion) -> ! { + bug!( + "Region parameter out of range when substituting in region {} (index={})", + data.name, + data.index + ) + } + // Note: This routine only handles regions that are bound on // type declarations and other outer declarations, not those // bound in *fn types*. Region substitution of the bound @@ -550,14 +560,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { let rk = self.substs.get(data.index as usize).map(|k| k.unpack()); match rk { Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt), - _ => { - let msg = format!( - "Region parameter out of range \ - when substituting in region {} (index={})", - data.name, data.index - ); - span_bug!(DUMMY_SP, "{}", msg); - } + _ => region_param_out_of_range(data), } } _ => r, @@ -595,67 +598,80 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { let opt_ty = self.substs.get(p.index as usize).map(|k| k.unpack()); let ty = match opt_ty { Some(GenericArgKind::Type(ty)) => ty, - Some(kind) => { - span_bug!( - DUMMY_SP, - "expected type for `{:?}` ({:?}/{}) but found {:?} \ - when substituting, substs={:?}", - p, - source_ty, - p.index, - kind, - self.substs, - ); - } - None => { - span_bug!( - DUMMY_SP, - "type parameter `{:?}` ({:?}/{}) out of range \ - when substituting, substs={:?}", - p, - source_ty, - p.index, - self.substs, - ); - } + Some(kind) => self.type_param_expected(p, source_ty, kind), + None => self.type_param_out_of_range(p, source_ty), }; self.shift_vars_through_binders(ty) } + #[cold] + #[inline(never)] + fn type_param_expected(&self, p: ty::ParamTy, ty: Ty<'tcx>, kind: GenericArgKind<'tcx>) -> ! { + bug!( + "expected type for `{:?}` ({:?}/{}) but found {:?} when substituting, substs={:?}", + p, + ty, + p.index, + kind, + self.substs, + ) + } + + #[cold] + #[inline(never)] + fn type_param_out_of_range(&self, p: ty::ParamTy, ty: Ty<'tcx>) -> ! { + bug!( + "type parameter `{:?}` ({:?}/{}) out of range when substituting, substs={:?}", + p, + ty, + p.index, + self.substs, + ) + } + fn const_for_param(&self, p: ParamConst, source_ct: ty::Const<'tcx>) -> ty::Const<'tcx> { // Look up the const in the substitutions. It really should be in there. let opt_ct = self.substs.get(p.index as usize).map(|k| k.unpack()); let ct = match opt_ct { Some(GenericArgKind::Const(ct)) => ct, - Some(kind) => { - span_bug!( - DUMMY_SP, - "expected const for `{:?}` ({:?}/{}) but found {:?} \ - when substituting substs={:?}", - p, - source_ct, - p.index, - kind, - self.substs, - ); - } - None => { - span_bug!( - DUMMY_SP, - "const parameter `{:?}` ({:?}/{}) out of range \ - when substituting substs={:?}", - p, - source_ct, - p.index, - self.substs, - ); - } + Some(kind) => self.const_param_expected(p, source_ct, kind), + None => self.const_param_out_of_range(p, source_ct), }; self.shift_vars_through_binders(ct) } + #[cold] + #[inline(never)] + fn const_param_expected( + &self, + p: ty::ParamConst, + ct: ty::Const<'tcx>, + kind: GenericArgKind<'tcx>, + ) -> ! { + bug!( + "expected const for `{:?}` ({:?}/{}) but found {:?} when substituting substs={:?}", + p, + ct, + p.index, + kind, + self.substs, + ) + } + + #[cold] + #[inline(never)] + fn const_param_out_of_range(&self, p: ty::ParamConst, ct: ty::Const<'tcx>) -> ! { + bug!( + "const parameter `{:?}` ({:?}/{}) out of range when substituting substs={:?}", + p, + ct, + p.index, + self.substs, + ) + } + /// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs /// when we are substituting a type with escaping bound vars into a context where we have /// passed through binders. That's quite a mouthful. Let's see an example: diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index fd6376ef6ee9d..791e9e0f5a359 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -310,6 +310,7 @@ impl DebruijnIndex { /// for<'a> fn(for<'b> fn(&'a x)) /// /// you would need to shift the index for `'a` into a new binder. + #[inline] #[must_use] pub fn shifted_in(self, amount: u32) -> DebruijnIndex { DebruijnIndex::from_u32(self.as_u32() + amount) @@ -317,18 +318,21 @@ impl DebruijnIndex { /// Update this index in place by shifting it "in" through /// `amount` number of binders. + #[inline] pub fn shift_in(&mut self, amount: u32) { *self = self.shifted_in(amount); } /// Returns the resulting index when this value is moved out from /// `amount` number of new binders. + #[inline] #[must_use] pub fn shifted_out(self, amount: u32) -> DebruijnIndex { DebruijnIndex::from_u32(self.as_u32() - amount) } /// Update in place by shifting out from `amount` binders. + #[inline] pub fn shift_out(&mut self, amount: u32) { *self = self.shifted_out(amount); } @@ -353,6 +357,7 @@ impl DebruijnIndex { /// If we invoke `shift_out_to_binder` and the region is in fact /// bound by one of the binders we are shifting out of, that is an /// error (and should fail an assertion failure). + #[inline] pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self { self.shifted_out(to_binder.as_u32() - INNERMOST.as_u32()) }