From 31731511c0563d71289d29d1f53a21fe2fce5534 Mon Sep 17 00:00:00 2001 From: Smitty <me@smitop.com> Date: Sat, 18 Dec 2021 08:50:01 -0500 Subject: [PATCH 01/10] Support [x; n] expressions in concat_bytes! Contributes to #87555. --- .../rustc_builtin_macros/src/concat_bytes.rs | 105 +++++++++++------- src/test/ui/macros/concat-bytes-error.rs | 8 ++ src/test/ui/macros/concat-bytes-error.stderr | 52 ++++++++- src/test/ui/macros/concat-bytes.rs | 12 +- 4 files changed, 135 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index a107f5993b546..87920e5175268 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -72,6 +72,52 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne } } +fn handle_array_element( + cx: &mut base::ExtCtxt<'_>, + has_errors: &mut bool, + missing_literals: &mut Vec<rustc_span::Span>, + expr: &P<rustc_ast::Expr>, +) -> Option<u8> { + match expr.kind { + ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => { + if !*has_errors { + cx.span_err(expr.span, "cannot concatenate doubly nested array"); + } + *has_errors = true; + None + } + ast::ExprKind::Lit(ref lit) => match lit.kind { + ast::LitKind::Int( + val, + ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8), + ) if val <= u8::MAX.into() => Some(val as u8), + + ast::LitKind::Byte(val) => Some(val), + ast::LitKind::ByteStr(_) => { + if !*has_errors { + cx.struct_span_err(expr.span, "cannot concatenate doubly nested array") + .note("byte strings are treated as arrays of bytes") + .help("try flattening the array") + .emit(); + } + *has_errors = true; + None + } + _ => { + if !*has_errors { + invalid_type_err(cx, expr, true); + } + *has_errors = true; + None + } + }, + _ => { + missing_literals.push(expr.span); + None + } + } +} + pub fn expand_concat_bytes( cx: &mut base::ExtCtxt<'_>, sp: rustc_span::Span, @@ -88,48 +134,27 @@ pub fn expand_concat_bytes( match e.kind { ast::ExprKind::Array(ref exprs) => { for expr in exprs { - match expr.kind { - ast::ExprKind::Array(_) => { - if !has_errors { - cx.span_err(expr.span, "cannot concatenate doubly nested array"); - } - has_errors = true; - } - ast::ExprKind::Lit(ref lit) => match lit.kind { - ast::LitKind::Int( - val, - ast::LitIntType::Unsuffixed - | ast::LitIntType::Unsigned(ast::UintTy::U8), - ) if val <= u8::MAX.into() => { - accumulator.push(val as u8); - } - - ast::LitKind::Byte(val) => { - accumulator.push(val); - } - ast::LitKind::ByteStr(_) => { - if !has_errors { - cx.struct_span_err( - expr.span, - "cannot concatenate doubly nested array", - ) - .note("byte strings are treated as arrays of bytes") - .help("try flattening the array") - .emit(); - } - has_errors = true; - } - _ => { - if !has_errors { - invalid_type_err(cx, expr, true); - } - has_errors = true; - } - }, - _ => { - missing_literals.push(expr.span); + if let Some(elem) = + handle_array_element(cx, &mut has_errors, &mut missing_literals, expr) + { + accumulator.push(elem); + } + } + } + ast::ExprKind::Repeat(ref expr, ref count) => { + if let ast::ExprKind::Lit(ast::Lit { + kind: ast::LitKind::Int(count_val, _), .. + }) = count.value.kind + { + if let Some(elem) = + handle_array_element(cx, &mut has_errors, &mut missing_literals, expr) + { + for _ in 0..count_val { + accumulator.push(elem); } } + } else { + cx.span_err(count.value.span, "repeat count is not a number"); } } ast::ExprKind::Lit(ref lit) => match lit.kind { diff --git a/src/test/ui/macros/concat-bytes-error.rs b/src/test/ui/macros/concat-bytes-error.rs index 9b4a9c2cf811d..2c7997d5e5905 100644 --- a/src/test/ui/macros/concat-bytes-error.rs +++ b/src/test/ui/macros/concat-bytes-error.rs @@ -39,4 +39,12 @@ fn main() { ]); concat_bytes!(5u16); //~ ERROR cannot concatenate numeric literals concat_bytes!([5u16]); //~ ERROR numeric literal is not a `u8` + concat_bytes!([3; ()]); //~ ERROR repeat count is not a number + concat_bytes!([3; -2]); //~ ERROR repeat count is not a number + concat_bytes!([pie; -2]); //~ ERROR repeat count is not a number + concat_bytes!([pie; 2]); //~ ERROR expected a byte literal + concat_bytes!([2.2; 0]); //~ ERROR cannot concatenate float literals + concat_bytes!([5.5; ()]); //~ ERROR repeat count is not a number + concat_bytes!([[1, 2, 3]; 3]); //~ ERROR cannot concatenate doubly nested array + concat_bytes!([[42; 2]; 3]); //~ ERROR cannot concatenate doubly nested array } diff --git a/src/test/ui/macros/concat-bytes-error.stderr b/src/test/ui/macros/concat-bytes-error.stderr index 1fc2d5c4843a0..f0c53839b3ad5 100644 --- a/src/test/ui/macros/concat-bytes-error.stderr +++ b/src/test/ui/macros/concat-bytes-error.stderr @@ -127,5 +127,55 @@ error: numeric literal is not a `u8` LL | concat_bytes!([5u16]); | ^^^^ -error: aborting due to 20 previous errors +error: repeat count is not a number + --> $DIR/concat-bytes-error.rs:42:23 + | +LL | concat_bytes!([3; ()]); + | ^^ + +error: repeat count is not a number + --> $DIR/concat-bytes-error.rs:43:23 + | +LL | concat_bytes!([3; -2]); + | ^^ + +error: repeat count is not a number + --> $DIR/concat-bytes-error.rs:44:25 + | +LL | concat_bytes!([pie; -2]); + | ^^ + +error: expected a byte literal + --> $DIR/concat-bytes-error.rs:45:20 + | +LL | concat_bytes!([pie; 2]); + | ^^^ + | + = note: only byte literals (like `b"foo"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()` + +error: cannot concatenate float literals + --> $DIR/concat-bytes-error.rs:46:20 + | +LL | concat_bytes!([2.2; 0]); + | ^^^ + +error: repeat count is not a number + --> $DIR/concat-bytes-error.rs:47:25 + | +LL | concat_bytes!([5.5; ()]); + | ^^ + +error: cannot concatenate doubly nested array + --> $DIR/concat-bytes-error.rs:48:20 + | +LL | concat_bytes!([[1, 2, 3]; 3]); + | ^^^^^^^^^ + +error: cannot concatenate doubly nested array + --> $DIR/concat-bytes-error.rs:49:20 + | +LL | concat_bytes!([[42; 2]; 3]); + | ^^^^^^^ + +error: aborting due to 28 previous errors diff --git a/src/test/ui/macros/concat-bytes.rs b/src/test/ui/macros/concat-bytes.rs index 5415cf3fe2235..fd8f99417ec98 100644 --- a/src/test/ui/macros/concat-bytes.rs +++ b/src/test/ui/macros/concat-bytes.rs @@ -3,5 +3,15 @@ fn main() { assert_eq!(concat_bytes!(), &[]); - assert_eq!(concat_bytes!(b'A', b"BC", [68, b'E', 70]), b"ABCDEF"); + assert_eq!( + concat_bytes!(b'A', b"BC", [68, b'E', 70], [b'G'; 1], [72; 2], [73u8; 3], [65; 0]), + b"ABCDEFGHHIII", + ); + assert_eq!( + concat_bytes!( + concat_bytes!(b"AB", b"CD"), + concat_bytes!(b"EF", b"GH"), + ), + b"ABCDEFGH", + ); } From d31f7f1097539c41fea01a7f05400d05d31786c7 Mon Sep 17 00:00:00 2001 From: Aaron Hill <aa1ronham@gmail.com> Date: Sat, 18 Dec 2021 11:25:05 -0500 Subject: [PATCH 02/10] Ignore other `PredicateKind`s in rustdoc auto trait finder Fixes #92073 There's not really anything we can do with them, and they're causing ICEs. I'm not using a wildcard match, as we should check that any new `PredicateKind`s are handled properly by rustdoc. --- .../rustc_trait_selection/src/traits/auto_trait.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 53ff911ea0cda..05d2a373dc639 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -839,7 +839,17 @@ impl<'tcx> AutoTraitFinder<'tcx> { _ => 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 From 4bbbdb7f459c72f02bf4b204c2ebad8fc7cd9b0c Mon Sep 17 00:00:00 2001 From: Eric Huss <eric@huss.org> Date: Wed, 22 Dec 2021 19:18:06 -0800 Subject: [PATCH 03/10] Remove VCVARS_BAT --- .github/workflows/ci.yml | 1 - src/ci/github-actions/ci.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd015e1cd4302..67deb3d977942 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -355,7 +355,6 @@ jobs: env: SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-lld" - VCVARS_BAT: vcvars64.bat os: windows-latest-xl - name: x86_64-msvc-tools env: diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 96af401369e94..ac5d5822bfbd5 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -548,7 +548,6 @@ jobs: env: SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld - VCVARS_BAT: vcvars64.bat <<: *job-windows-xl - name: x86_64-msvc-tools From a51326f1bafe669523a2aa413d2c068b2fe86ed6 Mon Sep 17 00:00:00 2001 From: David Tolnay <dtolnay@gmail.com> Date: Thu, 23 Dec 2021 13:02:31 -0800 Subject: [PATCH 04/10] Add a test suite for stringify macro --- src/test/ui/macros/stringify.rs | 894 ++++++++++++++++++++++++++++++++ 1 file changed, 894 insertions(+) create mode 100644 src/test/ui/macros/stringify.rs diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs new file mode 100644 index 0000000000000..924329d7a8441 --- /dev/null +++ b/src/test/ui/macros/stringify.rs @@ -0,0 +1,894 @@ +// 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 #![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 Unit,\n Tuple(T),\n Struct {\n t: T,\n },\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 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 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), ""); +} From ac43ba8bb8edd53090f8749c6be93eb7b7950488 Mon Sep 17 00:00:00 2001 From: David Tolnay <dtolnay@gmail.com> Date: Thu, 23 Dec 2021 16:53:30 -0800 Subject: [PATCH 05/10] Format with rust-lang/rust's rustfmt settings --- src/test/ui/macros/stringify.rs | 55 +++++++++------------------------ 1 file changed, 14 insertions(+), 41 deletions(-) diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs index 924329d7a8441..39aac34d45a4a 100644 --- a/src/test/ui/macros/stringify.rs +++ b/src/test/ui/macros/stringify.rs @@ -116,10 +116,7 @@ fn test_expr() { // ExprKind::Binary assert_eq!(stringify_expr!(true || false), "true || false"); - assert_eq!( - stringify_expr!(true || false && false), - "true || false && false", - ); + assert_eq!(stringify_expr!(true || false && false), "true || false && false"); // ExprKind::Unary assert_eq!(stringify_expr!(*expr), "*expr"); @@ -180,10 +177,7 @@ fn test_expr() { // 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 {}", - ); + assert_eq!(stringify_expr!(while let true = true {}), "while let true = true {}"); // ExprKind::ForLoop assert_eq!(stringify_expr!(for _ in x {}), "for _ in x {}"); @@ -328,14 +322,8 @@ fn test_expr() { 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}", - ); + 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]"); @@ -501,7 +489,10 @@ fn test_item() { ); assert_eq!( stringify_item!( - enum Enum<T> where T: 'a { + enum Enum<T> + where + T: 'a, + { Unit, Tuple(T), Struct { t: T }, @@ -660,10 +651,7 @@ fn test_pat() { // 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::<'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 { .. }"); @@ -682,10 +670,7 @@ fn test_pat() { 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()", - ); + assert_eq!(stringify_pat!(<Struct as Trait>::Type()), "<Struct as Trait>::Type()"); // PatKind::Or assert_eq!(stringify_pat!(true | false), "true | false"); @@ -696,10 +681,7 @@ fn test_pat() { 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", - ); + assert_eq!(stringify_pat!(<Struct as Trait>::Type), "<Struct as Trait>::Type"); // PatKind::Tuple assert_eq!(stringify_pat!(()), "()"); @@ -826,10 +808,7 @@ fn test_ty() { 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", - ); + assert_eq!(stringify_ty!(<Struct as Trait>::Type), "<Struct as Trait>::Type"); // TyKind::TraitObject assert_eq!(stringify_ty!(dyn Send), "dyn Send"); @@ -874,14 +853,8 @@ fn test_vis() { 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) ", - ); + 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. From 55fc986be72c0db77b65b0198ed5b26ac918ddad Mon Sep 17 00:00:00 2001 From: David Tolnay <dtolnay@gmail.com> Date: Thu, 23 Dec 2021 16:51:24 -0800 Subject: [PATCH 06/10] Fix tidy line length lint in stringify tests --- src/test/ui/macros/stringify.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs index 39aac34d45a4a..fcf6a9278d8fe 100644 --- a/src/test/ui/macros/stringify.rs +++ b/src/test/ui/macros/stringify.rs @@ -243,7 +243,9 @@ fn test_expr() { #![attr] } ), - "{\n #![attr]\n}", + "{\n\ + \x20 #![attr]\n\ + }", ); // ExprKind::Async @@ -498,7 +500,13 @@ fn test_item() { Struct { t: T }, } ), - "enum Enum<T> where T: 'a {\n Unit,\n Tuple(T),\n Struct {\n t: T,\n },\n}", + "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 @@ -535,7 +543,9 @@ fn test_item() { t: T, } ), - "struct Struct<T> where T: 'a {\n t: T,\n}", + "struct Struct<T> where T: 'a {\n\ + \x20 t: T,\n\ + }", ); // ItemKind::Union @@ -551,7 +561,9 @@ fn test_item() { t: T, } ), - "union Union<T> where T: 'a {\n t: T,\n}", + "union Union<T> where T: 'a {\n\ + \x20 t: T,\n\ + }", ); // ItemKind::Trait From 9702348957083e1104776edcf897ca1808364869 Mon Sep 17 00:00:00 2001 From: Smitty <me@smitop.com> Date: Mon, 27 Dec 2021 12:31:40 -0500 Subject: [PATCH 07/10] Clarify that repeat count must be positive --- compiler/rustc_builtin_macros/src/concat_bytes.rs | 2 +- src/test/ui/macros/concat-bytes-error.rs | 8 ++++---- src/test/ui/macros/concat-bytes-error.stderr | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index 87920e5175268..eb08170959bfb 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -154,7 +154,7 @@ pub fn expand_concat_bytes( } } } else { - cx.span_err(count.value.span, "repeat count is not a number"); + cx.span_err(count.value.span, "repeat count is not a positive number"); } } ast::ExprKind::Lit(ref lit) => match lit.kind { diff --git a/src/test/ui/macros/concat-bytes-error.rs b/src/test/ui/macros/concat-bytes-error.rs index 2c7997d5e5905..db5d3cab0bd8a 100644 --- a/src/test/ui/macros/concat-bytes-error.rs +++ b/src/test/ui/macros/concat-bytes-error.rs @@ -39,12 +39,12 @@ fn main() { ]); concat_bytes!(5u16); //~ ERROR cannot concatenate numeric literals concat_bytes!([5u16]); //~ ERROR numeric literal is not a `u8` - concat_bytes!([3; ()]); //~ ERROR repeat count is not a number - concat_bytes!([3; -2]); //~ ERROR repeat count is not a number - concat_bytes!([pie; -2]); //~ ERROR repeat count is not a number + concat_bytes!([3; ()]); //~ ERROR repeat count is not a positive number + concat_bytes!([3; -2]); //~ ERROR repeat count is not a positive number + concat_bytes!([pie; -2]); //~ ERROR repeat count is not a positive number concat_bytes!([pie; 2]); //~ ERROR expected a byte literal concat_bytes!([2.2; 0]); //~ ERROR cannot concatenate float literals - concat_bytes!([5.5; ()]); //~ ERROR repeat count is not a number + concat_bytes!([5.5; ()]); //~ ERROR repeat count is not a positive number concat_bytes!([[1, 2, 3]; 3]); //~ ERROR cannot concatenate doubly nested array concat_bytes!([[42; 2]; 3]); //~ ERROR cannot concatenate doubly nested array } diff --git a/src/test/ui/macros/concat-bytes-error.stderr b/src/test/ui/macros/concat-bytes-error.stderr index f0c53839b3ad5..d6cd1a3d178b0 100644 --- a/src/test/ui/macros/concat-bytes-error.stderr +++ b/src/test/ui/macros/concat-bytes-error.stderr @@ -127,19 +127,19 @@ error: numeric literal is not a `u8` LL | concat_bytes!([5u16]); | ^^^^ -error: repeat count is not a number +error: repeat count is not a positive number --> $DIR/concat-bytes-error.rs:42:23 | LL | concat_bytes!([3; ()]); | ^^ -error: repeat count is not a number +error: repeat count is not a positive number --> $DIR/concat-bytes-error.rs:43:23 | LL | concat_bytes!([3; -2]); | ^^ -error: repeat count is not a number +error: repeat count is not a positive number --> $DIR/concat-bytes-error.rs:44:25 | LL | concat_bytes!([pie; -2]); @@ -159,7 +159,7 @@ error: cannot concatenate float literals LL | concat_bytes!([2.2; 0]); | ^^^ -error: repeat count is not a number +error: repeat count is not a positive number --> $DIR/concat-bytes-error.rs:47:25 | LL | concat_bytes!([5.5; ()]); From 4361d9778b709512c6a9187e5998853787f3900d Mon Sep 17 00:00:00 2001 From: Wesley Wiser <wesleywiser@microsoft.com> Date: Mon, 27 Dec 2021 15:37:12 -0500 Subject: [PATCH 08/10] Add myself to .mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 9d82f8895dc1c..9366ef383fc6d 100644 --- a/.mailmap +++ b/.mailmap @@ -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> petrochenkov <vadim.petrochenkov@gmail.com> Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com> +Wesley Wiser <wwiser@gmail.com> <wesleywiser@microsoft.com> whitequark <whitequark@whitequark.org> William Ting <io@williamting.com> <william.h.ting@gmail.com> Xuefeng Wu <benewu@gmail.com> Xuefeng Wu <xfwu@thoughtworks.com> From 3115d8413af8599972c43a301514a0ad0d601c43 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie <ecstaticmorse@gmail.com> Date: Mon, 27 Dec 2021 15:35:01 -0800 Subject: [PATCH 09/10] Document units for `std::column` --- library/core/src/macros/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index b18508186a618..c648cdab13206 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1062,6 +1062,18 @@ pub(crate) mod builtin { /// let current_col = column!(); /// 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")] #[rustc_builtin_macro] #[macro_export] From 60c94031de44f9d56ca7a31e4083c7cfb78ba0a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= <lnicola@dend.ro> Date: Tue, 28 Dec 2021 09:44:21 +0200 Subject: [PATCH 10/10] :arrow_up: rust-analyzer --- src/tools/rust-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 0add6e95e5863..68319187d6370 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 0add6e95e58633fde2fff0bccaf6c7d71ebc130f +Subproject commit 68319187d63707fa36d7c215ed0e444e87d9652a