diff options
| author | varkor <github@varkor.com> | 2018-07-03 19:38:04 +0100 |
|---|---|---|
| committer | varkor <github@varkor.com> | 2018-08-19 20:02:32 +0100 |
| commit | 340a7fc4f5c9c8c9e8526d16c8a20ff48e0b514f (patch) | |
| tree | a8fc698c3c6097bd1d8b3c87e1e8ceba9ba2496e | |
| parent | 35ddd46a2d679b471b7c30bc4eb97de03396e838 (diff) | |
| download | rust-340a7fc4f5c9c8c9e8526d16c8a20ff48e0b514f.tar.gz rust-340a7fc4f5c9c8c9e8526d16c8a20ff48e0b514f.zip | |
Refactor astconv.rs
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 76 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 4 |
2 files changed, 45 insertions, 35 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0bc7ae04185..18bd00d43d6 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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() + if param.index == 0 { + if let Some(ty) = self_ty { + if let GenericParamDefKind::Type { .. } = param.kind { + // Handle `Self` first. + return ty.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) { - return ty.into(); + 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(), + _ => {} } + } + } - 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 { + 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() @@ -314,9 +324,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { // careful! if default_needs_object_self(param) { struct_span_err!(tcx.sess, span, E0393, - "the type parameter `{}` must be explicitly \ - specified", - param.name) + "the type parameter `{}` must be explicitly \ + specified", + param.name) .span_label(span, format!("missing reference to `{}`", param.name)) .note(&format!("because of the default `Self` reference, \ diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8286004c267..66f5e57ef6d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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 { |
