debug
This commit is contained in:
parent
9f401bda53
commit
bb8fa818d2
9 changed files with 1322 additions and 78 deletions
36
Cargo.lock
generated
36
Cargo.lock
generated
|
|
@ -248,6 +248,17 @@ dependencies = [
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console"
|
||||||
|
version = "0.16.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87"
|
||||||
|
dependencies = [
|
||||||
|
"encode_unicode",
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
|
|
@ -431,6 +442,12 @@ version = "1.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encode_unicode"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
|
@ -634,6 +651,18 @@ dependencies = [
|
||||||
"rustversion",
|
"rustversion",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "insta"
|
||||||
|
version = "1.47.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b4a6248eb93a4401ed2f37dfe8ea592d3cf05b7cf4f8efa867b6895af7e094e"
|
||||||
|
dependencies = [
|
||||||
|
"console",
|
||||||
|
"once_cell",
|
||||||
|
"similar",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instability"
|
name = "instability"
|
||||||
version = "0.3.11"
|
version = "0.3.11"
|
||||||
|
|
@ -1387,6 +1416,7 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"dumpster",
|
"dumpster",
|
||||||
|
"insta",
|
||||||
"itertools",
|
"itertools",
|
||||||
"jiff",
|
"jiff",
|
||||||
"nix 0.31.1",
|
"nix 0.31.1",
|
||||||
|
|
@ -1566,6 +1596,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "similar"
|
||||||
|
version = "2.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "siphasher"
|
name = "siphasher"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
|
|
||||||
|
|
@ -24,3 +24,4 @@ dumpster = "2.1"
|
||||||
winnow = {version="1", features=["parser"]}
|
winnow = {version="1", features=["parser"]}
|
||||||
proptest = "1"
|
proptest = "1"
|
||||||
proptest-derive = "0.8"
|
proptest-derive = "0.8"
|
||||||
|
insta = "1"
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,5 @@
|
||||||
# It is recommended to check this file in to source control so that
|
# It is recommended to check this file in to source control so that
|
||||||
# everyone who runs the test benefits from these saved cases.
|
# everyone who runs the test benefits from these saved cases.
|
||||||
cc 1dac24f74cdeb63f61d662876f276058bc71481f1df552aeea1293e22b682d59 # shrinks to original = "¡{}"
|
cc 1dac24f74cdeb63f61d662876f276058bc71481f1df552aeea1293e22b682d59 # shrinks to original = "¡{}"
|
||||||
|
cc f7a17a233c11246ea8182505c41e30dc2a2f1c9020d5108f95403eb2de179fac # shrinks to original = ")"
|
||||||
|
cc 7bfbe4d3505dc0e94e5b87ae86e4b4554d9af477f4d0770161c2403ce39627f3 # shrinks to original = "!/\t"
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use std::borrow::Cow;
|
||||||
pub enum Separator {
|
pub enum Separator {
|
||||||
Eq,
|
Eq,
|
||||||
Colon,
|
Colon,
|
||||||
|
DoubleColon,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Arbitrary, PartialEq)]
|
#[derive(Copy, Clone, Debug, Arbitrary, PartialEq)]
|
||||||
|
|
@ -36,6 +37,8 @@ pub struct Space<'a>(pub Cow<'a, str>);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Arbitrary)]
|
#[derive(Copy, Clone, Debug, PartialEq, Arbitrary)]
|
||||||
pub enum PathSep {
|
pub enum PathSep {
|
||||||
|
/// Happens at the start of paths, for the no leading / case
|
||||||
|
None,
|
||||||
Slash,
|
Slash,
|
||||||
Backslash,
|
Backslash,
|
||||||
}
|
}
|
||||||
|
|
@ -63,6 +66,7 @@ pub struct FileName<'a> {
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Path<'a> {
|
pub struct Path<'a> {
|
||||||
pub drive_excluding_colon: Option<char>,
|
pub drive_excluding_colon: Option<char>,
|
||||||
|
|
||||||
pub segments: Vec<PathSegment<'a>>,
|
pub segments: Vec<PathSegment<'a>>,
|
||||||
pub filename: FileName<'a>,
|
pub filename: FileName<'a>,
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +105,7 @@ pub enum Token<'a> {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Delimited<'a> {
|
pub struct Delimited<'a> {
|
||||||
pub prefix: Atom<'a>,
|
pub prefix: Option<Atom<'a>>,
|
||||||
pub delimiter: Delimiter,
|
pub delimiter: Delimiter,
|
||||||
pub contents: Segments<'a>,
|
pub contents: Segments<'a>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ impl Display for Separator {
|
||||||
match self {
|
match self {
|
||||||
Separator::Eq => write!(f, "="),
|
Separator::Eq => write!(f, "="),
|
||||||
Separator::Colon => write!(f, ":"),
|
Separator::Colon => write!(f, ":"),
|
||||||
|
Separator::DoubleColon => write!(f, "::"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +69,7 @@ impl Display for PathSep {
|
||||||
match self {
|
match self {
|
||||||
PathSep::Slash => write!(f, "/"),
|
PathSep::Slash => write!(f, "/"),
|
||||||
PathSep::Backslash => write!(f, "\\"),
|
PathSep::Backslash => write!(f, "\\"),
|
||||||
|
PathSep::None => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -105,13 +107,20 @@ impl<'a> Display for FileName<'a> {
|
||||||
|
|
||||||
impl<'a> Display for Path<'a> {
|
impl<'a> Display for Path<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
if let Some(drive) = &self.drive_excluding_colon {
|
let Self {
|
||||||
|
drive_excluding_colon,
|
||||||
|
segments,
|
||||||
|
filename,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
if let Some(drive) = &drive_excluding_colon {
|
||||||
write!(f, "{drive}:")?;
|
write!(f, "{drive}:")?;
|
||||||
}
|
}
|
||||||
for segment in &self.segments {
|
|
||||||
|
for segment in segments {
|
||||||
write!(f, "{segment}")?;
|
write!(f, "{segment}")?;
|
||||||
}
|
}
|
||||||
write!(f, "{}", self.filename)
|
write!(f, "{filename}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,7 +161,9 @@ impl<'a> Display for Token<'a> {
|
||||||
|
|
||||||
impl<'a> Display for Delimited<'a> {
|
impl<'a> Display for Delimited<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{}", self.prefix)?;
|
if let Some(prefix) = &self.prefix {
|
||||||
|
write!(f, "{prefix}")?;
|
||||||
|
}
|
||||||
self.delimiter.fmt_start(f)?;
|
self.delimiter.fmt_start(f)?;
|
||||||
write!(f, "{}", self.contents)?;
|
write!(f, "{}", self.contents)?;
|
||||||
self.delimiter.fmt_end(f)
|
self.delimiter.fmt_end(f)
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,24 @@ impl<'a> AnyString<'a> {
|
||||||
fn parse<E: ParserError<&'a str>>() -> impl Parser<&'a str, Self, E> {
|
fn parse<E: ParserError<&'a str>>() -> impl Parser<&'a str, Self, E> {
|
||||||
use winnow::{combinator::*, prelude::*, token::*};
|
use winnow::{combinator::*, prelude::*, token::*};
|
||||||
|
|
||||||
// let (prefix, num_hashtags, quote) =
|
let quote = alt((
|
||||||
let preamble = (
|
|
||||||
take_while(0.., |b: char| !b.is_whitespace()),
|
|
||||||
take_while(0.., |c| c == '#').map(|i: &'a str| i.len()),
|
|
||||||
alt((
|
|
||||||
'`'.value(QuoteType::Backtick),
|
'`'.value(QuoteType::Backtick),
|
||||||
'\''.value(QuoteType::Single),
|
'\''.value(QuoteType::Single),
|
||||||
'\"'.value(QuoteType::Double),
|
'\"'.value(QuoteType::Double),
|
||||||
)),
|
));
|
||||||
|
|
||||||
|
macro_rules! surrounding {
|
||||||
|
() => {
|
||||||
|
take_while(0.., |b: char| {
|
||||||
|
!b.is_whitespace() && b.is_alphabetic() && !['\'', '"', '`', '#'].contains(&b)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let preamble = (
|
||||||
|
surrounding!(),
|
||||||
|
take_while(0.., |c| c == '#').map(|i: &'a str| i.len()),
|
||||||
|
quote,
|
||||||
);
|
);
|
||||||
|
|
||||||
trace(
|
trace(
|
||||||
|
|
@ -35,17 +44,16 @@ impl<'a> AnyString<'a> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = repeat_till(0.., any, end).map(|(contents, _)| contents);
|
let contents = repeat_till(0.., any, end).map(|(contents, _)| contents);
|
||||||
let suffix = take_while(0.., |b: char| !b.is_whitespace());
|
|
||||||
|
|
||||||
(contents, suffix).map(move |(contents, suffix): (Cow<'a, str>, &'a str)| {
|
(contents, surrounding!()).map(
|
||||||
Self {
|
move |(contents, suffix): (Cow<'a, str>, &'a str)| Self {
|
||||||
prefix: prefix.into(),
|
prefix: prefix.into(),
|
||||||
ty: quote,
|
ty: quote,
|
||||||
contents,
|
contents,
|
||||||
num_hashtags,
|
num_hashtags,
|
||||||
suffix: suffix.into(),
|
suffix: suffix.into(),
|
||||||
}
|
},
|
||||||
})
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -75,14 +83,15 @@ impl PathSep {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Separator {
|
impl Separator {
|
||||||
fn parser<'a, E: ParserError<&'a str>>() -> impl Parser<&'a str, Self, E> {
|
fn parse<'a, E: ParserError<&'a str>>() -> impl Parser<&'a str, Self, E> {
|
||||||
use winnow::{combinator::*, prelude::*, token::*};
|
use winnow::{combinator::*, prelude::*, token::*};
|
||||||
|
|
||||||
trace(
|
trace(
|
||||||
"separator",
|
"separator",
|
||||||
alt((
|
alt((
|
||||||
literal('=').value(Self::Eq),
|
"::".value(Self::DoubleColon),
|
||||||
literal(':').value(Self::Colon),
|
(literal('=')).value(Self::Eq),
|
||||||
|
(literal(':')).value(Self::Colon),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -147,95 +156,159 @@ impl<'a> Path<'a> {
|
||||||
fn parse<E: ParserError<&'a str>>() -> impl Parser<&'a str, Self, E> {
|
fn parse<E: ParserError<&'a str>>() -> impl Parser<&'a str, Self, E> {
|
||||||
use winnow::{combinator::*, prelude::*, token::*};
|
use winnow::{combinator::*, prelude::*, token::*};
|
||||||
|
|
||||||
let till_next_sep = repeat_till(
|
let terminator = || {
|
||||||
0..,
|
alt((
|
||||||
any::<&'a str, E>.verify(|i: &char| !(*i).is_whitespace()),
|
eof.value(()),
|
||||||
peek(alt((
|
|
||||||
PathSep::parse().value(()),
|
|
||||||
any::<&'a str, E>
|
any::<&'a str, E>
|
||||||
.verify(|i: &char| (*i).is_whitespace())
|
.verify(|i: &char| {
|
||||||
|
(*i).is_whitespace()
|
||||||
|
|| !(i.is_alphanumeric()
|
||||||
|
|| ['_', '-', '\"', '\'', '.', '/', '\\'].contains(i))
|
||||||
|
})
|
||||||
.value(()),
|
.value(()),
|
||||||
))),
|
))
|
||||||
|
};
|
||||||
|
|
||||||
|
let terminator_or_sep = || alt((PathSep::parse().value(()), terminator()));
|
||||||
|
|
||||||
|
let till_next_sep = || {
|
||||||
|
trace(
|
||||||
|
"till next sep",
|
||||||
|
repeat_till(0.., any::<&'a str, E>, peek(terminator_or_sep()))
|
||||||
|
.map(|(segment, _)| segment),
|
||||||
)
|
)
|
||||||
.map(|(segment, _)| segment);
|
};
|
||||||
|
|
||||||
let sep_and_next =
|
let sep_and_next =
|
||||||
(PathSep::parse(), till_next_sep).map(|(leading_separator, segment)| PathSegment {
|
(PathSep::parse(), till_next_sep()).map(|(leading_separator, segment)| PathSegment {
|
||||||
leading_separator,
|
leading_separator,
|
||||||
segment,
|
segment,
|
||||||
});
|
});
|
||||||
|
let opt_sep_and_next =
|
||||||
|
(opt(PathSep::parse()), till_next_sep()).map(|(leading_separator, segment)| {
|
||||||
|
PathSegment {
|
||||||
|
leading_separator: leading_separator.unwrap_or(PathSep::None),
|
||||||
|
segment,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let drive = opt((
|
let drive = opt((
|
||||||
any::<&'a str, E>.verify(|x: &char| matches!(*x, 'A'..='Z')),
|
any::<&'a str, E>.verify(|x: &char| matches!(*x, 'A'..='Z' | 'a' ..= 'z')),
|
||||||
':',
|
':',
|
||||||
))
|
))
|
||||||
.map(|i| i.map(|(letter, _): (char, char)| letter));
|
.map(|i| i.map(|(letter, _): (char, char)| letter));
|
||||||
let drive_and_segments = (
|
let drive_and_segments = (
|
||||||
drive,
|
drive,
|
||||||
repeat_till(
|
opt_sep_and_next,
|
||||||
1..,
|
repeat_till(0.., sep_and_next, peek(terminator()))
|
||||||
sep_and_next,
|
.map(|(segments, _): (Vec<PathSegment>, _)| segments),
|
||||||
peek(any.verify(|i: &char| (*i).is_whitespace())),
|
|
||||||
)
|
|
||||||
.map(|(segments, _): (Vec<PathSegment>, _)| {
|
|
||||||
let (rest, last) = {
|
|
||||||
let mut segments = segments;
|
|
||||||
let last = segments.pop().unwrap();
|
|
||||||
(segments, last)
|
|
||||||
};
|
|
||||||
|
|
||||||
(rest, FileName::parse(last))
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
trace(
|
trace(
|
||||||
"path",
|
"path",
|
||||||
drive_and_segments.map(|(drive, (segments, filename))| Self {
|
drive_and_segments
|
||||||
|
.map(|(drive, segment, segments)| {
|
||||||
|
let (segments, last) = {
|
||||||
|
let mut segments = segments;
|
||||||
|
segments.insert(0, segment);
|
||||||
|
let last = segments.pop().unwrap();
|
||||||
|
(segments, last)
|
||||||
|
};
|
||||||
|
|
||||||
|
let filename = FileName::parse(last);
|
||||||
|
|
||||||
|
Self {
|
||||||
drive_excluding_colon: drive,
|
drive_excluding_colon: drive,
|
||||||
segments,
|
segments,
|
||||||
filename,
|
filename,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.verify(|i| {
|
||||||
|
!i.segments.is_empty()
|
||||||
|
|| i.drive_excluding_colon.is_some()
|
||||||
|
|| i.filename.ext_excluding_dot.is_some()
|
||||||
|
|| !matches!(i.filename.leading_separator, PathSep::None)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Atom<'a> {
|
impl<'a> Atom<'a> {
|
||||||
fn parse<E: ParserError<&'a str>>(
|
fn parse<E: ParserError<&'a str>, T: 'a>(
|
||||||
except_chars: &'static [char],
|
terminated_by: impl Parser<&'a str, T, E>,
|
||||||
) -> impl Parser<&'a str, Self, E> {
|
) -> impl Parser<&'a str, Self, E> {
|
||||||
use winnow::{combinator::*, prelude::*, token::*};
|
use winnow::{combinator::*, prelude::*, token::*};
|
||||||
|
|
||||||
trace(
|
let text = repeat::<_, _, Cow<'a, str>, _, _>(
|
||||||
"atom",
|
|
||||||
alt((repeat(
|
|
||||||
1..,
|
1..,
|
||||||
any.verify(move |i: &char| !(*i).is_whitespace() && !except_chars.contains(i)),
|
(
|
||||||
|
peek(not(terminated_by)),
|
||||||
|
any::<&str, _>.verify(move |i: &char| !(*i).is_whitespace()),
|
||||||
)
|
)
|
||||||
.map(Self::Text),)),
|
.map(|(_, i)| i),
|
||||||
)
|
)
|
||||||
|
.map(Self::Text);
|
||||||
|
|
||||||
|
trace("atom", alt((text,)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Token<'a> {
|
impl<'a> Token<'a> {
|
||||||
fn parse<E: ParserError<&'a str> + 'a>() -> impl Parser<&'a str, Self, E> {
|
fn parse_without_separator<E: ParserError<&'a str> + 'a>() -> impl Parser<&'a str, Self, E> {
|
||||||
use winnow::{combinator::*, prelude::*};
|
use winnow::{combinator::*, prelude::*};
|
||||||
|
|
||||||
let delimited: Box<dyn Parser<&'a str, Self, E>> =
|
let delimited: Box<dyn Parser<&'a str, Self, E>> =
|
||||||
Box::new(Delimited::parse().map(Self::Delimited));
|
Box::new(Delimited::parse().map(Self::Delimited));
|
||||||
|
|
||||||
trace(
|
trace(
|
||||||
"token",
|
"token-without-sep",
|
||||||
alt((
|
alt((
|
||||||
"true".value(Self::True),
|
"true".value(Self::True),
|
||||||
"false".value(Self::False),
|
"false".value(Self::False),
|
||||||
"None".value(Self::None),
|
"None".value(Self::None),
|
||||||
Path::parse().map(Self::Path),
|
Path::parse().map(Self::Path),
|
||||||
AnyString::parse().map(Self::String),
|
|
||||||
Number::parse().map(Self::Number),
|
Number::parse().map(Self::Number),
|
||||||
|
AnyString::parse().map(Self::String),
|
||||||
delimited,
|
delimited,
|
||||||
Atom::parse(&[]).map(Self::Atom),
|
Atom::parse(alt((Separator::parse().value(""), ")", "]", "}"))).map(Self::Atom),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse<E: ParserError<&'a str> + 'a>() -> Box<dyn Parser<&'a str, Self, E> + 'a> {
|
||||||
|
use winnow::{combinator::*, prelude::*};
|
||||||
|
|
||||||
|
let before = Self::parse_without_separator();
|
||||||
|
|
||||||
|
Box::new(trace(
|
||||||
|
"token",
|
||||||
|
alt((
|
||||||
|
(
|
||||||
|
before,
|
||||||
|
opt(
|
||||||
|
(Space::parse(), Separator::parse()).flat_map(|(space, sep)| {
|
||||||
|
let box_dyn_segment: Box<dyn Parser<_, _, _>> =
|
||||||
|
Box::new(Segment::parse());
|
||||||
|
box_dyn_segment.map(move |segment| (space.clone(), sep, segment))
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map(|(before, trailer)| {
|
||||||
|
if let Some((space_before, separator, after)) = trailer {
|
||||||
|
Token::Separated {
|
||||||
|
before: Box::new(before),
|
||||||
|
space_before,
|
||||||
|
separator,
|
||||||
|
after: Box::new(after),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
before
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Atom::parse(fail::<_, (), _>).map(Self::Atom),
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Delimited<'a> {
|
impl<'a> Delimited<'a> {
|
||||||
|
|
@ -245,7 +318,12 @@ impl<'a> Delimited<'a> {
|
||||||
trace(
|
trace(
|
||||||
"delimited",
|
"delimited",
|
||||||
(
|
(
|
||||||
Atom::parse(&['(', '[', '{']),
|
opt(Atom::parse(alt((
|
||||||
|
"(",
|
||||||
|
"[",
|
||||||
|
"{",
|
||||||
|
Separator::parse().value(""),
|
||||||
|
)))),
|
||||||
alt((
|
alt((
|
||||||
literal('(').map(|_| literal(')').value(Delimiter::Paren)),
|
literal('(').map(|_| literal(')').value(Delimiter::Paren)),
|
||||||
literal('[').map(|_| literal(']').value(Delimiter::Bracket)),
|
literal('[').map(|_| literal(']').value(Delimiter::Bracket)),
|
||||||
|
|
@ -264,11 +342,11 @@ impl<'a> Delimited<'a> {
|
||||||
|
|
||||||
impl<'a> Segments<'a> {
|
impl<'a> Segments<'a> {
|
||||||
fn parse<E: ParserError<&'a str> + 'a, End: 'a>(
|
fn parse<E: ParserError<&'a str> + 'a, End: 'a>(
|
||||||
end: impl Parser<&'a str, End, E>,
|
end: impl Parser<&'a str, End, E> + 'a,
|
||||||
) -> impl Parser<&'a str, (Self, End), E> {
|
) -> Box<dyn Parser<&'a str, (Self, End), E> + 'a> {
|
||||||
use winnow::{combinator::*, prelude::*};
|
use winnow::{combinator::*, prelude::*};
|
||||||
|
|
||||||
trace(
|
Box::new(trace(
|
||||||
"segments",
|
"segments",
|
||||||
repeat_till(0.., Segment::parse(), (Space::parse(), end)).map(
|
repeat_till(0.., Segment::parse(), (Space::parse(), end)).map(
|
||||||
|(segments, (trailing_space, end)): (Vec<_>, _)| {
|
|(segments, (trailing_space, end)): (Vec<_>, _)| {
|
||||||
|
|
@ -281,18 +359,21 @@ impl<'a> Segments<'a> {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Number<'a> {
|
impl<'a> Number<'a> {
|
||||||
fn parse<E: ParserError<&'a str>>() -> impl Parser<&'a str, Self, E> {
|
fn parse<E: ParserError<&'a str>>() -> impl Parser<&'a str, Self, E> {
|
||||||
use winnow::{ascii::*, combinator::*, prelude::*};
|
use winnow::{ascii::*, combinator::*, prelude::*, token::*};
|
||||||
|
|
||||||
trace(
|
trace(
|
||||||
"number",
|
"number",
|
||||||
alt((float::<_, f64, _>.take(), dec_int::<_, i64, _>.take()))
|
(
|
||||||
.map(|i: &str| Self(i.into())),
|
alt((float::<_, f64, _>.take(), dec_int::<_, i64, _>.take())),
|
||||||
|
peek(not(any::<&'a str, E>.verify(|x: &char| x.is_alphabetic()))),
|
||||||
|
)
|
||||||
|
.map(|(i, _): (&str, _)| Self(i.into())),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -318,3 +399,371 @@ pub fn parse_input<'a>(i: &'a str) -> Result<Segments<'a>, String> {
|
||||||
.parse(i)
|
.parse(i)
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use insta::assert_debug_snapshot;
|
||||||
|
use winnow::Parser;
|
||||||
|
|
||||||
|
use crate::format_debug_output::{
|
||||||
|
ast::{Path, Segments},
|
||||||
|
parse_input,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn parse_path_only<'a>(i: &'a str) -> Path<'a> {
|
||||||
|
Path::parse::<winnow::error::EmptyError>().parse(i).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse<'a>(input: &'a str) -> Segments<'a> {
|
||||||
|
parse_input(input).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_path() {
|
||||||
|
assert_debug_snapshot!(parse_path_only(r#"tests/ui/impl-trait/unsized_coercion.rs"#), @r#"
|
||||||
|
Path {
|
||||||
|
drive_excluding_colon: None,
|
||||||
|
segments: [
|
||||||
|
PathSegment {
|
||||||
|
leading_separator: None,
|
||||||
|
segment: "tests",
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
leading_separator: Slash,
|
||||||
|
segment: "ui",
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
leading_separator: Slash,
|
||||||
|
segment: "impl-trait",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
filename: FileName {
|
||||||
|
leading_separator: Slash,
|
||||||
|
segment: "unsized_coercion",
|
||||||
|
ext_excluding_dot: Some(
|
||||||
|
"rs",
|
||||||
|
),
|
||||||
|
location: None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_path_with_file_line() {
|
||||||
|
assert_debug_snapshot!(parse_path_only(r#"tests/ui/impl-trait/unsized_coercion.rs:3:4"#), @r#"
|
||||||
|
Path {
|
||||||
|
drive_excluding_colon: None,
|
||||||
|
segments: [
|
||||||
|
PathSegment {
|
||||||
|
leading_separator: None,
|
||||||
|
segment: "tests",
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
leading_separator: Slash,
|
||||||
|
segment: "ui",
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
leading_separator: Slash,
|
||||||
|
segment: "impl-trait",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
filename: FileName {
|
||||||
|
leading_separator: Slash,
|
||||||
|
segment: "unsized_coercion",
|
||||||
|
ext_excluding_dot: Some(
|
||||||
|
"rs",
|
||||||
|
),
|
||||||
|
location: Some(
|
||||||
|
FileLocation {
|
||||||
|
line: "3",
|
||||||
|
offset: Some(
|
||||||
|
"4",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_empty() {
|
||||||
|
assert_debug_snapshot!(parse(r#""#), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_text() {
|
||||||
|
assert_debug_snapshot!(parse(r#"abc"#), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: Atom(
|
||||||
|
Text(
|
||||||
|
"abc",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_boolean() {
|
||||||
|
assert_debug_snapshot!(parse(r#"true"#), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: True,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
assert_debug_snapshot!(parse(r#"false"#), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: False,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_string() {
|
||||||
|
assert_debug_snapshot!(parse(r##""foo""##), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: String(
|
||||||
|
AnyString {
|
||||||
|
prefix: "",
|
||||||
|
ty: Double,
|
||||||
|
contents: "foo",
|
||||||
|
num_hashtags: 0,
|
||||||
|
suffix: "",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
assert_debug_snapshot!(parse(r##"#"foo"#"##), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: String(
|
||||||
|
AnyString {
|
||||||
|
prefix: "",
|
||||||
|
ty: Double,
|
||||||
|
contents: "foo",
|
||||||
|
num_hashtags: 1,
|
||||||
|
suffix: "",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
assert_debug_snapshot!(parse(r##"r#"foo"#"##), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: String(
|
||||||
|
AnyString {
|
||||||
|
prefix: "r",
|
||||||
|
ty: Double,
|
||||||
|
contents: "foo",
|
||||||
|
num_hashtags: 1,
|
||||||
|
suffix: "",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
assert_debug_snapshot!(parse(r##"c"foo""##), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: String(
|
||||||
|
AnyString {
|
||||||
|
prefix: "c",
|
||||||
|
ty: Double,
|
||||||
|
contents: "foo",
|
||||||
|
num_hashtags: 0,
|
||||||
|
suffix: "",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
assert_debug_snapshot!(parse(r##"b"foo""##), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: String(
|
||||||
|
AnyString {
|
||||||
|
prefix: "b",
|
||||||
|
ty: Double,
|
||||||
|
contents: "foo",
|
||||||
|
num_hashtags: 0,
|
||||||
|
suffix: "",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
assert_debug_snapshot!(parse(r##"'a'"##), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: String(
|
||||||
|
AnyString {
|
||||||
|
prefix: "",
|
||||||
|
ty: Single,
|
||||||
|
contents: "a",
|
||||||
|
num_hashtags: 0,
|
||||||
|
suffix: "",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
assert_debug_snapshot!(parse(r##"`b`"##), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: String(
|
||||||
|
AnyString {
|
||||||
|
prefix: "",
|
||||||
|
ty: Backtick,
|
||||||
|
contents: "b",
|
||||||
|
num_hashtags: 0,
|
||||||
|
suffix: "",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
assert_debug_snapshot!(parse(r##"b'foo'"##), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: String(
|
||||||
|
AnyString {
|
||||||
|
prefix: "b",
|
||||||
|
ty: Single,
|
||||||
|
contents: "foo",
|
||||||
|
num_hashtags: 0,
|
||||||
|
suffix: "",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
assert_debug_snapshot!(parse(r##"b`foo`"##), @r#"
|
||||||
|
Segments {
|
||||||
|
segments: [
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
token: String(
|
||||||
|
AnyString {
|
||||||
|
prefix: "b",
|
||||||
|
ty: Backtick,
|
||||||
|
contents: "foo",
|
||||||
|
num_hashtags: 0,
|
||||||
|
suffix: "",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trailing_space: Space(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use super::ast::*;
|
use super::ast::*;
|
||||||
|
use crate::format_debug_output::parse_input;
|
||||||
use crate::format_debug_output::{Config, into_spans};
|
use crate::format_debug_output::{Config, into_spans};
|
||||||
use crate::format_debug_output::{ast::*, parse_input};
|
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
use proptest::proptest;
|
use proptest::proptest;
|
||||||
|
|
||||||
|
|
@ -155,7 +155,8 @@ impl Token<'static> {
|
||||||
impl Delimited<'static> {
|
impl Delimited<'static> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn arb(token: impl Strategy<Value = Token<'static>>) -> impl Strategy<Value = Self> {
|
fn arb(token: impl Strategy<Value = Token<'static>>) -> impl Strategy<Value = Self> {
|
||||||
(Atom::arb(), any::<Delimiter>(), Segments::arb(token)).prop_map(
|
use proptest::option::*;
|
||||||
|
(of(Atom::arb()), any::<Delimiter>(), Segments::arb(token)).prop_map(
|
||||||
|(prefix, delimiter, contents)| Self {
|
|(prefix, delimiter, contents)| Self {
|
||||||
prefix,
|
prefix,
|
||||||
delimiter,
|
delimiter,
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ mod private {
|
||||||
match self {
|
match self {
|
||||||
Separator::Eq => cx.push("=", Kind::Separator),
|
Separator::Eq => cx.push("=", Kind::Separator),
|
||||||
Separator::Colon => cx.push(":", Kind::Separator),
|
Separator::Colon => cx.push(":", Kind::Separator),
|
||||||
|
Separator::DoubleColon => cx.push("::", Kind::Separator),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +167,12 @@ mod private {
|
||||||
space_before,
|
space_before,
|
||||||
separator,
|
separator,
|
||||||
after,
|
after,
|
||||||
} => todo!(),
|
} => {
|
||||||
|
before.into_spans(cx);
|
||||||
|
space_before.into_spans(cx);
|
||||||
|
separator.into_spans(cx);
|
||||||
|
after.into_spans(cx);
|
||||||
|
}
|
||||||
Token::Delimited(delimited) => {
|
Token::Delimited(delimited) => {
|
||||||
delimited.into_spans(cx);
|
delimited.into_spans(cx);
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +216,8 @@ mod private {
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
match prefix {
|
match prefix {
|
||||||
Atom::Text(text) => cx.push(text, Kind::Constructor),
|
Some(Atom::Text(text)) => cx.push(text, Kind::Constructor),
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
match delimiter {
|
match delimiter {
|
||||||
|
|
@ -233,3 +240,736 @@ mod private {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use insta::assert_debug_snapshot;
|
||||||
|
|
||||||
|
use super::Kind;
|
||||||
|
use crate::format_debug_output::{Config, into_spans, parse_input};
|
||||||
|
|
||||||
|
fn spans(input: &str) -> Vec<(String, Kind)> {
|
||||||
|
let res = parse_input(input).unwrap();
|
||||||
|
into_spans(
|
||||||
|
res,
|
||||||
|
Config {
|
||||||
|
collapse_space: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| (i.text.into_owned(), i.kind))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spans_ex1() {
|
||||||
|
assert_debug_snapshot!(spans(
|
||||||
|
r#"def_id=DefId(0:3 ~ unsized_coercion[10fa]::Trait)"#
|
||||||
|
), @r#"
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"def_id",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"=",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"DefId",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"0",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"3",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"~",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unsized_coercion",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"[",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"10fa",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"]",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"::",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Trait",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
")",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
"#)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spans_ex2() {
|
||||||
|
assert_debug_snapshot!(spans(
|
||||||
|
r#"data=TypeNs("MetaSized") visible_parent=DefId(2:3984 ~ core[bcc4]::marker) actual_parent=Some(DefId(2:3984 ~ core[bcc4]::marker))"#
|
||||||
|
), @r#"
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"data",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"=",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"TypeNs",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"",
|
||||||
|
StringSurroundings,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"\"",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"MetaSized",
|
||||||
|
String,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"\"",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"",
|
||||||
|
StringSurroundings,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
")",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"visible_parent",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"=",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"DefId",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"2",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"3984",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"~",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"core",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"[",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"bcc4",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"]",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"::",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"marker",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
")",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"actual_parent",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"=",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Some",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"DefId",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"2",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"3984",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"~",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"core",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"[",
|
||||||
|
Delimiter(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"bcc4",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"]",
|
||||||
|
Delimiter(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"::",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"marker",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
")",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
")",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
"#)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spans_ex3() {
|
||||||
|
assert_debug_snapshot!(spans(
|
||||||
|
r#"insert(DefId(0:4 ~ unsized_coercion[10fa]::{impl#0})): inserting TraitRef <u32 as Trait> into specialization graph"#
|
||||||
|
), @r#"
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"insert",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"DefId",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"0",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"4",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"~",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unsized_coercion",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"[",
|
||||||
|
Delimiter(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"10fa",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"]",
|
||||||
|
Delimiter(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"::",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"{",
|
||||||
|
Delimiter(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"impl#0",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"}",
|
||||||
|
Delimiter(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
")",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
")",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"inserting",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"TraitRef",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"<u32",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"as",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Trait>",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"into",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"specialization",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"graph",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
"#)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spans_ex4() {
|
||||||
|
assert_debug_snapshot!(spans(
|
||||||
|
r#"inspecting def_id=DefId(3:662 ~ alloc[ef11]::boxed::Box) span=tests/ui/impl-trait/unsized_coercion.rs:12:15: 12:30 (#0)"#
|
||||||
|
), @r##"
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"inspecting",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"def_id",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"=",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"DefId",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"3",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"662",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"~",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"alloc",
|
||||||
|
Constructor,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"[",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ef11",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"]",
|
||||||
|
Delimiter(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"::",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"boxed",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"::",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Box",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
")",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"span",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"=",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tests/ui/impl-trait/unsized_coercion.rs",
|
||||||
|
Path,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"12",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"15",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"12",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
":",
|
||||||
|
Separator,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"30",
|
||||||
|
Number,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
" ",
|
||||||
|
Space(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"#0",
|
||||||
|
Text,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
")",
|
||||||
|
Delimiter(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
"##)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -215,10 +215,10 @@ impl Into<Line<'static>> for Styled<'_, LineText> {
|
||||||
let style = match kind {
|
let style = match kind {
|
||||||
SpanKind::Delimiter(_) => style.fg(self.styles.delimiter).bold(),
|
SpanKind::Delimiter(_) => style.fg(self.styles.delimiter).bold(),
|
||||||
SpanKind::Separator => style.fg(self.styles.faded),
|
SpanKind::Separator => style.fg(self.styles.faded),
|
||||||
SpanKind::Number => style.fg(self.styles.literal).underlined(),
|
SpanKind::Number => style.fg(self.styles.literal),
|
||||||
SpanKind::Literal => style.fg(self.styles.literal).underlined(),
|
SpanKind::Literal => style.fg(self.styles.literal).dim(),
|
||||||
SpanKind::String => style.fg(self.styles.literal).italic(),
|
SpanKind::String => style.fg(self.styles.literal),
|
||||||
SpanKind::Path => style.fg(self.styles.literal).italic(),
|
SpanKind::Path => style.fg(self.styles.literal).underlined(),
|
||||||
SpanKind::Space(_) => style,
|
SpanKind::Space(_) => style,
|
||||||
SpanKind::Constructor => style.fg(self.styles.literal),
|
SpanKind::Constructor => style.fg(self.styles.literal),
|
||||||
SpanKind::StringSurroundings => style.fg(self.styles.faded),
|
SpanKind::StringSurroundings => style.fg(self.styles.faded),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue