From 29be90bf95f2ea10c435e7b02f8c26626b956417 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 17 Jan 2021 13:53:22 +0100 Subject: =?UTF-8?q?Assertions=20with=20[eq]=20+=20better=20tests=20?= =?UTF-8?q?=F0=9F=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/eval/call.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'src/eval') diff --git a/src/eval/call.rs b/src/eval/call.rs index 8e75f17c..5b0628a8 100644 --- a/src/eval/call.rs +++ b/src/eval/call.rs @@ -73,7 +73,7 @@ impl Args { where T: Cast>, { - self.pos.iter_mut().find_map(move |slot| try_cast(ctx, slot)) + (0 .. self.pos.len()).find_map(move |i| try_cast(ctx, &mut self.pos, i)) } /// Find and remove the first convertible positional argument, producing an @@ -97,7 +97,16 @@ impl Args { where T: Cast>, { - self.pos.iter_mut().filter_map(move |slot| try_cast(ctx, slot)) + let mut i = 0; + std::iter::from_fn(move || { + while i < self.pos.len() { + if let Some(val) = try_cast(ctx, &mut self.pos, i) { + return Some(val); + } + i += 1; + } + None + }) } /// Convert and remove the value for the given named argument, producing an @@ -163,17 +172,26 @@ where /// Try to cast the value in the slot into `T`, putting it back if the /// conversion fails. -fn try_cast(ctx: &mut EvalContext, slot: &mut Spanned) -> Option +fn try_cast( + ctx: &mut EvalContext, + vec: &mut Vec>, + i: usize, +) -> Option where T: Cast>, { // Replace with error placeholder when conversion works since error values // are ignored when generating "unexpected argument" errors. - let value = std::mem::replace(slot, Spanned::zero(Value::Error)); + let slot = &mut vec[i]; + let value = std::mem::replace(slot, Spanned::zero(Value::None)); let span = value.span; match T::cast(value) { - CastResult::Ok(t) => Some(t), + CastResult::Ok(t) => { + vec.remove(i); + Some(t) + } CastResult::Warn(t, m) => { + vec.remove(i); ctx.diag(warning!(span, "{}", m)); Some(t) } -- cgit v1.2.3