Refactor astconv.rs
This commit is contained in:
parent
35ddd46a2d
commit
340a7fc4f5
@ -213,18 +213,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
||||
// If the type is parameterized by this region, then replace this
|
||||
// region with the current anon region binding (in other words,
|
||||
// whatever & would get replaced with).
|
||||
|
||||
// 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 lt_provided = lifetimes.len();
|
||||
let ty_provided = types.len();
|
||||
let mut lt_provided = 0;
|
||||
let mut ty_provided = 0;
|
||||
for arg in &generic_args.args {
|
||||
match arg {
|
||||
GenericArg::Lifetime(_) => lt_provided += 1,
|
||||
GenericArg::Type(_) => ty_provided += 1,
|
||||
}
|
||||
}
|
||||
|
||||
let decl_generics = tcx.generics_of(def_id);
|
||||
let mut lt_accepted = 0;
|
||||
@ -274,30 +270,44 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
||||
false
|
||||
};
|
||||
|
||||
let own_self = self_ty.is_some() as usize;
|
||||
let self_offset = self_ty.is_some() as usize;
|
||||
let substs = Substs::for_item(tcx, def_id, |param, substs| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
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()
|
||||
}
|
||||
}
|
||||
GenericParamDefKind::Type { has_default, .. } => {
|
||||
let i = param.index as usize;
|
||||
|
||||
// Handle Self first, so we can adjust the index to match the AST.
|
||||
if let (0, Some(ty)) = (i, self_ty) {
|
||||
if param.index == 0 {
|
||||
if let Some(ty) = self_ty {
|
||||
if let GenericParamDefKind::Type { .. } = param.kind {
|
||||
// Handle `Self` first.
|
||||
return ty.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let i = i - (lt_accepted + own_self);
|
||||
if i < ty_provided {
|
||||
// A provided type parameter.
|
||||
self.ast_ty_to_ty(&types[i]).into()
|
||||
} else if infer_types {
|
||||
let inferred_lifetimes = if lt_provided == 0 {
|
||||
lt_accepted
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let param_idx = (param.index as usize - self_offset).saturating_sub(inferred_lifetimes);
|
||||
|
||||
if let Some(arg) = generic_args.args.get(param_idx) {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => match arg {
|
||||
GenericArg::Lifetime(lt) => {
|
||||
return self.ast_region_to_region(lt, Some(param)).into();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
GenericParamDefKind::Type { .. } => match arg {
|
||||
GenericArg::Type(ty) => return self.ast_ty_to_ty(ty).into(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => tcx.types.re_static.into(),
|
||||
GenericParamDefKind::Type { has_default, .. } => {
|
||||
if infer_types {
|
||||
// No type parameters were provided, we can infer all.
|
||||
if !default_needs_object_self(param) {
|
||||
self.ty_infer_for_def(param, span).into()
|
||||
|
@ -4987,7 +4987,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
Substs::fill_single(&mut substs, defs, &mut |param: &ty::GenericParamDef, substs| {
|
||||
if param.index == 0 && has_self {
|
||||
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.
|
||||
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
|
||||
self.var_for_def(span, param)
|
||||
});
|
||||
@ -5004,7 +5004,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
if let Some(ref data) = segments[index].args {
|
||||
let self_offset = (defs.parent_count == 0 && has_self) as usize;
|
||||
let param_idx =
|
||||
(param.index as usize - defs.parent_count - self_offset as usize)
|
||||
(param.index as usize - defs.parent_count - self_offset)
|
||||
.saturating_sub(infer_lifetimes[&index]);
|
||||
if let Some(arg) = data.args.get(param_idx) {
|
||||
match param.kind {
|
||||
|
Loading…
x
Reference in New Issue
Block a user