};
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| {
match param.kind {
GenericParamDefKind::Lifetime => {
- let mut i = param.index as usize - own_self;
- for arg in &generic_args.args {
- match arg {
- GenericArg::Lifetime(lt) => {
- if i == 0 {
- return self.ast_region_to_region(lt, Some(param)).into();
- }
- i -= 1;
- }
- _ => {}
- }
+ let i = param.index as usize - own_self;
+ if let Some(lt) = lifetimes.get(i) {
+ self.ast_region_to_region(lt, Some(param)).into()
+ } else {
+ tcx.types.re_static.into()
}
- tcx.types.re_static.into()
}
GenericParamDefKind::Type { has_default, .. } => {
let i = param.index as usize;
return ty.into();
}
- let mut i = i - (lt_accepted + own_self);
+ let i = i - (lt_accepted + own_self);
if i < ty_provided {
// A provided type parameter.
- for arg in &generic_args.args {
- match arg {
- GenericArg::Type(ty) => {
- if i == 0 {
- return self.ast_ty_to_ty(ty).into();
- }
- i -= 1;
- }
- _ => {}
- }
- }
- bug!()
+ self.ast_ty_to_ty(&types[i]).into()
} else if infer_types {
// No type parameters were provided, we can infer all.
if !default_needs_object_self(param) {
}
(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 mut i = param.index as usize;
- let segment = if i < fn_start {
- if let GenericParamDefKind::Type {..} = param.kind {
+ let (segment, lifetimes, types, infer_types) = if i < fn_start {
+ if let GenericParamDefKind::Type { .. } = param.kind {
// Handle Self first, so we can adjust the index to match the AST.
if has_self && i == 0 {
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
}
}
i -= has_self as usize;
- type_segment
+ (type_segment, &lifetimes_type_seg, &types_type_seg, infer_types_type_seg)
} else {
i -= fn_start;
- fn_segment
+ (fn_segment, &lifetimes_fn_seg, &types_fn_seg, infer_types_fn_seg)
};
match param.kind {
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) {
AstConv::ast_region_to_region(self, lifetime, Some(param)).into()
} else {
self.re_infer(span, Some(param)).unwrap().into()
}
}
- 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)
- });
-
+ GenericParamDefKind::Type { .. } => {
// Skip over the lifetimes in the same segment.
if let Some((_, generics)) = segment {
i -= generics.own_counts().lifetimes;