From 891e0c5fa6cd9200c24011c33b6f2115d84d4d74 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sat, 10 Jul 2021 20:42:28 +0200 Subject: [PATCH] Remove warnings from parsing and casting --- src/eval/function.rs | 34 +++++-------------- src/eval/mod.rs | 8 ++--- src/eval/value.rs | 63 +++++++++++------------------------ src/library/elements.rs | 8 ++--- src/library/layout.rs | 23 +++++++------ src/library/text.rs | 47 ++++++-------------------- src/library/utility.rs | 27 ++++++--------- src/parse/mod.rs | 3 +- src/parse/parser.rs | 5 +++ tests/ref/markup/heading.png | Bin 7328 -> 7396 bytes tests/typ/markup/heading.typ | 1 - tests/typ/text/font.typ | 6 ---- tests/typ/utility/color.typ | 3 +- 13 files changed, 75 insertions(+), 153 deletions(-) diff --git a/src/eval/function.rs b/src/eval/function.rs index c986d71a9..28a628739 100644 --- a/src/eval/function.rs +++ b/src/eval/function.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Debug, Formatter}; use std::ops::Deref; use std::rc::Rc; -use super::{Cast, CastResult, EvalContext, Value}; +use super::{Cast, EvalContext, Value}; use crate::eco::EcoString; use crate::syntax::{Span, Spanned}; @@ -76,7 +76,7 @@ pub struct FuncArg { impl FuncArgs { /// Find and consume the first castable positional argument. - pub fn eat(&mut self, ctx: &mut EvalContext) -> Option + pub fn eat(&mut self) -> Option where T: Cast>, { @@ -87,19 +87,12 @@ impl FuncArgs { } let value = std::mem::replace(&mut slot.value, Spanned::zero(Value::None)); - let span = value.span; - match T::cast(value) { - CastResult::Ok(t) => { + Ok(t) => { self.items.remove(index); Some(t) } - CastResult::Warn(t, m) => { - self.items.remove(index); - ctx.diag(warning!(span, "{}", m)); - Some(t) - } - CastResult::Err(value) => { + Err(value) => { slot.value = value; None } @@ -113,7 +106,7 @@ impl FuncArgs { where T: Cast>, { - let found = self.eat(ctx); + let found = self.eat(); if found.is_none() { ctx.diag(error!(self.span, "missing argument: {}", what)); } @@ -121,16 +114,11 @@ impl FuncArgs { } /// Find, consume and collect all castable positional arguments. - /// - /// This function returns a vector instead of an iterator because the - /// iterator would require unique access to the context, rendering it rather - /// unusable. If you need to process arguments one-by-one, you probably want - /// to use a while-let loop together with [`eat()`](Self::eat). - pub fn all(&mut self, ctx: &mut EvalContext) -> Vec + pub fn all(&mut self) -> impl Iterator + '_ where T: Cast>, { - std::iter::from_fn(|| self.eat(ctx)).collect() + std::iter::from_fn(move || self.eat()) } /// Cast and remove the value for the given named argument, producing an @@ -148,12 +136,8 @@ impl FuncArgs { let span = value.span; match T::cast(value) { - CastResult::Ok(t) => Some(t), - CastResult::Warn(t, m) => { - ctx.diag(warning!(span, "{}", m)); - Some(t) - } - CastResult::Err(value) => { + Ok(t) => Some(t), + Err(value) => { ctx.diag(error!( span, "expected {}, found {}", diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 689234bd7..fd4417ec9 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -195,12 +195,8 @@ impl<'a> EvalContext<'a> { } match T::cast(value) { - CastResult::Ok(t) => Some(t), - CastResult::Warn(t, m) => { - self.diag(warning!(span, "{}", m)); - Some(t) - } - CastResult::Err(value) => { + Ok(t) => Some(t), + Err(value) => { self.diag(error!( span, "expected {}, found {}", diff --git a/src/eval/value.rs b/src/eval/value.rs index 7c35fdbd8..8e3a1c61c 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -84,7 +84,7 @@ impl Value { } /// Try to cast the value into a specific type. - pub fn cast(self) -> CastResult + pub fn cast(self) -> Result where T: Cast, { @@ -236,28 +236,7 @@ where /// Cast from a value to a specific type. pub trait Cast: Type + Sized { /// Try to cast the value into an instance of `Self`. - fn cast(value: V) -> CastResult; -} - -/// The result of casting a value to a specific type. -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum CastResult { - /// The value was cast successfully. - Ok(T), - /// The value was cast successfully, but with a warning message. - Warn(T, String), - /// The value could not be cast into the specified type. - Err(V), -} - -impl CastResult { - /// Access the conversion result, discarding a possibly existing warning. - pub fn ok(self) -> Option { - match self { - CastResult::Ok(t) | CastResult::Warn(t, _) => Some(t), - CastResult::Err(_) => None, - } - } + fn cast(value: V) -> Result; } impl Type for Value { @@ -265,8 +244,8 @@ impl Type for Value { } impl Cast for Value { - fn cast(value: Value) -> CastResult { - CastResult::Ok(value) + fn cast(value: Value) -> Result { + Ok(value) } } @@ -274,12 +253,11 @@ impl Cast> for T where T: Cast, { - fn cast(value: Spanned) -> CastResult> { + fn cast(value: Spanned) -> Result> { let span = value.span; match T::cast(value.v) { - CastResult::Ok(t) => CastResult::Ok(t), - CastResult::Warn(t, m) => CastResult::Warn(t, m), - CastResult::Err(v) => CastResult::Err(Spanned::new(v, span)), + Ok(t) => Ok(t), + Err(v) => Err(Spanned::new(v, span)), } } } @@ -288,12 +266,11 @@ impl Cast> for Spanned where T: Cast, { - fn cast(value: Spanned) -> CastResult> { + fn cast(value: Spanned) -> Result> { let span = value.span; match T::cast(value.v) { - CastResult::Ok(t) => CastResult::Ok(Spanned::new(t, span)), - CastResult::Warn(t, m) => CastResult::Warn(Spanned::new(t, span), m), - CastResult::Err(v) => CastResult::Err(Spanned::new(v, span)), + Ok(t) => Ok(Spanned::new(t, span)), + Err(v) => Err(Spanned::new(v, span)), } } } @@ -315,11 +292,11 @@ macro_rules! primitive { } impl Cast for $type { - fn cast(value: Value) -> CastResult { + fn cast(value: Value) -> Result { match value { - $variant(v) => CastResult::Ok(v), - $($pattern => CastResult::Ok($out),)* - v => CastResult::Err(v), + $variant(v) => Ok(v), + $($pattern => Ok($out),)* + v => Err(v), } } } @@ -426,26 +403,26 @@ macro_rules! castable { impl $crate::eval::Cast<$crate::eval::Value> for $type { fn cast( value: $crate::eval::Value, - ) -> $crate::eval::CastResult { + ) -> Result { use $crate::eval::*; #[allow(unreachable_code)] match value { - $($pattern => CastResult::Ok($out),)* + $($pattern => Ok($out),)* Value::Any(mut any) => { any = match any.downcast::() { - Ok(t) => return CastResult::Ok(t), + Ok(t) => return Ok(t), Err(any) => any, }; $(any = match any.downcast::<$anytype>() { - Ok($anyvar) => return CastResult::Ok($anyout), + Ok($anyvar) => return Ok($anyout), Err(any) => any, };)* - CastResult::Err(Value::Any(any)) + Err(Value::Any(any)) }, - v => CastResult::Err(v), + v => Err(v), } } } diff --git a/src/library/elements.rs b/src/library/elements.rs index 6c6c66db7..dd2da877a 100644 --- a/src/library/elements.rs +++ b/src/library/elements.rs @@ -36,7 +36,7 @@ pub fn rect(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { let width = args.named(ctx, "width"); let height = args.named(ctx, "height"); let fill = args.named(ctx, "fill"); - let body = args.eat(ctx).unwrap_or_default(); + let body = args.eat().unwrap_or_default(); rect_impl(width, height, None, fill, body) } @@ -46,7 +46,7 @@ pub fn square(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { let width = length.or_else(|| args.named(ctx, "width")); let height = width.is_none().then(|| args.named(ctx, "height")).flatten(); let fill = args.named(ctx, "fill"); - let body = args.eat(ctx).unwrap_or_default(); + let body = args.eat().unwrap_or_default(); rect_impl(width, height, Some(N64::from(1.0)), fill, body) } @@ -80,7 +80,7 @@ pub fn ellipse(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { let width = args.named(ctx, "width"); let height = args.named(ctx, "height"); let fill = args.named(ctx, "fill"); - let body = args.eat(ctx).unwrap_or_default(); + let body = args.eat().unwrap_or_default(); ellipse_impl(width, height, None, fill, body) } @@ -90,7 +90,7 @@ pub fn circle(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { let width = radius.or_else(|| args.named(ctx, "width")); let height = width.is_none().then(|| args.named(ctx, "height")).flatten(); let fill = args.named(ctx, "fill"); - let body = args.eat(ctx).unwrap_or_default(); + let body = args.eat().unwrap_or_default(); ellipse_impl(width, height, Some(N64::from(1.0)), fill, body) } diff --git a/src/library/layout.rs b/src/library/layout.rs index d7ada806f..19352062d 100644 --- a/src/library/layout.rs +++ b/src/library/layout.rs @@ -5,7 +5,7 @@ use crate::paper::{Paper, PaperClass}; /// `page`: Configure pages. pub fn page(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { let span = args.span; - let paper = args.eat::>(ctx).and_then(|name| { + let paper = args.eat::>().and_then(|name| { Paper::from_name(&name.v).or_else(|| { ctx.diag(error!(name.span, "invalid paper name")); None @@ -104,8 +104,8 @@ fn spacing_impl(ctx: &mut EvalContext, args: &mut FuncArgs, axis: GenAxis) -> Va /// `align`: Configure the alignment along the layouting axes. pub fn align(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { - let first = args.eat::(ctx); - let second = args.eat::(ctx); + let first = args.eat::(); + let second = args.eat::(); let mut horizontal = args.named::(ctx, "horizontal"); let mut vertical = args.named::(ctx, "vertical"); let body = args.expect::