pretty printing
This commit is contained in:
parent
52a80cfb0e
commit
c867ad379e
30 changed files with 1533 additions and 387 deletions
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "logparse"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
edition = "2024"
|
||||
description = "parse arbitrary messages containing rust-like debug output to syntax highlight them"
|
||||
authors = ["Jana Dönszelmann <cratesio@donsz.nl>"]
|
||||
|
|
@ -12,6 +12,9 @@ readme = "README.md"
|
|||
|
||||
[dependencies]
|
||||
winnow = {version="1", features=["parser"]}
|
||||
logparse-pretty-print = {path = "../pretty-print/projects/pretty-print", version="0.1.0"}
|
||||
|
||||
[dev-dependencies]
|
||||
proptest = "1"
|
||||
proptest-derive = "0.8"
|
||||
insta = "1"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#[cfg(test)]
|
||||
use proptest_derive::Arbitrary;
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
|
@ -11,7 +12,8 @@ pub enum Separator {
|
|||
}
|
||||
|
||||
/// See [`Token::String`].
|
||||
#[derive(Copy, Clone, Debug, Arbitrary, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
#[allow(missing_docs)]
|
||||
pub enum QuoteType {
|
||||
Single,
|
||||
|
|
@ -20,7 +22,8 @@ pub enum QuoteType {
|
|||
}
|
||||
|
||||
/// See [`Token::Delimited`].
|
||||
#[derive(Clone, Debug, Arbitrary, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
#[allow(missing_docs)]
|
||||
pub enum Delimiter {
|
||||
Paren,
|
||||
|
|
@ -50,7 +53,8 @@ pub struct AnyString<'a> {
|
|||
pub struct Space<'a>(pub Cow<'a, str>);
|
||||
|
||||
/// See [`Token::Path`].
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Arbitrary)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
#[allow(missing_docs)]
|
||||
pub enum PathSep {
|
||||
/// Happens at the start of paths, for the no leading / case
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#![deny(missing_docs)]
|
||||
#![deny(warnings)]
|
||||
// #![deny(warnings)]
|
||||
#![doc=include_str!("../README.md")]
|
||||
|
||||
/// The structure of parsed log lines
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ proptest! {
|
|||
#[test]
|
||||
fn proptest_into_spans(original in Segments::arb(Token::arb())) {
|
||||
let stringified = original.to_string();
|
||||
let spans = into_spans(original, Config {collapse_space: false});
|
||||
let spans = into_spans(original, Config {collapse_space: false, ..Default::default()});
|
||||
let spans_concatenated = spans.into_iter().map(|i| i.text).collect::<String>();
|
||||
assert_eq!(stringified, spans_concatenated);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,12 +47,11 @@ pub struct Span<'a> {
|
|||
|
||||
/// Configuration options for [`into_spans`]
|
||||
#[derive(Default)]
|
||||
#[non_exhaustive]
|
||||
pub struct Config {
|
||||
/// Turn sequences of more than 1 space into exactly 1 space.
|
||||
pub collapse_space: bool,
|
||||
/// Pretty print: wrap at braces etc
|
||||
pub pretty_print: bool,
|
||||
/// Pretty print: wrap at braces etc to the given width
|
||||
pub pretty_print: Option<usize>,
|
||||
}
|
||||
|
||||
pub trait IntoSpans<'a>: private::IntoSpansImpl<'a> {}
|
||||
|
|
@ -63,18 +62,27 @@ pub fn into_spans<'a>(ast: impl IntoSpans<'a>, config: Config) -> Vec<Span<'a>>
|
|||
config,
|
||||
res: Vec::new(),
|
||||
depth: 0,
|
||||
ignore_next_space: false,
|
||||
};
|
||||
ast.into_spans(&mut cx);
|
||||
if let Some(width) = cx.config.pretty_print {
|
||||
let res = ast.into_pretty_spans(&mut cx);
|
||||
let _ = res.render_vec(width, &mut cx.res);
|
||||
} else {
|
||||
ast.into_spans(&mut cx)
|
||||
}
|
||||
cx.res
|
||||
}
|
||||
|
||||
mod private {
|
||||
use logparse_pretty_print::{PrettyBuilder, PrettyTree, Text};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub struct Context<'a> {
|
||||
pub config: Config,
|
||||
pub res: Vec<Span<'a>>,
|
||||
pub depth: usize,
|
||||
pub ignore_next_space: bool,
|
||||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
|
|
@ -86,8 +94,22 @@ mod private {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Text<'a> for Span<'a> {
|
||||
fn from_static_str(s: &'static str) -> Self {
|
||||
Span {
|
||||
text: Cow::Borrowed(s),
|
||||
kind: SpanKind::Text,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_str(&self) -> Cow<'_, str> {
|
||||
self.text.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoSpansImpl<'a> {
|
||||
fn into_spans(self, cx: &mut Context<'a>);
|
||||
fn into_pretty_spans(self, cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>>;
|
||||
}
|
||||
|
||||
impl<'a, T> IntoSpans<'a> for T where T: IntoSpansImpl<'a> {}
|
||||
|
|
@ -100,14 +122,48 @@ mod private {
|
|||
Separator::DoubleColon => cx.push("::", SpanKind::Separator),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, _cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
match self {
|
||||
Separator::Eq => PrettyTree::text(Span {
|
||||
text: Cow::Borrowed("="),
|
||||
kind: SpanKind::Separator,
|
||||
}),
|
||||
Separator::Colon => PrettyTree::text(Span {
|
||||
text: Cow::Borrowed(":"),
|
||||
kind: SpanKind::Separator,
|
||||
}),
|
||||
Separator::DoubleColon => PrettyTree::text(Span {
|
||||
text: Cow::Borrowed("::"),
|
||||
kind: SpanKind::Separator,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoSpansImpl<'a> for QuoteType {
|
||||
fn into_spans(self, cx: &mut Context<'a>) {
|
||||
match self {
|
||||
QuoteType::Single => cx.push("'", SpanKind::Separator),
|
||||
QuoteType::Double => cx.push("\"", SpanKind::Separator),
|
||||
QuoteType::Backtick => cx.push("`", SpanKind::Separator),
|
||||
QuoteType::Single => cx.push("'", SpanKind::Surroundings),
|
||||
QuoteType::Double => cx.push("\"", SpanKind::Surroundings),
|
||||
QuoteType::Backtick => cx.push("`", SpanKind::Surroundings),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, _cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
match self {
|
||||
QuoteType::Single => PrettyTree::text(Span {
|
||||
text: Cow::Borrowed("'"),
|
||||
kind: SpanKind::Surroundings,
|
||||
}),
|
||||
QuoteType::Double => PrettyTree::text(Span {
|
||||
text: Cow::Borrowed("\""),
|
||||
kind: SpanKind::Surroundings,
|
||||
}),
|
||||
QuoteType::Backtick => PrettyTree::text(Span {
|
||||
text: Cow::Borrowed("`"),
|
||||
kind: SpanKind::Surroundings,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -135,12 +191,55 @@ mod private {
|
|||
}
|
||||
cx.push(suffix, SpanKind::Surroundings);
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
let Self {
|
||||
prefix,
|
||||
ty,
|
||||
contents,
|
||||
num_hashtags,
|
||||
suffix,
|
||||
} = self;
|
||||
|
||||
let hashtags = "#".repeat(num_hashtags);
|
||||
|
||||
PrettyTree::text(Span {
|
||||
text: prefix,
|
||||
kind: SpanKind::Surroundings,
|
||||
})
|
||||
.append(PrettyTree::text(Span {
|
||||
text: Cow::Owned(hashtags.clone()),
|
||||
kind: SpanKind::Surroundings,
|
||||
}))
|
||||
.group()
|
||||
.append(ty.into_pretty_spans(cx))
|
||||
.group()
|
||||
.append(PrettyTree::text(Span {
|
||||
text: contents,
|
||||
kind: SpanKind::String,
|
||||
}))
|
||||
.group()
|
||||
.append(ty.into_pretty_spans(cx))
|
||||
.group()
|
||||
.append(PrettyTree::text(Span {
|
||||
text: suffix,
|
||||
kind: SpanKind::Surroundings,
|
||||
}))
|
||||
.group()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoSpansImpl<'a> for Path<'a> {
|
||||
fn into_spans(self, cx: &mut Context<'a>) {
|
||||
cx.push(self.to_string(), SpanKind::Path)
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, _cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
PrettyTree::text(Span {
|
||||
text: Cow::Owned(self.to_string()),
|
||||
kind: SpanKind::Path,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoSpansImpl<'a> for Number<'a> {
|
||||
|
|
@ -152,6 +251,29 @@ mod private {
|
|||
cx.push(suffix, SpanKind::Surroundings);
|
||||
}
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, _cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
let main = PrettyTree::text(Span {
|
||||
text: self.number,
|
||||
kind: SpanKind::Number,
|
||||
});
|
||||
|
||||
let suffix = if let Some(suffix) = self.suffix_without_underscore {
|
||||
PrettyTree::text(Span {
|
||||
text: Cow::Borrowed("_"),
|
||||
kind: SpanKind::Surroundings,
|
||||
})
|
||||
.append(PrettyTree::text(Span {
|
||||
text: suffix,
|
||||
kind: SpanKind::Surroundings,
|
||||
}))
|
||||
.group()
|
||||
} else {
|
||||
PrettyTree::Nil
|
||||
};
|
||||
|
||||
main.append(suffix).group()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoSpansImpl<'a> for Atom<'a> {
|
||||
|
|
@ -160,6 +282,15 @@ mod private {
|
|||
Atom::Text(text) => cx.push(text, SpanKind::Text),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, _cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
match self {
|
||||
Atom::Text(text) => PrettyTree::text(Span {
|
||||
text,
|
||||
kind: SpanKind::Text,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoSpansImpl<'a> for Space<'a> {
|
||||
|
|
@ -171,6 +302,23 @@ mod private {
|
|||
n => cx.push(self.0, SpanKind::Space(n)),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
if cx.ignore_next_space {
|
||||
cx.ignore_next_space = false;
|
||||
return PrettyTree::Nil;
|
||||
}
|
||||
|
||||
match self.0.len() {
|
||||
0 => PrettyTree::Nil,
|
||||
1 => PrettyTree::line_or_space(),
|
||||
n if cx.config.collapse_space => PrettyTree::line_or_space(),
|
||||
n => PrettyTree::text(Span {
|
||||
text: self.0,
|
||||
kind: SpanKind::Space(n),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoSpansImpl<'a> for Token<'a> {
|
||||
|
|
@ -205,6 +353,50 @@ mod private {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
match self {
|
||||
Token::True => PrettyTree::text(Span {
|
||||
text: Cow::Borrowed("true"),
|
||||
kind: SpanKind::Literal,
|
||||
}),
|
||||
Token::False => PrettyTree::text(Span {
|
||||
text: Cow::Borrowed("true"),
|
||||
kind: SpanKind::Literal,
|
||||
}),
|
||||
Token::None => PrettyTree::text(Span {
|
||||
text: Cow::Borrowed("None"),
|
||||
kind: SpanKind::Literal,
|
||||
}),
|
||||
Token::Lifetime(lifetime) => PrettyTree::Text(Span {
|
||||
text: Cow::Borrowed("'"),
|
||||
kind: SpanKind::Surroundings,
|
||||
})
|
||||
.append(PrettyTree::text(Span {
|
||||
text: lifetime,
|
||||
kind: SpanKind::Lifetime,
|
||||
}))
|
||||
.group(),
|
||||
Token::Path(path) => path.into_pretty_spans(cx),
|
||||
Token::String(string) => string.into_pretty_spans(cx),
|
||||
Token::Number(number) => number.into_pretty_spans(cx),
|
||||
Token::Separated {
|
||||
before,
|
||||
space_before,
|
||||
separator,
|
||||
after,
|
||||
} => before
|
||||
.into_pretty_spans(cx)
|
||||
.append(space_before.into_pretty_spans(cx))
|
||||
.group()
|
||||
.append(separator.into_pretty_spans(cx))
|
||||
.group()
|
||||
.append(after.into_pretty_spans(cx))
|
||||
.group(),
|
||||
Token::Delimited(delimited) => delimited.into_pretty_spans(cx),
|
||||
Token::Atom(atom) => atom.into_pretty_spans(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoSpansImpl<'a> for Segment<'a> {
|
||||
|
|
@ -216,6 +408,18 @@ mod private {
|
|||
leading_space.into_spans(cx);
|
||||
token.into_spans(cx);
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
let Self {
|
||||
leading_space,
|
||||
token,
|
||||
} = self;
|
||||
|
||||
leading_space
|
||||
.into_pretty_spans(cx)
|
||||
.append(token.into_pretty_spans(cx))
|
||||
.group()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoSpansImpl<'a> for Segments<'a> {
|
||||
|
|
@ -229,6 +433,36 @@ mod private {
|
|||
}
|
||||
trailing_space.into_spans(cx);
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
let ignore_start = cx.ignore_next_space;
|
||||
|
||||
let Self {
|
||||
segments,
|
||||
trailing_space,
|
||||
} = self;
|
||||
let mut res = PrettyTree::Nil;
|
||||
for segment in segments {
|
||||
res = res.append(segment.into_pretty_spans(cx)).group();
|
||||
}
|
||||
|
||||
// if we ignore the first space, also ignore the last one.
|
||||
if ignore_start {
|
||||
cx.ignore_next_space = true;
|
||||
}
|
||||
res.append(trailing_space.into_pretty_spans(cx)).group()
|
||||
}
|
||||
}
|
||||
|
||||
fn prefix_kind(delimiter: Delimiter, space: &Space<'_>) -> SpanKind {
|
||||
match delimiter {
|
||||
Delimiter::Brace => SpanKind::Constructor,
|
||||
Delimiter::Paren if space.0.is_empty() => SpanKind::Constructor,
|
||||
Delimiter::Paren => SpanKind::Text,
|
||||
Delimiter::Bracket => SpanKind::Text,
|
||||
Delimiter::Angle if space.0.is_empty() => SpanKind::Constructor,
|
||||
Delimiter::Angle => SpanKind::Text,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoSpansImpl<'a> for Delimited<'a> {
|
||||
|
|
@ -241,17 +475,7 @@ mod private {
|
|||
|
||||
match prefix {
|
||||
Some((Atom::Text(text), space)) => {
|
||||
cx.push(
|
||||
text,
|
||||
match delimiter {
|
||||
Delimiter::Brace => SpanKind::Constructor,
|
||||
Delimiter::Paren if space.0.is_empty() => SpanKind::Constructor,
|
||||
Delimiter::Paren => SpanKind::Text,
|
||||
Delimiter::Bracket => SpanKind::Text,
|
||||
Delimiter::Angle if space.0.is_empty() => SpanKind::Constructor,
|
||||
Delimiter::Angle => SpanKind::Text,
|
||||
},
|
||||
);
|
||||
cx.push(text, prefix_kind(delimiter, &space));
|
||||
space.into_spans(cx);
|
||||
}
|
||||
None => {}
|
||||
|
|
@ -275,12 +499,105 @@ mod private {
|
|||
Delimiter::Angle => cx.push(">", SpanKind::Delimiter(cx.depth)),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_pretty_spans(self, cx: &mut Context<'a>) -> PrettyTree<'a, Span<'a>> {
|
||||
let Self {
|
||||
prefix,
|
||||
delimiter,
|
||||
contents,
|
||||
} = self;
|
||||
|
||||
let group = contents
|
||||
.segments
|
||||
.iter()
|
||||
.filter(|i| !matches!(i.token, Token::Atom(..)))
|
||||
.count()
|
||||
<= 1;
|
||||
|
||||
let prefix = match prefix {
|
||||
Some((Atom::Text(text), space)) => PrettyTree::text(Span {
|
||||
text,
|
||||
kind: prefix_kind(delimiter, &space),
|
||||
})
|
||||
.append(space.into_pretty_spans(cx))
|
||||
.group(),
|
||||
None => PrettyTree::Nil,
|
||||
};
|
||||
|
||||
let open = match delimiter {
|
||||
Delimiter::Paren => Span {
|
||||
text: Cow::Borrowed("("),
|
||||
kind: SpanKind::Delimiter(cx.depth),
|
||||
},
|
||||
Delimiter::Bracket => Span {
|
||||
text: Cow::Borrowed("["),
|
||||
kind: SpanKind::Delimiter(cx.depth),
|
||||
},
|
||||
Delimiter::Brace => Span {
|
||||
text: Cow::Borrowed("{"),
|
||||
kind: SpanKind::Delimiter(cx.depth),
|
||||
},
|
||||
Delimiter::Angle => Span {
|
||||
text: Cow::Borrowed("<"),
|
||||
kind: SpanKind::Delimiter(cx.depth),
|
||||
},
|
||||
};
|
||||
|
||||
let close = match delimiter {
|
||||
Delimiter::Paren => Span {
|
||||
text: Cow::Borrowed(")"),
|
||||
kind: SpanKind::Delimiter(cx.depth),
|
||||
},
|
||||
Delimiter::Bracket => Span {
|
||||
text: Cow::Borrowed("]"),
|
||||
kind: SpanKind::Delimiter(cx.depth),
|
||||
},
|
||||
Delimiter::Brace => Span {
|
||||
text: Cow::Borrowed("}"),
|
||||
kind: SpanKind::Delimiter(cx.depth),
|
||||
},
|
||||
Delimiter::Angle => Span {
|
||||
text: Cow::Borrowed(">"),
|
||||
kind: SpanKind::Delimiter(cx.depth),
|
||||
},
|
||||
};
|
||||
|
||||
cx.depth += 1;
|
||||
if !group {
|
||||
cx.ignore_next_space = true;
|
||||
}
|
||||
let contents = contents.into_pretty_spans(cx);
|
||||
cx.depth -= 1;
|
||||
|
||||
if group {
|
||||
prefix
|
||||
.append(PrettyTree::text(open))
|
||||
.group()
|
||||
.append(contents)
|
||||
.group()
|
||||
.append(PrettyTree::text(close))
|
||||
} else {
|
||||
prefix
|
||||
.append(PrettyTree::text(open))
|
||||
.group()
|
||||
.append(PrettyTree::Hardline)
|
||||
.group()
|
||||
.append(contents)
|
||||
.group()
|
||||
.nest(4)
|
||||
.group()
|
||||
.append(PrettyTree::Hardline)
|
||||
.group()
|
||||
.append(PrettyTree::text(close))
|
||||
.group()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use insta::assert_debug_snapshot;
|
||||
use insta::{assert_debug_snapshot, assert_snapshot};
|
||||
|
||||
use super::SpanKind;
|
||||
use crate::{Config, into_spans, parse_input};
|
||||
|
|
@ -291,6 +608,7 @@ mod tests {
|
|||
res,
|
||||
Config {
|
||||
collapse_space: true,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.into_iter()
|
||||
|
|
@ -298,6 +616,73 @@ mod tests {
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn pretty_print(input: &str, n: usize) -> String {
|
||||
let res = parse_input(input).unwrap();
|
||||
into_spans(
|
||||
res,
|
||||
Config {
|
||||
pretty_print: Some(n),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.into_iter()
|
||||
.map(|i| i.text.into_owned())
|
||||
.collect::<String>()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pretty_print_ex1() {
|
||||
assert_snapshot!(pretty_print(
|
||||
r#"def_id=DefId(0:3 ~ unsized_coercion[10fa]::Trait)"#, 60
|
||||
), @"
|
||||
def_id=DefId(
|
||||
0:3 ~ unsized_coercion[10fa]::Trait
|
||||
)
|
||||
");
|
||||
assert_snapshot!(pretty_print(
|
||||
r#"def_id=DefId(0:3 ~ unsized_coercion[10fa]::Trait)"#, 30
|
||||
), @"
|
||||
def_id=DefId(
|
||||
0:3 ~
|
||||
unsized_coercion[10fa]::Trait
|
||||
)
|
||||
");
|
||||
assert_snapshot!(pretty_print(
|
||||
r#"def_id=DefId(0:3 ~ unsized_coercion[10fa]::Trait)"#, 10
|
||||
), @"
|
||||
def_id=DefId(
|
||||
0:3 ~
|
||||
unsized_coercion[10fa]::Trait
|
||||
)
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pretty_print_ex2() {
|
||||
assert_snapshot!(pretty_print(
|
||||
r#"stability: inspecting def_id=DefId(3:662 ~ alloc[ef11]::boxed::Box) span=tests/ui/impl-trait/unsized_coercion.rs:16:16: 16:30 (#0) of stability=Some(Stability { level: Stable { since: Version(RustcVersion { major: 1, minor: 0, patch: 0 }), allowed_through_unstable_modules: None }, feature: "rust1" })"#, 60
|
||||
), @r#"
|
||||
stability: inspecting
|
||||
def_id=DefId(
|
||||
3:662 ~ alloc[ef11]::boxed::Box
|
||||
) span=tests/ui/impl-trait/unsized_coercion.rs:16:16: 16:30
|
||||
(#0) of
|
||||
stability=Some(Stability {
|
||||
|
||||
level:
|
||||
Stable {
|
||||
|
||||
since:
|
||||
Version(RustcVersion {
|
||||
major: 1, minor: 0, patch: 0
|
||||
}), allowed_through_unstable_modules: None
|
||||
|
||||
}, feature: "rust1"
|
||||
|
||||
})
|
||||
"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spans_ex1() {
|
||||
assert_debug_snapshot!(spans(
|
||||
|
|
@ -418,7 +803,7 @@ mod tests {
|
|||
),
|
||||
(
|
||||
"\"",
|
||||
Separator,
|
||||
Surroundings,
|
||||
),
|
||||
(
|
||||
"MetaSized",
|
||||
|
|
@ -426,7 +811,7 @@ mod tests {
|
|||
),
|
||||
(
|
||||
"\"",
|
||||
Separator,
|
||||
Surroundings,
|
||||
),
|
||||
(
|
||||
"",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue