Taking a peek

This commit is contained in:
varkor 2018-08-19 20:33:38 +01:00
parent 4722744e4d
commit 25b62679e9
2 changed files with 16 additions and 17 deletions

View File

@ -455,14 +455,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// Iterate over each segment of the path. // Iterate over each segment of the path.
while let Some((def_id, defs)) = stack.pop() { while let Some((def_id, defs)) = stack.pop() {
let mut params = defs.params.iter(); let mut params = defs.params.iter().peekable();
let mut next_param = params.next();
// If we have already computed substitutions for parents, we can use those directly. // If we have already computed substitutions for parents, we can use those directly.
while let Some(param) = next_param { while let Some(&param) = params.peek() {
if let Some(&kind) = parent_substs.get(param.index as usize) { if let Some(&kind) = parent_substs.get(param.index as usize) {
push_kind(&mut substs, kind); push_kind(&mut substs, kind);
next_param = params.next(); params.next();
} else { } else {
break; break;
} }
@ -470,12 +469,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// (Unless it's been handled in `parent_substs`) `Self` is handled first. // (Unless it's been handled in `parent_substs`) `Self` is handled first.
if has_self { if has_self {
if let Some(param) = next_param { if let Some(&param) = params.peek() {
if param.index == 0 { if param.index == 0 {
if let GenericParamDefKind::Type { .. } = param.kind { if let GenericParamDefKind::Type { .. } = param.kind {
push_kind(&mut substs, self_ty.map(|ty| ty.into()) push_kind(&mut substs, self_ty.map(|ty| ty.into())
.unwrap_or_else(|| inferred_kind(None, param, true))); .unwrap_or_else(|| inferred_kind(None, param, true)));
next_param = params.next(); params.next();
} }
} }
} }
@ -484,8 +483,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// Check whether this segment takes generic arguments and the user has provided any. // Check whether this segment takes generic arguments and the user has provided any.
let (generic_args, infer_types) = args_for_def_id(def_id); let (generic_args, infer_types) = args_for_def_id(def_id);
let mut args = generic_args.iter().flat_map(|generic_args| generic_args.args.iter()); let mut args = generic_args.iter().flat_map(|generic_args| generic_args.args.iter())
let mut next_arg = args.next(); .peekable();
loop { loop {
// We're going to iterate through the generic arguments that the user // We're going to iterate through the generic arguments that the user
@ -493,12 +492,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// Mismatches can occur as a result of elided lifetimes, or for malformed // Mismatches can occur as a result of elided lifetimes, or for malformed
// input. We try to handle both sensibly. // input. We try to handle both sensibly.
let mut progress_arg = true; let mut progress_arg = true;
match (next_arg, next_param) { match (args.peek(), params.peek()) {
(Some(arg), Some(param)) => { (Some(&arg), Some(&param)) => {
match (arg, &param.kind) { match (arg, &param.kind) {
(GenericArg::Lifetime(_), GenericParamDefKind::Lifetime) => { (GenericArg::Lifetime(_), GenericParamDefKind::Lifetime) => {
push_kind(&mut substs, provided_kind(param, arg)); push_kind(&mut substs, provided_kind(param, arg));
next_param = params.next(); params.next();
} }
(GenericArg::Lifetime(_), GenericParamDefKind::Type { .. }) => { (GenericArg::Lifetime(_), GenericParamDefKind::Type { .. }) => {
// We expected a type argument, but got a lifetime // We expected a type argument, but got a lifetime
@ -510,13 +509,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
} }
(GenericArg::Type(_), GenericParamDefKind::Type { .. }) => { (GenericArg::Type(_), GenericParamDefKind::Type { .. }) => {
push_kind(&mut substs, provided_kind(param, arg)); push_kind(&mut substs, provided_kind(param, arg));
next_param = params.next(); params.next();
} }
(GenericArg::Type(_), GenericParamDefKind::Lifetime) => { (GenericArg::Type(_), GenericParamDefKind::Lifetime) => {
// We expected a lifetime argument, but got a type // We expected a lifetime argument, but got a type
// argument. That means we're inferring the lifetimes. // argument. That means we're inferring the lifetimes.
push_kind(&mut substs, inferred_kind(None, param, infer_types)); push_kind(&mut substs, inferred_kind(None, param, infer_types));
next_param = params.next(); params.next();
progress_arg = false; progress_arg = false;
} }
} }
@ -526,7 +525,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// Getting to this point means the user supplied more arguments than // Getting to this point means the user supplied more arguments than
// there are parameters. // there are parameters.
} }
(None, Some(param)) => { (None, Some(&param)) => {
// If there are fewer arguments than parameters, it means // If there are fewer arguments than parameters, it means
// we're inferring the remaining arguments. // we're inferring the remaining arguments.
match param.kind { match param.kind {
@ -538,12 +537,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
push_kind(&mut substs, kind); push_kind(&mut substs, kind);
} }
} }
next_param = params.next(); params.next();
} }
(None, None) => break, (None, None) => break,
} }
if progress_arg { if progress_arg {
next_arg = args.next(); args.next();
} }
} }
} }

View File

@ -4832,7 +4832,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Def::VariantCtor(def_id, ..) => { Def::VariantCtor(def_id, ..) => {
// Everything but the final segment should have no // Everything but the final segment should have no
// parameters at all. // parameters at all.
let mut generics = self.tcx.generics_of(def_id); let generics = self.tcx.generics_of(def_id);
// Variant and struct constructors use the // Variant and struct constructors use the
// generics of their parent type definition. // generics of their parent type definition.
let generics_def_id = generics.parent.unwrap_or(def_id); let generics_def_id = generics.parent.unwrap_or(def_id);