Skip to content

Commit e497fb1

Browse files
committed
Outline SubstFolder bug reporting code paths
Bug reporting macro `span_bug!` generates quite a bit of code, we don't expect to execute. Outline it into a separate function.
1 parent 880bde0 commit e497fb1

File tree

1 file changed

+70
-55
lines changed

1 file changed

+70
-55
lines changed

compiler/rustc_middle/src/ty/subst.rs

+70-55
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_data_structures::intern::{Interned, WithStableHash};
1111
use rustc_hir::def_id::DefId;
1212
use rustc_macros::HashStable;
1313
use rustc_serialize::{self, Decodable, Encodable};
14-
use rustc_span::DUMMY_SP;
1514
use smallvec::SmallVec;
1615

1716
use core::intrinsics;
@@ -541,6 +540,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
541540
}
542541

543542
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
543+
#[cold]
544+
#[inline(never)]
545+
fn region_param_out_of_range(data: ty::EarlyBoundRegion) -> ! {
546+
bug!(
547+
"Region parameter out of range when substituting in region {} (index={})",
548+
data.name,
549+
data.index
550+
)
551+
}
552+
544553
// Note: This routine only handles regions that are bound on
545554
// type declarations and other outer declarations, not those
546555
// bound in *fn types*. Region substitution of the bound
@@ -551,14 +560,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
551560
let rk = self.substs.get(data.index as usize).map(|k| k.unpack());
552561
match rk {
553562
Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
554-
_ => {
555-
let msg = format!(
556-
"Region parameter out of range \
557-
when substituting in region {} (index={})",
558-
data.name, data.index
559-
);
560-
span_bug!(DUMMY_SP, "{}", msg);
561-
}
563+
_ => region_param_out_of_range(data),
562564
}
563565
}
564566
_ => r,
@@ -596,67 +598,80 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
596598
let opt_ty = self.substs.get(p.index as usize).map(|k| k.unpack());
597599
let ty = match opt_ty {
598600
Some(GenericArgKind::Type(ty)) => ty,
599-
Some(kind) => {
600-
span_bug!(
601-
DUMMY_SP,
602-
"expected type for `{:?}` ({:?}/{}) but found {:?} \
603-
when substituting, substs={:?}",
604-
p,
605-
source_ty,
606-
p.index,
607-
kind,
608-
self.substs,
609-
);
610-
}
611-
None => {
612-
span_bug!(
613-
DUMMY_SP,
614-
"type parameter `{:?}` ({:?}/{}) out of range \
615-
when substituting, substs={:?}",
616-
p,
617-
source_ty,
618-
p.index,
619-
self.substs,
620-
);
621-
}
601+
Some(kind) => self.type_param_expected(p, source_ty, kind),
602+
None => self.type_param_out_of_range(p, source_ty),
622603
};
623604

624605
self.shift_vars_through_binders(ty)
625606
}
626607

608+
#[cold]
609+
#[inline(never)]
610+
fn type_param_expected(&self, p: ty::ParamTy, ty: Ty<'tcx>, kind: GenericArgKind<'tcx>) -> ! {
611+
bug!(
612+
"expected type for `{:?}` ({:?}/{}) but found {:?} when substituting, substs={:?}",
613+
p,
614+
ty,
615+
p.index,
616+
kind,
617+
self.substs,
618+
)
619+
}
620+
621+
#[cold]
622+
#[inline(never)]
623+
fn type_param_out_of_range(&self, p: ty::ParamTy, ty: Ty<'tcx>) -> ! {
624+
bug!(
625+
"type parameter `{:?}` ({:?}/{}) out of range when substituting, substs={:?}",
626+
p,
627+
ty,
628+
p.index,
629+
self.substs,
630+
)
631+
}
632+
627633
fn const_for_param(&self, p: ParamConst, source_ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
628634
// Look up the const in the substitutions. It really should be in there.
629635
let opt_ct = self.substs.get(p.index as usize).map(|k| k.unpack());
630636
let ct = match opt_ct {
631637
Some(GenericArgKind::Const(ct)) => ct,
632-
Some(kind) => {
633-
span_bug!(
634-
DUMMY_SP,
635-
"expected const for `{:?}` ({:?}/{}) but found {:?} \
636-
when substituting substs={:?}",
637-
p,
638-
source_ct,
639-
p.index,
640-
kind,
641-
self.substs,
642-
);
643-
}
644-
None => {
645-
span_bug!(
646-
DUMMY_SP,
647-
"const parameter `{:?}` ({:?}/{}) out of range \
648-
when substituting substs={:?}",
649-
p,
650-
source_ct,
651-
p.index,
652-
self.substs,
653-
);
654-
}
638+
Some(kind) => self.const_param_expected(p, source_ct, kind),
639+
None => self.const_param_out_of_range(p, source_ct),
655640
};
656641

657642
self.shift_vars_through_binders(ct)
658643
}
659644

645+
#[cold]
646+
#[inline(never)]
647+
fn const_param_expected(
648+
&self,
649+
p: ty::ParamConst,
650+
ct: ty::Const<'tcx>,
651+
kind: GenericArgKind<'tcx>,
652+
) -> ! {
653+
bug!(
654+
"expected const for `{:?}` ({:?}/{}) but found {:?} when substituting substs={:?}",
655+
p,
656+
ct,
657+
p.index,
658+
kind,
659+
self.substs,
660+
)
661+
}
662+
663+
#[cold]
664+
#[inline(never)]
665+
fn const_param_out_of_range(&self, p: ty::ParamConst, ct: ty::Const<'tcx>) -> ! {
666+
bug!(
667+
"const parameter `{:?}` ({:?}/{}) out of range when substituting substs={:?}",
668+
p,
669+
ct,
670+
p.index,
671+
self.substs,
672+
)
673+
}
674+
660675
/// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs
661676
/// when we are substituting a type with escaping bound vars into a context where we have
662677
/// passed through binders. That's quite a mouthful. Let's see an example:

0 commit comments

Comments
 (0)