Skip to content

Commit e812b55

Browse files
committed
Refactor mod/check (part iv)
1 parent 96379e1 commit e812b55

File tree

1 file changed

+43
-76
lines changed
  • src/librustc_typeck/check

1 file changed

+43
-76
lines changed

src/librustc_typeck/check/mod.rs

Lines changed: 43 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4983,115 +4983,82 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49834983
// variables. If the user provided some types, we may still need
49844984
// to add defaults. If the user provided *too many* types, that's
49854985
// a problem.
4986+
let mut infer_lifetimes = FxHashMap();
49864987
let supress_mismatch = self.check_impl_trait(span, fn_segment);
49874988
for &PathSeg(def_id, index) in &path_segs {
49884989
let generics = self.tcx.generics_of(def_id);
4989-
self.check_generic_arg_count(span, &segments[index], &generics, false, supress_mismatch);
4990+
let seg = &segments[index];
4991+
self.check_generic_arg_count(span, seg, &generics, false, supress_mismatch);
4992+
infer_lifetimes.insert(index, if let Some(ref data) = seg.args {
4993+
!data.args.iter().any(|arg| match arg {
4994+
GenericArg::Lifetime(_) => true,
4995+
_ => false,
4996+
})
4997+
} else {
4998+
true
4999+
});
49905000
}
49915001

49925002
let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
49935003
self.tcx.generics_of(*def_id).has_self
49945004
}).unwrap_or(false);
49955005

4996-
let fn_start = match (type_segment, fn_segment) {
4997-
(_, Some((_, generics))) => generics.parent_count,
4998-
(Some((_, generics)), None) => generics.params.len(),
4999-
(None, None) => 0,
5000-
};
5001-
// FIXME(varkor): Separating out the parameters is messy.
5002-
let mut lifetimes_type_seg = vec![];
5003-
let mut types_type_seg = vec![];
5004-
let mut _infer_types_type_seg = true;
5005-
if let Some((seg, _)) = type_segment {
5006-
if let Some(ref data) = seg.args {
5007-
for (i, arg) in data.args.iter().enumerate() {
5008-
match arg {
5009-
GenericArg::Lifetime(lt) => lifetimes_type_seg.push((i, lt)),
5010-
GenericArg::Type(ty) => types_type_seg.push((i, ty)),
5011-
}
5012-
}
5013-
}
5014-
_infer_types_type_seg = seg.infer_types;
5015-
}
5016-
5017-
let mut lifetimes_fn_seg = vec![];
5018-
let mut types_fn_seg = vec![];
5019-
let mut _infer_types_fn_seg = true;
5020-
if let Some((seg, _)) = fn_segment {
5021-
if let Some(ref data) = seg.args {
5022-
for (i, arg) in data.args.iter().enumerate() {
5023-
match arg {
5024-
GenericArg::Lifetime(lt) => lifetimes_fn_seg.push((i, lt)),
5025-
GenericArg::Type(ty) => types_fn_seg.push((i, ty)),
5026-
}
5027-
}
5028-
}
5029-
_infer_types_fn_seg = seg.infer_types;
5030-
}
5031-
5032-
let defs = self.tcx.generics_of(def.def_id());
5006+
let def_id = def.def_id();
5007+
let defs = self.tcx.generics_of(def_id);
50335008
let count = defs.count();
50345009
let mut substs = if count <= 8 {
50355010
AccumulateVec::Array(ArrayVec::new())
50365011
} else {
50375012
AccumulateVec::Heap(Vec::with_capacity(count))
50385013
};
5039-
let mut stack = vec![def.def_id()];
50405014
let mut parent_defs = defs;
5015+
let mut stack = vec![(def_id, parent_defs)];
50415016
while let Some(def_id) = parent_defs.parent {
50425017
parent_defs = self.tcx.generics_of(def_id);
5043-
stack.push(def_id);
5018+
stack.push((def_id, parent_defs));
50445019
}
5045-
while let Some(def_id) = stack.pop() {
5046-
let defs = self.tcx.generics_of(def_id);
5020+
while let Some((def_id, defs)) = stack.pop() {
50475021
Substs::fill_single(&mut substs, defs, &mut |param: &ty::GenericParamDef, substs| {
5048-
let lifetimes = if (param.index as usize) < fn_start {
5022+
if param.index == 0 && has_self {
50495023
if let GenericParamDefKind::Type { .. } = param.kind {
50505024
// Handle Self first, so we can adjust the index to match the AST.
5051-
if has_self && param.index == 0 {
5052-
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
5053-
self.var_for_def(span, param)
5054-
});
5055-
}
5025+
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
5026+
self.var_for_def(span, param)
5027+
});
50565028
}
5057-
&lifetimes_type_seg
5058-
} else {
5059-
&lifetimes_fn_seg
5060-
};
5061-
5062-
let mut pi = param.index as usize - has_self as usize;
5029+
}
50635030

5064-
let (_segment, infer_types) = if let Some(&PathSeg(_, ind)) = path_segs.iter().find(|&PathSeg(di, _)| *di == def_id) {
5065-
let seg = &segments[ind];
5066-
if lifetimes.len() == 0 {
5067-
pi -= defs.own_counts().lifetimes;
5068-
}
5031+
let infer_types = if let Some(&PathSeg(_, index)) = path_segs
5032+
.iter()
5033+
.find(|&PathSeg(di, _)| *di == def_id) {
50695034

5070-
if let Some(ref data) = seg.args {
5071-
if let Some(arg) = data.args.get(pi) {
5035+
if let Some(ref data) = segments[index].args {
5036+
let lifetime_offset = if infer_lifetimes[&index] {
5037+
defs.own_counts().lifetimes
5038+
} else {
5039+
0
5040+
};
5041+
let param_idx = param.index as usize - has_self as usize - lifetime_offset;
5042+
if let Some(arg) = data.args.get(param_idx) {
50725043
return match param.kind {
5073-
GenericParamDefKind::Lifetime => {
5074-
let lt = match arg {
5075-
GenericArg::Lifetime(lt) => lt,
5076-
_ => bug!("should be a lifetime"),
5077-
};
5078-
AstConv::ast_region_to_region(self, lt, Some(param)).into()
5044+
GenericParamDefKind::Lifetime => match arg {
5045+
GenericArg::Lifetime(lt) => {
5046+
AstConv::ast_region_to_region(self, lt, Some(param)).into()
5047+
}
5048+
_ => bug!("expected a lifetime arg"),
50795049
}
5080-
GenericParamDefKind::Type { .. } => {
5050+
GenericParamDefKind::Type { .. } => match arg {
50815051
// A provided type parameter.
5082-
let ty = match arg {
5083-
GenericArg::Type(ty) => ty,
5084-
_ => bug!("should be a type"),
5085-
};
5086-
self.to_ty(ty).into()
5052+
GenericArg::Type(ty) => self.to_ty(ty).into(),
5053+
_ => bug!("expected a type arg"),
50875054
}
5088-
};
5055+
}
50895056
}
50905057
}
50915058

5092-
(Some((seg, defs)), seg.infer_types)
5059+
segments[index].infer_types
50935060
} else {
5094-
(None, true)
5061+
true
50955062
};
50965063

50975064
match param.kind {

0 commit comments

Comments
 (0)