Skip to content

Commit 5fe9aeb

Browse files
committed
Refactor mod/check (part ii)
1 parent d1a82af commit 5fe9aeb

File tree

2 files changed

+106
-60
lines changed

2 files changed

+106
-60
lines changed

src/librustc/ty/subst.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
226226
}
227227

228228
fn fill_item<F>(substs: &mut AccumulateVec<[Kind<'tcx>; 8]>,
229-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
230-
defs: &ty::Generics,
231-
mk_kind: &mut F)
229+
tcx: TyCtxt<'a, 'gcx, 'tcx>,
230+
defs: &ty::Generics,
231+
mk_kind: &mut F)
232232
where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
233233
{
234234
if let Some(def_id) = defs.parent {
@@ -238,7 +238,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
238238
Substs::fill_single(substs, defs, mk_kind)
239239
}
240240

241-
fn fill_single<F>(substs: &mut AccumulateVec<[Kind<'tcx>; 8]>,
241+
pub fn fill_single<F>(substs: &mut AccumulateVec<[Kind<'tcx>; 8]>,
242242
defs: &ty::Generics,
243243
mk_kind: &mut F)
244244
where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>

src/librustc_typeck/check/mod.rs

Lines changed: 102 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ use rustc::ty::fold::TypeFoldable;
103103
use rustc::ty::query::Providers;
104104
use rustc::ty::util::{Representability, IntTypeExt, Discr};
105105
use errors::{DiagnosticBuilder, DiagnosticId};
106+
use rustc_data_structures::accumulate_vec::AccumulateVec;
107+
use rustc_data_structures::array_vec::ArrayVec;
106108

107109
use require_c_abi_if_variadic;
108110
use session::{CompileIncomplete, config, Session};
@@ -5002,10 +5004,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50025004
let mut infer_types_type_seg = true;
50035005
if let Some((seg, _)) = type_segment {
50045006
if let Some(ref data) = seg.args {
5005-
for arg in &data.args {
5007+
for (i, arg) in data.args.iter().enumerate() {
50065008
match arg {
5007-
GenericArg::Lifetime(lt) => lifetimes_type_seg.push(lt),
5008-
GenericArg::Type(ty) => types_type_seg.push(ty),
5009+
GenericArg::Lifetime(lt) => lifetimes_type_seg.push((i, lt)),
5010+
GenericArg::Type(ty) => types_type_seg.push((i, ty)),
50095011
}
50105012
}
50115013
}
@@ -5017,74 +5019,118 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50175019
let mut infer_types_fn_seg = true;
50185020
if let Some((seg, _)) = fn_segment {
50195021
if let Some(ref data) = seg.args {
5020-
for arg in &data.args {
5022+
for (i, arg) in data.args.iter().enumerate() {
50215023
match arg {
5022-
GenericArg::Lifetime(lt) => lifetimes_fn_seg.push(lt),
5023-
GenericArg::Type(ty) => types_fn_seg.push(ty),
5024+
GenericArg::Lifetime(lt) => lifetimes_fn_seg.push((i, lt)),
5025+
GenericArg::Type(ty) => types_fn_seg.push((i, ty)),
50245026
}
50255027
}
50265028
}
50275029
infer_types_fn_seg = seg.infer_types;
50285030
}
50295031

5030-
let substs = Substs::for_item(self.tcx, def.def_id(), |param, substs| {
5031-
let mut i = param.index as usize;
5032-
5033-
let (segment, lifetimes, types, infer_types) = if i < fn_start {
5034-
if let GenericParamDefKind::Type { .. } = param.kind {
5035-
// Handle Self first, so we can adjust the index to match the AST.
5036-
if has_self && i == 0 {
5037-
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
5038-
self.var_for_def(span, param)
5039-
});
5032+
let defs = self.tcx.generics_of(def.def_id());
5033+
let count = defs.count();
5034+
let mut substs = if count <= 8 {
5035+
AccumulateVec::Array(ArrayVec::new())
5036+
} else {
5037+
AccumulateVec::Heap(Vec::with_capacity(count))
5038+
};
5039+
let mut stack = vec![def.def_id()];
5040+
let mut parent_defs = defs;
5041+
while let Some(def_id) = parent_defs.parent {
5042+
parent_defs = self.tcx.generics_of(def_id);
5043+
stack.push(def_id);
5044+
}
5045+
while let Some(def_id) = stack.pop() {
5046+
let defs = self.tcx.generics_of(def_id);
5047+
Substs::fill_single(&mut substs, defs, &mut |param: &ty::GenericParamDef, substs| {
5048+
let mut i = param.index as usize;
5049+
5050+
let (lifetimes, types, infer_types) = if i < fn_start {
5051+
if let GenericParamDefKind::Type { .. } = param.kind {
5052+
// Handle Self first, so we can adjust the index to match the AST.
5053+
if has_self && i == 0 {
5054+
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
5055+
self.var_for_def(span, param)
5056+
});
5057+
}
50405058
}
5041-
}
5042-
i -= has_self as usize;
5043-
(type_segment, &lifetimes_type_seg, &types_type_seg, infer_types_type_seg)
5044-
} else {
5045-
i -= fn_start;
5046-
(fn_segment, &lifetimes_fn_seg, &types_fn_seg, infer_types_fn_seg)
5047-
};
5059+
i -= has_self as usize;
5060+
(&lifetimes_type_seg, &types_type_seg, infer_types_type_seg)
5061+
} else {
5062+
i -= fn_start;
5063+
(&lifetimes_fn_seg, &types_fn_seg, infer_types_fn_seg)
5064+
};
50485065

5049-
match param.kind {
5050-
GenericParamDefKind::Lifetime => {
5051-
if let Some(lifetime) = lifetimes.get(i) {
5052-
AstConv::ast_region_to_region(self, lifetime, Some(param)).into()
5053-
} else {
5054-
self.re_infer(span, Some(param)).unwrap().into()
5066+
let mut pi = param.index as usize - has_self as usize;
5067+
5068+
let segment = if let Some(&PathSeg(_, ind)) = path_segs.iter().find(|&PathSeg(di, _)| *di == def_id) {
5069+
let seg = &segments[ind];
5070+
if lifetimes.len() == 0 {
5071+
pi -= defs.own_counts().lifetimes;
50555072
}
5056-
}
5057-
GenericParamDefKind::Type { .. } => {
5058-
// Skip over the lifetimes in the same segment.
5059-
if let Some((_, generics)) = segment {
5060-
i -= generics.own_counts().lifetimes;
5073+
5074+
Some((seg, defs))
5075+
} else {
5076+
None
5077+
};
5078+
5079+
// eprintln!("{:?} {:?} {:?}", param.index, i, segment);
5080+
5081+
5082+
5083+
match param.kind {
5084+
GenericParamDefKind::Lifetime => {
5085+
if let Some((z, lt)) = lifetimes.get(i) {
5086+
eprintln!("lifetime {:?} {:?} {:?}", pi, z, has_self);
5087+
if pi != *z {
5088+
eprintln!("error {:?} {:?} {:?} {:?} {:?} {:?}", pi, z, i, segment, fn_start, has_self);
5089+
bug!("uh oh")
5090+
}
5091+
AstConv::ast_region_to_region(self, lt, Some(param)).into()
5092+
} else {
5093+
self.re_infer(span, Some(param)).unwrap().into()
5094+
}
50615095
}
5096+
GenericParamDefKind::Type { .. } => {
5097+
// Skip over the lifetimes in the same segment.
5098+
if let Some((_, generics)) = segment {
5099+
i -= generics.own_counts().lifetimes;
5100+
}
50625101

5063-
let has_default = match param.kind {
5064-
GenericParamDefKind::Type { has_default, .. } => has_default,
5065-
_ => unreachable!()
5066-
};
5102+
let has_default = match param.kind {
5103+
GenericParamDefKind::Type { has_default, .. } => has_default,
5104+
_ => unreachable!()
5105+
};
50675106

5068-
if let Some(ast_ty) = types.get(i) {
5069-
// A provided type parameter.
5070-
self.to_ty(ast_ty).into()
5071-
} else if !infer_types && has_default {
5072-
// No type parameter provided, but a default exists.
5073-
let default = self.tcx.type_of(param.def_id);
5074-
self.normalize_ty(
5075-
span,
5076-
default.subst_spanned(self.tcx, substs, Some(span))
5077-
).into()
5078-
} else {
5079-
// No type parameters were provided, we can infer all.
5080-
// This can also be reached in some error cases:
5081-
// We prefer to use inference variables instead of
5082-
// TyError to let type inference recover somewhat.
5083-
self.var_for_def(span, param)
5107+
if let Some((z, ty)) = types.get(i) {
5108+
eprintln!("type {:?} {:?} {:?}", pi, z, has_self);
5109+
if pi != *z {
5110+
eprintln!("error {:?} {:?} {:?} {:?} {:?} {:?}", pi, z, i, segment, fn_start, has_self);
5111+
bug!("uh oh")
5112+
}
5113+
// A provided type parameter.
5114+
self.to_ty(ty).into()
5115+
} else if !infer_types && has_default {
5116+
// No type parameter provided, but a default exists.
5117+
let default = self.tcx.type_of(param.def_id);
5118+
self.normalize_ty(
5119+
span,
5120+
default.subst_spanned(self.tcx, substs, Some(span))
5121+
).into()
5122+
} else {
5123+
// No type parameters were provided, we can infer all.
5124+
// This can also be reached in some error cases:
5125+
// We prefer to use inference variables instead of
5126+
// TyError to let type inference recover somewhat.
5127+
self.var_for_def(span, param)
5128+
}
50845129
}
50855130
}
5086-
}
5087-
});
5131+
});
5132+
}
5133+
let substs = self.tcx.intern_substs(&substs);
50885134

50895135
// The things we are substituting into the type should not contain
50905136
// escaping late-bound regions, and nor should the base type scheme.

0 commit comments

Comments
 (0)