src: address a bunch of clippy::pedantic lints

This commit is contained in:
2025-10-28 02:53:20 -04:00
parent 0bf5a41498
commit 588606e0c4
8 changed files with 50 additions and 51 deletions

View File

@@ -276,7 +276,7 @@ impl<A: Annotation> Default for Expr<A> {
} }
impl<A: Annotation> Expr<A> { impl<A: Annotation> Expr<A> {
pub fn anno(self, annotation: A) -> Anno<Expr<A>, A> { pub const fn anno(self, annotation: A) -> Anno<Expr<A>, A> {
Anno(self, annotation) Anno(self, annotation)
} }
@@ -292,15 +292,15 @@ impl<A: Annotation> Expr<A> {
Self::Op(Op::Do, exprs) Self::Op(Op::Do, exprs)
} }
pub fn is_place(&self) -> bool { pub const fn is_place(&self) -> bool {
matches!( matches!(
self, self,
Self::Id(_) | Self::Op(Op::Index, _) | Self::Op(Op::Dot, _) | Self::Op(Op::Deref, _) Self::Id(_) | Self::Op(Op::Index | Op::Dot | Op::Deref, _)
) )
} }
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub fn as_slice(&self) -> Option<(Op, &[Anno<Expr<A>, A>])> { pub const fn as_slice(&self) -> Option<(Op, &[Anno<Expr<A>, A>])> {
match self { match self {
Expr::Op(op, args) => Some((*op, args.as_slice())), Expr::Op(op, args) => Some((*op, args.as_slice())),
_ => None, _ => None,

View File

@@ -135,7 +135,7 @@ impl<A: Annotation> Match<A> for Expr<A> {
match self { match self {
Expr::MetId(id) => { Expr::MetId(id) => {
if let Some(expr) = sub.exp.get(id) { if let Some(expr) = sub.exp.get(id) {
*self = expr.clone() *self = expr.clone();
} }
} }
Expr::Omitted | Expr::Id(_) | Expr::Lit(_) | Expr::Use(_) => {} Expr::Omitted | Expr::Id(_) | Expr::Lit(_) | Expr::Use(_) => {}
@@ -145,7 +145,7 @@ impl<A: Annotation> Match<A> for Expr<A> {
op.apply(sub); op.apply(sub);
exprs.apply(sub); exprs.apply(sub);
} }
}; }
} }
} }
@@ -190,7 +190,7 @@ impl<A: Annotation> Match<A> for Pat {
Pat::Ignore | Pat::Never | Pat::Name(_) | Pat::Path(_) | Pat::Lit(_) => {} Pat::Ignore | Pat::Never | Pat::Name(_) | Pat::Path(_) | Pat::Lit(_) => {}
Pat::MetId(id) => { Pat::MetId(id) => {
if let Some(expr) = sub.pat.get(id) { if let Some(expr) = sub.pat.get(id) {
*self = expr.clone() *self = expr.clone();
} }
} }
Pat::NamedStruct(_, expr) => expr.apply(sub), Pat::NamedStruct(_, expr) => expr.apply(sub),

View File

@@ -62,7 +62,7 @@ pub trait FmtAdapter: Write {
if !rest.is_empty() { if !rest.is_empty() {
write!(self, "{sep}")?; write!(self, "{sep}")?;
} }
items = rest items = rest;
} }
write!(self, "{close}") write!(self, "{close}")
} }
@@ -76,12 +76,12 @@ pub struct Indent<'f, F: Write + ?Sized> {
} }
impl<'f, F: Write + ?Sized> Indent<'f, F> { impl<'f, F: Write + ?Sized> Indent<'f, F> {
pub fn new(f: &'f mut F, indent: &'static str) -> Self { pub const fn new(f: &'f mut F, indent: &'static str) -> Self {
Indent { f, needs_indent: false, indent } Indent { f, needs_indent: false, indent }
} }
/// Gets mutable access to the inner [Write]-adapter /// Gets mutable access to the inner [Write]-adapter
pub fn inner(&mut self) -> &mut F { pub const fn inner(&mut self) -> &mut F {
self.f self.f
} }
} }
@@ -113,9 +113,9 @@ pub struct Delimit<'f, F: Write + ?Sized, E: Display = &'static str> {
close: E, close: E,
} }
impl<'f, F: Write + ?Sized, E: Display> Delimit<'f, F, E> { impl<F: Write + ?Sized, E: Display> Delimit<'_, F, E> {
/// Gets mutable access to the inner [Write]-adapter /// Gets mutable access to the inner [Write]-adapter
pub fn inner(&mut self) -> &mut F { pub const fn inner(&mut self) -> &mut F {
self.f self.f
} }
} }
@@ -146,9 +146,9 @@ pub struct DelimitIndent<'f, F: Write + ?Sized, E: Display = &'static str> {
close: E, close: E,
} }
impl<'f, F: Write + ?Sized, E: Display> DelimitIndent<'f, F, E> { impl<F: Write + ?Sized, E: Display> DelimitIndent<'_, F, E> {
/// Gets mutable access to the inner [Write]-adapter /// Gets mutable access to the inner [Write]-adapter
pub fn inner(&mut self) -> &mut F { pub const fn inner(&mut self) -> &mut F {
self.f.inner() self.f.inner()
} }
} }
@@ -164,7 +164,7 @@ impl<'f, F: Write + ?Sized, E: Display> DelimitIndent<'f, F, E> {
impl<F: Write + ?Sized, E: Display> Drop for DelimitIndent<'_, F, E> { impl<F: Write + ?Sized, E: Display> Drop for DelimitIndent<'_, F, E> {
fn drop(&mut self) { fn drop(&mut self) {
let Self { f: Indent { f, .. }, close, .. } = self; let Self { f: Indent { f, .. }, close, .. } = self;
let _ = write!(f, "{}", close); let _ = write!(f, "{close}");
} }
} }

View File

@@ -110,8 +110,8 @@ impl<'t> Lexer<'t> {
self self
} }
/// Produces a LexError at the start of the current token /// Produces a [`LexError`] at the start of the current token
fn error(&self, res: LexFailure) -> LexError { const fn error(&self, res: LexFailure) -> LexError {
LexError { pos: Span(self.head, self.tail), res } LexError { pos: Span(self.head, self.tail), res }
} }
@@ -144,7 +144,7 @@ impl<'t> Lexer<'t> {
self self
} }
fn start_token(&mut self) -> &mut Self { const fn start_token(&mut self) -> &mut Self {
self.head = self.tail; self.head = self.tail;
self self
} }
@@ -278,11 +278,11 @@ impl<'t> Lexer<'t> {
Err(self.error(UnterminatedBlockComment)) Err(self.error(UnterminatedBlockComment))
} }
/// Consumes characters until it reaches a character not in [is_xid_continue]. /// Consumes characters until it reaches a character not in [`is_xid_continue`].
/// ///
/// Always consumes the first character. /// Always consumes the first character.
/// ///
/// Maps the result to either a [TKind::Identifier] or a [TKind] keyword. /// Maps the result to either a [`TKind::Identifier`] or a [`TKind`] keyword.
pub fn identifier(&mut self) -> Result<Token, LexError> { pub fn identifier(&mut self) -> Result<Token, LexError> {
while self.consume().peek().is_some_and(is_xid_continue) {} while self.consume().peek().is_some_and(is_xid_continue) {}
let (lexeme, _span) = self.as_str(); let (lexeme, _span) = self.as_str();
@@ -346,7 +346,7 @@ impl<'t> Lexer<'t> {
Some('\\') => self.escape()?, Some('\\') => self.escape()?,
Some('"') => break, Some('"') => break,
Some(c) => c, Some(c) => c,
}) });
} }
lexeme.shrink_to_fit(); lexeme.shrink_to_fit();
Ok(self.produce_with_lexeme(TKind::String, Lexeme::String(lexeme))) Ok(self.produce_with_lexeme(TKind::String, Lexeme::String(lexeme)))
@@ -375,7 +375,7 @@ impl<'t> Lexer<'t> {
/// Parses two hex-digits and constructs a [char] out of them. /// Parses two hex-digits and constructs a [char] out of them.
pub fn hex_escape(&mut self) -> Result<char, LexError> { pub fn hex_escape(&mut self) -> Result<char, LexError> {
let out = (self.digit::<16>()? << 4) + self.digit::<16>()?; let out = (self.digit::<16>()? << 4) + self.digit::<16>()?;
char::from_u32(out).ok_or(self.error(InvalidUnicodeEscape(out))) char::from_u32(out).ok_or_else(|| self.error(InvalidUnicodeEscape(out)))
} }
/// Parses a sequence of `{}`-bracketed hex-digits and constructs a [char] out of them. /// Parses a sequence of `{}`-bracketed hex-digits and constructs a [char] out of them.

View File

@@ -27,7 +27,7 @@ pub mod typed_ast {
pub local: HashMap<usize, isize>, pub local: HashMap<usize, isize>,
} }
/// DefID annotation /// `DefID` annotation
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Defn { pub struct Defn {
pub span: Span, pub span: Span,

View File

@@ -1,4 +1,5 @@
//! The parser takes a stream of [Token]s from the [Lexer], and turns them into [crate::ast] nodes. //! The parser takes a stream of [`Token`]s from the [`Lexer`], and turns them into [`crate::ast`]
//! nodes.
use crate::{ use crate::{
ast::*, ast::*,
lexer::{LexError, LexFailure, Lexer}, lexer::{LexError, LexFailure, Lexer},
@@ -68,7 +69,7 @@ impl<T> PResultExt<T> for PResult<T> {
} }
} }
/// Opens a scope where [ParseError::EOF] is unexpected (See [PResultExt::no_eof]) /// Opens a scope where [`ParseError::EOF`] is unexpected (See [`PResultExt::no_eof`])
fn no_eof<T>(f: impl FnOnce() -> PResult<T>) -> PResult<T> { fn no_eof<T>(f: impl FnOnce() -> PResult<T>) -> PResult<T> {
f().no_eof() f().no_eof()
} }
@@ -88,11 +89,11 @@ impl<'t> Parser<'t> {
} }
/// The identity function. This exists to make production chaining easier. /// The identity function. This exists to make production chaining easier.
pub fn then<T>(&self, t: T) -> T { pub const fn then<T>(&self, t: T) -> T {
t t
} }
pub fn span(&self) -> Span { pub const fn span(&self) -> Span {
self.last_loc self.last_loc
} }
@@ -101,7 +102,7 @@ impl<'t> Parser<'t> {
Parse::parse(self, level) Parse::parse(self, level)
} }
/// Peeks the next [Token]. Returns [ParseError::FromLexer] on lexer error. /// Peeks the next [`Token`]. Returns [`ParseError::FromLexer`] on lexer error.
pub fn peek(&mut self) -> PResult<&Token> { pub fn peek(&mut self) -> PResult<&Token> {
let next_tok = match self.next_tok.take() { let next_tok = match self.next_tok.take() {
Some(tok) => tok, Some(tok) => tok,
@@ -114,9 +115,7 @@ impl<'t> Parser<'t> {
} }
}, },
}; };
self.next_tok = Some(next_tok); let next_tok = self.next_tok.insert(next_tok);
let next_tok = self.next_tok.as_ref().expect("should have Some lex result");
if let Ok(tok) = next_tok { if let Ok(tok) = next_tok {
self.last_loc = tok.span; self.last_loc = tok.span;
@@ -125,7 +124,7 @@ impl<'t> Parser<'t> {
next_tok.as_ref().map_err(|e| *e) next_tok.as_ref().map_err(|e| *e)
} }
/// Peeks the next token if it matches the `expected` [TKind] /// Peeks the next token if it matches the `expected` [`TKind`]
pub fn peek_if(&mut self, expected: TKind) -> PResult<Option<&Token>> { pub fn peek_if(&mut self, expected: TKind) -> PResult<Option<&Token>> {
match self.peek() { match self.peek() {
Ok(tok) if tok.kind == expected => Ok(Some(tok)), Ok(tok) if tok.kind == expected => Ok(Some(tok)),
@@ -152,10 +151,10 @@ impl<'t> Parser<'t> {
#[allow(clippy::should_implement_trait)] #[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> PResult<Token> { pub fn next(&mut self) -> PResult<Token> {
self.peek().no_eof()?; self.peek().no_eof()?;
Ok(self.take().expect("should have token here")) self.take() // .expect("should have token here")
} }
/// Consumes and returns the next [Token] if it matches the `expected` [TKind] /// Consumes and returns the next [`Token`] if it matches the `expected` [`TKind`]
pub fn next_if(&mut self, expected: TKind) -> PResult<Result<Token, TKind>> { pub fn next_if(&mut self, expected: TKind) -> PResult<Result<Token, TKind>> {
match self.peek() { match self.peek() {
Ok(t) if t.kind == expected => self.take().map(Ok), Ok(t) if t.kind == expected => self.take().map(Ok),
@@ -177,7 +176,7 @@ impl<'t> Parser<'t> {
) -> PResult<Vec<P>> { ) -> PResult<Vec<P>> {
// TODO: This loses lexer errors // TODO: This loses lexer errors
while self.peek_if(end).no_eof()?.is_none() { while self.peek_if(end).no_eof()?.is_none() {
elems.push(self.parse(level.clone()).no_eof()?); elems.push(self.parse(level).no_eof()?);
match self.peek_if(sep)? { match self.peek_if(sep)? {
Some(_) => self.consume(), Some(_) => self.consume(),
None => break, None => break,
@@ -199,7 +198,7 @@ impl<'t> Parser<'t> {
sep: TKind, sep: TKind,
) -> PResult<Vec<P>> { ) -> PResult<Vec<P>> {
loop { loop {
let elem = self.parse(level.clone()).no_eof()?; let elem = self.parse(level).no_eof()?;
elems.push(elem); elems.push(elem);
match self.peek_if(sep) { match self.peek_if(sep) {
Ok(Some(_)) => self.consume(), Ok(Some(_)) => self.consume(),
@@ -241,13 +240,13 @@ impl<'t> Parser<'t> {
} }
pub trait Parse<'t> { pub trait Parse<'t> {
type Prec: Clone; type Prec: Copy;
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self>
where Self: Sized; where Self: Sized;
} }
impl<'t> Parse<'t> for FqPath { impl<'t> Parse<'t> for FqPath {
// ugly hack: provide a partial path to parse()
type Prec = (); type Prec = ();
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> { fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
@@ -317,7 +316,7 @@ pub enum PPrec {
} }
impl PPrec { impl PPrec {
fn next(self) -> Self { const fn next(self) -> Self {
match self { match self {
Self::Min => Self::Alt, Self::Min => Self::Alt,
Self::Alt => Self::Tuple, Self::Alt => Self::Tuple,
@@ -448,7 +447,7 @@ impl<'t> Parse<'t> for Pat {
} }
} }
fn parse_array_pat<'t>(p: &mut Parser<'t>) -> PResult<Pat> { fn parse_array_pat(p: &mut Parser<'_>) -> PResult<Pat> {
if p.consume().peek()?.kind == TKind::RBrack { if p.consume().peek()?.kind == TKind::RBrack {
p.consume(); p.consume();
return Ok(Pat::Op(PatOp::Slice, vec![])); return Ok(Pat::Op(PatOp::Slice, vec![]));
@@ -528,7 +527,7 @@ impl Prec {
} }
} }
/// PseudoOperator: fake operators used to give certain tokens special behavior. /// `PseudoOperator`: fake operators used to give certain tokens special behavior.
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Ps { pub enum Ps {
Id, // Identifier Id, // Identifier
@@ -603,7 +602,7 @@ fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
}) })
} }
fn from_infix(token: &Token) -> PResult<(Ps, Prec)> { const fn from_infix(token: &Token) -> PResult<(Ps, Prec)> {
Ok(match token.kind { Ok(match token.kind {
TKind::Semi => (Ps::Op(Op::Do), Prec::Do), // the inspiration TKind::Semi => (Ps::Op(Op::Do), Prec::Do), // the inspiration
TKind::In => (Ps::Op(Op::Do), Prec::Do), TKind::In => (Ps::Op(Op::Do), Prec::Do),
@@ -806,7 +805,7 @@ impl<'t> Parse<'t> for Expr {
p.consume() p.consume()
.expect(TKind::LBrack)? .expect(TKind::LBrack)?
.opt(MIN, TKind::RBrack)? .opt(MIN, TKind::RBrack)?
.unwrap_or(Expr::Op(Op::Tuple, vec![]).anno(span)), .unwrap_or_else(|| Expr::Op(Op::Tuple, vec![]).anno(span)),
p.parse(level)?, p.parse(level)?,
], ],
), ),
@@ -885,7 +884,7 @@ impl<'t> Parse<'t> for Expr {
head.anno(span), head.anno(span),
p.consume() p.consume()
.opt(0, TKind::RParen)? .opt(0, TKind::RParen)?
.unwrap_or(Expr::Op(Op::Tuple, vec![]).anno(span)), .unwrap_or_else(|| Expr::Op(Op::Tuple, vec![]).anno(span)),
], ],
), ),
Ps::Op(op @ (Op::Tuple | Op::Dot | Op::LogAnd | Op::LogOr)) => Expr::Op( Ps::Op(op @ (Op::Tuple | Op::Dot | Op::LogAnd | Op::LogOr)) => Expr::Op(
@@ -910,7 +909,7 @@ impl<'t> Parse<'t> for Expr {
} }
/// Parses an array with 0 or more elements, or an array-repetition /// Parses an array with 0 or more elements, or an array-repetition
fn parse_array<'t>(p: &mut Parser<'t>) -> PResult<Expr> { fn parse_array(p: &mut Parser<'_>) -> PResult<Expr> {
if p.consume().peek()?.kind == TKind::RBrack { if p.consume().peek()?.kind == TKind::RBrack {
p.consume(); p.consume();
return Ok(Expr::Op(Op::Array, vec![])); return Ok(Expr::Op(Op::Array, vec![]));
@@ -928,7 +927,7 @@ fn parse_array<'t>(p: &mut Parser<'t>) -> PResult<Expr> {
}) })
} }
fn parse_match<'t>(p: &mut Parser<'t>) -> PResult<Expr> { fn parse_match(p: &mut Parser<'_>) -> PResult<Expr> {
let scrutinee = p.consume().parse(Prec::Logical.value())?; let scrutinee = p.consume().parse(Prec::Logical.value())?;
let arms = p let arms = p
@@ -942,7 +941,7 @@ fn parse_match<'t>(p: &mut Parser<'t>) -> PResult<Expr> {
Ok(expr) Ok(expr)
} }
fn parse_for<'t>(p: &mut Parser<'t>, _level: ()) -> PResult<Expr> { fn parse_for(p: &mut Parser<'_>, _level: ()) -> PResult<Expr> {
// for Pat // for Pat
let pat = p.consume().parse(PPrec::Tuple)?; let pat = p.consume().parse(PPrec::Tuple)?;
// in Expr // in Expr

View File

@@ -16,7 +16,7 @@ impl std::fmt::Debug for Span {
#[expect(non_snake_case)] #[expect(non_snake_case)]
/// Stores the start and end byte position /// Stores the start and end byte position
pub fn Span(head: u32, tail: u32) -> Span { pub const fn Span(head: u32, tail: u32) -> Span {
Span { head, tail } Span { head, tail }
} }

View File

@@ -10,7 +10,7 @@ pub struct Token {
} }
impl Token { impl Token {
pub fn kind(&self) -> TKind { pub const fn kind(&self) -> TKind {
self.kind self.kind
} }
} }
@@ -35,13 +35,13 @@ impl Lexeme {
_ => None, _ => None,
} }
} }
pub fn int(&self) -> Option<u128> { pub const fn int(&self) -> Option<u128> {
match self { match self {
Self::Integer(i, _) => Some(*i), Self::Integer(i, _) => Some(*i),
_ => None, _ => None,
} }
} }
pub fn char(&self) -> Option<char> { pub const fn char(&self) -> Option<char> {
match self { match self {
Self::Char(c) => Some(*c), Self::Char(c) => Some(*c),
_ => None, _ => None,