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"
derive-new = "0.7.0"
naan = "0.1.32"
lazy_static = "1.5.0"
[features]
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 crate::bng::score::lex::lexer::root;
use crate::bng::score::lex::lexer::{root, set_notes};
use super::{Atom, Atoms};
@ -44,7 +44,8 @@ impl<'de> Deserialize<'de> for Atoms {
if sheet.is_empty() {
Ok(Default::default())
} 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(de::Error::custom)
.map(|(i, r)| r)

View file

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