mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 18:23:49 +00:00
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.
This commit is contained in:
parent
880bde0ced
commit
e497fb19b0
@ -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;
|
||||
@ -541,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
|
||||
@ -551,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,
|
||||
@ -596,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:
|
||||
|
Loading…
Reference in New Issue
Block a user