Skip to content

Commit 340a7fc

Browse files
committed
Refactor astconv.rs
1 parent 35ddd46 commit 340a7fc

File tree

2 files changed

+45
-35
lines changed

2 files changed

+45
-35
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -213,18 +213,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
213213
// If the type is parameterized by this region, then replace this
214214
// region with the current anon region binding (in other words,
215215
// whatever & would get replaced with).
216-
217-
// FIXME(varkor): Separating out the parameters is messy.
218-
let lifetimes: Vec<_> = generic_args.args.iter().filter_map(|arg| match arg {
219-
GenericArg::Lifetime(lt) => Some(lt),
220-
_ => None,
221-
}).collect();
222-
let types: Vec<_> = generic_args.args.iter().filter_map(|arg| match arg {
223-
GenericArg::Type(ty) => Some(ty),
224-
_ => None,
225-
}).collect();
226-
let lt_provided = lifetimes.len();
227-
let ty_provided = types.len();
216+
let mut lt_provided = 0;
217+
let mut ty_provided = 0;
218+
for arg in &generic_args.args {
219+
match arg {
220+
GenericArg::Lifetime(_) => lt_provided += 1,
221+
GenericArg::Type(_) => ty_provided += 1,
222+
}
223+
}
228224

229225
let decl_generics = tcx.generics_of(def_id);
230226
let mut lt_accepted = 0;
@@ -274,30 +270,44 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
274270
false
275271
};
276272

277-
let own_self = self_ty.is_some() as usize;
273+
let self_offset = self_ty.is_some() as usize;
278274
let substs = Substs::for_item(tcx, def_id, |param, substs| {
279-
match param.kind {
280-
GenericParamDefKind::Lifetime => {
281-
let i = param.index as usize - own_self;
282-
if let Some(lt) = lifetimes.get(i) {
283-
self.ast_region_to_region(lt, Some(param)).into()
284-
} else {
285-
tcx.types.re_static.into()
275+
if param.index == 0 {
276+
if let Some(ty) = self_ty {
277+
if let GenericParamDefKind::Type { .. } = param.kind {
278+
// Handle `Self` first.
279+
return ty.into();
286280
}
287281
}
288-
GenericParamDefKind::Type { has_default, .. } => {
289-
let i = param.index as usize;
282+
}
290283

291-
// Handle Self first, so we can adjust the index to match the AST.
292-
if let (0, Some(ty)) = (i, self_ty) {
293-
return ty.into();
284+
let inferred_lifetimes = if lt_provided == 0 {
285+
lt_accepted
286+
} else {
287+
0
288+
};
289+
290+
let param_idx = (param.index as usize - self_offset).saturating_sub(inferred_lifetimes);
291+
292+
if let Some(arg) = generic_args.args.get(param_idx) {
293+
match param.kind {
294+
GenericParamDefKind::Lifetime => match arg {
295+
GenericArg::Lifetime(lt) => {
296+
return self.ast_region_to_region(lt, Some(param)).into();
297+
}
298+
_ => {}
299+
}
300+
GenericParamDefKind::Type { .. } => match arg {
301+
GenericArg::Type(ty) => return self.ast_ty_to_ty(ty).into(),
302+
_ => {}
294303
}
304+
}
305+
}
295306

296-
let i = i - (lt_accepted + own_self);
297-
if i < ty_provided {
298-
// A provided type parameter.
299-
self.ast_ty_to_ty(&types[i]).into()
300-
} else if infer_types {
307+
match param.kind {
308+
GenericParamDefKind::Lifetime => tcx.types.re_static.into(),
309+
GenericParamDefKind::Type { has_default, .. } => {
310+
if infer_types {
301311
// No type parameters were provided, we can infer all.
302312
if !default_needs_object_self(param) {
303313
self.ty_infer_for_def(param, span).into()
@@ -314,9 +324,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
314324
// careful!
315325
if default_needs_object_self(param) {
316326
struct_span_err!(tcx.sess, span, E0393,
317-
"the type parameter `{}` must be explicitly \
318-
specified",
319-
param.name)
327+
"the type parameter `{}` must be explicitly \
328+
specified",
329+
param.name)
320330
.span_label(span,
321331
format!("missing reference to `{}`", param.name))
322332
.note(&format!("because of the default `Self` reference, \

src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4987,7 +4987,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49874987
Substs::fill_single(&mut substs, defs, &mut |param: &ty::GenericParamDef, substs| {
49884988
if param.index == 0 && has_self {
49894989
if let GenericParamDefKind::Type { .. } = param.kind {
4990-
// Handle Self first, so we can adjust the index to match the AST.
4990+
// Handle `Self` first, so we can adjust the index to match the AST.
49914991
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
49924992
self.var_for_def(span, param)
49934993
});
@@ -5004,7 +5004,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50045004
if let Some(ref data) = segments[index].args {
50055005
let self_offset = (defs.parent_count == 0 && has_self) as usize;
50065006
let param_idx =
5007-
(param.index as usize - defs.parent_count - self_offset as usize)
5007+
(param.index as usize - defs.parent_count - self_offset)
50085008
.saturating_sub(infer_lifetimes[&index]);
50095009
if let Some(arg) = data.args.get(param_idx) {
50105010
match param.kind {

0 commit comments

Comments
 (0)