1
Fork 0

Place Self at the start of ty::Generics' param lists

This commit is contained in:
varkor 2018-04-15 01:36:31 +01:00
parent 6f257bf26f
commit a17896a3b6
2 changed files with 16 additions and 17 deletions

View file

@ -794,12 +794,8 @@ impl GenericParamDef {
/// Information about the formal type/lifetime parameters associated
/// with an item or method. Analogous to hir::Generics.
///
/// Note that in the presence of a `Self` parameter, the ordering here
/// is different from the ordering in a Substs. Substs are ordered as
/// Self, *Regions, *Other Type Params, (...child generics)
/// while this struct is ordered as
/// regions = Regions
/// types = [Self, *Other Type Params]
/// The ordering of parameters is the same as in Subst (excluding child generics):
/// Self (optionally), Lifetime params..., Type params...
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Generics {
pub parent: Option<DefId>,
@ -865,8 +861,7 @@ impl<'a, 'gcx, 'tcx> Generics {
-> &'tcx RegionParamDef
{
if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
// We're currently assuming that lifetimes precede other generic parameters.
match self.params[index as usize - self.has_self as usize] {
match self.params[index as usize] {
ty::GenericParamDef::Lifetime(ref lt) => lt,
_ => bug!("expected region parameter, but found another generic parameter")
}
@ -881,7 +876,7 @@ impl<'a, 'gcx, 'tcx> Generics {
param: &ParamTy,
tcx: TyCtxt<'a, 'gcx, 'tcx>)
-> &TypeParamDef {
if let Some(idx) = param.idx.checked_sub(self.parent_count as u32) {
if let Some(index) = param.idx.checked_sub(self.parent_count as u32) {
// non-Self type parameters are always offset by exactly
// `self.regions.len()`. In the absence of a Self, this is obvious,
// but even in the presence of a `Self` we just have to "compensate"
@ -912,11 +907,11 @@ impl<'a, 'gcx, 'tcx> Generics {
let type_param_offset = self.param_counts()[&Kind::Lifetime];
let has_self = self.has_self && self.parent.is_none();
let is_separated_self = type_param_offset != 0 && idx == 0 && has_self;
let is_separated_self = type_param_offset != 0 && index == 0 && has_self;
if let Some(_) = (idx as usize).checked_sub(type_param_offset) {
if let Some(_) = (index as usize).checked_sub(type_param_offset) {
assert!(!is_separated_self, "found a Self after type_param_offset");
match self.params[idx as usize] {
match self.params[index as usize] {
ty::GenericParamDef::Type(ref ty) => ty,
_ => bug!("expected type parameter, but found another generic parameter")
}

View file

@ -927,7 +927,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
});
let mut types: Vec<_> = opt_self.into_iter().chain(types).collect();
let mut types: Vec<_> = types.into_iter().collect();
// provide junk type parameter defs - the only place that
// cares about anything but the length is instantiation,
@ -966,13 +966,17 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
});
}
let type_param_to_index = types.iter()
.map(|param| (param.def_id, param.index))
.collect();
let type_param_to_index = opt_self.iter()
.chain(types.iter())
.map(|ty| (ty.def_id, ty.index))
.collect();
let opt_self = opt_self.into_iter().map(|ty| ty::GenericParamDef::Type(ty));
let lifetimes = regions.into_iter().map(|lt| ty::GenericParamDef::Lifetime(lt));
let types = types.into_iter().map(|ty| ty::GenericParamDef::Type(ty));
let params = lifetimes.chain(types).collect();
let params = opt_self.chain(lifetimes)
.chain(types)
.collect();
tcx.alloc_generics(ty::Generics {
parent: parent_def_id,