mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-03 05:27:36 +00:00
Fix accidental quadratic loops
This commit is contained in:
parent
37204027b6
commit
a65a9d77f3
@ -271,23 +271,25 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let own_self = self_ty.is_some() as usize;
|
let own_self = self_ty.is_some() as usize;
|
||||||
|
// FIXME(varkor): Separating out the parameters is messy.
|
||||||
|
let lifetimes: Vec<_> = generic_args.args.iter().filter_map(|arg| match arg {
|
||||||
|
GenericArg::Lifetime(lt) => Some(lt),
|
||||||
|
_ => None,
|
||||||
|
}).collect();
|
||||||
|
let types: Vec<_> = generic_args.args.iter().filter_map(|arg| match arg {
|
||||||
|
GenericArg::Type(ty) => Some(ty),
|
||||||
|
_ => None,
|
||||||
|
}).collect();
|
||||||
let substs = Substs::for_item(tcx, def_id, |param, substs| {
|
let substs = Substs::for_item(tcx, def_id, |param, substs| {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => {
|
GenericParamDefKind::Lifetime => {
|
||||||
let mut i = param.index as usize - own_self;
|
let i = param.index as usize - own_self;
|
||||||
for arg in &generic_args.args {
|
if let Some(lt) = lifetimes.get(i) {
|
||||||
match arg {
|
self.ast_region_to_region(lt, Some(param)).into()
|
||||||
GenericArg::Lifetime(lt) => {
|
} else {
|
||||||
if i == 0 {
|
|
||||||
return self.ast_region_to_region(lt, Some(param)).into();
|
|
||||||
}
|
|
||||||
i -= 1;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tcx.types.re_static.into()
|
tcx.types.re_static.into()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
GenericParamDefKind::Type { has_default, .. } => {
|
GenericParamDefKind::Type { has_default, .. } => {
|
||||||
let i = param.index as usize;
|
let i = param.index as usize;
|
||||||
|
|
||||||
@ -296,21 +298,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
return ty.into();
|
return ty.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut i = i - (lt_accepted + own_self);
|
let i = i - (lt_accepted + own_self);
|
||||||
if i < ty_provided {
|
if i < ty_provided {
|
||||||
// A provided type parameter.
|
// A provided type parameter.
|
||||||
for arg in &generic_args.args {
|
self.ast_ty_to_ty(&types[i]).into()
|
||||||
match arg {
|
|
||||||
GenericArg::Type(ty) => {
|
|
||||||
if i == 0 {
|
|
||||||
return self.ast_ty_to_ty(ty).into();
|
|
||||||
}
|
|
||||||
i -= 1;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bug!()
|
|
||||||
} else if infer_types {
|
} else if infer_types {
|
||||||
// No type parameters were provided, we can infer all.
|
// No type parameters were provided, we can infer all.
|
||||||
if !default_needs_object_self(param) {
|
if !default_needs_object_self(param) {
|
||||||
|
@ -4813,11 +4813,42 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
(None, None) => (0, false)
|
(None, None) => (0, false)
|
||||||
};
|
};
|
||||||
|
// FIXME(varkor): Separating out the parameters is messy.
|
||||||
|
let mut lifetimes_type_seg = vec![];
|
||||||
|
let mut types_type_seg = vec![];
|
||||||
|
let mut infer_types_type_seg = true;
|
||||||
|
if let Some((seg, _)) = type_segment {
|
||||||
|
if let Some(ref data) = seg.args {
|
||||||
|
for arg in &data.args {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Lifetime(lt) => lifetimes_type_seg.push(lt),
|
||||||
|
GenericArg::Type(ty) => types_type_seg.push(ty),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
infer_types_type_seg = seg.infer_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut lifetimes_fn_seg = vec![];
|
||||||
|
let mut types_fn_seg = vec![];
|
||||||
|
let mut infer_types_fn_seg = true;
|
||||||
|
if let Some((seg, _)) = fn_segment {
|
||||||
|
if let Some(ref data) = seg.args {
|
||||||
|
for arg in &data.args {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Lifetime(lt) => lifetimes_fn_seg.push(lt),
|
||||||
|
GenericArg::Type(ty) => types_fn_seg.push(ty),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
infer_types_fn_seg = seg.infer_types;
|
||||||
|
}
|
||||||
|
|
||||||
let substs = Substs::for_item(self.tcx, def.def_id(), |param, substs| {
|
let substs = Substs::for_item(self.tcx, def.def_id(), |param, substs| {
|
||||||
let mut i = param.index as usize;
|
let mut i = param.index as usize;
|
||||||
|
|
||||||
let segment = if i < fn_start {
|
let (segment, lifetimes, types, infer_types) = if i < fn_start {
|
||||||
if let GenericParamDefKind::Type {..} = param.kind {
|
if let GenericParamDefKind::Type { .. } = param.kind {
|
||||||
// Handle Self first, so we can adjust the index to match the AST.
|
// Handle Self first, so we can adjust the index to match the AST.
|
||||||
if has_self && i == 0 {
|
if has_self && i == 0 {
|
||||||
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
|
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
|
||||||
@ -4826,39 +4857,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
i -= has_self as usize;
|
i -= has_self as usize;
|
||||||
type_segment
|
(type_segment, &lifetimes_type_seg, &types_type_seg, infer_types_type_seg)
|
||||||
} else {
|
} else {
|
||||||
i -= fn_start;
|
i -= fn_start;
|
||||||
fn_segment
|
(fn_segment, &lifetimes_fn_seg, &types_fn_seg, infer_types_fn_seg)
|
||||||
};
|
};
|
||||||
|
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => {
|
GenericParamDefKind::Lifetime => {
|
||||||
let lifetimes = segment.map_or(vec![], |(s, _)| {
|
|
||||||
s.args.as_ref().map_or(vec![], |data| {
|
|
||||||
data.args.iter().filter_map(|arg| match arg {
|
|
||||||
GenericArg::Lifetime(lt) => Some(lt),
|
|
||||||
_ => None,
|
|
||||||
}).collect()
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(lifetime) = lifetimes.get(i) {
|
if let Some(lifetime) = lifetimes.get(i) {
|
||||||
AstConv::ast_region_to_region(self, lifetime, Some(param)).into()
|
AstConv::ast_region_to_region(self, lifetime, Some(param)).into()
|
||||||
} else {
|
} else {
|
||||||
self.re_infer(span, Some(param)).unwrap().into()
|
self.re_infer(span, Some(param)).unwrap().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GenericParamDefKind::Type {..} => {
|
GenericParamDefKind::Type { .. } => {
|
||||||
let (types, infer_types) = segment.map_or((vec![], true), |(s, _)| {
|
|
||||||
(s.args.as_ref().map_or(vec![], |data| {
|
|
||||||
data.args.iter().filter_map(|arg| match arg {
|
|
||||||
GenericArg::Type(ty) => Some(ty),
|
|
||||||
_ => None,
|
|
||||||
}).collect()
|
|
||||||
}), s.infer_types)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Skip over the lifetimes in the same segment.
|
// Skip over the lifetimes in the same segment.
|
||||||
if let Some((_, generics)) = segment {
|
if let Some((_, generics)) = segment {
|
||||||
i -= generics.own_counts().lifetimes;
|
i -= generics.own_counts().lifetimes;
|
||||||
|
Loading…
Reference in New Issue
Block a user