Skip to content

Commit a65a9d7

Browse files
committed
Fix accidental quadratic loops
1 parent 3720402 commit a65a9d7

File tree

2 files changed

+52
-48
lines changed

2 files changed

+52
-48
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -271,22 +271,24 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
271271
};
272272

273273
let own_self = self_ty.is_some() as usize;
274+
// FIXME(varkor): Separating out the parameters is messy.
275+
let lifetimes: Vec<_> = generic_args.args.iter().filter_map(|arg| match arg {
276+
GenericArg::Lifetime(lt) => Some(lt),
277+
_ => None,
278+
}).collect();
279+
let types: Vec<_> = generic_args.args.iter().filter_map(|arg| match arg {
280+
GenericArg::Type(ty) => Some(ty),
281+
_ => None,
282+
}).collect();
274283
let substs = Substs::for_item(tcx, def_id, |param, substs| {
275284
match param.kind {
276285
GenericParamDefKind::Lifetime => {
277-
let mut i = param.index as usize - own_self;
278-
for arg in &generic_args.args {
279-
match arg {
280-
GenericArg::Lifetime(lt) => {
281-
if i == 0 {
282-
return self.ast_region_to_region(lt, Some(param)).into();
283-
}
284-
i -= 1;
285-
}
286-
_ => {}
287-
}
286+
let i = param.index as usize - own_self;
287+
if let Some(lt) = lifetimes.get(i) {
288+
self.ast_region_to_region(lt, Some(param)).into()
289+
} else {
290+
tcx.types.re_static.into()
288291
}
289-
tcx.types.re_static.into()
290292
}
291293
GenericParamDefKind::Type { has_default, .. } => {
292294
let i = param.index as usize;
@@ -296,21 +298,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
296298
return ty.into();
297299
}
298300

299-
let mut i = i - (lt_accepted + own_self);
301+
let i = i - (lt_accepted + own_self);
300302
if i < ty_provided {
301303
// A provided type parameter.
302-
for arg in &generic_args.args {
303-
match arg {
304-
GenericArg::Type(ty) => {
305-
if i == 0 {
306-
return self.ast_ty_to_ty(ty).into();
307-
}
308-
i -= 1;
309-
}
310-
_ => {}
311-
}
312-
}
313-
bug!()
304+
self.ast_ty_to_ty(&types[i]).into()
314305
} else if infer_types {
315306
// No type parameters were provided, we can infer all.
316307
if !default_needs_object_self(param) {

src/librustc_typeck/check/mod.rs

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4813,11 +4813,42 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
48134813
}
48144814
(None, None) => (0, false)
48154815
};
4816+
// FIXME(varkor): Separating out the parameters is messy.
4817+
let mut lifetimes_type_seg = vec![];
4818+
let mut types_type_seg = vec![];
4819+
let mut infer_types_type_seg = true;
4820+
if let Some((seg, _)) = type_segment {
4821+
if let Some(ref data) = seg.args {
4822+
for arg in &data.args {
4823+
match arg {
4824+
GenericArg::Lifetime(lt) => lifetimes_type_seg.push(lt),
4825+
GenericArg::Type(ty) => types_type_seg.push(ty),
4826+
}
4827+
}
4828+
}
4829+
infer_types_type_seg = seg.infer_types;
4830+
}
4831+
4832+
let mut lifetimes_fn_seg = vec![];
4833+
let mut types_fn_seg = vec![];
4834+
let mut infer_types_fn_seg = true;
4835+
if let Some((seg, _)) = fn_segment {
4836+
if let Some(ref data) = seg.args {
4837+
for arg in &data.args {
4838+
match arg {
4839+
GenericArg::Lifetime(lt) => lifetimes_fn_seg.push(lt),
4840+
GenericArg::Type(ty) => types_fn_seg.push(ty),
4841+
}
4842+
}
4843+
}
4844+
infer_types_fn_seg = seg.infer_types;
4845+
}
4846+
48164847
let substs = Substs::for_item(self.tcx, def.def_id(), |param, substs| {
48174848
let mut i = param.index as usize;
48184849

4819-
let segment = if i < fn_start {
4820-
if let GenericParamDefKind::Type {..} = param.kind {
4850+
let (segment, lifetimes, types, infer_types) = if i < fn_start {
4851+
if let GenericParamDefKind::Type { .. } = param.kind {
48214852
// Handle Self first, so we can adjust the index to match the AST.
48224853
if has_self && i == 0 {
48234854
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
@@ -4826,39 +4857,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
48264857
}
48274858
}
48284859
i -= has_self as usize;
4829-
type_segment
4860+
(type_segment, &lifetimes_type_seg, &types_type_seg, infer_types_type_seg)
48304861
} else {
48314862
i -= fn_start;
4832-
fn_segment
4863+
(fn_segment, &lifetimes_fn_seg, &types_fn_seg, infer_types_fn_seg)
48334864
};
48344865

48354866
match param.kind {
48364867
GenericParamDefKind::Lifetime => {
4837-
let lifetimes = segment.map_or(vec![], |(s, _)| {
4838-
s.args.as_ref().map_or(vec![], |data| {
4839-
data.args.iter().filter_map(|arg| match arg {
4840-
GenericArg::Lifetime(lt) => Some(lt),
4841-
_ => None,
4842-
}).collect()
4843-
})
4844-
});
4845-
48464868
if let Some(lifetime) = lifetimes.get(i) {
48474869
AstConv::ast_region_to_region(self, lifetime, Some(param)).into()
48484870
} else {
48494871
self.re_infer(span, Some(param)).unwrap().into()
48504872
}
48514873
}
4852-
GenericParamDefKind::Type {..} => {
4853-
let (types, infer_types) = segment.map_or((vec![], true), |(s, _)| {
4854-
(s.args.as_ref().map_or(vec![], |data| {
4855-
data.args.iter().filter_map(|arg| match arg {
4856-
GenericArg::Type(ty) => Some(ty),
4857-
_ => None,
4858-
}).collect()
4859-
}), s.infer_types)
4860-
});
4861-
4874+
GenericParamDefKind::Type { .. } => {
48624875
// Skip over the lifetimes in the same segment.
48634876
if let Some((_, generics)) = segment {
48644877
i -= generics.own_counts().lifetimes;

0 commit comments

Comments
 (0)