no more type dep cycle (resolved with lazy_static)

This commit is contained in:
Ponj 2024-11-09 22:37:01 -05:00
parent 1c91b113fb
commit f0be539c69
Signed by: p6nj
GPG key ID: 6FED68D87C479A59
4 changed files with 167 additions and 21 deletions

View file

@ -22,6 +22,7 @@ const_format = "0.2.33"
thiserror = "1.0.64" thiserror = "1.0.64"
derive-new = "0.7.0" derive-new = "0.7.0"
naan = "0.1.32" naan = "0.1.32"
lazy_static = "1.5.0"
[features] [features]
default = ["play", "save"] default = ["play", "save"]

122
check.txt Normal file
View file

@ -0,0 +1,122 @@
Checking bng v0.1.0 (/home/p6nj/bng)
error[E0720]: cannot resolve opaque type
--> src/bng/score/lex/lexer.rs:35:39
|
35 | pub fn root<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atoms, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type
...
42 | / terminated(
43 | | many1(preceded(maybe_yml_str_space(), atom(notes))),
44 | | maybe_yml_str_space(),
45 | | )
46 | | .map(Atoms)
| |_______________- returning here with type `nom::Map<impl FnMut(&str) -> std::result::Result<(&str, std::vec::Vec<Atom>), nom::Err<E>>, fn(std::vec::Vec<Atom>) -> Atoms {Atoms}, std::vec::Vec<Atom>>`
|
::: /home/p6nj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/sequence/mod.rs:100:6
|
100 | ) -> impl FnMut(I) -> IResult<I, O1, E>
| ---------------------------------- returning this type `nom::Map<impl FnMut(&str) -> std::result::Result<(&str, std::vec::Vec<Atom>), nom::Err<E>>, fn(std::vec::Vec<Atom>) -> Atoms {Atoms}, std::vec::Vec<Atom>>`
error[E0720]: cannot resolve opaque type
--> src/bng/score/lex/lexer.rs:98:37
|
98 | fn r#loop<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type
...
105 | / context(
106 | | "loop",
107 | | delimited(
108 | | char(Atom::LOOP.0),
... |
121 | | )
122 | | .map(|(n, v)| Atom::Loop(n, v))
| |___________________________________- returning here with type `nom::Map<impl FnMut(&str) -> std::result::Result<(&str, (NonZero<u8>, Atoms)), nom::Err<E>>, {closure@src/bng/score/lex/lexer.rs:122:10: 122:18}, (NonZero<u8>, Atoms)>`
|
::: /home/p6nj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/error.rs:236:6
|
236 | ) -> impl FnMut(I) -> IResult<I, O, E>
| --------------------------------- returning this type `nom::Map<impl FnMut(&str) -> std::result::Result<(&str, (NonZero<u8>, Atoms)), nom::Err<E>>, {closure@src/bng/score/lex/lexer.rs:122:10: 122:18}, (NonZero<u8>, Atoms)>`
error[E0720]: cannot resolve opaque type
--> src/bng/score/lex/lexer.rs:185:35
|
185 | fn atom<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type
...
192 | / context(
193 | | "atom",
194 | | alt((
195 | | note(notes),
... |
204 | | )),
205 | | )
| |_____- returning here with type `impl FnMut(&str) -> std::result::Result<(&str, Atom), nom::Err<E>>`
|
::: /home/p6nj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/error.rs:236:6
|
236 | ) -> impl FnMut(I) -> IResult<I, O, E>
| --------------------------------- returning this opaque type `impl FnMut(&str) -> std::result::Result<(&str, Atom), nom::Err<E>>`
error[E0391]: cycle detected when computing type of opaque `bng::score::lex::lexer::root::{opaque#0}`
--> src/bng/score/lex/lexer.rs:35:39
|
35 | pub fn root<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atoms, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `bng::score::lex::lexer::root`...
--> src/bng/score/lex/lexer.rs:46:6
|
46 | .map(Atoms)
| ^^^
= note: ...which requires evaluating trait selection obligation `nom::sequence::terminated::{opaque#0}: core::marker::Sync`...
= note: ...which again requires computing type of opaque `bng::score::lex::lexer::root::{opaque#0}`, completing the cycle
note: cycle used when computing type of `bng::score::lex::lexer::root::{opaque#0}`
--> src/bng/score/lex/lexer.rs:35:39
|
35 | pub fn root<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atoms, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error[E0391]: cycle detected when computing type of opaque `bng::score::lex::lexer::tuple::{opaque#0}`
--> src/bng/score/lex/lexer.rs:125:36
|
125 | fn tuple<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `bng::score::lex::lexer::tuple`...
--> src/bng/score/lex/lexer.rs:136:6
|
136 | .map(Atom::Tuple)
| ^^^
= note: ...which requires evaluating trait selection obligation `nom::error::context::{opaque#0}: core::marker::Sync`...
= note: ...which again requires computing type of opaque `bng::score::lex::lexer::tuple::{opaque#0}`, completing the cycle
note: cycle used when computing type of `bng::score::lex::lexer::tuple::{opaque#0}`
--> src/bng/score/lex/lexer.rs:125:36
|
125 | fn tuple<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error[E0391]: cycle detected when computing type of opaque `bng::score::lex::lexer::slope::{opaque#0}`
--> src/bng/score/lex/lexer.rs:139:36
|
139 | fn slope<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `bng::score::lex::lexer::slope`...
--> src/bng/score/lex/lexer.rs:165:6
|
165 | .map(|((sm, i), v)| Atom::Slope(sm, i, v))
| ^^^
= note: ...which requires evaluating trait selection obligation `nom::error::context::{opaque#0}: core::marker::Sync`...
= note: ...which again requires computing type of opaque `bng::score::lex::lexer::slope::{opaque#0}`, completing the cycle
note: cycle used when computing type of `bng::score::lex::lexer::slope::{opaque#0}`
--> src/bng/score/lex/lexer.rs:139:36
|
139 | fn slope<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
Some errors have detailed explanations: E0391, E0720.
For more information about an error, try `rustc --explain E0391`.
error: could not compile `bng` (bin "bng") due to 6 previous errors

View file

@ -20,7 +20,7 @@ use serde::{
}; };
use thiserror::Error; use thiserror::Error;
use crate::bng::score::lex::lexer::root; use crate::bng::score::lex::lexer::{root, set_notes};
use super::{Atom, Atoms}; use super::{Atom, Atoms};
@ -44,7 +44,8 @@ impl<'de> Deserialize<'de> for Atoms {
if sheet.is_empty() { if sheet.is_empty() {
Ok(Default::default()) Ok(Default::default())
} else { } else {
all_consuming(root(&notes))(&sheet) set_notes(notes).unwrap();
all_consuming(root)(&sheet)
.map_err(|e| pretty_verbose_err.curry().call1(sheet.as_str()).call1(e)) .map_err(|e| pretty_verbose_err.curry().call1(sheet.as_str()).call1(e))
.map_err(de::Error::custom) .map_err(de::Error::custom)
.map(|(i, r)| r) .map(|(i, r)| r)

View file

@ -1,10 +1,12 @@
use std::{ use std::{
collections::BTreeMap, collections::BTreeMap,
num::{NonZeroU16, NonZeroU8, TryFromIntError}, num::{NonZeroU16, NonZeroU8, TryFromIntError},
sync::{Mutex, MutexGuard, PoisonError},
}; };
use clap::builder::TypedValueParser; use clap::builder::TypedValueParser;
use fasteval::Compiler; use fasteval::Compiler;
use lazy_static::lazy_static;
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::{take_till, take_till1}, bytes::complete::{take_till, take_till1},
@ -25,6 +27,16 @@ use super::{
// #[cfg(test)] // #[cfg(test)]
// mod tests; // mod tests;
lazy_static! {
static ref NOTES: Mutex<Option<String>> = Mutex::new(None);
}
pub fn set_notes(
notes: impl ToString,
) -> Result<Option<String>, PoisonError<MutexGuard<'static, Option<String>>>> {
Ok(NOTES.lock()?.replace(notes.to_string()))
}
fn maybe_yml_str_space<'a, E>() -> impl Parser<&'a str, Vec<char>, E> fn maybe_yml_str_space<'a, E>() -> impl Parser<&'a str, Vec<char>, E>
where where
E: nom::error::ParseError<&'a str> + ContextError<&'a str>, E: nom::error::ParseError<&'a str> + ContextError<&'a str>,
@ -32,7 +44,7 @@ where
context("yml white space", many0(one_of(" \t\r\n"))) context("yml white space", many0(one_of(" \t\r\n")))
} }
pub fn root<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atoms, E> pub fn root<'a, E>(i: &'a str) -> IResult<&'a str, Atoms, E>
where where
E: ParseError<&'a str> E: ParseError<&'a str>
+ ContextError<&'a str> + ContextError<&'a str>
@ -40,21 +52,27 @@ where
+ FromExternalError<&'a str, E>, + FromExternalError<&'a str, E>,
{ {
terminated( terminated(
many1(preceded(maybe_yml_str_space(), atom(notes))), many1(preceded(maybe_yml_str_space(), atom)),
maybe_yml_str_space(), maybe_yml_str_space(),
) )
.map(Atoms) .map(Atoms)
.parse(i)
} }
fn note<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> fn note<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
where where
E: ParseError<&'a str> + ContextError<&'a str> + FromExternalError<&'a str, TryFromIntError>, E: ParseError<&'a str> + ContextError<&'a str> + FromExternalError<&'a str, TryFromIntError>,
{ {
if let Some(notes) = NOTES.lock().unwrap().as_deref() {
context( context(
"note", "note",
map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from), map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from),
) )
.map(Atom::Note) .map(Atom::Note)
.parse(i)
} else {
panic!("trouble locking the note set!")
}
} }
fn rest<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E> fn rest<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
@ -95,7 +113,7 @@ where
.parse(i) .parse(i)
} }
fn r#loop<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> fn r#loop<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
where where
E: ParseError<&'a str> E: ParseError<&'a str>
+ ContextError<&'a str> + ContextError<&'a str>
@ -114,15 +132,16 @@ where
unsafe { Some(NonZeroU8::new_unchecked(2)) } unsafe { Some(NonZeroU8::new_unchecked(2)) }
} }
}), }),
root(notes), root,
), ),
char(Atom::LOOP.1), char(Atom::LOOP.1),
), ),
) )
.map(|(n, v)| Atom::Loop(n, v)) .map(|(n, v)| Atom::Loop(n, v))
.parse(i)
} }
fn tuple<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> fn tuple<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
where where
E: ParseError<&'a str> E: ParseError<&'a str>
+ ContextError<&'a str> + ContextError<&'a str>
@ -131,12 +150,13 @@ where
{ {
context( context(
"tuple", "tuple",
delimited(char(Atom::TUPLE.0), root(notes), char(Atom::TUPLE.1)), delimited(char(Atom::TUPLE.0), root, char(Atom::TUPLE.1)),
) )
.map(Atom::Tuple) .map(Atom::Tuple)
.parse(i)
} }
fn slope<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> fn slope<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
where where
E: ParseError<&'a str> E: ParseError<&'a str>
+ ContextError<&'a str> + ContextError<&'a str>
@ -159,10 +179,11 @@ where
), ),
), ),
char(','), char(','),
root(notes), root,
), ),
) )
.map(|((sm, i), v)| Atom::Slope(sm, i, v)) .map(|((sm, i), v)| Atom::Slope(sm, i, v))
.parse(i)
} }
fn comment<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E> fn comment<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
@ -182,7 +203,7 @@ where
)(i) )(i)
} }
fn atom<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> fn atom<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
where where
E: ParseError<&'a str> E: ParseError<&'a str>
+ ContextError<&'a str> + ContextError<&'a str>
@ -192,15 +213,16 @@ where
context( context(
"atom", "atom",
alt(( alt((
note(notes), note,
rest, rest,
start_here, start_here,
modifier, modifier,
quick_modifier, quick_modifier,
r#loop(&notes), r#loop,
tuple(&notes), tuple,
slope(&notes), slope,
comment, comment,
)), )),
) )
.parse(i)
} }