diff --git a/assembly/src/ast/ident.rs b/assembly/src/ast/ident.rs index 0f7e594c8..ea2d13a23 100644 --- a/assembly/src/ast/ident.rs +++ b/assembly/src/ast/ident.rs @@ -12,8 +12,8 @@ use crate::{SourceSpan, Span, Spanned}; pub enum IdentError { #[error("invalid identifier: cannot be empty")] Empty, - #[error("invalid identifier: must contain only lowercase, ascii alphanumeric characters, or underscores")] - InvalidChars, + #[error("invalid identifier '{ident}': must contain only lowercase, ascii alphanumeric characters, or underscores")] + InvalidChars { ident: Arc }, #[error("invalid identifier: must start with lowercase ascii alphabetic character")] InvalidStart, #[error("invalid identifier: length exceeds the maximum of {max} bytes")] @@ -109,7 +109,7 @@ impl Ident { return Err(IdentError::InvalidStart); } if !source.chars().all(|c| c.is_ascii_alphabetic() || matches!(c, '_' | '0'..='9')) { - return Err(IdentError::InvalidChars); + return Err(IdentError::InvalidChars { ident: source.into() }); } Ok(()) } diff --git a/assembly/src/ast/procedure/name.rs b/assembly/src/ast/procedure/name.rs index f7979bd42..731610aaf 100644 --- a/assembly/src/ast/procedure/name.rs +++ b/assembly/src/ast/procedure/name.rs @@ -298,17 +298,17 @@ impl FromStr for ProcedureName { match c { '"' => { if chars.next().is_some() { - break Err(IdentError::InvalidChars); + break Err(IdentError::InvalidChars { ident: s.into() }); } let tok = &s[1..pos]; break Ok(Arc::from(tok.to_string().into_boxed_str())); }, c if c.is_alphanumeric() => continue, '_' | '$' | '-' | '!' | '?' | '<' | '>' | ':' | '.' => continue, - _ => break Err(IdentError::InvalidChars), + _ => break Err(IdentError::InvalidChars { ident: s.into() }), } } else { - break Err(IdentError::InvalidChars); + break Err(IdentError::InvalidChars { ident: s.into() }); } }, Some((_, c)) if c.is_ascii_lowercase() || c == '_' || c == '$' => { @@ -317,13 +317,13 @@ impl FromStr for ProcedureName { '_' | '$' => false, _ => true, }) { - Err(IdentError::InvalidChars) + Err(IdentError::InvalidChars { ident: s.into() }) } else { Ok(Arc::from(s.to_string().into_boxed_str())) } }, Some((_, c)) if c.is_ascii_uppercase() => Err(IdentError::Casing(CaseKindError::Snake)), - Some(_) => Err(IdentError::InvalidChars), + Some(_) => Err(IdentError::InvalidChars { ident: s.into() }), }?; Ok(Self(Ident::new_unchecked(Span::unknown(raw)))) } diff --git a/assembly/src/library/path.rs b/assembly/src/library/path.rs index 22e5fe847..8175339dd 100644 --- a/assembly/src/library/path.rs +++ b/assembly/src/library/path.rs @@ -575,7 +575,10 @@ mod tests { assert_matches!(path, Err(PathError::InvalidComponent(IdentError::InvalidStart))); let path = LibraryPath::new("foo::b@r"); - assert_matches!(path, Err(PathError::InvalidComponent(IdentError::InvalidChars))); + assert_matches!( + path, + Err(PathError::InvalidComponent(IdentError::InvalidChars { ident: _ })) + ); let path = LibraryPath::new("#foo::bar"); assert_matches!(