Auto merge of #92352 - matthiaskrgr:rollup-19fbq7u, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #92076 (Ignore other `PredicateKind`s in rustdoc auto trait finder)
 - #92219 (Remove VCVARS_BAT)
 - #92238 (Add a test suite for stringify macro)
 - #92330 (Add myself to .mailmap)
 - #92333 (Tighten span when suggesting lifetime on path)
 - #92335 (Document units for `std::column`)
 - #92344 (⬆️ rust-analyzer)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-12-28 16:59:56 +00:00
commit 83b15bfe1c
12 changed files with 993 additions and 11 deletions

View File

@ -355,7 +355,6 @@ jobs:
env: env:
SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-lld" RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-lld"
VCVARS_BAT: vcvars64.bat
os: windows-latest-xl os: windows-latest-xl
- name: x86_64-msvc-tools - name: x86_64-msvc-tools
env: env:

View File

@ -296,6 +296,7 @@ Ulrik Sverdrup <bluss@users.noreply.github.com> Ulrik Sverdrup <root@localhost>
Vadim Petrochenkov <vadim.petrochenkov@gmail.com> Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Vadim Petrochenkov <vadim.petrochenkov@gmail.com> petrochenkov <vadim.petrochenkov@gmail.com> Vadim Petrochenkov <vadim.petrochenkov@gmail.com> petrochenkov <vadim.petrochenkov@gmail.com>
Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com> Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com>
Wesley Wiser <wwiser@gmail.com> <wesleywiser@microsoft.com>
whitequark <whitequark@whitequark.org> whitequark <whitequark@whitequark.org>
William Ting <io@williamting.com> <william.h.ting@gmail.com> William Ting <io@williamting.com> <william.h.ting@gmail.com>
Xuefeng Wu <benewu@gmail.com> Xuefeng Wu <xfwu@thoughtworks.com> Xuefeng Wu <benewu@gmail.com> Xuefeng Wu <xfwu@thoughtworks.com>

View File

@ -277,7 +277,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label // See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
let elided_lifetime_span = if generic_args.span.is_empty() { let elided_lifetime_span = if generic_args.span.is_empty() {
// If there are no brackets, use the identifier span. // If there are no brackets, use the identifier span.
path_span // HACK: we use find_ancestor_inside to properly suggest elided spans in paths
// originating from macros, since the segment's span might be from a macro arg.
segment.ident.span.find_ancestor_inside(path_span).unwrap_or(path_span)
} else if generic_args.is_empty() { } else if generic_args.is_empty() {
// If there are brackets, but not generic arguments, then use the opening bracket // If there are brackets, but not generic arguments, then use the opening bracket
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1)) generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))

View File

@ -2115,10 +2115,13 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
let spans_suggs: Vec<_> = formatters let spans_suggs: Vec<_> = formatters
.into_iter() .into_iter()
.zip(spans_with_counts.iter()) .zip(spans_with_counts.iter())
.filter_map(|(fmt, (span, _))| { .filter_map(|(formatter, (span, _))| {
if let Some(formatter) = fmt { Some((formatter, span)) } else { None } if let Some(formatter) = formatter {
Some((*span, formatter(name)))
} else {
None
}
}) })
.map(|(formatter, span)| (*span, formatter(name)))
.collect(); .collect();
if spans_suggs.is_empty() { if spans_suggs.is_empty() {
// If all the spans come from macros, we cannot extract snippets and then // If all the spans come from macros, we cannot extract snippets and then

View File

@ -839,7 +839,17 @@ fn evaluate_nested_obligations(
_ => return false, _ => return false,
} }
} }
_ => panic!("Unexpected predicate {:?} {:?}", ty, predicate), // There's not really much we can do with these predicates -
// we start out with a `ParamEnv` with no inference variables,
// and these don't correspond to adding any new bounds to
// the `ParamEnv`.
ty::PredicateKind::WellFormed(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
}; };
} }
true true

View File

@ -1065,6 +1065,18 @@ macro_rules! line {
/// let current_col = column!(); /// let current_col = column!();
/// println!("defined on column: {}", current_col); /// println!("defined on column: {}", current_col);
/// ``` /// ```
///
/// `column!` counts Unicode code points, not bytes or graphemes. As a result, the first two
/// invocations return the same value, but the third does not.
///
/// ```
/// let a = ("foobar", column!()).1;
/// let b = ("人之初性本善", column!()).1;
/// let c = ("f̅o̅o̅b̅a̅r̅", column!()).1; // Uses combining overline (U+0305)
///
/// assert_eq!(a, b);
/// assert_ne!(b, c);
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro] #[rustc_builtin_macro]
#[macro_export] #[macro_export]

View File

@ -548,7 +548,6 @@ jobs:
env: env:
SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld
VCVARS_BAT: vcvars64.bat
<<: *job-windows-xl <<: *job-windows-xl
- name: x86_64-msvc-tools - name: x86_64-msvc-tools

View File

@ -0,0 +1,34 @@
#![feature(generic_associated_types)]
#![allow(unused)]
trait Trait<'a> {
type Foo;
type Bar<'b>
//~^ NOTE associated type defined here, with 1 lifetime parameter
//~| NOTE
where
Self: 'b;
}
struct Impl<'a>(&'a ());
impl<'a> Trait<'a> for Impl<'a> {
type Foo = &'a ();
type Bar<'b> = &'b ();
}
type A<'a> = Impl<'a>;
type B<'a> = <A<'a> as Trait>::Foo;
//~^ ERROR missing lifetime specifier
//~| NOTE expected named lifetime parameter
type C<'a, 'b> = <A<'a> as Trait>::Bar;
//~^ ERROR missing lifetime specifier
//~| ERROR missing generics for associated type
//~| NOTE expected named lifetime parameter
//~| NOTE these named lifetimes are available to use
//~| NOTE expected 1 lifetime argument
fn main() {}

View File

@ -0,0 +1,43 @@
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-in-alias.rs:23:24
|
LL | type B<'a> = <A<'a> as Trait>::Foo;
| ^^^^^ expected named lifetime parameter
|
help: consider using the `'a` lifetime
|
LL | type B<'a> = <A<'a> as Trait<'a>>::Foo;
| ~~~~~~~~~
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-in-alias.rs:27:28
|
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
| ^^^^^ expected named lifetime parameter
|
note: these named lifetimes are available to use
--> $DIR/missing-lifetime-in-alias.rs:27:8
|
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
| ^^ ^^
error[E0107]: missing generics for associated type `Trait::Bar`
--> $DIR/missing-lifetime-in-alias.rs:27:36
|
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
| ^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'b`
--> $DIR/missing-lifetime-in-alias.rs:7:10
|
LL | type Bar<'b>
| ^^^ --
help: add missing lifetime argument
|
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar<'a>;
| ~~~~~~~
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0106, E0107.
For more information about an error, try `rustc --explain E0106`.

View File

@ -1,8 +1,8 @@
warning: hidden lifetime parameters in types are deprecated warning: hidden lifetime parameters in types are deprecated
--> $DIR/reasons.rs:20:29 --> $DIR/reasons.rs:20:34
| |
LL | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { LL | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
| ^^^^^^^^^^^^^^ expected named lifetime parameter | ^^^^^^^^^ expected named lifetime parameter
| |
= note: explicit anonymous lifetimes aid reasoning about ownership = note: explicit anonymous lifetimes aid reasoning about ownership
note: the lint level is defined here note: the lint level is defined here
@ -13,7 +13,7 @@ LL | #![warn(elided_lifetimes_in_paths,
help: consider using the `'_` lifetime help: consider using the `'_` lifetime
| |
LL | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { LL | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
| ~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~
warning: variable `Social_exchange_psychology` should have a snake case name warning: variable `Social_exchange_psychology` should have a snake case name
--> $DIR/reasons.rs:30:9 --> $DIR/reasons.rs:30:9

View File

@ -0,0 +1,879 @@
// run-pass
// edition:2021
// compile-flags: --test
#![feature(async_closure)]
#![feature(const_trait_impl)]
#![feature(generators)]
#![feature(half_open_range_patterns)]
#![feature(more_qualified_paths)]
#![feature(raw_ref_op)]
#![deny(unused_macros)]
macro_rules! stringify_block {
($block:block) => {
stringify!($block)
};
}
macro_rules! stringify_expr {
($expr:expr) => {
stringify!($expr)
};
}
macro_rules! stringify_item {
($item:item) => {
stringify!($item)
};
}
macro_rules! stringify_meta {
($meta:meta) => {
stringify!($meta)
};
}
macro_rules! stringify_pat {
($pat:pat) => {
stringify!($pat)
};
}
macro_rules! stringify_path {
($path:path) => {
stringify!($path)
};
}
macro_rules! stringify_stmt {
($stmt:stmt) => {
stringify!($stmt)
};
}
macro_rules! stringify_ty {
($ty:ty) => {
stringify!($ty)
};
}
macro_rules! stringify_vis {
($vis:vis) => {
stringify!($vis)
};
}
#[test]
fn test_block() {
assert_eq!(stringify_block!({}), "{}");
assert_eq!(stringify_block!({ true }), "{ true }");
assert_eq!(stringify_block!({ return }), "{ return }");
assert_eq!(
stringify_block!({
return;
}),
"{ return; }",
);
assert_eq!(
stringify_block!({
let _;
true
}),
"{ let _; true }",
);
}
#[test]
fn test_expr() {
// ExprKind::Box
assert_eq!(stringify_expr!(box expr), "box expr");
// ExprKind::Array
assert_eq!(stringify_expr!([]), "[]");
assert_eq!(stringify_expr!([true]), "[true]");
assert_eq!(stringify_expr!([true,]), "[true]");
assert_eq!(stringify_expr!([true, true]), "[true, true]");
// ExprKind::Call
assert_eq!(stringify_expr!(f()), "f()");
assert_eq!(stringify_expr!(f::<u8>()), "f::<u8>()");
assert_eq!(stringify_expr!(f::<1>()), "f::<1>()");
assert_eq!(stringify_expr!(f::<'a, u8, 1>()), "f::<'a, u8, 1>()");
assert_eq!(stringify_expr!(f(true)), "f(true)");
assert_eq!(stringify_expr!(f(true,)), "f(true)");
assert_eq!(stringify_expr!(()()), "()()");
// ExprKind::MethodCall
assert_eq!(stringify_expr!(x.f()), "x.f()");
assert_eq!(stringify_expr!(x.f::<u8>()), "x.f::<u8>()");
// ExprKind::Tup
assert_eq!(stringify_expr!(()), "()");
assert_eq!(stringify_expr!((true,)), "(true,)");
assert_eq!(stringify_expr!((true, false)), "(true, false)");
assert_eq!(stringify_expr!((true, false,)), "(true, false)");
// ExprKind::Binary
assert_eq!(stringify_expr!(true || false), "true || false");
assert_eq!(stringify_expr!(true || false && false), "true || false && false");
// ExprKind::Unary
assert_eq!(stringify_expr!(*expr), "*expr");
assert_eq!(stringify_expr!(!expr), "!expr");
assert_eq!(stringify_expr!(-expr), "-expr");
// ExprKind::Lit
assert_eq!(stringify_expr!('x'), "'x'");
assert_eq!(stringify_expr!(1_000_i8), "1_000_i8");
assert_eq!(stringify_expr!(1.00000000000000001), "1.00000000000000001");
// ExprKind::Cast
assert_eq!(stringify_expr!(expr as T), "expr as T");
assert_eq!(stringify_expr!(expr as T<u8>), "expr as T<u8>");
// ExprKind::Type
assert_eq!(stringify_expr!(expr: T), "expr: T");
assert_eq!(stringify_expr!(expr: T<u8>), "expr: T<u8>");
// ExprKind::If
assert_eq!(stringify_expr!(if true {}), "if true {}");
assert_eq!(
stringify_expr!(if true {
} else {
}),
"if true {} else {}",
);
assert_eq!(
stringify_expr!(if let true = true {
} else {
}),
"if let true = true {} else {}",
);
assert_eq!(
stringify_expr!(if true {
} else if false {
}),
"if true {} else if false {}",
);
assert_eq!(
stringify_expr!(if true {
} else if false {
} else {
}),
"if true {} else if false {} else {}",
);
assert_eq!(
stringify_expr!(if true {
return;
} else if false {
0
} else {
0
}),
"if true { return; } else if false { 0 } else { 0 }",
);
// ExprKind::While
assert_eq!(stringify_expr!(while true {}), "while true {}");
assert_eq!(stringify_expr!('a: while true {}), "'a: while true {}");
assert_eq!(stringify_expr!(while let true = true {}), "while let true = true {}");
// ExprKind::ForLoop
assert_eq!(stringify_expr!(for _ in x {}), "for _ in x {}");
assert_eq!(stringify_expr!('a: for _ in x {}), "'a: for _ in x {}");
// ExprKind::Loop
assert_eq!(stringify_expr!(loop {}), "loop {}");
assert_eq!(stringify_expr!('a: loop {}), "'a: loop {}");
// ExprKind::Match
assert_eq!(stringify_expr!(match self {}), "match self {}");
assert_eq!(
stringify_expr!(match self {
Ok => 1,
}),
"match self { Ok => 1, }",
);
assert_eq!(
stringify_expr!(match self {
Ok => 1,
Err => 0,
}),
"match self { Ok => 1, Err => 0, }",
);
// ExprKind::Closure
assert_eq!(stringify_expr!(|| {}), "|| {}");
assert_eq!(stringify_expr!(|x| {}), "|x| {}");
assert_eq!(stringify_expr!(|x: u8| {}), "|x: u8| {}");
assert_eq!(stringify_expr!(|| ()), "|| ()");
assert_eq!(stringify_expr!(move || self), "move || self");
assert_eq!(stringify_expr!(async || self), "async || self");
assert_eq!(stringify_expr!(async move || self), "async move || self");
assert_eq!(stringify_expr!(static || self), "static || self");
assert_eq!(stringify_expr!(static move || self), "static move || self");
#[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5149
assert_eq!(
stringify_expr!(static async || self),
"static async || self",
);
#[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5149
assert_eq!(
stringify_expr!(static async move || self),
"static async move || self",
);
assert_eq!(stringify_expr!(|| -> u8 { self }), "|| -> u8 { self }");
assert_eq!(stringify_expr!(1 + || {}), "1 + (|| {})"); // ??
// ExprKind::Block
assert_eq!(stringify_expr!({}), "{}");
assert_eq!(stringify_expr!(unsafe {}), "unsafe {}");
assert_eq!(stringify_expr!('a: {}), "'a: {}");
assert_eq!(
stringify_expr!(
#[attr]
{}
),
"#[attr] { }", // FIXME
);
assert_eq!(
stringify_expr!(
{
#![attr]
}
),
"{\n\
\x20 #![attr]\n\
}",
);
// ExprKind::Async
assert_eq!(stringify_expr!(async {}), "async {}");
assert_eq!(stringify_expr!(async move {}), "async move {}");
// ExprKind::Await
assert_eq!(stringify_expr!(expr.await), "expr.await");
// ExprKind::TryBlock
assert_eq!(stringify_expr!(try {}), "try {}"); // FIXME
// ExprKind::Assign
assert_eq!(stringify_expr!(expr = true), "expr = true");
// ExprKind::AssignOp
assert_eq!(stringify_expr!(expr += true), "expr += true");
// ExprKind::Field
assert_eq!(stringify_expr!(expr.field), "expr.field");
assert_eq!(stringify_expr!(expr.0), "expr.0");
// ExprKind::Index
assert_eq!(stringify_expr!(expr[true]), "expr[true]");
// ExprKind::Range
assert_eq!(stringify_expr!(..), "..");
assert_eq!(stringify_expr!(..hi), "..hi");
assert_eq!(stringify_expr!(lo..), "lo..");
assert_eq!(stringify_expr!(lo..hi), "lo..hi");
assert_eq!(stringify_expr!(..=hi), "..=hi");
assert_eq!(stringify_expr!(lo..=hi), "lo..=hi");
assert_eq!(stringify_expr!(-2..=-1), "-2..=-1");
// ExprKind::Path
assert_eq!(stringify_expr!(thing), "thing");
assert_eq!(stringify_expr!(m::thing), "m::thing");
assert_eq!(stringify_expr!(self::thing), "self::thing");
assert_eq!(stringify_expr!(crate::thing), "crate::thing");
assert_eq!(stringify_expr!(Self::thing), "Self::thing");
assert_eq!(stringify_expr!(<Self as T>::thing), "<Self as T>::thing");
assert_eq!(stringify_expr!(Self::<'static>), "Self::<'static>");
// ExprKind::AddrOf
assert_eq!(stringify_expr!(&expr), "&expr");
assert_eq!(stringify_expr!(&mut expr), "&mut expr");
assert_eq!(stringify_expr!(&raw const expr), "&raw const expr");
assert_eq!(stringify_expr!(&raw mut expr), "&raw mut expr");
// ExprKind::Break
assert_eq!(stringify_expr!(break), "break");
assert_eq!(stringify_expr!(break 'a), "break 'a");
assert_eq!(stringify_expr!(break true), "break true");
assert_eq!(stringify_expr!(break 'a true), "break 'a true");
// ExprKind::Continue
assert_eq!(stringify_expr!(continue), "continue");
assert_eq!(stringify_expr!(continue 'a), "continue 'a");
// ExprKind::Ret
assert_eq!(stringify_expr!(return), "return");
assert_eq!(stringify_expr!(return true), "return true");
// ExprKind::MacCall
assert_eq!(stringify_expr!(mac!(...)), "mac!(...)");
assert_eq!(stringify_expr!(mac![...]), "mac![...]");
assert_eq!(stringify_expr!(mac! { ... }), "mac! { ... }");
// ExprKind::Struct
assert_eq!(stringify_expr!(Struct {}), "Struct{}"); // FIXME
#[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5151
assert_eq!(stringify_expr!(<Struct as Trait>::Type {}), "<Struct as Trait>::Type{}");
assert_eq!(stringify_expr!(Struct { .. }), "Struct{..}"); // FIXME
assert_eq!(stringify_expr!(Struct { ..base }), "Struct{..base}"); // FIXME
assert_eq!(stringify_expr!(Struct { x }), "Struct{x,}");
assert_eq!(stringify_expr!(Struct { x, .. }), "Struct{x, ..}");
assert_eq!(stringify_expr!(Struct { x, ..base }), "Struct{x, ..base}");
assert_eq!(stringify_expr!(Struct { x: true }), "Struct{x: true,}");
assert_eq!(stringify_expr!(Struct { x: true, .. }), "Struct{x: true, ..}");
assert_eq!(stringify_expr!(Struct { x: true, ..base }), "Struct{x: true, ..base}");
// ExprKind::Repeat
assert_eq!(stringify_expr!([(); 0]), "[(); 0]");
// ExprKind::Paren
assert_eq!(stringify_expr!((expr)), "(expr)");
// ExprKind::Try
assert_eq!(stringify_expr!(expr?), "expr?");
// ExprKind::Yield
assert_eq!(stringify_expr!(yield), "yield");
assert_eq!(stringify_expr!(yield true), "yield true");
}
#[test]
fn test_item() {
// ItemKind::ExternCrate
assert_eq!(
stringify_item!(
extern crate std;
),
"extern crate std;",
);
assert_eq!(
stringify_item!(
pub extern crate self as std;
),
"pub extern crate self as std;",
);
// ItemKind::Use
assert_eq!(
stringify_item!(
pub use crate::{a, b::c};
),
"pub use crate::{a, b::c};",
);
// ItemKind::Static
assert_eq!(
stringify_item!(
pub static S: () = {};
),
"pub static S: () = {};",
);
assert_eq!(
stringify_item!(
static mut S: () = {};
),
"static mut S: () = {};",
);
assert_eq!(
stringify_item!(
static S: ();
),
"static S: () ;", // FIXME
);
assert_eq!(
stringify_item!(
static mut S: ();
),
"static mut S: () ;",
);
// ItemKind::Const
assert_eq!(
stringify_item!(
pub const S: () = {};
),
"pub const S: () = {};",
);
assert_eq!(
stringify_item!(
const S: ();
),
"const S: () ;", // FIXME
);
// ItemKind::Fn
assert_eq!(
stringify_item!(
pub default const async unsafe extern "C" fn f() {}
),
"pub default const async unsafe extern \"C\" fn f() {}",
);
// ItemKind::Mod
assert_eq!(
stringify_item!(
pub mod m;
),
"pub mod m;",
);
assert_eq!(
stringify_item!(
mod m {}
),
"mod m {}",
);
assert_eq!(
stringify_item!(
unsafe mod m;
),
"unsafe mod m;",
);
assert_eq!(
stringify_item!(
unsafe mod m {}
),
"unsafe mod m {}",
);
// ItemKind::ForeignMod
assert_eq!(
stringify_item!(
extern "C" {}
),
"extern \"C\" {}",
);
#[rustfmt::skip]
assert_eq!(
stringify_item!(
pub extern "C" {}
),
"extern \"C\" {}",
);
assert_eq!(
stringify_item!(
unsafe extern "C++" {}
),
"unsafe extern \"C++\" {}",
);
// ItemKind::TyAlias
#[rustfmt::skip]
assert_eq!(
stringify_item!(
pub default type Type<'a>: Bound
where
Self: 'a,
= T;
),
"pub default type Type<'a>: Bound where Self: 'a = T;",
);
// ItemKind::Enum
assert_eq!(
stringify_item!(
pub enum Void {}
),
"pub enum Void {}",
);
assert_eq!(
stringify_item!(
enum Empty {
Unit,
Tuple(),
Struct {},
}
),
"enum Empty { Unit, Tuple(), Struct {}, }",
);
assert_eq!(
stringify_item!(
enum Enum<T>
where
T: 'a,
{
Unit,
Tuple(T),
Struct { t: T },
}
),
"enum Enum<T> where T: 'a {\n\
\x20 Unit,\n\
\x20 Tuple(T),\n\
\x20 Struct {\n\
\x20 t: T,\n\
\x20 },\n\
}",
);
// ItemKind::Struct
assert_eq!(
stringify_item!(
pub struct Unit;
),
"pub struct Unit;",
);
assert_eq!(
stringify_item!(
struct Tuple();
),
"struct Tuple();",
);
assert_eq!(
stringify_item!(
struct Tuple(T);
),
"struct Tuple(T);",
);
assert_eq!(
stringify_item!(
struct Struct {}
),
"struct Struct {}",
);
assert_eq!(
stringify_item!(
struct Struct<T>
where
T: 'a,
{
t: T,
}
),
"struct Struct<T> where T: 'a {\n\
\x20 t: T,\n\
}",
);
// ItemKind::Union
assert_eq!(
stringify_item!(
pub union Union {}
),
"pub union Union {}",
);
assert_eq!(
stringify_item!(
union Union<T> where T: 'a {
t: T,
}
),
"union Union<T> where T: 'a {\n\
\x20 t: T,\n\
}",
);
// ItemKind::Trait
assert_eq!(
stringify_item!(
pub unsafe auto trait Send {}
),
"pub unsafe auto trait Send {}",
);
assert_eq!(
stringify_item!(
trait Trait<'a>: Sized
where
Self: 'a,
{
}
),
"trait Trait<'a>: Sized where Self: 'a {}",
);
// ItemKind::TraitAlias
assert_eq!(
stringify_item!(
pub trait Trait<T> = Sized where T: 'a;
),
"", // FIXME
);
// ItemKind::Impl
assert_eq!(
stringify_item!(
pub impl Struct {}
),
"pub impl Struct {}",
);
assert_eq!(
stringify_item!(
impl<T> Struct<T> {}
),
"impl <T> Struct<T> {}", // FIXME
);
assert_eq!(
stringify_item!(
pub impl Trait for Struct {}
),
"pub impl Trait for Struct {}",
);
assert_eq!(
stringify_item!(
impl ~const Struct {}
),
"impl Struct {}", // FIXME
);
// ItemKind::MacCall
assert_eq!(stringify_item!(mac!(...);), "mac!(...);");
assert_eq!(stringify_item!(mac![...];), "mac![...];");
assert_eq!(stringify_item!(mac! { ... }), "mac! { ... }");
// ItemKind::MacroDef
assert_eq!(
stringify_item!(
macro_rules! stringify {
() => {};
}
),
"macro_rules! stringify { () => {} ; }", // FIXME
);
assert_eq!(
stringify_item!(
pub macro stringify() {}
),
"pub macro stringify { () => {} }",
);
}
#[test]
fn test_meta() {
assert_eq!(stringify_meta!(k), "k");
assert_eq!(stringify_meta!(k = "v"), "k = \"v\"");
assert_eq!(stringify_meta!(list(k1, k2 = "v")), "list(k1, k2 = \"v\")");
assert_eq!(stringify_meta!(serde::k), "serde::k");
}
#[test]
fn test_pat() {
// PatKind::Wild
assert_eq!(stringify_pat!(_), "_");
// PatKind::Ident
assert_eq!(stringify_pat!(_x), "_x");
assert_eq!(stringify_pat!(ref _x), "ref _x");
assert_eq!(stringify_pat!(mut _x), "mut _x");
assert_eq!(stringify_pat!(ref mut _x), "ref mut _x");
assert_eq!(stringify_pat!(ref mut _x @ _), "ref mut _x @ _");
// PatKind::Struct
assert_eq!(stringify_pat!(Struct {}), "Struct { }"); // FIXME
assert_eq!(stringify_pat!(Struct::<u8> {}), "Struct::<u8> { }");
assert_eq!(stringify_pat!(Struct::<'static> {}), "Struct::<'static> { }");
assert_eq!(stringify_pat!(Struct { x }), "Struct { x }");
assert_eq!(stringify_pat!(Struct { x: _x }), "Struct { x: _x }");
assert_eq!(stringify_pat!(Struct { .. }), "Struct { .. }");
assert_eq!(stringify_pat!(Struct { x, .. }), "Struct { x, .. }");
assert_eq!(stringify_pat!(Struct { x: _x, .. }), "Struct { x: _x, .. }");
#[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5151
assert_eq!(
stringify_pat!(<Struct as Trait>::Type {}),
"<Struct as Trait>::Type { }",
);
// PatKind::TupleStruct
assert_eq!(stringify_pat!(Tuple()), "Tuple()");
assert_eq!(stringify_pat!(Tuple::<u8>()), "Tuple::<u8>()");
assert_eq!(stringify_pat!(Tuple::<'static>()), "Tuple::<'static>()");
assert_eq!(stringify_pat!(Tuple(x)), "Tuple(x)");
assert_eq!(stringify_pat!(Tuple(..)), "Tuple(..)");
assert_eq!(stringify_pat!(Tuple(x, ..)), "Tuple(x, ..)");
assert_eq!(stringify_pat!(<Struct as Trait>::Type()), "<Struct as Trait>::Type()");
// PatKind::Or
assert_eq!(stringify_pat!(true | false), "true | false");
assert_eq!(stringify_pat!(| true), "true");
assert_eq!(stringify_pat!(|true| false), "true | false");
// PatKind::Path
assert_eq!(stringify_pat!(crate::Path), "crate::Path");
assert_eq!(stringify_pat!(Path::<u8>), "Path::<u8>");
assert_eq!(stringify_pat!(Path::<'static>), "Path::<'static>");
assert_eq!(stringify_pat!(<Struct as Trait>::Type), "<Struct as Trait>::Type");
// PatKind::Tuple
assert_eq!(stringify_pat!(()), "()");
assert_eq!(stringify_pat!((true,)), "(true,)");
assert_eq!(stringify_pat!((true, false)), "(true, false)");
// PatKind::Box
assert_eq!(stringify_pat!(box pat), "box pat");
// PatKind::Ref
assert_eq!(stringify_pat!(&pat), "&pat");
assert_eq!(stringify_pat!(&mut pat), "&mut pat");
// PatKind::Lit
assert_eq!(stringify_pat!(1_000_i8), "1_000_i8");
// PatKind::Range
assert_eq!(stringify_pat!(..1), "..1");
assert_eq!(stringify_pat!(0..), "0 .."); // FIXME
assert_eq!(stringify_pat!(0..1), "0 ..1");
assert_eq!(stringify_pat!(0..=1), "0 ..=1");
assert_eq!(stringify_pat!(-2..=-1), "-2 ..=-1");
// PatKind::Slice
assert_eq!(stringify_pat!([]), "[]");
assert_eq!(stringify_pat!([true]), "[true]");
assert_eq!(stringify_pat!([true,]), "[true]");
assert_eq!(stringify_pat!([true, false]), "[true, false]");
// PatKind::Rest
assert_eq!(stringify_pat!(..), "..");
// PatKind::Paren
assert_eq!(stringify_pat!((pat)), "(pat)");
// PatKind::MacCall
assert_eq!(stringify_pat!(mac!(...)), "mac!(...)");
assert_eq!(stringify_pat!(mac![...]), "mac![...]");
assert_eq!(stringify_pat!(mac! { ... }), "mac! { ... }");
}
#[test]
fn test_path() {
assert_eq!(stringify_path!(thing), "thing");
assert_eq!(stringify_path!(m::thing), "m::thing");
assert_eq!(stringify_path!(self::thing), "self::thing");
assert_eq!(stringify_path!(crate::thing), "crate::thing");
assert_eq!(stringify_path!(Self::thing), "Self::thing");
assert_eq!(stringify_path!(Self<'static>), "Self<'static>");
assert_eq!(stringify_path!(Self::<'static>), "Self<'static>");
assert_eq!(stringify_path!(Self()), "Self()");
assert_eq!(stringify_path!(Self() -> ()), "Self() -> ()");
}
#[test]
fn test_stmt() {
// StmtKind::Local
assert_eq!(stringify_stmt!(let _), "let _;");
assert_eq!(stringify_stmt!(let x = true), "let x = true;");
assert_eq!(stringify_stmt!(let x: bool = true), "let x: bool = true;");
// StmtKind::Item
assert_eq!(
stringify_stmt!(
struct S;
),
"struct S;",
);
// StmtKind::Expr
assert_eq!(stringify_stmt!(loop {}), "loop {}");
// StmtKind::Semi
assert_eq!(stringify_stmt!(1 + 1), "1 + 1;");
// StmtKind::Empty
assert_eq!(stringify_stmt!(;), ";");
// StmtKind::MacCall
assert_eq!(stringify_stmt!(mac!(...)), "mac!(...)");
assert_eq!(stringify_stmt!(mac![...]), "mac![...]");
assert_eq!(stringify_stmt!(mac! { ... }), "mac! { ... }");
}
#[test]
fn test_ty() {
// TyKind::Slice
assert_eq!(stringify_ty!([T]), "[T]");
// TyKind::Array
assert_eq!(stringify_ty!([T; 0]), "[T; 0]");
// TyKind::Ptr
assert_eq!(stringify_ty!(*const T), "*const T");
assert_eq!(stringify_ty!(*mut T), "*mut T");
// TyKind::Rptr
assert_eq!(stringify_ty!(&T), "&T");
assert_eq!(stringify_ty!(&mut T), "&mut T");
assert_eq!(stringify_ty!(&'a T), "&'a T");
assert_eq!(stringify_ty!(&'a mut T), "&'a mut T");
// TyKind::BareFn
assert_eq!(stringify_ty!(fn()), "fn()");
assert_eq!(stringify_ty!(fn() -> ()), "fn() -> ()");
assert_eq!(stringify_ty!(fn(u8)), "fn(u8)");
assert_eq!(stringify_ty!(fn(x: u8)), "fn(x: u8)");
#[rustfmt::skip]
assert_eq!(stringify_ty!(for<> fn()), "fn()");
assert_eq!(stringify_ty!(for<'a> fn()), "for<'a>fn()"); // FIXME
// TyKind::Never
assert_eq!(stringify_ty!(!), "!");
// TyKind::Tup
assert_eq!(stringify_ty!(()), "()");
assert_eq!(stringify_ty!((T,)), "(T,)");
assert_eq!(stringify_ty!((T, U)), "(T, U)");
// TyKind::Path
assert_eq!(stringify_ty!(T), "T");
assert_eq!(stringify_ty!(Ref<'a>), "Ref<'a>");
assert_eq!(stringify_ty!(PhantomData<T>), "PhantomData<T>");
assert_eq!(stringify_ty!(PhantomData::<T>), "PhantomData<T>");
assert_eq!(stringify_ty!(Fn() -> !), "Fn() -> !");
assert_eq!(stringify_ty!(Fn(u8) -> !), "Fn(u8) -> !");
assert_eq!(stringify_ty!(<Struct as Trait>::Type), "<Struct as Trait>::Type");
// TyKind::TraitObject
assert_eq!(stringify_ty!(dyn Send), "dyn Send");
assert_eq!(stringify_ty!(dyn Send + 'a), "dyn Send + 'a");
assert_eq!(stringify_ty!(dyn 'a + Send), "dyn 'a + Send");
assert_eq!(stringify_ty!(dyn ?Sized), "dyn ?Sized");
assert_eq!(stringify_ty!(dyn ~const Clone), "dyn Clone"); // FIXME
assert_eq!(stringify_ty!(dyn for<'a> Send), "dyn for<'a> Send");
// TyKind::ImplTrait
assert_eq!(stringify_ty!(impl Send), "impl Send");
assert_eq!(stringify_ty!(impl Send + 'a), "impl Send + 'a");
assert_eq!(stringify_ty!(impl 'a + Send), "impl 'a + Send");
assert_eq!(stringify_ty!(impl ?Sized), "impl ?Sized");
assert_eq!(stringify_ty!(impl ~const Clone), "impl Clone"); // FIXME
assert_eq!(stringify_ty!(impl for<'a> Send), "impl for<'a> Send");
// TyKind::Paren
assert_eq!(stringify_ty!((T)), "(T)");
// TyKind::Infer
assert_eq!(stringify_ty!(_), "_");
// TyKind::MacCall
assert_eq!(stringify_ty!(mac!(...)), "mac!(...)");
assert_eq!(stringify_ty!(mac![...]), "mac![...]");
assert_eq!(stringify_ty!(mac! { ... }), "mac! { ... }");
}
#[test]
fn test_vis() {
// VisibilityKind::Public
assert_eq!(stringify_vis!(pub), "pub ");
// VisibilityKind::Crate
assert_eq!(stringify_vis!(crate), "crate ");
// VisibilityKind::Restricted
assert_eq!(stringify_vis!(pub(self)), "pub(self) ");
assert_eq!(stringify_vis!(pub(super)), "pub(super) ");
assert_eq!(stringify_vis!(pub(in self)), "pub(self) ");
assert_eq!(stringify_vis!(pub(in super)), "pub(super) ");
assert_eq!(stringify_vis!(pub(in path::to)), "pub(in path::to) ");
assert_eq!(stringify_vis!(pub(in ::path::to)), "pub(in ::path::to) ");
assert_eq!(stringify_vis!(pub(in self::path::to)), "pub(in self::path::to) ");
assert_eq!(stringify_vis!(pub(in super::path::to)), "pub(in super::path::to) ");
// VisibilityKind::Inherited
// Directly calling `stringify_vis!()` does not work.
macro_rules! stringify_inherited_vis {
($vis:vis struct) => {
stringify_vis!($vis)
};
}
assert_eq!(stringify_inherited_vis!(struct), "");
}

@ -1 +1 @@
Subproject commit 0add6e95e58633fde2fff0bccaf6c7d71ebc130f Subproject commit 68319187d63707fa36d7c215ed0e444e87d9652a