diff options
Diffstat (limited to 'src/tools/rustfmt/tests')
1430 files changed, 44861 insertions, 0 deletions
diff --git a/src/tools/rustfmt/tests/cargo-fmt/main.rs b/src/tools/rustfmt/tests/cargo-fmt/main.rs new file mode 100644 index 000000000..348876cd2 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/main.rs @@ -0,0 +1,98 @@ +// Integration tests for cargo-fmt. + +use std::env; +use std::path::Path; +use std::process::Command; + +/// Run the cargo-fmt executable and return its output. +fn cargo_fmt(args: &[&str]) -> (String, String) { + let mut bin_dir = env::current_exe().unwrap(); + bin_dir.pop(); // chop off test exe name + if bin_dir.ends_with("deps") { + bin_dir.pop(); + } + let cmd = bin_dir.join(format!("cargo-fmt{}", env::consts::EXE_SUFFIX)); + + // Ensure cargo-fmt runs the rustfmt binary from the local target dir. + let path = env::var_os("PATH").unwrap_or_default(); + let mut paths = env::split_paths(&path).collect::<Vec<_>>(); + paths.insert(0, bin_dir); + let new_path = env::join_paths(paths).unwrap(); + + match Command::new(&cmd).args(args).env("PATH", new_path).output() { + Ok(output) => ( + String::from_utf8(output.stdout).expect("utf-8"), + String::from_utf8(output.stderr).expect("utf-8"), + ), + Err(e) => panic!("failed to run `{:?} {:?}`: {}", cmd, args, e), + } +} + +macro_rules! assert_that { + ($args:expr, $check:ident $check_args:tt) => { + let (stdout, stderr) = cargo_fmt($args); + if !stdout.$check$check_args { + panic!( + "Output not expected for cargo-fmt {:?}\n\ + expected: {}{}\n\ + actual stdout:\n{}\n\ + actual stderr:\n{}", + $args, + stringify!($check), + stringify!($check_args), + stdout, + stderr + ); + } + }; +} + +#[ignore] +#[test] +fn version() { + assert_that!(&["--version"], starts_with("rustfmt ")); + assert_that!(&["--version"], starts_with("rustfmt ")); + assert_that!(&["--", "-V"], starts_with("rustfmt ")); + assert_that!(&["--", "--version"], starts_with("rustfmt ")); +} + +#[ignore] +#[test] +fn print_config() { + assert_that!( + &["--", "--print-config", "current", "."], + contains("max_width = ") + ); +} + +#[ignore] +#[test] +fn rustfmt_help() { + assert_that!(&["--", "--help"], contains("Format Rust code")); + assert_that!(&["--", "-h"], contains("Format Rust code")); + assert_that!(&["--", "--help=config"], contains("Configuration Options:")); +} + +#[ignore] +#[test] +fn cargo_fmt_out_of_line_test_modules() { + // See also https://github.com/rust-lang/rustfmt/issues/5119 + let expected_modified_files = [ + "tests/mod-resolver/test-submodule-issue-5119/src/lib.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs", + ]; + let args = [ + "-v", + "--check", + "--manifest-path", + "tests/mod-resolver/test-submodule-issue-5119/Cargo.toml", + ]; + let (stdout, _) = cargo_fmt(&args); + for file in expected_modified_files { + let path = Path::new(file).canonicalize().unwrap(); + assert!(stdout.contains(&format!("Diff in {}", path.display()))) + } +} diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml new file mode 100644 index 000000000..315364a64 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "cargo-fmt-test" +version = "0.1.0" +authors = ["calebcartwright"] +edition = "2018" + +[dependencies] +indexmap = "1.0.2" + +[workspace] +members = [ + "dependency-dir-name", +]
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml new file mode 100644 index 000000000..4493882bf --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "dependency-crate-name" +version = "0.1.0" +authors = ["calebcartwright"] +edition = "2018" + +[dependencies] +subdep-crate-name = { path = "subdep-dir-name" } +indexmap = "1.0.2" +rusty-hook = "0.8.4"
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs new file mode 100644 index 000000000..e93b18d72 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { +#[test] +fn it_works() { + assert_eq!(2 + 2, 4); +} +} diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml new file mode 100644 index 000000000..7dad09f40 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "subdep-crate-name" +version = "0.1.0" +authors = ["calebcartwright"] +edition = "2018" + +[dependencies] diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs new file mode 100644 index 000000000..1c08c1c4f --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { +#[test] +fn sub_test_that_works() { + assert_eq!(3 + 3, 6); +} + } diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs new file mode 100644 index 000000000..f5c339a8d --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs @@ -0,0 +1,3 @@ +fn main() { +println!("Hello, world!"); +} diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml new file mode 100644 index 000000000..eaf1d76f9 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "e" +version = "0.1.0" +edition = "2018" +[dependencies] +c = { path = "../ws/c" } + +[workspace] diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs new file mode 100644 index 000000000..1c26a3895 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs @@ -0,0 +1 @@ +struct E{ } diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml new file mode 100644 index 000000000..202739b61 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] +members = [ + "a", + "b" +]
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml new file mode 100644 index 000000000..712a11344 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "a" +version = "0.1.0" +edition = "2018" +[dependencies] +d = { path = "./d" } diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml new file mode 100644 index 000000000..fb0f06fe5 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "d" +version = "0.1.0" +edition = "2018" +[dependencies] +e = { path = "../../../e" } +f = { path = "f" } diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml new file mode 100644 index 000000000..5c4fa5617 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "f" +version = "0.1.0" +edition = "2018" diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs new file mode 100644 index 000000000..c655c4d5e --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs @@ -0,0 +1 @@ +struct F{ }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs new file mode 100644 index 000000000..04e6e4cb9 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs @@ -0,0 +1 @@ +struct D{ }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs new file mode 100644 index 000000000..04e6e4cb9 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs @@ -0,0 +1 @@ +struct D{ }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml new file mode 100644 index 000000000..47a24ff4f --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "b" +version = "0.1.0" +edition = "2018" +[dependencies] +c = { path = "../c" } diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs new file mode 100644 index 000000000..4833bbc69 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs @@ -0,0 +1 @@ +struct B{ }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml new file mode 100644 index 000000000..49fa6c395 --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "c" +version = "0.1.0" +edition = "2018" diff --git a/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs new file mode 100644 index 000000000..1245ac91d --- /dev/null +++ b/src/tools/rustfmt/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs @@ -0,0 +1 @@ +struct C{ }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/config/disable_all_formatting.toml b/src/tools/rustfmt/tests/config/disable_all_formatting.toml new file mode 100644 index 000000000..c7ad93baf --- /dev/null +++ b/src/tools/rustfmt/tests/config/disable_all_formatting.toml @@ -0,0 +1 @@ +disable_all_formatting = true diff --git a/src/tools/rustfmt/tests/config/issue-1111.toml b/src/tools/rustfmt/tests/config/issue-1111.toml new file mode 100644 index 000000000..44148a2d3 --- /dev/null +++ b/src/tools/rustfmt/tests/config/issue-1111.toml @@ -0,0 +1 @@ +reorder_imports = true diff --git a/src/tools/rustfmt/tests/config/issue-2641.toml b/src/tools/rustfmt/tests/config/issue-2641.toml new file mode 100644 index 000000000..11c9dca8a --- /dev/null +++ b/src/tools/rustfmt/tests/config/issue-2641.toml @@ -0,0 +1 @@ +newline_style = "Windows" diff --git a/src/tools/rustfmt/tests/config/issue-3779.toml b/src/tools/rustfmt/tests/config/issue-3779.toml new file mode 100644 index 000000000..6ca52aee3 --- /dev/null +++ b/src/tools/rustfmt/tests/config/issue-3779.toml @@ -0,0 +1,3 @@ +ignore = [ + "tests/**/issue-3779/ice.rs" +] diff --git a/src/tools/rustfmt/tests/config/skip_children.toml b/src/tools/rustfmt/tests/config/skip_children.toml new file mode 100644 index 000000000..f52930d50 --- /dev/null +++ b/src/tools/rustfmt/tests/config/skip_children.toml @@ -0,0 +1 @@ +skip_children = true diff --git a/src/tools/rustfmt/tests/config/small_tabs.toml b/src/tools/rustfmt/tests/config/small_tabs.toml new file mode 100644 index 000000000..c3cfd3431 --- /dev/null +++ b/src/tools/rustfmt/tests/config/small_tabs.toml @@ -0,0 +1,10 @@ +max_width = 100 +comment_width = 80 +tab_spaces = 2 +newline_style = "Unix" +brace_style = "SameLineWhere" +fn_args_layout = "Tall" +trailing_comma = "Vertical" +indent_style = "Block" +reorder_imports = false +format_strings = true diff --git a/src/tools/rustfmt/tests/coverage/source/comments.rs b/src/tools/rustfmt/tests/coverage/source/comments.rs new file mode 100644 index 000000000..10940039e --- /dev/null +++ b/src/tools/rustfmt/tests/coverage/source/comments.rs @@ -0,0 +1,7 @@ +// rustfmt-emit_mode: coverage +/// Here's a doc comment! +fn main() { + // foo is bar + let foo = "bar"; + // loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong comment!!!!! +} diff --git a/src/tools/rustfmt/tests/coverage/target/comments.rs b/src/tools/rustfmt/tests/coverage/target/comments.rs new file mode 100644 index 000000000..95e7b4705 --- /dev/null +++ b/src/tools/rustfmt/tests/coverage/target/comments.rs @@ -0,0 +1,7 @@ +XX XXXXXXXXXXXXXXXXXX XXXXXXXX +/// Here's a doc comment! +fn main() { + XX XXX XX XXX + let foo = "bar"; + XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXX +} diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-4874/bar/baz.rs b/src/tools/rustfmt/tests/mod-resolver/issue-4874/bar/baz.rs new file mode 100644 index 000000000..d31b675ea --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-4874/bar/baz.rs @@ -0,0 +1,5 @@ +fn + fail_fmt_check + ( + + ) {}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-4874/foo.rs b/src/tools/rustfmt/tests/mod-resolver/issue-4874/foo.rs new file mode 100644 index 000000000..246d84786 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-4874/foo.rs @@ -0,0 +1 @@ +mod qux;
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-4874/foo/qux.rs b/src/tools/rustfmt/tests/mod-resolver/issue-4874/foo/qux.rs new file mode 100644 index 000000000..d8bb610a6 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-4874/foo/qux.rs @@ -0,0 +1,5 @@ + fn + badly_formatted + ( + + ) {}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-4874/main.rs b/src/tools/rustfmt/tests/mod-resolver/issue-4874/main.rs new file mode 100644 index 000000000..3609415b1 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-4874/main.rs @@ -0,0 +1,8 @@ +fn main() { + println!("Hello, world!"); +} + +mod foo; +mod bar { + mod baz; +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo.rs new file mode 100644 index 000000000..d56974773 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo.rs @@ -0,0 +1,2 @@ +mod bar { + mod baz;}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo/bar/baz.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo/bar/baz.rs new file mode 100644 index 000000000..3519b0ee5 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo/bar/baz.rs @@ -0,0 +1 @@ +fn baz() { }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5063/main.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5063/main.rs new file mode 100644 index 000000000..41c81c7bb --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5063/main.rs @@ -0,0 +1,5 @@ +fn main() { + println!("Hello, world!"); +} + +mod foo;
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5167/src/a.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5167/src/a.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5167/src/a.rs diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5167/src/a/mod.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5167/src/a/mod.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5167/src/a/mod.rs diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5167/src/lib.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5167/src/lib.rs new file mode 100644 index 000000000..f21af614d --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5167/src/lib.rs @@ -0,0 +1 @@ +mod a; diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/a.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5198/a.rs new file mode 100644 index 000000000..cd686f561 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/a.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib.rs new file mode 100644 index 000000000..696832913 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib.rs @@ -0,0 +1,3 @@ +mod a; +mod b; +mod c; diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/b.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/b.rs new file mode 100644 index 000000000..cd686f561 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/b.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d.rs new file mode 100644 index 000000000..d1604aa23 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d.rs @@ -0,0 +1,3 @@ +mod e; +mod f; +mod g; diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt new file mode 100644 index 000000000..92c9e3021 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt @@ -0,0 +1,16 @@ +This file is contained in the './lib/c/d/' directory. + +The directory name './lib/c/d/' conflicts with the './lib/c/d.rs' file name. + +'./lib/c/d.rs' defines 3 external modules: + + * mod e; + * mod f; + * mod g; + +Module resolution will fail if we look for './lib/c/d/e.rs' or './lib/c/d/e/mod.rs', +so we should fall back to looking for './lib/c/e.rs', which correctly finds the modlue, that +rustfmt should format. + +'./lib/c/d/f.rs' and './lib/c/d/g/mod.rs' exist at the default submodule paths so we should be able +to resolve these modules with no problems.
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d/f.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d/f.rs new file mode 100644 index 000000000..cd686f561 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d/f.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d/g/mod.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d/g/mod.rs new file mode 100644 index 000000000..cd686f561 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/d/g/mod.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/e.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/e.rs new file mode 100644 index 000000000..cd686f561 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/e.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/mod.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/mod.rs new file mode 100644 index 000000000..819046196 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/c/mod.rs @@ -0,0 +1,3 @@ +mod d; + +fn main( ) { println!("Hello World!") } diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/explanation.txt b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/explanation.txt new file mode 100644 index 000000000..d436a8076 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/issue-5198/lib/explanation.txt @@ -0,0 +1,16 @@ +This file is contained in the './lib' directory. + +The directory name './lib' conflicts with the './lib.rs' file name. + +'lib.rs' defines 3 external modules: + + * mod a; + * mod b; + * mod c; + +Module resolution will fail if we look for './lib/a.rs' or './lib/a/mod.rs', +so we should fall back to looking for './a.rs', which correctly finds the modlue that +rustfmt should format. + +'./lib/b.rs' and './lib/c/mod.rs' exist at the default submodule paths so we should be able +to resolve these modules with no problems. diff --git a/src/tools/rustfmt/tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs b/src/tools/rustfmt/tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs new file mode 100644 index 000000000..2a63c961b --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs @@ -0,0 +1,3 @@ +// module resolution fails because the path does not exist. +#[path = "path/to/does_not_exist.rs"] +mod a; diff --git a/src/tools/rustfmt/tests/mod-resolver/module-not-found/relative_module/a.rs b/src/tools/rustfmt/tests/mod-resolver/module-not-found/relative_module/a.rs new file mode 100644 index 000000000..4a1eac896 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/module-not-found/relative_module/a.rs @@ -0,0 +1,2 @@ +// module resolution fails because `./a/b.rs` does not exist +mod b; diff --git a/src/tools/rustfmt/tests/mod-resolver/module-not-found/relative_module/lib.rs b/src/tools/rustfmt/tests/mod-resolver/module-not-found/relative_module/lib.rs new file mode 100644 index 000000000..f21af614d --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/module-not-found/relative_module/lib.rs @@ -0,0 +1 @@ +mod a; diff --git a/src/tools/rustfmt/tests/mod-resolver/module-not-found/sibling_module/lib.rs b/src/tools/rustfmt/tests/mod-resolver/module-not-found/sibling_module/lib.rs new file mode 100644 index 000000000..d9d9e1e3c --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/module-not-found/sibling_module/lib.rs @@ -0,0 +1,2 @@ +// module resolution fails because `./a.rs` does not exist +mod a; diff --git a/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/foo.rs b/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/foo.rs new file mode 100644 index 000000000..74889acf0 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/foo.rs @@ -0,0 +1,5 @@ +#![rustfmt::skip] + +mod bar { + + mod baz;}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs b/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs new file mode 100644 index 000000000..3519b0ee5 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs @@ -0,0 +1 @@ +fn baz() { }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/main.rs b/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/main.rs new file mode 100644 index 000000000..3122e4f22 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/main.rs @@ -0,0 +1,9 @@ +#![rustfmt::skip] + +mod foo; +mod one; + +fn main() {println!("Hello, world!"); +} + +// trailing commet diff --git a/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/one.rs b/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/one.rs new file mode 100644 index 000000000..e7eb2c2d6 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/skip-files-issue-5065/one.rs @@ -0,0 +1 @@ +struct One { value: String }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/Cargo.toml b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/Cargo.toml new file mode 100644 index 000000000..0993f1279 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rustfmt-test-submodule-issue" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/src/lib.rs b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/src/lib.rs new file mode 100644 index 000000000..3f7ddba8a --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/src/lib.rs @@ -0,0 +1,7 @@ +pub fn foo() -> i32 { +3 +} + +pub fn bar() -> i32 { +4 +} diff --git a/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs new file mode 100644 index 000000000..da4e86169 --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs @@ -0,0 +1,8 @@ +mod test1 { +#[cfg(unix)] +mod sub1; +#[cfg(not(unix))] +mod sub2; + +mod sub3; +} diff --git a/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs new file mode 100644 index 000000000..b760ba23c --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs @@ -0,0 +1,6 @@ +use rustfmt_test_submodule_issue::foo; + +#[test] +fn test_foo() { +assert_eq!(3, foo()); +} diff --git a/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs new file mode 100644 index 000000000..4fd8286ea --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs @@ -0,0 +1,6 @@ +use rustfmt_test_submodule_issue::bar; + +#[test] +fn test_bar() { +assert_eq!(4, bar()); +} diff --git a/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/mod.rs b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/mod.rs new file mode 100644 index 000000000..e029785bc --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/mod.rs @@ -0,0 +1 @@ +mod sub4; diff --git a/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/rustfmt/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs diff --git a/src/tools/rustfmt/tests/parser/issue-4126/invalid.rs b/src/tools/rustfmt/tests/parser/issue-4126/invalid.rs new file mode 100644 index 000000000..7709c8484 --- /dev/null +++ b/src/tools/rustfmt/tests/parser/issue-4126/invalid.rs @@ -0,0 +1,6 @@ +fn foo() { + if bar && if !baz { + next_is_none = Some(true); + } + println!("foo"); +} diff --git a/src/tools/rustfmt/tests/parser/issue-4126/lib.rs b/src/tools/rustfmt/tests/parser/issue-4126/lib.rs new file mode 100644 index 000000000..aac63e355 --- /dev/null +++ b/src/tools/rustfmt/tests/parser/issue-4126/lib.rs @@ -0,0 +1 @@ +mod invalid; diff --git a/src/tools/rustfmt/tests/parser/issue_4418.rs b/src/tools/rustfmt/tests/parser/issue_4418.rs new file mode 100644 index 000000000..ff30235f0 --- /dev/null +++ b/src/tools/rustfmt/tests/parser/issue_4418.rs @@ -0,0 +1 @@ +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs b/src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs new file mode 100644 index 000000000..2c2c81c91 --- /dev/null +++ b/src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs @@ -0,0 +1,11 @@ +fn main() { + if true { + println!("answer: {}", a_func(); + } else { + println!("don't think so."); + } +} + +fn a_func() -> i32 { + 42 +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/rustfmt/main.rs b/src/tools/rustfmt/tests/rustfmt/main.rs new file mode 100644 index 000000000..4c6d52726 --- /dev/null +++ b/src/tools/rustfmt/tests/rustfmt/main.rs @@ -0,0 +1,159 @@ +//! Integration tests for rustfmt. + +use std::env; +use std::fs::remove_file; +use std::path::Path; +use std::process::Command; + +/// Run the rustfmt executable and return its output. +fn rustfmt(args: &[&str]) -> (String, String) { + let mut bin_dir = env::current_exe().unwrap(); + bin_dir.pop(); // chop off test exe name + if bin_dir.ends_with("deps") { + bin_dir.pop(); + } + let cmd = bin_dir.join(format!("rustfmt{}", env::consts::EXE_SUFFIX)); + + // Ensure the rustfmt binary runs from the local target dir. + let path = env::var_os("PATH").unwrap_or_default(); + let mut paths = env::split_paths(&path).collect::<Vec<_>>(); + paths.insert(0, bin_dir); + let new_path = env::join_paths(paths).unwrap(); + + match Command::new(&cmd).args(args).env("PATH", new_path).output() { + Ok(output) => ( + String::from_utf8(output.stdout).expect("utf-8"), + String::from_utf8(output.stderr).expect("utf-8"), + ), + Err(e) => panic!("failed to run `{:?} {:?}`: {}", cmd, args, e), + } +} + +macro_rules! assert_that { + ($args:expr, $($check:ident $check_args:tt)&&+) => { + let (stdout, stderr) = rustfmt($args); + if $(!stdout.$check$check_args && !stderr.$check$check_args)||* { + panic!( + "Output not expected for rustfmt {:?}\n\ + expected: {}\n\ + actual stdout:\n{}\n\ + actual stderr:\n{}", + $args, + stringify!($( $check$check_args )&&*), + stdout, + stderr + ); + } + }; +} + +#[ignore] +#[test] +fn print_config() { + assert_that!( + &["--print-config", "unknown"], + starts_with("Unknown print-config option") + ); + assert_that!(&["--print-config", "default"], contains("max_width = 100")); + assert_that!(&["--print-config", "minimal"], contains("PATH required")); + assert_that!( + &["--print-config", "minimal", "minimal-config"], + contains("doesn't work with standard input.") + ); + + let (stdout, stderr) = rustfmt(&[ + "--print-config", + "minimal", + "minimal-config", + "src/shape.rs", + ]); + assert!( + Path::new("minimal-config").exists(), + "stdout:\n{}\nstderr:\n{}", + stdout, + stderr + ); + remove_file("minimal-config").unwrap(); +} + +#[ignore] +#[test] +fn inline_config() { + // single invocation + assert_that!( + &[ + "--print-config", + "current", + ".", + "--config=color=Never,edition=2018" + ], + contains("color = \"Never\"") && contains("edition = \"2018\"") + ); + + // multiple overriding invocations + assert_that!( + &[ + "--print-config", + "current", + ".", + "--config", + "color=never,edition=2018", + "--config", + "color=always,format_strings=true" + ], + contains("color = \"Always\"") + && contains("edition = \"2018\"") + && contains("format_strings = true") + ); +} + +#[test] +fn rustfmt_usage_text() { + let args = ["--help"]; + let (stdout, _) = rustfmt(&args); + assert!(stdout.contains("Format Rust code\n\nusage: rustfmt [options] <file>...")); +} + +#[test] +fn mod_resolution_error_multiple_candidate_files() { + // See also https://github.com/rust-lang/rustfmt/issues/5167 + let default_path = Path::new("tests/mod-resolver/issue-5167/src/a.rs"); + let secondary_path = Path::new("tests/mod-resolver/issue-5167/src/a/mod.rs"); + let error_message = format!( + "file for module found at both {:?} and {:?}", + default_path.canonicalize().unwrap(), + secondary_path.canonicalize().unwrap(), + ); + + let args = ["tests/mod-resolver/issue-5167/src/lib.rs"]; + let (_stdout, stderr) = rustfmt(&args); + assert!(stderr.contains(&error_message)) +} + +#[test] +fn mod_resolution_error_sibling_module_not_found() { + let args = ["tests/mod-resolver/module-not-found/sibling_module/lib.rs"]; + let (_stdout, stderr) = rustfmt(&args); + // Module resolution fails because we're unable to find `a.rs` in the same directory as lib.rs + assert!(stderr.contains("a.rs does not exist")) +} + +#[test] +fn mod_resolution_error_relative_module_not_found() { + let args = ["tests/mod-resolver/module-not-found/relative_module/lib.rs"]; + let (_stdout, stderr) = rustfmt(&args); + // The file `./a.rs` and directory `./a` both exist. + // Module resolution fails because we're unable to find `./a/b.rs` + #[cfg(not(windows))] + assert!(stderr.contains("a/b.rs does not exist")); + #[cfg(windows)] + assert!(stderr.contains("a\\b.rs does not exist")); +} + +#[test] +fn mod_resolution_error_path_attribute_does_not_exist() { + let args = ["tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs"]; + let (_stdout, stderr) = rustfmt(&args); + // The path attribute points to a file that does not exist + assert!(stderr.contains("does_not_exist.rs does not exist")); +} diff --git a/src/tools/rustfmt/tests/source/5131_crate.rs b/src/tools/rustfmt/tests/source/5131_crate.rs new file mode 100644 index 000000000..96a316590 --- /dev/null +++ b/src/tools/rustfmt/tests/source/5131_crate.rs @@ -0,0 +1,14 @@ +// rustfmt-imports_granularity: Crate + +use foo::a; +use foo::a; +use foo::b; +use foo::b as b2; +use foo::b::f; +use foo::b::g; +use foo::b::g as g2; +use foo::c; +use foo::d::e; +use qux::h; +use qux::h as h2; +use qux::i; diff --git a/src/tools/rustfmt/tests/source/5131_module.rs b/src/tools/rustfmt/tests/source/5131_module.rs new file mode 100644 index 000000000..3e9139177 --- /dev/null +++ b/src/tools/rustfmt/tests/source/5131_module.rs @@ -0,0 +1,33 @@ +// rustfmt-imports_granularity: Module + +#![allow(dead_code)] + +mod a { + pub mod b { + pub struct Data { + pub a: i32, + } + } + + use crate::a::b::Data; + use crate::a::b::Data as Data2; + + pub fn data(a: i32) -> Data { + Data { a } + } + + pub fn data2(a: i32) -> Data2 { + Data2 { a } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + pub fn test() { + data(1); + data2(1); + } + } +} diff --git a/src/tools/rustfmt/tests/source/5131_one.rs b/src/tools/rustfmt/tests/source/5131_one.rs new file mode 100644 index 000000000..61ddf1341 --- /dev/null +++ b/src/tools/rustfmt/tests/source/5131_one.rs @@ -0,0 +1,15 @@ +// rustfmt-imports_granularity: One + +pub use foo::x; +pub use foo::x as x2; +pub use foo::y; +use bar::a; +use bar::b; +use bar::b::f; +use bar::b::f as f2; +use bar::b::g; +use bar::c; +use bar::d::e; +use bar::d::e as e2; +use qux::h; +use qux::i; diff --git a/src/tools/rustfmt/tests/source/alignment_2633/block_style.rs b/src/tools/rustfmt/tests/source/alignment_2633/block_style.rs new file mode 100644 index 000000000..77fb2919e --- /dev/null +++ b/src/tools/rustfmt/tests/source/alignment_2633/block_style.rs @@ -0,0 +1,8 @@ +// rustfmt-struct_field_align_threshold: 50 + +fn func() { + Ok(ServerInformation { name: unwrap_message_string(items.get(0)), + vendor: unwrap_message_string(items.get(1)), + version: unwrap_message_string(items.get(2)), + spec_version: unwrap_message_string(items.get(3)), }); +} diff --git a/src/tools/rustfmt/tests/source/alignment_2633/visual_style.rs b/src/tools/rustfmt/tests/source/alignment_2633/visual_style.rs new file mode 100644 index 000000000..f34cc621e --- /dev/null +++ b/src/tools/rustfmt/tests/source/alignment_2633/visual_style.rs @@ -0,0 +1,9 @@ +// rustfmt-struct_field_align_threshold: 50 +// rustfmt-indent_style: Visual + +fn func() { + Ok(ServerInformation { name: unwrap_message_string(items.get(0)), + vendor: unwrap_message_string(items.get(1)), + version: unwrap_message_string(items.get(2)), + spec_version: unwrap_message_string(items.get(3)), }); +} diff --git a/src/tools/rustfmt/tests/source/array_comment.rs b/src/tools/rustfmt/tests/source/array_comment.rs new file mode 100644 index 000000000..87372b279 --- /dev/null +++ b/src/tools/rustfmt/tests/source/array_comment.rs @@ -0,0 +1,19 @@ +// Issue 2842 +// The comment should not make the last line shorter + +static XXX: [i8; 64] = [ + 1, // Comment + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +]; + +static XXX: [i8; 64] = [ + 1, + // Comment + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +]; + +static XXX: [i8; 64] = [ + 1, + // Comment + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +]; diff --git a/src/tools/rustfmt/tests/source/assignment.rs b/src/tools/rustfmt/tests/source/assignment.rs new file mode 100644 index 000000000..71de32556 --- /dev/null +++ b/src/tools/rustfmt/tests/source/assignment.rs @@ -0,0 +1,34 @@ +// Test assignment + +fn main() { + let some_var : Type ; + + let mut mutable; + + let variable = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA::BBBBBBBBBBBBBBBBBBBBBB::CCCCCCCCCCCCCCCCCCCCCC::EEEEEE; + + variable = LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG; + + let single_line_fit = + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD; + + single_line_fit = 5;single_lit_fit >>= 10; + + + // #2791 + let x = 2;;;; +} + +fn break_meee() { + { + (block_start, block_size, margin_block_start, margin_block_end) = match (block_start, + block_end, + block_size) { + x => 1, + _ => 2, + }; + } +} + +// #2018 +pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str = "Unsized tuple coercion is not stable enough for use and is subject to change"; diff --git a/src/tools/rustfmt/tests/source/associated-types-bounds-wrapping.rs b/src/tools/rustfmt/tests/source/associated-types-bounds-wrapping.rs new file mode 100644 index 000000000..464f428c7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/associated-types-bounds-wrapping.rs @@ -0,0 +1,5 @@ +// Test proper wrapping of long associated type bounds + +pub trait HttpService { + type WsService: 'static + Service<Request = WsCommand, Response = WsResponse, Error = ServerError>; +} diff --git a/src/tools/rustfmt/tests/source/associated_type_bounds.rs b/src/tools/rustfmt/tests/source/associated_type_bounds.rs new file mode 100644 index 000000000..8572778a5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/associated_type_bounds.rs @@ -0,0 +1,13 @@ +// See #3657 - https://github.com/rust-lang/rustfmt/issues/3657 + +#![feature(associated_type_bounds)] + +fn f<I: Iterator<Item: Clone>>() {} + +fn g<I: Iterator<Item : Clone>>() {} + +fn h<I: Iterator<Item : Clone>>() {} + +fn i<I: Iterator<Item:Clone>>() {} + +fn j<I: Iterator<Item : Clone+'a>>() {} diff --git a/src/tools/rustfmt/tests/source/async_block.rs b/src/tools/rustfmt/tests/source/async_block.rs new file mode 100644 index 000000000..18cb4fb5f --- /dev/null +++ b/src/tools/rustfmt/tests/source/async_block.rs @@ -0,0 +1,51 @@ +// rustfmt-edition: 2018 + +fn main() { + let x = async { + Ok(()) + }; +} + +fn baz() { + // test + let x = async { + // async blocks are great + Ok(()) + }; + + let y = async { + Ok(()) + }; // comment + + spawn( + a, + async move { + action(); + Ok(()) + }, + ); + + spawn( + a, + async move || { + action(); + Ok(()) + }, + ); + + spawn( + a, + static async || { + action(); + Ok(()) + }, + ); + + spawn( + a, + static async move || { + action(); + Ok(()) + }, + ); +} diff --git a/src/tools/rustfmt/tests/source/async_fn.rs b/src/tools/rustfmt/tests/source/async_fn.rs new file mode 100644 index 000000000..c63cf5b0f --- /dev/null +++ b/src/tools/rustfmt/tests/source/async_fn.rs @@ -0,0 +1,28 @@ +// rustfmt-edition: 2018 + +async fn bar() -> Result<(), ()> { + Ok(()) +} + +pub async fn baz() -> Result<(), ()> { + Ok(()) +} + +async unsafe fn foo() { + async move { + Ok(()) + } +} + +async unsafe fn rust() { + async move { // comment + Ok(()) + } +} + +async fn await_try() { + something + .await + ? + ; +} diff --git a/src/tools/rustfmt/tests/source/attrib.rs b/src/tools/rustfmt/tests/source/attrib.rs new file mode 100644 index 000000000..d45fba552 --- /dev/null +++ b/src/tools/rustfmt/tests/source/attrib.rs @@ -0,0 +1,234 @@ +// rustfmt-wrap_comments: true +// Test attributes and doc comments are preserved. +#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))] + +//! Doc comment + +#![attribute] + +//! Crate doc comment + +// Comment + +// Comment on attribute +#![the(attribute)] + +// Another comment + +/// Blah blah blah. +/// Blah blah blah. +/// Blah blah blah. +/// Blah blah blah. + +/// Blah blah blah. +impl Bar { + /// Blah blah blooo. + /// Blah blah blooo. + /// Blah blah blooo. + /// Blah blah blooo. + #[an_attribute] + #[doc = "an attribute that shouldn't be normalized to a doc comment"] + fn foo(&mut self) -> isize { + } + + /// Blah blah bing. + /// Blah blah bing. + /// Blah blah bing. + + + /// Blah blah bing. + /// Blah blah bing. + /// Blah blah bing. + pub fn f2(self) { + (foo, bar) + } + + #[another_attribute] + fn f3(self) -> Dog { + } + + /// Blah blah bing. + + #[attrib1] + /// Blah blah bing. + #[attrib2] + // Another comment that needs rewrite because it's tooooooooooooooooooooooooooooooo loooooooooooong. + /// Blah blah bing. + fn f4(self) -> Cat { + } + + // We want spaces around `=` + #[cfg(feature="nightly")] + fn f5(self) -> Monkey {} +} + +// #984 +struct Foo { + # [ derive ( Clone , PartialEq , Debug , Deserialize , Serialize ) ] + foo: usize, +} + +// #1668 + +/// Default path (*nix) +#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))] +fn foo() { + #[cfg(target_os = "freertos")] + match port_id { + 'a' | 'A' => GpioPort { port_address: GPIO_A }, + 'b' | 'B' => GpioPort { port_address: GPIO_B }, + _ => panic!(), + } + + #[cfg_attr(not(target_os = "freertos"), allow(unused_variables))] + let x = 3; +} + +// #1777 +#[test] +#[should_panic(expected = "(")] +#[should_panic(expected = /* ( */ "(")] +#[should_panic(/* ((((( */expected /* ((((( */= /* ((((( */ "("/* ((((( */)] +#[should_panic( + /* (((((((( *//* + (((((((((()(((((((( */ + expected = "(" + // (((((((( +)] +fn foo() {} + +// #1799 +fn issue_1799() { + #[allow(unreachable_code)] // https://github.com/rust-lang/rust/issues/43336 + Some( Err(error) ) ; + + #[allow(unreachable_code)] + // https://github.com/rust-lang/rust/issues/43336 + Some( Err(error) ) ; +} + +// Formatting inner attributes +fn inner_attributes() { + #![ this_is_an_inner_attribute ( foo ) ] + + foo(); +} + +impl InnerAttributes() { + #![ this_is_an_inner_attribute ( foo ) ] + + fn foo() {} +} + +mod InnerAttributes { + #![ this_is_an_inner_attribute ( foo ) ] +} + +fn attributes_on_statements() { + // Local + # [ attr ( on ( local ) ) ] + let x = 3; + + // Item + # [ attr ( on ( item ) ) ] + use foo; + + // Expr + # [ attr ( on ( expr ) ) ] + {} + + // Semi + # [ attr ( on ( semi ) ) ] + foo(); + + // Mac + # [ attr ( on ( mac ) ) ] + foo!(); +} + +// Large derives +#[derive(Add, Sub, Mul, Div, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Serialize, Mul)] + + +/// Foo bar baz + + +#[derive(Add, Sub, Mul, Div, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Serialize, Deserialize)] +pub struct HP(pub u8); + +// Long `#[doc = "..."]` +struct A { #[doc = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] b: i32 } + +// #2647 +#[cfg(feature = "this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")] +pub fn foo() {} + +// path attrs +#[clippy::bar] +#[clippy::bar(a, b, c)] +pub fn foo() {} + +mod issue_2620 { + #[derive(Debug, StructOpt)] +#[structopt(about = "Display information about the character on FF Logs")] +pub struct Params { + #[structopt(help = "The server the character is on")] + server: String, + #[structopt(help = "The character's first name")] + first_name: String, + #[structopt(help = "The character's last name")] + last_name: String, + #[structopt( + short = "j", + long = "job", + help = "The job to look at", + parse(try_from_str) + )] + job: Option<Job> +} +} + +// #2969 +#[cfg(not(all(feature="std", + any(target_os = "linux", target_os = "android", + target_os = "netbsd", + target_os = "dragonfly", + target_os = "haiku", + target_os = "emscripten", + target_os = "solaris", + target_os = "cloudabi", + target_os = "macos", target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "redox", + target_os = "fuchsia", + windows, + all(target_arch = "wasm32", feature = "stdweb"), + all(target_arch = "wasm32", feature = "wasm-bindgen"), + ))))] +type Os = NoSource; + +// #3313 +fn stmt_expr_attributes() { + let foo ; + #[must_use] + foo = false ; +} + +// #3509 +fn issue3509() { + match MyEnum { + MyEnum::Option1 if cfg!(target_os = "windows") => + #[cfg(target_os = "windows")]{ + 1 + } + } + match MyEnum { + MyEnum::Option1 if cfg!(target_os = "windows") => + #[cfg(target_os = "windows")] + 1, + } +} diff --git a/src/tools/rustfmt/tests/source/big-impl-block.rs b/src/tools/rustfmt/tests/source/big-impl-block.rs new file mode 100644 index 000000000..f71e6515c --- /dev/null +++ b/src/tools/rustfmt/tests/source/big-impl-block.rs @@ -0,0 +1,123 @@ +// #1357 +impl< + 'a, + Select, + From, + Distinct, + Where, + Order, + Limit, + Offset, + Groupby, + DB, +> InternalBoxedDsl<'a, DB> + for SelectStatement< + Select, + From, + Distinct, + Where, + Order, + Limit, + Offset, + GroupBy, + > where + DB: Backend, + Select: QueryFragment<DB> + SelectableExpression<From> + 'a, + Distinct: QueryFragment<DB> + 'a, + Where: Into<Option<Box<QueryFragment<DB> + 'a>>>, + Order: QueryFragment<DB> + 'a, + Limit: QueryFragment<DB> + 'a, + Offset: QueryFragment<DB> + 'a, +{ + type Output = BoxedSelectStatement<'a, Select::SqlTypeForSelect, From, DB>; + + fn internal_into_boxed(self) -> Self::Output { + BoxedSelectStatement::new( + Box::new(self.select), + self.from, + Box::new(self.distinct), + self.where_clause.into(), + Box::new(self.order), + Box::new(self.limit), + Box::new(self.offset), + ) + } +} + +// #1369 +impl< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> Foo for Bar { + fn foo() {} +} +impl Foo< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> for Bar { + fn foo() {} +} +impl< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> Foo< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> for Bar { + fn foo() {} +} +impl< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> Foo for Bar< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> { + fn foo() {} +} +impl Foo< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> for Bar< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> { + fn foo() {} +} +impl< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> Foo< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> for Bar< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> { + fn foo() {} +} + +// #1689 +impl<M, S, F, X> SubSelectDirect<M, S, F, X> + where + M: select::Selector, + S: event::Stream, + F: for<'t> FnMut(transform::Api< + 't, + Stream<ContentStream<S>>, + >) + -> transform::Api<'t, X>, + X: event::Stream, +{ +} diff --git a/src/tools/rustfmt/tests/source/big-impl-visual.rs b/src/tools/rustfmt/tests/source/big-impl-visual.rs new file mode 100644 index 000000000..7d906ac37 --- /dev/null +++ b/src/tools/rustfmt/tests/source/big-impl-visual.rs @@ -0,0 +1,106 @@ +// rustfmt-indent_style: Visual + +// #1357 +impl< + 'a, + Select, + From, + Distinct, + Where, + Order, + Limit, + Offset, + Groupby, + DB, +> InternalBoxedDsl<'a, DB> + for SelectStatement< + Select, + From, + Distinct, + Where, + Order, + Limit, + Offset, + GroupBy, + > where + DB: Backend, + Select: QueryFragment<DB> + SelectableExpression<From> + 'a, + Distinct: QueryFragment<DB> + 'a, + Where: Into<Option<Box<QueryFragment<DB> + 'a>>>, + Order: QueryFragment<DB> + 'a, + Limit: QueryFragment<DB> + 'a, + Offset: QueryFragment<DB> + 'a, +{ + type Output = BoxedSelectStatement<'a, Select::SqlTypeForSelect, From, DB>; + + fn internal_into_boxed(self) -> Self::Output { + BoxedSelectStatement::new( + Box::new(self.select), + self.from, + Box::new(self.distinct), + self.where_clause.into(), + Box::new(self.order), + Box::new(self.limit), + Box::new(self.offset), + ) + } +} + +// #1369 +impl< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> Foo for Bar { + fn foo() {} +} +impl Foo< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> for Bar { + fn foo() {} +} +impl< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> Foo< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> for Bar { + fn foo() {} +} +impl< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> Foo for Bar< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> { + fn foo() {} +} +impl Foo< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> for Bar< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, +> { + fn foo() {} +} +impl<ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName> Foo<ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName> + for Bar<ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName> { + fn foo() {} +} diff --git a/src/tools/rustfmt/tests/source/binary-expr.rs b/src/tools/rustfmt/tests/source/binary-expr.rs new file mode 100644 index 000000000..f7502931d --- /dev/null +++ b/src/tools/rustfmt/tests/source/binary-expr.rs @@ -0,0 +1,10 @@ +// Binary expressions + +fn foo() { + // 100 + let x = aaaaaaaaaa || bbbbbbbbbb || cccccccccc || dddddddddd && eeeeeeeeee || ffffffffff || ggg; + // 101 + let x = aaaaaaaaaa || bbbbbbbbbb || cccccccccc || dddddddddd && eeeeeeeeee || ffffffffff || gggg; + // 104 + let x = aaaaaaaaaa || bbbbbbbbbb || cccccccccc || dddddddddd && eeeeeeeeee || ffffffffff || gggggggg; +} diff --git a/src/tools/rustfmt/tests/source/binop-separator-back/bitwise.rs b/src/tools/rustfmt/tests/source/binop-separator-back/bitwise.rs new file mode 100644 index 000000000..3804bf321 --- /dev/null +++ b/src/tools/rustfmt/tests/source/binop-separator-back/bitwise.rs @@ -0,0 +1,14 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ^ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ & abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ | abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ << abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ >> abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + +} diff --git a/src/tools/rustfmt/tests/source/binop-separator-back/comp.rs b/src/tools/rustfmt/tests/source/binop-separator-back/comp.rs new file mode 100644 index 000000000..50a271274 --- /dev/null +++ b/src/tools/rustfmt/tests/source/binop-separator-back/comp.rs @@ -0,0 +1,23 @@ +// rustfmt-binop_separator: Back + +fn main() { + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ < abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ <= abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ > abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ >= abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ == abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } +} diff --git a/src/tools/rustfmt/tests/source/binop-separator-back/logic.rs b/src/tools/rustfmt/tests/source/binop-separator-back/logic.rs new file mode 100644 index 000000000..8c297e5a6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/binop-separator-back/logic.rs @@ -0,0 +1,7 @@ +// rustfmt-binop_separator: Back + +fn main() { + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ && abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ || abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } +} diff --git a/src/tools/rustfmt/tests/source/binop-separator-back/math.rs b/src/tools/rustfmt/tests/source/binop-separator-back/math.rs new file mode 100644 index 000000000..3af4aad16 --- /dev/null +++ b/src/tools/rustfmt/tests/source/binop-separator-back/math.rs @@ -0,0 +1,7 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} diff --git a/src/tools/rustfmt/tests/source/binop-separator-back/patterns.rs b/src/tools/rustfmt/tests/source/binop-separator-back/patterns.rs new file mode 100644 index 000000000..a8c3b5cdd --- /dev/null +++ b/src/tools/rustfmt/tests/source/binop-separator-back/patterns.rs @@ -0,0 +1,9 @@ +// rustfmt-binop_separator: Back + +fn main() { + match val { + ThisIsA::ReallyLongPatternNameToHelpOverflowTheNextValueOntoTheNextLine | ThisIsA::SecondValueSeparatedByAPipe | ThisIsA::ThirdValueSeparatedByAPipe => { + // + } + } +} diff --git a/src/tools/rustfmt/tests/source/binop-separator-back/range.rs b/src/tools/rustfmt/tests/source/binop-separator-back/range.rs new file mode 100644 index 000000000..bdd3de992 --- /dev/null +++ b/src/tools/rustfmt/tests/source/binop-separator-back/range.rs @@ -0,0 +1,7 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ..abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ..=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} diff --git a/src/tools/rustfmt/tests/source/break-and-continue.rs b/src/tools/rustfmt/tests/source/break-and-continue.rs new file mode 100644 index 000000000..c01d8a078 --- /dev/null +++ b/src/tools/rustfmt/tests/source/break-and-continue.rs @@ -0,0 +1,23 @@ +// break and continue formatting + +#![feature(loop_break_value)] + +fn main() { + 'a: loop { + break 'a; + } + + let mut done = false; + 'b: while !done { + done = true; + continue 'b; + } + + let x = loop { + break 5; + }; + + let x = 'c: loop { + break 'c 5; + }; +} diff --git a/src/tools/rustfmt/tests/source/catch.rs b/src/tools/rustfmt/tests/source/catch.rs new file mode 100644 index 000000000..541db1dc9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/catch.rs @@ -0,0 +1,28 @@ +// rustfmt-edition: 2018 +#![feature(try_blocks)] + +fn main() { + let x = try { + foo()? + }; + + let x = try /* Invisible comment */ { foo()? }; + + let x = try { + unsafe { foo()? } + }; + + let y = match (try { + foo()? + }) { + _ => (), + }; + + try { + foo()?; + }; + + try { + // Regular try block + }; +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/arch/aarch64.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/aarch64.rs new file mode 100644 index 000000000..ebae2bd28 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/aarch64.rs @@ -0,0 +1,106 @@ +//! Aarch64 run-time features. + +/// Checks if `aarch64` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal,stdsimd)] +macro_rules! is_aarch64_feature_detected { + ("neon") => { + // FIXME: this should be removed once we rename Aarch64 neon to asimd + cfg!(target_feature = "neon") || + $crate::detect::check_for($crate::detect::Feature::asimd) + }; + ("asimd") => { + cfg!(target_feature = "neon") || + $crate::detect::check_for($crate::detect::Feature::asimd) + }; + ("pmull") => { + cfg!(target_feature = "pmull") || + $crate::detect::check_for($crate::detect::Feature::pmull) + }; + ("fp") => { + cfg!(target_feature = "fp") || + $crate::detect::check_for($crate::detect::Feature::fp) + }; + ("fp16") => { + cfg!(target_feature = "fp16") || + $crate::detect::check_for($crate::detect::Feature::fp16) + }; + ("sve") => { + cfg!(target_feature = "sve") || + $crate::detect::check_for($crate::detect::Feature::sve) + }; + ("crc") => { + cfg!(target_feature = "crc") || + $crate::detect::check_for($crate::detect::Feature::crc) + }; + ("crypto") => { + cfg!(target_feature = "crypto") || + $crate::detect::check_for($crate::detect::Feature::crypto) + }; + ("lse") => { + cfg!(target_feature = "lse") || + $crate::detect::check_for($crate::detect::Feature::lse) + }; + ("rdm") => { + cfg!(target_feature = "rdm") || + $crate::detect::check_for($crate::detect::Feature::rdm) + }; + ("rcpc") => { + cfg!(target_feature = "rcpc") || + $crate::detect::check_for($crate::detect::Feature::rcpc) + }; + ("dotprod") => { + cfg!(target_feature = "dotprod") || + $crate::detect::check_for($crate::detect::Feature::dotprod) + }; + ("ras") => { + compile_error!("\"ras\" feature cannot be detected at run-time") + }; + ("v8.1a") => { + compile_error!("\"v8.1a\" feature cannot be detected at run-time") + }; + ("v8.2a") => { + compile_error!("\"v8.2a\" feature cannot be detected at run-time") + }; + ("v8.3a") => { + compile_error!("\"v8.3a\" feature cannot be detected at run-time") + }; + ($t:tt,) => { + is_aarch64_feature_detected!($t); + }; + ($t:tt) => { compile_error!(concat!("unknown aarch64 target feature: ", $t)) }; +} + +/// ARM Aarch64 CPU Feature enum. Each variant denotes a position in a bitset +/// for a particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// ARM Advanced SIMD (ASIMD) + asimd, + /// Polynomial Multiply + pmull, + /// Floating point support + fp, + /// Half-float support. + fp16, + /// Scalable Vector Extension (SVE) + sve, + /// CRC32 (Cyclic Redundancy Check) + crc, + /// Crypto: AES + PMULL + SHA1 + SHA2 + crypto, + /// Atomics (Large System Extension) + lse, + /// Rounding Double Multiply (ASIMDRDM) + rdm, + /// Release consistent Processor consistent (RcPc) + rcpc, + /// Vector Dot-Product (ASIMDDP) + dotprod, +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/arch/arm.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/arm.rs new file mode 100644 index 000000000..b2626bf29 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/arm.rs @@ -0,0 +1,39 @@ +//! Run-time feature detection on ARM Aarch32. + +/// Checks if `arm` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal,stdsimd)] +macro_rules! is_arm_feature_detected { + ("neon") => { + cfg!(target_feature = "neon") || + $crate::detect::check_for($crate::detect::Feature::neon) + }; + ("pmull") => { + cfg!(target_feature = "pmull") || + $crate::detect::check_for($crate::detect::Feature::pmull) + }; + ("v7") => { compile_error!("\"v7\" feature cannot be detected at run-time") }; + ("vfp2") => { compile_error!("\"vfp2\" feature cannot be detected at run-time") }; + ("vfp3") => { compile_error!("\"vfp3\" feature cannot be detected at run-time") }; + ("vfp4") => { compile_error!("\"vfp4\" feature cannot be detected at run-time") }; + ($t:tt,) => { + is_arm_feature_detected!($t); + }; + ($t:tt) => { compile_error!(concat!("unknown arm target feature: ", $t)) }; +} + +/// ARM CPU Feature enum. Each variant denotes a position in a bitset for a +/// particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// ARM Advanced SIMD (NEON) - Aarch32 + neon, + /// Polynomial Multiply + pmull, +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/arch/mips.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/mips.rs new file mode 100644 index 000000000..f4381b811 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/mips.rs @@ -0,0 +1,29 @@ +//! Run-time feature detection on MIPS. + +/// Checks if `mips` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal,stdsimd)] +macro_rules! is_mips_feature_detected { + ("msa") => { + cfg!(target_feature = "msa") || + $crate::detect::check_for($crate::detect::Feature::msa) + }; + ($t:tt,) => { + is_mips_feature_detected!($t); + }; + ($t:tt) => { compile_error!(concat!("unknown mips target feature: ", $t)) }; +} + +/// MIPS CPU Feature enum. Each variant denotes a position in a bitset for a +/// particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// MIPS SIMD Architecture (MSA) + msa, +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/arch/mips64.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/mips64.rs new file mode 100644 index 000000000..2663bc68b --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/mips64.rs @@ -0,0 +1,29 @@ +//! Run-time feature detection on MIPS64. + +/// Checks if `mips64` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal,stdsimd)] +macro_rules! is_mips64_feature_detected { + ("msa") => { + cfg!(target_feature = "msa") || + $crate::detect::check_for($crate::detect::Feature::msa) + }; + ($t:tt,) => { + is_mips64_feature_detected!($t); + }; + ($t:tt) => { compile_error!(concat!("unknown mips64 target feature: ", $t)) }; +} + +/// MIPS64 CPU Feature enum. Each variant denotes a position in a bitset +/// for a particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// MIPS SIMD Architecture (MSA) + msa, +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/arch/powerpc.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/powerpc.rs new file mode 100644 index 000000000..a342dc1aa --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/powerpc.rs @@ -0,0 +1,42 @@ +//! Run-time feature detection on PowerPC. + +/// Checks if `powerpc` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal,stdsimd)] +macro_rules! is_powerpc_feature_detected { + ("altivec") => { + cfg!(target_feature = "altivec") || + $crate::detect::check_for($crate::detect::Feature::altivec) + }; + ("vsx") => { + cfg!(target_feature = "vsx") || + $crate::detect::check_for($crate::detect::Feature::vsx) + }; + ("power8") => { + cfg!(target_feature = "power8") || + $crate::detect::check_for($crate::detect::Feature::power8) + }; + ($t:tt,) => { + is_powerpc_feature_detected!($t); + }; + ($t:tt) => { compile_error!(concat!("unknown powerpc target feature: ", $t)) }; +} + + +/// PowerPC CPU Feature enum. Each variant denotes a position in a bitset +/// for a particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// Altivec + altivec, + /// VSX + vsx, + /// Power8 + power8, +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/arch/powerpc64.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/powerpc64.rs new file mode 100644 index 000000000..2e82c5692 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/powerpc64.rs @@ -0,0 +1,42 @@ +//! Run-time feature detection on PowerPC64. + +/// Checks if `powerpc64` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal,stdsimd)] +macro_rules! is_powerpc64_feature_detected { + ("altivec") => { + cfg!(target_feature = "altivec") || + $crate::detect::check_for($crate::detect::Feature::altivec) + }; + ("vsx") => { + cfg!(target_feature = "vsx") || + $crate::detect::check_for($crate::detect::Feature::vsx) + }; + ("power8") => { + cfg!(target_feature = "power8") || + $crate::detect::check_for($crate::detect::Feature::power8) + }; + ($t:tt,) => { + is_powerpc64_feature_detected!($t); + }; + ($t:tt) => { compile_error!(concat!("unknown powerpc64 target feature: ", $t)) }; +} + + +/// PowerPC64 CPU Feature enum. Each variant denotes a position in a bitset +/// for a particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// Altivec + altivec, + /// VSX + vsx, + /// Power8 + power8, +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/arch/x86.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/x86.rs new file mode 100644 index 000000000..d26f4ee89 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/x86.rs @@ -0,0 +1,348 @@ +//! This module implements minimal run-time feature detection for x86. +//! +//! The features are detected using the `detect_features` function below. +//! This function uses the CPUID instruction to read the feature flags from the +//! CPU and encodes them in a `usize` where each bit position represents +//! whether a feature is available (bit is set) or unavailable (bit is cleared). +//! +//! The enum `Feature` is used to map bit positions to feature names, and the +//! the `__crate::detect::check_for!` macro is used to map string literals (e.g., +//! "avx") to these bit positions (e.g., `Feature::avx`). +//! +//! The run-time feature detection is performed by the +//! `__crate::detect::check_for(Feature) -> bool` function. On its first call, +//! this functions queries the CPU for the available features and stores them +//! in a global `AtomicUsize` variable. The query is performed by just checking +//! whether the feature bit in this global variable is set or cleared. + +/// A macro to test at *runtime* whether a CPU feature is available on +/// x86/x86-64 platforms. +/// +/// This macro is provided in the standard library and will detect at runtime +/// whether the specified CPU feature is detected. This does **not** resolve at +/// compile time unless the specified feature is already enabled for the entire +/// crate. Runtime detection currently relies mostly on the `cpuid` instruction. +/// +/// This macro only takes one argument which is a string literal of the feature +/// being tested for. The feature names supported are the lowercase versions of +/// the ones defined by Intel in [their documentation][docs]. +/// +/// ## Supported arguments +/// +/// This macro supports the same names that `#[target_feature]` supports. Unlike +/// `#[target_feature]`, however, this macro does not support names separated +/// with a comma. Instead testing for multiple features must be done through +/// separate macro invocations for now. +/// +/// Supported arguments are: +/// +/// * `"aes"` +/// * `"pclmulqdq"` +/// * `"rdrand"` +/// * `"rdseed"` +/// * `"tsc"` +/// * `"mmx"` +/// * `"sse"` +/// * `"sse2"` +/// * `"sse3"` +/// * `"ssse3"` +/// * `"sse4.1"` +/// * `"sse4.2"` +/// * `"sse4a"` +/// * `"sha"` +/// * `"avx"` +/// * `"avx2"` +/// * `"avx512f"` +/// * `"avx512cd"` +/// * `"avx512er"` +/// * `"avx512pf"` +/// * `"avx512bw"` +/// * `"avx512dq"` +/// * `"avx512vl"` +/// * `"avx512ifma"` +/// * `"avx512vbmi"` +/// * `"avx512vpopcntdq"` +/// * `"f16c"` +/// * `"fma"` +/// * `"bmi1"` +/// * `"bmi2"` +/// * `"abm"` +/// * `"lzcnt"` +/// * `"tbm"` +/// * `"popcnt"` +/// * `"fxsr"` +/// * `"xsave"` +/// * `"xsaveopt"` +/// * `"xsaves"` +/// * `"xsavec"` +/// * `"adx"` +/// * `"rtm"` +/// +/// [docs]: https://software.intel.com/sites/landingpage/IntrinsicsGuide +#[macro_export] +#[stable(feature = "simd_x86", since = "1.27.0")] +#[allow_internal_unstable(stdsimd_internal,stdsimd)] +macro_rules! is_x86_feature_detected { + ("aes") => { + cfg!(target_feature = "aes") || $crate::detect::check_for( + $crate::detect::Feature::aes) }; + ("pclmulqdq") => { + cfg!(target_feature = "pclmulqdq") || $crate::detect::check_for( + $crate::detect::Feature::pclmulqdq) }; + ("rdrand") => { + cfg!(target_feature = "rdrand") || $crate::detect::check_for( + $crate::detect::Feature::rdrand) }; + ("rdseed") => { + cfg!(target_feature = "rdseed") || $crate::detect::check_for( + $crate::detect::Feature::rdseed) }; + ("tsc") => { + cfg!(target_feature = "tsc") || $crate::detect::check_for( + $crate::detect::Feature::tsc) }; + ("mmx") => { + cfg!(target_feature = "mmx") || $crate::detect::check_for( + $crate::detect::Feature::mmx) }; + ("sse") => { + cfg!(target_feature = "sse") || $crate::detect::check_for( + $crate::detect::Feature::sse) }; + ("sse2") => { + cfg!(target_feature = "sse2") || $crate::detect::check_for( + $crate::detect::Feature::sse2) + }; + ("sse3") => { + cfg!(target_feature = "sse3") || $crate::detect::check_for( + $crate::detect::Feature::sse3) + }; + ("ssse3") => { + cfg!(target_feature = "ssse3") || $crate::detect::check_for( + $crate::detect::Feature::ssse3) + }; + ("sse4.1") => { + cfg!(target_feature = "sse4.1") || $crate::detect::check_for( + $crate::detect::Feature::sse4_1) + }; + ("sse4.2") => { + cfg!(target_feature = "sse4.2") || $crate::detect::check_for( + $crate::detect::Feature::sse4_2) + }; + ("sse4a") => { + cfg!(target_feature = "sse4a") || $crate::detect::check_for( + $crate::detect::Feature::sse4a) + }; + ("sha") => { + cfg!(target_feature = "sha") || $crate::detect::check_for( + $crate::detect::Feature::sha) + }; + ("avx") => { + cfg!(target_feature = "avx") || $crate::detect::check_for( + $crate::detect::Feature::avx) + }; + ("avx2") => { + cfg!(target_feature = "avx2") || $crate::detect::check_for( + $crate::detect::Feature::avx2) + }; + ("avx512f") => { + cfg!(target_feature = "avx512f") || $crate::detect::check_for( + $crate::detect::Feature::avx512f) + }; + ("avx512cd") => { + cfg!(target_feature = "avx512cd") || $crate::detect::check_for( + $crate::detect::Feature::avx512cd) + }; + ("avx512er") => { + cfg!(target_feature = "avx512er") || $crate::detect::check_for( + $crate::detect::Feature::avx512er) + }; + ("avx512pf") => { + cfg!(target_feature = "avx512pf") || $crate::detect::check_for( + $crate::detect::Feature::avx512pf) + }; + ("avx512bw") => { + cfg!(target_feature = "avx512bw") || $crate::detect::check_for( + $crate::detect::Feature::avx512bw) + }; + ("avx512dq") => { + cfg!(target_feature = "avx512dq") || $crate::detect::check_for( + $crate::detect::Feature::avx512dq) + }; + ("avx512vl") => { + cfg!(target_Feature = "avx512vl") || $crate::detect::check_for( + $crate::detect::Feature::avx512vl) + }; + ("avx512ifma") => { + cfg!(target_feature = "avx512ifma") || $crate::detect::check_for( + $crate::detect::Feature::avx512_ifma) + }; + ("avx512vbmi") => { + cfg!(target_feature = "avx512vbmi") || $crate::detect::check_for( + $crate::detect::Feature::avx512_vbmi) + }; + ("avx512vpopcntdq") => { + cfg!(target_feature = "avx512vpopcntdq") || $crate::detect::check_for( + $crate::detect::Feature::avx512_vpopcntdq) + }; + ("f16c") => { + cfg!(target_feature = "f16c") || $crate::detect::check_for( + $crate::detect::Feature::f16c) + }; + ("fma") => { + cfg!(target_feature = "fma") || $crate::detect::check_for( + $crate::detect::Feature::fma) + }; + ("bmi1") => { + cfg!(target_feature = "bmi1") || $crate::detect::check_for( + $crate::detect::Feature::bmi) + }; + ("bmi2") => { + cfg!(target_feature = "bmi2") || $crate::detect::check_for( + $crate::detect::Feature::bmi2) + }; + ("abm") => { + cfg!(target_feature = "abm") || $crate::detect::check_for( + $crate::detect::Feature::abm) + }; + ("lzcnt") => { + cfg!(target_feature = "lzcnt") || $crate::detect::check_for( + $crate::detect::Feature::abm) + }; + ("tbm") => { + cfg!(target_feature = "tbm") || $crate::detect::check_for( + $crate::detect::Feature::tbm) + }; + ("popcnt") => { + cfg!(target_feature = "popcnt") || $crate::detect::check_for( + $crate::detect::Feature::popcnt) + }; + ("fxsr") => { + cfg!(target_feature = "fxsr") || $crate::detect::check_for( + $crate::detect::Feature::fxsr) + }; + ("xsave") => { + cfg!(target_feature = "xsave") || $crate::detect::check_for( + $crate::detect::Feature::xsave) + }; + ("xsaveopt") => { + cfg!(target_feature = "xsaveopt") || $crate::detect::check_for( + $crate::detect::Feature::xsaveopt) + }; + ("xsaves") => { + cfg!(target_feature = "xsaves") || $crate::detect::check_for( + $crate::detect::Feature::xsaves) + }; + ("xsavec") => { + cfg!(target_feature = "xsavec") || $crate::detect::check_for( + $crate::detect::Feature::xsavec) + }; + ("cmpxchg16b") => { + cfg!(target_feature = "cmpxchg16b") || $crate::detect::check_for( + $crate::detect::Feature::cmpxchg16b) + }; + ("adx") => { + cfg!(target_feature = "adx") || $crate::detect::check_for( + $crate::detect::Feature::adx) + }; + ("rtm") => { + cfg!(target_feature = "rtm") || $crate::detect::check_for( + $crate::detect::Feature::rtm) + }; + ($t:tt,) => { + is_x86_feature_detected!($t); + }; + ($t:tt) => { + compile_error!(concat!("unknown target feature: ", $t)) + }; +} + +/// X86 CPU Feature enum. Each variant denotes a position in a bitset for a +/// particular feature. +/// +/// This is an unstable implementation detail subject to change. +#[allow(non_camel_case_types)] +#[repr(u8)] +#[doc(hidden)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// AES (Advanced Encryption Standard New Instructions AES-NI) + aes, + /// CLMUL (Carry-less Multiplication) + pclmulqdq, + /// RDRAND + rdrand, + /// RDSEED + rdseed, + /// TSC (Time Stamp Counter) + tsc, + /// MMX + mmx, + /// SSE (Streaming SIMD Extensions) + sse, + /// SSE2 (Streaming SIMD Extensions 2) + sse2, + /// SSE3 (Streaming SIMD Extensions 3) + sse3, + /// SSSE3 (Supplemental Streaming SIMD Extensions 3) + ssse3, + /// SSE4.1 (Streaming SIMD Extensions 4.1) + sse4_1, + /// SSE4.2 (Streaming SIMD Extensions 4.2) + sse4_2, + /// SSE4a (Streaming SIMD Extensions 4a) + sse4a, + /// SHA + sha, + /// AVX (Advanced Vector Extensions) + avx, + /// AVX2 (Advanced Vector Extensions 2) + avx2, + /// AVX-512 F (Foundation) + avx512f, + /// AVX-512 CD (Conflict Detection Instructions) + avx512cd, + /// AVX-512 ER (Exponential and Reciprocal Instructions) + avx512er, + /// AVX-512 PF (Prefetch Instructions) + avx512pf, + /// AVX-512 BW (Byte and Word Instructions) + avx512bw, + /// AVX-512 DQ (Doubleword and Quadword) + avx512dq, + /// AVX-512 VL (Vector Length Extensions) + avx512vl, + /// AVX-512 IFMA (Integer Fused Multiply Add) + avx512_ifma, + /// AVX-512 VBMI (Vector Byte Manipulation Instructions) + avx512_vbmi, + /// AVX-512 VPOPCNTDQ (Vector Population Count Doubleword and + /// Quadword) + avx512_vpopcntdq, + /// F16C (Conversions between IEEE-754 `binary16` and `binary32` formats) + f16c, + /// FMA (Fused Multiply Add) + fma, + /// BMI1 (Bit Manipulation Instructions 1) + bmi, + /// BMI1 (Bit Manipulation Instructions 2) + bmi2, + /// ABM (Advanced Bit Manipulation) on AMD / LZCNT (Leading Zero + /// Count) on Intel + abm, + /// TBM (Trailing Bit Manipulation) + tbm, + /// POPCNT (Population Count) + popcnt, + /// FXSR (Floating-point context fast save and restor) + fxsr, + /// XSAVE (Save Processor Extended States) + xsave, + /// XSAVEOPT (Save Processor Extended States Optimized) + xsaveopt, + /// XSAVES (Save Processor Extended States Supervisor) + xsaves, + /// XSAVEC (Save Processor Extended States Compacted) + xsavec, + /// CMPXCH16B, a 16-byte compare-and-swap instruction + cmpxchg16b, + /// ADX, Intel ADX (Multi-Precision Add-Carry Instruction Extensions) + adx, + /// RTM, Intel (Restricted Transactional Memory) + rtm, +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/bit.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/bit.rs new file mode 100644 index 000000000..578f0b16b --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/bit.rs @@ -0,0 +1,9 @@ +//! Bit manipulation utilities. + +/// Tests the `bit` of `x`. +#[allow(dead_code)] +#[inline] +pub(crate) fn test(x: usize, bit: u32) -> bool { + debug_assert!(bit < 32, "bit index out-of-bounds"); + x & (1 << bit) != 0 +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/cache.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/cache.rs new file mode 100644 index 000000000..92bc4b58d --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/cache.rs @@ -0,0 +1,164 @@ +//! Caches run-time feature detection so that it only needs to be computed +//! once. + +#![allow(dead_code)] // not used on all platforms + +use crate::sync::atomic::Ordering; + +#[cfg(target_pointer_width = "64")] +use crate::sync::atomic::AtomicU64; + +#[cfg(target_pointer_width = "32")] +use crate::sync::atomic::AtomicU32; + +/// Sets the `bit` of `x`. +#[inline] +const fn set_bit(x: u64, bit: u32) -> u64 { + x | 1 << bit +} + +/// Tests the `bit` of `x`. +#[inline] +const fn test_bit(x: u64, bit: u32) -> bool { + x & (1 << bit) != 0 +} + +/// Maximum number of features that can be cached. +const CACHE_CAPACITY: u32 = 63; + +/// This type is used to initialize the cache +#[derive(Copy, Clone)] +pub(crate) struct Initializer(u64); + +#[allow(clippy::use_self)] +impl Default for Initializer { + fn default() -> Self { + Initializer(0) + } +} + +impl Initializer { + /// Tests the `bit` of the cache. + #[allow(dead_code)] + #[inline] + pub(crate) fn test(self, bit: u32) -> bool { + // FIXME: this way of making sure that the cache is large enough is + // brittle. + debug_assert!( + bit < CACHE_CAPACITY, + "too many features, time to increase the cache size!" + ); + test_bit(self.0, bit) + } + + /// Sets the `bit` of the cache. + #[inline] + pub(crate) fn set(&mut self, bit: u32) { + // FIXME: this way of making sure that the cache is large enough is + // brittle. + debug_assert!( + bit < CACHE_CAPACITY, + "too many features, time to increase the cache size!" + ); + let v = self.0; + self.0 = set_bit(v, bit); + } +} + +/// This global variable is a cache of the features supported by the CPU. +static CACHE: Cache = Cache::uninitialized(); + +/// Feature cache with capacity for `CACHE_CAPACITY` features. +/// +/// Note: the last feature bit is used to represent an +/// uninitialized cache. +#[cfg(target_pointer_width = "64")] +struct Cache(AtomicU64); + +#[cfg(target_pointer_width = "64")] +#[allow(clippy::use_self)] +impl Cache { + /// Creates an uninitialized cache. + #[allow(clippy::declare_interior_mutable_const)] + const fn uninitialized() -> Self { + Cache(AtomicU64::new(u64::max_value())) + } + /// Is the cache uninitialized? + #[inline] + pub(crate) fn is_uninitialized(&self) -> bool { + self.0.load(Ordering::Relaxed) == u64::max_value() + } + + /// Is the `bit` in the cache set? + #[inline] + pub(crate) fn test(&self, bit: u32) -> bool { + test_bit(CACHE.0.load(Ordering::Relaxed), bit) + } + + /// Initializes the cache. + #[inline] + pub(crate) fn initialize(&self, value: Initializer) { + self.0.store(value.0, Ordering::Relaxed); + } +} + +/// Feature cache with capacity for `CACHE_CAPACITY` features. +/// +/// Note: the last feature bit is used to represent an +/// uninitialized cache. +#[cfg(target_pointer_width = "32")] +struct Cache(AtomicU32, AtomicU32); + +#[cfg(target_pointer_width = "32")] +impl Cache { + /// Creates an uninitialized cache. + const fn uninitialized() -> Self { + Cache( + AtomicU32::new(u32::max_value()), + AtomicU32::new(u32::max_value()), + ) + } + /// Is the cache uninitialized? + #[inline] + pub(crate) fn is_uninitialized(&self) -> bool { + self.1.load(Ordering::Relaxed) == u32::max_value() + } + + /// Is the `bit` in the cache set? + #[inline] + pub(crate) fn test(&self, bit: u32) -> bool { + if bit < 32 { + test_bit(CACHE.0.load(Ordering::Relaxed) as u64, bit) + } else { + test_bit(CACHE.1.load(Ordering::Relaxed) as u64, bit - 32) + } + } + + /// Initializes the cache. + #[inline] + pub(crate) fn initialize(&self, value: Initializer) { + let lo: u32 = value.0 as u32; + let hi: u32 = (value.0 >> 32) as u32; + self.0.store(lo, Ordering::Relaxed); + self.1.store(hi, Ordering::Relaxed); + } +} + +/// Tests the `bit` of the storage. If the storage has not been initialized, +/// initializes it with the result of `f()`. +/// +/// On its first invocation, it detects the CPU features and caches them in the +/// `CACHE` global variable as an `AtomicU64`. +/// +/// It uses the `Feature` variant to index into this variable as a bitset. If +/// the bit is set, the feature is enabled, and otherwise it is disabled. +#[inline] +pub(crate) fn test<F>(bit: u32, f: F) -> bool +where + F: FnOnce() -> Initializer, +{ + if CACHE.is_uninitialized() { + CACHE.initialize(f()); + } + CACHE.test(bit) +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/error_macros.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/error_macros.rs new file mode 100644 index 000000000..6769757ed --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/error_macros.rs @@ -0,0 +1,150 @@ +//! The `is_{target_arch}_feature_detected!` macro are only available on their +//! architecture. These macros provide a better error messages when the user +//! attempts to call them in a different architecture. + +/// Prevents compilation if `is_x86_feature_detected` is used somewhere +/// else than `x86` and `x86_64` targets. +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_x86_feature_detected { + ($t: tt) => { + compile_error!( + r#" + is_x86_feature_detected can only be used on x86 and x86_64 targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + if is_x86_feature_detected(...) { ... } + } + "# + ) + }; +} + +/// Prevents compilation if `is_arm_feature_detected` is used somewhere else +/// than `ARM` targets. +#[cfg(not(target_arch = "arm"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_arm_feature_detected { + ($t:tt) => { + compile_error!( + r#" + is_arm_feature_detected can only be used on ARM targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "arm")] { + if is_arm_feature_detected(...) { ... } + } + "# + ) + }; +} + +/// Prevents compilation if `is_aarch64_feature_detected` is used somewhere else +/// than `aarch64` targets. +#[cfg(not(target_arch = "aarch64"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_aarch64_feature_detected { + ($t: tt) => { + compile_error!( + r#" + is_aarch64_feature_detected can only be used on AArch64 targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "aarch64")] { + if is_aarch64_feature_detected(...) { ... } + } + "# + ) + }; +} + +/// Prevents compilation if `is_powerpc_feature_detected` is used somewhere else +/// than `PowerPC` targets. +#[cfg(not(target_arch = "powerpc"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_powerpc_feature_detected { + ($t:tt) => { + compile_error!( + r#" +is_powerpc_feature_detected can only be used on PowerPC targets. +You can prevent it from being used in other architectures by +guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "powerpc")] { + if is_powerpc_feature_detected(...) { ... } + } +"# + ) + }; +} + +/// Prevents compilation if `is_powerpc64_feature_detected` is used somewhere +/// else than `PowerPC64` targets. +#[cfg(not(target_arch = "powerpc64"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_powerpc64_feature_detected { + ($t:tt) => { + compile_error!( + r#" +is_powerpc64_feature_detected can only be used on PowerPC64 targets. +You can prevent it from being used in other architectures by +guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "powerpc64")] { + if is_powerpc64_feature_detected(...) { ... } + } +"# + ) + }; +} + +/// Prevents compilation if `is_mips_feature_detected` is used somewhere else +/// than `MIPS` targets. +#[cfg(not(target_arch = "mips"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_mips_feature_detected { + ($t:tt) => { + compile_error!( + r#" + is_mips_feature_detected can only be used on MIPS targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "mips")] { + if is_mips_feature_detected(...) { ... } + } + "# + ) + }; +} + +/// Prevents compilation if `is_mips64_feature_detected` is used somewhere else +/// than `MIPS64` targets. +#[cfg(not(target_arch = "mips64"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_mips64_feature_detected { + ($t:tt) => { + compile_error!( + r#" + is_mips64_feature_detected can only be used on MIPS64 targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "mips64")] { + if is_mips64_feature_detected(...) { ... } + } + "# + ) + }; +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/mod.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/mod.rs new file mode 100644 index 000000000..f446e88ee --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/mod.rs @@ -0,0 +1,85 @@ +//! This module implements run-time feature detection. +//! +//! The `is_{arch}_feature_detected!("feature-name")` macros take the name of a +//! feature as a string-literal, and return a boolean indicating whether the +//! feature is enabled at run-time or not. +//! +//! These macros do two things: +//! * map the string-literal into an integer stored as a `Feature` enum, +//! * call a `os::check_for(x: Feature)` function that returns `true` if the +//! feature is enabled. +//! +//! The `Feature` enums are also implemented in the `arch/{target_arch}.rs` +//! modules. +//! +//! The `check_for` functions are, in general, Operating System dependent. Most +//! architectures do not allow user-space programs to query the feature bits +//! due to security concerns (x86 is the big exception). These functions are +//! implemented in the `os/{target_os}.rs` modules. + +#[macro_use] +mod error_macros; + +cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + #[path = "arch/x86.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "arm")] { + #[path = "arch/arm.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "aarch64")] { + #[path = "arch/aarch64.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "powerpc")] { + #[path = "arch/powerpc.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "powerpc64")] { + #[path = "arch/powerpc64.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "mips")] { + #[path = "arch/mips.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "mips64")] { + #[path = "arch/mips64.rs"] + #[macro_use] + mod arch; + } else { + // Unimplemented architecture: + mod arch { + pub enum Feature { + Null + } + } + } +} +pub use self::arch::Feature; + +mod bit; +mod cache; + +cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + // On x86/x86_64 no OS specific functionality is required. + #[path = "os/x86.rs"] + mod os; + } else if #[cfg(all(target_os = "linux", feature = "use_std"))] { + #[path = "os/linux/mod.rs"] + mod os; + } else if #[cfg(target_os = "freebsd")] { + #[cfg(target_arch = "aarch64")] + #[path = "os/aarch64.rs"] + mod aarch64; + #[path = "os/freebsd/mod.rs"] + mod os; + } else { + #[path = "os/other.rs"] + mod os; + } +} +pub use self::os::check_for; diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/aarch64.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/aarch64.rs new file mode 100644 index 000000000..dfb8c8770 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/aarch64.rs @@ -0,0 +1,79 @@ +//! Run-time feature detection for Aarch64 on any OS that emulates the mrs instruction. +//! +//! On FreeBSD >= 12.0, Linux >= 4.11 and other operating systems, it is possible to use +//! privileged system registers from userspace to check CPU feature support. +//! +//! AArch64 system registers ID_AA64ISAR0_EL1, ID_AA64PFR0_EL1, ID_AA64ISAR1_EL1 +//! have bits dedicated to features like AdvSIMD, CRC32, AES, atomics (LSE), etc. +//! Each part of the register indicates the level of support for a certain feature, e.g. +//! when ID_AA64ISAR0_EL1\[7:4\] is >= 1, AES is supported; when it's >= 2, PMULL is supported. +//! +//! For proper support of [SoCs where different cores have different capabilities](https://medium.com/@jadr2ddude/a-big-little-problem-a-tale-of-big-little-gone-wrong-e7778ce744bb), +//! the OS has to always report only the features supported by all cores, like [FreeBSD does](https://reviews.freebsd.org/D17137#393947). +//! +//! References: +//! +//! - [Zircon implementation](https://fuchsia.googlesource.com/zircon/+/master/kernel/arch/arm64/feature.cpp) +//! - [Linux documentation](https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt) + +use crate::detect::{Feature, cache}; + +/// Try to read the features from the system registers. +/// +/// This will cause SIGILL if the current OS is not trapping the mrs instruction. +pub(crate) fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + + { + let mut enable_feature = |f, enable| { + if enable { + value.set(f as u32); + } + }; + + // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0 + let aa64isar0: u64; + unsafe { asm!("mrs $0, ID_AA64ISAR0_EL1" : "=r"(aa64isar0)); } + + let aes = bits_shift(aa64isar0, 7, 4) >= 1; + let pmull = bits_shift(aa64isar0, 7, 4) >= 2; + let sha1 = bits_shift(aa64isar0, 11, 8) >= 1; + let sha2 = bits_shift(aa64isar0, 15, 12) >= 1; + enable_feature(Feature::pmull, pmull); + // Crypto is specified as AES + PMULL + SHA1 + SHA2 per LLVM/hosts.cpp + enable_feature(Feature::crypto, aes && pmull && sha1 && sha2); + enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 1); + enable_feature(Feature::crc, bits_shift(aa64isar0, 19, 16) >= 1); + + // ID_AA64PFR0_EL1 - Processor Feature Register 0 + let aa64pfr0: u64; + unsafe { asm!("mrs $0, ID_AA64PFR0_EL1" : "=r"(aa64pfr0)); } + + let fp = bits_shift(aa64pfr0, 19, 16) < 0xF; + let fphp = bits_shift(aa64pfr0, 19, 16) >= 1; + let asimd = bits_shift(aa64pfr0, 23, 20) < 0xF; + let asimdhp = bits_shift(aa64pfr0, 23, 20) >= 1; + enable_feature(Feature::fp, fp); + enable_feature(Feature::fp16, fphp); + // SIMD support requires float support - if half-floats are + // supported, it also requires half-float support: + enable_feature(Feature::asimd, fp && asimd && (!fphp | asimdhp)); + // SIMD extensions require SIMD support: + enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1); + enable_feature(Feature::dotprod, asimd && bits_shift(aa64isar0, 47, 44) >= 1); + enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1); + + // ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1 + let aa64isar1: u64; + unsafe { asm!("mrs $0, ID_AA64ISAR1_EL1" : "=r"(aa64isar1)); } + + enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1); + } + + value +} + +#[inline] +fn bits_shift(x: u64, high: usize, low: usize) -> u64 { + (x >> low) & ((1 << (high - low + 1)) - 1) +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/aarch64.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/aarch64.rs new file mode 100644 index 000000000..910d2f33b --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/aarch64.rs @@ -0,0 +1,28 @@ +//! Run-time feature detection for Aarch64 on FreeBSD. + +use crate::detect::{Feature, cache}; +use super::super::aarch64::detect_features; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +#[cfg(test)] +mod tests { + #[test] + fn dump() { + println!("asimd: {:?}", is_aarch64_feature_detected!("asimd")); + println!("pmull: {:?}", is_aarch64_feature_detected!("pmull")); + println!("fp: {:?}", is_aarch64_feature_detected!("fp")); + println!("fp16: {:?}", is_aarch64_feature_detected!("fp16")); + println!("sve: {:?}", is_aarch64_feature_detected!("sve")); + println!("crc: {:?}", is_aarch64_feature_detected!("crc")); + println!("crypto: {:?}", is_aarch64_feature_detected!("crypto")); + println!("lse: {:?}", is_aarch64_feature_detected!("lse")); + println!("rdm: {:?}", is_aarch64_feature_detected!("rdm")); + println!("rcpc: {:?}", is_aarch64_feature_detected!("rcpc")); + println!("dotprod: {:?}", is_aarch64_feature_detected!("dotprod")); + } +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/arm.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/arm.rs new file mode 100644 index 000000000..e13847dcb --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/arm.rs @@ -0,0 +1,27 @@ +//! Run-time feature detection for ARM on FreeBSD + +use crate::detect::{Feature, cache}; +use super::{auxvec}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + if let Ok(auxv) = auxvec::auxv() { + enable_feature(&mut value, Feature::neon, auxv.hwcap & 0x00001000 != 0); + enable_feature(&mut value, Feature::pmull, auxv.hwcap2 & 0x00000002 != 0); + return value; + } + value +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/auxvec.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/auxvec.rs new file mode 100644 index 000000000..a2bac7676 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/auxvec.rs @@ -0,0 +1,86 @@ +//! Parses ELF auxiliary vectors. +#![cfg_attr(any(target_arch = "arm", target_arch = "powerpc64"), allow(dead_code))] + +/// Key to access the CPU Hardware capabilities bitfield. +pub(crate) const AT_HWCAP: usize = 25; +/// Key to access the CPU Hardware capabilities 2 bitfield. +pub(crate) const AT_HWCAP2: usize = 26; + +/// Cache HWCAP bitfields of the ELF Auxiliary Vector. +/// +/// If an entry cannot be read all the bits in the bitfield are set to zero. +/// This should be interpreted as all the features being disabled. +#[derive(Debug, Copy, Clone)] +pub(crate) struct AuxVec { + pub hwcap: usize, + pub hwcap2: usize, +} + +/// ELF Auxiliary Vector +/// +/// The auxiliary vector is a memory region in a running ELF program's stack +/// composed of (key: usize, value: usize) pairs. +/// +/// The keys used in the aux vector are platform dependent. For FreeBSD, they are +/// defined in [sys/elf_common.h][elf_common_h]. The hardware capabilities of a given +/// CPU can be queried with the `AT_HWCAP` and `AT_HWCAP2` keys. +/// +/// Note that run-time feature detection is not invoked for features that can +/// be detected at compile-time. +/// +/// [elf_common.h]: https://svnweb.freebsd.org/base/release/12.0.0/sys/sys/elf_common.h?revision=341707 +pub(crate) fn auxv() -> Result<AuxVec, ()> { + if let Ok(hwcap) = archauxv(AT_HWCAP) { + if let Ok(hwcap2) = archauxv(AT_HWCAP2) { + if hwcap != 0 && hwcap2 != 0 { + return Ok(AuxVec { hwcap, hwcap2 }); + } + } + } + Err(()) +} + +/// Tries to read the `key` from the auxiliary vector. +fn archauxv(key: usize) -> Result<usize, ()> { + use crate::mem; + + #[derive (Copy, Clone)] + #[repr(C)] + pub struct Elf_Auxinfo { + pub a_type: usize, + pub a_un: unnamed, + } + #[derive (Copy, Clone)] + #[repr(C)] + pub union unnamed { + pub a_val: libc::c_long, + pub a_ptr: *mut libc::c_void, + pub a_fcn: Option<unsafe extern "C" fn() -> ()>, + } + + let mut auxv: [Elf_Auxinfo; 27] = + [Elf_Auxinfo{a_type: 0, a_un: unnamed{a_val: 0,},}; 27]; + + let mut len: libc::c_uint = mem::size_of_val(&auxv) as libc::c_uint; + + unsafe { + let mut mib = [libc::CTL_KERN, libc::KERN_PROC, libc::KERN_PROC_AUXV, libc::getpid()]; + + let ret = libc::sysctl(mib.as_mut_ptr(), + mib.len() as u32, + &mut auxv as *mut _ as *mut _, + &mut len as *mut _ as *mut _, + 0 as *mut libc::c_void, + 0, + ); + + if ret != -1 { + for i in 0..auxv.len() { + if auxv[i].a_type == key { + return Ok(auxv[i].a_un.a_val as usize); + } + } + } + } + return Ok(0); +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/mod.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/mod.rs new file mode 100644 index 000000000..1a5338a35 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/mod.rs @@ -0,0 +1,22 @@ +//! Run-time feature detection on FreeBSD + +mod auxvec; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::check_for; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::check_for; + } else if #[cfg(target_arch = "powerpc64")] { + mod powerpc; + pub use self::powerpc::check_for; + } else { + use crate::arch::detect::Feature; + /// Performs run-time feature detection. + pub fn check_for(_x: Feature) -> bool { + false + } + } +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/powerpc.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/powerpc.rs new file mode 100644 index 000000000..c7f761d4d --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/freebsd/powerpc.rs @@ -0,0 +1,27 @@ +//! Run-time feature detection for PowerPC on FreeBSD. + +use crate::detect::{Feature, cache}; +use super::{auxvec}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + if let Ok(auxv) = auxvec::auxv() { + enable_feature(&mut value, Feature::altivec, auxv.hwcap & 0x10000000 != 0); + enable_feature(&mut value, Feature::vsx, auxv.hwcap & 0x00000080 != 0); + enable_feature(&mut value, Feature::power8, auxv.hwcap2 & 0x80000000 != 0); + return value; + } + value +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/aarch64.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/aarch64.rs new file mode 100644 index 000000000..f7dc0f022 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/aarch64.rs @@ -0,0 +1,157 @@ +//! Run-time feature detection for Aarch64 on Linux. + +use crate::detect::{Feature, cache, bit}; +use super::{auxvec, cpuinfo}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector, and if that fails, try +/// to read them from /proc/cpuinfo. +fn detect_features() -> cache::Initializer { + if let Ok(auxv) = auxvec::auxv() { + let hwcap: AtHwcap = auxv.into(); + return hwcap.cache(); + } + if let Ok(c) = cpuinfo::CpuInfo::new() { + let hwcap: AtHwcap = c.into(); + return hwcap.cache(); + } + cache::Initializer::default() +} + +/// These values are part of the platform-specific [asm/hwcap.h][hwcap] . +/// +/// [hwcap]: https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h +struct AtHwcap { + fp: bool, // 0 + asimd: bool, // 1 + // evtstrm: bool, // 2 + aes: bool, // 3 + pmull: bool, // 4 + sha1: bool, // 5 + sha2: bool, // 6 + crc32: bool, // 7 + atomics: bool, // 8 + fphp: bool, // 9 + asimdhp: bool, // 10 + // cpuid: bool, // 11 + asimdrdm: bool, // 12 + // jscvt: bool, // 13 + // fcma: bool, // 14 + lrcpc: bool, // 15 + // dcpop: bool, // 16 + // sha3: bool, // 17 + // sm3: bool, // 18 + // sm4: bool, // 19 + asimddp: bool, // 20 + // sha512: bool, // 21 + sve: bool, // 22 +} + +impl From<auxvec::AuxVec> for AtHwcap { + /// Reads AtHwcap from the auxiliary vector. + fn from(auxv: auxvec::AuxVec) -> Self { + AtHwcap { + fp: bit::test(auxv.hwcap, 0), + asimd: bit::test(auxv.hwcap, 1), + // evtstrm: bit::test(auxv.hwcap, 2), + aes: bit::test(auxv.hwcap, 3), + pmull: bit::test(auxv.hwcap, 4), + sha1: bit::test(auxv.hwcap, 5), + sha2: bit::test(auxv.hwcap, 6), + crc32: bit::test(auxv.hwcap, 7), + atomics: bit::test(auxv.hwcap, 8), + fphp: bit::test(auxv.hwcap, 9), + asimdhp: bit::test(auxv.hwcap, 10), + // cpuid: bit::test(auxv.hwcap, 11), + asimdrdm: bit::test(auxv.hwcap, 12), + // jscvt: bit::test(auxv.hwcap, 13), + // fcma: bit::test(auxv.hwcap, 14), + lrcpc: bit::test(auxv.hwcap, 15), + // dcpop: bit::test(auxv.hwcap, 16), + // sha3: bit::test(auxv.hwcap, 17), + // sm3: bit::test(auxv.hwcap, 18), + // sm4: bit::test(auxv.hwcap, 19), + asimddp: bit::test(auxv.hwcap, 20), + // sha512: bit::test(auxv.hwcap, 21), + sve: bit::test(auxv.hwcap, 22), + } + } +} + +impl From<cpuinfo::CpuInfo> for AtHwcap { + /// Reads AtHwcap from /proc/cpuinfo . + fn from(c: cpuinfo::CpuInfo) -> Self { + let f = &c.field("Features"); + AtHwcap { + // 64-bit names. FIXME: In 32-bit compatibility mode /proc/cpuinfo will + // map some of the 64-bit names to some 32-bit feature names. This does not + // cover that yet. + fp: f.has("fp"), + asimd: f.has("asimd"), + // evtstrm: f.has("evtstrm"), + aes: f.has("aes"), + pmull: f.has("pmull"), + sha1: f.has("sha1"), + sha2: f.has("sha2"), + crc32: f.has("crc32"), + atomics: f.has("atomics"), + fphp: f.has("fphp"), + asimdhp: f.has("asimdhp"), + // cpuid: f.has("cpuid"), + asimdrdm: f.has("asimdrdm"), + // jscvt: f.has("jscvt"), + // fcma: f.has("fcma"), + lrcpc: f.has("lrcpc"), + // dcpop: f.has("dcpop"), + // sha3: f.has("sha3"), + // sm3: f.has("sm3"), + // sm4: f.has("sm4"), + asimddp: f.has("asimddp"), + // sha512: f.has("sha512"), + sve: f.has("sve"), + } + } +} + +impl AtHwcap { + /// Initializes the cache from the feature -bits. + /// + /// The features are enabled approximately like in LLVM host feature detection: + /// https://github.com/llvm-mirror/llvm/blob/master/lib/Support/Host.cpp#L1273 + fn cache(self) -> cache::Initializer { + let mut value = cache::Initializer::default(); + { + let mut enable_feature = |f, enable| { + if enable { + value.set(f as u32); + } + }; + + enable_feature(Feature::fp, self.fp); + // Half-float support requires float support + enable_feature(Feature::fp16, self.fp && self.fphp); + enable_feature(Feature::pmull, self.pmull); + enable_feature(Feature::crc, self.crc32); + enable_feature(Feature::lse, self.atomics); + enable_feature(Feature::rcpc, self.lrcpc); + + // SIMD support requires float support - if half-floats are + // supported, it also requires half-float support: + let asimd = self.fp && self.asimd && (!self.fphp | self.asimdhp); + enable_feature(Feature::asimd, asimd); + // SIMD extensions require SIMD support: + enable_feature(Feature::rdm, self.asimdrdm && asimd); + enable_feature(Feature::dotprod, self.asimddp && asimd); + enable_feature(Feature::sve, self.sve && asimd); + + // Crypto is specified as AES + PMULL + SHA1 + SHA2 per LLVM/hosts.cpp + enable_feature(Feature::crypto, self.aes && self.pmull && self.sha1 && self.sha2); + } + value + } +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/arm.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/arm.rs new file mode 100644 index 000000000..0d58a847c --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/arm.rs @@ -0,0 +1,49 @@ +//! Run-time feature detection for ARM on Linux. + +use crate::detect::{Feature, cache, bit}; +use super::{auxvec, cpuinfo}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector, and if that fails, try +/// to read them from /proc/cpuinfo. +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + // The values are part of the platform-specific [asm/hwcap.h][hwcap] + // + // [hwcap]: https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h + if let Ok(auxv) = auxvec::auxv() { + enable_feature(&mut value, Feature::neon, bit::test(auxv.hwcap, 12)); + enable_feature(&mut value, Feature::pmull, bit::test(auxv.hwcap2, 1)); + return value; + } + + if let Ok(c) = cpuinfo::CpuInfo::new() { + enable_feature(&mut value, Feature::neon, c.field("Features").has("neon") && + !has_broken_neon(&c)); + enable_feature(&mut value, Feature::pmull, c.field("Features").has("pmull")); + return value; + } + value +} + +/// Is the CPU known to have a broken NEON unit? +/// +/// See https://crbug.com/341598. +fn has_broken_neon(cpuinfo: &cpuinfo::CpuInfo) -> bool { + cpuinfo.field("CPU implementer") == "0x51" + && cpuinfo.field("CPU architecture") == "7" + && cpuinfo.field("CPU variant") == "0x1" + && cpuinfo.field("CPU part") == "0x04d" + && cpuinfo.field("CPU revision") == "0" +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/auxvec.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/auxvec.rs new file mode 100644 index 000000000..07b6432ea --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/auxvec.rs @@ -0,0 +1,307 @@ +//! Parses ELF auxiliary vectors. +#![cfg_attr(not(target_arch = "aarch64"), allow(dead_code))] + +#[cfg(feature = "std_detect_file_io")] +use crate::{fs::File, io::Read}; + +/// Key to access the CPU Hardware capabilities bitfield. +pub(crate) const AT_HWCAP: usize = 16; +/// Key to access the CPU Hardware capabilities 2 bitfield. +#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] +pub(crate) const AT_HWCAP2: usize = 26; + +/// Cache HWCAP bitfields of the ELF Auxiliary Vector. +/// +/// If an entry cannot be read all the bits in the bitfield are set to zero. +/// This should be interpreted as all the features being disabled. +#[derive(Debug, Copy, Clone)] +pub(crate) struct AuxVec { + pub hwcap: usize, + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + pub hwcap2: usize, +} + +/// ELF Auxiliary Vector +/// +/// The auxiliary vector is a memory region in a running ELF program's stack +/// composed of (key: usize, value: usize) pairs. +/// +/// The keys used in the aux vector are platform dependent. For Linux, they are +/// defined in [linux/auxvec.h][auxvec_h]. The hardware capabilities of a given +/// CPU can be queried with the `AT_HWCAP` and `AT_HWCAP2` keys. +/// +/// There is no perfect way of reading the auxiliary vector. +/// +/// - If the `std_detect_dlsym_getauxval` cargo feature is enabled, this will use +/// `getauxval` if its linked to the binary, and otherwise proceed to a fallback implementation. +/// When `std_detect_dlsym_getauxval` is disabled, this will assume that `getauxval` is +/// linked to the binary - if that is not the case the behavior is undefined. +/// - Otherwise, if the `std_detect_file_io` cargo feature is enabled, it will +/// try to read `/proc/self/auxv`. +/// - If that fails, this function returns an error. +/// +/// Note that run-time feature detection is not invoked for features that can +/// be detected at compile-time. Also note that if this function returns an +/// error, cpuinfo still can (and will) be used to try to perform run-time +/// feature detecton on some platforms. +/// +/// For more information about when `getauxval` is available check the great +/// [`auxv` crate documentation][auxv_docs]. +/// +/// [auxvec_h]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/auxvec.h +/// [auxv_docs]: https://docs.rs/auxv/0.3.3/auxv/ +pub(crate) fn auxv() -> Result<AuxVec, ()> { + #[cfg(feature = "std_detect_dlsym_getauxval")] { + // Try to call a dynamically-linked getauxval function. + if let Ok(hwcap) = getauxval(AT_HWCAP) { + // Targets with only AT_HWCAP: + #[cfg(any(target_arch = "aarch64", target_arch = "mips", + target_arch = "mips64"))] + { + if hwcap != 0 { + return Ok(AuxVec { hwcap }); + } + } + + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + if let Ok(hwcap2) = getauxval(AT_HWCAP2) { + if hwcap != 0 && hwcap2 != 0 { + return Ok(AuxVec { hwcap, hwcap2 }); + } + } + } + drop(hwcap); + } + #[cfg(feature = "std_detect_file_io")] { + // If calling getauxval fails, try to read the auxiliary vector from + // its file: + auxv_from_file("/proc/self/auxv") + } + #[cfg(not(feature = "std_detect_file_io"))] { + Err(()) + } + } + + #[cfg(not(feature = "std_detect_dlsym_getauxval"))] { + let hwcap = unsafe { ffi_getauxval(AT_HWCAP) }; + + // Targets with only AT_HWCAP: + #[cfg(any(target_arch = "aarch64", target_arch = "mips", + target_arch = "mips64"))] + { + if hwcap != 0 { + return Ok(AuxVec { hwcap }); + } + } + + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + let hwcap2 = unsafe { ffi_getauxval(AT_HWCAP2) }; + if hwcap != 0 && hwcap2 != 0 { + return Ok(AuxVec { hwcap, hwcap2 }); + } + } + } +} + +/// Tries to read the `key` from the auxiliary vector by calling the +/// dynamically-linked `getauxval` function. If the function is not linked, +/// this function return `Err`. +#[cfg(feature = "std_detect_dlsym_getauxval")] +fn getauxval(key: usize) -> Result<usize, ()> { + use libc; + pub type F = unsafe extern "C" fn(usize) -> usize; + unsafe { + let ptr = libc::dlsym( + libc::RTLD_DEFAULT, + "getauxval\0".as_ptr() as *const _, + ); + if ptr.is_null() { + return Err(()); + } + + let ffi_getauxval: F = mem::transmute(ptr); + Ok(ffi_getauxval(key)) + } +} + +/// Tries to read the auxiliary vector from the `file`. If this fails, this +/// function returns `Err`. +#[cfg(feature = "std_detect_file_io")] +fn auxv_from_file(file: &str) -> Result<AuxVec, ()> { + let mut file = File::open(file).map_err(|_| ())?; + + // See <https://github.com/torvalds/linux/blob/v3.19/include/uapi/linux/auxvec.h>. + // + // The auxiliary vector contains at most 32 (key,value) fields: from + // `AT_EXECFN = 31` to `AT_NULL = 0`. That is, a buffer of + // 2*32 `usize` elements is enough to read the whole vector. + let mut buf = [0_usize; 64]; + { + let raw: &mut [u8; 64 * mem::size_of::<usize>()] = + unsafe { mem::transmute(&mut buf) }; + file.read(raw).map_err(|_| ())?; + } + auxv_from_buf(&buf) +} + +/// Tries to interpret the `buffer` as an auxiliary vector. If that fails, this +/// function returns `Err`. +#[cfg(feature = "std_detect_file_io")] +fn auxv_from_buf(buf: &[usize; 64]) -> Result<AuxVec, ()> { + // Targets with only AT_HWCAP: + #[cfg(any(target_arch = "aarch64", target_arch = "mips", + target_arch = "mips64"))] + { + for el in buf.chunks(2) { + match el[0] { + AT_HWCAP => return Ok(AuxVec { hwcap: el[1] }), + _ => (), + } + } + } + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + let mut hwcap = None; + let mut hwcap2 = None; + for el in buf.chunks(2) { + match el[0] { + AT_HWCAP => hwcap = Some(el[1]), + AT_HWCAP2 => hwcap2 = Some(el[1]), + _ => (), + } + } + + if let (Some(hwcap), Some(hwcap2)) = (hwcap, hwcap2) { + return Ok(AuxVec { hwcap, hwcap2 }); + } + } + drop(buf); + Err(()) +} + +#[cfg(test)] +mod tests { + extern crate auxv as auxv_crate; + use super::*; + + // Reads the Auxiliary Vector key from /proc/self/auxv + // using the auxv crate. + #[cfg(feature = "std_detect_file_io")] + fn auxv_crate_getprocfs(key: usize) -> Option<usize> { + use self::auxv_crate::AuxvType; + use self::auxv_crate::procfs::search_procfs_auxv; + let k = key as AuxvType; + match search_procfs_auxv(&[k]) { + Ok(v) => Some(v[&k] as usize), + Err(_) => None, + } + } + + // Reads the Auxiliary Vector key from getauxval() + // using the auxv crate. + #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] + fn auxv_crate_getauxval(key: usize) -> Option<usize> { + use self::auxv_crate::AuxvType; + use self::auxv_crate::getauxval::Getauxval; + let q = auxv_crate::getauxval::NativeGetauxval {}; + match q.getauxval(key as AuxvType) { + Ok(v) => Some(v as usize), + Err(_) => None, + } + } + + // FIXME: on mips/mips64 getauxval returns 0, and /proc/self/auxv + // does not always contain the AT_HWCAP key under qemu. + #[cfg(not(any(target_arch = "mips", target_arch = "mips64", target_arch = "powerpc")))] + #[test] + fn auxv_crate() { + let v = auxv(); + if let Some(hwcap) = auxv_crate_getauxval(AT_HWCAP) { + let rt_hwcap = v.expect("failed to find hwcap key").hwcap; + assert_eq!(rt_hwcap, hwcap); + } + + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + if let Some(hwcap2) = auxv_crate_getauxval(AT_HWCAP2) { + let rt_hwcap2 = v.expect("failed to find hwcap2 key").hwcap2; + assert_eq!(rt_hwcap2, hwcap2); + } + } + } + + #[test] + fn auxv_dump() { + if let Ok(auxvec) = auxv() { + println!("{:?}", auxvec); + } else { + println!("both getauxval() and reading /proc/self/auxv failed!"); + } + } + + #[cfg(feature = "std_detect_file_io")] + cfg_if! { + if #[cfg(target_arch = "arm")] { + #[test] + fn linux_rpi3() { + let file = concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-rpi3.auxv"); + println!("file: {}", file); + let v = auxv_from_file(file).unwrap(); + assert_eq!(v.hwcap, 4174038); + assert_eq!(v.hwcap2, 16); + } + + #[test] + #[should_panic] + fn linux_macos_vb() { + let file = concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/macos-virtualbox-linux-x86-4850HQ.auxv"); + println!("file: {}", file); + let v = auxv_from_file(file).unwrap(); + // this file is incomplete (contains hwcap but not hwcap2), we + // want to fall back to /proc/cpuinfo in this case, so + // reading should fail. assert_eq!(v.hwcap, 126614527); + // assert_eq!(v.hwcap2, 0); + } + } else if #[cfg(target_arch = "aarch64")] { + #[test] + fn linux_x64() { + let file = concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-x64-i7-6850k.auxv"); + println!("file: {}", file); + let v = auxv_from_file(file).unwrap(); + assert_eq!(v.hwcap, 3219913727); + } + } + } + + #[test] + #[cfg(feature = "std_detect_file_io")] + fn auxv_dump_procfs() { + if let Ok(auxvec) = auxv_from_file("/proc/self/auxv") { + println!("{:?}", auxvec); + } else { + println!("reading /proc/self/auxv failed!"); + } + } + + #[test] + fn auxv_crate_procfs() { + let v = auxv(); + if let Some(hwcap) = auxv_crate_getprocfs(AT_HWCAP) { + assert_eq!(v.unwrap().hwcap, hwcap); + } + + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + if let Some(hwcap2) = auxv_crate_getprocfs(AT_HWCAP2) { + assert_eq!(v.unwrap().hwcap2, hwcap2); + } + } + } +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/cpuinfo.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/cpuinfo.rs new file mode 100644 index 000000000..b31685785 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/cpuinfo.rs @@ -0,0 +1,301 @@ +//! Parses /proc/cpuinfo +#![cfg_attr(not(target_arch = "arm"), allow(dead_code))] + +extern crate std; +use self::std::{prelude::v1::*, fs::File, io, io::Read}; + +/// cpuinfo +pub(crate) struct CpuInfo { + raw: String, +} + +impl CpuInfo { + /// Reads /proc/cpuinfo into CpuInfo. + pub(crate) fn new() -> Result<Self, io::Error> { + let mut file = File::open("/proc/cpuinfo")?; + let mut cpui = Self { raw: String::new() }; + file.read_to_string(&mut cpui.raw)?; + Ok(cpui) + } + /// Returns the value of the cpuinfo `field`. + pub(crate) fn field(&self, field: &str) -> CpuInfoField { + for l in self.raw.lines() { + if l.trim().starts_with(field) { + return CpuInfoField::new(l.split(": ").nth(1)); + } + } + CpuInfoField(None) + } + + /// Returns the `raw` contents of `/proc/cpuinfo` + #[cfg(test)] + fn raw(&self) -> &String { + &self.raw + } + + #[cfg(test)] + fn from_str(other: &str) -> Result<Self, ::std::io::Error> { + Ok(Self { + raw: String::from(other), + }) + } +} + +/// Field of cpuinfo +#[derive(Debug)] +pub(crate) struct CpuInfoField<'a>(Option<&'a str>); + +impl<'a> PartialEq<&'a str> for CpuInfoField<'a> { + fn eq(&self, other: &&'a str) -> bool { + match self.0 { + None => other.is_empty(), + Some(f) => f == other.trim(), + } + } +} + +impl<'a> CpuInfoField<'a> { + pub(crate) fn new<'b>(v: Option<&'b str>) -> CpuInfoField<'b> { + match v { + None => CpuInfoField::<'b>(None), + Some(f) => CpuInfoField::<'b>(Some(f.trim())), + } + } + /// Does the field exist? + #[cfg(test)] + pub(crate) fn exists(&self) -> bool { + self.0.is_some() + } + /// Does the field contain `other`? + pub(crate) fn has(&self, other: &str) -> bool { + match self.0 { + None => other.is_empty(), + Some(f) => { + let other = other.trim(); + for v in f.split(' ') { + if v == other { + return true; + } + } + false + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn raw_dump() { + let cpuinfo = CpuInfo::new().unwrap(); + if cpuinfo.field("vendor_id") == "GenuineIntel" { + assert!(cpuinfo.field("flags").exists()); + assert!(!cpuinfo.field("vendor33_id").exists()); + assert!(cpuinfo.field("flags").has("sse")); + assert!(!cpuinfo.field("flags").has("avx314")); + } + println!("{}", cpuinfo.raw()); + } + + const CORE_DUO_T6500: &str = r"processor : 0 +vendor_id : GenuineIntel +cpu family : 6 +model : 23 +model name : Intel(R) Core(TM)2 Duo CPU T6500 @ 2.10GHz +stepping : 10 +microcode : 0xa0b +cpu MHz : 1600.000 +cache size : 2048 KB +physical id : 0 +siblings : 2 +core id : 0 +cpu cores : 2 +apicid : 0 +initial apicid : 0 +fdiv_bug : no +hlt_bug : no +f00f_bug : no +coma_bug : no +fpu : yes +fpu_exception : yes +cpuid level : 13 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm +bogomips : 4190.43 +clflush size : 64 +cache_alignment : 64 +address sizes : 36 bits physical, 48 bits virtual +power management: +"; + + #[test] + fn core_duo_t6500() { + let cpuinfo = CpuInfo::from_str(CORE_DUO_T6500).unwrap(); + assert_eq!(cpuinfo.field("vendor_id"), "GenuineIntel"); + assert_eq!(cpuinfo.field("cpu family"), "6"); + assert_eq!(cpuinfo.field("model"), "23"); + assert_eq!( + cpuinfo.field("model name"), + "Intel(R) Core(TM)2 Duo CPU T6500 @ 2.10GHz" + ); + assert_eq!( + cpuinfo.field("flags"), + "fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm" + ); + assert!(cpuinfo.field("flags").has("fpu")); + assert!(cpuinfo.field("flags").has("dtherm")); + assert!(cpuinfo.field("flags").has("sse2")); + assert!(!cpuinfo.field("flags").has("avx")); + } + + const ARM_CORTEX_A53: &str = + r"Processor : AArch64 Processor rev 3 (aarch64) + processor : 0 + processor : 1 + processor : 2 + processor : 3 + processor : 4 + processor : 5 + processor : 6 + processor : 7 + Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 + CPU implementer : 0x41 + CPU architecture: AArch64 + CPU variant : 0x0 + CPU part : 0xd03 + CPU revision : 3 + + Hardware : HiKey Development Board + "; + + #[test] + fn arm_cortex_a53() { + let cpuinfo = CpuInfo::from_str(ARM_CORTEX_A53).unwrap(); + assert_eq!( + cpuinfo.field("Processor"), + "AArch64 Processor rev 3 (aarch64)" + ); + assert_eq!( + cpuinfo.field("Features"), + "fp asimd evtstrm aes pmull sha1 sha2 crc32" + ); + assert!(cpuinfo.field("Features").has("pmull")); + assert!(!cpuinfo.field("Features").has("neon")); + assert!(cpuinfo.field("Features").has("asimd")); + } + + const ARM_CORTEX_A57: &str = r"Processor : Cortex A57 Processor rev 1 (aarch64) +processor : 0 +processor : 1 +processor : 2 +processor : 3 +Features : fp asimd aes pmull sha1 sha2 crc32 wp half thumb fastmult vfp edsp neon vfpv3 tlsi vfpv4 idiva idivt +CPU implementer : 0x41 +CPU architecture: 8 +CPU variant : 0x1 +CPU part : 0xd07 +CPU revision : 1"; + + #[test] + fn arm_cortex_a57() { + let cpuinfo = CpuInfo::from_str(ARM_CORTEX_A57).unwrap(); + assert_eq!( + cpuinfo.field("Processor"), + "Cortex A57 Processor rev 1 (aarch64)" + ); + assert_eq!( + cpuinfo.field("Features"), + "fp asimd aes pmull sha1 sha2 crc32 wp half thumb fastmult vfp edsp neon vfpv3 tlsi vfpv4 idiva idivt" + ); + assert!(cpuinfo.field("Features").has("pmull")); + assert!(cpuinfo.field("Features").has("neon")); + assert!(cpuinfo.field("Features").has("asimd")); + } + + const POWER8E_POWERKVM: &str = r"processor : 0 +cpu : POWER8E (raw), altivec supported +clock : 3425.000000MHz +revision : 2.1 (pvr 004b 0201) + +processor : 1 +cpu : POWER8E (raw), altivec supported +clock : 3425.000000MHz +revision : 2.1 (pvr 004b 0201) + +processor : 2 +cpu : POWER8E (raw), altivec supported +clock : 3425.000000MHz +revision : 2.1 (pvr 004b 0201) + +processor : 3 +cpu : POWER8E (raw), altivec supported +clock : 3425.000000MHz +revision : 2.1 (pvr 004b 0201) + +timebase : 512000000 +platform : pSeries +model : IBM pSeries (emulated by qemu) +machine : CHRP IBM pSeries (emulated by qemu)"; + + #[test] + fn power8_powerkvm() { + let cpuinfo = CpuInfo::from_str(POWER8E_POWERKVM).unwrap(); + assert_eq!(cpuinfo.field("cpu"), "POWER8E (raw), altivec supported"); + + assert!(cpuinfo.field("cpu").has("altivec")); + } + + const POWER5P: &str = r"processor : 0 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 1 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 2 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 3 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 4 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 5 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 6 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 7 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +timebase : 237331000 +platform : pSeries +machine : CHRP IBM,9133-55A"; + + #[test] + fn power5p() { + let cpuinfo = CpuInfo::from_str(POWER5P).unwrap(); + assert_eq!(cpuinfo.field("cpu"), "POWER5+ (gs)"); + + assert!(!cpuinfo.field("cpu").has("altivec")); + } +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/mips.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/mips.rs new file mode 100644 index 000000000..c0a5fb2e5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/mips.rs @@ -0,0 +1,31 @@ +//! Run-time feature detection for MIPS on Linux. + +use crate::detect::{Feature, cache, bit}; +use super::auxvec; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector, and if that fails, try +/// to read them from `/proc/cpuinfo`. +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + // The values are part of the platform-specific [asm/hwcap.h][hwcap] + // + // [hwcap]: https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h + if let Ok(auxv) = auxvec::auxv() { + enable_feature(&mut value, Feature::msa, bit::test(auxv.hwcap, 1)); + return value; + } + // TODO: fall back via `cpuinfo`. + value +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/mod.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/mod.rs new file mode 100644 index 000000000..e02d5e6dc --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/mod.rs @@ -0,0 +1,28 @@ +//! Run-time feature detection on Linux + +mod auxvec; + +#[cfg(feature = "std_detect_file_io")] +mod cpuinfo; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::check_for; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::check_for; + } else if #[cfg(any(target_arch = "mips", target_arch = "mips64"))] { + mod mips; + pub use self::mips::check_for; + } else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] { + mod powerpc; + pub use self::powerpc::check_for; + } else { + use crate::detect::Feature; + /// Performs run-time feature detection. + pub fn check_for(_x: Feature) -> bool { + false + } + } +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/powerpc.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/powerpc.rs new file mode 100644 index 000000000..1c08a5844 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/linux/powerpc.rs @@ -0,0 +1,41 @@ +//! Run-time feature detection for PowerPC on Linux. + +use crate::detect::{Feature, cache}; +use super::{auxvec, cpuinfo}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector, and if that fails, try +/// to read them from /proc/cpuinfo. +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + // The values are part of the platform-specific [asm/cputable.h][cputable] + // + // [cputable]: https://github.com/torvalds/linux/blob/master/arch/powerpc/include/uapi/asm/cputable.h + if let Ok(auxv) = auxvec::auxv() { + // note: the PowerPC values are the mask to do the test (instead of the + // index of the bit to test like in ARM and Aarch64) + enable_feature(&mut value, Feature::altivec, auxv.hwcap & 0x10000000 != 0); + enable_feature(&mut value, Feature::vsx, auxv.hwcap & 0x00000080 != 0); + enable_feature(&mut value, Feature::power8, auxv.hwcap2 & 0x80000000 != 0); + return value; + } + + // PowerPC's /proc/cpuinfo lacks a proper Feature field, + // but `altivec` support is indicated in the `cpu` field. + if let Ok(c) = cpuinfo::CpuInfo::new() { + enable_feature(&mut value, Feature::altivec, c.field("cpu").has("altivec")); + return value; + } + value +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/other.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/other.rs new file mode 100644 index 000000000..23e399ea7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/other.rs @@ -0,0 +1,9 @@ +//! Other operating systems + +use crate::detect::Feature; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(_x: Feature) -> bool { + false +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/x86.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/x86.rs new file mode 100644 index 000000000..9257b8a4b --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/x86.rs @@ -0,0 +1,375 @@ +//! x86 run-time feature detection is OS independent. + +#[cfg(target_arch = "x86")] +use crate::arch::x86::*; +#[cfg(target_arch = "x86_64")] +use crate::arch::x86_64::*; + +use crate::mem; + +use crate::detect::{Feature, cache, bit}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Run-time feature detection on x86 works by using the CPUID instruction. +/// +/// The [CPUID Wikipedia page][wiki_cpuid] contains +/// all the information about which flags to set to query which values, and in +/// which registers these are reported. +/// +/// The definitive references are: +/// - [Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2: +/// Instruction Set Reference, A-Z][intel64_ref]. +/// - [AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and +/// System Instructions][amd64_ref]. +/// +/// [wiki_cpuid]: https://en.wikipedia.org/wiki/CPUID +/// [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +/// [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +#[allow(clippy::similar_names)] +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + + // If the x86 CPU does not support the CPUID instruction then it is too + // old to support any of the currently-detectable features. + if !has_cpuid() { + return value; + } + + // Calling `__cpuid`/`__cpuid_count` from here on is safe because the CPU + // has `cpuid` support. + + // 0. EAX = 0: Basic Information: + // - EAX returns the "Highest Function Parameter", that is, the maximum + // leaf value for subsequent calls of `cpuinfo` in range [0, + // 0x8000_0000]. - The vendor ID is stored in 12 u8 ascii chars, + // returned in EBX, EDX, and ECX (in that order): + let (max_basic_leaf, vendor_id) = unsafe { + let CpuidResult { + eax: max_basic_leaf, + ebx, + ecx, + edx, + } = __cpuid(0); + let vendor_id: [[u8; 4]; 3] = [ + mem::transmute(ebx), + mem::transmute(edx), + mem::transmute(ecx), + ]; + let vendor_id: [u8; 12] = mem::transmute(vendor_id); + (max_basic_leaf, vendor_id) + }; + + if max_basic_leaf < 1 { + // Earlier Intel 486, CPUID not implemented + return value; + } + + // EAX = 1, ECX = 0: Queries "Processor Info and Feature Bits"; + // Contains information about most x86 features. + let CpuidResult { + ecx: proc_info_ecx, + edx: proc_info_edx, + .. + } = unsafe { __cpuid(0x0000_0001_u32) }; + + // EAX = 7, ECX = 0: Queries "Extended Features"; + // Contains information about bmi,bmi2, and avx2 support. + let (extended_features_ebx, extended_features_ecx) = if max_basic_leaf >= 7 + { + let CpuidResult { ebx, ecx, .. } = unsafe { __cpuid(0x0000_0007_u32) }; + (ebx, ecx) + } else { + (0, 0) // CPUID does not support "Extended Features" + }; + + // EAX = 0x8000_0000, ECX = 0: Get Highest Extended Function Supported + // - EAX returns the max leaf value for extended information, that is, + // `cpuid` calls in range [0x8000_0000; u32::MAX]: + let CpuidResult { + eax: extended_max_basic_leaf, + .. + } = unsafe { __cpuid(0x8000_0000_u32) }; + + // EAX = 0x8000_0001, ECX=0: Queries "Extended Processor Info and Feature + // Bits" + let extended_proc_info_ecx = if extended_max_basic_leaf >= 1 { + let CpuidResult { ecx, .. } = unsafe { __cpuid(0x8000_0001_u32) }; + ecx + } else { + 0 + }; + + { + // borrows value till the end of this scope: + let mut enable = |r, rb, f| { + if bit::test(r as usize, rb) { + value.set(f as u32); + } + }; + + enable(proc_info_ecx, 0, Feature::sse3); + enable(proc_info_ecx, 1, Feature::pclmulqdq); + enable(proc_info_ecx, 9, Feature::ssse3); + enable(proc_info_ecx, 13, Feature::cmpxchg16b); + enable(proc_info_ecx, 19, Feature::sse4_1); + enable(proc_info_ecx, 20, Feature::sse4_2); + enable(proc_info_ecx, 23, Feature::popcnt); + enable(proc_info_ecx, 25, Feature::aes); + enable(proc_info_ecx, 29, Feature::f16c); + enable(proc_info_ecx, 30, Feature::rdrand); + enable(extended_features_ebx, 18, Feature::rdseed); + enable(extended_features_ebx, 19, Feature::adx); + enable(extended_features_ebx, 11, Feature::rtm); + enable(proc_info_edx, 4, Feature::tsc); + enable(proc_info_edx, 23, Feature::mmx); + enable(proc_info_edx, 24, Feature::fxsr); + enable(proc_info_edx, 25, Feature::sse); + enable(proc_info_edx, 26, Feature::sse2); + enable(extended_features_ebx, 29, Feature::sha); + + enable(extended_features_ebx, 3, Feature::bmi); + enable(extended_features_ebx, 8, Feature::bmi2); + + // `XSAVE` and `AVX` support: + let cpu_xsave = bit::test(proc_info_ecx as usize, 26); + if cpu_xsave { + // 0. Here the CPU supports `XSAVE`. + + // 1. Detect `OSXSAVE`, that is, whether the OS is AVX enabled and + // supports saving the state of the AVX/AVX2 vector registers on + // context-switches, see: + // + // - [intel: is avx enabled?][is_avx_enabled], + // - [mozilla: sse.cpp][mozilla_sse_cpp]. + // + // [is_avx_enabled]: https://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled + // [mozilla_sse_cpp]: https://hg.mozilla.org/mozilla-central/file/64bab5cbb9b6/mozglue/build/SSE.cpp#l190 + let cpu_osxsave = bit::test(proc_info_ecx as usize, 27); + + if cpu_osxsave { + // 2. The OS must have signaled the CPU that it supports saving and + // restoring the: + // + // * SSE -> `XCR0.SSE[1]` + // * AVX -> `XCR0.AVX[2]` + // * AVX-512 -> `XCR0.AVX-512[7:5]`. + // + // by setting the corresponding bits of `XCR0` to `1`. + // + // This is safe because the CPU supports `xsave` + // and the OS has set `osxsave`. + let xcr0 = unsafe { _xgetbv(0) }; + // Test `XCR0.SSE[1]` and `XCR0.AVX[2]` with the mask `0b110 == 6`: + let os_avx_support = xcr0 & 6 == 6; + // Test `XCR0.AVX-512[7:5]` with the mask `0b1110_0000 == 224`: + let os_avx512_support = xcr0 & 224 == 224; + + // Only if the OS and the CPU support saving/restoring the AVX + // registers we enable `xsave` support: + if os_avx_support { + // See "13.3 ENABLING THE XSAVE FEATURE SET AND XSAVE-ENABLED + // FEATURES" in the "Intel® 64 and IA-32 Architectures Software + // Developer’s Manual, Volume 1: Basic Architecture": + // + // "Software enables the XSAVE feature set by setting + // CR4.OSXSAVE[bit 18] to 1 (e.g., with the MOV to CR4 + // instruction). If this bit is 0, execution of any of XGETBV, + // XRSTOR, XRSTORS, XSAVE, XSAVEC, XSAVEOPT, XSAVES, and XSETBV + // causes an invalid-opcode exception (#UD)" + // + enable(proc_info_ecx, 26, Feature::xsave); + + // For `xsaveopt`, `xsavec`, and `xsaves` we need to query: + // Processor Extended State Enumeration Sub-leaf (EAX = 0DH, + // ECX = 1): + if max_basic_leaf >= 0xd { + let CpuidResult { + eax: proc_extended_state1_eax, + .. + } = unsafe { __cpuid_count(0xd_u32, 1) }; + enable(proc_extended_state1_eax, 0, Feature::xsaveopt); + enable(proc_extended_state1_eax, 1, Feature::xsavec); + enable(proc_extended_state1_eax, 3, Feature::xsaves); + } + + // FMA (uses 256-bit wide registers): + enable(proc_info_ecx, 12, Feature::fma); + + // And AVX/AVX2: + enable(proc_info_ecx, 28, Feature::avx); + enable(extended_features_ebx, 5, Feature::avx2); + + // For AVX-512 the OS also needs to support saving/restoring + // the extended state, only then we enable AVX-512 support: + if os_avx512_support { + enable(extended_features_ebx, 16, Feature::avx512f); + enable(extended_features_ebx, 17, Feature::avx512dq); + enable(extended_features_ebx, 21, Feature::avx512_ifma); + enable(extended_features_ebx, 26, Feature::avx512pf); + enable(extended_features_ebx, 27, Feature::avx512er); + enable(extended_features_ebx, 28, Feature::avx512cd); + enable(extended_features_ebx, 30, Feature::avx512bw); + enable(extended_features_ebx, 31, Feature::avx512vl); + enable(extended_features_ecx, 1, Feature::avx512_vbmi); + enable( + extended_features_ecx, + 14, + Feature::avx512_vpopcntdq, + ); + } + } + } + } + + // This detects ABM on AMD CPUs and LZCNT on Intel CPUs. + // On intel CPUs with popcnt, lzcnt implements the + // "missing part" of ABM, so we map both to the same + // internal feature. + // + // The `is_x86_feature_detected!("lzcnt")` macro then + // internally maps to Feature::abm. + enable(extended_proc_info_ecx, 5, Feature::abm); + // As Hygon Dhyana originates from AMD technology and shares most of the architecture with + // AMD's family 17h, but with different CPU Vendor ID("HygonGenuine")/Family series + // number(Family 18h). + // + // For CPUID feature bits, Hygon Dhyana(family 18h) share the same definition with AMD + // family 17h. + // + // Related AMD CPUID specification is https://www.amd.com/system/files/TechDocs/25481.pdf. + // Related Hygon kernel patch can be found on + // http://lkml.kernel.org/r/5ce86123a7b9dad925ac583d88d2f921040e859b.1538583282.git.puwen@hygon.cn + if vendor_id == *b"AuthenticAMD" || vendor_id == *b"HygonGenuine" { + // These features are available on AMD arch CPUs: + enable(extended_proc_info_ecx, 6, Feature::sse4a); + enable(extended_proc_info_ecx, 21, Feature::tbm); + } + } + + value +} + +#[cfg(test)] +mod tests { + extern crate cupid; + + #[test] + fn dump() { + println!("aes: {:?}", is_x86_feature_detected!("aes")); + println!("pclmulqdq: {:?}", is_x86_feature_detected!("pclmulqdq")); + println!("rdrand: {:?}", is_x86_feature_detected!("rdrand")); + println!("rdseed: {:?}", is_x86_feature_detected!("rdseed")); + println!("tsc: {:?}", is_x86_feature_detected!("tsc")); + println!("sse: {:?}", is_x86_feature_detected!("sse")); + println!("sse2: {:?}", is_x86_feature_detected!("sse2")); + println!("sse3: {:?}", is_x86_feature_detected!("sse3")); + println!("ssse3: {:?}", is_x86_feature_detected!("ssse3")); + println!("sse4.1: {:?}", is_x86_feature_detected!("sse4.1")); + println!("sse4.2: {:?}", is_x86_feature_detected!("sse4.2")); + println!("sse4a: {:?}", is_x86_feature_detected!("sse4a")); + println!("sha: {:?}", is_x86_feature_detected!("sha")); + println!("avx: {:?}", is_x86_feature_detected!("avx")); + println!("avx2: {:?}", is_x86_feature_detected!("avx2")); + println!("avx512f {:?}", is_x86_feature_detected!("avx512f")); + println!("avx512cd {:?}", is_x86_feature_detected!("avx512cd")); + println!("avx512er {:?}", is_x86_feature_detected!("avx512er")); + println!("avx512pf {:?}", is_x86_feature_detected!("avx512pf")); + println!("avx512bw {:?}", is_x86_feature_detected!("avx512bw")); + println!("avx512dq {:?}", is_x86_feature_detected!("avx512dq")); + println!("avx512vl {:?}", is_x86_feature_detected!("avx512vl")); + println!("avx512_ifma {:?}", is_x86_feature_detected!("avx512ifma")); + println!("avx512_vbmi {:?}", is_x86_feature_detected!("avx512vbmi")); + println!( + "avx512_vpopcntdq {:?}", + is_x86_feature_detected!("avx512vpopcntdq") + ); + println!("fma: {:?}", is_x86_feature_detected!("fma")); + println!("abm: {:?}", is_x86_feature_detected!("abm")); + println!("bmi: {:?}", is_x86_feature_detected!("bmi1")); + println!("bmi2: {:?}", is_x86_feature_detected!("bmi2")); + println!("tbm: {:?}", is_x86_feature_detected!("tbm")); + println!("popcnt: {:?}", is_x86_feature_detected!("popcnt")); + println!("lzcnt: {:?}", is_x86_feature_detected!("lzcnt")); + println!("fxsr: {:?}", is_x86_feature_detected!("fxsr")); + println!("xsave: {:?}", is_x86_feature_detected!("xsave")); + println!("xsaveopt: {:?}", is_x86_feature_detected!("xsaveopt")); + println!("xsaves: {:?}", is_x86_feature_detected!("xsaves")); + println!("xsavec: {:?}", is_x86_feature_detected!("xsavec")); + println!("cmpxchg16b: {:?}", is_x86_feature_detected!("cmpxchg16b")); + println!("adx: {:?}", is_x86_feature_detected!("adx")); + println!("rtm: {:?}", is_x86_feature_detected!("rtm")); + } + + #[test] + fn compare_with_cupid() { + let information = cupid::master().unwrap(); + assert_eq!(is_x86_feature_detected!("aes"), information.aesni()); + assert_eq!(is_x86_feature_detected!("pclmulqdq"), information.pclmulqdq()); + assert_eq!(is_x86_feature_detected!("rdrand"), information.rdrand()); + assert_eq!(is_x86_feature_detected!("rdseed"), information.rdseed()); + assert_eq!(is_x86_feature_detected!("tsc"), information.tsc()); + assert_eq!(is_x86_feature_detected!("sse"), information.sse()); + assert_eq!(is_x86_feature_detected!("sse2"), information.sse2()); + assert_eq!(is_x86_feature_detected!("sse3"), information.sse3()); + assert_eq!(is_x86_feature_detected!("ssse3"), information.ssse3()); + assert_eq!(is_x86_feature_detected!("sse4.1"), information.sse4_1()); + assert_eq!(is_x86_feature_detected!("sse4.2"), information.sse4_2()); + assert_eq!(is_x86_feature_detected!("sse4a"), information.sse4a()); + assert_eq!(is_x86_feature_detected!("sha"), information.sha()); + assert_eq!(is_x86_feature_detected!("avx"), information.avx()); + assert_eq!(is_x86_feature_detected!("avx2"), information.avx2()); + assert_eq!(is_x86_feature_detected!("avx512f"), information.avx512f()); + assert_eq!(is_x86_feature_detected!("avx512cd"), information.avx512cd()); + assert_eq!(is_x86_feature_detected!("avx512er"), information.avx512er()); + assert_eq!(is_x86_feature_detected!("avx512pf"), information.avx512pf()); + assert_eq!(is_x86_feature_detected!("avx512bw"), information.avx512bw()); + assert_eq!(is_x86_feature_detected!("avx512dq"), information.avx512dq()); + assert_eq!(is_x86_feature_detected!("avx512vl"), information.avx512vl()); + assert_eq!( + is_x86_feature_detected!("avx512ifma"), + information.avx512_ifma() + ); + assert_eq!( + is_x86_feature_detected!("avx512vbmi"), + information.avx512_vbmi() + ); + assert_eq!( + is_x86_feature_detected!("avx512vpopcntdq"), + information.avx512_vpopcntdq() + ); + assert_eq!(is_x86_feature_detected!("fma"), information.fma()); + assert_eq!(is_x86_feature_detected!("bmi1"), information.bmi1()); + assert_eq!(is_x86_feature_detected!("bmi2"), information.bmi2()); + assert_eq!(is_x86_feature_detected!("popcnt"), information.popcnt()); + assert_eq!(is_x86_feature_detected!("abm"), information.lzcnt()); + assert_eq!(is_x86_feature_detected!("tbm"), information.tbm()); + assert_eq!(is_x86_feature_detected!("lzcnt"), information.lzcnt()); + assert_eq!(is_x86_feature_detected!("xsave"), information.xsave()); + assert_eq!(is_x86_feature_detected!("xsaveopt"), information.xsaveopt()); + assert_eq!( + is_x86_feature_detected!("xsavec"), + information.xsavec_and_xrstor() + ); + assert_eq!( + is_x86_feature_detected!("xsaves"), + information.xsaves_xrstors_and_ia32_xss() + ); + assert_eq!( + is_x86_feature_detected!("cmpxchg16b"), + information.cmpxchg16b(), + ); + assert_eq!( + is_x86_feature_detected!("adx"), + information.adx(), + ); + assert_eq!( + is_x86_feature_detected!("rtm"), + information.rtm(), + ); + } +} diff --git a/src/tools/rustfmt/tests/source/cfg_if/lib.rs b/src/tools/rustfmt/tests/source/cfg_if/lib.rs new file mode 100644 index 000000000..8b3bb304f --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/lib.rs @@ -0,0 +1,49 @@ +//! Run-time feature detection for the Rust standard library. +//! +//! To detect whether a feature is enabled in the system running the binary +//! use one of the appropriate macro for the target: +//! +//! * `x86` and `x86_64`: [`is_x86_feature_detected`] +//! * `arm`: [`is_arm_feature_detected`] +//! * `aarch64`: [`is_aarch64_feature_detected`] +//! * `mips`: [`is_mips_feature_detected`] +//! * `mips64`: [`is_mips64_feature_detected`] +//! * `powerpc`: [`is_powerpc_feature_detected`] +//! * `powerpc64`: [`is_powerpc64_feature_detected`] + +#![unstable(feature = "stdsimd", issue = "27731")] +#![feature(const_fn, staged_api, stdsimd, doc_cfg, allow_internal_unstable)] +#![allow(clippy::shadow_reuse)] +#![deny(clippy::missing_inline_in_public_items)] +#![cfg_attr(target_os = "linux", feature(linkage))] +#![cfg_attr(all(target_os = "freebsd", target_arch = "aarch64"), feature(asm))] +#![cfg_attr(stdsimd_strict, deny(warnings))] +#![cfg_attr(test, allow(unused_imports))] +#![no_std] + +#[macro_use] +extern crate cfg_if; + +cfg_if! { + if #[cfg(feature = "std_detect_file_io")] { + #[cfg_attr(test, macro_use(println))] + extern crate std; + + #[allow(unused_imports)] + use std::{arch, fs, io, mem, sync}; + } else { + #[cfg(test)] + #[macro_use(println)] + extern crate std; + + #[allow(unused_imports)] + use core::{arch, mem, sync}; + } +} + +#[cfg(feature = "std_detect_dlsym_getauxval")] +extern crate libc; + +#[doc(hidden)] +#[unstable(feature = "stdsimd", issue = "27731")] +pub mod detect; diff --git a/src/tools/rustfmt/tests/source/cfg_if/mod.rs b/src/tools/rustfmt/tests/source/cfg_if/mod.rs new file mode 100644 index 000000000..b630e7ff3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_if/mod.rs @@ -0,0 +1,5 @@ +//! `std_detect` + +#[doc(hidden)] // unstable implementation detail +#[unstable(feature = "stdsimd", issue = "27731")] +pub mod detect; diff --git a/src/tools/rustfmt/tests/source/cfg_mod/bar.rs b/src/tools/rustfmt/tests/source/cfg_mod/bar.rs new file mode 100644 index 000000000..5b6b5f438 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_mod/bar.rs @@ -0,0 +1,3 @@ +fn bar( ) -> &str { +"bar" +} diff --git a/src/tools/rustfmt/tests/source/cfg_mod/dir/dir1/dir2/wasm32.rs b/src/tools/rustfmt/tests/source/cfg_mod/dir/dir1/dir2/wasm32.rs new file mode 100644 index 000000000..0f8c0a3a7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_mod/dir/dir1/dir2/wasm32.rs @@ -0,0 +1,6 @@ +fn + wasm32 + () -> &str +{ + "wasm32" +} diff --git a/src/tools/rustfmt/tests/source/cfg_mod/dir/dir1/dir3/wasm32.rs b/src/tools/rustfmt/tests/source/cfg_mod/dir/dir1/dir3/wasm32.rs new file mode 100644 index 000000000..0f8c0a3a7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_mod/dir/dir1/dir3/wasm32.rs @@ -0,0 +1,6 @@ +fn + wasm32 + () -> &str +{ + "wasm32" +} diff --git a/src/tools/rustfmt/tests/source/cfg_mod/foo.rs b/src/tools/rustfmt/tests/source/cfg_mod/foo.rs new file mode 100644 index 000000000..de4ce55ef --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_mod/foo.rs @@ -0,0 +1,4 @@ +fn foo( ) + -> &str { + "foo" +} diff --git a/src/tools/rustfmt/tests/source/cfg_mod/mod.rs b/src/tools/rustfmt/tests/source/cfg_mod/mod.rs new file mode 100644 index 000000000..45ba86f11 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_mod/mod.rs @@ -0,0 +1,10 @@ +#[cfg_attr(feature = "foo", path = "foo.rs")] +#[cfg_attr(not(feture = "foo"), path = "bar.rs")] +mod sub_mod; + +#[cfg_attr(target_arch = "wasm32", path = "dir/dir1/dir2/wasm32.rs")] +#[cfg_attr(not(target_arch = "wasm32"), path = "dir/dir1/dir3/wasm32.rs")] +mod wasm32; + +#[some_attr(path = "somewhere.rs")] +mod other; diff --git a/src/tools/rustfmt/tests/source/cfg_mod/other.rs b/src/tools/rustfmt/tests/source/cfg_mod/other.rs new file mode 100644 index 000000000..0b5c04d21 --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_mod/other.rs @@ -0,0 +1 @@ +fn other() -> &str { "other"} diff --git a/src/tools/rustfmt/tests/source/cfg_mod/wasm32.rs b/src/tools/rustfmt/tests/source/cfg_mod/wasm32.rs new file mode 100644 index 000000000..3741e53fd --- /dev/null +++ b/src/tools/rustfmt/tests/source/cfg_mod/wasm32.rs @@ -0,0 +1,4 @@ +fn + wasm32() -> &str { + "wasm32" + } diff --git a/src/tools/rustfmt/tests/source/chains-visual.rs b/src/tools/rustfmt/tests/source/chains-visual.rs new file mode 100644 index 000000000..20a96311e --- /dev/null +++ b/src/tools/rustfmt/tests/source/chains-visual.rs @@ -0,0 +1,158 @@ +// rustfmt-indent_style: Visual +// Test chain formatting. + +fn main() { + // Don't put chains on a single line if it wasn't so in source. + let a = b .c + .d.1 + .foo(|x| x + 1); + + bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc + .ddddddddddddddddddddddddddd(); + + bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddd.eeeeeeee(); + + // Test case where first chain element isn't a path, but is shorter than + // the size of a tab. + x() + .y(|| match cond() { true => (), false => () }); + + loong_func() + .quux(move || if true { + 1 + } else { + 2 + }); + + some_fuuuuuuuuunction() + .method_call_a(aaaaa, bbbbb, |c| { + let x = c; + x + }); + + some_fuuuuuuuuunction().method_call_a(aaaaa, bbbbb, |c| { + let x = c; + x + }).method_call_b(aaaaa, bbbbb, |c| { + let x = c; + x + }); + + fffffffffffffffffffffffffffffffffff(a, + { + SCRIPT_TASK_ROOT + .with(|root| { + *root.borrow_mut() = Some(&script_task); + }); + }); + + let suuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuum = xxxxxxx + .map(|x| x + 5) + .map(|x| x / 2) + .fold(0, |acc, x| acc + x); + + aaaaaaaaaaaaaaaa.map(|x| { + x += 1; + x + }).filter(some_mod::some_filter) +} + +fn floaters() { + let z = Foo { + field1: val1, + field2: val2, + }; + + let x = Foo { + field1: val1, + field2: val2, + }.method_call().method_call(); + + let y = if cond { + val1 + } else { + val2 + } + .method_call(); + + { + match x { + PushParam => { + // params are 1-indexed + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } + + if cond { some(); } else { none(); } + .bar() + .baz(); + + Foo { x: val } .baz(|| { force(); multiline(); }) .quux(); + + Foo { y: i_am_multi_line, z: ok } + .baz(|| { + force(); multiline(); + }) + .quux(); + + a + match x { true => "yay!", false => "boo!" }.bar() +} + +fn is_replaced_content() -> bool { + constellat.send(ConstellationMsg::ViewportConstrained( + self.id, constraints)).unwrap(); +} + +fn issue587() { + a.b::<()>(c); + + std::mem::transmute(dl.symbol::<()>("init").unwrap()) +} + +fn issue_1389() { + let names = String::from_utf8(names)?.split('|').map(str::to_owned).collect(); +} + +fn issue1217() -> Result<Mnemonic, Error> { +let random_chars: String = OsRng::new()? + .gen_ascii_chars() + .take(self.bit_length) + .collect(); + + Ok(Mnemonic::new(&random_chars)) +} + +fn issue1236(options: Vec<String>) -> Result<Option<String>> { +let process = Command::new("dmenu").stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .chain_err(|| "failed to spawn dmenu")?; +} + +fn issue1434() { + for _ in 0..100 { + let prototype_id = PrototypeIdData::from_reader::<_, B>(&mut self.file_cursor).chain_err(|| { + format!("could not read prototype ID at offset {:#010x}", + current_offset) + })?; + } +} + +fn issue2264() { + { + something.function() + .map(|| { + if let a_very_very_very_very_very_very_very_very_long_variable = + compute_this_variable() + { + println!("Hello"); + } + }) + .collect(); + } +} diff --git a/src/tools/rustfmt/tests/source/chains.rs b/src/tools/rustfmt/tests/source/chains.rs new file mode 100644 index 000000000..c77f5bac4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/chains.rs @@ -0,0 +1,266 @@ +// rustfmt-use_small_heuristics: Off +// Test chain formatting. + +fn main() { + let a = b .c + .d.1 + .foo(|x| x + 1); + + bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc + .ddddddddddddddddddddddddddd(); + + bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddd.eeeeeeee(); + + let f = fooooooooooooooooooooooooooooooooooooooooooooooooooo.baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar; + + // Test case where first chain element isn't a path, but is shorter than + // the size of a tab. + x() + .y(|| match cond() { true => (), false => () }); + + loong_func() + .quux(move || if true { + 1 + } else { + 2 + }); + + some_fuuuuuuuuunction() + .method_call_a(aaaaa, bbbbb, |c| { + let x = c; + x + }); + + some_fuuuuuuuuunction().method_call_a(aaaaa, bbbbb, |c| { + let x = c; + x + }).method_call_b(aaaaa, bbbbb, |c| { + let x = c; + x + }); + + fffffffffffffffffffffffffffffffffff(a, + { + SCRIPT_TASK_ROOT + .with(|root| { + *root.borrow_mut() = Some(&script_task); + }); + }); + + let suuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuum = xxxxxxx + .map(|x| x + 5) + .map(|x| x / 2) + .fold(0, |acc, x| acc + x); + + body.fold(Body::new(), |mut body, chunk| { + body.extend(chunk); + Ok(body) + }).and_then(move |body| { + let req = Request::from_parts(parts, body); + f(req).map_err(|_| io::Error::new(io::ErrorKind::Other, "")) + }); + + aaaaaaaaaaaaaaaa.map(|x| { + x += 1; + x + }).filter(some_mod::some_filter) +} + +fn floaters() { + let z = Foo { + field1: val1, + field2: val2, + }; + + let x = Foo { + field1: val1, + field2: val2, + }.method_call().method_call(); + + let y = if cond { + val1 + } else { + val2 + } + .method_call(); + + { + match x { + PushParam => { + // params are 1-indexed + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } + + if cond { some(); } else { none(); } + .bar() + .baz(); + + Foo { x: val } .baz(|| { force(); multiline(); }) .quux(); + + Foo { y: i_am_multi_line, z: ok } + .baz(|| { + force(); multiline(); + }) + .quux(); + + a + match x { true => "yay!", false => "boo!" }.bar() +} + +fn is_replaced_content() -> bool { + constellat.send(ConstellationMsg::ViewportConstrained( + self.id, constraints)).unwrap(); +} + +fn issue587() { + a.b::<()>(c); + + std::mem::transmute(dl.symbol::<()>("init").unwrap()) +} + +fn try_shorthand() { + let x = expr?; + let y = expr.kaas()?.test(); + let loooooooooooooooooooooooooooooooooooooooooong = does_this?.look?.good?.should_we_break?.after_the_first_question_mark?; + let yyyy = expr?.another?.another?.another?.another?.another?.another?.another?.another?.test(); + let zzzz = expr?.another?.another?.another?.another?; + let aaa = x ???????????? ?????????????? ???? ????? ?????????????? ????????? ?????????????? ??; + + let y = a.very .loooooooooooooooooooooooooooooooooooooong() .chain() + .inside() .weeeeeeeeeeeeeee()? .test() .0 + .x; + + parameterized(f, + substs, + def_id, + Ns::Value, + &[], + |tcx| tcx.lookup_item_type(def_id).generics)?; + fooooooooooooooooooooooooooo()?.bar()?.baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz()?; +} + +fn issue_1004() { + match *self { + ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i), + ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i), + ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i), + } + ?; + + ty::tls::with(|tcx| { + let tap = ty::Binder(TraitAndProjections(principal, projections)); + in_binder(f, tcx, &ty::Binder(""), Some(tap)) + }) + ?; +} + +fn issue1392() { + test_method(r#" + if foo { + a(); + } + else { + b(); + } + "#.trim()); +} + +// #2067 +impl Settings { + fn save(&self) -> Result<()> { + let mut file = File::create(&settings_path).chain_err(|| ErrorKind::WriteError(settings_path.clone()))?; + } +} + +fn issue2126() { + { + { + { + { + { + let x = self.span_from(sub_span.expect("No span found for struct arant variant")); + self.sspanpan_from_span(sub_span.expect("No span found for struct variant")); + let x = self.spanpan_from_span(sub_span.expect("No span found for struct variant"))?; + } + } + } + } + } +} + +// #2200 +impl Foo { + pub fn from_ast(diagnostic: &::errors::Handler, + attrs: &[ast::Attribute]) -> Attributes { + let other_attrs = attrs.iter().filter_map(|attr| { + attr.with_desugared_doc(|attr| { + if attr.check_name("doc") { + if let Some(mi) = attr.meta() { + if let Some(value) = mi.value_str() { + doc_strings.push(DocFragment::Include(line, + attr.span, + filename, + contents)); + } + } + } + }) + }).collect(); + } +} + +// #2415 +// Avoid orphan in chain +fn issue2415() { + let base_url = (|| { + // stuff + + Ok((|| { + // stuff + Some(value.to_string()) + })() + .ok_or("")?) + })() + .unwrap_or_else(|_: Box<::std::error::Error>| String::from("")); +} + +impl issue_2786 { + fn thing(&self) { + foo(|a| { + println!("a"); + println!("b"); + }).bar(|c| { + println!("a"); + println!("b"); + }) + .baz(|c| { + println!("a"); + println!("b"); + }) + } +} + +fn issue_2773() { + let bar = Some(0); + bar.or_else(|| { + // do stuff + None + }).or_else(|| { + // do other stuff + None + }) + .and_then(|val| { + // do this stuff + None + }); +} + +fn issue_3034() { + disallowed_headers.iter().any(|header| *header == name) || + disallowed_header_prefixes.iter().any(|prefix| name.starts_with(prefix)) +} diff --git a/src/tools/rustfmt/tests/source/chains_with_comment.rs b/src/tools/rustfmt/tests/source/chains_with_comment.rs new file mode 100644 index 000000000..91160711b --- /dev/null +++ b/src/tools/rustfmt/tests/source/chains_with_comment.rs @@ -0,0 +1,121 @@ +// Chains with comment. + +fn main() { + let x = y // comment + .z; + + foo // foo + // comment after parent + .x + .y + // comment 1 + .bar() // comment after bar() + // comment 2 + .foobar + // comment after + // comment 3 + .baz(x, y, z); + + self.rev_dep_graph + .iter() + // Remove nodes that are not dirty + .filter(|&(unit, _)| dirties.contains(&unit)) + // Retain only dirty dependencies of the ones that are dirty + .map(|(k, deps)| { + ( + k.clone(), + deps.iter() + .cloned() + .filter(|d| dirties.contains(&d)) + .collect(), + ) + }); + + let y = expr /* comment */.kaas()? +// comment + .test(); + let loooooooooooooooooooooooooooooooooooooooooong = does_this?.look?.good?.should_we_break?.after_the_first_question_mark?; + let zzzz = expr? // comment after parent +// comment 0 +.another??? // comment 1 +.another???? // comment 2 +.another? // comment 3 +.another?; + + let y = a.very .loooooooooooooooooooooooooooooooooooooong() /* comment */ .chain() + .inside() /* comment */ .weeeeeeeeeeeeeee()? .test() .0 + .x; + + parameterized(f, + substs, + def_id, + Ns::Value, + &[], + |tcx| tcx.lookup_item_type(def_id).generics)?; + fooooooooooooooooooooooooooo()?.bar()?.baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz()?; + + // #2559 + App::new("cargo-cache") +.version(crate_version!()) +.bin_name("cargo") +.about("Manage cargo cache") +.author("matthiaskrgr") +.subcommand( +SubCommand::with_name("cache") +.version(crate_version!()) +.bin_name("cargo-cache") +.about("Manage cargo cache") +.author("matthiaskrgr") +.arg(&list_dirs) +.arg(&remove_dir) +.arg(&gc_repos) +.arg(&info) +.arg(&keep_duplicate_crates) .arg(&dry_run) +.arg(&auto_clean) +.arg(&auto_clean_expensive), + ) // subcommand + .arg(&list_dirs); +} + +// #2177 +impl Foo { + fn dirty_rev_dep_graph( + &self, + dirties: &HashSet<UnitKey>, + ) -> HashMap<UnitKey, HashSet<UnitKey>> { + let dirties = self.transitive_dirty_units(dirties); + trace!("transitive_dirty_units: {:?}", dirties); + + self.rev_dep_graph.iter() + // Remove nodes that are not dirty + .filter(|&(unit, _)| dirties.contains(&unit)) + // Retain only dirty dependencies of the ones that are dirty + .map(|(k, deps)| (k.clone(), deps.iter().cloned().filter(|d| dirties.contains(&d)).collect())) + } +} + +// #2907 +fn foo() { + let x = foo + .bar?? ? // comment + .baz; + let x = foo + .bar? ?? + // comment + .baz; + let x = foo + .bar? ? ? // comment + // comment + .baz; + let x = foo + .bar? ?? // comment + // comment + ? ?? + // comment + ? ?? + // comment + ??? + // comment + ? ? ? + .baz; +} diff --git a/src/tools/rustfmt/tests/source/closure-block-inside-macro.rs b/src/tools/rustfmt/tests/source/closure-block-inside-macro.rs new file mode 100644 index 000000000..b3ddfb512 --- /dev/null +++ b/src/tools/rustfmt/tests/source/closure-block-inside-macro.rs @@ -0,0 +1,9 @@ +// #1547 +fuzz_target!(|data: &[u8]| if let Some(first) = data.first() { + let index = *first as usize; + if index >= ENCODINGS.len() { + return; + } + let encoding = ENCODINGS[index]; + dispatch_test(encoding, &data[1..]); +}); diff --git a/src/tools/rustfmt/tests/source/closure.rs b/src/tools/rustfmt/tests/source/closure.rs new file mode 100644 index 000000000..b2d28b305 --- /dev/null +++ b/src/tools/rustfmt/tests/source/closure.rs @@ -0,0 +1,223 @@ +// rustfmt-normalize_comments: true +// Closures + +fn main() { + let square = ( |i: i32 | i * i ); + + let commented = |/* first */ a /*argument*/, /* second*/ b: WithType /* argument*/, /* ignored */ _ | + (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb); + + let block_body = move |xxxxxxxxxxxxxxxxxxxxxxxxxxxxx, ref yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy| { + xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy + }; + + let loooooooooooooong_name = |field| { + // format comments. + if field.node.attrs.len() > 0 { field.node.attrs[0].span.lo() + } else { + field.span.lo() + }}; + + let unblock_me = |trivial| { + closure() + }; + + let empty = |arg| {}; + + let simple = |arg| { /* comment formatting */ foo(arg) }; + + let test = | | { do_something(); do_something_else(); }; + + let arg_test = |big_argument_name, test123| looooooooooooooooooong_function_naaaaaaaaaaaaaaaaame(); + + let arg_test = |big_argument_name, test123| {looooooooooooooooooong_function_naaaaaaaaaaaaaaaaame()}; + + let simple_closure = move || -> () {}; + + let closure = |input: Ty| -> Option<String> { + foo() + }; + + let closure_with_return_type = |aaaaaaaaaaaaaaaaaaaaaaarg1, aaaaaaaaaaaaaaaaaaaaaaarg2| -> Strong { "sup".to_owned() }; + + |arg1, arg2, _, _, arg3, arg4| { let temp = arg4 + arg3; + arg2 * arg1 - temp }; + + let block_body_with_comment = args.iter() + .map(|a| { + // Emitting only dep-info is possible only for final crate type, as + // as others may emit required metadata for dependent crate types + if a.starts_with("--emit") && is_final_crate_type && !self.workspace_mode { + "--emit=dep-info" + } else { a } + }); + + for<> || -> () {}; + for< >|| -> () {}; + for< +> || -> () {}; + +for< 'a + ,'b, +'c > |_: &'a (), _: &'b (), _: &'c ()| -> () {}; + +} + +fn issue311() { + let func = |x| println!("{}", x); + + (func)(0.0); +} + +fn issue863() { + let closure = |x| match x { + 0 => true, + _ => false, + } == true; +} + +fn issue934() { + let hash: &Fn(&&Block) -> u64 = &|block| -> u64 { + let mut h = SpanlessHash::new(cx); + h.hash_block(block); + h.finish() + }; + + let hash: &Fn(&&Block) -> u64 = &|block| -> u64 { + let mut h = SpanlessHash::new(cx); + h.hash_block(block); + h.finish(); + }; +} + +impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { + pub fn eq_expr(&self, left: &Expr, right: &Expr) -> bool { + match (&left.node, &right.node) { + (&ExprBinary(l_op, ref ll, ref lr), &ExprBinary(r_op, ref rl, ref rr)) => { + l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) || + swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)) + } + } + } +} + +fn foo() { + lifetimes_iter___map(|lasdfasfd| { + let hi = if l.bounds.is_empty() { + l.lifetime.span.hi() + }; + }); +} + +fn issue1405() { + open_raw_fd(fd, b'r') + .and_then(|file| Capture::new_raw(None, |_, err| unsafe { + raw::pcap_fopen_offline(file, err) + })); +} + +fn issue1466() { + let vertex_buffer = frame.scope(|ctx| { + let buffer = + ctx.create_host_visible_buffer::<VertexBuffer<Vertex>>(&vertices); + ctx.create_device_local_buffer(buffer) + }); +} + +fn issue470() { + {{{ + let explicit_arg_decls = + explicit_arguments.into_iter() + .enumerate() + .map(|(index, (ty, pattern))| { + let lvalue = Lvalue::Arg(index as u32); + block = this.pattern(block, + argument_extent, + hair::PatternRef::Hair(pattern), + &lvalue); + ArgDecl { ty: ty } + }); + }}} +} + +// #1509 +impl Foo { + pub fn bar(&self) { + Some(SomeType { + push_closure_out_to_100_chars: iter(otherwise_it_works_ok.into_iter().map(|f| { + Ok(f) + })), + }) + } +} + +fn issue1329() { + aaaaaaaaaaaaaaaa.map(|x| { + x += 1; + x + }) + .filter +} + +fn issue325() { + let f = || unsafe { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }; +} + +fn issue1697() { + Test.func_a(A_VERY_LONG_CONST_VARIABLE_NAME, move |arg1, arg2, arg3, arg4| arg1 + arg2 + arg3 + arg4) +} + +fn issue1694() { + foooooo(|_referencefffffffff: _, _target_reference: _, _oid: _, _target_oid: _| format!("refs/pull/{}/merge", pr_id)) +} + +fn issue1713() { + rayon::join( + || recurse(left, is_less, pred, limit), + || recurse(right, is_less, Some(pivot), limit), + ); + + rayon::join( + 1, + || recurse(left, is_less, pred, limit), + 2, + || recurse(right, is_less, Some(pivot), limit), + ); +} + +fn issue2063() { + |ctx: Ctx<(String, String)>| -> io::Result<Response> { + Ok(Response::new().with_body(ctx.params.0)) + } +} + +fn issue1524() { + let f = |x| {{{{x}}}}; + let f = |x| {{{x}}}; + let f = |x| {{x}}; + let f = |x| {x}; + let f = |x| x; +} + +fn issue2171() { + foo(|| unsafe { + if PERIPHERALS { + loop {} + } else { + PERIPHERALS = true; + } + }) +} + +fn issue2207() { + a.map(|_| unsafe { + a_very_very_very_very_very_very_very_long_function_name_or_anything_else() + }.to_string()) +} + +fn issue2262() { + result.init(&mut result.slave.borrow_mut(), &mut (result.strategy)()).map_err(|factory| Error { + factory, + slave: None, + })?; +} diff --git a/src/tools/rustfmt/tests/source/comment.rs b/src/tools/rustfmt/tests/source/comment.rs new file mode 100644 index 000000000..b6ce5267f --- /dev/null +++ b/src/tools/rustfmt/tests/source/comment.rs @@ -0,0 +1,90 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +//! Doc comment +fn test() { + /*! + * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam */ + +// comment + // comment2 + + code(); /* leave this comment alone! + * ok? */ + + /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a + * diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam + * viverra nec consectetur ante hendrerit. Donec et mollis dolor. + * Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam + * tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut + * libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit + * amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis + * felis, pulvinar a semper sed, adipiscing id dolor. */ + + // Very looooooooooooooooooooooooooooooooooooooooooooooooooooooooong comment that should be split + + // println!("{:?}", rewrite_comment(subslice, + // false, + // comment_width, + // self.block_indent, + // self.config) + // .unwrap()); + + funk(); //dontchangeme + // or me + + // #1388 + const EXCEPTION_PATHS: &'static [&'static str] = + &[// std crates + "src/libstd/sys/", // Platform-specific code for std lives here. + "src/bootstrap"]; +} + + /// test123 +fn doc_comment() { +} + +fn chains() { + foo.bar(|| { + let x = 10; + /* comment */ x }) +} + +fn issue_1086() { + /**/ +} + +/* + * random comment */ + +fn main() {/* Test */} + +// #1643 +fn some_fn() /* some comment */ +{ +} + +fn some_fn1() +// some comment +{ +} + +fn some_fn2() // some comment +{ +} + +fn some_fn3() /* some comment some comment some comment some comment some comment some comment so */ +{ +} + +fn some_fn4() +/* some comment some comment some comment some comment some comment some comment some comment */ +{ +} + +// #1603 +pub enum Foo { + A, // `/** **/` + B, // `/*!` + C, +} diff --git a/src/tools/rustfmt/tests/source/comment2.rs b/src/tools/rustfmt/tests/source/comment2.rs new file mode 100644 index 000000000..d68bb5483 --- /dev/null +++ b/src/tools/rustfmt/tests/source/comment2.rs @@ -0,0 +1,4 @@ +// rustfmt-wrap_comments: true + +/// This is a long line that angers rustfmt. Rustfmt shall deal with it swiftly and justly. +pub mod foo {} diff --git a/src/tools/rustfmt/tests/source/comment3.rs b/src/tools/rustfmt/tests/source/comment3.rs new file mode 100644 index 000000000..f19a85863 --- /dev/null +++ b/src/tools/rustfmt/tests/source/comment3.rs @@ -0,0 +1,5 @@ +// rustfmt-wrap_comments: true + +//! This is a long line that angers rustfmt. Rustfmt shall deal with it swiftly and justly. + +pub mod foo {} diff --git a/src/tools/rustfmt/tests/source/comment4.rs b/src/tools/rustfmt/tests/source/comment4.rs new file mode 100644 index 000000000..f53a8a4a1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/comment4.rs @@ -0,0 +1,52 @@ +#![allow(dead_code)] // bar + +//! Doc comment +fn test() { +// comment + // comment2 + + code(); /* leave this comment alone! + * ok? */ + + /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a + * diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam + * viverra nec consectetur ante hendrerit. Donec et mollis dolor. + * Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam + * tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut + * libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit + * amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis + * felis, pulvinar a semper sed, adipiscing id dolor. */ + + // Very loooooooooooooooooooooooooooooooooooooooooooooooooooooooong comment that should be split + + // println!("{:?}", rewrite_comment(subslice, + // false, + // comment_width, + // self.block_indent, + // self.config) + // .unwrap()); + + funk(); //dontchangeme + // or me +} + + /// test123 +fn doc_comment() { +} + +/* +Regression test for issue #956 + +(some very important text) +*/ + +/* +fn debug_function() { + println!("hello"); +} +// */ + +#[link_section=".vectors"] +#[no_mangle] // Test this attribute is preserved. +#[cfg_attr(rustfmt, rustfmt::skip)] +pub static ISSUE_1284: [i32; 16] = []; diff --git a/src/tools/rustfmt/tests/source/comment5.rs b/src/tools/rustfmt/tests/source/comment5.rs new file mode 100644 index 000000000..2835d8b25 --- /dev/null +++ b/src/tools/rustfmt/tests/source/comment5.rs @@ -0,0 +1,14 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +//@ special comment +//@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec adiam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam +//@ +//@foo +fn test() {} + +//@@@ another special comment +//@@@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec adiam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam +//@@@ +//@@@foo +fn bar() {} diff --git a/src/tools/rustfmt/tests/source/comment6.rs b/src/tools/rustfmt/tests/source/comment6.rs new file mode 100644 index 000000000..e5d72113c --- /dev/null +++ b/src/tools/rustfmt/tests/source/comment6.rs @@ -0,0 +1,10 @@ +// rustfmt-wrap_comments: true + +// Pendant la nuit du 9 mars 1860, les nuages, se confondant avec la mer, limitaient à quelques brasses la portée de la vue. +// Sur cette mer démontée, dont les lames déferlaient en projetant des lueurs livides, un léger bâtiment fuyait presque à sec de toile. + +pub mod foo {} + +// ゆく河の流れは絶えずして、しかももとの水にあらず。淀みに浮かぶうたかたは、かつ消えかつ結びて、久しくとどまりたるためしなし。世の中にある人とすみかと、またかくのごとし。 + +pub mod bar {} diff --git a/src/tools/rustfmt/tests/source/comment_crlf_newline.rs b/src/tools/rustfmt/tests/source/comment_crlf_newline.rs new file mode 100644 index 000000000..7a65f762f --- /dev/null +++ b/src/tools/rustfmt/tests/source/comment_crlf_newline.rs @@ -0,0 +1,4 @@ +// rustfmt-normalize_comments: true
+/* Block comments followed by CRLF newlines should not an extra newline at the end */
+
+/* Something else */
diff --git a/src/tools/rustfmt/tests/source/comments-in-lists/wrap-comments-not-normalized.rs b/src/tools/rustfmt/tests/source/comments-in-lists/wrap-comments-not-normalized.rs new file mode 100644 index 000000000..b96c02802 --- /dev/null +++ b/src/tools/rustfmt/tests/source/comments-in-lists/wrap-comments-not-normalized.rs @@ -0,0 +1,129 @@ +// rustfmt-wrap_comments: true + +// https://github.com/rust-lang/rustfmt/issues/4909 +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec<i32> = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } + + match a { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + } +} diff --git a/src/tools/rustfmt/tests/source/comments-in-lists/wrap-comments-true.rs b/src/tools/rustfmt/tests/source/comments-in-lists/wrap-comments-true.rs new file mode 100644 index 000000000..360b83852 --- /dev/null +++ b/src/tools/rustfmt/tests/source/comments-in-lists/wrap-comments-true.rs @@ -0,0 +1,130 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +// https://github.com/rust-lang/rustfmt/issues/4909 +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec<i32> = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } + + match a { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + } +} diff --git a/src/tools/rustfmt/tests/source/configs/blank_lines_lower_bound/1.rs b/src/tools/rustfmt/tests/source/configs/blank_lines_lower_bound/1.rs new file mode 100644 index 000000000..c6058a55b --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/blank_lines_lower_bound/1.rs @@ -0,0 +1,13 @@ +// rustfmt-blank_lines_lower_bound: 1 + +fn foo() {} +fn bar() {} +// comment +fn foobar() {} + +fn foo1() {} +fn bar1() {} + +// comment + +fn foobar1() {} diff --git a/src/tools/rustfmt/tests/source/configs/brace_style/fn_always_next_line.rs b/src/tools/rustfmt/tests/source/configs/brace_style/fn_always_next_line.rs new file mode 100644 index 000000000..d3bd9ac09 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/brace_style/fn_always_next_line.rs @@ -0,0 +1,14 @@ +// rustfmt-brace_style: AlwaysNextLine +// Function brace style + +fn lorem() { + // body +} + +fn lorem(ipsum: usize) { + // body +} + +fn lorem<T>(ipsum: T) where T: Add + Sub + Mul + Div { + // body +} diff --git a/src/tools/rustfmt/tests/source/configs/brace_style/fn_prefer_same_line.rs b/src/tools/rustfmt/tests/source/configs/brace_style/fn_prefer_same_line.rs new file mode 100644 index 000000000..78a449524 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/brace_style/fn_prefer_same_line.rs @@ -0,0 +1,14 @@ +// rustfmt-brace_style: PreferSameLine +// Function brace style + +fn lorem() { + // body +} + +fn lorem(ipsum: usize) { + // body +} + +fn lorem<T>(ipsum: T) where T: Add + Sub + Mul + Div { + // body +} diff --git a/src/tools/rustfmt/tests/source/configs/brace_style/fn_same_line_where.rs b/src/tools/rustfmt/tests/source/configs/brace_style/fn_same_line_where.rs new file mode 100644 index 000000000..3b78932e1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/brace_style/fn_same_line_where.rs @@ -0,0 +1,14 @@ +// rustfmt-brace_style: SameLineWhere +// Function brace style + +fn lorem() { + // body +} + +fn lorem(ipsum: usize) { + // body +} + +fn lorem<T>(ipsum: T) where T: Add + Sub + Mul + Div { + // body +} diff --git a/src/tools/rustfmt/tests/source/configs/brace_style/item_always_next_line.rs b/src/tools/rustfmt/tests/source/configs/brace_style/item_always_next_line.rs new file mode 100644 index 000000000..0cc19b34d --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/brace_style/item_always_next_line.rs @@ -0,0 +1,20 @@ +// rustfmt-brace_style: AlwaysNextLine +// Item brace style + +enum Foo {} + +struct Bar {} + +struct Lorem { + ipsum: bool, +} + +struct Dolor<T> where T: Eq { + sit: T, +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() {} +} diff --git a/src/tools/rustfmt/tests/source/configs/brace_style/item_prefer_same_line.rs b/src/tools/rustfmt/tests/source/configs/brace_style/item_prefer_same_line.rs new file mode 100644 index 000000000..4412bc869 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/brace_style/item_prefer_same_line.rs @@ -0,0 +1,16 @@ +// rustfmt-brace_style: PreferSameLine +// Item brace style + +struct Lorem { + ipsum: bool, +} + +struct Dolor<T> where T: Eq { + sit: T, +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() {} +} diff --git a/src/tools/rustfmt/tests/source/configs/brace_style/item_same_line_where.rs b/src/tools/rustfmt/tests/source/configs/brace_style/item_same_line_where.rs new file mode 100644 index 000000000..b8e69147d --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/brace_style/item_same_line_where.rs @@ -0,0 +1,16 @@ +// rustfmt-brace_style: SameLineWhere +// Item brace style + +struct Lorem { + ipsum: bool, +} + +struct Dolor<T> where T: Eq { + sit: T, +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() {} +} diff --git a/src/tools/rustfmt/tests/source/configs/chain_width/always.rs b/src/tools/rustfmt/tests/source/configs/chain_width/always.rs new file mode 100644 index 000000000..2d16d66ae --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/chain_width/always.rs @@ -0,0 +1,23 @@ +// rustfmt-chain_width: 1 +// setting an unachievable chain_width to always get chains +// on separate lines + +struct Fluent {} + +impl Fluent { + fn blorp(&self) -> &Self { + self + } +} + +fn main() { + let test = Fluent {}; + + // should be left alone + test.blorp(); + + // should be wrapped + test.blorp().blorp(); + test.blorp().blorp().blorp(); + test.blorp().blorp().blorp().blorp(); +} diff --git a/src/tools/rustfmt/tests/source/configs/chain_width/small.rs b/src/tools/rustfmt/tests/source/configs/chain_width/small.rs new file mode 100644 index 000000000..26f935453 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/chain_width/small.rs @@ -0,0 +1,23 @@ +// rustfmt-chain_width: 40 + +struct Fluent {} + +impl Fluent { + fn blorp(&self) -> &Self { + self + } +} + +fn main() { + let test = Fluent {}; + + // should not be wrapped + test.blorp(); + test.blorp().blorp(); + test.blorp().blorp().blorp(); + test.blorp().blorp().blorp().blorp(); + + // should be wrapped + test.blorp().blorp().blorp().blorp().blorp(); + test.blorp().blorp().blorp().blorp().blorp().blorp(); +} diff --git a/src/tools/rustfmt/tests/source/configs/chain_width/tiny.rs b/src/tools/rustfmt/tests/source/configs/chain_width/tiny.rs new file mode 100644 index 000000000..fffc81dd5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/chain_width/tiny.rs @@ -0,0 +1,21 @@ +// rustfmt-chain_width: 20 + +struct Fluent {} + +impl Fluent { + fn blorp(&self) -> &Self { + self + } +} + +fn main() { + let test = Fluent {}; + + // should not be wrapped + test.blorp(); + test.blorp().blorp(); + + // should be wrapped + test.blorp().blorp().blorp(); + test.blorp().blorp().blorp().blorp(); +} diff --git a/src/tools/rustfmt/tests/source/configs/comment_width/above.rs b/src/tools/rustfmt/tests/source/configs/comment_width/above.rs new file mode 100644 index 000000000..36187ce0a --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/comment_width/above.rs @@ -0,0 +1,7 @@ +// rustfmt-comment_width: 40 +// rustfmt-wrap_comments: true +// Comment width + +fn main() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. +} diff --git a/src/tools/rustfmt/tests/source/configs/comment_width/below.rs b/src/tools/rustfmt/tests/source/configs/comment_width/below.rs new file mode 100644 index 000000000..abbc5930c --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/comment_width/below.rs @@ -0,0 +1,7 @@ +// rustfmt-comment_width: 80 +// rustfmt-wrap_comments: true +// Comment width + +fn main() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. +} diff --git a/src/tools/rustfmt/tests/source/configs/comment_width/ignore.rs b/src/tools/rustfmt/tests/source/configs/comment_width/ignore.rs new file mode 100644 index 000000000..c86e71c28 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/comment_width/ignore.rs @@ -0,0 +1,7 @@ +// rustfmt-comment_width: 40 +// rustfmt-wrap_comments: false +// Comment width + +fn main() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. +} diff --git a/src/tools/rustfmt/tests/source/configs/condense_wildcard_suffixes/false.rs b/src/tools/rustfmt/tests/source/configs/condense_wildcard_suffixes/false.rs new file mode 100644 index 000000000..3b967f35a --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/condense_wildcard_suffixes/false.rs @@ -0,0 +1,6 @@ +// rustfmt-condense_wildcard_suffixes: false +// Condense wildcard suffixes + +fn main() { + let (lorem, ipsum, _, _) = (1, 2, 3, 4); +} diff --git a/src/tools/rustfmt/tests/source/configs/condense_wildcard_suffixes/true.rs b/src/tools/rustfmt/tests/source/configs/condense_wildcard_suffixes/true.rs new file mode 100644 index 000000000..3798a6b99 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/condense_wildcard_suffixes/true.rs @@ -0,0 +1,6 @@ +// rustfmt-condense_wildcard_suffixes: true +// Condense wildcard suffixes + +fn main() { + let (lorem, ipsum, _, _) = (1, 2, 3, 4); +} diff --git a/src/tools/rustfmt/tests/source/configs/control_brace_style/always_next_line.rs b/src/tools/rustfmt/tests/source/configs/control_brace_style/always_next_line.rs new file mode 100644 index 000000000..c4ddad9ce --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/control_brace_style/always_next_line.rs @@ -0,0 +1,10 @@ +// rustfmt-control_brace_style: AlwaysNextLine +// Control brace style + +fn main() { + if lorem { println!("ipsum!"); } else { println!("dolor!"); } + match magi { + Homura => "Akemi", + Madoka => "Kaname", + } +} diff --git a/src/tools/rustfmt/tests/source/configs/control_brace_style/always_same_line.rs b/src/tools/rustfmt/tests/source/configs/control_brace_style/always_same_line.rs new file mode 100644 index 000000000..a9c699d27 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/control_brace_style/always_same_line.rs @@ -0,0 +1,10 @@ +// rustfmt-control_brace_style: AlwaysSameLine +// Control brace style + +fn main() { + if lorem { println!("ipsum!"); } else { println!("dolor!"); } + match magi { + Homura => "Akemi", + Madoka => "Kaname", + } +} diff --git a/src/tools/rustfmt/tests/source/configs/control_brace_style/closing_next_line.rs b/src/tools/rustfmt/tests/source/configs/control_brace_style/closing_next_line.rs new file mode 100644 index 000000000..1a74a28f2 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/control_brace_style/closing_next_line.rs @@ -0,0 +1,10 @@ +// rustfmt-control_brace_style: ClosingNextLine +// Control brace style + +fn main() { + if lorem { println!("ipsum!"); } else { println!("dolor!"); } + match magi { + Homura => "Akemi", + Madoka => "Kaname", + } +} diff --git a/src/tools/rustfmt/tests/source/configs/disable_all_formatting/false.rs b/src/tools/rustfmt/tests/source/configs/disable_all_formatting/false.rs new file mode 100644 index 000000000..834ca7a3c --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/disable_all_formatting/false.rs @@ -0,0 +1,6 @@ +// rustfmt-disable_all_formatting: false +// Disable all formatting + +fn main() { + if lorem{println!("ipsum!");}else{println!("dolor!");} +} diff --git a/src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs b/src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs new file mode 100644 index 000000000..56955bf38 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs @@ -0,0 +1,6 @@ +// rustfmt-disable_all_formatting: true +// Disable all formatting + +fn main() { + iflorem{println!("ipsum!");}else{println!("dolor!");} +} diff --git a/src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/100.rs b/src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/100.rs new file mode 100644 index 000000000..515780761 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/100.rs @@ -0,0 +1,16 @@ +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 100 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { +/// Self::from_bytes_manual_slice(v, 0, v.len() ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { + Self::from_bytes_manual_slice(v, 0, v.len() ) + } +} diff --git a/src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/100_greater_max_width.rs b/src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/100_greater_max_width.rs new file mode 100644 index 000000000..96505c697 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/100_greater_max_width.rs @@ -0,0 +1,17 @@ +// rustfmt-max_width: 50 +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 100 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { +/// Self::from_bytes_manual_slice(v, 0, v.len() ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { + Self::from_bytes_manual_slice(v, 0, v.len() ) + } +} diff --git a/src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/50.rs b/src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/50.rs new file mode 100644 index 000000000..2c6307951 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/50.rs @@ -0,0 +1,16 @@ +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 50 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { +/// Self::from_bytes_manual_slice(v, 0, v.len() ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { + Self::from_bytes_manual_slice(v, 0, v.len() ) + } +} diff --git a/src/tools/rustfmt/tests/source/configs/empty_item_single_line/false.rs b/src/tools/rustfmt/tests/source/configs/empty_item_single_line/false.rs new file mode 100644 index 000000000..9bfb2b964 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/empty_item_single_line/false.rs @@ -0,0 +1,16 @@ +// rustfmt-empty_item_single_line: false +// Empty impl on single line + +impl Lorem { + +} + +impl Ipsum { + +} + +fn lorem() { +} + +fn lorem() { +} diff --git a/src/tools/rustfmt/tests/source/configs/empty_item_single_line/true.rs b/src/tools/rustfmt/tests/source/configs/empty_item_single_line/true.rs new file mode 100644 index 000000000..8af8b88ff --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/empty_item_single_line/true.rs @@ -0,0 +1,16 @@ +// rustfmt-empty_item_single_line: true +// Empty impl on single line + +impl Lorem { + +} + +impl Ipsum { + +} + +fn lorem() { +} + +fn lorem() { +} diff --git a/src/tools/rustfmt/tests/source/configs/enum_discrim_align_threshold/40.rs b/src/tools/rustfmt/tests/source/configs/enum_discrim_align_threshold/40.rs new file mode 100644 index 000000000..796e47c38 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/enum_discrim_align_threshold/40.rs @@ -0,0 +1,34 @@ +// rustfmt-enum_discrim_align_threshold: 40
+
+enum Standard {
+ A = 1,
+ Bcdef = 2,
+}
+
+enum NoDiscrims {
+ ThisIsAFairlyLongEnumVariantWithoutDiscrimLongerThan40,
+ A = 1,
+ ThisIsAnotherFairlyLongEnumVariantWithoutDiscrimLongerThan40,
+ Bcdef = 2,
+}
+
+enum TooLong {
+ ThisOneHasDiscrimAaaaaaaaaaaaaaaaaaaaaaChar40 = 10,
+ A = 1,
+ Bcdef = 2,
+}
+
+enum Borderline {
+ ThisOneHasDiscrimAaaaaaaaaaaaaaaaaaaaaa = 10,
+ A = 1,
+ Bcdef = 2,
+}
+
+// Live specimen from #1686
+enum LongWithSmallDiff {
+ SceneColorimetryEstimates = 0x73636F65,
+ SceneAppearanceEstimates = 0x73617065,
+ FocalPlaneColorimetryEstimates = 0x66706365,
+ ReflectionHardcopyOriginalColorimetry = 0x72686F63,
+ ReflectionPrintOutputColorimetry = 0x72706F63,
+}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/configs/error_on_line_overflow/false.rs b/src/tools/rustfmt/tests/source/configs/error_on_line_overflow/false.rs new file mode 100644 index 000000000..fa70ae783 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/error_on_line_overflow/false.rs @@ -0,0 +1,6 @@ +// rustfmt-error_on_line_overflow: false +// Error on line overflow + +fn main() { + let lorem_ipsum_dolor_sit_amet_consectetur_adipiscing_elit_lorem_ipsum_dolor_sit_amet_consectetur_adipiscing_elit; +} diff --git a/src/tools/rustfmt/tests/source/configs/fn_args_layout/compressed.rs b/src/tools/rustfmt/tests/source/configs/fn_args_layout/compressed.rs new file mode 100644 index 000000000..66a371c25 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/fn_args_layout/compressed.rs @@ -0,0 +1,16 @@ +// rustfmt-fn_args_layout: Compressed +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit) { + // body + } +} diff --git a/src/tools/rustfmt/tests/source/configs/fn_args_layout/tall.rs b/src/tools/rustfmt/tests/source/configs/fn_args_layout/tall.rs new file mode 100644 index 000000000..f11e86fd3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/fn_args_layout/tall.rs @@ -0,0 +1,16 @@ +// rustfmt-fn_args_layout: Tall +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit) { + // body + } +} diff --git a/src/tools/rustfmt/tests/source/configs/fn_args_layout/vertical.rs b/src/tools/rustfmt/tests/source/configs/fn_args_layout/vertical.rs new file mode 100644 index 000000000..a23cc0252 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/fn_args_layout/vertical.rs @@ -0,0 +1,16 @@ +// rustfmt-fn_args_layout: Vertical +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit) { + // body + } +} diff --git a/src/tools/rustfmt/tests/source/configs/fn_single_line/false.rs b/src/tools/rustfmt/tests/source/configs/fn_single_line/false.rs new file mode 100644 index 000000000..3d092f0c0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/fn_single_line/false.rs @@ -0,0 +1,11 @@ +// rustfmt-fn_single_line: false +// Single-expression function on single line + +fn lorem() -> usize { + 42 +} + +fn lorem() -> usize { + let ipsum = 42; + ipsum +} diff --git a/src/tools/rustfmt/tests/source/configs/fn_single_line/true.rs b/src/tools/rustfmt/tests/source/configs/fn_single_line/true.rs new file mode 100644 index 000000000..3cb0fdedf --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/fn_single_line/true.rs @@ -0,0 +1,11 @@ +// rustfmt-fn_single_line: true +// Single-expression function on single line + +fn lorem() -> usize { + 42 +} + +fn lorem() -> usize { + let ipsum = 42; + ipsum +} diff --git a/src/tools/rustfmt/tests/source/configs/force_explicit_abi/false.rs b/src/tools/rustfmt/tests/source/configs/force_explicit_abi/false.rs new file mode 100644 index 000000000..3c48f8e0c --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/force_explicit_abi/false.rs @@ -0,0 +1,6 @@ +// rustfmt-force_explicit_abi: false +// Force explicit abi + +extern { + pub static lorem: c_int; +} diff --git a/src/tools/rustfmt/tests/source/configs/force_explicit_abi/true.rs b/src/tools/rustfmt/tests/source/configs/force_explicit_abi/true.rs new file mode 100644 index 000000000..e5ff6cf7d --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/force_explicit_abi/true.rs @@ -0,0 +1,6 @@ +// rustfmt-force_explicit_abi: true +// Force explicit abi + +extern { + pub static lorem: c_int; +} diff --git a/src/tools/rustfmt/tests/source/configs/force_multiline_block/false.rs b/src/tools/rustfmt/tests/source/configs/force_multiline_block/false.rs new file mode 100644 index 000000000..b97e348e5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/force_multiline_block/false.rs @@ -0,0 +1,22 @@ +// rustfmt-force_multiline_blocks: false +// Option forces multiline match arm and closure bodies to be wrapped in a block + +fn main() { + match lorem { + Lorem::Ipsum => { + if ipsum { + println!("dolor"); + } + } + Lorem::Dolor => println!("amet"), + } +} + +fn main() { + result.and_then(|maybe_value| { + match maybe_value { + None => Err("oops"), + Some(value) => Ok(1), + } + }); +} diff --git a/src/tools/rustfmt/tests/source/configs/force_multiline_block/true.rs b/src/tools/rustfmt/tests/source/configs/force_multiline_block/true.rs new file mode 100644 index 000000000..db9d3de46 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/force_multiline_block/true.rs @@ -0,0 +1,18 @@ +// rustfmt-force_multiline_blocks: true +// Option forces multiline match arm and closure bodies to be wrapped in a block + +fn main() { + match lorem { + Lorem::Ipsum => if ipsum { + println!("dolor"); + }, + Lorem::Dolor => println!("amet"), + } +} + +fn main() { + result.and_then(|maybe_value| match maybe_value { + None => Err("oops"), + Some(value) => Ok(1), + }); +} diff --git a/src/tools/rustfmt/tests/source/configs/format_generated_files/false.rs b/src/tools/rustfmt/tests/source/configs/format_generated_files/false.rs new file mode 100644 index 000000000..dec1e00d1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/format_generated_files/false.rs @@ -0,0 +1,8 @@ +// @generated +// rustfmt-format_generated_files: false + +fn main() +{ + println!("hello, world") + ; +} diff --git a/src/tools/rustfmt/tests/source/configs/format_generated_files/true.rs b/src/tools/rustfmt/tests/source/configs/format_generated_files/true.rs new file mode 100644 index 000000000..a25ddc25a --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/format_generated_files/true.rs @@ -0,0 +1,8 @@ +// @generated +// rustfmt-format_generated_files: true + +fn main() +{ + println!("hello, world") + ; +} diff --git a/src/tools/rustfmt/tests/source/configs/format_macro_bodies/false.rs b/src/tools/rustfmt/tests/source/configs/format_macro_bodies/false.rs new file mode 100644 index 000000000..d618a1ac3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/format_macro_bodies/false.rs @@ -0,0 +1,7 @@ +// rustfmt-format_macro_bodies: false + +macro_rules! foo { + ($a: ident : $b: ty) => { $a(42): $b; }; + ($a: ident $b: ident $c: ident) => { $a=$b+$c; }; +} + diff --git a/src/tools/rustfmt/tests/source/configs/format_macro_bodies/true.rs b/src/tools/rustfmt/tests/source/configs/format_macro_bodies/true.rs new file mode 100644 index 000000000..b254b82d7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/format_macro_bodies/true.rs @@ -0,0 +1,7 @@ +// rustfmt-format_macro_bodies: true + +macro_rules! foo { + ($a: ident : $b: ty) => { $a(42): $b; }; + ($a: ident $b: ident $c: ident) => { $a=$b+$c; }; +} + diff --git a/src/tools/rustfmt/tests/source/configs/format_macro_matchers/false.rs b/src/tools/rustfmt/tests/source/configs/format_macro_matchers/false.rs new file mode 100644 index 000000000..a721bb55c --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/format_macro_matchers/false.rs @@ -0,0 +1,7 @@ +// rustfmt-format_macro_matchers: false + +macro_rules! foo { + ($a: ident : $b: ty) => { $a(42): $b; }; + ($a: ident $b: ident $c: ident) => { $a=$b+$c; }; +} + diff --git a/src/tools/rustfmt/tests/source/configs/format_macro_matchers/true.rs b/src/tools/rustfmt/tests/source/configs/format_macro_matchers/true.rs new file mode 100644 index 000000000..fa0442e22 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/format_macro_matchers/true.rs @@ -0,0 +1,6 @@ +// rustfmt-format_macro_matchers: true + +macro_rules! foo { + ($a: ident : $b: ty) => { $a(42): $b; }; + ($a: ident $b: ident $c: ident) => { $a=$b+$c; }; +} diff --git a/src/tools/rustfmt/tests/source/configs/format_strings/false.rs b/src/tools/rustfmt/tests/source/configs/format_strings/false.rs new file mode 100644 index 000000000..ecca0d7d1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/format_strings/false.rs @@ -0,0 +1,8 @@ +// rustfmt-format_strings: false +// rustfmt-max_width: 50 +// rustfmt-error_on_line_overflow: false +// Force format strings + +fn main() { + let lorem = "ipsum dolor sit amet consectetur adipiscing elit lorem ipsum dolor sit"; +} diff --git a/src/tools/rustfmt/tests/source/configs/format_strings/true.rs b/src/tools/rustfmt/tests/source/configs/format_strings/true.rs new file mode 100644 index 000000000..337314478 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/format_strings/true.rs @@ -0,0 +1,7 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 +// Force format strings + +fn main() { + let lorem = "ipsum dolor sit amet consectetur adipiscing elit lorem ipsum dolor sit"; +} diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/One-merge_imports.rs b/src/tools/rustfmt/tests/source/configs/group_imports/One-merge_imports.rs new file mode 100644 index 000000000..157d38579 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/group_imports/One-merge_imports.rs @@ -0,0 +1,17 @@ +// rustfmt-group_imports: One +// rustfmt-imports_granularity: Crate +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; +use alloc::vec::Vec; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/One-nested.rs b/src/tools/rustfmt/tests/source/configs/group_imports/One-nested.rs new file mode 100644 index 000000000..109bd07e1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/group_imports/One-nested.rs @@ -0,0 +1,7 @@ +// rustfmt-group_imports: One +mod test { + use crate::foo::bar; + + use std::path; + use crate::foo::bar2; +} diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/One-no_reorder.rs b/src/tools/rustfmt/tests/source/configs/group_imports/One-no_reorder.rs new file mode 100644 index 000000000..f82f62c7f --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/group_imports/One-no_reorder.rs @@ -0,0 +1,16 @@ +// rustfmt-group_imports: One +// rustfmt-reorder_imports: false +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/One.rs b/src/tools/rustfmt/tests/source/configs/group_imports/One.rs new file mode 100644 index 000000000..5ab7a9508 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/group_imports/One.rs @@ -0,0 +1,15 @@ +// rustfmt-group_imports: One +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-merge_imports.rs b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-merge_imports.rs new file mode 100644 index 000000000..ea7f6280a --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-merge_imports.rs @@ -0,0 +1,17 @@ +// rustfmt-group_imports: StdExternalCrate +// rustfmt-imports_granularity: Crate +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; +use alloc::vec::Vec; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-nested.rs b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-nested.rs new file mode 100644 index 000000000..08f4e07b7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-nested.rs @@ -0,0 +1,6 @@ +// rustfmt-group_imports: StdExternalCrate +mod test { + use crate::foo::bar; + use std::path; + use crate::foo::bar2; +} diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-no_reorder.rs b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-no_reorder.rs new file mode 100644 index 000000000..08c9a72ae --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-no_reorder.rs @@ -0,0 +1,17 @@ +// rustfmt-group_imports: StdExternalCrate +// rustfmt-reorder_imports: false + +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-non_consecutive.rs b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-non_consecutive.rs new file mode 100644 index 000000000..f239a0efa --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-non_consecutive.rs @@ -0,0 +1,27 @@ +// rustfmt-group_imports: StdExternalCrate +use chrono::Utc; +use super::update::convert_publish_payload; + + + + + +use juniper::{FieldError, FieldResult}; + +use uuid::Uuid; +use alloc::alloc::Layout; + +extern crate uuid; + + + + + +use std::sync::Arc; + + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate.rs b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate.rs new file mode 100644 index 000000000..d49c8941e --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate.rs @@ -0,0 +1,15 @@ +// rustfmt-group_imports: StdExternalCrate +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/source/configs/hard_tabs/false.rs b/src/tools/rustfmt/tests/source/configs/hard_tabs/false.rs new file mode 100644 index 000000000..bf92162b4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/hard_tabs/false.rs @@ -0,0 +1,6 @@ +// rustfmt-hard_tabs: false +// Hard tabs + +fn lorem() -> usize { +42 // spaces before 42 +} diff --git a/src/tools/rustfmt/tests/source/configs/hard_tabs/true.rs b/src/tools/rustfmt/tests/source/configs/hard_tabs/true.rs new file mode 100644 index 000000000..738922a4d --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/hard_tabs/true.rs @@ -0,0 +1,6 @@ +// rustfmt-hard_tabs: true +// Hard tabs + +fn lorem() -> usize { +42 // spaces before 42 +} diff --git a/src/tools/rustfmt/tests/source/configs/imports_layout/merge_mixed.rs b/src/tools/rustfmt/tests/source/configs/imports_layout/merge_mixed.rs new file mode 100644 index 000000000..477c4aa16 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/imports_layout/merge_mixed.rs @@ -0,0 +1,6 @@ +// rustfmt-imports_indent: Block +// rustfmt-imports_granularity: Crate +// rustfmt-imports_layout: Mixed + +use std::{fmt, io, str}; +use std::str::FromStr; diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_args.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_args.rs new file mode 100644 index 000000000..4d2d280a1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_args.rs @@ -0,0 +1,26 @@ +// rustfmt-indent_style: Block +// Function arguments layout + +fn lorem() {} + +fn lorem(ipsum: usize) {} + +fn lorem(ipsum: usize, dolor: usize, sit: usize, amet: usize, consectetur: usize, adipiscing: usize, elit: usize) { + // body +} + +// #1441 +extern "system" { + pub fn GetConsoleHistoryInfo(console_history_info: *mut ConsoleHistoryInfo) -> Boooooooooooooool; +} + +// rustfmt should not add trailing comma for variadic function. See #1623. +extern "C" { + pub fn variadic_fn(first_parameter: FirstParameterType, + second_parameter: SecondParameterType, + ...); +} + +// #1652 +fn deconstruct(foo: Bar) -> (SocketAddr, Header, Method, RequestUri, HttpVersion, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) { +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_array.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_array.rs new file mode 100644 index 000000000..8404f65f4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_array.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Block +// Array layout + +fn main() { + let lorem = vec!["ipsum","dolor","sit","amet","consectetur","adipiscing","elit"]; +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_call.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_call.rs new file mode 100644 index 000000000..c82b6b8e3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_call.rs @@ -0,0 +1,133 @@ +// rustfmt-indent_style: Block +// Function call style + +fn main() { + lorem("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit"); + // #1501 + let hyper = Arc::new(Client::with_connector(HttpsConnector::new(TlsClient::new()))); + + // chain + let x = yooooooooooooo.fooooooooooooooo.baaaaaaaaaaaaar(hello, world); + + // #1380 + { + { + let creds = self.client + .client_credentials(&self.config.auth.oauth2.id, &self.config.auth.oauth2.secret)?; + } + } + + // nesting macro and function call + try!(foo(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)); + try!(foo(try!(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx))); +} + +// #1521 +impl Foo { + fn map_pixel_to_coords(&self, point: &Vector2i, view: &View) -> Vector2f { + unsafe { + Vector2f::from_raw(ffi::sfRenderTexture_mapPixelToCoords(self.render_texture, point.raw(), view.raw())) + } + } +} + +fn issue1420() { + given( + r#" + # Getting started + ... + "#, + ) + .running(waltz) +} + +// #1563 +fn query(conn: &Connection) -> Result<()> { + conn.query_row( + r#" + SELECT title, date + FROM posts, + WHERE DATE(date) = $1 + "#, + &[], + |row| { + Post { + title: row.get(0), + date: row.get(1), + } + }, + )?; + + Ok(()) +} + +// #1449 +fn future_rayon_wait_1_thread() { + // run with only 1 worker thread; this would deadlock if we couldn't make progress + let mut result = None; + ThreadPool::new(Configuration::new().num_threads(1)) + .unwrap() + .install( + || { + scope( + |s| { + use std::sync::mpsc::channel; + let (tx, rx) = channel(); + let a = s.spawn_future(lazy(move || Ok::<usize, ()>(rx.recv().unwrap()))); + // ^^^^ FIXME: why is this needed? + let b = s.spawn_future(a.map(|v| v + 1)); + let c = s.spawn_future(b.map(|v| v + 1)); + s.spawn(move |_| tx.send(20).unwrap()); + result = Some(c.rayon_wait().unwrap()); + }, + ); + }, + ); + assert_eq!(result, Some(22)); +} + +// #1494 +impl Cursor { + fn foo() { + self.cur_type() + .num_template_args() + .or_else(|| { + let n: c_int = unsafe { clang_Cursor_getNumTemplateArguments(self.x) }; + + if n >= 0 { + Some(n as u32) + } else { + debug_assert_eq!(n, -1); + None + } + }) + .or_else(|| { + let canonical = self.canonical(); + if canonical != *self { + canonical.num_template_args() + } else { + None + } + }); + } +} + +fn issue1581() { + bootstrap.checks.register( + "PERSISTED_LOCATIONS", + move || if locations2.0.inner_mut.lock().poisoned { + Check::new( + State::Error, + "Persisted location storage is poisoned due to a write failure", + ) + } else { + Check::new(State::Healthy, "Persisted location storage is healthy") + }, + ); +} + +fn issue1651() { + { + let type_list: Vec<_> = try_opt!(types.iter().map(|ty| ty.rewrite(context, shape)).collect()); + } +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_chain.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_chain.rs new file mode 100644 index 000000000..41d914691 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_chain.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Block +// Chain indent + +fn main() { + let lorem = ipsum.dolor().sit().amet().consectetur().adipiscing().elite(); +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_generic.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_generic.rs new file mode 100644 index 000000000..2cf17be56 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_generic.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Block +// Generics indent + +fn lorem<Ipsum: Eq = usize, Dolor: Eq = usize, Sit: Eq = usize, Amet: Eq = usize, Adipiscing: Eq = usize, Consectetur: Eq = usize, Elit: Eq = usize>(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, adipiscing: Adipiscing, consectetur: Consectetur, elit: Elit) -> T { + // body +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_struct_lit.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_struct_lit.rs new file mode 100644 index 000000000..47a6994f4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_struct_lit.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Block +// Struct literal-style + +fn main() { + let lorem = Lorem { ipsum: dolor, sit: amet }; +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/one.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/one.rs new file mode 100644 index 000000000..6d48ea742 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/one.rs @@ -0,0 +1,9 @@ +// rustfmt-version: One +// rustfmt-error_on_line_overflow: false +// rustfmt-indent_style: Block + +// rustfmt should not add trailing comma when rewriting macro. See #1528. +fn a() { + panic!("this is a long string that goes past the maximum line length causing rustfmt to insert a comma here:"); + foo(a, oooptoptoptoptptooptoptoptoptptooptoptoptoptptoptoptoptoptpt()); +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/two.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/two.rs new file mode 100644 index 000000000..7a62d722c --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/two.rs @@ -0,0 +1,9 @@ +// rustfmt-version: Two +// rustfmt-error_on_line_overflow: false +// rustfmt-indent_style: Block + +// rustfmt should not add trailing comma when rewriting macro. See #1528. +fn a() { + panic!("this is a long string that goes past the maximum line length causing rustfmt to insert a comma here:"); + foo(a, oooptoptoptoptptooptoptoptoptptooptoptoptoptptoptoptoptoptpt()); +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_where_pred.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_where_pred.rs new file mode 100644 index 000000000..450491f02 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_where_pred.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Block +// Where predicate indent + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T where Ipsum: Eq, Dolor: Eq, Sit: Eq, Amet: Eq { + // body +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/default.rs b/src/tools/rustfmt/tests/source/configs/indent_style/default.rs new file mode 100644 index 000000000..f08f5c644 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/default.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Visual +// Where style + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T where Ipsum: Eq, Dolor: Eq, Sit: Eq, Amet: Eq { + // body +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/rfc_where.rs b/src/tools/rustfmt/tests/source/configs/indent_style/rfc_where.rs new file mode 100644 index 000000000..012840be2 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/rfc_where.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Block +// Where style + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T where Ipsum: Eq, Dolor: Eq, Sit: Eq, Amet: Eq { + // body +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/visual_args.rs b/src/tools/rustfmt/tests/source/configs/indent_style/visual_args.rs new file mode 100644 index 000000000..5aa28a62b --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/visual_args.rs @@ -0,0 +1,32 @@ +// rustfmt-indent_style: Visual +// Function arguments layout + +fn lorem() {} + +fn lorem(ipsum: usize) {} + +fn lorem(ipsum: usize, dolor: usize, sit: usize, amet: usize, consectetur: usize, adipiscing: usize, elit: usize) { + // body +} + +// #1922 +extern "C" { + pub fn LAPACKE_csytrs_rook_work(matrix_layout: c_int, + uplo: c_char, + n: lapack_int, + nrhs: lapack_int, + a: *const lapack_complex_float, + lda: lapack_int, ipiv: *const lapack_int, + b: *mut lapack_complex_float, + ldb: lapack_int + )-> lapack_int; + + pub fn LAPACKE_csytrs_rook_work(matrix_layout: c_int, + uplo: c_char, + n: lapack_int, + nrhs: lapack_int, + lda: lapack_int, ipiv: *const lapack_int, + b: *mut lapack_complex_float, + ldb: lapack_int + ) -> lapack_int; +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/visual_array.rs b/src/tools/rustfmt/tests/source/configs/indent_style/visual_array.rs new file mode 100644 index 000000000..05bbf00b1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/visual_array.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Visual +// Array layout + +fn main() { + let lorem = vec!["ipsum","dolor","sit","amet","consectetur","adipiscing","elit"]; +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/visual_call.rs b/src/tools/rustfmt/tests/source/configs/indent_style/visual_call.rs new file mode 100644 index 000000000..9a679d6bb --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/visual_call.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Visual +// Function call style + +fn main() { + lorem("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit"); +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/visual_chain.rs b/src/tools/rustfmt/tests/source/configs/indent_style/visual_chain.rs new file mode 100644 index 000000000..b74948753 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/visual_chain.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Visual +// Chain indent + +fn main() { + let lorem = ipsum.dolor().sit().amet().consectetur().adipiscing().elite(); +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/visual_generics.rs b/src/tools/rustfmt/tests/source/configs/indent_style/visual_generics.rs new file mode 100644 index 000000000..1f910d32d --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/visual_generics.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Visual +// Generics indent + +fn lorem<Ipsum: Eq = usize, Dolor: Eq = usize, Sit: Eq = usize, Amet: Eq = usize, Adipiscing: Eq = usize, Consectetur: Eq = usize, Elit: Eq = usize>(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, adipiscing: Adipiscing, consectetur: Consectetur, elit: Elit) -> T { + // body +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/visual_struct_lit.rs b/src/tools/rustfmt/tests/source/configs/indent_style/visual_struct_lit.rs new file mode 100644 index 000000000..45538e704 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/visual_struct_lit.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Visual +// Struct literal-style + +fn main() { + let lorem = Lorem { ipsum: dolor, sit: amet }; +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/visual_trailing_comma.rs b/src/tools/rustfmt/tests/source/configs/indent_style/visual_trailing_comma.rs new file mode 100644 index 000000000..9738d397d --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/visual_trailing_comma.rs @@ -0,0 +1,7 @@ +// rustfmt-error_on_line_overflow: false +// rustfmt-indent_style: Visual + +// rustfmt should not add trailing comma when rewriting macro. See #1528. +fn a() { + panic!("this is a long string that goes past the maximum line length causing rustfmt to insert a comma here:"); +} diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/visual_where_pred.rs b/src/tools/rustfmt/tests/source/configs/indent_style/visual_where_pred.rs new file mode 100644 index 000000000..055806b68 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/indent_style/visual_where_pred.rs @@ -0,0 +1,6 @@ +// rustfmt-indent_style: Visual +// Where predicate indent + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T where Ipsum: Eq, Dolor: Eq, Sit: Eq, Amet: Eq { + // body +} diff --git a/src/tools/rustfmt/tests/source/configs/match_arm_blocks/false.rs b/src/tools/rustfmt/tests/source/configs/match_arm_blocks/false.rs new file mode 100644 index 000000000..53e37e13c --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/match_arm_blocks/false.rs @@ -0,0 +1,11 @@ +// rustfmt-match_arm_blocks: false +// Wrap match-arms + +fn main() { + match lorem { + true => foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(x), + false => { + println!("{}", sit) + } + } +} diff --git a/src/tools/rustfmt/tests/source/configs/match_arm_blocks/true.rs b/src/tools/rustfmt/tests/source/configs/match_arm_blocks/true.rs new file mode 100644 index 000000000..a452b13cd --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/match_arm_blocks/true.rs @@ -0,0 +1,11 @@ +// rustfmt-match_arm_blocks: true +// Wrap match-arms + +fn main() { + match lorem { + true => foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(x), + false => { + println!("{}", sit) + } + } +} diff --git a/src/tools/rustfmt/tests/source/configs/match_arm_leading_pipes/always.rs b/src/tools/rustfmt/tests/source/configs/match_arm_leading_pipes/always.rs new file mode 100644 index 000000000..162d812d8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/match_arm_leading_pipes/always.rs @@ -0,0 +1,27 @@ +// rustfmt-match_arm_leading_pipes: Always + +fn foo() { + match foo { + "foo" | "bar" => {} + "baz" + | "something relatively long" + | "something really really really realllllllllllllly long" => println!("x"), + "qux" => println!("y"), + _ => {} + } +} + +fn issue_3973() { + match foo { + "foo" | "bar" => {} + _ => {} + } +} + +fn bar() { + match baz { + "qux" => {} + "foo" | "bar" => {} + _ => {} + } +} diff --git a/src/tools/rustfmt/tests/source/configs/match_arm_leading_pipes/never.rs b/src/tools/rustfmt/tests/source/configs/match_arm_leading_pipes/never.rs new file mode 100644 index 000000000..8a68fe214 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/match_arm_leading_pipes/never.rs @@ -0,0 +1,28 @@ +// rustfmt-match_arm_leading_pipes: Never + +fn foo() { + match foo { + | "foo" | "bar" => {} + | "baz" + | "something relatively long" + | "something really really really realllllllllllllly long" => println!("x"), + | "qux" => println!("y"), + _ => {} + } +} + +fn issue_3973() { + match foo { + | "foo" + | "bar" => {} + _ => {} + } +} + +fn bar() { + match baz { + "qux" => {} + "foo" | "bar" => {} + _ => {} + } +} diff --git a/src/tools/rustfmt/tests/source/configs/match_arm_leading_pipes/preserve.rs b/src/tools/rustfmt/tests/source/configs/match_arm_leading_pipes/preserve.rs new file mode 100644 index 000000000..5486877bd --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/match_arm_leading_pipes/preserve.rs @@ -0,0 +1,36 @@ +// rustfmt-match_arm_leading_pipes: Preserve + +fn foo() { + match foo { + | "foo" | "bar" => {} + | "baz" + | "something relatively long" + | "something really really really realllllllllllllly long" => println!("x"), + | "qux" => println!("y"), + _ => {} + } +} + +fn issue_3973() { + match foo { + | "foo" + | "bar" => {} + _ => {} + } +} + +fn bar() { + match baz { + "qux" => { } + "foo" | "bar" => {} + _ => {} + } +} + +fn f(x: NonAscii) -> bool { + match x { + // foo + | Éfgh => true, + _ => false, + } +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/configs/match_block_trailing_comma/false.rs b/src/tools/rustfmt/tests/source/configs/match_block_trailing_comma/false.rs new file mode 100644 index 000000000..70e02955f --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/match_block_trailing_comma/false.rs @@ -0,0 +1,11 @@ +// rustfmt-match_block_trailing_comma: false +// Match block trailing comma + +fn main() { + match lorem { + Lorem::Ipsum => { + println!("ipsum"); + } + Lorem::Dolor => println!("dolor"), + } +} diff --git a/src/tools/rustfmt/tests/source/configs/match_block_trailing_comma/true.rs b/src/tools/rustfmt/tests/source/configs/match_block_trailing_comma/true.rs new file mode 100644 index 000000000..b9af3d472 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/match_block_trailing_comma/true.rs @@ -0,0 +1,11 @@ +// rustfmt-match_block_trailing_comma: true +// Match block trailing comma + +fn main() { + match lorem { + Lorem::Ipsum => { + println!("ipsum"); + } + Lorem::Dolor => println!("dolor"), + } +} diff --git a/src/tools/rustfmt/tests/source/configs/merge_derives/true.rs b/src/tools/rustfmt/tests/source/configs/merge_derives/true.rs new file mode 100644 index 000000000..18b8443f0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/merge_derives/true.rs @@ -0,0 +1,46 @@ +// rustfmt-merge_derives: true +// Merge multiple derives to a single one. + +#[bar] +#[derive(Eq, PartialEq)] +#[foo] +#[derive(Debug)] +#[foobar] +#[derive(Copy, Clone)] +pub enum Foo {} + +#[derive(Eq, PartialEq)] +#[derive(Debug)] +#[foobar] +#[derive(Copy, Clone)] +pub enum Bar {} + +#[derive(Eq, PartialEq)] +#[derive(Debug)] +#[derive(Copy, Clone)] +pub enum FooBar {} + +mod foo { +#[bar] +#[derive(Eq, PartialEq)] +#[foo] +#[derive(Debug)] +#[foobar] +#[derive(Copy, Clone)] +pub enum Foo {} +} + +mod bar { +#[derive(Eq, PartialEq)] +#[derive(Debug)] +#[foobar] +#[derive(Copy, Clone)] +pub enum Bar {} +} + +mod foobar { +#[derive(Eq, PartialEq)] +#[derive(Debug)] +#[derive(Copy, Clone)] +pub enum FooBar {} +} diff --git a/src/tools/rustfmt/tests/source/configs/normalize_comments/false.rs b/src/tools/rustfmt/tests/source/configs/normalize_comments/false.rs new file mode 100644 index 000000000..488962ed9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/normalize_comments/false.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_comments: false +// Normalize comments + +// Lorem ipsum: +fn dolor() -> usize {} + +/* sit amet: */ +fn adipiscing() -> usize {} + +// #652 +//////////////////////////////////////////////////////////////////////////////// +// Basic slice extension methods +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/tools/rustfmt/tests/source/configs/normalize_comments/true.rs b/src/tools/rustfmt/tests/source/configs/normalize_comments/true.rs new file mode 100644 index 000000000..c74a9808e --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/normalize_comments/true.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_comments: true +// Normalize comments + +// Lorem ipsum: +fn dolor() -> usize {} + +/* sit amet: */ +fn adipiscing() -> usize {} + +// #652 +//////////////////////////////////////////////////////////////////////////////// +// Basic slice extension methods +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/tools/rustfmt/tests/source/configs/normalize_doc_attributes/false.rs b/src/tools/rustfmt/tests/source/configs/normalize_doc_attributes/false.rs new file mode 100644 index 000000000..f8eb64273 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/normalize_doc_attributes/false.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_doc_attributes: false +// Normalize doc attributes + +#![doc = " Example documentation"] + +#[doc = " Example item documentation"] +pub enum Foo {} + +#[doc = " Lots of space"] +pub enum Bar {} + +#[doc = "no leading space"] +pub mod FooBar {} diff --git a/src/tools/rustfmt/tests/source/configs/normalize_doc_attributes/true.rs b/src/tools/rustfmt/tests/source/configs/normalize_doc_attributes/true.rs new file mode 100644 index 000000000..894c00a4d --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/normalize_doc_attributes/true.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_doc_attributes: true +// Normalize doc attributes + +#![doc = " Example documentation"] + +#[doc = " Example item documentation"] +pub enum Foo {} + +#[doc = " Lots of space"] +pub enum Bar {} + +#[doc = "no leading space"] +pub mod FooBar {} diff --git a/src/tools/rustfmt/tests/source/configs/remove_nested_parens/remove_nested_parens.rs b/src/tools/rustfmt/tests/source/configs/remove_nested_parens/remove_nested_parens.rs new file mode 100644 index 000000000..87aed09c1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/remove_nested_parens/remove_nested_parens.rs @@ -0,0 +1,5 @@ +// rustfmt-remove_nested_parens: true + +fn main() { + ((((((foo())))))); +} diff --git a/src/tools/rustfmt/tests/source/configs/reorder_impl_items/false.rs b/src/tools/rustfmt/tests/source/configs/reorder_impl_items/false.rs new file mode 100644 index 000000000..beb99f0fb --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_impl_items/false.rs @@ -0,0 +1,11 @@ +// rustfmt-reorder_impl_items: false + +struct Dummy; + +impl Iterator for Dummy { + fn next(&mut self) -> Option<Self::Item> { + None + } + + type Item = i32; +} diff --git a/src/tools/rustfmt/tests/source/configs/reorder_impl_items/true.rs b/src/tools/rustfmt/tests/source/configs/reorder_impl_items/true.rs new file mode 100644 index 000000000..612b1c84a --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_impl_items/true.rs @@ -0,0 +1,11 @@ +// rustfmt-reorder_impl_items: true + +struct Dummy; + +impl Iterator for Dummy { + fn next(&mut self) -> Option<Self::Item> { + None + } + + type Item = i32; +} diff --git a/src/tools/rustfmt/tests/source/configs/reorder_imports/false.rs b/src/tools/rustfmt/tests/source/configs/reorder_imports/false.rs new file mode 100644 index 000000000..4b85684dc --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_imports/false.rs @@ -0,0 +1,7 @@ +// rustfmt-reorder_imports: false +// Reorder imports + +use lorem; +use ipsum; +use dolor; +use sit; diff --git a/src/tools/rustfmt/tests/source/configs/reorder_imports/true.rs b/src/tools/rustfmt/tests/source/configs/reorder_imports/true.rs new file mode 100644 index 000000000..2a40f6d06 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_imports/true.rs @@ -0,0 +1,19 @@ +// rustfmt-reorder_imports: true +// Reorder imports + +use lorem; +use ipsum; +use dolor; +use sit; + +fn foo() { + use C; + use B; + use A; + + bar(); + + use F; + use E; + use D; +} diff --git a/src/tools/rustfmt/tests/source/configs/reorder_modules/dolor/mod.rs b/src/tools/rustfmt/tests/source/configs/reorder_modules/dolor/mod.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_modules/dolor/mod.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/source/configs/reorder_modules/false.rs b/src/tools/rustfmt/tests/source/configs/reorder_modules/false.rs new file mode 100644 index 000000000..56b1aa03e --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_modules/false.rs @@ -0,0 +1,7 @@ +// rustfmt-reorder_modules: false +// Reorder modules + +mod lorem; +mod ipsum; +mod dolor; +mod sit; diff --git a/src/tools/rustfmt/tests/source/configs/reorder_modules/ipsum/mod.rs b/src/tools/rustfmt/tests/source/configs/reorder_modules/ipsum/mod.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_modules/ipsum/mod.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/source/configs/reorder_modules/lorem/mod.rs b/src/tools/rustfmt/tests/source/configs/reorder_modules/lorem/mod.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_modules/lorem/mod.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/source/configs/reorder_modules/sit/mod.rs b/src/tools/rustfmt/tests/source/configs/reorder_modules/sit/mod.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_modules/sit/mod.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/source/configs/reorder_modules/true.rs b/src/tools/rustfmt/tests/source/configs/reorder_modules/true.rs new file mode 100644 index 000000000..79b0ab1e3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/reorder_modules/true.rs @@ -0,0 +1,7 @@ +// rustfmt-reorder_modules: true +// Reorder modules + +mod lorem; +mod ipsum; +mod dolor; +mod sit; diff --git a/src/tools/rustfmt/tests/source/configs/short_array_element_width_threshold/10.rs b/src/tools/rustfmt/tests/source/configs/short_array_element_width_threshold/10.rs new file mode 100644 index 000000000..7d0d70919 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/short_array_element_width_threshold/10.rs @@ -0,0 +1,11 @@ +// rustfmt-short_array_element_width_threshold: 10 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/configs/short_array_element_width_threshold/20.rs b/src/tools/rustfmt/tests/source/configs/short_array_element_width_threshold/20.rs new file mode 100644 index 000000000..8a93a51d6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/short_array_element_width_threshold/20.rs @@ -0,0 +1,11 @@ +// rustfmt-short_array_element_width_threshold: 20 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/configs/short_array_element_width_threshold/greater_than_max_width.rs b/src/tools/rustfmt/tests/source/configs/short_array_element_width_threshold/greater_than_max_width.rs new file mode 100644 index 000000000..710b6fe7c --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/short_array_element_width_threshold/greater_than_max_width.rs @@ -0,0 +1,12 @@ +// rustfmt-max_width: 20 +// rustfmt-short_array_element_width_threshold: 30 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} diff --git a/src/tools/rustfmt/tests/source/configs/skip_children/foo/mod.rs b/src/tools/rustfmt/tests/source/configs/skip_children/foo/mod.rs new file mode 100644 index 000000000..d7ff6cdb8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/skip_children/foo/mod.rs @@ -0,0 +1,3 @@ +fn skip_formatting_this() { + println ! ( "Skip this" ) ; +} diff --git a/src/tools/rustfmt/tests/source/configs/skip_children/true.rs b/src/tools/rustfmt/tests/source/configs/skip_children/true.rs new file mode 100644 index 000000000..e51889dd4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/skip_children/true.rs @@ -0,0 +1,4 @@ +// rustfmt-skip_children: true + +mod foo ; +mod void; diff --git a/src/tools/rustfmt/tests/source/configs/space_before_colon/true.rs b/src/tools/rustfmt/tests/source/configs/space_before_colon/true.rs new file mode 100644 index 000000000..0a5976025 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/space_before_colon/true.rs @@ -0,0 +1,11 @@ +// rustfmt-space_before_colon: true +// Space before colon + +fn lorem<T : Eq>(t : T) { + let ipsum: Dolor = sit; +} + +const LOREM : Lorem = Lorem { + ipsum : dolor, + sit : amet, +}; diff --git a/src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs b/src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs new file mode 100644 index 000000000..1878c68a5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs @@ -0,0 +1,34 @@ +// rustfmt-spaces_around_ranges: false +// Spaces around ranges + +fn main() { + let lorem = 0 .. 10; + let ipsum = 0 ..= 10; + + match lorem { + 1 .. 5 => foo(), + _ => bar, + } + + match lorem { + 1 ..= 5 => foo(), + _ => bar, + } + + match lorem { + 1 ... 5 => foo(), + _ => bar, + } +} + +fn half_open() { + match [5 .. 4, 99 .. 105, 43 .. 44] { + [_, 99 .., _] => {} + [_, .. 105, _] => {} + _ => {} + }; + + if let ..= 5 = 0 {} + if let .. 5 = 0 {} + if let 5 .. = 0 {} +} diff --git a/src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs b/src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs new file mode 100644 index 000000000..0eadfb285 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs @@ -0,0 +1,34 @@ +// rustfmt-spaces_around_ranges: true +// Spaces around ranges + +fn main() { + let lorem = 0..10; + let ipsum = 0..=10; + + match lorem { + 1..5 => foo(), + _ => bar, + } + + match lorem { + 1..=5 => foo(), + _ => bar, + } + + match lorem { + 1...5 => foo(), + _ => bar, + } +} + +fn half_open() { + match [5..4, 99..105, 43..44] { + [_, 99.., _] => {} + [_, ..105, _] => {} + _ => {} + }; + + if let ..=5 = 0 {} + if let ..5 = 0 {} + if let 5.. = 0 {} +} diff --git a/src/tools/rustfmt/tests/source/configs/struct_field_align_threshold/20.rs b/src/tools/rustfmt/tests/source/configs/struct_field_align_threshold/20.rs new file mode 100644 index 000000000..81253c460 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/struct_field_align_threshold/20.rs @@ -0,0 +1,383 @@ +// rustfmt-struct_field_align_threshold: 20 +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-error_on_line_overflow: false + +struct Foo { + x: u32, + yy: u32, // comment + zzz: u32, +} + +pub struct Bar { + x: u32, + yy: u32, + zzz: u32, + + xxxxxxx: u32, +} + +fn main() { + let foo = Foo { + x: 0, + yy: 1, + zzz: 2, + }; + + let bar = Bar { + x: 0, + yy: 1, + zzz: 2, + + xxxxxxx: 3, + }; +} + + /// A Doc comment +#[AnAttribute] +pub struct Foo { + #[rustfmt::skip] + f : SomeType, // Comment beside a field + f: SomeType, // Comment beside a field + // Comment on a field + #[AnAttribute] + g: SomeOtherType, + /// A doc comment on a field + h: AThirdType, + pub i: TypeForPublicField +} + +// #1029 +pub struct Foo { + #[doc(hidden)] + // This will NOT get deleted! + bar: String, // hi +} + +// #1029 +struct X { + // `x` is an important number. + #[allow(unused)] // TODO: use + x: u32, +} + +// #410 +#[allow(missing_docs)] +pub struct Writebatch<K: Key> { + #[allow(dead_code)] //only used for holding the internal pointer + writebatch: RawWritebatch, + marker: PhantomData<K>, +} + +struct Bar; + +struct NewType(Type, OtherType); + +struct +NewInt <T: Copy>(pub i32, SomeType /* inline comment */, T /* sup */ + + + ); + +struct Qux<'a, + N: Clone + 'a, + E: Clone + 'a, + G: Labeller<'a, N, E> + GraphWalk<'a, N, E>, + W: Write + Copy> +( + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // Comment + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, + #[AnAttr] + // Comment + /// Testdoc + G, + pub W, +); + +struct Tuple(/*Comment 1*/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + /* Comment 2 */ BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,); + +// With a where-clause and generics. +pub struct Foo<'a, Y: Baz> + where X: Whatever +{ + f: SomeType, // Comment beside a field +} + +struct Baz { + + a: A, // Comment A + b: B, // Comment B + c: C, // Comment C + +} + +struct Baz { + a: A, // Comment A + + b: B, // Comment B + + + + + c: C, // Comment C +} + +struct Baz { + + a: A, + + b: B, + c: C, + + + + + d: D + +} + +struct Baz +{ + // Comment A + a: A, + + // Comment B +b: B, + // Comment C + c: C,} + +// Will this be a one-liner? +struct Tuple( + A, //Comment + B +); + +pub struct State<F: FnMut() -> time::Timespec> { now: F } + +pub struct State<F: FnMut() -> ()> { now: F } + +pub struct State<F: FnMut()> { now: F } + +struct Palette { /// A map of indices in the palette to a count of pixels in approximately that color + foo: i32} + +// Splitting a single line comment into a block previously had a misalignment +// when the field had attributes +struct FieldsWithAttributes { + // Pre Comment + #[rustfmt::skip] pub host:String, // Post comment BBBBBBBBBBBBBB BBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBB BBBBBBBBBBB + //Another pre comment + #[attr1] + #[attr2] pub id: usize // CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCC CCCCCCCCCCCC +} + +struct Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: node::Handle<IdRef<'id, Node<K, V>>, + Type, + NodeType>, +} + +struct Foo<T>(T); +struct Foo<T>(T) where T: Copy, T: Eq; +struct Foo<T>(TTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUU); +struct Foo<T>(TTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTT) where T: PartialEq; +struct Foo<T>(TTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTTTT) where T: PartialEq; +struct Foo<T>(TTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUU) where T: PartialEq; +struct Foo<T>(TTTTTTTTTTTTTTTTT, // Foo + UUUUUUUUUUUUUUUUUUUUUUUU /* Bar */, + // Baz + TTTTTTTTTTTTTTTTTTT, + // Qux (FIXME #572 - doc comment) + UUUUUUUUUUUUUUUUUUU); + +mod m { + struct X<T> where T: Sized { + a: T, + } +} + +struct Foo<T>(TTTTTTTTTTTTTTTTTTT, + /// Qux + UUUUUUUUUUUUUUUUUUU); + +struct Issue677 { + pub ptr: *const libc::c_void, + pub trace: fn( obj: + *const libc::c_void, tracer : *mut JSTracer ), +} + +struct Foo {} +struct Foo { + } +struct Foo { + // comment + } +struct Foo { + // trailing space -> + + + } +struct Foo { /* comment */ } +struct Foo( /* comment */ ); + +struct LongStruct { + a: A, + the_quick_brown_fox_jumps_over_the_lazy_dog:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +} + +struct Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: node::Handle<IdRef<'id, Node<Key, Value>>, + Type, + NodeType>, +} + +struct Foo<C=()>(String); + +// #1364 +fn foo() { + convex_shape.set_point(0, &Vector2f { x: 400.0, y: 100.0 }); + convex_shape.set_point(1, &Vector2f { x: 500.0, y: 70.0 }); + convex_shape.set_point(2, &Vector2f { x: 450.0, y: 100.0 }); + convex_shape.set_point(3, &Vector2f { x: 580.0, y: 150.0 }); +} + +fn main() { + let x = Bar; + + // Comment + let y = Foo {a: x }; + + Foo { a: foo() /* comment*/, /* comment*/ b: bar(), ..something }; + + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: f(), b: b(), }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: f(), b: b(), }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + // Comment + a: foo(), // Comment + // Comment + b: bar(), // Comment + }; + + Foo { a:Bar, + b:f() }; + + Quux { x: if cond { bar(); }, y: baz() }; + + A { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item + }; + + Some(Data::MethodCallData(MethodCallData { + span: sub_span.unwrap(), + scope: self.enclosing_scope(id), + ref_id: def_id, + decl_id: Some(decl_id), + })); + + Diagram { /* o This graph demonstrates how + * / \ significant whitespace is + * o o preserved. + * /|\ \ + * o o o o */ + graph: G, } +} + +fn matcher() { + TagTerminatedByteMatcher { + matcher: ByteMatcher { + pattern: b"<HTML", + mask: b"\xFF\xDF\xDF\xDF\xDF\xFF", + }, + }; +} + +fn issue177() { + struct Foo<T> { memb: T } + let foo = Foo::<i64> { memb: 10 }; +} + +fn issue201() { + let s = S{a:0, .. b}; +} + +fn issue201_2() { + let s = S{a: S2{ .. c}, .. b}; +} + +fn issue278() { + let s = S { + a: 0, + // + b: 0, + }; + let s1 = S { + a: 0, + // foo + // + // bar + b: 0, + }; +} + +fn struct_exprs() { + Foo + { a : 1, b:f( 2)}; + Foo{a:1,b:f(2),..g(3)}; + LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongStruct { ..base }; + IntrinsicISizesContribution { content_intrinsic_sizes: IntrinsicISizes { minimum_inline_size: 0, }, }; +} + +fn issue123() { + Foo { a: b, c: d, e: f }; + + Foo { a: bb, c: dd, e: ff }; + + Foo { a: ddddddddddddddddddddd, b: cccccccccccccccccccccccccccccccccccccc }; +} + +fn issue491() { + Foo { + guard: None, + arm: 0, // Comment + }; + + Foo { + arm: 0, // Comment + }; + + Foo { a: aaaaaaaaaa, b: bbbbbbbb, c: cccccccccc, d: dddddddddd, /* a comment */ + e: eeeeeeeee }; +} + +fn issue698() { + Record { + ffffffffffffffffffffffffffields: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + }; + Record { + ffffffffffffffffffffffffffields: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + } +} + +fn issue835() { + MyStruct {}; + MyStruct { /* a comment */ }; + MyStruct { + // Another comment + }; + MyStruct {} +} + +fn field_init_shorthand() { + MyStruct { x, y, z }; + MyStruct { x, y, z, .. base }; + Foo { aaaaaaaaaa, bbbbbbbb, cccccccccc, dddddddddd, /* a comment */ + eeeeeeeee }; + Record { ffffffffffffffffffffffffffieldsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa }; +} diff --git a/src/tools/rustfmt/tests/source/configs/struct_lit_single_line/false.rs b/src/tools/rustfmt/tests/source/configs/struct_lit_single_line/false.rs new file mode 100644 index 000000000..17cad8dde --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/struct_lit_single_line/false.rs @@ -0,0 +1,6 @@ +// rustfmt-struct_lit_single_line: false +// Struct literal multiline-style + +fn main() { + let lorem = Lorem { ipsum: dolor, sit: amet }; +} diff --git a/src/tools/rustfmt/tests/source/configs/tab_spaces/2.rs b/src/tools/rustfmt/tests/source/configs/tab_spaces/2.rs new file mode 100644 index 000000000..5c2667bc2 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/tab_spaces/2.rs @@ -0,0 +1,11 @@ +// rustfmt-tab_spaces: 2 +// rustfmt-max_width: 30 +// rustfmt-indent_style: Block +// Tab spaces + +fn lorem() { +let ipsum = dolor(); +let sit = vec![ +"amet", "consectetur", "adipiscing", "elit." +]; +} diff --git a/src/tools/rustfmt/tests/source/configs/tab_spaces/4.rs b/src/tools/rustfmt/tests/source/configs/tab_spaces/4.rs new file mode 100644 index 000000000..da61bbd42 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/tab_spaces/4.rs @@ -0,0 +1,11 @@ +// rustfmt-tab_spaces: 4 +// rustfmt-max_width: 30 +// rustfmt-indent_style: Block +// Tab spaces + +fn lorem() { +let ipsum = dolor(); +let sit = vec![ +"amet", "consectetur", "adipiscing", "elit." +]; +} diff --git a/src/tools/rustfmt/tests/source/configs/trailing_comma/always.rs b/src/tools/rustfmt/tests/source/configs/trailing_comma/always.rs new file mode 100644 index 000000000..57e874cd8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/trailing_comma/always.rs @@ -0,0 +1,7 @@ +// rustfmt-trailing_comma: Always +// Trailing comma + +fn main() { + let Lorem { ipsum, dolor, sit, } = amet; + let Lorem { ipsum, dolor, sit, amet, consectetur, adipiscing } = elit; +} diff --git a/src/tools/rustfmt/tests/source/configs/trailing_comma/never.rs b/src/tools/rustfmt/tests/source/configs/trailing_comma/never.rs new file mode 100644 index 000000000..4da3b996f --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/trailing_comma/never.rs @@ -0,0 +1,23 @@ +// rustfmt-trailing_comma: Never +// Trailing comma + +fn main() { + let Lorem { ipsum, dolor, sit, } = amet; + let Lorem { ipsum, dolor, sit, amet, consectetur, adipiscing } = elit; + + // #1544 + if let VrMsg::ClientReply {request_num: reply_req_num, value, ..} = msg { + let _ = safe_assert_eq!(reply_req_num, request_num, op); + return Ok((request_num, op, value)); + } + + // #1710 + pub struct FileInput { + input: StringInput, + file_name: OsString, + } + match len { + Some(len) => Ok(new(self.input, self.pos + len)), + None => Err(self), + } +} diff --git a/src/tools/rustfmt/tests/source/configs/trailing_comma/vertical.rs b/src/tools/rustfmt/tests/source/configs/trailing_comma/vertical.rs new file mode 100644 index 000000000..c903e8221 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/trailing_comma/vertical.rs @@ -0,0 +1,7 @@ +// rustfmt-trailing_comma: Vertical +// Trailing comma + +fn main() { + let Lorem { ipsum, dolor, sit, } = amet; + let Lorem { ipsum, dolor, sit, amet, consectetur, adipiscing } = elit; +} diff --git a/src/tools/rustfmt/tests/source/configs/type_punctuation_density/compressed.rs b/src/tools/rustfmt/tests/source/configs/type_punctuation_density/compressed.rs new file mode 100644 index 000000000..223b9a2f0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/type_punctuation_density/compressed.rs @@ -0,0 +1,37 @@ +// rustfmt-type_punctuation_density: Compressed +// Type punctuation density + +fn lorem<Ipsum:Dolor+Sit=Amet>() { + // body +} + +struct Foo<T: Eq + Clone, U> +where U: Eq + Clone { + // body +} + +trait Foo<'a, T = usize> +where T: 'a + Eq + Clone +{ + type Bar: Eq + Clone; +} + +trait Foo: Eq + Clone { + // body +} + +impl<T> Foo<'a> for Bar +where for<'a> T: 'a + Eq + Clone +{ + // body +} + +fn foo<'a, 'b, 'c>() +where 'a: 'b + 'c +{ + // body +} + +fn Foo<T = Foo, Output = Expr<'tcx> + Foo>() { + let i = 6; +} diff --git a/src/tools/rustfmt/tests/source/configs/type_punctuation_density/wide.rs b/src/tools/rustfmt/tests/source/configs/type_punctuation_density/wide.rs new file mode 100644 index 000000000..fe0c08167 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/type_punctuation_density/wide.rs @@ -0,0 +1,37 @@ +// rustfmt-type_punctuation_density: Wide +// Type punctuation density + +fn lorem<Ipsum:Dolor+Sit=Amet>() { + // body +} + +struct Foo<T: Eq + Clone, U> +where U: Eq + Clone { + // body +} + +trait Foo<'a, T = usize> +where T: 'a + Eq + Clone +{ + type Bar: Eq + Clone; +} + +trait Foo: Eq + Clone { + // body +} + +impl<T> Foo<'a> for Bar +where for<'a> T: 'a + Eq + Clone +{ + // body +} + +fn foo<'a, 'b, 'c>() +where 'a: 'b + 'c +{ + // body +} + +fn Foo<T = Foo, Output = Expr<'tcx> + Foo>() { + let i = 6; +} diff --git a/src/tools/rustfmt/tests/source/configs/use_field_init_shorthand/false.rs b/src/tools/rustfmt/tests/source/configs/use_field_init_shorthand/false.rs new file mode 100644 index 000000000..4c2eb1de1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/use_field_init_shorthand/false.rs @@ -0,0 +1,19 @@ +// rustfmt-use_field_init_shorthand: false +// Use field initialization shorthand if possible. + +fn main() { + let a = Foo { + x: x, + y: y, + z: z, + }; + + let b = Bar { + x: x, + y: y, + #[attr] + z: z, + #[rustfmt::skip] + skipped: skipped, + }; +} diff --git a/src/tools/rustfmt/tests/source/configs/use_field_init_shorthand/true.rs b/src/tools/rustfmt/tests/source/configs/use_field_init_shorthand/true.rs new file mode 100644 index 000000000..dcde28d74 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/use_field_init_shorthand/true.rs @@ -0,0 +1,19 @@ +// rustfmt-use_field_init_shorthand: true +// Use field initialization shorthand if possible. + +fn main() { + let a = Foo { + x: x, + y: y, + z: z, + }; + + let b = Bar { + x: x, + y: y, + #[attr] + z: z, + #[rustfmt::skip] + skipped: skipped, + }; +} diff --git a/src/tools/rustfmt/tests/source/configs/use_small_heuristics/default.rs b/src/tools/rustfmt/tests/source/configs/use_small_heuristics/default.rs new file mode 100644 index 000000000..68bc40271 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/use_small_heuristics/default.rs @@ -0,0 +1,25 @@ +// rustfmt-use_small_heuristics: Default + +enum Lorem { + Ipsum, + Dolor(bool), + Sit { + amet: Consectetur, + adipiscing: Elit, + }, +} + +fn main() { + lorem("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing"); + + let lorem = Lorem { + ipsum: dolor, + sit: amet, + }; + + let lorem = if ipsum { + dolor + } else { + sit + }; +} diff --git a/src/tools/rustfmt/tests/source/configs/use_small_heuristics/max.rs b/src/tools/rustfmt/tests/source/configs/use_small_heuristics/max.rs new file mode 100644 index 000000000..8d30932e2 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/use_small_heuristics/max.rs @@ -0,0 +1,25 @@ +// rustfmt-use_small_heuristics: Max + +enum Lorem { + Ipsum, + Dolor(bool), + Sit { + amet: Consectetur, + adipiscing: Elit, + }, +} + +fn main() { + lorem("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing"); + + let lorem = Lorem { + ipsum: dolor, + sit: amet, + }; + + let lorem = if ipsum { + dolor + } else { + sit + }; +} diff --git a/src/tools/rustfmt/tests/source/configs/use_small_heuristics/off.rs b/src/tools/rustfmt/tests/source/configs/use_small_heuristics/off.rs new file mode 100644 index 000000000..f76392d24 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/use_small_heuristics/off.rs @@ -0,0 +1,25 @@ +// rustfmt-use_small_heuristics: Off + +enum Lorem { + Ipsum, + Dolor(bool), + Sit { + amet: Consectetur, + adipiscing: Elit, + }, +} + +fn main() { + lorem("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing"); + + let lorem = Lorem { + ipsum: dolor, + sit: amet, + }; + + let lorem = if ipsum { + dolor + } else { + sit + }; +} diff --git a/src/tools/rustfmt/tests/source/configs/use_try_shorthand/false.rs b/src/tools/rustfmt/tests/source/configs/use_try_shorthand/false.rs new file mode 100644 index 000000000..de7f8b4a5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/use_try_shorthand/false.rs @@ -0,0 +1,6 @@ +// rustfmt-use_try_shorthand: false +// Use try! shorthand + +fn main() { + let lorem = try!(ipsum.map(|dolor| dolor.sit())); +} diff --git a/src/tools/rustfmt/tests/source/configs/use_try_shorthand/true.rs b/src/tools/rustfmt/tests/source/configs/use_try_shorthand/true.rs new file mode 100644 index 000000000..9015ec41e --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/use_try_shorthand/true.rs @@ -0,0 +1,6 @@ +// rustfmt-use_try_shorthand: true +// Use try! shorthand + +fn main() { + let lorem = try!(ipsum.map(|dolor| dolor.sit())); +} diff --git a/src/tools/rustfmt/tests/source/configs/where_single_line/true.rs b/src/tools/rustfmt/tests/source/configs/where_single_line/true.rs new file mode 100644 index 000000000..9de98283b --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/where_single_line/true.rs @@ -0,0 +1,26 @@ +// rustfmt-where_single_line: true +// Where style + + +fn lorem_two_items<Ipsum, Dolor, Sit, Amet>() -> T where Ipsum: Eq, Lorem: Eq { + // body +} + +fn lorem_multi_line<Ipsum, Dolor, Sit, Amet>( + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee, +) -> T +where + Ipsum: Eq, +{ + // body +} + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T where Ipsum: Eq { + // body +} + +unsafe impl Sync for Foo where (): Send {} diff --git a/src/tools/rustfmt/tests/source/configs/wrap_comments/false.rs b/src/tools/rustfmt/tests/source/configs/wrap_comments/false.rs new file mode 100644 index 000000000..48ecd88ac --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/wrap_comments/false.rs @@ -0,0 +1,8 @@ +// rustfmt-wrap_comments: false +// rustfmt-max_width: 50 +// rustfmt-error_on_line_overflow: false +// Wrap comments + +fn main() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +} diff --git a/src/tools/rustfmt/tests/source/configs/wrap_comments/true.rs b/src/tools/rustfmt/tests/source/configs/wrap_comments/true.rs new file mode 100644 index 000000000..39a79a4ca --- /dev/null +++ b/src/tools/rustfmt/tests/source/configs/wrap_comments/true.rs @@ -0,0 +1,15 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 50 +// Wrap comments + +fn main() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +} + +fn code_block() { + // ```rust + // let x = 3; + // + // println!("x = {}", x); + // ``` +} diff --git a/src/tools/rustfmt/tests/source/const_generics.rs b/src/tools/rustfmt/tests/source/const_generics.rs new file mode 100644 index 000000000..01b764dbe --- /dev/null +++ b/src/tools/rustfmt/tests/source/const_generics.rs @@ -0,0 +1,44 @@ +struct Message { + field2: Vec< + "MessageEntity" + >, + field3: Vec< + 1 + >, + field4: Vec< + 2 , 3 + >, + +} + +struct RectangularArray<T, const WIDTH: usize, const HEIGHT: usize> { + array: [[T; WIDTH]; HEIGHT], +} + +fn main() { + const X: usize = 7; + let x: RectangularArray<i32, 2, 4>; + let y: RectangularArray<i32, X, {2 + * 2} >; +} + +fn foo<const X: usize>() { + const Y: usize = X * 2; + static Z: (usize, usize) = (X, X); + + struct Foo([i32; X]); +} + +type Foo<const N: usize> = [i32; N + 1]; + +pub trait Foo: Bar<{Baz::COUNT}> { + const ASD: usize; +} + +// #4263 +fn const_generics_on_params< + // AAAA + const BBBB: usize, + /* CCCC */ + const DDDD: usize, + >() {} diff --git a/src/tools/rustfmt/tests/source/control-brace-style-always-next-line.rs b/src/tools/rustfmt/tests/source/control-brace-style-always-next-line.rs new file mode 100644 index 000000000..9079fb46c --- /dev/null +++ b/src/tools/rustfmt/tests/source/control-brace-style-always-next-line.rs @@ -0,0 +1,44 @@ +// rustfmt-control_brace_style: AlwaysNextLine + +fn main() { + loop { + (); + (); + } + + + 'label: loop // loop comment + { + (); + } + + + cond = true; + while cond { + (); + } + + + 'while_label: while cond { // while comment + (); + } + + + for obj in iter { + for sub_obj in obj + { + 'nested_while_label: while cond { + (); + } + } + } + + match some_var { // match comment + pattern0 => val0, + pattern1 => val1, + pattern2 | pattern3 => { + do_stuff(); + val2 + }, + }; +} diff --git a/src/tools/rustfmt/tests/source/control-brace-style-always-same-line.rs b/src/tools/rustfmt/tests/source/control-brace-style-always-same-line.rs new file mode 100644 index 000000000..45111aaab --- /dev/null +++ b/src/tools/rustfmt/tests/source/control-brace-style-always-same-line.rs @@ -0,0 +1,42 @@ +fn main() { + loop { + (); + (); + } + + + 'label: loop // loop comment + { + (); + } + + + cond = true; + while cond { + (); + } + + + 'while_label: while cond { // while comment + (); + } + + + for obj in iter { + for sub_obj in obj + { + 'nested_while_label: while cond { + (); + } + } + } + + match some_var { // match comment + pattern0 => val0, + pattern1 => val1, + pattern2 | pattern3 => { + do_stuff(); + val2 + }, + }; +} diff --git a/src/tools/rustfmt/tests/source/doc-attrib.rs b/src/tools/rustfmt/tests/source/doc-attrib.rs new file mode 100644 index 000000000..dde88c6e9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/doc-attrib.rs @@ -0,0 +1,118 @@ +// rustfmt-wrap_comments: true +// rustfmt-normalize_doc_attributes: true + +// Only doc = "" attributes should be normalized +#![doc = " Example doc attribute comment"] +#![doc = " Example doc attribute comment with 10 leading spaces"] +#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))] + + +// Long `#[doc = "..."]` +struct A { #[doc = " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] b: i32 } + + +#[doc = " The `nodes` and `edges` method each return instantiations of `Cow<[T]>` to leave implementers the freedom to create entirely new vectors or to pass back slices into internally owned vectors."] +struct B { b: i32 } + + +#[doc = " Level 1 comment"] +mod tests { + #[doc = " Level 2 comment"] + impl A { + #[doc = " Level 3 comment"] + fn f() { + #[doc = " Level 4 comment"] + fn g() { + } + } + } +} + +struct C { + #[doc = " item doc attrib comment"] + // regular item comment + b: i32, + + // regular item comment + #[doc = " item doc attrib comment"] + c: i32, +} + +// non-regression test for regular attributes, from #2647 +#[cfg(feature = "this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")] +pub fn foo() {} + +// path attrs +#[clippy::bar] +#[clippy::bar(a, b, c)] +pub fn foo() {} + +mod issue_2620 { + #[derive(Debug, StructOpt)] +#[structopt(about = "Display information about the character on FF Logs")] +pub struct Params { + #[structopt(help = "The server the character is on")] + server: String, + #[structopt(help = "The character's first name")] + first_name: String, + #[structopt(help = "The character's last name")] + last_name: String, + #[structopt( + short = "j", + long = "job", + help = "The job to look at", + parse(try_from_str) + )] + job: Option<Job> +} +} + +// non-regression test for regular attributes, from #2969 +#[cfg(not(all(feature="std", + any(target_os = "linux", target_os = "android", + target_os = "netbsd", + target_os = "dragonfly", + target_os = "haiku", + target_os = "emscripten", + target_os = "solaris", + target_os = "cloudabi", + target_os = "macos", target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "redox", + target_os = "fuchsia", + windows, + all(target_arch = "wasm32", feature = "stdweb"), + all(target_arch = "wasm32", feature = "wasm-bindgen"), + ))))] +type Os = NoSource; + +// use cases from bindgen needing precise control over leading spaces +#[doc = " <div rustbindgen accessor></div>"] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct ContradictAccessors { + #[doc = "<foo>no leading spaces here</foo>"] + pub mBothAccessors: ::std::os::raw::c_int, + #[doc = " <div rustbindgen accessor=\"false\"></div>"] + pub mNoAccessors: ::std::os::raw::c_int, + #[doc = " <div rustbindgen accessor=\"unsafe\"></div>"] + pub mUnsafeAccessors: ::std::os::raw::c_int, + #[doc = " <div rustbindgen accessor=\"immutable\"></div>"] + pub mImmutableAccessor: ::std::os::raw::c_int, +} + +#[doc = " \\brief MPI structure"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct mbedtls_mpi { + #[doc = "< integer sign"] + pub s: ::std::os::raw::c_int, + #[doc = "< total # of limbs"] + pub n: ::std::os::raw::c_ulong, + #[doc = "< pointer to limbs"] + pub p: *mut mbedtls_mpi_uint, +} diff --git a/src/tools/rustfmt/tests/source/doc-comment-with-example.rs b/src/tools/rustfmt/tests/source/doc-comment-with-example.rs new file mode 100644 index 000000000..e74ceefd1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/doc-comment-with-example.rs @@ -0,0 +1,12 @@ +// rustfmt-format_code_in_doc_comments: true + +/// Foo +/// +/// # Example +/// ``` +/// # #![cfg_attr(not(dox), feature(cfg_target_feature, target_feature, stdsimd))] +/// # #![cfg_attr(not(dox), no_std)] +/// fn foo() { } +/// ``` +/// +fn foo() {} diff --git a/src/tools/rustfmt/tests/source/doc.rs b/src/tools/rustfmt/tests/source/doc.rs new file mode 100644 index 000000000..3b25918b1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/doc.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true +// Part of multiple.rs + +// sadfsdfa +//sdffsdfasdf diff --git a/src/tools/rustfmt/tests/source/dyn_trait.rs b/src/tools/rustfmt/tests/source/dyn_trait.rs new file mode 100644 index 000000000..012643be9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/dyn_trait.rs @@ -0,0 +1,20 @@ +#![feature(dyn_trait)] + +fn main() { + // #2506 + // checks rustfmt doesn't remove dyn + trait MyTrait { + fn method(&self) -> u64; + } + fn f1(a: Box<dyn MyTrait>) {} + + // checks if line wrap works correctly + trait Very_______________________Long__________________Name_______________________________Trait { + fn method(&self) -> u64; + } + + fn f2(a: Box<dyn Very_______________________Long__________________Name____________________Trait+ 'static,>) {} + + // #2582 + let _: &dyn (::std::any::Any) = &msg; +} diff --git a/src/tools/rustfmt/tests/source/else-if-brace-style-always-next-line.rs b/src/tools/rustfmt/tests/source/else-if-brace-style-always-next-line.rs new file mode 100644 index 000000000..7b4870fc6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/else-if-brace-style-always-next-line.rs @@ -0,0 +1,54 @@ +// rustfmt-control_brace_style: AlwaysNextLine + +fn main() { + if false + { + (); + (); + } + + if false // lone if comment + { + (); + (); + } + + + let a = + if 0 > 1 { + unreachable!() + } + else + { + 0x0 + }; + + + if true + { + (); + } else if false { + (); + (); + } + else { + (); + (); + (); + } + + if true // else-if-chain if comment + { + (); + } + else if false // else-if-chain else-if comment + { + (); + (); + } else // else-if-chain else comment + { + (); + (); + (); + } +} diff --git a/src/tools/rustfmt/tests/source/else-if-brace-style-always-same-line.rs b/src/tools/rustfmt/tests/source/else-if-brace-style-always-same-line.rs new file mode 100644 index 000000000..37c9417ea --- /dev/null +++ b/src/tools/rustfmt/tests/source/else-if-brace-style-always-same-line.rs @@ -0,0 +1,52 @@ +fn main() { + if false + { + (); + (); + } + + if false // lone if comment + { + (); + (); + } + + + let a = + if 0 > 1 { + unreachable!() + } + else + { + 0x0 + }; + + + if true + { + (); + } else if false { + (); + (); + } + else { + (); + (); + (); + } + + if true // else-if-chain if comment + { + (); + } + else if false // else-if-chain else-if comment + { + (); + (); + } else // else-if-chain else comment + { + (); + (); + (); + } +} diff --git a/src/tools/rustfmt/tests/source/else-if-brace-style-closing-next-line.rs b/src/tools/rustfmt/tests/source/else-if-brace-style-closing-next-line.rs new file mode 100644 index 000000000..3b885b3fa --- /dev/null +++ b/src/tools/rustfmt/tests/source/else-if-brace-style-closing-next-line.rs @@ -0,0 +1,54 @@ +// rustfmt-control_brace_style: ClosingNextLine + +fn main() { + if false + { + (); + (); + } + + if false // lone if comment + { + (); + (); + } + + + let a = + if 0 > 1 { + unreachable!() + } + else + { + 0x0 + }; + + + if true + { + (); + } else if false { + (); + (); + } + else { + (); + (); + (); + } + + if true // else-if-chain if comment + { + (); + } + else if false // else-if-chain else-if comment + { + (); + (); + } else // else-if-chain else comment + { + (); + (); + (); + } +} diff --git a/src/tools/rustfmt/tests/source/empty-item-single-line-false.rs b/src/tools/rustfmt/tests/source/empty-item-single-line-false.rs new file mode 100644 index 000000000..20c5bc83b --- /dev/null +++ b/src/tools/rustfmt/tests/source/empty-item-single-line-false.rs @@ -0,0 +1,46 @@ +// rustfmt-brace_style: AlwaysNextLine +// rustfmt-empty_item_single_line: false + +fn function() +{ + +} + +struct Struct +{ + +} + +enum Enum +{ + +} + +trait Trait +{ + +} + +impl<T> Trait for T +{ + +} + +trait Trait2<T> +where + T: Copy + Display + Write + Read + FromStr, {} + +trait Trait3<T> +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, {} diff --git a/src/tools/rustfmt/tests/source/empty_file.rs b/src/tools/rustfmt/tests/source/empty_file.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/rustfmt/tests/source/empty_file.rs diff --git a/src/tools/rustfmt/tests/source/enum.rs b/src/tools/rustfmt/tests/source/enum.rs new file mode 100644 index 000000000..0ed9651ab --- /dev/null +++ b/src/tools/rustfmt/tests/source/enum.rs @@ -0,0 +1,212 @@ +// rustfmt-wrap_comments: true +// Enums test + +#[atrr] +pub enum Test { + A, B(u32, + A /* comment */, + SomeType), + /// Doc comment + C, +} + +pub enum Foo<'a, Y: Baz> where X: Whatever +{ A, } + +enum EmtpyWithComment { + // Some comment +} + +// C-style enum +enum Bar { + A = 1, + #[someAttr(test)] + B = 2, // comment + C, +} + +enum LongVariants { +First(LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG, // comment +VARIANT), + // This is the second variant + Second +} + +enum StructLikeVariants { + Normal(u32, String, ), + StructLike { x: i32, // Test comment + // Pre-comment + #[Attr50] y: SomeType, // Aanother Comment + }, SL { a: A } +} + +enum X { + CreateWebGLPaintTask(Size2D<i32>, GLContextAttributes, IpcSender<Result<(IpcSender<CanvasMsg>, usize), String>>), // This is a post comment +} + +pub enum EnumWithAttributes { + //This is a pre comment AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + TupleVar(usize, usize, usize), // AAAA AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + // Pre Comment + #[rustfmt::skip] + SkippedItem(String,String,), // Post-comment + #[another_attr] + #[attr2] + ItemStruct {x: usize, y: usize}, // Comment AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + // And another + ForcedPreflight // AAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +} + +pub enum SingleTuple { + // Pre Comment AAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + Match(usize, usize, String) // Post-comment AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +} + +pub enum SingleStruct { + Match {name: String, loc: usize} // Post-comment +} + +pub enum GenericEnum<I, T> +where I: Iterator<Item = T> { + // Pre Comment + Left {list: I, root: T}, // Post-comment + Right {list: I, root: T} // Post Comment +} + + +enum EmtpyWithComment { + // Some comment +} + +enum TestFormatFails { + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +} + +fn nested_enum_test() { + if true { + enum TestEnum { + One(usize, usize, usize, usize, usize, usize, usize, usize, usize, usize, usize, usize, usize, usize, usize, usize,), // AAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAA + Two // AAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAA + } + enum TestNestedFormatFail { + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + } + } +} + + pub struct EmtpyWithComment { + // FIXME: Implement this struct +} + +// #1115 +pub enum Bencoding<'i> { + Str(&'i [u8]), + Int(i64), + List(Vec<Bencoding<'i>>), + /// A bencoded dict value. The first element the slice of bytes in the source that the dict is + /// composed of. The second is the dict, decoded into an ordered map. + // TODO make Dict "structlike" AKA name the two values. + Dict(&'i [u8], BTreeMap<&'i [u8], Bencoding<'i>>), +} + +// #1261 +pub enum CoreResourceMsg { + SetCookieForUrl( + ServoUrl, + #[serde(deserialize_with = "::hyper_serde::deserialize", + serialize_with = "::hyper_serde::serialize")] + Cookie, + CookieSource + ), +} + +enum Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong {} +enum Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong {} +enum Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong {} +enum Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong { Foo } + +// #1046 +pub enum Entry<'a, K: 'a, V: 'a> { + Vacant( + #[ stable( feature = "rust1", since = "1.0.0" ) ] VacantEntry<'a, K, V>, + ), + Occupied( + #[ stable( feature = "rust1", since = "1.0.0" ) ] + OccupiedEntry<'a, K, V>, + ), +} + +// #2081 +pub enum ForegroundColor { + CYAN = (winapi::FOREGROUND_INTENSITY | winapi::FOREGROUND_GREEN | winapi::FOREGROUND_BLUE) as u16, +} + +// #2098 +pub enum E<'a> { + V ( < std::slice::Iter<'a, Xxxxxxxxxxxxxx> as Iterator> :: Item ) , +} + +// #1809 +enum State { + TryRecv { + pos: usize, + lap: u8, + closed_count: usize, + }, + Subscribe { pos: usize }, + IsReady { pos: usize, ready: bool }, + Unsubscribe { + pos: usize, + lap: u8, + id_woken: usize, + }, + FinalTryRecv { pos: usize, id_woken: usize }, + TimedOut, + Disconnected, +} + +// #2190 +#[derive(Debug, Fail)] +enum AnError { + #[fail(display = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] + UnexpectedSingleToken { token: syn::Token }, +} + +// #2193 +enum WidthOf101 { + #[fail(display = ".....................................................")] Io(::std::io::Error), + #[fail(display = ".....................................................")] Ioo(::std::io::Error), + Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(::std::io::Error), + Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(::std::io::Error), +} + +// #2389 +pub enum QlError { + #[fail(display = "Parsing error: {}", 0)] LexError(parser::lexer::LexError), + #[fail(display = "Parsing error: {:?}", 0)] ParseError(parser::ParseError), + #[fail(display = "Validation error: {:?}", 0)] ValidationError(Vec<validation::Error>), + #[fail(display = "Execution error: {}", 0)] ExecutionError(String), + // (from, to) + #[fail(display = "Translation error: from {} to {}", 0, 1)] TranslationError(String, String), + // (kind, input, expected) + #[fail(display = "aaaaaaaaaaaaCould not find {}: Found: {}, expected: {:?}", 0, 1, 2)] ResolveError(&'static str, String, Option<String>), +} + +// #2594 +enum Foo {} +enum Bar { } + +// #3562 +enum PublishedFileVisibility { + Public = sys::ERemoteStoragePublishedFileVisibility_k_ERemoteStoragePublishedFileVisibilityPublic, + FriendsOnly = sys::ERemoteStoragePublishedFileVisibility_k_ERemoteStoragePublishedFileVisibilityFriendsOnly, + Private = sys::ERemoteStoragePublishedFileVisibility_k_ERemoteStoragePublishedFileVisibilityPrivate, +} + +// #3771 +//#![feature(arbitrary_enum_discriminant)] +#[repr(u32)] +pub enum E { + A { a: u32 } = 0x100, + B { field1: u32, field2: u8, field3: m::M } = 0x300 // comment +} diff --git a/src/tools/rustfmt/tests/source/existential_type.rs b/src/tools/rustfmt/tests/source/existential_type.rs new file mode 100644 index 000000000..33bb9a951 --- /dev/null +++ b/src/tools/rustfmt/tests/source/existential_type.rs @@ -0,0 +1,23 @@ +// Opaque type. + + #![feature(type_alias_impl_trait)] + +pub type Adder<F, T> +where + T: Clone, + F: Copy + = impl Fn(T) -> T; + +pub type Adderrr<T> = impl Fn( T ) -> T; + +impl Foo for Bar { +type E = impl Trait; +} + +pub type Adder_without_impl<F, T> +where + T: Clone, + F: Copy + = Fn(T) -> T; + +pub type Adderrr_without_impl<T> = Fn( T ) -> T; diff --git a/src/tools/rustfmt/tests/source/expr-block.rs b/src/tools/rustfmt/tests/source/expr-block.rs new file mode 100644 index 000000000..a3e6100b7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/expr-block.rs @@ -0,0 +1,300 @@ +// Test expressions with block formatting. + +fn arrays() { + [ ]; + let empty = []; + + let foo = [a_long_name, a_very_lng_name, a_long_name]; + + let foo = [a_long_name, a_very_lng_name, a_long_name, a_very_lng_name, a_long_name, a_very_lng_name, a_long_name, a_very_lng_name]; + + vec![a_long_name, a_very_lng_name, a_long_name, a_very_lng_name, a_long_name, a_very_lng_name, a_very_lng_name]; + + [a_long_name, a_very_lng_name, a_long_name, a_very_lng_name, a_long_name, a_very_lng_name, a_very_lng_name] +} + +fn arrays() { + let x = [0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 0, + 7, + 8, + 9, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 0]; + + let y = [/* comment */ 1, 2 /* post comment */, 3]; + + let xy = [ strukt { test123: value_one_two_three_four, turbo: coolio(), } , /* comment */ 1 ]; + + let a =WeightedChoice::new(&mut [Weighted { + weight: x, + item: 0, + }, + Weighted { + weight: 1, + item: 1, + }, + Weighted { + weight: x, + item: 2, + }, + Weighted { + weight: 1, + item: 3, + }]); + + let z = [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzzz, q]; + + [ 1 + 3, 4 , 5, 6, 7, 7, fncall::<Vec<_>>(3-1)] +} + +fn function_calls() { + let items = itemize_list(context.source_map, + args.iter(), + ")", + |item| item.span.lo(), + |item| item.span.hi(), + |item| { + item.rewrite(context, + Shape { + width: remaining_width, + ..nested_shape + }) + }, + span.lo(), + span.hi()); + + itemize_list(context.source_map, + args.iter(), + ")", + |item| item.span.lo(), + |item| item.span.hi(), + |item| { + item.rewrite(context, + Shape { + width: remaining_width, + ..nested_shape + }) + }, + span.lo(), + span.hi()) +} + +fn macros() { + baz!(do_not, add, trailing, commas, inside, of, function, like, macros, even, if_they, are, long); + + baz!(one_item_macro_which_is_also_loooooooooooooooooooooooooooooooooooooooooooooooong); + + let _ = match option { + None => baz!(function, like, macro_as, expression, which, is, loooooooooooooooong), + Some(p) => baz!(one_item_macro_as_expression_which_is_also_loooooooooooooooong), + }; +} + +fn issue_1450() { + if selfstate + .compare_exchandsfasdsdfgsdgsdfgsdfgsdfgsdfgsdfgfsfdsage_weak( + STATE_PARKED, + STATE_UNPARKED, + Release, + Relaxed, + Release, + Relaxed, + ) + .is_ok() { + return; + } +} + +fn foo() { + if real_total <= limit && !pre_line_comments && + !items.into_iter().any(|item| item.as_ref().is_multiline()) { + DefinitiveListTactic::Horizontal + } +} + +fn combine_block() { + foo( + Bar { + x: value, + y: value2, + }, + ); + + foo((Bar { + x: value, + y: value2, + },)); + + foo((1, 2, 3, Bar { + x: value, + y: value2, + })); + + foo((1, 2, 3, |x| { + let y = x + 1; + let z = y + 1; + z + })); + + let opt = Some( + Struct( + long_argument_one, + long_argument_two, + long_argggggggg, + ), + ); + + do_thing( + |param| { + action(); + foo(param) + }, + ); + + do_thing( + x, + |param| { + action(); + foo(param) + }, + ); + + do_thing( + x, + ( + 1, + 2, + 3, + |param| { + action(); + foo(param) + }, + ), + ); + + Ok( + some_function( + lllllllllong_argument_one, + lllllllllong_argument_two, + lllllllllllllllllllllllllllllong_argument_three, + ), + ); + + foo( + thing, + bar( + param2, + pparam1param1param1param1param1param1param1param1param1param1aram1, + param3, + ), + ); + + foo.map_or( + || { + Ok( + SomeStruct { + f1: 0, + f2: 0, + f3: 0, + }, + ) + }, + ); + + match opt { + Some(x) => somefunc(anotherfunc( + long_argument_one, + long_argument_two, + long_argument_three, + )), + Some(x) => |x| { + let y = x + 1; + let z = y + 1; + z + }, + Some(x) => (1, 2, |x| { + let y = x + 1; + let z = y + 1; + z + }), + Some(x) => SomeStruct { + f1: long_argument_one, + f2: long_argument_two, + f3: long_argument_three, + }, + None => Ok(SomeStruct { + f1: long_argument_one, + f2: long_argument_two, + f3: long_argument_three, + }), + }; + + match x { + y => func( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + ), + _ => func( + x, + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, + zzz, + ), + } +} + +fn issue_1862() { + foo( + /* bar = */ None , + something_something, + /* baz = */ None , + /* This comment waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay too long to be kept on the same line */ None , + /* com */ this_last_arg_is_tooooooooooooooooooooooooooooooooo_long_to_be_kept_with_the_pre_comment , + ) +} + +fn issue_3025() { + foo( + // This describes the argument below. + /* bar = */ None , + // This describes the argument below. + something_something, + // This describes the argument below. */ + None , + // This describes the argument below. + /* This comment waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay too long to be kept on the same line */ None , + // This describes the argument below. + /* com */ this_last_arg_is_tooooooooooooooooooooooooooooooooo_long_to_be_kept_with_the_pre_comment , + ) +} + +fn issue_1878() { + let channel: &str = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?; +} diff --git a/src/tools/rustfmt/tests/source/expr-overflow-delimited.rs b/src/tools/rustfmt/tests/source/expr-overflow-delimited.rs new file mode 100644 index 000000000..cd80ca6fc --- /dev/null +++ b/src/tools/rustfmt/tests/source/expr-overflow-delimited.rs @@ -0,0 +1,155 @@ +// rustfmt-overflow_delimited_expr: true + +fn combine_blocklike() { + do_thing( + |param| { + action(); + foo(param) + }, + ); + + do_thing( + x, + |param| { + action(); + foo(param) + }, + ); + + do_thing( + x, + + // I'll be discussing the `action` with your para(m)legal counsel + |param| { + action(); + foo(param) + }, + ); + + do_thing( + Bar { + x: value, + y: value2, + }, + ); + + do_thing( + x, + Bar { + x: value, + y: value2, + }, + ); + + do_thing( + x, + + // Let me tell you about that one time at the `Bar` + Bar { + x: value, + y: value2, + }, + ); + + do_thing( + &[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + x, + &[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + x, + + // Just admit it; my list is longer than can be folded on to one line + &[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + x, + vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + x, + + // Just admit it; my list is longer than can be folded on to one line + vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + x, + ( + 1, + 2, + 3, + |param| { + action(); + foo(param) + }, + ), + ); +} + +fn combine_struct_sample() { + let identity = verify( + &ctx, + VerifyLogin { + type_: LoginType::Username, + username: args.username.clone(), + password: Some(args.password.clone()), + domain: None, + }, + )?; +} + +fn combine_macro_sample() { + rocket::ignite() + .mount( + "/", + routes![ + http::auth::login, + http::auth::logout, + http::cors::options, + http::action::dance, + http::action::sleep, + ], + ) + .launch(); +} diff --git a/src/tools/rustfmt/tests/source/expr.rs b/src/tools/rustfmt/tests/source/expr.rs new file mode 100644 index 000000000..21f8a4a43 --- /dev/null +++ b/src/tools/rustfmt/tests/source/expr.rs @@ -0,0 +1,579 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// Test expressions + +fn foo() -> bool { + let boxed: Box<i32> = box 5; + let referenced = &5 ; + + let very_long_variable_name = ( a + first + simple + test ); + let very_long_variable_name = (a + first + simple + test + AAAAAAAAAAAAA + BBBBBBBBBBBBBBBBB + b + c); + + let is_internalxxxx = self.source_map.span_to_filename(s) == self.source_map.span_to_filename(m.inner); + + let some_val = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa * bbbb / (bbbbbb - + function_call(x, *very_long_pointer, y)) + + 1000 ; + +some_ridiculously_loooooooooooooooooooooong_function(10000 * 30000000000 + 40000 / 1002200000000 + - 50000 * sqrt(-1), + trivial_value); + (((((((((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + a + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaa))))))))) ; + + { for _ in 0..10 {} } + + {{{{}}}} + + if 1 + 2 > 0 { let result = 5; result } else { 4}; + + if let Some(x) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { + // Nothing + } + + if let Some(x) = (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {} + + if let (some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple) = 1 + + 2 + 3 { + } + + if let (some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple) = 1111 + 2222 {} + + if let (some_very_large, tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple) = 1 + + 2 + 3 { + } + + if let ast::ItemKind::Trait(_, unsafety, ref generics, ref type_param_bounds, ref trait_items) = item.node + { + // nothing + } + + let test = if true { 5 } else { 3 }; + + if cond() { + something(); + } else if different_cond() { + something_else(); + } else { + // Check subformatting + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + } + + // #2884 + let _ = [0; {struct Foo; impl Foo {const fn get(&self) -> usize {5}}; Foo.get()}]; +} + +fn bar() { + let range = ( 111111111 + 333333333333333333 + 1111 + 400000000000000000) .. (2222 + 2333333333333333); + + let another_range = 5..some_func( a , b /* comment */); + + for _ in 1 ..{ call_forever(); } + + syntactically_correct(loop { sup( '?'); }, if cond { 0 } else { 1 }); + + let third = ..10; + let infi_range = .. ; + let foo = 1..; + let bar = 5 ; + let nonsense = (10 .. 0)..(0..10); + + loop{if true {break}} + + let x = (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa && + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + a); +} + +fn baz() { + unsafe /* {}{}{}{{{{}} */ { + let foo = 1u32; + } + + unsafe /* very looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong comment */ {} + + unsafe // So this is a very long comment. + // Multi-line, too. + // Will it still format correctly? + { + } + + unsafe { + // Regular unsafe block + } + + unsafe { + foo() + } + + unsafe { + foo(); + } + + // #2289 + let identifier_0 = unsafe { this_is_58_chars_long_and_line_is_93_chars_long_xxxxxxxxxx }; + let identifier_1 = unsafe { this_is_59_chars_long_and_line_is_94_chars_long_xxxxxxxxxxx }; + let identifier_2 = unsafe { this_is_65_chars_long_and_line_is_100_chars_long_xxxxxxxxxxxxxxxx }; + let identifier_3 = unsafe { this_is_66_chars_long_and_line_is_101_chars_long_xxxxxxxxxxxxxxxxx }; +} + +// Test some empty blocks. +fn qux() { + {} + // FIXME this one could be done better. + { /* a block with a comment */ } + { + + } + { + // A block with a comment. + } +} + +fn issue227() { + { + let handler = box DocumentProgressHandler::new(addr, DocumentProgressTask::DOMContentLoaded); + } +} + +fn issue184(source: &str) { + for c in source.chars() { + if index < 'a' { + continue; + } + } +} + +fn arrays() { + let x = [0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 0, + 7, + 8, + 9, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 0]; + + let y = [/* comment */ 1, 2 /* post comment */, 3]; + + let xy = [ strukt { test123: value_one_two_three_four, turbo: coolio(), } , /* comment */ 1 ]; + + let a =WeightedChoice::new(&mut [Weighted { + weightweight: x, + item: 0, + }, + Weighted { + weightweight: 1, + item: 1, + }, + Weighted { + weightweight: x, + item: 2, + }, + Weighted { + weightweight: 1, + item: 3, + }]); + + let z = [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzzzz, q]; + + [ 1 + 3, 4 , 5, 6, 7, 7, fncall::<Vec<_>>(3-1)] +} + +fn returns() { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa && return; + + return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; +} + +fn addrof() { + & mut(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb); + & (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb); + + // raw reference operator + & raw const a; + & raw mut b; +} + +fn casts() { + fn unpack(packed: u32) -> [u16; 2] { + [ + (packed >> 16) as u16, + (packed >> 0) as u16, + ] + } + + let some_trait_xxx = xxxxxxxxxxx + xxxxxxxxxxxxx + as SomeTraitXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; + let slightly_longer_trait = yyyyyyyyy + yyyyyyyyyyy as SomeTraitYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY; +} + +fn indices() { + let x = (aaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb+cccccccccccccccc) [ x + y + z ]; + let y = (aaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccc)[ xxxxx + yyyyy + zzzzz ]; + let z = xxxxxxxxxx.x().y().zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz()[aaaaa]; + let z = xxxxxxxxxx.x().y().zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz()[aaaaa]; +} + +fn repeats() { + let x = [aaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb+cccccccccccccccc; x + y + z ]; + let y = [aaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccc; xxxxx + yyyyy + zzzzz ]; +} + +fn blocks() { + if 1 + 1 == 2 { + println!("yay arithmetix!"); + }; +} + +fn issue767() { + if false { + if false { + } else { + // A let binding here seems necessary to trigger it. + let _ = (); + } + } else if let false = false { + } +} + +fn ranges() { + let x = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa .. bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + let y = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ..= bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + let z = ..= x ; + + // #1766 + let x = [0. ..10.0]; + let x = [0. ..=10.0]; + + a ..= b + + // the expr below won't compile because inclusive ranges need a defined end + // let a = 0 ..= ; +} + +fn if_else() { + let exact = diff / + (if size == 0 { + 1 +} else { + size +}); + + let cx = tp1.x + + any * radius * + if anticlockwise { + 1.0 + } else { + -1.0 + }; +} + +fn complex_if_else() { + if let Some(x) = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx { + } else if let Some(x) = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx { + ha(); + } else if xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxx { + yo(); + } else if let Some(x) = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx { + ha(); + } else if xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxx { + yo(); + } +} + +fn issue1106() { + { + if let hir::ItemEnum(ref enum_def, ref generics) = self.ast_map.expect_item(enum_node_id).node { + } + } + + for entry in + WalkDir::new(path) + .into_iter() + .filter_entry(|entry| exclusions.filter_entry(entry)) { + } +} + +fn issue1570() { + a_very_long_function_name({some_func(1, {1})}) +} + +fn issue1714() { + v = &mut {v}[mid..]; + let (left, right) = {v}.split_at_mut(mid); +} + +// Multi-lined index should be put on the next line if it fits in one line. +fn issue1749() { + { + { + { + if self.shape[(r as f32 + self.x_offset) as usize][(c as f32 + self.y_offset) as usize] != 0 { + // hello + } + } + } + } +} + +// #1172 +fn newlines_between_list_like_expr() { + foo( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, + + zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, + ); + + vec![ + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, + + zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, + ]; + + match x { + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | + + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy | + + zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz => foo(a, b, c), + _ => bar(), + }; +} + +fn issue2178() { + Ok(result.iter().map(|item| ls_util::rls_to_location(item)).collect()) +} + +// #2493 +impl Foo { +fn bar(&self) { + { + let x = match () { + () => { + let i; + i == self.install_config.storage.experimental_compressed_block_size as usize + } + }; + } +} +} + +fn dots() { + .. .. ..; // (.. (.. (..))) + ..= ..= ..; + (..) .. ..; // ((..) .. (..)) +} + +// #2676 +// A function call with a large single argument. +fn foo() { + let my_var = + Mutex::new(RpcClientType::connect(server_iddd).chain_err(|| "Unable to create RPC client")?); +} + +// #2704 +// Method call with prefix and suffix. +fn issue2704() { + // We should not combine the callee with a multi-lined method call. + let requires = requires.set(&requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total()); + let requires = requires.set(box requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total()); + let requires = requires.set(requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total() as u32); + let requires = requires.set(requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total()?); + let requires = requires.set(!requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total()); + // We should combine a small callee with an argument. + bar(vec![22] + .into_iter() + .map(|x| x * 2) + .filter(|_| true) + .collect()); + // But we should not combine a long callee with an argument. + barrrr(vec![22] + .into_iter() + .map(|x| x * 2) + .filter(|_| true) + .collect()); +} + +// #2782 +fn issue2782() { + {let f={let f={{match f{F(f,_)=>{{loop{let f={match f{F(f,_)=>{{match f{F(f,_)=>{{loop{let f={let f={match f{'-'=>F(f,()),}};};}}}}}}}};}}}}}};};} +} + +fn issue_2802() { + function_to_fill_this_line(some_arg, some_arg, some_arg) + * a_very_specific_length(specific_length_arg) * very_specific_length(Foo { + a: some_much_much_longer_value, + }) * some_value +} + +fn issue_3003() { + let mut path: PathBuf = [ + env!("CARGO_MANIFEST_DIR"), + "tests", + "support", + "dejavu-fonts-ttf-2.37", + "ttf", + ] + .iter() + .collect(); +} + +fn issue3226() { + { + { + { + return Err(ErrorKind::ManagementInterfaceError("Server exited unexpectedly").into()) + } + } + } + { + { + { + break Err(ErrorKind::ManagementInterfaceError("Server exited unexpectedlyy").into()) + } + } + } +} + +// #3457 +fn issue3457() { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + println!("Test"); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +} + +// #3498 +static REPRO: &[usize] = &[#[cfg(feature = "zero")] + 0]; + +fn overflow_with_attr() { + foo(#[cfg(feature = "zero")] + 0); + foobar(#[cfg(feature = "zero")] + 0); + foobar(x, y, #[cfg(feature = "zero")] + {}); +} + + +// https://github.com/rust-lang/rustfmt/issues/3765 +fn foo() { + async { + // Do + // some + // work + } + .await; + + async { + // Do + // some + // work + } + .await; +} + +fn underscore() { + _= 1; + _; + [ _,a,_ ] = [1, 2, 3]; + (a, _) = (8, 9); + TupleStruct( _, a) = TupleStruct(2, 2); + + let _ : usize = foo(_, _); +} diff --git a/src/tools/rustfmt/tests/source/extern.rs b/src/tools/rustfmt/tests/source/extern.rs new file mode 100644 index 000000000..f51ba6e98 --- /dev/null +++ b/src/tools/rustfmt/tests/source/extern.rs @@ -0,0 +1,92 @@ +// rustfmt-normalize_comments: true + + extern crate foo ; + extern crate foo as bar ; + +extern crate futures; +extern crate dotenv; +extern crate chrono; + +extern crate foo; +extern crate bar; + +// #2315 +extern crate proc_macro2; +extern crate proc_macro; + +// #3128 +extern crate serde; // 1.0.78 +extern crate serde_derive; // 1.0.78 +extern crate serde_json; // 1.0.27 + + extern "C" { + fn c_func(x: *mut *mut libc::c_void); + + fn c_func(x: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX, y: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY); + + #[test123] + fn foo() -> uint64_t; + +pub fn bar() ; + } + +extern { + fn DMR_GetDevice(pHDev: *mut HDEV, searchMode: DeviceSearchMode, pSearchString: *const c_char, devNr: c_uint, wildcard: c_char) -> TDMR_ERROR; + + fn quux() -> (); // Post comment + + pub type + Foo; + + type Bar; +} + +extern "Rust" { static ext: u32; + // Some comment. + pub static mut var : SomeType ; } + +extern "C" { + fn syscall(number: libc::c_long /* comment 1 */, /* comm 2 */ ... /* sup? */) -> libc::c_long; + + fn foo (x: *const c_char , ... ) -> +libc::c_long; + } + + extern { + pub fn freopen(filename: *const c_char, mode: *const c_char + , mode2: *const c_char + , mode3: *const c_char, + file: *mut FILE) + -> *mut FILE; + + + const fn foo( + + ) -> + *mut Bar; + unsafe fn foo( + + ) -> * + mut + Bar; + + pub(super) const fn foo() -> *mut Bar; + pub(crate) unsafe fn foo() -> *mut Bar; + } + +extern { + +} + +macro_rules! x { + ($tt:tt) => {}; +} + +extern "macros" { + x!(ident); + x!(#); + x![ident]; + x![#]; + x! {ident} + x! {#} +} diff --git a/src/tools/rustfmt/tests/source/extern_not_explicit.rs b/src/tools/rustfmt/tests/source/extern_not_explicit.rs new file mode 100644 index 000000000..9d6c4c2a1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/extern_not_explicit.rs @@ -0,0 +1,14 @@ +// rustfmt-force_explicit_abi: false + + extern "C" { + fn some_fn() -> (); + } + + extern "C" fn sup() { + + } + +type funky_func = extern "C" fn (unsafe extern "rust-call" fn(*const JSJitInfo, *mut JSContext, + HandleObject, *mut libc::c_void, u32, + *mut JSVal) + -> u8); diff --git a/src/tools/rustfmt/tests/source/file-lines-1.rs b/src/tools/rustfmt/tests/source/file-lines-1.rs new file mode 100644 index 000000000..0164e30a8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/file-lines-1.rs @@ -0,0 +1,29 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-1.rs","range":[4,8]}] + +fn floaters() { + let x = Foo { + field1: val1, + field2: val2, + } + .method_call().method_call(); + + let y = if cond { + val1 + } else { + val2 + } + .method_call(); + + { + match x { + PushParam => { + // comment + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } +} diff --git a/src/tools/rustfmt/tests/source/file-lines-2.rs b/src/tools/rustfmt/tests/source/file-lines-2.rs new file mode 100644 index 000000000..6f44ec6e6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/file-lines-2.rs @@ -0,0 +1,29 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-2.rs","range":[10,15]}] + +fn floaters() { + let x = Foo { + field1: val1, + field2: val2, + } + .method_call().method_call(); + + let y = if cond { + val1 + } else { + val2 + } + .method_call(); + + { + match x { + PushParam => { + // comment + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } +} diff --git a/src/tools/rustfmt/tests/source/file-lines-3.rs b/src/tools/rustfmt/tests/source/file-lines-3.rs new file mode 100644 index 000000000..4b825b9f5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/file-lines-3.rs @@ -0,0 +1,29 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-3.rs","range":[4,8]},{"file":"tests/source/file-lines-3.rs","range":[10,15]}] + +fn floaters() { + let x = Foo { + field1: val1, + field2: val2, + } + .method_call().method_call(); + + let y = if cond { + val1 + } else { + val2 + } + .method_call(); + + { + match x { + PushParam => { + // comment + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } +} diff --git a/src/tools/rustfmt/tests/source/file-lines-4.rs b/src/tools/rustfmt/tests/source/file-lines-4.rs new file mode 100644 index 000000000..83928bf6f --- /dev/null +++ b/src/tools/rustfmt/tests/source/file-lines-4.rs @@ -0,0 +1,30 @@ +// rustfmt-file_lines: [] +// (Test that nothing is formatted if an empty array is specified.) + +fn floaters() { + let x = Foo { + field1: val1, + field2: val2, + } + .method_call().method_call(); + + let y = if cond { + val1 + } else { + val2 + } + .method_call(); + // aaaaaaaaaaaaa + { + match x { + PushParam => { + // comment + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } +} diff --git a/src/tools/rustfmt/tests/source/file-lines-5.rs b/src/tools/rustfmt/tests/source/file-lines-5.rs new file mode 100644 index 000000000..8ec2c67bc --- /dev/null +++ b/src/tools/rustfmt/tests/source/file-lines-5.rs @@ -0,0 +1,17 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-5.rs","range":[3,5]}] + +struct A { +t: i64, +} + +mod foo { + fn bar() { + // test + let i = 12; + // test + } + // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + fn baz() { + let j = 15; + } +} diff --git a/src/tools/rustfmt/tests/source/file-lines-6.rs b/src/tools/rustfmt/tests/source/file-lines-6.rs new file mode 100644 index 000000000..2eacc8a0e --- /dev/null +++ b/src/tools/rustfmt/tests/source/file-lines-6.rs @@ -0,0 +1,18 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-6.rs","range":[9,10]}] + +struct A { + t: i64, +} + +mod foo { + fn bar() { + // test + let i = 12; + // test + } + + fn baz() { +/// + let j = 15; + } +} diff --git a/src/tools/rustfmt/tests/source/file-lines-7.rs b/src/tools/rustfmt/tests/source/file-lines-7.rs new file mode 100644 index 000000000..b227ac35d --- /dev/null +++ b/src/tools/rustfmt/tests/source/file-lines-7.rs @@ -0,0 +1,24 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-7.rs","range":[8,15]}] + +struct A { + t: i64, +} + +mod foo { + fn bar() { + + + + // test + let i = 12; + // test + } + + fn baz() { + + + + /// + let j = 15; + } +} diff --git a/src/tools/rustfmt/tests/source/file-lines-item.rs b/src/tools/rustfmt/tests/source/file-lines-item.rs new file mode 100644 index 000000000..fe52a7fa1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/file-lines-item.rs @@ -0,0 +1,21 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-item.rs","range":[6,8]}] + +use foo::{c, b, a}; +use bar; + +fn foo() { + bar ( ) ; +} + +impl Drop for Context { + fn drop(&mut self) { + } +} + +impl Bar for Baz { + fn foo() { + bar( + baz, // Who knows? + ) + } +} diff --git a/src/tools/rustfmt/tests/source/fn-custom-2.rs b/src/tools/rustfmt/tests/source/fn-custom-2.rs new file mode 100644 index 000000000..a3697c36d --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-custom-2.rs @@ -0,0 +1,35 @@ +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); +} + +fn baz() where X: TTTTTTTT { + baz(); +} + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + +impl Foo { + fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); + } + + fn baz() where X: TTTTTTTT { + baz(); + } +} + +struct Foo<TTTTTTTTTTTTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUU, VVVVVVVVVVVVVVVVVVVVVVVVVVV, WWWWWWWWWWWWWWWWWWWWWWWW> { + foo: Foo, +} diff --git a/src/tools/rustfmt/tests/source/fn-custom-3.rs b/src/tools/rustfmt/tests/source/fn-custom-3.rs new file mode 100644 index 000000000..a5e0f9af2 --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-custom-3.rs @@ -0,0 +1,31 @@ +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); +} + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + +impl Foo { + fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); + } +} + +struct Foo<TTTTTTTTTTTTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUU, VVVVVVVVVVVVVVVVVVVVVVVVVVV, WWWWWWWWWWWWWWWWWWWWWWWW> { + foo: Foo, +} diff --git a/src/tools/rustfmt/tests/source/fn-custom-4.rs b/src/tools/rustfmt/tests/source/fn-custom-4.rs new file mode 100644 index 000000000..6e18b6f9f --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-custom-4.rs @@ -0,0 +1,13 @@ +// Test different indents. + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + +fn qux(a: Aaaaaaaaaaaaaaaaa) where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} diff --git a/src/tools/rustfmt/tests/source/fn-custom-6.rs b/src/tools/rustfmt/tests/source/fn-custom-6.rs new file mode 100644 index 000000000..807084575 --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-custom-6.rs @@ -0,0 +1,40 @@ +// rustfmt-brace_style: PreferSameLine +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) -> String { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) where T: UUUUUUUUUUU { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) where T: UUUUUUUUUUU { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String where T: UUUUUUUUUUU { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) -> String where T: UUUUUUUUUUU { + bar(); +} + +trait Test { + fn foo(a: u8) {} + + fn bar(a: u8) -> String {} +} diff --git a/src/tools/rustfmt/tests/source/fn-custom-7.rs b/src/tools/rustfmt/tests/source/fn-custom-7.rs new file mode 100644 index 000000000..d5330196b --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-custom-7.rs @@ -0,0 +1,24 @@ +// rustfmt-normalize_comments: true +// rustfmt-fn_args_layout: Vertical +// rustfmt-brace_style: AlwaysNextLine + +// Case with only one variable. +fn foo(a: u8) -> u8 { + bar() +} + +// Case with 2 variables and some pre-comments. +fn foo(a: u8 /* Comment 1 */, b: u8 /* Comment 2 */) -> u8 { + bar() +} + +// Case with 2 variables and some post-comments. +fn foo(/* Comment 1 */ a: u8, /* Comment 2 */ b: u8) -> u8 { + bar() +} + +trait Test { + fn foo(a: u8) {} + + fn bar(a: u8) -> String {} +} diff --git a/src/tools/rustfmt/tests/source/fn-custom-8.rs b/src/tools/rustfmt/tests/source/fn-custom-8.rs new file mode 100644 index 000000000..0dd64868b --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-custom-8.rs @@ -0,0 +1,48 @@ +// rustfmt-brace_style: PreferSameLine +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) -> String { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) where T: UUUUUUUUUUU { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) where T: UUUUUUUUUUU { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String where T: UUUUUUUUUUU { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) -> String where T: UUUUUUUUUUU { + bar(); +} + +trait Test { + fn foo( + a: u8) { + + } + + fn bar(a: u8) + -> String { + + } + + fn bar(a: u8) -> String where Foo: foooo, Bar: barrr {} +} diff --git a/src/tools/rustfmt/tests/source/fn-custom.rs b/src/tools/rustfmt/tests/source/fn-custom.rs new file mode 100644 index 000000000..77ced4c5e --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-custom.rs @@ -0,0 +1,13 @@ +// rustfmt-fn_args_layout: Compressed +// Test some of the ways function signatures can be customised. + +// Test compressed layout of args. +fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +impl Foo { + fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } +} diff --git a/src/tools/rustfmt/tests/source/fn-param-attributes.rs b/src/tools/rustfmt/tests/source/fn-param-attributes.rs new file mode 100644 index 000000000..3407a3b2e --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-param-attributes.rs @@ -0,0 +1,57 @@ +// https://github.com/rust-lang/rustfmt/issues/3623 + +fn foo(#[cfg(something)] x: i32, y: i32) -> i32 { + x + y +} + +fn foo_b(#[cfg(something)]x: i32, y: i32) -> i32 { + x + y +} + +fn add(#[cfg(something)]#[deny(C)] x: i32, y: i32) -> i32 { + x + y +} + +struct NamedSelfRefStruct {} +impl NamedSelfRefStruct { + fn foo( +#[cfg(something)] self: &Self, + ) {} +} + +struct MutStruct {} +impl MutStruct { + fn foo( + #[cfg(foo)]&mut self,#[deny(C)] b: i32, + ) {} +} + +fn main() { + let c = | + #[allow(C)]a: u32, + #[cfg(something)] b: i32, + #[cfg_attr(something, cfg(nothing))]#[deny(C)] c: i32, + | {}; + let _ = c(1, 2); +} + +pub fn bar( + /// bar +#[test] a: u32, + /// Bar + #[must_use] +/// Baz + #[no_mangle] b: i32, +) {} + + +fn abc( + #[foo] + #[bar] param: u32, +) { + // ... +} + +fn really_really_really_loooooooooooooooooooong(#[cfg(some_even_longer_config_feature_that_keeps_going_and_going_and_going_forever_and_ever_and_ever_on_and_on)] b: i32) { + // ... +} diff --git a/src/tools/rustfmt/tests/source/fn-simple.rs b/src/tools/rustfmt/tests/source/fn-simple.rs new file mode 100644 index 000000000..12a50c013 --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-simple.rs @@ -0,0 +1,74 @@ +// rustfmt-normalize_comments: true + +fn simple(/*pre-comment on a function!?*/ i: i32/*yes, it's possible! */ + ,response: NoWay /* hose */) { +fn op(x: Typ, key : &[u8], upd : Box<Fn(Option<&memcache::Item>) -> (memcache::Status, Result<memcache::Item, Option<String>>)>) -> MapResult {} + + "cool"} + + +fn weird_comment(/* /*/ double level */ comment */ x: Hello /*/*/* triple, even */*/*/, +// Does this work? +y: World +) { + simple(/* does this preserve comments now? */ 42, NoWay) +} + +fn generic<T>(arg: T) -> &SomeType + where T: Fn(// First arg + A, + // Second argument + B, C, D, /* pre comment */ E /* last comment */) -> &SomeType { + arg(a, b, c, d, e) +} + +fn foo() -> ! {} + +pub fn http_fetch_async(listener:Box< AsyncCORSResponseListener+Send >, script_chan: Box<ScriptChan+Send>) { +} + +fn some_func<T:Box<Trait+Bound>>(val:T){} + +fn zzzzzzzzzzzzzzzzzzzz<Type, NodeType> + (selff: Type, mut handle: node::Handle<IdRef<'id, Node<K, V>>, Type, NodeType>) + -> SearchStack<'a, K, V, Type, NodeType>{ +} + +unsafe fn generic_call(cx: *mut JSContext, argc: libc::c_uint, vp: *mut JSVal, + is_lenient: bool, + call: unsafe extern fn(*const JSJitInfo, *mut JSContext, + HandleObject, *mut libc::c_void, u32, + *mut JSVal) + -> u8) { + let f: fn ( _ , _ ) -> _ = panic!() ; +} + +pub fn start_export_thread<C: CryptoSchemee + 'static>(database: &Database, crypto_scheme: &C, block_size: usize, source_path: &Path) -> BonzoResult<mpsc::Consumer<'static, FileInstruction>> {} + +pub fn waltz(cwd: &Path) -> CliAssert { + { + { + formatted_comment = rewrite_comment(comment, block_style, width, offset, formatting_fig); + } + } +} + +// #2003 +mod foo { + fn __bindgen_test_layout_i_open0_c_open1_char_a_open2_char_close2_close1_close0_instantiation() { + foo(); + } +} + +// #2082 +pub(crate) fn init() {} + +pub(crate) fn init() {} + +// #2630 +fn make_map<T, F: (Fn(&T) -> String)>(records: &Vec<T>, key_fn: F) -> HashMap<String, usize> {} + +// #2956 +fn bar(beans: Asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf, spam: bool, eggs: bool) -> bool{ + unimplemented!(); +} diff --git a/src/tools/rustfmt/tests/source/fn-single-line/version_one.rs b/src/tools/rustfmt/tests/source/fn-single-line/version_one.rs new file mode 100644 index 000000000..469ab6215 --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-single-line/version_one.rs @@ -0,0 +1,80 @@ +// rustfmt-fn_single_line: true +// rustfmt-version: One +// Test single-line functions. + +fn foo_expr() { + 1 +} + +fn foo_stmt() { + foo(); +} + +fn foo_decl_local() { + let z = 5; + } + +fn foo_decl_item(x: &mut i32) { + x = 3; +} + + fn empty() { + +} + +fn foo_return() -> String { + "yay" +} + +fn foo_where() -> T where T: Sync { + let x = 2; +} + +fn fooblock() { + { + "inner-block" + } +} + +fn fooblock2(x: i32) { + let z = match x { + _ => 2, + }; +} + +fn comment() { + // this is a test comment + 1 +} + +fn comment2() { + // multi-line comment + let z = 2; + 1 +} + +fn only_comment() { + // Keep this here +} + +fn aaaaaaaaaaaaaaaaa_looooooooooooooooooooooong_name() { + let z = "aaaaaaawwwwwwwwwwwwwwwwwwwwwwwwwwww"; +} + +fn lots_of_space () { + 1 +} + +fn mac() -> Vec<i32> { vec![] } + +trait CoolTypes { + fn dummy(&self) { + } +} + +trait CoolerTypes { fn dummy(&self) { +} +} + +fn Foo<T>() where T: Bar { +} diff --git a/src/tools/rustfmt/tests/source/fn-single-line/version_two.rs b/src/tools/rustfmt/tests/source/fn-single-line/version_two.rs new file mode 100644 index 000000000..bf381ff10 --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn-single-line/version_two.rs @@ -0,0 +1,80 @@ +// rustfmt-fn_single_line: true +// rustfmt-version: Two +// Test single-line functions. + +fn foo_expr() { + 1 +} + +fn foo_stmt() { + foo(); +} + +fn foo_decl_local() { + let z = 5; + } + +fn foo_decl_item(x: &mut i32) { + x = 3; +} + + fn empty() { + +} + +fn foo_return() -> String { + "yay" +} + +fn foo_where() -> T where T: Sync { + let x = 2; +} + +fn fooblock() { + { + "inner-block" + } +} + +fn fooblock2(x: i32) { + let z = match x { + _ => 2, + }; +} + +fn comment() { + // this is a test comment + 1 +} + +fn comment2() { + // multi-line comment + let z = 2; + 1 +} + +fn only_comment() { + // Keep this here +} + +fn aaaaaaaaaaaaaaaaa_looooooooooooooooooooooong_name() { + let z = "aaaaaaawwwwwwwwwwwwwwwwwwwwwwwwwwww"; +} + +fn lots_of_space () { + 1 +} + +fn mac() -> Vec<i32> { vec![] } + +trait CoolTypes { + fn dummy(&self) { + } +} + +trait CoolerTypes { fn dummy(&self) { +} +} + +fn Foo<T>() where T: Bar { +} diff --git a/src/tools/rustfmt/tests/source/fn_args_indent-block.rs b/src/tools/rustfmt/tests/source/fn_args_indent-block.rs new file mode 100644 index 000000000..955f390cc --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn_args_indent-block.rs @@ -0,0 +1,77 @@ +// rustfmt-normalize_comments: true + +fn foo() { + foo(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) -> String { + bar(); +} + +fn foo(a: u8 /* Comment 1 */, b: u8 /* Comment 2 */) -> u8 { + bar() +} + +fn foo(a: u8 /* Comment 1 */, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee /* Comment 2 */) -> u8 { + bar() +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) -> String where X: Fooooo, Y: Baaar { + bar(); +} + +fn foo() -> T { + foo(); +} + +fn foo() -> T where X: Foooo, Y: Baaar { + foo(); +} + +fn foo() where X: Foooo { +} + +fn foo() where X: Foooo, Y: Baaar { +} + +fn foo() -> (Loooooooooooooooooooooong, Reeeeeeeeeeeeeeeeeeeeeeeeturn, iiiiiiiiis, Looooooooooooooooong) { + foo(); +} + +fn foo<g: G>() { + foo(); +} + +fn foo<L: Loooooooooooooooooooooong, G: Geeeeeeeeeeeneric, I: iiiiiiiiis, L: Looooooooooooooooong>() { + foo(); +} + +fn foo<L: Loooooooooooooooooooong, G: Geeeeeeeeeeneric, I: iiiiiiiiis, L: Loooooooooooooooong>() { + foo(); +} + +trait Test { + fn foo(a: u8) {} + + fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) -> String {} +} + +fn foo<L: Loooooooooooooooooooong, G: Geeeeeeeeeeneric, I: iiiiiiiiis, L: Loooooooooooooooong>(a: Aaaaaaaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd) { + foo(); +} + +fn foo() -> (Looooooooooooooooooooooooooong, Reeeeeeeeeeeeeeeeeeeeeeeeeeeeeturn, iiiiiiiiiiiiiis, Loooooooooooooooooooooong) { + foo(); +} diff --git a/src/tools/rustfmt/tests/source/fn_args_layout-vertical.rs b/src/tools/rustfmt/tests/source/fn_args_layout-vertical.rs new file mode 100644 index 000000000..759bc83d0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/fn_args_layout-vertical.rs @@ -0,0 +1,33 @@ +// rustfmt-fn_args_layout: Vertical + +// Empty list should stay on one line. +fn do_bar( + +) -> u8 { + bar() +} + +// A single argument should stay on the same line. +fn do_bar( + a: u8) -> u8 { + bar() +} + +// Multiple arguments should each get their own line. +fn do_bar(a: u8, mut b: u8, c: &u8, d: &mut u8, closure: &Fn(i32) -> i32) -> i32 { + // This feature should not affect closures. + let bar = |x: i32, y: i32| -> i32 { x + y }; + bar(a, b) +} + +// If the first argument doesn't fit on the same line with the function name, +// the whole list should probably be pushed to the next line with hanging +// indent. That's not what happens though, so check current behaviour instead. +// In any case, it should maintain single argument per line. +fn do_this_that_and_the_other_thing( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: u8, + b: u8, c: u8, d: u8) { + this(); + that(); + the_other_thing(); +} diff --git a/src/tools/rustfmt/tests/source/hard-tabs.rs b/src/tools/rustfmt/tests/source/hard-tabs.rs new file mode 100644 index 000000000..e4a0f4170 --- /dev/null +++ b/src/tools/rustfmt/tests/source/hard-tabs.rs @@ -0,0 +1,84 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-hard_tabs: true + +fn main() { +let x = Bar; + +let y = Foo {a: x }; + +Foo { a: foo() /* comment*/, /* comment*/ b: bar(), ..something }; + +fn foo(a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32) {} + +let str = "AAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAa"; + +if let (some_very_large, tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple) = 1 ++ 2 + 3 { +} + + if cond() { + something(); + } else if different_cond() { + something_else(); + } else { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + } + +unsafe /* very looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong comment */ {} + +unsafe // So this is a very long comment. + // Multi-line, too. + // Will it still format correctly? +{ +} + +let chain = funktion_kall().go_to_next_line_with_tab().go_to_next_line_with_tab().go_to_next_line_with_tab(); + +let z = [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzzzz, q]; + +fn generic<T>(arg: T) -> &SomeType + where T: Fn(// First arg + A, + // Second argument + B, C, D, /* pre comment */ E /* last comment */) -> &SomeType { + arg(a, b, c, d, e) +} + + loong_func().quux(move || { + if true { + 1 + } else { + 2 + } + }); + + fffffffffffffffffffffffffffffffffff(a, + { + SCRIPT_TASK_ROOT + .with(|root| { + *root.borrow_mut() = Some(&script_task); + }); + }); + a.b + .c + .d(); + + x().y(|| { + match cond() { + true => (), + false => (), + } + }); +} + +// #2296 +impl Foo { + // a comment + // on multiple lines + fn foo() { + // another comment + // on multiple lines + let x = true; + } +} diff --git a/src/tools/rustfmt/tests/source/hello.rs b/src/tools/rustfmt/tests/source/hello.rs new file mode 100644 index 000000000..f892e6deb --- /dev/null +++ b/src/tools/rustfmt/tests/source/hello.rs @@ -0,0 +1,6 @@ +// rustfmt-config: small_tabs.toml +// rustfmt-target: hello.rs + +// Smoke test - hello world. + +fn main() { println!("Hello world!"); } diff --git a/src/tools/rustfmt/tests/source/hello2.rs b/src/tools/rustfmt/tests/source/hello2.rs new file mode 100644 index 000000000..48af7de38 --- /dev/null +++ b/src/tools/rustfmt/tests/source/hello2.rs @@ -0,0 +1,8 @@ +// rustfmt-config: small_tabs.toml +// rustfmt-target: hello.rs + +// Smoke test - hello world. + +fn main( ) { +println!("Hello world!"); +} diff --git a/src/tools/rustfmt/tests/source/hex_literal_lower.rs b/src/tools/rustfmt/tests/source/hex_literal_lower.rs new file mode 100644 index 000000000..ce307b3aa --- /dev/null +++ b/src/tools/rustfmt/tests/source/hex_literal_lower.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Lower +fn main() { + let h1 = 0xCAFE_5EA7; + let h2 = 0xCAFE_F00Du32; +} diff --git a/src/tools/rustfmt/tests/source/hex_literal_upper.rs b/src/tools/rustfmt/tests/source/hex_literal_upper.rs new file mode 100644 index 000000000..b1092ad71 --- /dev/null +++ b/src/tools/rustfmt/tests/source/hex_literal_upper.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Upper +fn main() { + let h1 = 0xCaFE_5ea7; + let h2 = 0xCAFE_F00Du32; +} diff --git a/src/tools/rustfmt/tests/source/if_while_or_patterns.rs b/src/tools/rustfmt/tests/source/if_while_or_patterns.rs new file mode 100644 index 000000000..f01df7e91 --- /dev/null +++ b/src/tools/rustfmt/tests/source/if_while_or_patterns.rs @@ -0,0 +1,27 @@ +#![feature(if_while_or_patterns)] + +fn main() { + if let 0 | 1 = 0 { + println!("hello, world"); + }; + + if let aaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbbbbbbbbbbbbbbbbbbb | cccccccccccccccc | d_100 = 0 { + println!("hello, world"); + } + + if let aaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbbbbbbbbbbbbbbb | ccccccccccccccccccccc | d_101 = 0 { + println!("hello, world"); + } + + if let aaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbbbbbbbbbbbbbbb | ccccccccccccccccccccc | d_103 = 0 { + println!("hello, world"); + } + + if let aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbbbbbbbbbbbbbbb | ccccccccccccccccccccc | d_105 = 0 { + println!("hello, world"); + } + + while let xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx = foo_bar(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccccccccccccccccc) { + println!("hello, world"); + } +} diff --git a/src/tools/rustfmt/tests/source/immovable_generators.rs b/src/tools/rustfmt/tests/source/immovable_generators.rs new file mode 100644 index 000000000..c57a1e144 --- /dev/null +++ b/src/tools/rustfmt/tests/source/immovable_generators.rs @@ -0,0 +1,7 @@ +#![feature(generators)] + +unsafe fn foo() { + let mut ga = static || { + yield 1; + }; +} diff --git a/src/tools/rustfmt/tests/source/impls.rs b/src/tools/rustfmt/tests/source/impls.rs new file mode 100644 index 000000000..dcd1f0cd5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/impls.rs @@ -0,0 +1,178 @@ +// rustfmt-normalize_comments: true +impl Foo for Bar { fn foo() { "hi" } } + +pub impl Foo for Bar { + // Associated Constants + const Baz: i32 = 16; + // Associated Types + type FooBar = usize; + // Comment 1 + fn foo() { "hi" } + // Comment 2 + fn foo() { "hi" } + // Comment 3 +} + +#[inherent] +impl Visible for Bar { + pub const C: i32; + pub type T; + pub fn f(); + pub fn g() {} +} + +pub unsafe impl<'a, 'b, X, Y: Foo<Bar>> !Foo<'a, X> for Bar<'b, Y> where X: Foo<'a, Z> { + fn foo() { "hi" } +} + +impl<'a, 'b, X, Y: Foo<Bar>> Foo<'a, X> for Bar<'b, Y> where X: Fooooooooooooooooooooooooooooo<'a, Z> +{ + fn foo() { "hi" } +} + +impl<'a, 'b, X, Y: Foo<Bar>> Foo<'a, X> for Bar<'b, Y> where X: Foooooooooooooooooooooooooooo<'a, Z> +{ + fn foo() { "hi" } +} + +impl<T> Foo for Bar<T> where T: Baz +{ +} + +impl<T> Foo for Bar<T> where T: Baz { /* Comment */ } + +impl Foo { + fn foo() {} +} + +impl Boo { + + // BOO + fn boo() {} + // FOO + + + +} + +mod a { + impl Foo { + // Hello! + fn foo() {} + } +} + + +mod b { + mod a { + impl Foo { + fn foo() {} + } + } +} + +impl Foo { add_fun!(); } + +impl Blah { + fn boop() {} + add_fun!(); +} + +impl X { fn do_parse( mut self : X ) {} } + +impl Y5000 { + fn bar(self: X< 'a , 'b >, y: Y) {} + + fn bad(&self, ( x, y): CoorT) {} + + fn turbo_bad(self: X< 'a , 'b > , ( x, y): CoorT) { + + } +} + +pub impl<T> Foo for Bar<T> where T: Foo +{ + fn foo() { "hi" } +} + +pub impl<T, Z> Foo for Bar<T, Z> where T: Foo, Z: Baz {} + +mod m { + impl<T> PartialEq for S<T> where T: PartialEq { + fn eq(&self, other: &Self) { + true + } + } + + impl<T> PartialEq for S<T> where T: PartialEq { } + } + +impl<BorrowType, K, V, NodeType, HandleType> Handle<NodeRef<BorrowType, K, V, NodeType>, HandleType> { +} + +impl<BorrowType, K, V, NodeType, HandleType> PartialEq for Handle<NodeRef<BorrowType, K, V, NodeType>, HandleType> { +} + +mod x { + impl<A, B, C, D> Foo + where A: 'static, + B: 'static, + C: 'static, + D: 'static { } +} + +impl<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNodeFoo> Issue1249<ConcreteThreadSafeLayoutNode> { + // Creates a new flow constructor. + fn foo() {} +} + +// #1600 +impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> { + fn drop() {} +} + +// #1168 +pub trait Number: Copy + Eq + Not<Output = Self> + Shl<u8, Output = Self> + + Shr<u8, Output = Self> + + BitAnd<Self, Output=Self> + BitOr<Self, Output=Self> + BitAndAssign + BitOrAssign + + + +{ + // test + fn zero() -> Self; +} + +// #1642 +pub trait SomeTrait : Clone + Eq + PartialEq + Ord + PartialOrd + Default + Hash + Debug + Display + Write + Read + FromStr { + // comment +} + +// #1995 +impl Foo { + fn f( + S { + aaaaaaaaaa: aaaaaaaaaa, + bbbbbbbbbb: bbbbbbbbbb, + cccccccccc: cccccccccc, + }: S + ) -> u32{ + 1 + } +} + +// #2491 +impl<'a, 'b, 'c> SomeThing<Something> for (&'a mut SomethingLong, &'b mut SomethingLong, &'c mut SomethingLong) { + fn foo() {} +} + +// #2746 +impl<'seq1, 'seq2, 'body, 'scope, Channel> Adc12< Dual, MasterRunningDma<'seq1, 'body, 'scope, Channel>, SlaveRunningDma<'seq2, 'body, 'scope>, > where Channel: DmaChannel, {} + +// #4084 +impl const std::default::Default for Struct { + #[inline] + fn default() -> Self { + Self { f: 12.5 } + } +} diff --git a/src/tools/rustfmt/tests/source/imports/imports-impl-only-use.rs b/src/tools/rustfmt/tests/source/imports/imports-impl-only-use.rs new file mode 100644 index 000000000..d290d8d91 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports-impl-only-use.rs @@ -0,0 +1,4 @@ +#![feature(underscore_imports)] + +use attr; +use std::iter::Iterator as _; diff --git a/src/tools/rustfmt/tests/source/imports/imports-reorder-lines-and-items.rs b/src/tools/rustfmt/tests/source/imports/imports-reorder-lines-and-items.rs new file mode 100644 index 000000000..b6380f31c --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports-reorder-lines-and-items.rs @@ -0,0 +1,7 @@ +/// This comment should stay with `use std::str;` +use std::str; +use std::cmp::{d, c, b, a}; +use std::ddd::aaa; +use std::ddd::{d as p, c as g, b, a}; +// This comment should stay with `use std::ddd:bbb;` +use std::ddd::bbb; diff --git a/src/tools/rustfmt/tests/source/imports/imports-reorder-lines.rs b/src/tools/rustfmt/tests/source/imports/imports-reorder-lines.rs new file mode 100644 index 000000000..2b018544e --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports-reorder-lines.rs @@ -0,0 +1,32 @@ +use std::str; +use std::cmp::{d, c, b, a}; +use std::cmp::{b, e, g, f}; +use std::ddd::aaa; +// This comment should stay with `use std::ddd;` +use std::ddd; +use std::ddd::bbb; + +mod test { +} + +use aaa::bbb; +use aaa; +use aaa::*; + +mod test {} +// If item names are equal, order by rename + +use test::{a as bb, b}; +use test::{a as aa, c}; + +mod test {} +// If item names are equal, order by rename - no rename comes before a rename + +use test::{a as bb, b}; +use test::{a, c}; + +mod test {} +// `self` always comes first + +use test::{a as aa, c}; +use test::{self as bb, b}; diff --git a/src/tools/rustfmt/tests/source/imports/imports-reorder.rs b/src/tools/rustfmt/tests/source/imports/imports-reorder.rs new file mode 100644 index 000000000..cbe9d6ca7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports-reorder.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true + +use path::{C,/*A*/ A, B /* B */, self /* self */}; + +use {ab, ac, aa, Z, b}; diff --git a/src/tools/rustfmt/tests/source/imports/imports.rs b/src/tools/rustfmt/tests/source/imports/imports.rs new file mode 100644 index 000000000..4dfc6ed94 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports.rs @@ -0,0 +1,107 @@ +// rustfmt-normalize_comments: true + +// Imports. + +// Long import. +use rustc_ast::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl}; +use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA, ItemB}; +use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA, ItemB}; + +use list::{ + // Some item + SomeItem /* Comment */, /* Another item */ AnotherItem /* Another Comment */, // Last Item + LastItem +}; + +use test::{ Other /* C */ , /* A */ self /* B */ }; + +use rustc_ast::{self}; +use {/* Pre-comment! */ + Foo, Bar /* comment */}; +use Foo::{Bar, Baz}; +pub use rustc_ast::ast::{Expr_, Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath}; + +use rustc_ast::some::{}; + +use self; +use std::io::{self}; +use std::io::self; + +mod Foo { + pub use rustc_ast::ast::{ + ItemForeignMod, + ItemImpl, + ItemMac, + ItemMod, + ItemStatic, + ItemDefaultImpl + }; + + mod Foo2 { + pub use rustc_ast::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, self, ItemDefaultImpl}; + } +} + +fn test() { +use Baz::*; + use Qux; +} + +// Simple imports +use foo::bar::baz as baz ; +use bar::quux as kaas; +use foo; + +// With aliases. +use foo::{self as bar, baz}; +use foo::{self as bar}; +use foo::{qux as bar}; +use foo::{baz, qux as bar}; + +// With absolute paths +use ::foo; +use ::foo::{Bar}; +use ::foo::{Bar, Baz}; +use ::{Foo}; +use ::{Bar, Baz}; + +// Root globs +use *; +use ::*; + +// spaces used to cause glob imports to disappear (#1356) +use super:: * ; +use foo::issue_1356:: * ; + +// We shouldn't remove imports which have attributes attached (#1858) +#[cfg(unix)] +use self::unix::{}; + +// nested imports +use foo::{a, bar::{baz, qux, xxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, foo::{a, b, cxxxxxxxxxxxxx, yyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz}}, b, boo, c,}; + +use fooo::{baar::{foobar::{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz}}, z, bar, bar::*, x, y}; + +use exonum::{api::{Api, ApiError}, blockchain::{self, BlockProof, Blockchain, Transaction, TransactionSet}, crypto::{Hash, PublicKey}, helpers::Height, node::TransactionSend, storage::{ListProof, MapProof}}; + +// nested imports with a single sub-tree. +use a::{b::{c::*}}; +use a::{b::{c::{}}}; +use a::{b::{c::d}}; +use a::{b::{c::{xxx, yyy, zzz}}}; + +// #2645 +/// This line is not affected. +// This line is deleted. +use c; + +// #2670 +#[macro_use] +use imports_with_attr; + +// #2888 +use std::f64::consts::{SQRT_2, E, PI}; + +// #3273 +#[rustfmt::skip] +use std::fmt::{self, {Display, Formatter}}; diff --git a/src/tools/rustfmt/tests/source/imports/imports_block_indent.rs b/src/tools/rustfmt/tests/source/imports/imports_block_indent.rs new file mode 100644 index 000000000..016deefe5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports_block_indent.rs @@ -0,0 +1,2 @@ +// #2569 +use apns2::request::notification::{Notificatio, NotificationBuilder, Priority, SilentNotificationBuilder}; diff --git a/src/tools/rustfmt/tests/source/imports/imports_granularity_crate.rs b/src/tools/rustfmt/tests/source/imports/imports_granularity_crate.rs new file mode 100644 index 000000000..f6f7761e8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports_granularity_crate.rs @@ -0,0 +1,65 @@ +// rustfmt-imports_granularity: Crate + +use a::{c,d,b}; +use a::{d, e, b, a, f}; +use a::{f, g, c}; + +#[doc(hidden)] +use a::b; +use a::c; +use a::d; + +use a::{c, d, e}; +#[doc(hidden)] +use a::b; +use a::d; + +pub use foo::bar; +use foo::{a, b, c}; +pub use foo::foobar; + +use a::{b::{c::*}}; +use a::{b::{c::{}}}; +use a::{b::{c::d}}; +use a::{b::{c::{xxx, yyy, zzz}}}; + +// https://github.com/rust-lang/rustfmt/issues/3808 +use d::{self}; +use e::{self as foo}; +use f::{self, b}; +use g::a; +use g::{self, b}; +use h::{a}; +use i::a::{self}; +use j::{a::{self}}; + +use {k::{a, b}, l::{a, b}}; +use {k::{c, d}, l::{c, d}}; + +use b::{f::g, h::{i, j} /* After b::h group */}; +use b::e; +use b::{/* Before b::l group */ l::{self, m, n::o, p::*}, q}; +use b::d; +use b::r; // After b::r +use b::q::{self /* After b::q::self */}; +use b::u::{ + a, + b, +}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::s::{ + a, + b, // After b::s::b +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::t::{/* Before b::t::self */ self}; +use b::c; diff --git a/src/tools/rustfmt/tests/source/imports/imports_granularity_default-with-dups.rs b/src/tools/rustfmt/tests/source/imports/imports_granularity_default-with-dups.rs new file mode 100644 index 000000000..cbb21a9f1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports_granularity_default-with-dups.rs @@ -0,0 +1,6 @@ +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{tokens::TokenData}; +use crate::lexer::self; +use crate::lexer::{self}; +use crate::lexer::{self, tokens::TokenData}; diff --git a/src/tools/rustfmt/tests/source/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs b/src/tools/rustfmt/tests/source/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs new file mode 100644 index 000000000..e23705a88 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs @@ -0,0 +1,13 @@ +// rustfmt-imports_granularity: Item +// rustfmt-reorder_imports: false +// rustfmt-group_imports: StdExternalCrate + +use crate::lexer; +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{tokens::TokenData}; +use crate::lexer::self; +use crate::lexer; +use crate::lexer; +use crate::lexer::{self}; +use crate::lexer::{self, tokens::TokenData}; diff --git a/src/tools/rustfmt/tests/source/imports/imports_granularity_item-with-dups.rs b/src/tools/rustfmt/tests/source/imports/imports_granularity_item-with-dups.rs new file mode 100644 index 000000000..3e9589c29 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports_granularity_item-with-dups.rs @@ -0,0 +1,11 @@ +// rustfmt-imports_granularity: Item + +use crate::lexer; +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{tokens::TokenData}; +use crate::lexer::self; +use crate::lexer; +use crate::lexer; +use crate::lexer::{self}; +use crate::lexer::{self, tokens::TokenData}; diff --git a/src/tools/rustfmt/tests/source/imports/imports_granularity_item.rs b/src/tools/rustfmt/tests/source/imports/imports_granularity_item.rs new file mode 100644 index 000000000..b82c0d33c --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports_granularity_item.rs @@ -0,0 +1,34 @@ +// rustfmt-imports_granularity: Item + +use a::{b, c, d}; +use a::{f::g, h::{i, j}}; +use a::{l::{self, m, n::o, p::*}}; +use a::q::{self}; + +use b::{f::g, h::{i, j} /* After b::h group */}; +use b::e; +use b::{/* Before b::l group */ l::{self, m, n::o, p::*}, q}; +use b::d; +use b::r; // After b::r +use b::q::{self /* After b::q::self */}; +use b::u::{ + a, + b, +}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::s::{ + a, + b, // After b::s::b +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::t::{/* Before b::t::self */ self}; +use b::c; diff --git a/src/tools/rustfmt/tests/source/imports/imports_granularity_module.rs b/src/tools/rustfmt/tests/source/imports/imports_granularity_module.rs new file mode 100644 index 000000000..c7f68cea6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports/imports_granularity_module.rs @@ -0,0 +1,47 @@ +// rustfmt-imports_granularity: Module + +use a::{b::c, d::e}; +use a::{f, g::{h, i}}; +use a::{j::{self, k::{self, l}, m}, n::{o::p, q}}; +pub use a::{r::s, t}; +use b::{c::d, self}; + +#[cfg(test)] +use foo::{a::b, c::d}; +use foo::e; + +use bar::{ + // comment + a::b, + // more comment + c::d, + e::f, +}; + +use b::{f::g, h::{i, j} /* After b::h group */}; +use b::e; +use b::{/* Before b::l group */ l::{self, m, n::o, p::*}, q}; +use b::d; +use b::r; // After b::r +use b::q::{self /* After b::q::self */}; +use b::u::{ + a, + b, +}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::s::{ + a, + b, // After b::s::b +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::t::{/* Before b::t::self */ self}; +use b::c; diff --git a/src/tools/rustfmt/tests/source/imports_granularity_one.rs b/src/tools/rustfmt/tests/source/imports_granularity_one.rs new file mode 100644 index 000000000..4d5a47956 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports_granularity_one.rs @@ -0,0 +1,88 @@ +// rustfmt-imports_granularity: One + +use b; +use a::ac::{aca, acb}; +use a::{aa::*, ab}; + +use a as x; +use b::ba; +use a::{aa, ab}; + +use a::aa::aaa; +use a::ab::aba as x; +use a::aa::*; + +use a::aa; +use a::ad::ada; +#[cfg(test)] +use a::{ab, ac::aca}; +use b; +#[cfg(test)] +use b::{ + ba, bb, + bc::bca::{bcaa, bcab}, +}; + +pub use a::aa; +pub use a::ae; +use a::{ab, ac, ad}; +use b::ba; +pub use b::{bb, bc::bca}; + +use a::aa::aaa; +use a::ac::{aca, acb}; +use a::{aa::*, ab}; +use b::{ + ba, + bb::{self, bba}, +}; + +use crate::a; +use crate::b::ba; +use c::ca; + +use super::a; +use c::ca; +use super::b::ba; + +use crate::a; +use super::b; +use c::{self, ca}; + +use a::{ + // some comment + aa::{aaa, aab}, + ab, + // another comment + ac::aca, +}; +use b as x; +use a::ad::ada; + +use b::{f::g, h::{i, j} /* After b::h group */}; +use b::e; +use b::{/* Before b::l group */ l::{self, m, n::o, p::*}, q}; +use b::d; +use b::r; // After b::r +use b::q::{self /* After b::q::self */}; +use b::u::{ + a, + b, +}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::s::{ + a, + b, // After b::s::b +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::t::{/* Before b::t::self */ self}; +use b::c; diff --git a/src/tools/rustfmt/tests/source/imports_raw_identifiers/version_One.rs b/src/tools/rustfmt/tests/source/imports_raw_identifiers/version_One.rs new file mode 100644 index 000000000..bc4b5b135 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports_raw_identifiers/version_One.rs @@ -0,0 +1,5 @@ +// rustfmt-version:One + +use websocket::client::ClientBuilder; +use websocket::r#async::futures::Stream; +use websocket::result::WebSocketError; diff --git a/src/tools/rustfmt/tests/source/imports_raw_identifiers/version_Two.rs b/src/tools/rustfmt/tests/source/imports_raw_identifiers/version_Two.rs new file mode 100644 index 000000000..88e7fbd01 --- /dev/null +++ b/src/tools/rustfmt/tests/source/imports_raw_identifiers/version_Two.rs @@ -0,0 +1,5 @@ +// rustfmt-version:Two + +use websocket::client::ClientBuilder; +use websocket::r#async::futures::Stream; +use websocket::result::WebSocketError; diff --git a/src/tools/rustfmt/tests/source/invalid-rust-code-in-doc-comment.rs b/src/tools/rustfmt/tests/source/invalid-rust-code-in-doc-comment.rs new file mode 100644 index 000000000..835b0261b --- /dev/null +++ b/src/tools/rustfmt/tests/source/invalid-rust-code-in-doc-comment.rs @@ -0,0 +1,20 @@ +// rustfmt-format_code_in_doc_comments: true + +/// ```rust +/// if (true) { … } +/// ``` +fn a() { +} + +/// ```rust +/// if foo() { +/// … +/// } +/// ``` +fn a() { +} + +/// ```rust +/// k1 == k2 ⇒ hash(k1) == hash(k2) +/// ``` +pub struct a ; diff --git a/src/tools/rustfmt/tests/source/issue-1021.rs b/src/tools/rustfmt/tests/source/issue-1021.rs new file mode 100644 index 000000000..380e24cc0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1021.rs @@ -0,0 +1,22 @@ +// rustfmt-normalize_comments: true +fn main() { + match x { + S(true , .., true ) => (), + S(true , .. ) => (), + S(.., true ) => (), + S( .. ) => (), + S(_) => (), + S(/* .. */ .. ) => (), + S(/* .. */ .., true ) => (), + } + + match y { + (true , .., true ) => (), + (true , .. ) => (), + (.., true ) => (), + ( .. ) => (), + (_,) => (), + (/* .. */ .. ) => (), + (/* .. */ .., true ) => (), + } +} diff --git a/src/tools/rustfmt/tests/source/issue-1049.rs b/src/tools/rustfmt/tests/source/issue-1049.rs new file mode 100644 index 000000000..bcfba41e7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1049.rs @@ -0,0 +1,18 @@ +// Test overlong function signature +pub unsafe fn reborrow_mut(&mut X: Abcde) -> Handle<NodeRef<marker::Mut, K, V, NodeType>, HandleType> { +} + +pub fn merge(mut X: Abcdef) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge> { +} + +impl Handle { + pub fn merge(a: Abcd) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge> { + } +} + +// Long function without return type that should not be reformatted. +fn veeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {} + +fn veeeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {} + +fn veeeeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {} diff --git a/src/tools/rustfmt/tests/source/issue-1111.rs b/src/tools/rustfmt/tests/source/issue-1111.rs new file mode 100644 index 000000000..2e1a89ad7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1111.rs @@ -0,0 +1 @@ +use bar; diff --git a/src/tools/rustfmt/tests/source/issue-1120.rs b/src/tools/rustfmt/tests/source/issue-1120.rs new file mode 100644 index 000000000..e85c9af99 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1120.rs @@ -0,0 +1,9 @@ +// rustfmt-reorder_imports: true + +// Ensure that a use at the start of an inline module is correctly formatted. +mod foo {use bar;} + +// Ensure that an indented `use` gets the correct indentation. +mod foo { + use bar; +} diff --git a/src/tools/rustfmt/tests/source/issue-1124.rs b/src/tools/rustfmt/tests/source/issue-1124.rs new file mode 100644 index 000000000..35c2197fa --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1124.rs @@ -0,0 +1,15 @@ +// rustfmt-reorder_imports: true + +use d; use c; use b; use a; +// The previous line has a space after the `use a;` + +mod a { use d; use c; use b; use a; } + +use z; + +use y; + + + +use x; +use a; diff --git a/src/tools/rustfmt/tests/source/issue-1127.rs b/src/tools/rustfmt/tests/source/issue-1127.rs new file mode 100644 index 000000000..b49db4e3f --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1127.rs @@ -0,0 +1,23 @@ +// rustfmt-max_width: 120 +// rustfmt-match_arm_blocks: false +// rustfmt-match_block_trailing_comma: true + +fn a_very_very_very_very_very_very_very_very_very_very_very_long_function_name() -> i32 { + 42 +} + +enum TestEnum { + AVeryVeryLongEnumName, + AnotherVeryLongEnumName, + TheLastVeryLongEnumName, +} + +fn main() { + let var = TestEnum::AVeryVeryLongEnumName; + let num = match var { + TestEnum::AVeryVeryLongEnumName => a_very_very_very_very_very_very_very_very_very_very_very_long_function_name(), + TestEnum::AnotherVeryLongEnumName => a_very_very_very_very_very_very_very_very_very_very_very_long_function_name(), + TestEnum::TheLastVeryLongEnumName => a_very_very_very_very_very_very_very_very_very_very_very_long_function_name(), + }; +} + diff --git a/src/tools/rustfmt/tests/source/issue-1158.rs b/src/tools/rustfmt/tests/source/issue-1158.rs new file mode 100644 index 000000000..6742e1745 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1158.rs @@ -0,0 +1,3 @@ +trait T { + itemmacro!(this, is.now() .formatted(yay)); +} diff --git a/src/tools/rustfmt/tests/source/issue-1177.rs b/src/tools/rustfmt/tests/source/issue-1177.rs new file mode 100644 index 000000000..3ac423c5a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1177.rs @@ -0,0 +1,7 @@ +// rustfmt-normalize_comments: true +fn main() { + // Line Comment + /* Block Comment */ + + let d = 5; +} diff --git a/src/tools/rustfmt/tests/source/issue-1192.rs b/src/tools/rustfmt/tests/source/issue-1192.rs new file mode 100644 index 000000000..4e39fbf9a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1192.rs @@ -0,0 +1,3 @@ +fn main() { + assert!(true) ; +} diff --git a/src/tools/rustfmt/tests/source/issue-1210/a.rs b/src/tools/rustfmt/tests/source/issue-1210/a.rs new file mode 100644 index 000000000..6bb9964b4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1210/a.rs @@ -0,0 +1,12 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 + +impl Foo { + fn cxx(&self, target: &str) -> &Path { + match self.cxx.get(target) { + Some(p) => p.path(), + None => panic!("\n\ntarget `{}` is not configured as a host, + only as a target\n\n", target), + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-1210/b.rs b/src/tools/rustfmt/tests/source/issue-1210/b.rs new file mode 100644 index 000000000..8c71ef98b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1210/b.rs @@ -0,0 +1,12 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 + +impl Foo { + fn cxx(&self, target: &str) -> &Path { + match self.cxx.get(target) { + Some(p) => p.path(), + None => panic!("\ntarget `{}`: is not, configured as a host, + only as a target\n\n", target), + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-1210/c.rs b/src/tools/rustfmt/tests/source/issue-1210/c.rs new file mode 100644 index 000000000..c080cef95 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1210/c.rs @@ -0,0 +1,5 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 + +const foo: String = "trailing_spaces!! + keep them! Amet neque. Praesent rhoncus eros non velit."; diff --git a/src/tools/rustfmt/tests/source/issue-1210/d.rs b/src/tools/rustfmt/tests/source/issue-1210/d.rs new file mode 100644 index 000000000..783736bc3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1210/d.rs @@ -0,0 +1,4 @@ +// rustfmt-wrap_comments: true + +// trailing_spaces_in_comment!! +// remove those from above diff --git a/src/tools/rustfmt/tests/source/issue-1210/e.rs b/src/tools/rustfmt/tests/source/issue-1210/e.rs new file mode 100644 index 000000000..9abada1d6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1210/e.rs @@ -0,0 +1,8 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 + +// explicit line breaks should be kept in order to preserve the layout + +const foo: String = "Suspendisse vel augue at felis tincidunt sollicitudin. Fusce arcu. + Duis et odio et leo + sollicitudin consequat. Aliquam lobortis. Phasellus condimentum."; diff --git a/src/tools/rustfmt/tests/source/issue-1211.rs b/src/tools/rustfmt/tests/source/issue-1211.rs new file mode 100644 index 000000000..5818736bf --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1211.rs @@ -0,0 +1,15 @@ +fn main() { + for iface in &ifaces { + match iface.addr { + get_if_addrs::IfAddr::V4(ref addr) => { + match addr.broadcast { + Some(ip) => { + sock.send_to(&buf, (ip, 8765)).expect("foobar"); + } + _ => () + } + } + _ => () + }; + } +} diff --git a/src/tools/rustfmt/tests/source/issue-1216.rs b/src/tools/rustfmt/tests/source/issue-1216.rs new file mode 100644 index 000000000..d727c158a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1216.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true +enum E { + A, //* I am not a block comment (caused panic) + B, +} diff --git a/src/tools/rustfmt/tests/source/issue-1239.rs b/src/tools/rustfmt/tests/source/issue-1239.rs new file mode 100644 index 000000000..913058257 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1239.rs @@ -0,0 +1,9 @@ +fn foo() { + let with_alignment = if condition__uses_alignment_for_first_if__0 || + condition__uses_alignment_for_first_if__1 || + condition__uses_alignment_for_first_if__2 { + } else if condition__no_alignment_for_later_else__0 || + condition__no_alignment_for_later_else__1 || + condition__no_alignment_for_later_else__2 { + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-1278.rs b/src/tools/rustfmt/tests/source/issue-1278.rs new file mode 100644 index 000000000..e25376561 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1278.rs @@ -0,0 +1,9 @@ +// rustfmt-indent_style = "block" + +#![feature(pub_restricted)] + +mod inner_mode { + pub(super) fn func_name(abc: i32) -> i32 { + abc + } +} diff --git a/src/tools/rustfmt/tests/source/issue-1350.rs b/src/tools/rustfmt/tests/source/issue-1350.rs new file mode 100644 index 000000000..1baa1985a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1350.rs @@ -0,0 +1,16 @@ +// rustfmt-max_width: 120 +// rustfmt-comment_width: 110 + +impl Struct { + fn fun() { + let result = match <R::RequestResult as serde::Deserialize>::deserialize(&json) { + Ok(v) => v, + Err(e) => { + match <R::ErrorResult as serde::Deserialize>::deserialize(&json) { + Ok(v) => return Err(Error::with_json(v)), + Err(e2) => return Err(Error::with_json(e)), + } + } + }; + } +} diff --git a/src/tools/rustfmt/tests/source/issue-1366.rs b/src/tools/rustfmt/tests/source/issue-1366.rs new file mode 100644 index 000000000..9d2964fc7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1366.rs @@ -0,0 +1,12 @@ +fn main() { + fn f() -> Option<i32> { + Some("fffffffsssssssssddddssssfffffddddff").map(|s| s).map(|s| s.to_string()).map(|res| { + match Some(res) { + Some(ref s) if s == "" => 41, + Some(_) => 42, + _ => 43, + } + }) + } + println!("{:?}", f()) +} diff --git a/src/tools/rustfmt/tests/source/issue-1468.rs b/src/tools/rustfmt/tests/source/issue-1468.rs new file mode 100644 index 000000000..4d0d4f0eb --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1468.rs @@ -0,0 +1,27 @@ +fn issue1468() { +euc_jp_decoder_functions!({ +let trail_minus_offset = byte.wrapping_sub(0xA1); +// Fast-track Hiragana (60% according to Lunde) +// and Katakana (10% according to Lunde). +if jis0208_lead_minus_offset == 0x03 && +trail_minus_offset < 0x53 { +// Hiragana +handle.write_upper_bmp(0x3041 + trail_minus_offset as u16) +} else if jis0208_lead_minus_offset == 0x04 && +trail_minus_offset < 0x56 { +// Katakana +handle.write_upper_bmp(0x30A1 + trail_minus_offset as u16) +} else if trail_minus_offset > (0xFE - 0xA1) { +if byte < 0x80 { +return (DecoderResult::Malformed(1, 0), +unread_handle_trail.unread(), +handle.written()); +} +return (DecoderResult::Malformed(2, 0), +unread_handle_trail.consumed(), +handle.written()); +} else { +unreachable!(); +} +}); +} diff --git a/src/tools/rustfmt/tests/source/issue-1693.rs b/src/tools/rustfmt/tests/source/issue-1693.rs new file mode 100644 index 000000000..0622ce502 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1693.rs @@ -0,0 +1,3 @@ +fn issue1693() { + let pixel_data = vec![(f16::from_f32(0.82), f16::from_f32(1.78), f16::from_f32(0.21)); 256 * 256]; +} diff --git a/src/tools/rustfmt/tests/source/issue-1800.rs b/src/tools/rustfmt/tests/source/issue-1800.rs new file mode 100644 index 000000000..eae226532 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1800.rs @@ -0,0 +1,3 @@ +#![doc(html_root_url = "http://example.com")] +#[cfg(feature = "foo")] +fn a() {} diff --git a/src/tools/rustfmt/tests/source/issue-1914.rs b/src/tools/rustfmt/tests/source/issue-1914.rs new file mode 100644 index 000000000..447296c4b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-1914.rs @@ -0,0 +1,6 @@ +// rustfmt-max_width: 80 + +extern "C" { +#[link_name = "_ZN7MyClass26example_check_no_collisionE"] + pub static mut MyClass_example_check_no_collision : * const :: std :: os :: raw :: c_int ; +} diff --git a/src/tools/rustfmt/tests/source/issue-2025.rs b/src/tools/rustfmt/tests/source/issue-2025.rs new file mode 100644 index 000000000..c6f61b4e3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2025.rs @@ -0,0 +1,8 @@ + + + + +// See if rustfmt removes empty lines on top of the file. +pub fn foo() { + println!("hello, world"); +} diff --git a/src/tools/rustfmt/tests/source/issue-2111.rs b/src/tools/rustfmt/tests/source/issue-2111.rs new file mode 100644 index 000000000..ccd113696 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2111.rs @@ -0,0 +1,26 @@ +// An import with single line comments. +use super::{ + SCHEMA_VERSIONS, + LodaModel, + ModelProperties, + StringMap, + ModelSelector, + RequestDescription, + MethodDescription, + ModelBehaviour, + ModelRequestGraph, + DelayChoice, + Holding, + Destinations, + ModelEdges, + Switch, + // ModelMetaData, + // Generated, + // SecondsString, + // DateString, + // ModelConfiguration, + // ModelRequests, + // RestResponse, + // RestResponseCode, + // UniformHolding +}; diff --git a/src/tools/rustfmt/tests/source/issue-2164.rs b/src/tools/rustfmt/tests/source/issue-2164.rs new file mode 100644 index 000000000..6c288e1bd --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2164.rs @@ -0,0 +1,4 @@ +// A stress test against code generated by bindgen. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct emacs_env_25 { pub size : isize , pub private_members : * mut emacs_env_private , pub make_global_ref : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , any_reference : emacs_value ) -> emacs_value > , pub free_global_ref : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , global_reference : emacs_value ) > , pub non_local_exit_check : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env ) -> emacs_funcall_exit > , pub non_local_exit_clear : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env ) > , pub non_local_exit_get : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , non_local_exit_symbol_out : * mut emacs_value , non_local_exit_data_out : * mut emacs_value ) -> emacs_funcall_exit > , pub non_local_exit_signal : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , non_local_exit_symbol : emacs_value , non_local_exit_data : emacs_value ) > , pub non_local_exit_throw : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , tag : emacs_value , value : emacs_value ) > , pub make_function : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , min_arity : isize , max_arity : isize , function : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , nargs : isize , args : * mut emacs_value , arg1 : * mut ::libc :: c_void ) -> emacs_value > , documentation : * const ::libc :: c_char , data : * mut ::libc :: c_void ) -> emacs_value > , pub funcall : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , function : emacs_value , nargs : isize , args : * mut emacs_value ) -> emacs_value > , pub intern : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , symbol_name : * const ::libc :: c_char ) -> emacs_value > , pub type_of : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , value : emacs_value ) -> emacs_value > , pub is_not_nil : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , value : emacs_value ) -> bool > , pub eq : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , a : emacs_value , b : emacs_value ) -> bool > , pub extract_integer : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , value : emacs_value ) -> intmax_t > , pub make_integer : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , value : intmax_t ) -> emacs_value > , pub extract_float : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , value : emacs_value ) -> f64 > , pub make_float : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , value : f64 ) -> emacs_value > , pub copy_string_contents : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , value : emacs_value , buffer : * mut ::libc :: c_char , size_inout : * mut isize ) -> bool > , pub make_string : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , contents : * const ::libc :: c_char , length : isize ) -> emacs_value > , pub make_user_ptr : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , fin : :: std :: option :: Option < unsafe extern "C" fn ( arg1 : * mut ::libc :: c_void ) > , ptr : * mut ::libc :: c_void ) -> emacs_value > , pub get_user_ptr : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , uptr : emacs_value ) -> * mut ::libc :: c_void > , pub set_user_ptr : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , uptr : emacs_value , ptr : * mut ::libc :: c_void ) > , pub get_user_finalizer : :: std :: option :: Option < unsafe extern "C" fn ( arg1 : * mut ::libc :: c_void , env : * mut emacs_env , uptr : emacs_value ) -> :: std :: option :: Option < unsafe extern "C" fn ( arg1 : * mut ::libc :: c_void , env : * mut emacs_env , uptr : emacs_value ) > > , pub set_user_finalizer : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , uptr : emacs_value , fin : :: std :: option :: Option < unsafe extern "C" fn ( arg1 : * mut ::libc :: c_void ) > ) > , pub vec_get : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , vec : emacs_value , i : isize ) -> emacs_value > , pub vec_set : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , vec : emacs_value , i : isize , val : emacs_value ) > , pub vec_size : :: std :: option :: Option < unsafe extern "C" fn ( env : * mut emacs_env , vec : emacs_value ) -> isize > , } diff --git a/src/tools/rustfmt/tests/source/issue-2179/one.rs b/src/tools/rustfmt/tests/source/issue-2179/one.rs new file mode 100644 index 000000000..d23947931 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2179/one.rs @@ -0,0 +1,36 @@ +// rustfmt-version: One +// rustfmt-error_on_line_overflow: false + +fn issue_2179() { + let (opts, rustflags, clear_env_rust_log) = + { + // We mustn't lock configuration for the whole build process + let rls_config = rls_config.lock().unwrap(); + + let opts = CargoOptions::new(&rls_config); + trace!("Cargo compilation options:\n{:?}", opts); + let rustflags = prepare_cargo_rustflags(&rls_config); + + // Warn about invalid specified bin target or package depending on current mode + // TODO: Return client notifications along with diagnostics to inform the user + if !rls_config.workspace_mode { + let cur_pkg_targets = ws.current().unwrap().targets(); + + if let &Some(ref build_bin) = rls_config.build_bin.as_ref() { + let mut bins = cur_pkg_targets.iter().filter(|x| x.is_bin()); + if let None = bins.find(|x| x.name() == build_bin) { + warn!("cargo - couldn't find binary `{}` specified in `build_bin` configuration", build_bin); + } + } + } else { + for package in &opts.package { + if let None = ws.members().find(|x| x.name() == package) { + warn!("cargo - couldn't find member package `{}` specified in `analyze_package` configuration", package); + } + } + } + + (opts, rustflags, rls_config.clear_env_rust_log) + }; + +} diff --git a/src/tools/rustfmt/tests/source/issue-2179/two.rs b/src/tools/rustfmt/tests/source/issue-2179/two.rs new file mode 100644 index 000000000..f4cc9cc48 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2179/two.rs @@ -0,0 +1,36 @@ +// rustfmt-version: Two +// rustfmt-error_on_line_overflow: false + +fn issue_2179() { + let (opts, rustflags, clear_env_rust_log) = + { + // We mustn't lock configuration for the whole build process + let rls_config = rls_config.lock().unwrap(); + + let opts = CargoOptions::new(&rls_config); + trace!("Cargo compilation options:\n{:?}", opts); + let rustflags = prepare_cargo_rustflags(&rls_config); + + // Warn about invalid specified bin target or package depending on current mode + // TODO: Return client notifications along with diagnostics to inform the user + if !rls_config.workspace_mode { + let cur_pkg_targets = ws.current().unwrap().targets(); + + if let &Some(ref build_bin) = rls_config.build_bin.as_ref() { + let mut bins = cur_pkg_targets.iter().filter(|x| x.is_bin()); + if let None = bins.find(|x| x.name() == build_bin) { + warn!("cargo - couldn't find binary `{}` specified in `build_bin` configuration", build_bin); + } + } + } else { + for package in &opts.package { + if let None = ws.members().find(|x| x.name() == package) { + warn!("cargo - couldn't find member package `{}` specified in `analyze_package` configuration", package); + } + } + } + + (opts, rustflags, rls_config.clear_env_rust_log) + }; + +} diff --git a/src/tools/rustfmt/tests/source/issue-2256.rs b/src/tools/rustfmt/tests/source/issue-2256.rs new file mode 100644 index 000000000..a206e8db6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2256.rs @@ -0,0 +1,12 @@ +// こんにちは +use std::{}; +use std::borrow::Cow; + +/* comment 1 */ use std::{}; +/* comment 2 */ use std::{}; + + + + + +/* comment 3 */ use std::{}; diff --git a/src/tools/rustfmt/tests/source/issue-2342.rs b/src/tools/rustfmt/tests/source/issue-2342.rs new file mode 100644 index 000000000..f86d24a14 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2342.rs @@ -0,0 +1,5 @@ +// rustfmt-max_width: 80 + +struct Foo { + #[cfg(feature = "serde")] bytes: [[u8; 17]; 5], // Same size as signature::ED25519_PKCS8_V2_LEN +} diff --git a/src/tools/rustfmt/tests/source/issue-2445.rs b/src/tools/rustfmt/tests/source/issue-2445.rs new file mode 100644 index 000000000..84ce6e647 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2445.rs @@ -0,0 +1,21 @@ +test!(RunPassPretty { + // comment + path: "src/test/run-pass/pretty", + mode: "pretty", + suite: "run-pass", + default: false, + host: true // should, force, , no trailing comma here +}); + +test!(RunPassPretty { + // comment + path: "src/test/run-pass/pretty", + mode: "pretty", + suite: "run-pass", + default: false, + host: true, // should, , preserve, the trailing comma +}); + +test!(Test{ + field: i32, // comment +}); diff --git a/src/tools/rustfmt/tests/source/issue-2446.rs b/src/tools/rustfmt/tests/source/issue-2446.rs new file mode 100644 index 000000000..ad649d95c --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2446.rs @@ -0,0 +1,11 @@ +enum Issue2446 { + V { + f: u8, // x + }, +} + +enum Issue2446TrailingCommentsOnly { + V { + f: u8, /* */ + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2479.rs b/src/tools/rustfmt/tests/source/issue-2479.rs new file mode 100644 index 000000000..df50236d0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2479.rs @@ -0,0 +1,2 @@ +// Long attributes. +# [ derive ( Clone , Copy , Debug , PartialEq ) ] pub enum POLARITYR { # [ doc = "Task mode: No effect on pin from OUT[n] task. Event mode: no IN[n] event generated on pin activity." ] NONE , # [ doc = "Task mode: Set pin from OUT[n] task. Event mode: Generate IN[n] event when rising edge on pin." ] LOTOHI , # [ doc = "Task mode: Clear pin from OUT[n] task. Event mode: Generate IN[n] event when falling edge on pin." ] HITOLO , # [ doc = "Task mode: Toggle pin from OUT[n]. Event mode: Generate IN[n] when any change on pin." ] TOGGLE } diff --git a/src/tools/rustfmt/tests/source/issue-2482/a.rs b/src/tools/rustfmt/tests/source/issue-2482/a.rs new file mode 100644 index 000000000..fbbcb52a8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2482/a.rs @@ -0,0 +1,9 @@ +// rustfmt-reorder_modules: true + +// Do not reorder inline modules. + +mod c; +mod a { + fn a() {} +} +mod b; diff --git a/src/tools/rustfmt/tests/source/issue-2482/b.rs b/src/tools/rustfmt/tests/source/issue-2482/b.rs new file mode 100644 index 000000000..40a8d9421 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2482/b.rs @@ -0,0 +1 @@ +pub fn b() {} diff --git a/src/tools/rustfmt/tests/source/issue-2482/c.rs b/src/tools/rustfmt/tests/source/issue-2482/c.rs new file mode 100644 index 000000000..d93754551 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2482/c.rs @@ -0,0 +1 @@ +pub fn c() {} diff --git a/src/tools/rustfmt/tests/source/issue-2496.rs b/src/tools/rustfmt/tests/source/issue-2496.rs new file mode 100644 index 000000000..0ebd4b510 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2496.rs @@ -0,0 +1,16 @@ +// rustfmt-indent_style: Visual +fn main() { + match option { + None => some_function(first_reasonably_long_argument, + second_reasonably_long_argument), + } +} + +fn main() { + match option { + None => { + some_function(first_reasonably_long_argument, + second_reasonably_long_argument) + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2520.rs b/src/tools/rustfmt/tests/source/issue-2520.rs new file mode 100644 index 000000000..5a23f1043 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2520.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_comments: true +// rustfmt-format_code_in_doc_comments: true + +//! ```rust +//! println!( "hello, world" ); +//! ``` + +#![deny( missing_docs )] + +//! ```rust +//! println!("hello, world"); + +#![deny( missing_docs )] diff --git a/src/tools/rustfmt/tests/source/issue-2523.rs b/src/tools/rustfmt/tests/source/issue-2523.rs new file mode 100644 index 000000000..491d5c38f --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2523.rs @@ -0,0 +1,18 @@ +// rustfmt-normalize_comments: true +// rustfmt-format_code_in_doc_comments: true + +// Do not unindent macro calls in comment with unformattable syntax. +//! ```rust +//! let x = 3 ; +//! some_macro!(pub fn fn foo() ( +//! println!("Don't unindent me!"); +//! )); +//! ``` + +// Format items that appear as arguments of macro call. +//! ```rust +//! let x = 3 ; +//! some_macro!(pub fn foo() { +//! println!("Don't unindent me!"); +//! }); +//! ``` diff --git a/src/tools/rustfmt/tests/source/issue-2582.rs b/src/tools/rustfmt/tests/source/issue-2582.rs new file mode 100644 index 000000000..bba8ce150 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2582.rs @@ -0,0 +1 @@ + fn main() {} diff --git a/src/tools/rustfmt/tests/source/issue-2641.rs b/src/tools/rustfmt/tests/source/issue-2641.rs new file mode 100644 index 000000000..c7ad60674 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2641.rs @@ -0,0 +1,3 @@ +macro_rules! a { + () => {{}} +} diff --git a/src/tools/rustfmt/tests/source/issue-2644.rs b/src/tools/rustfmt/tests/source/issue-2644.rs new file mode 100644 index 000000000..fa9d16f44 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2644.rs @@ -0,0 +1,11 @@ +// rustfmt-max_width: 80 +fn foo(e: Enum) { + match e { + Enum::Var { + element1, + element2, + } => { + return; + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2728.rs b/src/tools/rustfmt/tests/source/issue-2728.rs new file mode 100644 index 000000000..6cb41b75b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2728.rs @@ -0,0 +1,8 @@ +// rustfmt-wrap_comments: true +// rustfmt-newline_style: Windows + +//! ```rust +//! extern crate uom; +//! ``` + +fn main() {} diff --git a/src/tools/rustfmt/tests/source/issue-2761.rs b/src/tools/rustfmt/tests/source/issue-2761.rs new file mode 100644 index 000000000..bc3123190 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2761.rs @@ -0,0 +1,15 @@ +const DATA: &'static [u8] = &[ + 0x42, 0x50, 0x54, 0x44, //type + 0x23, 0x00, 0x00, 0x00, //size + 0x00, 0x00, 0x04, 0x00, //flags + 0xEC, 0x0C, 0x00, 0x00, //id + 0x00, 0x00, 0x00, 0x00, //revision + 0x2B, 0x00, //version + 0x00, 0x00, //unknown + 0x42, 0x50, 0x54, 0x4E, //field type + 0x1D, 0x00, //field size + 0x19, 0x00, 0x00, 0x00, //decompressed field size + 0x75, 0xc5, 0x21, 0x0d, 0x00, 0x00, 0x08, 0x05, 0xd1, 0x6c, //field data (compressed) + 0x6c, 0xdc, 0x57, 0x48, 0x3c, 0xfd, 0x5b, 0x5c, 0x02, 0xd4, //field data (compressed) + 0x6b, 0x32, 0xb5, 0xdc, 0xa3 //field data (compressed) +]; diff --git a/src/tools/rustfmt/tests/source/issue-2781.rs b/src/tools/rustfmt/tests/source/issue-2781.rs new file mode 100644 index 000000000..2c15b29b6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2781.rs @@ -0,0 +1,11 @@ +pub // Oh, no. A line comment. +struct Foo {} + +pub /* Oh, no. A block comment. */ struct Foo {} + +mod inner { +pub // Oh, no. A line comment. +struct Foo {} + +pub /* Oh, no. A block comment. */ struct Foo {} +} diff --git a/src/tools/rustfmt/tests/source/issue-2794.rs b/src/tools/rustfmt/tests/source/issue-2794.rs new file mode 100644 index 000000000..c3f9c0412 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2794.rs @@ -0,0 +1,7 @@ +// rustfmt-indent_style: Block +// rustfmt-imports_indent: Block +// rustfmt-imports_layout: Vertical + +use std::{ + env, fs, io::{Read, Write}, +}; diff --git a/src/tools/rustfmt/tests/source/issue-2835.rs b/src/tools/rustfmt/tests/source/issue-2835.rs new file mode 100644 index 000000000..2219b0b38 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2835.rs @@ -0,0 +1,7 @@ +// rustfmt-brace_style: AlwaysNextLine +// rustfmt-fn_single_line: true + +fn lorem() -> i32 +{ + 42 +} diff --git a/src/tools/rustfmt/tests/source/issue-2863.rs b/src/tools/rustfmt/tests/source/issue-2863.rs new file mode 100644 index 000000000..1bda857be --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2863.rs @@ -0,0 +1,25 @@ +// rustfmt-reorder_impl_items: true + +impl<T> IntoIterator for SafeVec<T> { + type F = impl Trait; + type IntoIter = self::IntoIter<T>; + type Item = T; + // comment on foo() + fn foo() {println!("hello, world");} + type Bar = u32; + fn foo1() {println!("hello, world");} + type FooBar = u32; + fn foo2() {println!("hello, world");} + fn foo3() {println!("hello, world");} + const SomeConst: i32 = 100; + fn foo4() {println!("hello, world");} + fn foo5() {println!("hello, world");} + // comment on FoooooBar + type FoooooBar = u32; + fn foo6() {println!("hello, world");} + fn foo7() {println!("hello, world");} + type BarFoo = u32; + type E = impl Trait; + const AnotherConst: i32 = 100; + fn foo8() {println!("hello, world");} +} diff --git a/src/tools/rustfmt/tests/source/issue-2869.rs b/src/tools/rustfmt/tests/source/issue-2869.rs new file mode 100644 index 000000000..d18adfb46 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2869.rs @@ -0,0 +1,41 @@ +// rustfmt-struct_field_align_threshold: 50 + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "PascalCase")] +struct AuditLog1 { + creation_time: String, + id: String, + operation: String, + organization_id: String, + record_type: u32, + result_status: Option<String>, + #[serde(rename = "ClientIP")] + client_ip: Option<IpAddr>, + object_id: String, + actor: Option<Vec<IDType>>, + actor_context_id: Option<String>, + actor_ip_address: Option<IpAddr>, + azure_active_directory_event_type: Option<u8>, + + #[serde(rename = "very")] + aaaaa: String, + #[serde(rename = "cool")] + bb: i32, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "PascalCase")] +struct AuditLog2 { + creation_time: String, + id: String, + operation: String, + organization_id: String, + record_type: u32, + result_status: Option<String>, + client_ip: Option<IpAddr>, + object_id: String, + actor: Option<Vec<IDType>>, + actor_context_id: Option<String>, + actor_ip_address: Option<IpAddr>, + azure_active_directory_event_type: Option<u8>, +} diff --git a/src/tools/rustfmt/tests/source/issue-2896.rs b/src/tools/rustfmt/tests/source/issue-2896.rs new file mode 100644 index 000000000..f648e64b1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2896.rs @@ -0,0 +1,161 @@ +extern crate rand; +extern crate timely; +extern crate differential_dataflow; + +use rand::{Rng, SeedableRng, StdRng}; + +use timely::dataflow::operators::*; + +use differential_dataflow::AsCollection; +use differential_dataflow::operators::*; +use differential_dataflow::input::InputSession; + +// mod loglikelihoodratio; + +fn main() { + + // define a new timely dataflow computation. + timely::execute_from_args(std::env::args().skip(6), move |worker| { + + // capture parameters of the experiment. + let users: usize = std::env::args().nth(1).unwrap().parse().unwrap(); + let items: usize = std::env::args().nth(2).unwrap().parse().unwrap(); + let scale: usize = std::env::args().nth(3).unwrap().parse().unwrap(); + let batch: usize = std::env::args().nth(4).unwrap().parse().unwrap(); + let noisy: bool = std::env::args().nth(5).unwrap() == "noisy"; + + let index = worker.index(); + let peers = worker.peers(); + + let (input, probe) = worker.dataflow(|scope| { + + // input of (user, item) collection. + let (input, occurrences) = scope.new_input(); + let occurrences = occurrences.as_collection(); + + //TODO adjust code to only work with upper triangular half of cooccurrence matrix + + /* Compute the cooccurrence matrix C = A'A from the binary interaction matrix A. */ + let cooccurrences = + occurrences + .join_map(&occurrences, |_user, &item_a, &item_b| (item_a, item_b)) + .filter(|&(item_a, item_b)| item_a != item_b) + .count(); + + /* compute the rowsums of C indicating how often we encounter individual items. */ + let row_sums = + occurrences + .map(|(_user, item)| item) + .count(); + + // row_sums.inspect(|record| println!("[row_sums] {:?}", record)); + + /* Join the cooccurrence pairs with the corresponding row sums. */ + let mut cooccurrences_with_row_sums = cooccurrences + .map(|((item_a, item_b), num_cooccurrences)| (item_a, (item_b, num_cooccurrences))) + .join_map(&row_sums, |&item_a, &(item_b, num_cooccurrences), &row_sum_a| { + assert!(row_sum_a > 0); + (item_b, (item_a, num_cooccurrences, row_sum_a)) + }) + .join_map(&row_sums, |&item_b, &(item_a, num_cooccurrences, row_sum_a), &row_sum_b| { + assert!(row_sum_a > 0); + assert!(row_sum_b > 0); + (item_a, (item_b, num_cooccurrences, row_sum_a, row_sum_b)) + }); + + // cooccurrences_with_row_sums + // .inspect(|record| println!("[cooccurrences_with_row_sums] {:?}", record)); + + // //TODO compute top-k "similar items" per item + // /* Compute LLR scores for each item pair. */ + // let llr_scores = cooccurrences_with_row_sums.map( + // |(item_a, (item_b, num_cooccurrences, row_sum_a, row_sum_b))| { + + // println!( + // "[llr_scores] item_a={} item_b={}, num_cooccurrences={} row_sum_a={} row_sum_b={}", + // item_a, item_b, num_cooccurrences, row_sum_a, row_sum_b); + + // let k11: isize = num_cooccurrences; + // let k12: isize = row_sum_a as isize - k11; + // let k21: isize = row_sum_b as isize - k11; + // let k22: isize = 10000 - k12 - k21 + k11; + + // let llr_score = loglikelihoodratio::log_likelihood_ratio(k11, k12, k21, k22); + + // ((item_a, item_b), llr_score) + // }); + + if noisy { + cooccurrences_with_row_sums = + cooccurrences_with_row_sums + .inspect(|x| println!("change: {:?}", x)); + } + + let probe = + cooccurrences_with_row_sums + .probe(); +/* + // produce the (item, item) collection + let cooccurrences = occurrences + .join_map(&occurrences, |_user, &item_a, &item_b| (item_a, item_b)); + // count the occurrences of each item. + let counts = cooccurrences + .map(|(item_a,_)| item_a) + .count(); + // produce ((item1, item2), count1, count2, count12) tuples + let cooccurrences_with_counts = cooccurrences + .join_map(&counts, |&item_a, &item_b, &count_item_a| (item_b, (item_a, count_item_a))) + .join_map(&counts, |&item_b, &(item_a, count_item_a), &count_item_b| { + ((item_a, item_b), count_item_a, count_item_b) + }); + let probe = cooccurrences_with_counts + .inspect(|x| println!("change: {:?}", x)) + .probe(); +*/ + (input, probe) + }); + + let seed: &[_] = &[1, 2, 3, index]; + let mut rng1: StdRng = SeedableRng::from_seed(seed); // rng for edge additions + let mut rng2: StdRng = SeedableRng::from_seed(seed); // rng for edge deletions + + let mut input = InputSession::from(input); + + for count in 0 .. scale { + if count % peers == index { + let user = rng1.gen_range(0, users); + let item = rng1.gen_range(0, items); + // println!("[INITIAL INPUT] ({}, {})", user, item); + input.insert((user, item)); + } + } + + // load the initial data up! + while probe.less_than(input.time()) { worker.step(); } + + for round in 1 .. { + + for element in (round * batch) .. ((round + 1) * batch) { + if element % peers == index { + // advance the input timestamp. + input.advance_to(round * batch); + // insert a new item. + let user = rng1.gen_range(0, users); + let item = rng1.gen_range(0, items); + if noisy { println!("[INPUT: insert] ({}, {})", user, item); } + input.insert((user, item)); + // remove an old item. + let user = rng2.gen_range(0, users); + let item = rng2.gen_range(0, items); + if noisy { println!("[INPUT: remove] ({}, {})", user, item); } + input.remove((user, item)); + } + } + + input.advance_to(round * batch); + input.flush(); + + while probe.less_than(input.time()) { worker.step(); } + } + }).unwrap(); +} diff --git a/src/tools/rustfmt/tests/source/issue-2916.rs b/src/tools/rustfmt/tests/source/issue-2916.rs new file mode 100644 index 000000000..ccb1f8486 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2916.rs @@ -0,0 +1,2 @@ +a_macro!(name<Param1, Param2>, +) ; diff --git a/src/tools/rustfmt/tests/source/issue-2917/packed_simd.rs b/src/tools/rustfmt/tests/source/issue-2917/packed_simd.rs new file mode 100644 index 000000000..afa9e67c8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2917/packed_simd.rs @@ -0,0 +1,63 @@ +// rustfmt-wrap_comments: true +//! Implements `From` and `Into` for vector types. + +macro_rules! impl_from_vector { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | $source:ident) => { + impl From<$source> for $id { + #[inline] + fn from(source: $source) -> Self { + fn static_assert_same_number_of_lanes<T, U>() + where + T: crate::sealed::Simd, + U: crate::sealed::Simd<LanesType = T::LanesType>, + { + } + use llvm::simd_cast; + static_assert_same_number_of_lanes::<$id, $source>(); + Simd(unsafe { simd_cast(source.0) }) + } + } + + // FIXME: `Into::into` is not inline, but due to + // the blanket impl in `std`, which is not + // marked `default`, we cannot override it here with + // specialization. + /* + impl Into<$id> for $source { + #[inline] + fn into(self) -> $id { + unsafe { simd_cast(self) } + } + } + */ + + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _from_ $source] { + use super::*; + #[test] + fn from() { + assert_eq!($id::lanes(), $source::lanes()); + let source: $source = Default::default(); + let vec: $id = Default::default(); + + let e = $id::from(source); + assert_eq!(e, vec); + + let e: $id = source.into(); + assert_eq!(e, vec); + } + } + } + } + }; +} + +macro_rules! impl_from_vectors { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | $($source:ident),*) => { + $( + impl_from_vector!([$elem_ty; $elem_count]: $id | $test_tt | $source); + )* + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2922.rs b/src/tools/rustfmt/tests/source/issue-2922.rs new file mode 100644 index 000000000..44fae0b64 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2922.rs @@ -0,0 +1,9 @@ +// rustfmt-indent_style: Visual +struct Functions { + RunListenServer: unsafe extern "C" fn(*mut c_void, + *mut c_char, + *mut c_char, + *mut c_char, + *mut c_void, + *mut c_void) -> c_int, +} diff --git a/src/tools/rustfmt/tests/source/issue-2927-2.rs b/src/tools/rustfmt/tests/source/issue-2927-2.rs new file mode 100644 index 000000000..d87761fdc --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2927-2.rs @@ -0,0 +1,7 @@ +// rustfmt-edition: 2015 +#![feature(rust_2018_preview, uniform_paths)] +use futures::prelude::*; +use http_03::cli::Cli; +use hyper::{service::service_fn_ok, Body, Response, Server}; +use ::log::{error, info, log}; +use structopt::StructOpt; diff --git a/src/tools/rustfmt/tests/source/issue-2927.rs b/src/tools/rustfmt/tests/source/issue-2927.rs new file mode 100644 index 000000000..a7df32084 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2927.rs @@ -0,0 +1,7 @@ +// rustfmt-edition: 2018 +#![feature(rust_2018_preview, uniform_paths)] +use futures::prelude::*; +use http_03::cli::Cli; +use hyper::{service::service_fn_ok, Body, Response, Server}; +use ::log::{error, info, log}; +use structopt::StructOpt; diff --git a/src/tools/rustfmt/tests/source/issue-2930.rs b/src/tools/rustfmt/tests/source/issue-2930.rs new file mode 100644 index 000000000..962c3e4fe --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2930.rs @@ -0,0 +1,5 @@ +// rustfmt-indent_style: Visual +fn main() { + let (first_variable, second_variable) = (this_is_something_with_an_extraordinarily_long_name, + this_variable_name_is_also_pretty_long); +} diff --git a/src/tools/rustfmt/tests/source/issue-2936.rs b/src/tools/rustfmt/tests/source/issue-2936.rs new file mode 100644 index 000000000..55b5c56e6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2936.rs @@ -0,0 +1,19 @@ +struct AStruct { + A: u32, + B: u32, + C: u32, +} + +impl Something for AStruct { + fn a_func() { + match a_val { + ContextualParseError::InvalidMediaRule(ref err) => { + let err: &CStr = match err.kind { + ParseErrorKind::Custom(StyleParseErrorKind::MediaQueryExpectedFeatureName(..)) => { + cstr!("PEMQExpectedFeatureName") + }, + }; + } + }; + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2955.rs b/src/tools/rustfmt/tests/source/issue-2955.rs new file mode 100644 index 000000000..525e070a5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2955.rs @@ -0,0 +1,6 @@ +// rustfmt-condense_wildcard_suffixes: true +fn main() { + match (1, 2, 3) { + (_, _, _) => (), + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2973.rs b/src/tools/rustfmt/tests/source/issue-2973.rs new file mode 100644 index 000000000..5256dd7c9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2973.rs @@ -0,0 +1,158 @@ +#[cfg(test)] +mod test { + summary_test! { + tokenize_recipe_interpolation_eol, + "foo: # some comment + {{hello}} +", + "foo: \ + {{hello}} \ +{{ahah}}", + "N:#$>^{N}$<.", + } + + summary_test! { + tokenize_strings, + r#"a = "'a'" + '"b"' + "'c'" + '"d"'#echo hello"#, + r#"N="+'+"+'#."#, + } + + summary_test! { + tokenize_recipe_interpolation_eol, + "foo: # some comment + {{hello}} +", + "N:#$>^{N}$<.", + } + + summary_test! { + tokenize_recipe_interpolation_eof, + "foo: # more comments + {{hello}} +# another comment +", + "N:#$>^{N}$<#$.", + } + + summary_test! { + tokenize_recipe_complex_interpolation_expression, + "foo: #lol\n {{a + b + \"z\" + blarg}}", + "N:#$>^{N+N+\"+N}<.", + } + + summary_test! { + tokenize_recipe_multiple_interpolations, + "foo:,#ok\n {{a}}0{{b}}1{{c}}", + "N:,#$>^{N}_{N}_{N}<.", + } + + summary_test! { + tokenize_junk, + "bob + +hello blah blah blah : a b c #whatever + ", + "N$$NNNN:NNN#$.", + } + + summary_test! { + tokenize_empty_lines, + " +# this does something +hello: + asdf + bsdf + + csdf + + dsdf # whatever + +# yolo + ", + "$#$N:$>^_$^_$$^_$$^_$$<#$.", + } + + summary_test! { + tokenize_comment_before_variable, + " +# +A='1' +echo: + echo {{A}} + ", + "$#$N='$N:$>^_{N}$<.", + } + + summary_test! { + tokenize_interpolation_backticks, + "hello:\n echo {{`echo hello` + `echo goodbye`}}", + "N:$>^_{`+`}<.", + } + + summary_test! { + tokenize_assignment_backticks, + "a = `echo hello` + `echo goodbye`", + "N=`+`.", + } + + summary_test! { + tokenize_multiple, + " +hello: + a + b + + c + + d + +# hello +bob: + frank + ", + + "$N:$>^_$^_$$^_$$^_$$<#$N:$>^_$<.", + } + + summary_test! { + tokenize_comment, + "a:=#", + "N:=#." + } + + summary_test! { + tokenize_comment_with_bang, + "a:=#foo!", + "N:=#." + } + + summary_test! { + tokenize_order, + r" +b: a + @mv a b + +a: + @touch F + @touch a + +d: c + @rm c + +c: b + @mv b c", + "$N:N$>^_$$<N:$>^_$^_$$<N:N$>^_$$<N:N$>^_<.", + } + + summary_test! { + tokenize_parens, + r"((())) )abc(+", + "((())))N(+.", + } + + summary_test! { + crlf_newline, + "#\r\n#asdf\r\n", + "#$#$.", + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2977/impl.rs b/src/tools/rustfmt/tests/source/issue-2977/impl.rs new file mode 100644 index 000000000..8d7bb9414 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2977/impl.rs @@ -0,0 +1,44 @@ +macro_rules! atomic_bits { + // the println macro cannot be rewritten because of the asm macro + ($type:ty, $ldrex:expr, $strex:expr) => { + impl AtomicBits for $type { + unsafe fn load_excl(address: usize) -> Self { + let raw: $type; + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + raw + } + + unsafe fn store_excl(self, address: usize) -> bool { + let status: $type; + println!("{}", + status); + status == 0 + } + } + }; + + // the println macro should be rewritten here + ($type:ty) => { + fn some_func(self) { + let status: $type; + println!("{}", status); + } + }; + + // unrewritale macro in func + ($type:ty, $ldrex:expr) => { + unsafe fn load_excl(address: usize) -> Self { + let raw: $type; + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + raw + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2977/trait.rs b/src/tools/rustfmt/tests/source/issue-2977/trait.rs new file mode 100644 index 000000000..ae20668cd --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2977/trait.rs @@ -0,0 +1,44 @@ +macro_rules! atomic_bits { + // the println macro cannot be rewritten because of the asm macro + ($type:ty, $ldrex:expr, $strex:expr) => { + trait $type { + unsafe fn load_excl(address: usize) -> Self { + let raw: $type; + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + raw + } + + unsafe fn store_excl(self, address: usize) -> bool { + let status: $type; + println!("{}", + status); + status == 0 + } + } + }; + + // the println macro should be rewritten here + ($type:ty) => { + fn some_func(self) { + let status: $type; + println!("{}", status); + } + }; + + // unrewritale macro in func + ($type:ty, $ldrex:expr) => { + unsafe fn load_excl(address: usize) -> Self { + let raw: $type; + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + raw + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2985.rs b/src/tools/rustfmt/tests/source/issue-2985.rs new file mode 100644 index 000000000..bde4da831 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2985.rs @@ -0,0 +1,35 @@ +// rustfmt-indent_style: Visual +fn foo() { + { + { + let extra_encoder_settings = extra_encoder_settings.iter() + .filter_map(|&(name, value)| { + value.split() + .next() + .something() + .something2() + .something3() + .something4() + }); + let extra_encoder_settings = extra_encoder_settings.iter() + .filter_map(|&(name, value)| { + value.split() + .next() + .something() + .something2() + .something3() + .something4() + }) + .something(); + if let Some(subpod) = pod.subpods.iter().find(|s| { + !s.plaintext + .as_ref() + .map(String::as_ref) + .unwrap_or("") + .is_empty() + }) { + do_something(); + } + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-2995.rs b/src/tools/rustfmt/tests/source/issue-2995.rs new file mode 100644 index 000000000..accf7c3a1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-2995.rs @@ -0,0 +1,7 @@ +fn issue_2995() { + // '\u{2028}' is inserted in the code below. + + [0,
1]; + [0,
/* */ 1]; +
[
0
,
1
]
; +} diff --git a/src/tools/rustfmt/tests/source/issue-3029.rs b/src/tools/rustfmt/tests/source/issue-3029.rs new file mode 100644 index 000000000..a7ac5c32b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3029.rs @@ -0,0 +1,94 @@ +fn keep_if() { + { + { + { + EvaluateJSReply::NumberValue( + if FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_if_let() { + { + { + { + EvaluateJSReply::NumberValue( + if let Some(e) = FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_for() { + { + { + { + EvaluateJSReply::NumberValue( + for conv in FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_loop() { + { + { + { + EvaluateJSReply::NumberValue(loop { + FromJSValConvertible::from_jsval(cx, rval.handle(), ()); + }) + } + } + } +} + +fn keep_while() { + { + { + { + EvaluateJSReply::NumberValue( + while FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_while_let() { + { + { + { + EvaluateJSReply::NumberValue( + while let Some(e) = FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_match() { + { + { + EvaluateJSReply::NumberValue( + match FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + Ok(ConversionResult::Success(v)) => v, + _ => unreachable!(), + }, + ) + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3038.rs b/src/tools/rustfmt/tests/source/issue-3038.rs new file mode 100644 index 000000000..0fbb05ddc --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3038.rs @@ -0,0 +1,20 @@ +impl HTMLTableElement { + fn func() { + if number_of_row_elements == 0 { + if let Some(last_tbody) = node.rev_children() + .filter_map(DomRoot::downcast::<Element>) + .find(|n| n.is::<HTMLTableSectionElement>() && n.local_name() == &local_name!("tbody")) { + last_tbody.upcast::<Node>().AppendChild(new_row.upcast::<Node>()) + .expect("InsertRow failed to append first row."); + } + } + + if number_of_row_elements == 0 { + if let Some(last_tbody) = node + .find(|n| n.is::<HTMLTableSectionElement>() && n.local_name() == &local_name!("tbody")) { + last_tbody.upcast::<Node>().AppendChild(new_row.upcast::<Node>()) + .expect("InsertRow failed to append first row."); + } + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3049.rs b/src/tools/rustfmt/tests/source/issue-3049.rs new file mode 100644 index 000000000..43742683e --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3049.rs @@ -0,0 +1,45 @@ +// rustfmt-indent_style: Visual +fn main() { + something.aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .bench_function(|| { + let x = hello(); + }); + + something.aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .bench_function(arg, || { + let x = hello(); + }); + + something.aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .bench_function(arg, + || { + let x = hello(); + }, + arg); + + AAAAAAAAAAA.function(|| { + let _ = (); + }); + + AAAAAAAAAAA.chain().function(|| { + let _ = (); + }) +} diff --git a/src/tools/rustfmt/tests/source/issue-3055/original.rs b/src/tools/rustfmt/tests/source/issue-3055/original.rs new file mode 100644 index 000000000..45e58473a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3055/original.rs @@ -0,0 +1,43 @@ +// rustfmt-wrap_comments: true +// rustfmt-format_code_in_doc_comments: true + +/// Vestibulum elit nibh, rhoncus non, euismod sit amet, pretium eu, enim. Nunc commodo ultricies dui. +/// +/// Should not format with text attribute +/// ```text +/// .--------------. +/// | v +/// Park <- Idle -> Poll -> Probe -> Download -> Install -> Reboot +/// ^ ^ ' ' ' +/// ' ' ' ' ' +/// ' `--------' ' ' +/// `---------------' ' ' +/// `--------------------------' ' +/// `-------------------------------------' +/// ``` +/// +/// Should not format with ignore attribute +/// ```text +/// .--------------. +/// | v +/// Park <- Idle -> Poll -> Probe -> Download -> Install -> Reboot +/// ^ ^ ' ' ' +/// ' ' ' ' ' +/// ' `--------' ' ' +/// `---------------' ' ' +/// `--------------------------' ' +/// `-------------------------------------' +/// ``` +/// +/// Should format with rust attribute +/// ```rust +/// let x = +/// 42; +/// ``` +/// +/// Should format with no attribute as it defaults to rust +/// ``` +/// let x = +/// 42; +/// ``` +fn func() {} diff --git a/src/tools/rustfmt/tests/source/issue-3059.rs b/src/tools/rustfmt/tests/source/issue-3059.rs new file mode 100644 index 000000000..49a75cd67 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3059.rs @@ -0,0 +1,7 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 80 + +/// Vestibulum elit nibh, rhoncus non, euismod sit amet, pretium eu, enim. Nunc commodo ultricies dui. +/// Cras gravida rutrum massa. Donec accumsan mattis turpis. Quisque sem. Quisque elementum sapien +/// iaculis augue. In dui sem, congue sit amet, feugiat quis, lobortis at, eros. +fn func4() {} diff --git a/src/tools/rustfmt/tests/source/issue-3066.rs b/src/tools/rustfmt/tests/source/issue-3066.rs new file mode 100644 index 000000000..4d1ece43d --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3066.rs @@ -0,0 +1,7 @@ +// rustfmt-indent_style: Visual +fn main() { + Struct { field: aaaaaaaaaaa }; + Struct { field: aaaaaaaaaaaa, }; + Struct { field: value, + field2: value2, }; +} diff --git a/src/tools/rustfmt/tests/source/issue-3131.rs b/src/tools/rustfmt/tests/source/issue-3131.rs new file mode 100644 index 000000000..c4cb2d8c0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3131.rs @@ -0,0 +1,8 @@ +fn main() { + match 3 { + t if match t { + _ => true, + } => {}, + _ => {} + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3153.rs b/src/tools/rustfmt/tests/source/issue-3153.rs new file mode 100644 index 000000000..2836ce97c --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3153.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: true + +/// This may panic if: +/// - there are fewer than `max_header_bytes` bytes preceding the body +/// - there are fewer than `max_footer_bytes` bytes following the body +/// - the sum of the body bytes and post-body bytes is less than the sum +/// of `min_body_and_padding_bytes` and `max_footer_bytes` (in other +/// words, the minimum body and padding byte requirement is not met) +fn foo() {} diff --git a/src/tools/rustfmt/tests/source/issue-3158.rs b/src/tools/rustfmt/tests/source/issue-3158.rs new file mode 100644 index 000000000..315073db6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3158.rs @@ -0,0 +1,74 @@ +// rustfmt-format_code_in_doc_comments: true + +/// Should format +/// ```rust +/// assert!( false ); +/// ``` +/// +/// Should format +/// ```rust,should_panic +/// assert!( false ); +/// ``` +/// +/// Should format +/// ```rust,should_panic,edition2018 +/// assert!( false ); +/// ``` +/// +/// Should format +/// ```rust , should_panic , edition2018 +/// assert!( false ); +/// ``` +/// +/// Should not format +/// ```ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (not all are rust) +/// ```rust,ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```compile_fail +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```rust,compile_fail +/// assert!( false ); +/// ``` +/// +/// Various unspecified ones that should format +/// ``` +/// assert!( false ); +/// ``` +/// +/// ```, +/// assert!( false ); +/// ``` +/// +/// ```,,,,, +/// assert!( false ); +/// ``` +/// +/// ```,,, rust ,, +/// assert!( false ); +/// ``` +/// +/// Should not format +/// ```,,, rust , ignore, +/// assert!( false ); +/// ``` +/// +/// Few empty ones +/// ``` +/// ``` +/// +/// ```rust +/// ``` +/// +/// ```ignore +/// ``` +fn foo() {} diff --git a/src/tools/rustfmt/tests/source/issue-3194.rs b/src/tools/rustfmt/tests/source/issue-3194.rs new file mode 100644 index 000000000..b80ce346b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3194.rs @@ -0,0 +1,13 @@ +mod m { struct S where A: B; } + +mod n { struct Foo where A: B { foo: usize } } + +mod o { enum Bar where A: B { Bar } } + +mod with_comments { + mod m { struct S /* before where */ where A: B; /* after where */ } + + mod n { struct Foo /* before where */ where A: B /* after where */ { foo: usize } } + + mod o { enum Bar /* before where */ where A: B /* after where */ { Bar } } +} diff --git a/src/tools/rustfmt/tests/source/issue-3198.rs b/src/tools/rustfmt/tests/source/issue-3198.rs new file mode 100644 index 000000000..48cb24a00 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3198.rs @@ -0,0 +1,99 @@ +impl TestTrait { + fn foo_one_pre(/* Important comment1 */ + self) { + } + + fn foo_one_post(self + /* Important comment1 */) { + } + + fn foo_pre( + /* Important comment1 */ + self, + /* Important comment2 */ + a: i32, + ) { + } + + fn foo_post( + self + /* Important comment1 */, + a: i32 + /* Important comment2 */, + ) { + } + + fn bar_pre( + /* Important comment1 */ + &mut self, + /* Important comment2 */ + a: i32, + ) { + } + + fn bar_post( + &mut self + /* Important comment1 */, + a: i32 + /* Important comment2 */, + ) { + } + + fn baz_pre( + /* Important comment1 */ + self: X< 'a , 'b >, + /* Important comment2 */ + a: i32, + ) { + } + + fn baz_post( + self: X< 'a , 'b > + /* Important comment1 */, + a: i32 + /* Important comment2 */, + ) { + } + + fn baz_tree_pre( + /* Important comment1 */ + self: X< 'a , 'b >, + /* Important comment2 */ + a: i32, + /* Important comment3 */ + b: i32, + ) { + } + + fn baz_tree_post( + self: X< 'a , 'b > + /* Important comment1 */, + a: i32 + /* Important comment2 */, + b: i32 + /* Important comment3 */,){ + } + + fn multi_line( + self: X<'a, 'b>, /* Important comment1-1 */ + /* Important comment1-2 */ + a: i32, /* Important comment2 */ + b: i32, /* Important comment3 */ + ) { + } + + fn two_line_comment( + self: X<'a, 'b>, /* Important comment1-1 + Important comment1-2 */ + a: i32, /* Important comment2 */ + b: i32, /* Important comment3 */ + ) { + } + + fn no_first_line_comment( + self: X<'a, 'b>, + /* Important comment2 */a: i32, + /* Important comment3 */b: i32, + ) { + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3213/version_one.rs b/src/tools/rustfmt/tests/source/issue-3213/version_one.rs new file mode 100644 index 000000000..f9f4cab55 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3213/version_one.rs @@ -0,0 +1,9 @@ +// rustfmt-version: One + +fn foo() { + match 0 { + 0 => return AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + 1 => AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + _ => "", + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-3213/version_two.rs b/src/tools/rustfmt/tests/source/issue-3213/version_two.rs new file mode 100644 index 000000000..0f068c19d --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3213/version_two.rs @@ -0,0 +1,9 @@ +// rustfmt-version: Two + +fn foo() { + match 0 { + 0 => return AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + 1 => AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + _ => "", + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-3217.rs b/src/tools/rustfmt/tests/source/issue-3217.rs new file mode 100644 index 000000000..176c70200 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3217.rs @@ -0,0 +1,8 @@ +#![feature(label_break_value)] + +fn main() { + let mut res = 0; + 's_39: { if res == 0i32 { println!("Hello, world!"); } } + 's_40: loop { println!("res = {}", res); res += 1; if res == 3i32 { break 's_40; } } + let toto = || { if true { 42 } else { 24 } }; +} diff --git a/src/tools/rustfmt/tests/source/issue-3227/two.rs b/src/tools/rustfmt/tests/source/issue-3227/two.rs new file mode 100644 index 000000000..c1572c00d --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3227/two.rs @@ -0,0 +1,13 @@ +// rustfmt-version: Two + +fn main() { + thread::spawn(|| { + while true { + println!("iteration"); + } + }); + + thread::spawn(|| loop { + println!("iteration"); + }); +} diff --git a/src/tools/rustfmt/tests/source/issue-3234.rs b/src/tools/rustfmt/tests/source/issue-3234.rs new file mode 100644 index 000000000..120740a72 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3234.rs @@ -0,0 +1,14 @@ +macro_rules! fuzz_target { + (|$data:ident: &[u8]| $body:block) => {}; +} + +fuzz_target!(|data: &[u8]| { + + if let Ok(app_img) = AppImage::parse(data) { + if let Ok(app_img) = app_img.sign_for_secureboot(include_str!("../../test-data/signing-key")) { + assert!(app_img.is_signed()); + Gbl::from_app_image(app_img).to_bytes(); + } + } + +}); diff --git a/src/tools/rustfmt/tests/source/issue-3241.rs b/src/tools/rustfmt/tests/source/issue-3241.rs new file mode 100644 index 000000000..090284a21 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3241.rs @@ -0,0 +1,11 @@ +// rustfmt-edition: 2018 + +use ::ignore; +use ::ignore::some::more; +use ::{foo, bar}; +use ::*; +use ::baz::{foo, bar}; + +fn main() { + println!("Hello, world!"); +} diff --git a/src/tools/rustfmt/tests/source/issue-3253/bar.rs b/src/tools/rustfmt/tests/source/issue-3253/bar.rs new file mode 100644 index 000000000..eaeffd3ad --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3253/bar.rs @@ -0,0 +1,4 @@ +// Empty + fn empty() { + +} diff --git a/src/tools/rustfmt/tests/source/issue-3253/foo.rs b/src/tools/rustfmt/tests/source/issue-3253/foo.rs new file mode 100644 index 000000000..4ebe5326b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3253/foo.rs @@ -0,0 +1,6 @@ +pub fn hello( ) + { +println!("Hello World!"); + + } + diff --git a/src/tools/rustfmt/tests/source/issue-3253/lib.rs b/src/tools/rustfmt/tests/source/issue-3253/lib.rs new file mode 100644 index 000000000..3eef586bd --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3253/lib.rs @@ -0,0 +1,14 @@ +#[macro_use] +extern crate cfg_if; + +cfg_if! { + if #[cfg(target_family = "unix")] { + mod foo; + #[path = "paths/bar_foo.rs"] + mod bar_foo; + } else { + mod bar; + #[path = "paths/foo_bar.rs"] + mod foo_bar; + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3253/paths/bar_foo.rs b/src/tools/rustfmt/tests/source/issue-3253/paths/bar_foo.rs new file mode 100644 index 000000000..da19f9dfa --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3253/paths/bar_foo.rs @@ -0,0 +1,3 @@ +fn foo_decl_item(x: &mut i32) { + x = 3; +} diff --git a/src/tools/rustfmt/tests/source/issue-3253/paths/excluded.rs b/src/tools/rustfmt/tests/source/issue-3253/paths/excluded.rs new file mode 100644 index 000000000..5c63eb832 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3253/paths/excluded.rs @@ -0,0 +1,6 @@ +// This module is not imported in the cfg_if macro in lib.rs so it is ignored +// while the foo and bar mods are formatted. +// Check the corresponding file in tests/target/issue-3253/paths/excluded.rs +trait CoolerTypes { fn dummy(&self) { +} +} diff --git a/src/tools/rustfmt/tests/source/issue-3253/paths/foo_bar.rs b/src/tools/rustfmt/tests/source/issue-3253/paths/foo_bar.rs new file mode 100644 index 000000000..fbb5d92c6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3253/paths/foo_bar.rs @@ -0,0 +1,4 @@ + + +fn Foo<T>() where T: Bar { +} diff --git a/src/tools/rustfmt/tests/source/issue-3265.rs b/src/tools/rustfmt/tests/source/issue-3265.rs new file mode 100644 index 000000000..e927cf2be --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3265.rs @@ -0,0 +1,14 @@ +// rustfmt-newline_style: Windows +#[cfg(test)] +mod test { + summary_test! { + tokenize_recipe_interpolation_eol, + "foo: # some comment + {{hello}} +", + "foo: \ + {{hello}} \ +{{ahah}}", + "N:#$>^{N}$<.", + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3270/one.rs b/src/tools/rustfmt/tests/source/issue-3270/one.rs new file mode 100644 index 000000000..3c2e27e22 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3270/one.rs @@ -0,0 +1,12 @@ +// rustfmt-version: One + +pub fn main() { + /* let s = String::from( + " +hello +world +", + ); */ + + assert_eq!(s, "\nhello\nworld\n"); +} diff --git a/src/tools/rustfmt/tests/source/issue-3270/two.rs b/src/tools/rustfmt/tests/source/issue-3270/two.rs new file mode 100644 index 000000000..0eb756471 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3270/two.rs @@ -0,0 +1,12 @@ +// rustfmt-version: Two + +pub fn main() { + /* let s = String::from( + " +hello +world +", + ); */ + + assert_eq!(s, "\nhello\nworld\n"); +} diff --git a/src/tools/rustfmt/tests/source/issue-3272/v1.rs b/src/tools/rustfmt/tests/source/issue-3272/v1.rs new file mode 100644 index 000000000..f4c1b7c99 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3272/v1.rs @@ -0,0 +1,15 @@ +// rustfmt-version: One + +fn main() { + assert!(HAYSTACK + .par_iter() + .find_any(|&&x| x[0] % 1000 == 999) + .is_some()); + + assert( + HAYSTACK + .par_iter() + .find_any(|&&x| x[0] % 1000 == 999) + .is_some(), + ); +} diff --git a/src/tools/rustfmt/tests/source/issue-3272/v2.rs b/src/tools/rustfmt/tests/source/issue-3272/v2.rs new file mode 100644 index 000000000..0148368ed --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3272/v2.rs @@ -0,0 +1,15 @@ +// rustfmt-version: Two + +fn main() { + assert!(HAYSTACK + .par_iter() + .find_any(|&&x| x[0] % 1000 == 999) + .is_some()); + + assert( + HAYSTACK + .par_iter() + .find_any(|&&x| x[0] % 1000 == 999) + .is_some(), + ); +} diff --git a/src/tools/rustfmt/tests/source/issue-3278/version_one.rs b/src/tools/rustfmt/tests/source/issue-3278/version_one.rs new file mode 100644 index 000000000..580679fba --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3278/version_one.rs @@ -0,0 +1,8 @@ +// rustfmt-version: One + +pub fn parse_conditional<'a, I: 'a>( +) -> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a +where + I: Stream<Item = char>, +{ +} diff --git a/src/tools/rustfmt/tests/source/issue-3278/version_two.rs b/src/tools/rustfmt/tests/source/issue-3278/version_two.rs new file mode 100644 index 000000000..c17b1742d --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3278/version_two.rs @@ -0,0 +1,8 @@ +// rustfmt-version: Two + +pub fn parse_conditional<'a, I: 'a>() +-> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a +where + I: Stream<Item = char>, +{ +} diff --git a/src/tools/rustfmt/tests/source/issue-3295/two.rs b/src/tools/rustfmt/tests/source/issue-3295/two.rs new file mode 100644 index 000000000..0eaf02224 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3295/two.rs @@ -0,0 +1,13 @@ +// rustfmt-version: Two +pub enum TestEnum { + a, + b, +} + +fn the_test(input: TestEnum) { + match input { + TestEnum::a => String::from("aaa"), + TestEnum::b => String::from("this is a very very very very very very very very very very very very very very very ong string"), + + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-3302.rs b/src/tools/rustfmt/tests/source/issue-3302.rs new file mode 100644 index 000000000..c037584fd --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3302.rs @@ -0,0 +1,43 @@ +// rustfmt-version: Two + +macro_rules! moo1 { + () => { + bar! { +" +" + } + }; +} + +macro_rules! moo2 { + () => { + bar! { + " +" + } + }; +} + +macro_rules! moo3 { + () => { + 42 + /* + bar! { + " + toto +tata" + } + */ + }; +} + +macro_rules! moo4 { + () => { + bar! { +" + foo + bar +baz" + } + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-3343.rs b/src/tools/rustfmt/tests/source/issue-3343.rs new file mode 100644 index 000000000..5670b04f5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3343.rs @@ -0,0 +1,47 @@ +// rustfmt-inline_attribute_width: 50 + +#[cfg(feature = "alloc")] +use core::slice; + +#[cfg(feature = "alloc")] +use total_len_is::_50__; + +#[cfg(feature = "alloc")] +use total_len_is::_51___; + +#[cfg(feature = "alloc")] +extern crate len_is_50_; + +#[cfg(feature = "alloc")] +extern crate len_is_51__; + +/// this is a comment to test is_sugared_doc property +use core::convert; + +#[fooooo] +#[barrrrr] +use total_len_is_::_51______; + +#[cfg(not(all( + feature = "std", + any( + target_os = "linux", + target_os = "android", + target_os = "netbsd", + target_os = "dragonfly", + target_os = "haiku", + target_os = "emscripten", + target_os = "solaris", + target_os = "cloudabi", + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "redox", + target_os = "fuchsia", + windows, + all(target_arch = "wasm32", feature = "stdweb"), + all(target_arch = "wasm32", feature = "wasm-bindgen"), + ) +)))] +use core::slice; diff --git a/src/tools/rustfmt/tests/source/issue-3423.rs b/src/tools/rustfmt/tests/source/issue-3423.rs new file mode 100644 index 000000000..fbe8e5c37 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3423.rs @@ -0,0 +1,5 @@ +/* a nice comment with a trailing whitespace */ +fn foo() {} + +/* a nice comment with a trailing tab */ +fn bar() {} diff --git a/src/tools/rustfmt/tests/source/issue-3434/lib.rs b/src/tools/rustfmt/tests/source/issue-3434/lib.rs new file mode 100644 index 000000000..7e396b383 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3434/lib.rs @@ -0,0 +1,57 @@ +#![rustfmt::skip::macros(skip_macro_mod)] + +mod no_entry; + +#[rustfmt::skip::macros(html, skip_macro)] +fn main() { + let macro_result1 = html! { <div> +this should be skipped</div> + } + .to_string(); + + let macro_result2 = not_skip_macro! { <div> +this should be mangled</div> + } + .to_string(); + + skip_macro! { +this should be skipped +}; + + foo(); +} + +fn foo() { + let macro_result1 = html! { <div> +this should be mangled</div> + } + .to_string(); +} + +fn bar() { + let macro_result1 = skip_macro_mod! { <div> +this should be skipped</div> + } + .to_string(); +} + +fn visitor_made_from_same_context() { + let pair = ( + || { + foo!(<div> +this should be mangled</div> + ); + skip_macro_mod!(<div> +this should be skipped</div> + ); + }, + || { + foo!(<div> +this should be mangled</div> + ); + skip_macro_mod!(<div> +this should be skipped</div> + ); + }, + ); +} diff --git a/src/tools/rustfmt/tests/source/issue-3434/no_entry.rs b/src/tools/rustfmt/tests/source/issue-3434/no_entry.rs new file mode 100644 index 000000000..0838829fe --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3434/no_entry.rs @@ -0,0 +1,18 @@ +#[rustfmt::skip::macros(another_macro)] +fn foo() { + another_macro!( +This should be skipped. + ); +} + +fn bar() { + skip_macro_mod!( +This should be skipped. + ); +} + +fn baz() { + let macro_result1 = no_skip_macro! { <div> +this should be mangled</div> + }.to_string(); +} diff --git a/src/tools/rustfmt/tests/source/issue-3434/not_skip_macro.rs b/src/tools/rustfmt/tests/source/issue-3434/not_skip_macro.rs new file mode 100644 index 000000000..1d7d73c52 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3434/not_skip_macro.rs @@ -0,0 +1,8 @@ +#[this::is::not::skip::macros(ouch)] + +fn main() { + let macro_result1 = ouch! { <div> +this should be mangled</div> + } + .to_string(); +} diff --git a/src/tools/rustfmt/tests/source/issue-3465.rs b/src/tools/rustfmt/tests/source/issue-3465.rs new file mode 100644 index 000000000..0bc95ad46 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3465.rs @@ -0,0 +1,42 @@ +fn main() { + ((((((((((((((((((((((((((((((((((((((((((0) + 1) + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1); +} diff --git a/src/tools/rustfmt/tests/source/issue-3494/crlf.rs b/src/tools/rustfmt/tests/source/issue-3494/crlf.rs new file mode 100644 index 000000000..9ce457c7b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3494/crlf.rs @@ -0,0 +1,8 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-3494/crlf.rs","range":[4,5]}] + +pub fn main()
+{
+let world1 = "world"; println!("Hello, {}!", world1);
+let world2 = "world"; println!("Hello, {}!", world2);
+let world3 = "world"; println!("Hello, {}!", world3);
+}
diff --git a/src/tools/rustfmt/tests/source/issue-3494/lf.rs b/src/tools/rustfmt/tests/source/issue-3494/lf.rs new file mode 100644 index 000000000..bdbe69cef --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3494/lf.rs @@ -0,0 +1,8 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-3494/lf.rs","range":[4,5]}] + +pub fn main() +{ +let world1 = "world"; println!("Hello, {}!", world1); +let world2 = "world"; println!("Hello, {}!", world2); +let world3 = "world"; println!("Hello, {}!", world3); +} diff --git a/src/tools/rustfmt/tests/source/issue-3508.rs b/src/tools/rustfmt/tests/source/issue-3508.rs new file mode 100644 index 000000000..821e947c7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3508.rs @@ -0,0 +1,29 @@ +fn foo<F>(foo2: F) +where + F: Fn( + // this comment is deleted +), +{ +} + +fn foo_block<F>(foo2: F) +where + F: Fn( + /* this comment is deleted */ + ), +{ +} + +fn bar( + bar2: impl Fn( + // this comment is deleted + ), +) { +} + +fn bar_block( + bar2: impl Fn( + /* this comment is deleted */ + ), +) { +} diff --git a/src/tools/rustfmt/tests/source/issue-3515.rs b/src/tools/rustfmt/tests/source/issue-3515.rs new file mode 100644 index 000000000..9f760cb94 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3515.rs @@ -0,0 +1,6 @@ +// rustfmt-reorder_imports: false + +use std :: fmt :: { self , Display } ; +use std :: collections :: HashMap ; + +fn main() {} diff --git a/src/tools/rustfmt/tests/source/issue-3532.rs b/src/tools/rustfmt/tests/source/issue-3532.rs new file mode 100644 index 000000000..ec0c01610 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3532.rs @@ -0,0 +1,7 @@ +fn foo(a: T) { + match a { +1 => {} + 0 => {} + // _ => panic!("doesn't format!"), + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3585/extern_crate.rs b/src/tools/rustfmt/tests/source/issue-3585/extern_crate.rs new file mode 100644 index 000000000..6716983ba --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3585/extern_crate.rs @@ -0,0 +1,12 @@ +// rustfmt-inline_attribute_width: 100 + +#[macro_use] +extern crate static_assertions; + +#[cfg(unix)] +extern crate static_assertions; + +// a comment before the attribute +#[macro_use] +// some comment after +extern crate static_assertions; diff --git a/src/tools/rustfmt/tests/source/issue-3585/reorder_imports_disabled.rs b/src/tools/rustfmt/tests/source/issue-3585/reorder_imports_disabled.rs new file mode 100644 index 000000000..45b1bb9fd --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3585/reorder_imports_disabled.rs @@ -0,0 +1,12 @@ +// rustfmt-inline_attribute_width: 100 +// rustfmt-reorder_imports: false + +#[cfg(unix)] +extern crate crateb; +#[cfg(unix)] +extern crate cratea; + +#[cfg(unix)] +use crateb; +#[cfg(unix)] +use cratea; diff --git a/src/tools/rustfmt/tests/source/issue-3585/reorder_imports_enabled.rs b/src/tools/rustfmt/tests/source/issue-3585/reorder_imports_enabled.rs new file mode 100644 index 000000000..9f433e5ca --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3585/reorder_imports_enabled.rs @@ -0,0 +1,12 @@ +// rustfmt-inline_attribute_width: 100 +// rustfmt-reorder_imports: true + +#[cfg(unix)] +extern crate crateb; +#[cfg(unix)] +extern crate cratea; + +#[cfg(unix)] +use crateb; +#[cfg(unix)] +use cratea; diff --git a/src/tools/rustfmt/tests/source/issue-3585/use.rs b/src/tools/rustfmt/tests/source/issue-3585/use.rs new file mode 100644 index 000000000..e71ba9008 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3585/use.rs @@ -0,0 +1,7 @@ +// rustfmt-inline_attribute_width: 100 + +#[macro_use] +use static_assertions; + +#[cfg(unix)] +use static_assertions; diff --git a/src/tools/rustfmt/tests/source/issue-3636.rs b/src/tools/rustfmt/tests/source/issue-3636.rs new file mode 100644 index 000000000..edfa03012 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3636.rs @@ -0,0 +1,10 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-3636.rs","range":[4,7]},{"file":"tests/target/issue-3636.rs","range":[3,6]}] + +fn foo() { + let x = + 42; + let y = + 42; + let z = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + let z = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +} diff --git a/src/tools/rustfmt/tests/source/issue-3639.rs b/src/tools/rustfmt/tests/source/issue-3639.rs new file mode 100644 index 000000000..7b16b2dfd --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3639.rs @@ -0,0 +1,5 @@ +trait Foo where {} +struct Bar where {} +struct Bax where; +struct Baz(String) where; +impl<> Foo<> for Bar<> where {} diff --git a/src/tools/rustfmt/tests/source/issue-3651.rs b/src/tools/rustfmt/tests/source/issue-3651.rs new file mode 100644 index 000000000..c153e99d0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3651.rs @@ -0,0 +1,4 @@ +fn f() -> Box< + dyn FnMut() -> Thing< WithType = LongItemName, Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger>, +>{ +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue-3665/lib.rs b/src/tools/rustfmt/tests/source/issue-3665/lib.rs new file mode 100644 index 000000000..e049fbc56 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3665/lib.rs @@ -0,0 +1,33 @@ +#![rustfmt::skip::attributes(skip_mod_attr)] + +mod sub_mod; + +#[rustfmt::skip::attributes(other, skip_attr)] +fn main() { + #[other(should, +skip, + this, format)] + struct S {} + + #[skip_attr(should, skip, +this, format,too)] + fn doesnt_mater() {} + + #[skip_mod_attr(should, skip, +this, format, + enerywhere)] + fn more() {} + + #[not_skip(not, +skip, me)] + struct B {} +} + +#[other(should, not, skip, +this, format, here)] +fn foo() {} + +#[skip_mod_attr(should, skip, +this, format,in, master, + and, sub, module)] +fn bar() {} diff --git a/src/tools/rustfmt/tests/source/issue-3665/not_skip_attribute.rs b/src/tools/rustfmt/tests/source/issue-3665/not_skip_attribute.rs new file mode 100644 index 000000000..14985259a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3665/not_skip_attribute.rs @@ -0,0 +1,4 @@ +#![this::is::not::skip::attribute(ouch)] + +#[ouch(not, skip, me)] +fn main() {} diff --git a/src/tools/rustfmt/tests/source/issue-3665/sub_mod.rs b/src/tools/rustfmt/tests/source/issue-3665/sub_mod.rs new file mode 100644 index 000000000..75fb24b4a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3665/sub_mod.rs @@ -0,0 +1,14 @@ +#[rustfmt::skip::attributes(more_skip)] +#[more_skip(should, + skip, +this, format)] +fn foo() {} + +#[skip_mod_attr(should, skip, +this, format,in, master, + and, sub, module)] +fn bar() {} + +#[skip_attr(should, not, + skip, this, attribute, here)] +fn baz() {} diff --git a/src/tools/rustfmt/tests/source/issue-3672.rs b/src/tools/rustfmt/tests/source/issue-3672.rs new file mode 100644 index 000000000..82616bd42 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3672.rs @@ -0,0 +1,4 @@ +fn main() { + let x = 5;; + +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue-3675.rs b/src/tools/rustfmt/tests/source/issue-3675.rs new file mode 100644 index 000000000..f16efb2dc --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3675.rs @@ -0,0 +1,5 @@ + fn main() { + println!("{}" + // comment + , 111); + }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue-3701/one.rs b/src/tools/rustfmt/tests/source/issue-3701/one.rs new file mode 100644 index 000000000..a7f0bd3aa --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3701/one.rs @@ -0,0 +1,12 @@ +// rustfmt-version: One + +fn build_sorted_static_get_entry_names( + mut entries: Vec<(u8, &'static str)>, +) -> (impl Fn( + AlphabeticalTraversal, + Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>, +) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>> + + Send + + Sync + + 'static) { +} diff --git a/src/tools/rustfmt/tests/source/issue-3701/two.rs b/src/tools/rustfmt/tests/source/issue-3701/two.rs new file mode 100644 index 000000000..8e15c58b8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3701/two.rs @@ -0,0 +1,12 @@ +// rustfmt-version: Two + +fn build_sorted_static_get_entry_names( + mut entries: Vec<(u8, &'static str)>, +) -> (impl Fn( + AlphabeticalTraversal, + Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>, +) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>> + + Send + + Sync + + 'static) { +} diff --git a/src/tools/rustfmt/tests/source/issue-3709.rs b/src/tools/rustfmt/tests/source/issue-3709.rs new file mode 100644 index 000000000..73c2a624e --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3709.rs @@ -0,0 +1,10 @@ +// rustfmt-edition: 2018 + +macro_rules! token { + ($t:tt) => {}; +} + +fn main() { + token!(dyn); + token!(dyn ); +} diff --git a/src/tools/rustfmt/tests/source/issue-3740.rs b/src/tools/rustfmt/tests/source/issue-3740.rs new file mode 100644 index 000000000..2769a8cc9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3740.rs @@ -0,0 +1,10 @@ +impl<T, const SIZE: usize> IntoNormalized for Vector<T, { SIZE }> + where + Vector<T, { SIZE }>: Div<Vector<T, { SIZE }>>, + for<'a> &'a Vector<T, { SIZE }>: IntoLength<Output = T>, +{ + type Output = Vector<T, { SIZE }>; + fn into_normalized(self) -> Self::Output { + + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3750.rs b/src/tools/rustfmt/tests/source/issue-3750.rs new file mode 100644 index 000000000..1189a99d2 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3750.rs @@ -0,0 +1,16 @@ +// rustfmt-imports_granularity: Crate + +pub mod foo { + pub mod bar { + pub struct Bar; + } + + pub fn bar() {} +} + +use foo::bar; +use foo::bar::Bar; + +fn main() { + bar(); +} diff --git a/src/tools/rustfmt/tests/source/issue-3751.rs b/src/tools/rustfmt/tests/source/issue-3751.rs new file mode 100644 index 000000000..1343f80e6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3751.rs @@ -0,0 +1,10 @@ +// rustfmt-format_code_in_doc_comments: true + +//! Empty pound line +//! +//! ```rust +//! # +//! # fn main() { +//! foo ( ) ; +//! # } +//! ``` diff --git a/src/tools/rustfmt/tests/source/issue-3779/ice.rs b/src/tools/rustfmt/tests/source/issue-3779/ice.rs new file mode 100644 index 000000000..cde21412d --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3779/ice.rs @@ -0,0 +1,3 @@ +pub fn bar() { + 1x; +} diff --git a/src/tools/rustfmt/tests/source/issue-3779/lib.rs b/src/tools/rustfmt/tests/source/issue-3779/lib.rs new file mode 100644 index 000000000..16e9d4833 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3779/lib.rs @@ -0,0 +1,9 @@ +// rustfmt-unstable: true +// rustfmt-config: issue-3779.toml + +#[path = "ice.rs"] +mod ice; + +fn foo() { +println!("abc") ; + } diff --git a/src/tools/rustfmt/tests/source/issue-3786.rs b/src/tools/rustfmt/tests/source/issue-3786.rs new file mode 100644 index 000000000..54f8211ed --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3786.rs @@ -0,0 +1,12 @@ +fn main() { + let _ = +r#" +this is a very long string exceeded maximum width in this case maximum 100. (current this line width is about 115) +"#; + + let _with_newline = + +r#" +this is a very long string exceeded maximum width in this case maximum 100. (current this line width is about 115) +"#; +} diff --git a/src/tools/rustfmt/tests/source/issue-3787.rs b/src/tools/rustfmt/tests/source/issue-3787.rs new file mode 100644 index 000000000..bcdc131a0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3787.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: true + +//! URLs in items +//! * [This is a link with a very loooooooooooooooooooooooooooooooooooooooooong URL.](https://example.com/This/is/a/link/with/a/very/loooooooooooooooooooooooooooooooooooooooooong/URL) +//! * This is a [link](https://example.com/This/is/a/link/with/a/very/loooooooooooooooooooooooooooooooooooooooooong/URL) with a very loooooooooooooooooooooooooooooooooooooooooong URL. +//! * there is no link here: In hac habitasse platea dictumst. Maecenas in ligula. Duis tincidunt odio sollicitudin quam. Nullam non mauris. Phasellus lacinia, velit sit amet bibendum euismod, leo diam interdum ligula, eu scelerisque sem purus in tellus. +fn main() { + println!("Hello, world!"); +} diff --git a/src/tools/rustfmt/tests/source/issue-3840/version-one_hard-tabs.rs b/src/tools/rustfmt/tests/source/issue-3840/version-one_hard-tabs.rs new file mode 100644 index 000000000..bf7ea7da0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3840/version-one_hard-tabs.rs @@ -0,0 +1,15 @@ +// rustfmt-hard_tabs: true + +impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B> +{ + type Ctx = C; + type Event = Vec<Target>; +} + +mod foo { + impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B> + { + type Ctx = C; + type Event = Vec<Target>; + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3840/version-one_soft-tabs.rs b/src/tools/rustfmt/tests/source/issue-3840/version-one_soft-tabs.rs new file mode 100644 index 000000000..3fc26224d --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3840/version-one_soft-tabs.rs @@ -0,0 +1,13 @@ +impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B> +{ + type Ctx = C; + type Event = Vec<Target>; +} + +mod foo { + impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B> + { + type Ctx = C; + type Event = Vec<Target>; + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3840/version-two_hard-tabs.rs b/src/tools/rustfmt/tests/source/issue-3840/version-two_hard-tabs.rs new file mode 100644 index 000000000..7b505fda8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3840/version-two_hard-tabs.rs @@ -0,0 +1,16 @@ +// rustfmt-hard_tabs: true +// rustfmt-version: Two + +impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B> +{ + type Ctx = C; + type Event = Vec<Target>; +} + +mod foo { + impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B> + { + type Ctx = C; + type Event = Vec<Target>; + } +} diff --git a/src/tools/rustfmt/tests/source/issue-3840/version-two_soft-tabs.rs b/src/tools/rustfmt/tests/source/issue-3840/version-two_soft-tabs.rs new file mode 100644 index 000000000..39c8ef312 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-3840/version-two_soft-tabs.rs @@ -0,0 +1,15 @@ +// rustfmt-version: Two + +impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B> +{ + type Ctx = C; + type Event = Vec<Target>; +} + +mod foo { + impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B> + { + type Ctx = C; + type Event = Vec<Target>; + } +} diff --git a/src/tools/rustfmt/tests/source/issue-4018.rs b/src/tools/rustfmt/tests/source/issue-4018.rs new file mode 100644 index 000000000..9a91dd9a3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4018.rs @@ -0,0 +1,13 @@ +fn main() { + ; + /* extra comment */ ; +} + +fn main() { + println!(""); + // comment 1 + // comment 2 + // comment 3 + // comment 4 + ; +} diff --git a/src/tools/rustfmt/tests/source/issue-4036/one.rs b/src/tools/rustfmt/tests/source/issue-4036/one.rs new file mode 100644 index 000000000..9f9675f51 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4036/one.rs @@ -0,0 +1,11 @@ +// rustfmt-format_strings: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "We asserted that `buffer.len()` is exactly `$n` so we can expect `ApInt::from_iter` to be successful.", + ) + } + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-4036/three.rs b/src/tools/rustfmt/tests/source/issue-4036/three.rs new file mode 100644 index 000000000..e1865dd08 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4036/three.rs @@ -0,0 +1,12 @@ +// rustfmt-format_strings: true +// rustfmt-hard_tabs: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + ) + } + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-4036/two.rs b/src/tools/rustfmt/tests/source/issue-4036/two.rs new file mode 100644 index 000000000..fa54d2e3e --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4036/two.rs @@ -0,0 +1,11 @@ +// rustfmt-format_strings: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + ) + } + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-4079.rs b/src/tools/rustfmt/tests/source/issue-4079.rs new file mode 100644 index 000000000..eb1ce5ed2 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4079.rs @@ -0,0 +1,8 @@ +// rustfmt-wrap_comments: true + +/*! + * Lorem ipsum dolor sit amet, consectetur adipiscing elit. In lacinia + * ullamcorper lorem, non hendrerit enim convallis ut. Curabitur id sem volutpat + */ + +/*! Lorem ipsum dolor sit amet, consectetur adipiscing elit. In lacinia ullamcorper lorem, non hendrerit enim convallis ut. Curabitur id sem volutpat */ diff --git a/src/tools/rustfmt/tests/source/issue-4120.rs b/src/tools/rustfmt/tests/source/issue-4120.rs new file mode 100644 index 000000000..c9ce838c5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4120.rs @@ -0,0 +1,85 @@ +fn main() { + let x = if true { + 1 + // In if + } else { + 0 + // In else + }; + + let x = if true { + 1 + /* In if */ + } else { + 0 + /* In else */ + }; + + let z = if true { + if true { + 1 + + // In if level 2 + } else { + 2 + } + } else { + 3 + }; + + let a = if true { + 1 + // In if + } else { + 0 + // In else + }; + + let a = if true { + 1 + + // In if + } else { + 0 + // In else + }; + + let b = if true { + 1 + + // In if + } else { + 0 + // In else + }; + + let c = if true { + 1 + + // In if + } else { + 0 + // In else + }; + for i in 0..2 { + println!("Something"); + // In for + } + + for i in 0..2 { + println!("Something"); + /* In for */ + } + + extern "C" { + fn first(); + + // In foreign mod + } + + extern "C" { + fn first(); + + /* In foreign mod */ + } +} diff --git a/src/tools/rustfmt/tests/source/issue-4243.rs b/src/tools/rustfmt/tests/source/issue-4243.rs new file mode 100644 index 000000000..d8a27f7a4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4243.rs @@ -0,0 +1,21 @@ +fn main() { + type A: AA /*AA*/ + /*AB*/ AB ++ AC = AA +/*AA*/ + + /*AB*/ AB+AC; + + type B: BA /*BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA*/+/*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/ BB + + BC = BA /*BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA*/ + /*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/ BB+ BC; + + type C: CA // CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +// CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + + // CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + // CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + CB + CC = CA // CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + // CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + + // CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + // CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + CB+ CC; +} diff --git a/src/tools/rustfmt/tests/source/issue-4244.rs b/src/tools/rustfmt/tests/source/issue-4244.rs new file mode 100644 index 000000000..34b51085e --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4244.rs @@ -0,0 +1,16 @@ +pub struct SS {} + +pub type A /* A Comment */ = SS; + +pub type B // Comment +// B += SS; + +pub type C + /* Comment C */ = SS; + +pub trait D <T> { + type E /* Comment E */ = SS; +} + +type F<'a: 'static, T: Ord + 'static>: Eq + PartialEq where T: 'static + Copy /* x */ = Vec<u8>; diff --git a/src/tools/rustfmt/tests/source/issue-4245.rs b/src/tools/rustfmt/tests/source/issue-4245.rs new file mode 100644 index 000000000..57d7e192d --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4245.rs @@ -0,0 +1,26 @@ + + +fn a(a: & // Comment + // Another comment + 'a File) {} + +fn b(b: & /* Another Comment */'a File) {} + +fn c(c: &'a /*Comment */ mut /*Comment */ File){} + +fn d(c: & // Comment +'b // Multi Line +// Comment +mut // Multi Line +// Comment +File +) {} + +fn e(c: &// Comment +File) {} + +fn d(c: &// Comment +mut // Multi Line +// Comment +File +) {} diff --git a/src/tools/rustfmt/tests/source/issue-4312.rs b/src/tools/rustfmt/tests/source/issue-4312.rs new file mode 100644 index 000000000..b36b0efdb --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4312.rs @@ -0,0 +1,22 @@ +// issue 4312 +fn main() { + /* " */ + println!("Hello, world!"); + /* abc " */ + println!("Hello, world!"); + /* " abc */ + println!("Hello, world!"); + let y = 4; + let x = match 1 + y == 3 { + True => 3, + False => 4, + /* " unreachable */ + }; +} + +// issue 4806 +enum X { + A, + B, + /*"*/ +} diff --git a/src/tools/rustfmt/tests/source/issue-4382.rs b/src/tools/rustfmt/tests/source/issue-4382.rs new file mode 100644 index 000000000..cbf0c4ed6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4382.rs @@ -0,0 +1,4 @@ +pub const NAME_MAX: usize = { + #[cfg(target_os = "linux")] { 1024 } + #[cfg(target_os = "freebsd")] { 255 } +}; diff --git a/src/tools/rustfmt/tests/source/issue-4398.rs b/src/tools/rustfmt/tests/source/issue-4398.rs new file mode 100644 index 000000000..b0095aaac --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4398.rs @@ -0,0 +1,19 @@ +impl Struct { + /// Documentation for `foo` + #[rustfmt::skip] // comment on why use a skip here + pub fn foo(&self) {} +} + +impl Struct { + /// Documentation for `foo` + #[rustfmt::skip] // comment on why use a skip here + pub fn foo(&self) {} +} + +/// Documentation for `Struct` +#[rustfmt::skip] // comment +impl Struct { + /// Documentation for `foo` + #[rustfmt::skip] // comment on why use a skip here + pub fn foo(&self) {} +} diff --git a/src/tools/rustfmt/tests/source/issue-4427.rs b/src/tools/rustfmt/tests/source/issue-4427.rs new file mode 100644 index 000000000..e14e039b9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4427.rs @@ -0,0 +1,31 @@ +const A: usize = + // Some constant + 2; + +const B: usize = +/* constant */ +3; + +const C : usize + = /* foo */5; + +const D: usize = // baz +/* Some constant */ + /* ba */ + { 3 + // foo + }; +const E: usize= /* foo */5; +const F: usize = +{ + 7 + }; +const G: usize = /* foooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000xx00 */ 5; + const H: usize = /* asdfasdf */ match G > 1 { + true => 1, + false => 3, + }; + + pub static FOO_BAR: Vec<u8> = //f + { + vec![]}; diff --git a/src/tools/rustfmt/tests/source/issue-447.rs b/src/tools/rustfmt/tests/source/issue-447.rs new file mode 100644 index 000000000..7c542cb58 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-447.rs @@ -0,0 +1,39 @@ +// rustfmt-normalize_comments: true + +fn main() { + if /* shouldn't be dropped + shouldn't be dropped */ + + cond /* shouldn't be dropped + shouldn't be dropped */ + + { + } /* shouldn't be dropped + shouldn't be dropped */ + + else /* shouldn't be dropped + shouldn't be dropped */ + + if /* shouldn't be dropped + shouldn't be dropped */ + + cond /* shouldn't be dropped + shouldn't be dropped */ + + { + } /* shouldn't be dropped + shouldn't be dropped */ + + else /* shouldn't be dropped + shouldn't be dropped */ + + { + } + + if /* shouldn't be dropped + shouldn't be dropped */ + let Some(x) = y/* shouldn't be dropped + shouldn't be dropped */ + { + } +} diff --git a/src/tools/rustfmt/tests/source/issue-4530.rs b/src/tools/rustfmt/tests/source/issue-4530.rs new file mode 100644 index 000000000..9d2882abb --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4530.rs @@ -0,0 +1,4 @@ +// rustfmt-version: Two +fn main() { + let [aaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccc, ddddddddddddddddddddddddd] = panic!(); +} diff --git a/src/tools/rustfmt/tests/source/issue-4577.rs b/src/tools/rustfmt/tests/source/issue-4577.rs new file mode 100644 index 000000000..79975dd73 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4577.rs @@ -0,0 +1,20 @@ +fn main() { + let s: String = "ABAABBAA".chars() + .filter(|c| { + if *c == 'A' { + true + } + else { + false + } + }) + .map(|c| -> char { + if c == 'A' { + '0' + } else { + '1' + } + }).collect(); + + println!("{}", s); +} diff --git a/src/tools/rustfmt/tests/source/issue-4603.rs b/src/tools/rustfmt/tests/source/issue-4603.rs new file mode 100644 index 000000000..ba0803e0e --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4603.rs @@ -0,0 +1,47 @@ +// Formatting when original macro snippet is used + +// Original issue #4603 code +#![feature(or_patterns)] +macro_rules! t_or_f { + () => { + (true // some comment + | false) + }; +} + +// Other test cases variations +macro_rules! RULES { + () => { + ( + xxxxxxx // COMMENT + | yyyyyyy + ) + }; +} +macro_rules! RULES { + () => { + (xxxxxxx // COMMENT + | yyyyyyy) + }; +} + +fn main() { + macro_rules! RULES { + () => { + (xxxxxxx // COMMENT + | yyyyyyy) + }; + } +} + +macro_rules! RULES { + () => { + (xxxxxxx /* COMMENT */ | yyyyyyy) + }; +} +macro_rules! RULES { + () => { + (xxxxxxx /* COMMENT */ + | yyyyyyy) + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-4615/minimum_example.rs b/src/tools/rustfmt/tests/source/issue-4615/minimum_example.rs new file mode 100644 index 000000000..89af5d123 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4615/minimum_example.rs @@ -0,0 +1,4 @@ +info!(//debug + "{}: sending function_code={:04x} data={:04x} crc=0x{:04X} data={:02X?}", + self.name, function_code, data, crc, output_cmd +); diff --git a/src/tools/rustfmt/tests/source/issue-4646.rs b/src/tools/rustfmt/tests/source/issue-4646.rs new file mode 100644 index 000000000..ee0f23220 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4646.rs @@ -0,0 +1,20 @@ +trait Foo { + fn bar(&self) + // where + // Self: Bar + ; +} + +trait Foo { + fn bar(&self) + // where + // Self: Bar +; +} + +trait Foo { + fn bar(&self) + // where + // Self: Bar + ; +} diff --git a/src/tools/rustfmt/tests/source/issue-4656/format_me_please.rs b/src/tools/rustfmt/tests/source/issue-4656/format_me_please.rs new file mode 100644 index 000000000..7de753016 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4656/format_me_please.rs @@ -0,0 +1,2 @@ + +pub fn hello( ) { } diff --git a/src/tools/rustfmt/tests/source/issue-4656/lib.rs b/src/tools/rustfmt/tests/source/issue-4656/lib.rs new file mode 100644 index 000000000..5dac91b8a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4656/lib.rs @@ -0,0 +1,7 @@ +extern crate cfg_if; + +cfg_if::cfg_if! { + if #[cfg(target_family = "unix")] { + mod format_me_please; + } +} diff --git a/src/tools/rustfmt/tests/source/issue-4656/lib2.rs b/src/tools/rustfmt/tests/source/issue-4656/lib2.rs new file mode 100644 index 000000000..b17fffc58 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4656/lib2.rs @@ -0,0 +1,3 @@ +its_a_macro! { + // Contents +} diff --git a/src/tools/rustfmt/tests/source/issue-4791/buggy.rs b/src/tools/rustfmt/tests/source/issue-4791/buggy.rs new file mode 100644 index 000000000..4760022ee --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4791/buggy.rs @@ -0,0 +1,14 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-trailing_comma: Never + +struct Foo { + group_a: u8, + + group_b: u8, +} + +struct Bar { + group_a: u8, + + group_b: u8 +} diff --git a/src/tools/rustfmt/tests/source/issue-4791/trailing_comma.rs b/src/tools/rustfmt/tests/source/issue-4791/trailing_comma.rs new file mode 100644 index 000000000..c56c70fae --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4791/trailing_comma.rs @@ -0,0 +1,14 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-trailing_comma: Always + +struct Foo { + group_a: u8, + + group_b: u8 +} + +struct Bar { + group_a: u8, + + group_b: u8, +} diff --git a/src/tools/rustfmt/tests/source/issue-4816/lib.rs b/src/tools/rustfmt/tests/source/issue-4816/lib.rs new file mode 100644 index 000000000..43d540c4a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4816/lib.rs @@ -0,0 +1,10 @@ +#![feature(const_generics_defaults)] +struct Foo<const N: usize = 1, const N2: usize = 2>; +struct Bar<const N: usize, const N2: usize = { N + +1 }>; +struct Lots<const N1BlahFooUwU: usize = { 10 + 28 + 1872 / 10 * 3 },const N2SecondParamOhmyyy: usize = { N1BlahFooUwU / 2 + 10 * 2 },>; +struct NamesRHard<const N: usize = { 1 + 1 + 1 + 1 + 1 + 1 }>; +struct FooBar< + const LessThan100ButClose: usize = {1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1} +>; +struct FooBarrrrrrrr<const N: usize = {13478234326456456444323871+ 1+ 1+ 1+ 1+ 1+ 1+ 1+ 1+ 1+ 1+ 1+ 1+ 1+1+1+1 + 1},>; diff --git a/src/tools/rustfmt/tests/source/issue-4926/deeply_nested_struct.rs b/src/tools/rustfmt/tests/source/issue-4926/deeply_nested_struct.rs new file mode 100644 index 000000000..e55e41bd1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4926/deeply_nested_struct.rs @@ -0,0 +1,35 @@ + +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { a: 1_000, b: 1_000, .. } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs b/src/tools/rustfmt/tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs new file mode 100644 index 000000000..516699fa2 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs @@ -0,0 +1,43 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs b/src/tools/rustfmt/tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs new file mode 100644 index 000000000..38fd6f02c --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs @@ -0,0 +1,44 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + a: 1_000, b: 1_000, c: 1_000, d: 1_000, e: 1_000, f: 1_000, g: 1_000, h: 1_000, i: 1_000, j: 1_000, .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-4926/enum_struct_field.rs b/src/tools/rustfmt/tests/source/issue-4926/enum_struct_field.rs new file mode 100644 index 000000000..336378537 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4926/enum_struct_field.rs @@ -0,0 +1,35 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-enum_discrim_align_threshold: 30 +// rustfmt-imports_layout: HorizontalVertical + +#[derive(Default)] +struct InnerStructA { bbbbbbbbb: i32, cccccccc: i32 } + +enum SomeEnumNamedD { + E(InnerStructA), + F { + ggggggggggggggggggggggggg: bool, + h: bool, + } +} + +impl SomeEnumNamedD { + fn f_variant() -> Self { + Self::F { ggggggggggggggggggggggggg: true, h: true } + } +} + +fn main() { + let kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk = SomeEnumNamedD::f_variant(); + let something_we_care_about = matches!( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, + SomeEnumNamedD::F { + ggggggggggggggggggggggggg: true, + .. + } + ); + + if something_we_care_about { + println!("Yup it happened"); + } +} diff --git a/src/tools/rustfmt/tests/source/issue-4926/minimum_example.rs b/src/tools/rustfmt/tests/source/issue-4926/minimum_example.rs new file mode 100644 index 000000000..2c3045dea --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4926/minimum_example.rs @@ -0,0 +1,10 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { a: i32, b: i32 } + +fn test(x: X) { + let y = matches!(x, X { + a: 1, + .. + }); +} diff --git a/src/tools/rustfmt/tests/source/issue-4926/struct_with_long_field_names.rs b/src/tools/rustfmt/tests/source/issue-4926/struct_with_long_field_names.rs new file mode 100644 index 000000000..b8a37f071 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4926/struct_with_long_field_names.rs @@ -0,0 +1,21 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let y = matches!(x, X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, + .. + }); +} diff --git a/src/tools/rustfmt/tests/source/issue-4926/struct_with_many_fields.rs b/src/tools/rustfmt/tests/source/issue-4926/struct_with_many_fields.rs new file mode 100644 index 000000000..4adfd3b30 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4926/struct_with_many_fields.rs @@ -0,0 +1,21 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let y = matches!(x, X { + a: 1_000, b: 1_000, c: 1_000, d: 1_000, e: 1_000, f: 1_000, g: 1_000, h: 1_000, i: 1_000, j: 1_000, .. + }); +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue-4984/minimum_example.rs b/src/tools/rustfmt/tests/source/issue-4984/minimum_example.rs new file mode 100644 index 000000000..677f87377 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4984/minimum_example.rs @@ -0,0 +1,2 @@ +#[derive(/*Debug, */Clone)] +struct Foo; diff --git a/src/tools/rustfmt/tests/source/issue-4984/multi_line_derive.rs b/src/tools/rustfmt/tests/source/issue-4984/multi_line_derive.rs new file mode 100644 index 000000000..73921dd17 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4984/multi_line_derive.rs @@ -0,0 +1,20 @@ +#[derive( +/* ---------- Some really important comment that just had to go inside the derive --------- */ +Debug, Clone, Eq, PartialEq, +)] +struct Foo { + a: i32, + b: T, +} + +#[derive( +/* + Some really important comment that just had to go inside the derive. + Also had to be put over multiple lines +*/ +Debug, Clone, Eq, PartialEq, +)] +struct Bar { + a: i32, + b: T, +} diff --git a/src/tools/rustfmt/tests/source/issue-4984/multiple_comments_within.rs b/src/tools/rustfmt/tests/source/issue-4984/multiple_comments_within.rs new file mode 100644 index 000000000..eb474a723 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-4984/multiple_comments_within.rs @@ -0,0 +1,8 @@ +#[derive( +/* ---------- Some really important comment that just had to go inside the derive --------- */ +Debug, Clone,/* Another comment */Eq, PartialEq, +)] +struct Foo { + a: i32, + b: T, +} diff --git a/src/tools/rustfmt/tests/source/issue-5011.rs b/src/tools/rustfmt/tests/source/issue-5011.rs new file mode 100644 index 000000000..b48292164 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5011.rs @@ -0,0 +1,12 @@ +pub(crate) struct ASlash( + // hello + i32 +); + +pub(crate) struct AStar( + /* hello */ + i32 +); + +pub(crate) struct BStar(/* hello */ i32); + diff --git a/src/tools/rustfmt/tests/source/issue-5023.rs b/src/tools/rustfmt/tests/source/issue-5023.rs new file mode 100644 index 000000000..ae1c723ef --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5023.rs @@ -0,0 +1,22 @@ +// rustfmt-wrap_comments: true + +/// A comment to test special unicode characters on boundaries +/// 是,是,是,是,是,是,是,是,是,是,是,是 it should break right here this goes to the next line +fn main() { + if xxx { + let xxx = xxx + .into_iter() + .filter(|(xxx, xxx)| { + if let Some(x) = Some(1) { + // xxxxxxxxxxxxxxxxxx, xxxxxxxxxxxx, xxxxxxxxxxxxxxxxxxxx xxx xxxxxxx, xxxxx xxx + // xxxxxxxxxx. xxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxx xxx xxxxxxx + // 是sdfadsdfxxxxxxxxx,sdfaxxxxxx_xxxxx_masdfaonxxx, + if false { + return true; + } + } + false + }) + .collect(); + } +} diff --git a/src/tools/rustfmt/tests/source/issue-5030.rs b/src/tools/rustfmt/tests/source/issue-5030.rs new file mode 100644 index 000000000..08ffaac7d --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5030.rs @@ -0,0 +1,22 @@ +// rustfmt-imports_granularity: Item +// rustfmt-group_imports: One + +// Confirm that attributes are duplicated to all items in the use statement +#[cfg(feature = "foo")] +use std::collections::{ + HashMap, + HashSet, +}; + +// Separate the imports below from the ones above +const A: usize = 0; + +// Copying attrs works with import grouping as well +#[cfg(feature = "foo")] +use std::collections::{ + HashMap, + HashSet, +}; + +#[cfg(feature = "spam")] +use qux::{bar, baz}; diff --git a/src/tools/rustfmt/tests/source/issue-5042/multi-line_comment_with_trailing_comma.rs b/src/tools/rustfmt/tests/source/issue-5042/multi-line_comment_with_trailing_comma.rs new file mode 100644 index 000000000..5d171f32a --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5042/multi-line_comment_with_trailing_comma.rs @@ -0,0 +1,24 @@ +fn main() { + // 5042 deals with trailing commas, not the indentation issue of these comments + // When a future PR fixes the inentation issues these test can be updated + let _ = std::ops::Add::add(10, 20 + // ... + // ..., + ); + + let _ = std::ops::Add::add(10, 20 + /* ... */ + // ..., + ); + + let _ = std::ops::Add::add(10, 20 + // ..., + // ..., + ); + + let _ = std::ops::Add::add(10, 20 + // ..., + /* ... + */, + ); +} diff --git a/src/tools/rustfmt/tests/source/issue-5042/multi-line_comment_without_trailing_comma.rs b/src/tools/rustfmt/tests/source/issue-5042/multi-line_comment_without_trailing_comma.rs new file mode 100644 index 000000000..b8a824b34 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5042/multi-line_comment_without_trailing_comma.rs @@ -0,0 +1,24 @@ +fn main() { + // 5042 deals with trailing commas, not the indentation issue of these comments + // When a future PR fixes the inentation issues these test can be updated + let _ = std::ops::Add::add(10, 20 + // ... + // ... + ); + + let _ = std::ops::Add::add(10, 20 + /* ... */ + // ... + ); + + let _ = std::ops::Add::add(10, 20 + // ... + // ... + ); + + let _ = std::ops::Add::add(10, 20 + // ... + /* ... + */ + ); +} diff --git a/src/tools/rustfmt/tests/source/issue-5042/single-line_comment_with_trailing_comma.rs b/src/tools/rustfmt/tests/source/issue-5042/single-line_comment_with_trailing_comma.rs new file mode 100644 index 000000000..bd765b7b4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5042/single-line_comment_with_trailing_comma.rs @@ -0,0 +1,9 @@ +fn main() { + let _ = std::ops::Add::add(10, 20 + // ..., + ); + + let _ = std::ops::Add::add(10, 20 + /* ... */, + ); +} diff --git a/src/tools/rustfmt/tests/source/issue-5042/single-line_comment_without_trailing_comma.rs b/src/tools/rustfmt/tests/source/issue-5042/single-line_comment_without_trailing_comma.rs new file mode 100644 index 000000000..2ed8de875 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5042/single-line_comment_without_trailing_comma.rs @@ -0,0 +1,10 @@ +fn main() { + let _ = std::ops::Add::add(10, 20 + // ... + ); + + let _ = std::ops::Add::add(10, 20 + /* ... */ + ); +} + diff --git a/src/tools/rustfmt/tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs b/src/tools/rustfmt/tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs new file mode 100644 index 000000000..09f68cae4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs @@ -0,0 +1,33 @@ +// rustfmt-wrap_comments: true + +fn main() { + { + { + { + { + { + { + { + { + { + { + { + // - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + // * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + /* - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + + /* * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/src/tools/rustfmt/tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs b/src/tools/rustfmt/tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000..75f748000 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs @@ -0,0 +1,19 @@ +// rustfmt-wrap_comments: true + +// +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/src/tools/rustfmt/tests/source/issue-5088/very_long_comment_wrap_comments_true.rs b/src/tools/rustfmt/tests/source/issue-5088/very_long_comment_wrap_comments_true.rs new file mode 100644 index 000000000..00437f002 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5088/very_long_comment_wrap_comments_true.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: true + +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/src/tools/rustfmt/tests/source/issue-510.rs b/src/tools/rustfmt/tests/source/issue-510.rs new file mode 100644 index 000000000..4c60859e6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-510.rs @@ -0,0 +1,37 @@ +impl ISizeAndMarginsComputer for AbsoluteNonReplaced { +fn solve_inline_size_constraints(&self, +block: &mut BlockFlow, +input: &ISizeConstraintInput) +-> ISizeConstraintSolution { +let (inline_start,inline_size,margin_inline_start,margin_inline_end) = +match (inline_startssssssxxxxxxsssssxxxxxxxxxssssssxxx,inline_startssssssxxxxxxsssssxxxxxxxxxssssssxxx) { +(MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => { +let margin_start = inline_start_margin.specified_or_zero(); +let margin_end = inline_end_margin.specified_or_zero(); +// Now it is the same situation as inline-start Specified and inline-end +// and inline-size Auto. +// +// Set inline-end to zero to calculate inline-size. +let inline_size = block.get_shrink_to_fit_inline_size(available_inline_size - +(margin_start + margin_end)); +(Au(0), inline_size, margin_start, margin_end) +} +}; + + let (inline_start, inline_size, margin_inline_start, margin_inline_end) = + match (inline_start, inline_end, computed_inline_size) { + (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => { + let margin_start = inline_start_margin.specified_or_zero(); + let margin_end = inline_end_margin.specified_or_zero(); + // Now it is the same situation as inline-start Specified and inline-end + // and inline-size Auto. + // + // Set inline-end to zero to calculate inline-size. + let inline_size = + block.get_shrink_to_fit_inline_size(available_inline_size - + (margin_start + margin_end)); + (Au(0), inline_size, margin_start, margin_end) + } + }; +} +} diff --git a/src/tools/rustfmt/tests/source/issue-5157/indented_itemized_markdown_blockquote.rs b/src/tools/rustfmt/tests/source/issue-5157/indented_itemized_markdown_blockquote.rs new file mode 100644 index 000000000..5c1d79a74 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5157/indented_itemized_markdown_blockquote.rs @@ -0,0 +1,4 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +fn block_quote() {} diff --git a/src/tools/rustfmt/tests/source/issue-5157/nested_itemized_markdown_blockquote.rs b/src/tools/rustfmt/tests/source/issue-5157/nested_itemized_markdown_blockquote.rs new file mode 100644 index 000000000..cf200d04e --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5157/nested_itemized_markdown_blockquote.rs @@ -0,0 +1,10 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +/// +/// > > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +/// +/// > > > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +/// +/// > > > > > > > > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +fn block_quote() {} diff --git a/src/tools/rustfmt/tests/source/issue-5157/support_itemized_markdown_blockquote.rs b/src/tools/rustfmt/tests/source/issue-5157/support_itemized_markdown_blockquote.rs new file mode 100644 index 000000000..eb436402e --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5157/support_itemized_markdown_blockquote.rs @@ -0,0 +1,4 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +fn block_quote() {} diff --git a/src/tools/rustfmt/tests/source/issue-5238/markdown_header_wrap_comments_false.rs b/src/tools/rustfmt/tests/source/issue-5238/markdown_header_wrap_comments_false.rs new file mode 100644 index 000000000..229c6e575 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5238/markdown_header_wrap_comments_false.rs @@ -0,0 +1,11 @@ +// rustfmt-wrap_comments: false + +/// no markdown header so rustfmt should wrap this comment when `format_code_in_doc_comments = true` and `wrap_comments = true` +fn not_documented_with_markdown_header() { + // This is just a normal inline comment so rustfmt should wrap this comment when `wrap_comments = true` +} + +/// # We're using a markdown header here so rustfmt should refuse to wrap this comment in all circumstances +fn documented_with_markdown_header() { + // # We're using a markdown header in an inline comment. rustfmt should be able to wrap this comment when `wrap_comments = true` +} diff --git a/src/tools/rustfmt/tests/source/issue-5238/markdown_header_wrap_comments_true.rs b/src/tools/rustfmt/tests/source/issue-5238/markdown_header_wrap_comments_true.rs new file mode 100644 index 000000000..c547ff35c --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5238/markdown_header_wrap_comments_true.rs @@ -0,0 +1,11 @@ +// rustfmt-wrap_comments: true + +/// no markdown header so rustfmt should wrap this comment when `format_code_in_doc_comments = true` and `wrap_comments = true` +fn not_documented_with_markdown_header() { + // This is just a normal inline comment so rustfmt should wrap this comment when `wrap_comments = true` +} + +/// # We're using a markdown header here so rustfmt should refuse to wrap this comment in all circumstances +fn documented_with_markdown_header() { + // # We're using a markdown header in an inline comment. rustfmt should be able to wrap this comment when `wrap_comments = true` +} diff --git a/src/tools/rustfmt/tests/source/issue-5260.rs b/src/tools/rustfmt/tests/source/issue-5260.rs new file mode 100644 index 000000000..c06068172 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5260.rs @@ -0,0 +1,14 @@ +// rustfmt-wrap_comments: true + +/// [MyType](VeryLongPathToMyType::NoLineBreak::Here::Okay::ThatWouldBeNice::Thanks) +fn documented_with_longtype() { + // # We're using a long type link, rustfmt should not break line + // on the type when `wrap_comments = true` +} + +/// VeryLongPathToMyType::JustMyType::But::VeryVery::Long::NoLineBreak::Here::Okay::ThatWouldBeNice::Thanks +fn documented_with_verylongtype() { + // # We're using a long type link, rustfmt should not break line + // on the type when `wrap_comments = true` +} + diff --git a/src/tools/rustfmt/tests/source/issue-5270/merge_derives_true.rs b/src/tools/rustfmt/tests/source/issue-5270/merge_derives_true.rs new file mode 100644 index 000000000..b31bbf095 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-5270/merge_derives_true.rs @@ -0,0 +1,62 @@ +// rustfmt-merge_derives:true + +#[rustfmt::skip::attributes(derive)] +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct DoNotMergeDerives { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[rustfmt::skip::attributes(derive)] +#[derive(Clone)] +struct DoNotMergeDerivesSkipInMiddle { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +#[rustfmt::skip::attributes(derive)] +struct DoNotMergeDerivesSkipAtEnd { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct MergeDerives { + field: String, +} + +mod inner_attribute_derive_skip { + #![rustfmt::skip::attributes(derive)] + + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +#[rustfmt::skip::attributes(derive)] +mod outer_attribute_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +mod no_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct MergeDerives { + field: String, + } +} diff --git a/src/tools/rustfmt/tests/source/issue-539.rs b/src/tools/rustfmt/tests/source/issue-539.rs new file mode 100644 index 000000000..d70682e3b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-539.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true +/* + FIXME (#3300): Should allow items to be anonymous. Right now + we just use dummy names for anon items. + */ diff --git a/src/tools/rustfmt/tests/source/issue-683.rs b/src/tools/rustfmt/tests/source/issue-683.rs new file mode 100644 index 000000000..fd99015ea --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-683.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true +/* + * FIXME (#3300): Should allow items to be anonymous. Right now + * we just use dummy names for anon items. + */ diff --git a/src/tools/rustfmt/tests/source/issue-811.rs b/src/tools/rustfmt/tests/source/issue-811.rs new file mode 100644 index 000000000..b7a89b5d0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-811.rs @@ -0,0 +1,19 @@ +trait FooTrait<T>: Sized { + type Bar: BarTrait<T>; +} + +trait BarTrait<T>: Sized { + type Baz; + fn foo(); +} + +type Foo<T: FooTrait> = <<T as FooTrait<U>>::Bar as BarTrait<U>>::Baz; +type Bar<T: BarTrait> = <T as BarTrait<U>>::Baz; + +fn some_func<T: FooTrait<U>, U>() { + <<T as FooTrait<U>>::Bar as BarTrait<U>>::foo(); +} + +fn some_func<T: BarTrait<U>>() { + <T as BarTrait<U>>::foo(); +} diff --git a/src/tools/rustfmt/tests/source/issue-850.rs b/src/tools/rustfmt/tests/source/issue-850.rs new file mode 100644 index 000000000..c939716a6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-850.rs @@ -0,0 +1 @@ +const unsafe fn x() {} diff --git a/src/tools/rustfmt/tests/source/issue-855.rs b/src/tools/rustfmt/tests/source/issue-855.rs new file mode 100644 index 000000000..8f33fa685 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-855.rs @@ -0,0 +1,20 @@ +fn main() { + 'running: loop { + for event in event_pump.poll_iter() { + match event { + Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => break 'running, + } + } + } +} + +fn main2() { + 'running: loop { + for event in event_pump.poll_iter() { + match event { + Event::Quit {..} | + Event::KeyDownXXXXXXXXXXXXX { keycode: Some(Keycode::Escape), .. } => break 'running, + } + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-913.rs b/src/tools/rustfmt/tests/source/issue-913.rs new file mode 100644 index 000000000..25b9d42fd --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-913.rs @@ -0,0 +1,20 @@ +mod client { + impl Client { + fn test(self) -> Result<()> { + let next_state = match self.state { + State::V5(v5::State::Command(v5::coand::State::WriteVersion(ref mut response))) => { + let x = reformat . meeee() ; + } + }; + + let next_state = match self.state { + State::V5(v5::State::Command(v5::comand::State::WriteVersion(ref mut response))) => { + // The pattern cannot be formatted in a way that the match stays + // within the column limit. The rewrite should therefore be + // skipped. + let x = dont . reformat . meeee(); + } + }; + } + } +} diff --git a/src/tools/rustfmt/tests/source/issue-945.rs b/src/tools/rustfmt/tests/source/issue-945.rs new file mode 100644 index 000000000..37d703c46 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-945.rs @@ -0,0 +1,5 @@ +impl Bar { default const unsafe fn foo() { "hi" } } + +impl Baz { default unsafe extern "C" fn foo() { "hi" } } + +impl Foo for Bar { default fn foo() { "hi" } } diff --git a/src/tools/rustfmt/tests/source/issue-977.rs b/src/tools/rustfmt/tests/source/issue-977.rs new file mode 100644 index 000000000..fe16387b7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-977.rs @@ -0,0 +1,7 @@ +// rustfmt-normalize_comments: true + +trait NameC { /* comment */ } +struct FooC { /* comment */ } +enum MooC { /* comment */ } +mod BarC { /* comment */ } +extern { /* comment */ } diff --git a/src/tools/rustfmt/tests/source/issue_3839.rs b/src/tools/rustfmt/tests/source/issue_3839.rs new file mode 100644 index 000000000..3933d31ee --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_3839.rs @@ -0,0 +1,8 @@ +struct Foo { + a: i32, +/* +asd +*/ + // foo +b: i32, +} diff --git a/src/tools/rustfmt/tests/source/issue_3844.rs b/src/tools/rustfmt/tests/source/issue_3844.rs new file mode 100644 index 000000000..15441b2b0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_3844.rs @@ -0,0 +1,3 @@ +fn main() { +|| {{}}; +} diff --git a/src/tools/rustfmt/tests/source/issue_3853.rs b/src/tools/rustfmt/tests/source/issue_3853.rs new file mode 100644 index 000000000..c41309bc7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_3853.rs @@ -0,0 +1,52 @@ +fn by_ref_with_block_before_ident() { +if let Some(ref /*def*/ state)= foo{ + println!( + "asdfasdfasdf"); } +} + +fn mut_block_before_ident() { +if let Some(mut /*def*/ state ) =foo{ + println!( + "123" ); } +} + +fn ref_and_mut_blocks_before_ident() { +if let Some(ref /*abc*/ + mut /*def*/ state ) = foo { + println!( + "deefefefefefwea" ); } +} + +fn sub_pattern() { + let foo @ /*foo*/ +bar(f) = 42; +} + +fn no_prefix_block_before_ident() { +if let Some( + /*def*/ state ) = foo { + println!( + "129387123123" ); } +} + +fn issue_3853() { +if let Some(ref /*mut*/ state) = foo { + } +} + +fn double_slash_comment_between_lhs_and_rhs() { + if let Some(e) = + // self.foo.bar(e, tx) + packet.transaction.state.committed + { + // body + println!( + "a2304712836123"); + } +} + +fn block_comment_between_lhs_and_rhs() { +if let Some(ref /*def*/ mut /*abc*/ state)= /*abc*/foo{ + println!( + "asdfasdfasdf"); } +} diff --git a/src/tools/rustfmt/tests/source/issue_3868.rs b/src/tools/rustfmt/tests/source/issue_3868.rs new file mode 100644 index 000000000..6c46c3c9e --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_3868.rs @@ -0,0 +1,13 @@ +fn foo() { + ; +} + +fn bar() { + for _ in 0..1 { + ; + } +} + +fn baz() { + (); + }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_4032.rs b/src/tools/rustfmt/tests/source/issue_4032.rs new file mode 100644 index 000000000..11ded074c --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4032.rs @@ -0,0 +1,4 @@ +fn a1(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] a: u8) {} +fn b1(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] bb: u8) {} +fn a2(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] a: u8) {} +fn b2(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] bb: u8) {} diff --git a/src/tools/rustfmt/tests/source/issue_4057.rs b/src/tools/rustfmt/tests/source/issue_4057.rs new file mode 100644 index 000000000..7cd80734b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4057.rs @@ -0,0 +1,15 @@ +// rustfmt-format_code_in_doc_comments: true + +/// ``` +/// # #[rustversion::since(1.36)] +/// # fn dox() { +/// # use std::pin::Pin; +/// # type Projection<'a> = &'a (); +/// # type ProjectionRef<'a> = &'a (); +/// # trait Dox { +/// fn project_ex (self: Pin<&mut Self>) -> Projection<'_>; +/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>; +/// # } +/// # } +/// ``` +struct Foo; diff --git a/src/tools/rustfmt/tests/source/issue_4086.rs b/src/tools/rustfmt/tests/source/issue_4086.rs new file mode 100644 index 000000000..ffa6442e9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4086.rs @@ -0,0 +1,2 @@ +#[cfg(any())] +extern "C++" {} diff --git a/src/tools/rustfmt/tests/source/issue_4257.rs b/src/tools/rustfmt/tests/source/issue_4257.rs new file mode 100644 index 000000000..2b887fadb --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4257.rs @@ -0,0 +1,13 @@ +#![feature(generic_associated_types)] +#![allow(incomplete_features)] + +trait Trait<T> { + type Type<'a> where T: 'a; + fn foo(x: &T) -> Self::Type<'_>; +} +impl<T> Trait<T> for () { + type Type<'a> where T: 'a = &'a T; + fn foo(x: &T) -> Self::Type<'_> { + x + } +} diff --git a/src/tools/rustfmt/tests/source/issue_4322.rs b/src/tools/rustfmt/tests/source/issue_4322.rs new file mode 100644 index 000000000..b28cc7cdd --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4322.rs @@ -0,0 +1,3 @@ +trait Bar { + type X<'a> where Self: 'a; +} diff --git a/src/tools/rustfmt/tests/source/issue_4374.rs b/src/tools/rustfmt/tests/source/issue_4374.rs new file mode 100644 index 000000000..2a45a022e --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4374.rs @@ -0,0 +1,13 @@ +fn a<F>(_f: F) -> () +where + F: FnOnce() -> (), +{ +} +fn main() { + a(|| { + #[allow(irrefutable_let_patterns)] + while let _ = 0 { + break; + } + }); +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_4475.rs b/src/tools/rustfmt/tests/source/issue_4475.rs new file mode 100644 index 000000000..241dc91d7 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4475.rs @@ -0,0 +1,27 @@ +fn main() { + #[cfg(debug_assertions)] + { println!("DEBUG"); } +} + +fn main() { + #[cfg(feature = "foo")] + { + /* + let foo = 0 + */ + } +} + +fn main() { + #[cfg(feature = "foo")] + { /* let foo = 0; */ } +} + +fn main() { + #[foo] + #[bar] + #[baz] + { + // let foo = 0; + } +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_4528.rs b/src/tools/rustfmt/tests/source/issue_4528.rs new file mode 100644 index 000000000..85f6d8c03 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4528.rs @@ -0,0 +1,8 @@ +#![allow(clippy::no_effect)] + +extern "C" { + // N.B., mutability can be easily incorrect in FFI calls -- as + // in C, the default is mutable pointers. + fn ffi(c: *mut u8); + fn int_ffi(c: *mut i32); +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_4579.rs b/src/tools/rustfmt/tests/source/issue_4579.rs new file mode 100644 index 000000000..73f345233 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4579.rs @@ -0,0 +1,15 @@ +// rustfmt-hard_tabs: true + +#[macro_export] +macro_rules! main { + () => { + #[spirv(fragment)] + pub fn main_fs( + mut out_color: ::spirv_std::storage_class::Output<Vec4>, + #[spirv(descriptor_set = 1)]iChannelResolution: ::spirv_std::storage_class::UniformConstant< + [::spirv_std::glam::Vec3A; 4], + >, + ) { + } + }; +} diff --git a/src/tools/rustfmt/tests/source/issue_4584.rs b/src/tools/rustfmt/tests/source/issue_4584.rs new file mode 100644 index 000000000..695c55905 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4584.rs @@ -0,0 +1,19 @@ +// rustfmt-indent_style: Visual + +#[derive(Debug,)] +pub enum Case { + Upper, + Lower +} + +#[derive(Debug, Clone, PartialEq, Eq,)] +pub enum Case { + Upper, + Lower +} + +// NB - This formatting looks potentially off the desired state, but is +// consistent with current behavior. Included here to provide a line wrapped +// derive case with the changes applied to resolve issue #4584 +#[derive(Add, Sub, Mul, Div, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Serialize, Mul,)] +struct Foo {}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_4636.rs b/src/tools/rustfmt/tests/source/issue_4636.rs new file mode 100644 index 000000000..ea7079f6c --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4636.rs @@ -0,0 +1,13 @@ +pub trait PrettyPrinter<'tcx>: + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > + fmt::Write + { + // + }
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_4675.rs b/src/tools/rustfmt/tests/source/issue_4675.rs new file mode 100644 index 000000000..66613eed0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4675.rs @@ -0,0 +1,8 @@ +macro_rules! foo { + ($s:ident ( $p:pat )) => { + Foo { + name: Name::$s($p), + .. + } + }; +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_4823.rs b/src/tools/rustfmt/tests/source/issue_4823.rs new file mode 100644 index 000000000..a008dd3d8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4823.rs @@ -0,0 +1,5 @@ +macro_rules! m { +() => { +type Type; +}; +} diff --git a/src/tools/rustfmt/tests/source/issue_4854.rs b/src/tools/rustfmt/tests/source/issue_4854.rs new file mode 100644 index 000000000..35d6e21af --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4854.rs @@ -0,0 +1,113 @@ +struct Struct { + // Multiline comment + // should be formatted + // properly. +} + +struct Struct2 { + // This formatting +// Should be changed +} + +struct Struct3( + // This + // is + // correct +); + +struct Struct4( + // This +// is +// not +// correct +); + +struct Struct5 { + /* + Comment block + with many lines. + */ +} + +struct Struct6( + /* + Comment block + with many lines. + */ +); + +struct Struct7 { + /* +Invalid +format +*/ +} + +struct Struct8( + /* +Invalid +format +*/ +); + +struct Struct9 { /* bar */ } + +struct Struct10 { /* bar +baz +*/ } + +mod module { + struct Struct { + // Multiline comment + // should be formatted + // properly. + } + + struct Struct2 { + // This formatting +// Should be changed + } + + struct Struct3( + // This + // is + // correct + ); + + struct Struct4( + // This + // is + // not +// correct + ); + + struct Struct5 { + /* + Comment block + with many lines. + */ + } + + struct Struct6( + /* + Comment block + with many lines. + */ + ); + + struct Struct7 { + /* +Invalid +format +*/ + } + + struct Struct8( + /* +Invalid +format +*/ + ); + + struct Struct9 { /* bar */ } +} diff --git a/src/tools/rustfmt/tests/source/issue_4911.rs b/src/tools/rustfmt/tests/source/issue_4911.rs new file mode 100644 index 000000000..21ef6c6c4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4911.rs @@ -0,0 +1,6 @@ +#![feature(generic_associated_types)] +#![feature(min_type_alias_impl_trait)] + +impl SomeTrait for SomeType { + type SomeGAT<'a> where Self: 'a = impl SomeOtherTrait; +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_4943.rs b/src/tools/rustfmt/tests/source/issue_4943.rs new file mode 100644 index 000000000..0793b7b4f --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4943.rs @@ -0,0 +1,9 @@ +#![feature(generic_associated_types)] + +impl SomeStruct { + fn process<T>(v: T) -> <Self as GAT>::R<T> + where Self: GAT<R<T> = T> + { + SomeStruct::do_something(v) + } +} diff --git a/src/tools/rustfmt/tests/source/issue_4954.rs b/src/tools/rustfmt/tests/source/issue_4954.rs new file mode 100644 index 000000000..8011c601b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4954.rs @@ -0,0 +1,5 @@ +trait Foo { + type Arg<'a>; +} + +struct Bar<T>(T) where for<'a> T: Foo<Arg<'a> = ()>; diff --git a/src/tools/rustfmt/tests/source/issue_4963.rs b/src/tools/rustfmt/tests/source/issue_4963.rs new file mode 100644 index 000000000..32e1f6cd4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_4963.rs @@ -0,0 +1,5 @@ +mod test { + extern "C" {fn test();} +} + +extern "C" {fn test();}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_5027.rs b/src/tools/rustfmt/tests/source/issue_5027.rs new file mode 100644 index 000000000..67beeb23b --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_5027.rs @@ -0,0 +1,7 @@ +// rustfmt-version: Two + +pub type Iter<'a, D> = impl DoubleEndedIterator<Item = (SomethingSomethingSomethingLongType<D>)>+ ExactSizeIterator+ 'a; + +trait FOo {pub type Iter<'a, D> = impl DoubleEndedIterator<Item = (SomethingSomethingSomethingLongType<D>)>+ ExactSizeIterator+ 'a;} + +impl Bar {pub type Iter<'a, D> = impl DoubleEndedIterator<Item = (SomethingSomethingSomethingLongType<D>)>+ ExactSizeIterator+ 'a;}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/issue_5086.rs b/src/tools/rustfmt/tests/source/issue_5086.rs new file mode 100644 index 000000000..1644c9d2c --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue_5086.rs @@ -0,0 +1,2 @@ +#[cfg(any())] + type Type : Bound ;
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/item-brace-style-always-next-line.rs b/src/tools/rustfmt/tests/source/item-brace-style-always-next-line.rs new file mode 100644 index 000000000..0fb640512 --- /dev/null +++ b/src/tools/rustfmt/tests/source/item-brace-style-always-next-line.rs @@ -0,0 +1,64 @@ +// rustfmt-brace_style: AlwaysNextLine + +mod M { + enum A { + A, + } + + struct B { + b: i32, + } + + // For empty enums and structs, the brace remains on the same line. + enum C {} + + struct D {} + + enum A<T> where T: Copy { + A, + } + + struct B<T> where T: Copy { + b: i32, + } + + // For empty enums and structs, the brace remains on the same line. + enum C<T> where T: Copy {} + + struct D<T> where T: Copy {} +} + + +fn function() +{ + +} + +trait Trait +{ + +} + +impl<T> Trait for T +{ + +} + +trait Trait2<T> +where + T: Copy + Display + Write + Read + FromStr, {} + +trait Trait3<T> +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, {} diff --git a/src/tools/rustfmt/tests/source/item-brace-style-prefer-same-line.rs b/src/tools/rustfmt/tests/source/item-brace-style-prefer-same-line.rs new file mode 100644 index 000000000..dff89b8b6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/item-brace-style-prefer-same-line.rs @@ -0,0 +1,29 @@ +// rustfmt-brace_style: PreferSameLine + +mod M { + enum A + { + A, + } + + struct B + { + b: i32, + } + + enum C {} + + struct D {} + + enum A<T> where T: Copy { + A, + } + + struct B<T> where T: Copy { + b: i32, + } + + enum C<T> where T: Copy {} + + struct D<T> where T: Copy {} +} diff --git a/src/tools/rustfmt/tests/source/item-brace-style-same-line-where.rs b/src/tools/rustfmt/tests/source/item-brace-style-same-line-where.rs new file mode 100644 index 000000000..1d034089f --- /dev/null +++ b/src/tools/rustfmt/tests/source/item-brace-style-same-line-where.rs @@ -0,0 +1,29 @@ +mod M { + enum A + { + A, + } + + struct B + { + b: i32, + } + + // For empty enums and structs, the brace remains on the same line. + enum C {} + + struct D {} + + enum A<T> where T: Copy { + A, + } + + struct B<T> where T: Copy { + b: i32, + } + + // For empty enums and structs, the brace remains on the same line. + enum C<T> where T: Copy {} + + struct D<T> where T: Copy {} +} diff --git a/src/tools/rustfmt/tests/source/itemized-blocks/no_wrap.rs b/src/tools/rustfmt/tests/source/itemized-blocks/no_wrap.rs new file mode 100644 index 000000000..a7b6a10a0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/itemized-blocks/no_wrap.rs @@ -0,0 +1,47 @@ +// rustfmt-normalize_comments: true +// rustfmt-format_code_in_doc_comments: true + +//! This is a list: +//! * Outer +//! * Outer +//! * Inner +//! * Inner with lots of text so that it could be reformatted something something something lots of text so that it could be reformatted something something something +//! +//! This example shows how to configure fern to output really nicely colored logs +//! - when the log level is error, the whole line is red +//! - when the log level is warn, the whole line is yellow +//! - when the log level is info, the level name is green and the rest of the line is white +//! - when the log level is debug, the whole line is white +//! - when the log level is trace, the whole line is gray ("bright black") + +/// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote +/// theater, i.e., as passed to [`Theater::send`] on the remote actor: +/// * `from` is the sending (remote) [`ActorId`], as reported by the remote theater by theater-specific means +/// * `to` is the receiving (local) [`ActorId`], as requested by the remote theater +/// * `tag` is a tag that identifies the message type +/// * `msg` is the (serialized) message +/// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote +/// theater, i.e., as passed to [`Theater::send`] on the remote actor +fn func1() {} + +/// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote +/// theater, i.e., as passed to [`Theater::send`] on the remote actor: +/// * `from` is the sending (remote) [`ActorId`], as reported by the remote theater by theater-specific means +/// * `to` is the receiving (local) [`ActorId`], as requested by the remote theater +/// * `tag` is a tag that identifies the message type +/// * `msg` is the (serialized) message +/// ``` +/// let x = 42; +/// ``` +fn func2() {} + +/// Look: +/// +/// ``` +/// let x = 42; +/// ``` +/// * `from` is the sending (remote) [`ActorId`], as reported by the remote theater by theater-specific means +/// * `to` is the receiving (local) [`ActorId`], as requested by the remote theater +/// * `tag` is a tag that identifies the message type +/// * `msg` is the (serialized) message +fn func3() {} diff --git a/src/tools/rustfmt/tests/source/itemized-blocks/rewrite_fail.rs b/src/tools/rustfmt/tests/source/itemized-blocks/rewrite_fail.rs new file mode 100644 index 000000000..f99c2cc5f --- /dev/null +++ b/src/tools/rustfmt/tests/source/itemized-blocks/rewrite_fail.rs @@ -0,0 +1,11 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 50 + +// This example shows how to configure fern to output really nicely colored logs +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +// - when the log level is info, the level name is green and the rest of the line is white +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +fn func1() {} diff --git a/src/tools/rustfmt/tests/source/itemized-blocks/urls.rs b/src/tools/rustfmt/tests/source/itemized-blocks/urls.rs new file mode 100644 index 000000000..2eaaafbbc --- /dev/null +++ b/src/tools/rustfmt/tests/source/itemized-blocks/urls.rs @@ -0,0 +1,22 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 79 + +//! CMSIS: Cortex Microcontroller Software Interface Standard +//! +//! The version 5 of the standard can be found at: +//! +//! http://arm-software.github.io/CMSIS_5/Core/html/index.html +//! +//! The API reference of the standard can be found at: +//! +//! - example -- http://example.org -- something something something something something something +//! - something something something something something something more -- http://example.org +//! - http://example.org/something/something/something/something/something/something and the rest +//! - Core function access -- http://arm-software.github.io/CMSIS_5/Core/html/group__Core__Register__gr.html +//! - Intrinsic functions for CPU instructions -- http://arm-software.github.io/CMSIS_5/Core/html/group__intrinsic__CPU__gr.html +//! - Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vestibulum sem lacus, commodo vitae. +//! +//! The reference C implementation used as the base of this Rust port can be +//! found at +//! +//! https://github.com/ARM-software/CMSIS_5/blob/5.3.0/CMSIS/Core/Include/cmsis_gcc.h diff --git a/src/tools/rustfmt/tests/source/itemized-blocks/wrap.rs b/src/tools/rustfmt/tests/source/itemized-blocks/wrap.rs new file mode 100644 index 000000000..955cc698b --- /dev/null +++ b/src/tools/rustfmt/tests/source/itemized-blocks/wrap.rs @@ -0,0 +1,55 @@ +// rustfmt-wrap_comments: true +// rustfmt-format_code_in_doc_comments: true +// rustfmt-max_width: 50 + +//! This is a list: +//! * Outer +//! * Outer +//! * Inner +//! * Inner with lots of text so that it could be reformatted something something something lots of text so that it could be reformatted something something something +//! +//! This example shows how to configure fern to output really nicely colored logs +//! - when the log level is error, the whole line is red +//! - when the log level is warn, the whole line is yellow +//! - when the log level is info, the level name is green and the rest of the line is white +//! - when the log level is debug, the whole line is white +//! - when the log level is trace, the whole line is gray ("bright black") + +// This example shows how to configure fern to output really nicely colored logs +// - when the log level is error, the whole line is red +// - when the log level is warn, the whole line is yellow +// - when the log level is info, the level name is green and the rest of the line is white +// - when the log level is debug, the whole line is white +// - when the log level is trace, the whole line is gray ("bright black") + +/// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote +/// theater, i.e., as passed to [`Theater::send`] on the remote actor: +/// * `from` is the sending (remote) [`ActorId`], as reported by the remote theater by theater-specific means +/// * `to` is the receiving (local) [`ActorId`], as requested by the remote theater +/// * `tag` is a tag that identifies the message type +/// * `msg` is the (serialized) message +/// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote +/// theater, i.e., as passed to [`Theater::send`] on the remote actor +fn func1() {} + +/// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote +/// theater, i.e., as passed to [`Theater::send`] on the remote actor: +/// * `from` is the sending (remote) [`ActorId`], as reported by the remote theater by theater-specific means +/// * `to` is the receiving (local) [`ActorId`], as requested by the remote theater +/// * `tag` is a tag that identifies the message type +/// * `msg` is the (serialized) message +/// ``` +/// let x = 42; +/// ``` +fn func2() {} + +/// Look: +/// +/// ``` +/// let x = 42; +/// ``` +/// * `from` is the sending (remote) [`ActorId`], as reported by the remote theater by theater-specific means +/// * `to` is the receiving (local) [`ActorId`], as requested by the remote theater +/// * `tag` is a tag that identifies the message type +/// * `msg` is the (serialized) message +fn func3() {} diff --git a/src/tools/rustfmt/tests/source/label_break.rs b/src/tools/rustfmt/tests/source/label_break.rs new file mode 100644 index 000000000..2c79fd35e --- /dev/null +++ b/src/tools/rustfmt/tests/source/label_break.rs @@ -0,0 +1,28 @@ +// format with label break value. +fn main() { + +'empty_block: {} + +'block: { + do_thing(); + if condition_not_met() { + break 'block; + } + do_next_thing(); + if condition_not_met() { + break 'block; + } + do_last_thing(); +} + +let result = 'block: { + if foo() { + // comment + break 'block 1; + } + if bar() { /* comment */ + break 'block 2; + } + 3 +}; +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/large-block.rs b/src/tools/rustfmt/tests/source/large-block.rs new file mode 100644 index 000000000..09e9169f3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/large-block.rs @@ -0,0 +1,5 @@ +fn issue1351() { + std_fmt_Arguments_new_v1_std_rt_begin_panic_fmt_sdfasfasdfasdf({ + static __STATIC_FMTSTR: &'static [&'static str] = &[]; + }); +} diff --git a/src/tools/rustfmt/tests/source/large_vec.rs b/src/tools/rustfmt/tests/source/large_vec.rs new file mode 100644 index 000000000..34d5bf399 --- /dev/null +++ b/src/tools/rustfmt/tests/source/large_vec.rs @@ -0,0 +1,29 @@ +// See #1470. + +impl Environment { + pub fn new_root() -> Rc<RefCell<Environment>> { + let mut env = Environment::new(); + let builtin_functions = &[("println", + Function::NativeVoid(CallSign { + num_params: 0, + variadic: true, + param_types: vec![], + }, + native_println)), + ("run_http_server", + Function::NativeVoid(CallSign { + num_params: 1, + variadic: false, + param_types: + vec![Some(ConstraintType::Function)], + }, + native_run_http_server)), + ("len", + Function::NativeReturning(CallSign { + num_params: 1, + variadic: false, + param_types: vec![None], + }, + native_len))]; + } +} diff --git a/src/tools/rustfmt/tests/source/lazy_static.rs b/src/tools/rustfmt/tests/source/lazy_static.rs new file mode 100644 index 000000000..38fefbcbe --- /dev/null +++ b/src/tools/rustfmt/tests/source/lazy_static.rs @@ -0,0 +1,45 @@ +// Format `lazy_static!`. + +lazy_static! { +static ref CONFIG_NAME_REGEX: regex::Regex = +regex::Regex::new(r"^## `([^`]+)`").expect("Failed creating configuration pattern"); +static ref CONFIG_VALUE_REGEX: regex::Regex = regex::Regex::new(r#"^#### `"?([^`"]+)"?`"#) +.expect("Failed creating configuration value pattern"); +} + +// We need to be able to format `lazy_static!` without known syntax. +lazy_static!( + xxx, +yyyy , + zzzzz +); + +lazy_static!{ +} + +// #2354 +lazy_static ! { +pub static ref Sbase64_encode_string : :: lisp :: LispSubrRef = { +let subr = :: remacs_sys :: Lisp_Subr { +header : :: remacs_sys :: Lisp_Vectorlike_Header { +size : ( +( :: remacs_sys :: PseudovecType :: PVEC_SUBR as :: libc :: ptrdiff_t ) << :: +remacs_sys :: PSEUDOVECTOR_AREA_BITS ) , } , function : self :: +Fbase64_encode_string as * const :: libc :: c_void , min_args : 1i16 , +max_args : 2i16 , symbol_name : ( b"base64-encode-string\x00" ) . as_ptr ( ) +as * const :: libc :: c_char , intspec : :: std :: ptr :: null ( ) , doc : :: +std :: ptr :: null ( ) , lang : :: remacs_sys :: Lisp_Subr_Lang_Rust , } ; +unsafe { +let ptr = :: remacs_sys :: xmalloc ( +:: std :: mem :: size_of :: < :: remacs_sys :: Lisp_Subr > ( ) ) as * mut :: +remacs_sys :: Lisp_Subr ; :: std :: ptr :: copy_nonoverlapping ( +& subr , ptr , 1 ) ; :: std :: mem :: forget ( subr ) ; :: lisp :: ExternalPtr +:: new ( ptr ) } } ; } + + +lazy_static! { +static ref FOO: HashMap<String, +(&'static str, +fn(Foo) -> Result<Box<Bar>, Either<FooError, BarError>> +),> = HashMap::new(); +} diff --git a/src/tools/rustfmt/tests/source/let_else.rs b/src/tools/rustfmt/tests/source/let_else.rs new file mode 100644 index 000000000..a6e816fb5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/let_else.rs @@ -0,0 +1,3 @@ +fn main() { + let Some(1) = Some(1) else { return }; +} diff --git a/src/tools/rustfmt/tests/source/long-fn-1/version_one.rs b/src/tools/rustfmt/tests/source/long-fn-1/version_one.rs new file mode 100644 index 000000000..d6832c2af --- /dev/null +++ b/src/tools/rustfmt/tests/source/long-fn-1/version_one.rs @@ -0,0 +1,21 @@ +// rustfmt-version: One +// Tests that a function which is almost short enough, but not quite, gets +// formatted correctly. + +impl Foo { + fn some_input(&mut self, input: Input, input_path: Option<PathBuf>, ) -> (Input, Option<PathBuf>) {} + + fn some_inpu(&mut self, input: Input, input_path: Option<PathBuf>) -> (Input, Option<PathBuf>) {} +} + +// #1843 +#[allow(non_snake_case)] +pub extern "C" fn Java_com_exonum_binding_storage_indices_ValueSetIndexProxy_nativeContainsByHash() -> bool { + false +} + +// #3009 +impl Something { + fn my_function_name_is_way_to_long_but_used_as_a_case_study_or_an_example_its_fine( +) -> Result< (), String > {} +} diff --git a/src/tools/rustfmt/tests/source/long-fn-1/version_two.rs b/src/tools/rustfmt/tests/source/long-fn-1/version_two.rs new file mode 100644 index 000000000..f402a26e8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/long-fn-1/version_two.rs @@ -0,0 +1,21 @@ +// rustfmt-version: Two +// Tests that a function which is almost short enough, but not quite, gets +// formatted correctly. + +impl Foo { + fn some_input(&mut self, input: Input, input_path: Option<PathBuf>, ) -> (Input, Option<PathBuf>) {} + + fn some_inpu(&mut self, input: Input, input_path: Option<PathBuf>) -> (Input, Option<PathBuf>) {} +} + +// #1843 +#[allow(non_snake_case)] +pub extern "C" fn Java_com_exonum_binding_storage_indices_ValueSetIndexProxy_nativeContainsByHash() -> bool { + false +} + +// #3009 +impl Something { + fn my_function_name_is_way_to_long_but_used_as_a_case_study_or_an_example_its_fine( +) -> Result< (), String > {} +} diff --git a/src/tools/rustfmt/tests/source/long-match-arms-brace-newline.rs b/src/tools/rustfmt/tests/source/long-match-arms-brace-newline.rs new file mode 100644 index 000000000..927ada0ff --- /dev/null +++ b/src/tools/rustfmt/tests/source/long-match-arms-brace-newline.rs @@ -0,0 +1,15 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 80 +// rustfmt-control_brace_style: AlwaysNextLine + +fn main() { + match x { + aaaaaaaa::Bbbbb::Ccccccccccccc(_, Some(ref x)) if x == + "aaaaaaaaaaa \ + aaaaaaa \ + aaaaaa" => { + Ok(()) + } + _ => Err(x), + } +} diff --git a/src/tools/rustfmt/tests/source/long-use-statement-issue-3154.rs b/src/tools/rustfmt/tests/source/long-use-statement-issue-3154.rs new file mode 100644 index 000000000..339382b5b --- /dev/null +++ b/src/tools/rustfmt/tests/source/long-use-statement-issue-3154.rs @@ -0,0 +1,3 @@ +// rustfmt-reorder_imports: false + +pub use self :: super :: super :: super :: root::mozilla::detail::StringClassFlags as nsTStringRepr_ClassFlags ; diff --git a/src/tools/rustfmt/tests/source/long_field_access.rs b/src/tools/rustfmt/tests/source/long_field_access.rs new file mode 100644 index 000000000..7aa626221 --- /dev/null +++ b/src/tools/rustfmt/tests/source/long_field_access.rs @@ -0,0 +1,3 @@ +fn f() { + block_flow.base.stacking_relative_position_of_display_port = self.base.stacking_relative_position_of_display_port; +} diff --git a/src/tools/rustfmt/tests/source/loop.rs b/src/tools/rustfmt/tests/source/loop.rs new file mode 100644 index 000000000..6e92cdc6c --- /dev/null +++ b/src/tools/rustfmt/tests/source/loop.rs @@ -0,0 +1,29 @@ + +fn main() { + loop + { return some_val;} + +let x = loop { do_forever(); }; + + 'label : loop { + // Just comments + } + + 'a: while loooooooooooooooooooooooooooooooooong_variable_name + another_value > some_other_value{} + + while aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb { + } + + while aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {} + + 'b: for xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx in some_iter(arg1, arg2) { + // do smth + } + + while let Some(i) = x.find('s') + { + x.update(); + continue; + continue 'foo; + } +} diff --git a/src/tools/rustfmt/tests/source/macro_not_expr.rs b/src/tools/rustfmt/tests/source/macro_not_expr.rs new file mode 100644 index 000000000..d8de4dce3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/macro_not_expr.rs @@ -0,0 +1,7 @@ +macro_rules! test { + ($($t:tt)*) => {} +} + +fn main() { + test!( a : B => c d ); +} diff --git a/src/tools/rustfmt/tests/source/macro_rules.rs b/src/tools/rustfmt/tests/source/macro_rules.rs new file mode 100644 index 000000000..5aaca0c83 --- /dev/null +++ b/src/tools/rustfmt/tests/source/macro_rules.rs @@ -0,0 +1,301 @@ +// rustfmt-format_macro_matchers: true + +macro_rules! m { + () => (); + ( $ x : ident ) => (); + ( $ m1 : ident , $ m2 : ident , $ x : ident ) => (); + ( $($beginning:ident),*;$middle:ident;$($end:ident),* ) => (); + ( $($beginning: ident),*; $middle: ident; $($end: ident),*; $($beginning: ident),*; $middle: ident; $($end: ident),* ) => {}; + ( $ name : ident ( $ ( $ dol : tt $ var : ident ) * ) $ ( $ body : tt ) * ) => (); + ( $( $ i : ident : $ ty : ty , $def : expr , $stb : expr , $ ( $ dstring : tt ) , + ) ; + $ ( ; ) * + $( $ i : ident : $ ty : ty , $def : expr , $stb : expr , $ ( $ dstring : tt ) , + ) ; + $ ( ; ) * + ) => {}; + ( $foo: tt foo [$ attr : meta] $name: ident ) => {}; + ( $foo: tt [$ attr: meta] $name: ident ) => {}; + ( $foo: tt &'a [$attr : meta] $name: ident ) => {}; + ( $foo: tt foo # [ $attr : meta] $name: ident ) => {}; + ( $foo: tt # [ $attr : meta] $name: ident) => {}; + ( $foo: tt &'a # [ $attr : meta] $name: ident ) => {}; + ( $ x : tt foo bar foo bar foo bar $ y : tt => x*y*z $ z : tt , $ ( $a: tt ) , * ) => {}; +} + + +macro_rules! impl_a_method { + ($n:ident ( $a:ident : $ta:ty ) -> $ret:ty { $body:expr }) => { + fn $n($a:$ta) -> $ret { $body } + macro_rules! $n { ($va:expr) => { $n($va) } } + }; + ($n:ident ( $a:ident : $ta:ty, $b:ident : $tb:ty ) -> $ret:ty { $body:expr }) => { + fn $n($a:$ta, $b:$tb) -> $ret { $body } + macro_rules! $n { ($va:expr, $vb:expr) => { $n($va, $vb) } } + }; + ($n:ident ( $a:ident : $ta:ty, $b:ident : $tb:ty, $c:ident : $tc:ty ) -> $ret:ty { $body:expr }) => { + fn $n($a:$ta, $b:$tb, $c:$tc) -> $ret { $body } + macro_rules! $n { ($va:expr, $vb:expr, $vc:expr) => { $n($va, $vb, $vc) } } + }; + ($n:ident ( $a:ident : $ta:ty, $b:ident : $tb:ty, $c:ident : $tc:ty, $d:ident : $td:ty ) -> $ret:ty { $body:expr }) => { + fn $n($a:$ta, $b:$tb, $c:$tc, $d:$td) -> $ret { $body } + macro_rules! $n { ($va:expr, $vb:expr, $vc:expr, $vd:expr) => { $n($va, $vb, $vc, $vd) } } + }; +} + +macro_rules! m { + // a + ($expr :expr, $( $func : ident ) * ) => { + { + let x = $expr; + $func ( + x + ) + } + }; + + /* b */ + + () => {/* c */}; + + (@tag) => + { + + }; + +// d +( $item:ident ) => { + mod macro_item { struct $item ; } +}; +} + +macro m2 { + // a + ($expr :expr, $( $func : ident ) * ) => { + { + let x = $expr; + $func ( + x + ) + } + } + + /* b */ + + () => {/* c */} + + (@tag) => + { + + } + +// d +( $item:ident ) => { + mod macro_item { struct $item ; } +} +} + +// #2438, #2476 +macro_rules! m { + () => { + fn foo() { + this_line_is_98_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + ); + } + } +} +macro_rules! m { + () => { + fn foo() { + this_line_is_99_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( +); + } + }; +} +macro_rules! m { + () => { + fn foo() { + this_line_is_100_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( +); + } + }; +} +macro_rules! m { + () => { + fn foo() { + this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + ); + } + }; +} + +// #2439 +macro_rules! m { + ($line0_xxxxxxxxxxxxxxxxx: expr, $line1_xxxxxxxxxxxxxxxxx: expr, $line2_xxxxxxxxxxxxxxxxx: expr, $line3_xxxxxxxxxxxxxxxxx: expr,) => {}; +} + +// #2466 +// Skip formatting `macro_rules!` that are not using `{}`. +macro_rules! m ( + () => () +); +macro_rules! m [ + () => () +]; + +// #2470 +macro foo($type_name: ident, $docs: expr) { + #[allow(non_camel_case_types)] + #[doc=$docs] + #[derive(Debug, Clone, Copy)] + pub struct $type_name; +} + +// #2534 +macro_rules! foo { + ($a:ident : $b:ty) => {}; + ($a:ident $b:ident $c:ident) => {}; +} + +// #2538 +macro_rules! add_message_to_notes { + ($msg:expr) => {{ + let mut lines = message.lines(); + notes.push_str(&format!("\n{}: {}", level, lines.next().unwrap())); + for line in lines { + notes.push_str(&format!( + "\n{:indent$}{line}", + "", + indent = level.len() + 2, + line = line, + )); + } + }} +} + +// #2560 +macro_rules! binary { + ($_self:ident,$expr:expr, $lhs:expr,$func:ident) => { + while $_self.matched($expr) { + let op = $_self.get_binary_op()?; + + let rhs = Box::new($_self.$func()?); + + $lhs = Spanned { + span: $lhs.get_span().to(rhs.get_span()), + value: Expression::Binary { + lhs: Box::new($lhs), + op, + rhs, + }, + } + } + }; +} + +// #2558 +macro_rules! m { + ($x:) => {}; + ($($foo:expr)()?) => {}; +} + +// #2749 +macro_rules! foo { + ($(x)* {}) => {}; + ($(x)* ()) => {}; + ($(x)* []) => {}; +} +macro_rules! __wundergraph_expand_sqlite_mutation { + ( $mutation_name:ident $((context = $($context:tt)*))*{ $( $entity_name:ident( $(insert = $insert:ident,)* $(update = $update:ident,)* $(delete = $($delete:tt)+)* ), )* } ) => {}; +} + +// #2607 +macro_rules! bench { + ($ty:ident) => { + criterion_group!( + name = benches; + config = ::common_bench::reduced_samples(); + targets = call, map; + ); + }; +} + +// #2770 +macro_rules! save_regs { + () => { + asm!("push rax + push rcx + push rdx + push rsi + push rdi + push r8 + push r9 + push r10 + push r11" + :::: "intel", "volatile"); + }; +} + +// #2721 +macro_rules! impl_as_byte_slice_arrays { + ($n:expr,) => {}; + ($n:expr, $N:ident, $($NN:ident,)*) => { + impl_as_byte_slice_arrays!($n - 1, $($NN,)*); + + impl<T> AsByteSliceMut for [T; $n] where [T]: AsByteSliceMut { + fn as_byte_slice_mut(&mut self) -> &mut [u8] { + self[..].as_byte_slice_mut() + } + + fn to_le(&mut self) { + self[..].to_le() + } + } + }; + (!div $n:expr,) => {}; + (!div $n:expr, $N:ident, $($NN:ident,)*) => { + impl_as_byte_slice_arrays!(!div $n / 2, $($NN,)*); + + impl<T> AsByteSliceMut for [T; $n] where [T]: AsByteSliceMut { + fn as_byte_slice_mut(&mut self) -> &mut [u8] { + self[..].as_byte_slice_mut() + } + + fn to_le(&mut self) { + self[..].to_le() + } + } + }; +} + +// #2919 +fn foo() { + { + macro_rules! touch_value { + ($func:ident, $value:expr) => {{ + let result = API::get_cached().$func(self, key.as_ptr(), $value, ffi::VSPropAppendMode::paTouch); + let result = API::get_cached().$func(self, key.as_ptr(), $value, ffi::VSPropAppend); + let result = API::get_cached().$func(self, key.as_ptr(), $value, ffi::VSPropAppendM); + let result = APIIIIIIIII::get_cached().$func(self, key.as_ptr(), $value, ffi::VSPropAppendM); + let result = API::get_cached().$func(self, key.as_ptr(), $value, ffi::VSPropAppendMMMMMMMMMM); + debug_assert!(result == 0); + }}; + } + } +} + +// #2642 +macro_rules! template { + ($name: expr) => { + format_args!(r##" +"http://example.com" + +# test +"##, $name) + } +} + +macro_rules! template { + () => { + format_args!(r" +// + +") + } +} diff --git a/src/tools/rustfmt/tests/source/macros.rs b/src/tools/rustfmt/tests/source/macros.rs new file mode 100644 index 000000000..3b286579c --- /dev/null +++ b/src/tools/rustfmt/tests/source/macros.rs @@ -0,0 +1,486 @@ +// rustfmt-normalize_comments: true +// rustfmt-format_macro_matchers: true +itemmacro!(this, is.now() .formatted(yay)); + +itemmacro!(really, long.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbb() .is.formatted()); + +itemmacro!{this, is.brace().formatted()} + +fn main() { + foo! ( ); + + foo!(,); + + bar!( a , b , c ); + + bar!( a , b , c , ); + + baz!(1+2+3, quux. kaas()); + + quux!(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB); + + kaas!(/* comments */ a /* post macro */, b /* another */); + + trailingcomma!( a , b , c , ); + // Preserve trailing comma only when necessary. + ok!(file.seek( + SeekFrom::Start( + table.map(|table| fixture.offset(table)).unwrap_or(0), + ) + )); + + noexpr!( i am not an expression, OK? ); + + vec! [ a , b , c]; + + vec! [AAAAAA, AAAAAA, AAAAAA, AAAAAA, AAAAAA, AAAAAA, AAAAAA, AAAAAA, AAAAAA, + BBBBB, 5, 100-30, 1.33, b, b, b]; + + vec! [a /* comment */]; + + // Trailing spaces after a comma + vec![ + a, + ]; + + vec![a; b]; + vec!(a; b); + vec!{a; b}; + + vec![a, b; c]; + vec![a; b, c]; + + vec![a; (|x| { let y = x + 1; let z = y + 1; z })(2)]; + vec![a; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]; + vec![a; unsafe { + x + 1 + }]; + + unknown_bracket_macro__comma_should_not_be_stripped![ + a, + ]; + + foo(makro!(1, 3)); + + hamkaas!{ () }; + + macrowithbraces! {dont, format, me} + + x!(fn); + + some_macro!( + + ); + + some_macro![ + ]; + + some_macro!{ + // comment + }; + + some_macro!{ + // comment + }; + + some_macro!( + // comment + not function like + ); + + // #1712 + let image = gray_image!( + 00, 01, 02; + 10, 11, 12; + 20, 21, 22); + + // #1092 + chain!(input, a:take!(max_size), || []); + + // #2727 + foo!("bar") +; +} + +impl X { + empty_invoc!{} + empty_invoc! {} +} + +fn issue_1279() { + println!("dsfs"); // a comment +} + +fn issue_1555() { + let hello = &format!("HTTP/1.1 200 OK\r\nServer: {}\r\n\r\n{}", + "65454654654654654654654655464", + "4"); +} + +fn issue1178() { + macro_rules! foo { + (#[$attr:meta] $name:ident) => {} + } + + foo!(#[doc = "bar"] baz); +} + +fn issue1739() { + sql_function!(add_rss_item, + add_rss_item_t, + (a: types::Integer, + b: types::Timestamptz, + c: types::Text, + d: types::Text, + e: types::Text)); + + w.slice_mut(s![.., init_size[1] - extreeeeeeeeeeeeeeeeeeeeeeeem..init_size[1], ..]) + .par_map_inplace(|el| *el = 0.); +} + +fn issue_1885() { + let threads = people.into_iter().map(|name| { + chan_select! { + rx.recv() => {} + } + }).collect::<Vec<_>>(); +} + +fn issue_1917() { + mod x { + quickcheck! { + fn test(a: String, s: String, b: String) -> TestResult { + if a.find(&s).is_none() { + + TestResult::from_bool(true) + } else { + TestResult::discard() + } + } + } + } +} + +fn issue_1921() { + // Macro with tabs. + lazy_static! { + static ref ONE: u32 = 1; + static ref TWO: u32 = 2; + static ref THREE: u32 = 3; + static ref FOUR: u32 = { + let mut acc = 1; + acc += 1; + acc += 2; + acc + } +} +} + +// #1577 +fn issue1577() { + let json = json!({ + "foo": "bar", + }); +} + +// #3174 +fn issue_3174() { + let data = + if let Some(debug) = error.debug_info() { + json!({ + "errorKind": format!("{:?}", error.err_kind()), + "debugMessage": debug.message, + }) + } else { + json!({"errorKind": format!("{:?}", error.err_kind())}) + }; +} + +gfx_pipeline!(pipe { + vbuf: gfx::VertexBuffer<Vertex> = (), + out: gfx::RenderTarget<ColorFormat> = "Target0", +}); + +// #1919 +#[test] +fn __bindgen_test_layout_HandleWithDtor_open0_int_close0_instantiation() { + assert_eq!( + ::std::mem::size_of::<HandleWithDtor<::std::os::raw::c_int>>(), + 8usize, + concat!( + "Size of template specialization: ", + stringify ! ( HandleWithDtor < :: std :: os :: raw :: c_int > ) + ) + ); + assert_eq ! ( :: std :: mem :: align_of :: < HandleWithDtor < :: std :: os :: raw :: c_int > > ( ) , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( HandleWithDtor < :: std :: os :: raw :: c_int > ) ) ); +} + +// #878 +macro_rules! try_opt { + ($expr:expr) => (match $expr { + Some(val) => val, + + None => { return None; } + }) +} + +// #2214 +// macro call whose argument is an array with trailing comma. +fn issue2214() { +make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [ + Reject(0, 1), + Match (1, 3), + Reject(3, 4), + Match (4, 6), + Reject(6, 7), +]); +} + +fn special_case_macros() { + let p = eprint!(); + let q = eprint!("{}", 1); + let r = eprint!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let s = eprint!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + let q = eprintln!("{}", 1); + let r = eprintln!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let s = eprintln!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + let q = format!("{}", 1); + let r = format!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let s = format!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + let q = format_args!("{}", 1); + let r = format_args!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let s = format_args!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + let q = print!("{}", 1); + let r = print!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let s = print!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + let q = println!("{}", 1); + let r = println!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let s = println!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + let q = unreachable!("{}", 1); + let r = unreachable!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let s = unreachable!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + debug!("{}", 1); + debug!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + debug!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + error!("{}", 1); + error!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + error!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + info!("{}", 1); + info!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + info!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + panic!("{}", 1); + panic!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + panic!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + warn!("{}", 1); + warn!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + warn!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + assert!(); + assert!(result == 42); + assert!(result == 42, "Ahoy there, {}!", target); + assert!(result == 42, "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", result, input, expected); + assert!(result == 42, "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + assert_eq!(); + assert_eq!(left); + assert_eq!(left, right); + assert_eq!(left, right, "Ahoy there, {}!", target); + assert_eq!(left, right, "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", result, input, expected); + assert_eq!(first_realllllllllllly_long_variable_that_doesnt_fit_one_one_line, second_reallllllllllly_long_variable_that_doesnt_fit_one_one_line, "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", result, input, expected); + assert_eq!(left + 42, right, "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", result, input, expected); + assert_eq!(left, right, "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + write!(&mut s, "Ahoy there, {}!", target); + write!(&mut s, "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", result, input, expected); + write!(&mut s, "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); + + writeln!(&mut s, "Ahoy there, {}!", target); + writeln!(&mut s, "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", result, input, expected); + writeln!(&mut s, "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); +} + +// #1209 +impl Foo { + /// foo + pub fn foo(&self) -> Bar<foo!( )> {} +} + +// #819 +fn macro_in_pattern_position () { + let x = match y { + foo!( ) => (), + bar!( a, b, + c) => (), + bar!(a + , b + , c + ,) => (), + baz!( 1 + 2 + 3, quux.kaas( ) + ) => (), + quux!(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB) => (), + }; +} + +macro foo() { + + +} + +pub macro bar($x:ident+$y:expr; ) { + fn foo($x: Foo) { + long_function(a_long_argument_to_a_long_function_is_what_this_is(AAAAAAAAAAAAAAAAAAAAAAAAAAAA), + $x.bar($y)); + } +} + +macro foo() { + // a comment + fn foo() { + // another comment + bar(); + } +} + +// #2574 +macro_rules! test { + () => {{}} +} + +macro lex_err($kind: ident $(, $body: expr)*) { + Err(QlError::LexError(LexError::$kind($($body,)*))) +} + +// Preserve trailing comma on item-level macro with `()` or `[]`. +methods![ get, post, delete, ]; +methods!( get, post, delete, ); + +// #2588 +macro_rules! m { + () => { + r#" + test + "# + }; +} +fn foo() { + f!{r#" + test + "#}; +} + +// #2591 +fn foo() { + match 0u32 { + 0 => (), + _ => unreachable!(/* obviously */), + } +} + +fn foo() { + let _ = column!(/* here */); +} + +// #2616 +// Preserve trailing comma when using mixed layout for macro call. +fn foo() { + foo!(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + foo!(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,); +} + +// #2830 +// Preserve trailing comma-less/ness inside nested macro. +named!( + do_parse_gsv<GsvData>, + map_res!( + do_parse!( + number_of_sentences: map_res!(digit, parse_num::<u16>) + >> char!(',') + >> sentence_index: map_res!(digit, parse_num::<u16>) + >> char!(',') + >> total_number_of_sats: map_res!(digit, parse_num::<u16>) + >> char!(',') + >> sat0: opt!(complete!(parse_gsv_sat_info)) + >> sat1: opt!(complete!(parse_gsv_sat_info)) + >> sat2: opt!(complete!(parse_gsv_sat_info)) + >> sat3: opt!(complete!(parse_gsv_sat_info)) + >> ( + number_of_sentences, + sentence_index, + total_number_of_sats, + sat0, + sat1, + sat2, + sat3 + ) + ), + construct_gsv_data + ) +); + +// #2857 +convert_args!(vec!(1, 2, 3)); + +// #3031 +thread_local!( +/// TLV Holds a set of JSTraceables that need to be rooted + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = + RefCell::new(RootedTraceableSet::new()) ; +) ; + +thread_local![ + /// TLV Holds a set of JSTraceables that need to be rooted + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = + RefCell::new(RootedTraceableSet::new()) ; + + /// TLV Holds a set of JSTraceables that need to be rooted + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = + RefCell::new(RootedTraceableSet::new(0)) ; + + /// TLV Holds a set of JSTraceables that need to be rooted + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = + RefCell::new(RootedTraceableSet::new(), xxx, yyy) ; + + /// TLV Holds a set of JSTraceables that need to be rooted +static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = + RefCell::new(RootedTraceableSet::new(1234)) ; + +] ; + +fn issue3004() { + foo!(|_| { ( ) }); + stringify!(( foo+ )); +} + +// #3331 +pub fn fold_abi<V: Fold + ?Sized>(_visitor: &mut V, _i: Abi) -> Abi { + Abi { + extern_token: Token ! [ extern ](tokens_helper(_visitor, &_i.extern_token.span)), + name: (_i.name).map(|it| _visitor.fold_lit_str(it)), + } +} + +// #3463 +x ! {()} + +// #3746 +f!(match a { + 4 => + &[ + (3, false), // Missing + (4, true) // I-frame + ] [..], +}); + +// #3583 +foo!(|x = y|); diff --git a/src/tools/rustfmt/tests/source/markdown-comment-with-options.rs b/src/tools/rustfmt/tests/source/markdown-comment-with-options.rs new file mode 100644 index 000000000..2c4d6a5cc --- /dev/null +++ b/src/tools/rustfmt/tests/source/markdown-comment-with-options.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: true + +// Preserve two trailing whitespaces in doc comment, +// but trim any whitespaces in normal comment. + +//! hello world +//! hello world + +/// hello world +/// hello world +/// hello world +fn foo() { + // hello world + // hello world + let x = 3; + println!("x = {}", x); +} diff --git a/src/tools/rustfmt/tests/source/markdown-comment.rs b/src/tools/rustfmt/tests/source/markdown-comment.rs new file mode 100644 index 000000000..1ec26562f --- /dev/null +++ b/src/tools/rustfmt/tests/source/markdown-comment.rs @@ -0,0 +1,15 @@ +// Preserve two trailing whitespaces in doc comment, +// but trim any whitespaces in normal comment. + +//! hello world +//! hello world + +/// hello world +/// hello world +/// hello world +fn foo() { + // hello world + // hello world + let x = 3; + println!("x = {}", x); +} diff --git a/src/tools/rustfmt/tests/source/match-block-trailing-comma.rs b/src/tools/rustfmt/tests/source/match-block-trailing-comma.rs new file mode 100644 index 000000000..baa05b79c --- /dev/null +++ b/src/tools/rustfmt/tests/source/match-block-trailing-comma.rs @@ -0,0 +1,22 @@ +// rustfmt-match_block_trailing_comma: true +// Match expressions, no unwrapping of block arms or wrapping of multiline +// expressions. + +fn foo() { + match x { + a => { + "line1"; + "line2" + } + ThisIsA::Guard if true => { + "line1"; + "line2" + } + ThisIsA::ReallyLongPattern(ThatWillForce::TheGuard, ToWrapOnto::TheFollowingLine) if true => { + "line1"; + "line2" + } + b => (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb), + } +} diff --git a/src/tools/rustfmt/tests/source/match-flattening.rs b/src/tools/rustfmt/tests/source/match-flattening.rs new file mode 100644 index 000000000..935ece53b --- /dev/null +++ b/src/tools/rustfmt/tests/source/match-flattening.rs @@ -0,0 +1,21 @@ +fn main() { + match option { + None => if condition { + true + } else { + false + }, + } +} + +fn main() { + match option { + None => { + if condition { + true + } else { + false + } + } + } +} diff --git a/src/tools/rustfmt/tests/source/match-nowrap-trailing-comma.rs b/src/tools/rustfmt/tests/source/match-nowrap-trailing-comma.rs new file mode 100644 index 000000000..134d2fdf9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/match-nowrap-trailing-comma.rs @@ -0,0 +1,15 @@ +// rustfmt-match_arm_blocks: false +// rustfmt-match_block_trailing_comma: true +// Match expressions, no unwrapping of block arms or wrapping of multiline +// expressions. + +fn foo() { + match x { + a => { + "line1"; + "line2" + } + b => (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb), + } +} diff --git a/src/tools/rustfmt/tests/source/match-nowrap.rs b/src/tools/rustfmt/tests/source/match-nowrap.rs new file mode 100644 index 000000000..db22cd9f0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/match-nowrap.rs @@ -0,0 +1,12 @@ +// rustfmt-match_arm_blocks: false +// Match expressions, no unwrapping of block arms or wrapping of multiline +// expressions. + +fn foo() { + match x { + a => { foo() } + b => + (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb), + } +} diff --git a/src/tools/rustfmt/tests/source/match.rs b/src/tools/rustfmt/tests/source/match.rs new file mode 100644 index 000000000..b5dc9957a --- /dev/null +++ b/src/tools/rustfmt/tests/source/match.rs @@ -0,0 +1,589 @@ +// rustfmt-normalize_comments: true +// Match expressions. + +fn foo() { + // A match expression. + match x { + // Some comment. + a => foo(), + b if 0 < 42 => foo(), + c => { // Another comment. + // Comment. + an_expression; + foo() + } + Foo(ref bar) => + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + Pattern1 | Pattern2 | Pattern3 => false, + Paternnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn | + Paternnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn => { + blah + } + Patternnnnnnnnnnnnnnnnnnn | + Patternnnnnnnnnnnnnnnnnnn | + Patternnnnnnnnnnnnnnnnnnn | + Patternnnnnnnnnnnnnnnnnnn => meh, + + Patternnnnnnnnnnnnnnnnnnn | + Patternnnnnnnnnnnnnnnnnnn if looooooooooooooooooong_guard => meh, + + Patternnnnnnnnnnnnnnnnnnnnnnnnn | + Patternnnnnnnnnnnnnnnnnnnnnnnnn if looooooooooooooooooooooooooooooooooooooooong_guard => + meh, + + // Test that earlier patterns can take the guard space + (aaaa, bbbbb, ccccccc, aaaaa, bbbbbbbb, cccccc, aaaa, bbbbbbbb, cccccc, dddddd) | + Patternnnnnnnnnnnnnnnnnnnnnnnnn if loooooooooooooooooooooooooooooooooooooooooong_guard => {} + + _ => {} + ast::PathParameters::AngleBracketedParameters(ref data) if data.lifetimes.len() > 0 || + data.types.len() > 0 || + data.bindings.len() > 0 => {} + } + + let whatever = match something { + /// DOC COMMENT! + Some(_) => 42, + // Comment on an attribute. + #[an_attribute] + // Comment after an attribute. + None => 0, + #[rustfmt::skip] + Blurb => { } + }; +} + +// Test that a match on an overflow line is laid out properly. +fn main() { + let sub_span = + match xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx { + Some(sub_span) => Some(sub_span), + None => sub_span, + }; +} + +// Test that one-line bodies align. +fn main() { + match r { + Variableeeeeeeeeeeeeeeeee => ( "variable", + vec!("id", "name", "qualname", + "value", "type", "scopeid"), + true, + true), + Enummmmmmmmmmmmmmmmmmmmm => ("enum", + vec!("id","qualname","scopeid","value"), + true, + true), + Variantttttttttttttttttttttttt => ("variant", + vec!("id", + "name", + "qualname", + "type", + "value", + "scopeid"), + true, + true), + }; + + match x{ + y=>{/*Block with comment. Preserve me.*/ } + z=>{stmt();} } +} + +fn matches() { + match 1 { + -1 => 10, + 1 => 1, // foo + 2 => 2, + // bar + 3 => 3, + _ => 0 // baz + } +} + +fn match_skip() { + let _ = match Some(1) { + #[rustfmt::skip] + Some( n ) => n, + None => 1, + }; +} + +fn issue339() { + match a { + b => {} + c => { } + d => { + } + e => { + + + + } + // collapsing here is safe + ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff => { + } + // collapsing here exceeds line length + ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffg => { + } + h => { // comment above block + } + i => { + } // comment below block + j => { + // comment inside block + } + j2 => { + // comments inside... + } // ... and after + // TODO uncomment when vertical whitespace is handled better + // k => { + // + // // comment with WS above + // } + // l => { + // // comment with ws below + // + // } + m => { + } n => { } o => + { + + } + p => { // Don't collapse me + } q => { } r => + { + + } + s => 0, // s comment + // t comment + t => 1, + u => 2, + v => { + } /* funky block + * comment */ + // final comment + } +} + +fn issue355() { + match mac { + a => println!("a", b), + b => vec!(1, 2), + c => vec!(3; 4), + d => { + println!("a", b) + } + e => { + vec!(1, 2) + } + f => { + vec!(3; 4) + } + h => println!("a", b), // h comment + i => vec!(1, 2), // i comment + j => vec!(3; 4), // j comment + // k comment + k => println!("a", b), + // l comment + l => vec!(1, 2), + // m comment + m => vec!(3; 4), + // Rewrite splits macro + nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn => println!("a", b), + // Rewrite splits macro + oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo => vec!(1, 2), + // Macro support fails to recognise this macro as splittable + // We push the whole expr to a new line, TODO split this macro as well + pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp => vec!(3; 4), + // q, r and s: Rewrite splits match arm + qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq => println!("a", b), + rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr => vec!(1, 2), + ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss => vec!(3; 4), + // Funky bracketing styles + t => println!{"a", b}, + u => vec!{1, 2}, + v => vec!{3; 4}, + w => println!["a", b], + x => vec![1, 2], + y =>vec![3; 4], + // Brackets with comments + tc => println!{"a", b}, // comment + uc => vec!{1, 2}, // comment + vc =>vec!{3; 4}, // comment + wc =>println!["a", b], // comment + xc => vec![1,2], // comment + yc => vec![3; 4], // comment + yd => + looooooooooooooooooooooooooooooooooooooooooooooooooooooooong_func(aaaaaaaaaa, + bbbbbbbbbb, + cccccccccc, + dddddddddd), + } +} + +fn issue280() { + { + match x { + CompressionMode::DiscardNewline | CompressionMode::CompressWhitespaceNewline => ch == + '\n', + ast::ItemConst(ref typ, ref expr) => self.process_static_or_const_item(item, + &typ, + &expr), + } + } +} + +fn issue383() { + match resolution.last_private {LastImport{..} => false, _ => true}; +} + +fn issue507() { + match 1 { + 1 => unsafe { std::intrinsics::abort() }, + _ => (), + } +} + +fn issue508() { + match s.type_id() { + Some(NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLCanvasElement))) => true, + Some(NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLObjectElement))) => s.has_object_data(), + Some(NodeTypeId::Element(_)) => false, + } +} + +fn issue496() {{{{ + match def { + def::DefConst(def_id) | def::DefAssociatedConst(def_id) => + match const_eval::lookup_const_by_id(cx.tcx, def_id, Some(self.pat.id)) { + Some(const_expr) => { x }}}}}}} + +fn issue494() { + { + match stmt.node { + hir::StmtExpr(ref expr, id) | hir::StmtSemi(ref expr, id) => + result.push( + StmtRef::Mirror( + Box::new(Stmt { span: stmt.span, + kind: StmtKind::Expr { + scope: cx.tcx.region_maps.node_extent(id), + expr: expr.to_ref() } }))), + } + } +} + +fn issue386() { + match foo { + BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => + true, + BiAnd | BiOr | BiAdd | BiSub | BiMul | BiDiv | BiRem | + BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr => + false, + } +} + +fn guards() { + match foo { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa if foooooooooooooo && barrrrrrrrrrrr => {} + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa if foooooooooooooo && barrrrrrrrrrrr => {} + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + if fooooooooooooooooooooo && + (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb || cccccccccccccccccccccccccccccccccccccccc) => {} + } +} + +fn issue1371() { + Some(match type_ { + sfEvtClosed => Closed, + sfEvtResized => { + let e = unsafe { *event.size.as_ref() }; + + Resized { + width: e.width, + height: e.height, + } + } + sfEvtLostFocus => LostFocus, + sfEvtGainedFocus => GainedFocus, + sfEvtTextEntered => { + TextEntered { + unicode: unsafe { + ::std::char::from_u32((*event.text.as_ref()).unicode) + .expect("Invalid unicode encountered on TextEntered event") + }, + } + } + sfEvtKeyPressed => { + let e = unsafe { event.key.as_ref() }; + + KeyPressed { + code: unsafe { ::std::mem::transmute(e.code) }, + alt: e.alt.to_bool(), + ctrl: e.control.to_bool(), + shift: e.shift.to_bool(), + system: e.system.to_bool(), + } + } + sfEvtKeyReleased => { + let e = unsafe { event.key.as_ref() }; + + KeyReleased { + code: unsafe { ::std::mem::transmute(e.code) }, + alt: e.alt.to_bool(), + ctrl: e.control.to_bool(), + shift: e.shift.to_bool(), + system: e.system.to_bool(), + } + } + }) +} + +fn issue1395() { + let bar = Some(true); + let foo = Some(true); + let mut x = false; + bar.and_then(|_| { + match foo { + None => None, + Some(b) => { + x = true; + Some(b) + } + } + }); +} + +fn issue1456() { + Ok(Recording { + artists: match reader.evaluate(".//mb:recording/mb:artist-credit/mb:name-credit")? { + Nodeset(nodeset) => { + let res: Result<Vec<ArtistRef>, ReadError> = nodeset + .iter() + .map(|node| { + XPathNodeReader::new(node, &context).and_then(|r| ArtistRef::from_xml(&r)) + }) + .collect(); + res? + } + _ => Vec::new(), + }, + }) +} + +fn issue1460() { + let _ = match foo { + REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT => "internal_spec_insert_internal_spec_insert_internal_spec_insert", + _ => "reorder_something", + }; +} + +fn issue525() { + foobar(f, "{}", match *self { + TaskState::Started => "started", + TaskState::Success => "success", + TaskState::Failed => "failed", + }); +} + +// #1838, #1839 +fn match_with_near_max_width() { + let (this_line_uses_99_characters_and_is_formatted_properly, x012345) = match some_expression { + _ => unimplemented!(), + }; + + let (should_be_formatted_like_the_line_above_using_100_characters, x0) = match some_expression { + _ => unimplemented!(), + }; + + let (should_put_the_brace_on_the_next_line_using_101_characters, x0000) = match some_expression + { + _ => unimplemented!(), + }; + match m { + Variant::Tag | Variant::Tag2 | Variant::Tag3 | Variant::Tag4 | Variant::Tag5 | Variant::Tag6 => + {} + } +} + +fn match_with_trailing_spaces() { + match x { + + Some(..) => 0, + None => 1, + } +} + +fn issue_2099() { + let a = match x { +}; + let b = match x { + + }; + + match x {} +} + +// #2021 +impl<'tcx> Const<'tcx> { + pub fn from_constval<'a>() -> Const<'tcx> { + let val = match *cv { + ConstVal::Variant(_) | ConstVal::Aggregate(..) | ConstVal::Unevaluated(..) => bug!("MIR must not use `{:?}` (aggregates are expanded to MIR rvalues)", cv), + }; + } +} + +// #2151 +fn issue_2151() { + match either { + x => { + + }y => () + } +} + +// #2152 +fn issue_2152() { + match m { + "aaaaaaaaaaaaa" | "bbbbbbbbbbbbb" | "cccccccccccccccccccccccccccccccccccccccccccc" if true => {} + "bind" | "writev" | "readv" | "sendmsg" | "recvmsg" if android && (aarch64 || x86_64) => true, + } +} + +// #2376 +// Preserve block around expressions with condition. +fn issue_2376() { + let mut x = None; + match x { + Some(0) => { + for i in 1..11 { + x = Some(i); + } + } + Some(ref mut y) => { + while *y < 10 { + *y += 1; + } + } + None => { + while let None = x { + x = Some(10); + } + } + } +} + +// #2621 +// Strip leading `|` in match arm patterns +fn issue_2621() { + let x = Foo::A; + match x { + Foo::A => println!("No vert single condition"), + Foo::B | Foo::C => println!("Center vert two conditions"), + | Foo::D => println!("Preceding vert single condition"), + | Foo::E + | Foo::F => println!("Preceding vert over two lines"), + Foo::G | + Foo::H => println!("Trailing vert over two lines"), + // Comment on its own line + | Foo::I => println!("With comment"), // Comment after line + } +} + +fn issue_2377() { + match tok { + Tok::Not + | Tok::BNot + | Tok::Plus + | Tok::Minus + | Tok::PlusPlus + | Tok::MinusMinus + | Tok::Void + | Tok::Delete if prec <= 16 => { + // code here... + } + Tok::TypeOf if prec <= 16 => {} + } +} + +// #3040 +fn issue_3040() { + { + match foo { + DevtoolScriptControlMsg::WantsLiveNotifications(id, to_send) => { + match documents.find_window(id) { + Some(window) => devtools::handle_wants_live_notifications(window.upcast(), to_send), + None => return warn!("Message sent to closed pipeline {}.", id), + } + } + } + } +} + +// #3030 +fn issue_3030() { + match input.trim().parse::<f64>() { + Ok(val) + if !( + // A valid number is the same as what rust considers to be valid, + // except for +1., NaN, and Infinity. + val.is_infinite() || val + .is_nan() || input.ends_with(".") || input.starts_with("+") + ) + => { + } + } +} + +fn issue_3005() { + match *token { + Token::Dimension { + value, ref unit, .. + } if num_context.is_ok(context.parsing_mode, value) => + { + return NoCalcLength::parse_dimension(context, value, unit) + .map(LengthOrPercentage::Length) + .map_err(|()| location.new_unexpected_token_error(token.clone())); + }, + } +} + +// #3774 +fn issue_3774() { + { + { + { + match foo { + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachab(), + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreacha!(), + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachabl(), + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachae!(), + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachable(), + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachable!(), + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => rrunreachable!(), + } + } + } + } +} + +// #4109 +fn issue_4109() { + match () { + _ => { +#[cfg(debug_assertions)] +{ +println!("Foo"); +} +} +} + +match () { +_ => { +#[allow(unsafe_code)] +unsafe {} +} +} +} diff --git a/src/tools/rustfmt/tests/source/match_overflow_expr.rs b/src/tools/rustfmt/tests/source/match_overflow_expr.rs new file mode 100644 index 000000000..91275a894 --- /dev/null +++ b/src/tools/rustfmt/tests/source/match_overflow_expr.rs @@ -0,0 +1,53 @@ +// rustfmt-overflow_delimited_expr: true + +fn main() { + println!( + "Foobar: {}", + match "input" { + "a" => "", + "b" => "", + "c" => "", + "d" => "", + "e" => "", + "f" => "", + "g" => "", + "h" => "", + "i" => "", + "j" => "", + "k" => "", + "l" => "", + "m" => "", + "n" => "", + "o" => "", + "p" => "", + "q" => "", + "r" => "Rust", + } + ); +} + +fn main() { + println!( + "Very Long Input String Which Makes It Impossible To Fit On The Same Line: {}", + match "input" { + "a" => "", + "b" => "", + "c" => "", + "d" => "", + "e" => "", + "f" => "", + "g" => "", + "h" => "", + "i" => "", + "j" => "", + "k" => "", + "l" => "", + "m" => "", + "n" => "", + "o" => "", + "p" => "", + "q" => "", + "r" => "Rust", + } + ); +} diff --git a/src/tools/rustfmt/tests/source/max-line-length-in-chars.rs b/src/tools/rustfmt/tests/source/max-line-length-in-chars.rs new file mode 100644 index 000000000..d49fbb7e3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/max-line-length-in-chars.rs @@ -0,0 +1,4 @@ +// rustfmt-max_width: 25 + +// абвгдеёжзийклмнопрст +fn main() {} diff --git a/src/tools/rustfmt/tests/source/merge_imports_true_compat.rs b/src/tools/rustfmt/tests/source/merge_imports_true_compat.rs new file mode 100644 index 000000000..bcea94351 --- /dev/null +++ b/src/tools/rustfmt/tests/source/merge_imports_true_compat.rs @@ -0,0 +1,4 @@ +// rustfmt-merge_imports: true + +use a::b; +use a::c;
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/mod-1.rs b/src/tools/rustfmt/tests/source/mod-1.rs new file mode 100644 index 000000000..427a355b6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/mod-1.rs @@ -0,0 +1,29 @@ +// Deeply indented modules. + + mod foo { mod bar { mod baz {} } } + +mod foo { + mod bar { + mod baz { + fn foo() { bar() } + } + } + + mod qux { + + } +} + +mod boxed { pub use std::boxed::{Box, HEAP}; } + +pub mod x { + pub fn freopen(filename: *const c_char, + mode: *const c_char, + mode2: *const c_char, + mode3: *const c_char, + file: *mut FILE) + -> *mut FILE{} +} + + mod y { // sup boooooiiii + } diff --git a/src/tools/rustfmt/tests/source/mod-2.rs b/src/tools/rustfmt/tests/source/mod-2.rs new file mode 100644 index 000000000..7202e0020 --- /dev/null +++ b/src/tools/rustfmt/tests/source/mod-2.rs @@ -0,0 +1,4 @@ +// Some nested mods + +#[cfg(test)] mod nestedmod ; +pub mod no_new_line_beginning; diff --git a/src/tools/rustfmt/tests/source/mod_skip_child.rs b/src/tools/rustfmt/tests/source/mod_skip_child.rs new file mode 100644 index 000000000..d48c4a37e --- /dev/null +++ b/src/tools/rustfmt/tests/source/mod_skip_child.rs @@ -0,0 +1,2 @@ +// rustfmt-skip_children: true +mod nested_skipped; diff --git a/src/tools/rustfmt/tests/source/multiple.rs b/src/tools/rustfmt/tests/source/multiple.rs new file mode 100644 index 000000000..f89f4f68d --- /dev/null +++ b/src/tools/rustfmt/tests/source/multiple.rs @@ -0,0 +1,134 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-format_strings: true +// Test of lots of random stuff. +// FIXME split this into multiple, self-contained tests. + + +#[attr1] extern crate foo; +#[attr2] #[attr3] extern crate foo; +#[attr1]extern crate foo; +#[attr2]#[attr3]extern crate foo; + +use std::cell::*; +use std::{any, ascii, self, borrow, boxed, char, borrow, boxed, char, borrow, borrow, boxed, char, borrow, boxed, char, borrow, boxed, char, borrow, boxed, char, borrow, boxed, char, borrow, boxed, char, borrow, boxed, char, borrow, boxed, char}; + +mod doc; +mod other; + + +// sfdgfffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff + + fn foo(a: isize, + b: u32, /* blah blah */ + c: f64) { + +} + +fn foo()->Box<Write+'static> where 'a: 'b, for<'a> D<'b>: 'a { + hello!() +} + +fn baz<'a: 'b /* comment on 'a */, T: SomsssssssssssssssssssssssssssssssssssssssssssssssssssssseType /* comment on T */>(a: A, b: B /* comment on b */, c: C) -> Bob { + #[attr1] extern crate foo; + #[attr2] #[attr3] extern crate foo; + #[attr1]extern crate foo; + #[attr2]#[attr3]extern crate foo; +} + +#[rustfmt::skip] +fn qux(a: dadsfa, // Comment 1 + b: sdfasdfa, // Comment 2 + c: dsfdsafa) // Comment 3 +{ + +} + +/// Blah blah blah. +impl Bar { + fn foo(&mut self, a: sdfsdfcccccccccccccccccccccccccccccccccccccccccccccccccc, // comment on a + b: sdfasdfsdfasfs /*closing comment*/ ) -> isize {} + + /// Blah blah blah. + pub fn f2(self) { + (foo, bar) + } + + #[an_attribute] + fn f3(self) -> Dog { + } +} + +/// The `nodes` and `edges` method each return instantiations of +/// `Cow<[T]>` to leave implementers the freedom to create + +/// entirely new vectors or to pass back slices into internally owned +/// vectors. +pub trait GraphWalk<'a, N, E> { + /// Returns all the nodes in this graph. + fn nodes(&'a self) -> Nodes<'a, N>; + /// Returns all of the edges in this graph. + fn edges(&'a self) -> Edges<'a, E>; + /// The source node for `edge`. + fn source(&'a self, edge: &E) -> N; + /// The target node for `edge`. + fn target(&'a self, edge: &E) -> N; +} + +/// A Doc comment +#[AnAttribute] +pub struct Foo { + #[rustfmt::skip] + f : SomeType, // Comment beside a field + f : SomeType, // Comment beside a field + // Comment on a field + g: SomeOtherType, + /// A doc comment on a field + h: AThirdType,} + +struct Bar; + +// With a where-clause and generics. +pub struct Foo<'a, Y: Baz> + where X: Whatever +{ + f: SomeType, // Comment beside a field +} + +fn foo(ann: &'a (PpAnn+'a)) {} + +fn main() { + for i in 0i32..4 { + println!("{}", i); + } + + + while true { + hello(); + } + + let rc = Cell::new(42usize,42usize, Cell::new(42usize, remaining_widthremaining_widthremaining_widthremaining_width), 42usize); + let rc = RefCell::new(42usize,remaining_width, remaining_width); // a comment + let x = "Hello!!!!!!!!! abcd abcd abcd abcd abcd abcd\n abcd abcd abcd abcd abcd abcd abcd abcd abcd \ + abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd \ + abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd"; + let s = expand(a + , + b); } + +fn deconstruct() -> (SocketAddr, Method, Headers, + RequestUri, HttpVersion, + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) { +} + +fn deconstruct(foo: Bar) -> (SocketAddr, Method, Headers, + RequestUri, HttpVersion, + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) { +} + +#[rustfmt::skip] +mod a{ +fn foo(x: T) { + let x: T = dfasdf; +} +} diff --git a/src/tools/rustfmt/tests/source/negative-impl.rs b/src/tools/rustfmt/tests/source/negative-impl.rs new file mode 100644 index 000000000..da242d4f3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/negative-impl.rs @@ -0,0 +1,7 @@ +impl ! Display for JoinHandle { } + +impl ! Box < JoinHandle > { } + +impl ! std :: fmt :: Display for JoinHandle < T : std :: future :: Future + std :: marker :: Send + std :: marker :: Sync > { } + +impl ! JoinHandle < T : std :: future :: Future < Output > + std :: marker :: Send + std :: marker :: Sync + 'static > + 'static { } diff --git a/src/tools/rustfmt/tests/source/nested-if-else.rs b/src/tools/rustfmt/tests/source/nested-if-else.rs new file mode 100644 index 000000000..9a54789dd --- /dev/null +++ b/src/tools/rustfmt/tests/source/nested-if-else.rs @@ -0,0 +1,11 @@ +fn issue1518() { + Some(Object { + field: if a { + a_thing + } else if b { + b_thing + } else { + c_thing + }, + }) +} diff --git a/src/tools/rustfmt/tests/source/nested_skipped/mod.rs b/src/tools/rustfmt/tests/source/nested_skipped/mod.rs new file mode 100644 index 000000000..44b25ca87 --- /dev/null +++ b/src/tools/rustfmt/tests/source/nested_skipped/mod.rs @@ -0,0 +1,3 @@ +fn ugly() { +92; +} diff --git a/src/tools/rustfmt/tests/source/nestedmod/mod.rs b/src/tools/rustfmt/tests/source/nestedmod/mod.rs new file mode 100644 index 000000000..d04e49570 --- /dev/null +++ b/src/tools/rustfmt/tests/source/nestedmod/mod.rs @@ -0,0 +1,13 @@ + +mod mod2a; +mod mod2b; + +mod mymod1 { + use mod2a::{Foo,Bar}; +mod mod3a; +} + +#[path="mod2c.rs"] +mod mymod2; + +mod submod2; diff --git a/src/tools/rustfmt/tests/source/nestedmod/mod2a.rs b/src/tools/rustfmt/tests/source/nestedmod/mod2a.rs new file mode 100644 index 000000000..5df457a83 --- /dev/null +++ b/src/tools/rustfmt/tests/source/nestedmod/mod2a.rs @@ -0,0 +1,4 @@ +// This is an empty file containing only +// comments + +// ................... diff --git a/src/tools/rustfmt/tests/source/nestedmod/mod2b.rs b/src/tools/rustfmt/tests/source/nestedmod/mod2b.rs new file mode 100644 index 000000000..f128e2da6 --- /dev/null +++ b/src/tools/rustfmt/tests/source/nestedmod/mod2b.rs @@ -0,0 +1,3 @@ + +#[path="mod2a.rs"] +mod c; diff --git a/src/tools/rustfmt/tests/source/nestedmod/mod2c.rs b/src/tools/rustfmt/tests/source/nestedmod/mod2c.rs new file mode 100644 index 000000000..eda6b233e --- /dev/null +++ b/src/tools/rustfmt/tests/source/nestedmod/mod2c.rs @@ -0,0 +1,3 @@ +// A standard mod + +fn a( ) {} diff --git a/src/tools/rustfmt/tests/source/nestedmod/mymod1/mod3a.rs b/src/tools/rustfmt/tests/source/nestedmod/mymod1/mod3a.rs new file mode 100644 index 000000000..f28bde5e5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/nestedmod/mymod1/mod3a.rs @@ -0,0 +1,2 @@ +// Another mod +fn a( ) { } diff --git a/src/tools/rustfmt/tests/source/nestedmod/submod2/a.rs b/src/tools/rustfmt/tests/source/nestedmod/submod2/a.rs new file mode 100644 index 000000000..0eaf08f0d --- /dev/null +++ b/src/tools/rustfmt/tests/source/nestedmod/submod2/a.rs @@ -0,0 +1,6 @@ +// Yet Another mod +// Nested + +use c::a; + +fn foo( ) { } diff --git a/src/tools/rustfmt/tests/source/nestedmod/submod2/mod.rs b/src/tools/rustfmt/tests/source/nestedmod/submod2/mod.rs new file mode 100644 index 000000000..52f8be910 --- /dev/null +++ b/src/tools/rustfmt/tests/source/nestedmod/submod2/mod.rs @@ -0,0 +1,5 @@ +// Another mod + +mod a; + +use a::a; diff --git a/src/tools/rustfmt/tests/source/no_arg_with_commnet.rs b/src/tools/rustfmt/tests/source/no_arg_with_commnet.rs new file mode 100644 index 000000000..ea4ee0f1e --- /dev/null +++ b/src/tools/rustfmt/tests/source/no_arg_with_commnet.rs @@ -0,0 +1,2 @@ +fn foo( /* cooment */ +) {} diff --git a/src/tools/rustfmt/tests/source/no_new_line_beginning.rs b/src/tools/rustfmt/tests/source/no_new_line_beginning.rs new file mode 100644 index 000000000..f79c691f0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/no_new_line_beginning.rs @@ -0,0 +1,2 @@ +fn main() { +} diff --git a/src/tools/rustfmt/tests/source/normalize_doc_attributes_should_not_imply_format_doc_comments.rs b/src/tools/rustfmt/tests/source/normalize_doc_attributes_should_not_imply_format_doc_comments.rs new file mode 100644 index 000000000..a97705bfb --- /dev/null +++ b/src/tools/rustfmt/tests/source/normalize_doc_attributes_should_not_imply_format_doc_comments.rs @@ -0,0 +1,15 @@ +// rustfmt-normalize_doc_attributes: true + +/// Foo +/// +/// # Example +/// ``` +/// # #![cfg_attr(not(dox), feature(cfg_target_feature, target_feature, stdsimd))] +/// # #![cfg_attr(not(dox), no_std)] +/// fn foo() { } +/// ``` +/// +fn foo() {} + +#[doc = "Bar documents"] +fn bar() {} diff --git a/src/tools/rustfmt/tests/source/normalize_multiline_doc_attribute.rs b/src/tools/rustfmt/tests/source/normalize_multiline_doc_attribute.rs new file mode 100644 index 000000000..3564e3e7a --- /dev/null +++ b/src/tools/rustfmt/tests/source/normalize_multiline_doc_attribute.rs @@ -0,0 +1,12 @@ +// rustfmt-unstable: true +// rustfmt-normalize_doc_attributes: true + +#[doc = "This comment +is split +on multiple lines"] +fn foo() {} + +#[doc = " B1"] +#[doc = ""] +#[doc = " A1"] +fn bar() {} diff --git a/src/tools/rustfmt/tests/source/one_line_if_v1.rs b/src/tools/rustfmt/tests/source/one_line_if_v1.rs new file mode 100644 index 000000000..d3dcbe678 --- /dev/null +++ b/src/tools/rustfmt/tests/source/one_line_if_v1.rs @@ -0,0 +1,42 @@ +// rustfmt-version: One + +fn plain_if(x: bool) -> u8 { + if x { + 0 + } else { + 1 + } +} + +fn paren_if(x: bool) -> u8 { + (if x { 0 } else { 1 }) +} + +fn let_if(x: bool) -> u8 { + let x = if x { + foo() + } else { + bar() + }; + x +} + +fn return_if(x: bool) -> u8 { + return if x { + 0 + } else { + 1 + }; +} + +fn multi_if() { + use std::io; + if x { foo() } else { bar() } + if x { foo() } else { bar() } +} + +fn middle_if() { + use std::io; + if x { foo() } else { bar() } + let x = 1; +} diff --git a/src/tools/rustfmt/tests/source/one_line_if_v2.rs b/src/tools/rustfmt/tests/source/one_line_if_v2.rs new file mode 100644 index 000000000..40c834959 --- /dev/null +++ b/src/tools/rustfmt/tests/source/one_line_if_v2.rs @@ -0,0 +1,42 @@ +// rustfmt-version: Two + +fn plain_if(x: bool) -> u8 { + if x { + 0 + } else { + 1 + } +} + +fn paren_if(x: bool) -> u8 { + (if x { 0 } else { 1 }) +} + +fn let_if(x: bool) -> u8 { + let x = if x { + foo() + } else { + bar() + }; + x +} + +fn return_if(x: bool) -> u8 { + return if x { + 0 + } else { + 1 + }; +} + +fn multi_if() { + use std::io; + if x { foo() } else { bar() } + if x { foo() } else { bar() } +} + +fn middle_if() { + use std::io; + if x { foo() } else { bar() } + let x = 1; +} diff --git a/src/tools/rustfmt/tests/source/other.rs b/src/tools/rustfmt/tests/source/other.rs new file mode 100644 index 000000000..dfce84fcd --- /dev/null +++ b/src/tools/rustfmt/tests/source/other.rs @@ -0,0 +1,5 @@ +// Part of multiple.rs + +fn bob() { + println!("hello other!"); +} diff --git a/src/tools/rustfmt/tests/source/paren.rs b/src/tools/rustfmt/tests/source/paren.rs new file mode 100644 index 000000000..04e5ab7a5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/paren.rs @@ -0,0 +1,6 @@ +fn main() { + let x = (((1))); + let y = (/* comment */((2))); + let z = (((3)/* comment */)); + let a = (((4/* comment */))); +} diff --git a/src/tools/rustfmt/tests/source/path_clarity/foo.rs b/src/tools/rustfmt/tests/source/path_clarity/foo.rs new file mode 100644 index 000000000..cd247fabf --- /dev/null +++ b/src/tools/rustfmt/tests/source/path_clarity/foo.rs @@ -0,0 +1,2 @@ +// rustfmt-edition: 2018 +mod bar; diff --git a/src/tools/rustfmt/tests/source/path_clarity/foo/bar.rs b/src/tools/rustfmt/tests/source/path_clarity/foo/bar.rs new file mode 100644 index 000000000..8c1be504c --- /dev/null +++ b/src/tools/rustfmt/tests/source/path_clarity/foo/bar.rs @@ -0,0 +1,3 @@ +pub fn fn_in_bar( ) { + println!( "foo/bar.rs" ); +} diff --git a/src/tools/rustfmt/tests/source/paths.rs b/src/tools/rustfmt/tests/source/paths.rs new file mode 100644 index 000000000..ebc26f146 --- /dev/null +++ b/src/tools/rustfmt/tests/source/paths.rs @@ -0,0 +1,25 @@ +// rustfmt-normalize_comments: true + +fn main() { + let constellation_chan = Constellation::<layout::layout_task::LayoutTask, script::script_task::ScriptTask> ::start( + compositor_proxy, + resource_task, + image_cache_task,font_cache_task, + time_profiler_chan, + mem_profiler_chan, + devtools_chan, + storage_task, + supports_clipboard + ); + + Quux::<ParamOne, // Comment 1 + ParamTwo, // Comment 2 + >::some_func(); + + < *mut JSObject >:: relocate(entry); + + let x: Foo<A >; + let x: Foo/*::*/<A>; +} + +fn op(foo: Bar, key : &[u8], upd : Fn(Option<&memcache::Item> , Baz ) -> Result) -> MapResult {} diff --git a/src/tools/rustfmt/tests/source/pattern-condense-wildcards.rs b/src/tools/rustfmt/tests/source/pattern-condense-wildcards.rs new file mode 100644 index 000000000..69c3fa3cb --- /dev/null +++ b/src/tools/rustfmt/tests/source/pattern-condense-wildcards.rs @@ -0,0 +1,12 @@ +// rustfmt-normalize_comments: true +// rustfmt-condense_wildcard_suffixes: true + +fn main() { + match x { + Butt (_,_) => "hah", + Tup (_) => "nah", + Quad (_,_, x,_) => " also no rewrite", + Quad (x, _, _, _) => "condense me pls", + Weird (x, _, _, /* don't condense before */ _, _, _) => "pls work", + } +} diff --git a/src/tools/rustfmt/tests/source/pattern.rs b/src/tools/rustfmt/tests/source/pattern.rs new file mode 100644 index 000000000..f06d03cad --- /dev/null +++ b/src/tools/rustfmt/tests/source/pattern.rs @@ -0,0 +1,90 @@ +// rustfmt-normalize_comments: true +#![feature(exclusive_range_pattern)] +use core::u8::MAX; + +fn main() { + let z = match x { + "pat1" => 1, + ( ref x, ref mut y /*comment*/) => 2, + }; + + if let < T as Trait > :: CONST = ident { + do_smth(); + } + + let Some ( ref xyz /* comment! */) = opt; + + if let None = opt2 { panic!("oh noes"); } + + let foo@bar (f) = 42; + let a::foo ( ..) = 42; + let [ ] = 42; + let [a, b,c ] = 42; + let [ a,b,c ] = 42; + let [a, b, c, d,e,f, g] = 42; + let foo { } = 42; + let foo {..} = 42; + let foo { x, y: ref foo, .. } = 42; + let foo { x, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: ref foo, .. } = 42; + let foo { x, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: ref foo, } = 42; + let foo { x, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: ref foo, .. }; + let foo { x, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: ref foo, }; + + match b"12" { + [0, + 1..MAX + ] => {} + _ => {} + } +} + +impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> { + fn mutate_fragment(&mut self, fragment: &mut Fragment) { + match **info { + GeneratedContentInfo::ContentItem( + ContentItem::Counter( + ref counter_name, + counter_style + ) + ) => {}}} +} + +fn issue_1319() { + if let (Event { .. }, .. ) = ev_state {} +} + +fn issue_1874() { + if let Some(()) = x { +y + } +} + +fn combine_patterns() { + let x = match y { + Some( + Some( + Foo { + z: Bar(..), + a: Bar(..), + b: Bar(..), + }, + ), + ) => z, + _ => return, + }; +} + +fn slice_patterns() { + match b"123" { + [0, ..] => {} + [0, foo] => {} + _ => {} + } +} + +fn issue3728() { + let foo = | + (c,) + | c; + foo((1,)); +} diff --git a/src/tools/rustfmt/tests/source/preserves_carriage_return_for_unix.rs b/src/tools/rustfmt/tests/source/preserves_carriage_return_for_unix.rs new file mode 100644 index 000000000..e5e0b2865 --- /dev/null +++ b/src/tools/rustfmt/tests/source/preserves_carriage_return_for_unix.rs @@ -0,0 +1,2 @@ +// rustfmt-newline_style: Unix +// Foo
Bar diff --git a/src/tools/rustfmt/tests/source/preserves_carriage_return_for_windows.rs b/src/tools/rustfmt/tests/source/preserves_carriage_return_for_windows.rs new file mode 100644 index 000000000..1085360ee --- /dev/null +++ b/src/tools/rustfmt/tests/source/preserves_carriage_return_for_windows.rs @@ -0,0 +1,2 @@ +// rustfmt-newline_style: Windows +// Foo
Bar diff --git a/src/tools/rustfmt/tests/source/pub-restricted.rs b/src/tools/rustfmt/tests/source/pub-restricted.rs new file mode 100644 index 000000000..5683acbf3 --- /dev/null +++ b/src/tools/rustfmt/tests/source/pub-restricted.rs @@ -0,0 +1,51 @@ +pub( super ) enum WriteState<D> { + WriteId { + id: U64Writer, + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteSize { + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteData(Writer<D>), +} + +pub( crate ) enum WriteState<D> { + WriteId { + id: U64Writer, + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteSize { + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteData(Writer<D>), +} + +pub(in ::global:: path :: to::some_mod ) enum WriteState<D> { + WriteId { + id: U64Writer, + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteSize { + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteData(Writer<D>), +} + +pub( in local:: path :: to::some_mod ) enum WriteState<D> { + WriteId { + id: U64Writer, + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteSize { + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteData(Writer<D>), +} diff --git a/src/tools/rustfmt/tests/source/remove_blank_lines.rs b/src/tools/rustfmt/tests/source/remove_blank_lines.rs new file mode 100644 index 000000000..43733ce76 --- /dev/null +++ b/src/tools/rustfmt/tests/source/remove_blank_lines.rs @@ -0,0 +1,44 @@ +fn main() { + + + + + let x = 1; + + + let y = 2; + + + println!("x + y = {}", x + y); + + + +} + + +fn foo() { + + #![attribute] + + let x = 1; + + // comment + + +} +// comment after item + + +// comment before item +fn bar() { + let x = 1; + // comment after statement + + + // comment before statement + let y = 2; + let z = 3; + + + println!("x + y + z = {}", x + y + z); +} diff --git a/src/tools/rustfmt/tests/source/reorder-impl-items.rs b/src/tools/rustfmt/tests/source/reorder-impl-items.rs new file mode 100644 index 000000000..16efff55b --- /dev/null +++ b/src/tools/rustfmt/tests/source/reorder-impl-items.rs @@ -0,0 +1,15 @@ +// rustfmt-reorder_impl_items: true + +// The ordering of the following impl items should be idempotent. +impl<'a> Command<'a> { + pub fn send_to(&self, w: &mut io::Write) -> io::Result<()> { + match self { + &Command::Data(ref c) => c.send_to(w), + &Command::Vrfy(ref c) => c.send_to(w), + } + } + + pub fn parse(arg: &[u8]) -> Result<Command, ParseError> { + nom_to_result(command(arg)) + } +} diff --git a/src/tools/rustfmt/tests/source/single-line-if-else.rs b/src/tools/rustfmt/tests/source/single-line-if-else.rs new file mode 100644 index 000000000..bcde390d1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/single-line-if-else.rs @@ -0,0 +1,49 @@ + +// Format if-else expressions on a single line, when possible. + +fn main() { + let a = if 1 > 2 { + unreachable!() + } else { + 10 + }; + + let a = if x { 1 } else if y { 2 } else { 3 }; + + let b = if cond() { + 5 + } else { + // Brief comment. + 10 + }; + + let c = if cond() { + statement(); + + 5 + } else { + 10 + }; + + let d = if let Some(val) = turbo + { "cool" } else { + "beans" }; + + if cond() { statement(); } else { other_statement(); } + + if true { + do_something() + } + + let x = if veeeeeeeeery_loooooong_condition() { aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa } else { bbbbbbbbbb }; + + let x = if veeeeeeeeery_loooooong_condition() { aaaaaaaaaaaaaaaaaaaaaaaaa } else { + bbbbbbbbbb }; + + funk(if test() { + 1 + } else { + 2 + }, + arg2); +} diff --git a/src/tools/rustfmt/tests/source/single-line-macro/v1.rs b/src/tools/rustfmt/tests/source/single-line-macro/v1.rs new file mode 100644 index 000000000..a3aa631ed --- /dev/null +++ b/src/tools/rustfmt/tests/source/single-line-macro/v1.rs @@ -0,0 +1,10 @@ +// rustfmt-version: One + +// #2652 +// Preserve trailing comma inside macro, even if it looks an array. +macro_rules! bar { + ($m:ident) => { + $m!([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,]); + $m!([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]); + }; +} diff --git a/src/tools/rustfmt/tests/source/single-line-macro/v2.rs b/src/tools/rustfmt/tests/source/single-line-macro/v2.rs new file mode 100644 index 000000000..51a665f75 --- /dev/null +++ b/src/tools/rustfmt/tests/source/single-line-macro/v2.rs @@ -0,0 +1,10 @@ +// rustfmt-version: Two + +// #2652 +// Preserve trailing comma inside macro, even if it looks an array. +macro_rules! bar { + ($m:ident) => { + $m!([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,]); + $m!([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]); + }; +} diff --git a/src/tools/rustfmt/tests/source/soft-wrapping.rs b/src/tools/rustfmt/tests/source/soft-wrapping.rs new file mode 100644 index 000000000..b0682d4db --- /dev/null +++ b/src/tools/rustfmt/tests/source/soft-wrapping.rs @@ -0,0 +1,15 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 80 +// Soft wrapping for comments. + +// #535, soft wrapping for comments +// Compare the lowest `f32` of both inputs for greater than or equal. The +// lowest 32 bits of the result will be `0xffffffff` if `a.extract(0)` is +// ggreater than or equal `b.extract(0)`, or `0` otherwise. The upper 96 bits off +// the result are the upper 96 bits of `a`. + +/// Compares the lowest `f32` of both inputs for greater than or equal. The +/// lowest 32 bits of the result will be `0xffffffff` if `a.extract(0)` is +/// greater than or equal `b.extract(0)`, or `0` otherwise. The upper 96 bits off +/// the result are the upper 96 bits of `a`. +fn foo() {} diff --git a/src/tools/rustfmt/tests/source/space-not-before-newline.rs b/src/tools/rustfmt/tests/source/space-not-before-newline.rs new file mode 100644 index 000000000..2a1e18569 --- /dev/null +++ b/src/tools/rustfmt/tests/source/space-not-before-newline.rs @@ -0,0 +1,8 @@ +struct Foo { + a: (), + // spaces ^^^ to be removed +} +enum Foo { + Bar, + // spaces ^^^ to be removed +} diff --git a/src/tools/rustfmt/tests/source/spaces-around-ranges.rs b/src/tools/rustfmt/tests/source/spaces-around-ranges.rs new file mode 100644 index 000000000..1936b5e16 --- /dev/null +++ b/src/tools/rustfmt/tests/source/spaces-around-ranges.rs @@ -0,0 +1,15 @@ +// rustfmt-spaces_around_ranges: true + +fn bar(v: &[u8]) {} + +fn foo() { + let a = vec![0; 20]; + for j in 0..=20 { + for i in 0..3 { + bar(a[i..j]); + bar(a[i..]); + bar(a[..j]); + bar(a[..=(j + 1)]); + } + } +} diff --git a/src/tools/rustfmt/tests/source/statements.rs b/src/tools/rustfmt/tests/source/statements.rs new file mode 100644 index 000000000..c840b8ce1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/statements.rs @@ -0,0 +1,43 @@ +// FIXME(calebcartwright) - Hopefully one day we can +// elide these redundant semis like we do in other contexts. +fn redundant_item_semis() { + impl Foo { + fn get(&self) -> usize { + 5 + } + }; + + impl Bar { + fn get(&self) -> usize { + 5 + } + } /*asdfsf*/; + + + impl Baz { + fn get(&self) -> usize { + 5 + } + } /*asdfsf*/ + + // why would someone do this + ; + + + impl Qux { + fn get(&self) -> usize { + 5 + } + } + + // why + ; + + impl Lorem { + fn get(&self) -> usize { + 5 + } + } + // oh why + ; +}
\ No newline at end of file diff --git a/src/tools/rustfmt/tests/source/static.rs b/src/tools/rustfmt/tests/source/static.rs new file mode 100644 index 000000000..970786381 --- /dev/null +++ b/src/tools/rustfmt/tests/source/static.rs @@ -0,0 +1,23 @@ +const FILE_GENERIC_READ: DWORD = + STANDARD_RIGHTS_READ | FILE_READ_DATA | + FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE; + +static boolnames: &'static[&'static str] = &["bw", "am", "xsb", "xhp", "xenl", "eo", + "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon", + "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy", + "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"]; + +static mut name: SomeType = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + + pub static count : u8 = 10 ; + +pub const test: &Type = &val; + +impl Color { + pub const WHITE: u32 = 10; +} + +// #1391 +pub const XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: NTSTATUS = 0 as usize; + +pub const XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: Yyyyyyyyyyyyyyyyyyyyyyyyyyyy = 1; diff --git a/src/tools/rustfmt/tests/source/string-lit-2.rs b/src/tools/rustfmt/tests/source/string-lit-2.rs new file mode 100644 index 000000000..6b95e25a0 --- /dev/null +++ b/src/tools/rustfmt/tests/source/string-lit-2.rs @@ -0,0 +1,25 @@ +fn main() -> &'static str { + let too_many_lines = "Hello"; + let leave_me = "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss\ + s + jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"; +} + +fn issue_1237() { + let msg = "eedadn\n\ + drvtee\n\ + eandsr\n\ + raavrd\n\ + atevrs\n\ + tsrnev\n\ + sdttsa\n\ + rasrtv\n\ + nssdts\n\ + ntnada\n\ + svetve\n\ + tesnvt\n\ + vntsnd\n\ + vrdear\n\ + dvrsen\n\ + enarar"; +} diff --git a/src/tools/rustfmt/tests/source/string-lit.rs b/src/tools/rustfmt/tests/source/string-lit.rs new file mode 100644 index 000000000..7719e76ff --- /dev/null +++ b/src/tools/rustfmt/tests/source/string-lit.rs @@ -0,0 +1,61 @@ +// rustfmt-format_strings: true +// Long string literals + +fn main() -> &'static str { + let str = "AAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAaAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAa"; + let str = "AAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAa"; + let str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + let too_many_lines = "H\ + e\ + l\ + l\ + o"; + + // Make sure we don't break after an escape character. + let odd_length_name = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; + let even_length_name = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; + + let really_long_variable_name = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + let raw_string = r#"Do +not +remove +formatting"#; + + filename.replace(" ", "\\" ); + + let xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = + funktion("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"); + + let unicode = "a̐éö̲\r\n"; + let unicode2 = "Löwe 老虎 Léopard"; + let unicode3 = "中华Việt Nam"; + let unicode4 = "☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃"; + + "stuffin'" +} + +fn issue682() { + let a = "hello \\ o/"; + let b = a.replace("\\ ", "\\"); +} + +fn issue716() { + println!("forall x. mult(e(), x) = x /\\ + forall x. mult(x, x) = e()"); +} + +fn issue_1282() { + { + match foo { + Permission::AndroidPermissionAccessLocationExtraCommands => { + "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" + } + } + } +} + +// #1987 +#[link_args = "-s NO_FILESYSTEM=1 -s NO_EXIT_RUNTIME=1 -s EXPORTED_RUNTIME_METHODS=[\"_malloc\"] -s NO_DYNAMIC_EXECUTION=1 -s ELIMINATE_DUPLICATE_FUNCTIONS=1 -s EVAL_CTORS=1"] +extern "C" {} diff --git a/src/tools/rustfmt/tests/source/string_punctuation.rs b/src/tools/rustfmt/tests/source/string_punctuation.rs new file mode 100644 index 000000000..552c461ed --- /dev/null +++ b/src/tools/rustfmt/tests/source/string_punctuation.rs @@ -0,0 +1,9 @@ +// rustfmt-format_strings: true + +fn main() { + println!("ThisIsAReallyLongStringWithNoSpaces.It_should_prefer_to_break_onpunctuation:Likethisssssssssssss"); + format!("{}__{}__{}ItShouldOnlyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyNoticeSemicolonsPeriodsColonsAndCommasAndResortToMid-CharBreaksAfterPunctuation{}{}",x,y,z,a,b); + println!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaalhijalfhiigjapdighjapdigjapdighdapighapdighpaidhg;adopgihadoguaadbadgad,qeoihapethae8t0aet8haetadbjtaeg;ooeouthaoeutgadlgajduabgoiuadogabudogubaodugbadgadgadga;adoughaoeugbaouea"); + println!("sentuhaesnuthaesnutheasunteahusnaethuseantuihaesntdiastnidaetnuhaideuhsenathe。WeShouldSupportNonAsciiPunctuations§ensuhatheasunteahsuneathusneathuasnuhaesnuhaesnuaethusnaetuheasnuth"); + println!("ThisIsASampleOfCJKString.祇園精舍の鐘の声、諸行無常の響きあり。娑羅双樹の花の色、盛者必衰の理をあらはす。奢れる人も久しからず、ただ春の夜の夢のごとし。猛き者もつひにはほろびぬ、ひとへに風の前の塵に同じ。"); +} diff --git a/src/tools/rustfmt/tests/source/struct-field-attributes.rs b/src/tools/rustfmt/tests/source/struct-field-attributes.rs new file mode 100644 index 000000000..76d6eda88 --- /dev/null +++ b/src/tools/rustfmt/tests/source/struct-field-attributes.rs @@ -0,0 +1,52 @@ +// #1535 +#![feature(struct_field_attributes)] + +struct Foo { + bar: u64, + + #[cfg(test)] + qux: u64, +} + +fn do_something() -> Foo { + Foo { + bar: 0, + + #[cfg(test)] + qux: 1, + } +} + +fn main() { + do_something(); +} + +// #1462 +struct Foo { + foo: usize, + #[cfg(feature="include-bar")] + bar: usize, +} + +fn new_foo() -> Foo { + Foo { + foo: 0, + #[cfg(feature="include-bar")] + bar: 0, + } +} + +// #2044 +pub enum State { + Closure(#[cfg_attr(feature = "serde_derive", serde(state_with = "::serialization::closure"))] GcPtr<ClosureData>), +} + +struct Fields( + #[cfg_attr(feature = "serde_derive", serde(state_with = "::base::serialization::shared"))] Arc<Vec<InternedStr>>, +); + +// #2309 +pub struct A { +#[doc="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"] +pub foos:Vec<bool> +} diff --git a/src/tools/rustfmt/tests/source/struct_field_doc_comment.rs b/src/tools/rustfmt/tests/source/struct_field_doc_comment.rs new file mode 100644 index 000000000..191a62100 --- /dev/null +++ b/src/tools/rustfmt/tests/source/struct_field_doc_comment.rs @@ -0,0 +1,72 @@ +// #5215 +struct MyTuple( + /// Doc Comments + /* TODO note to add more to Doc Comments */ u32, + /// Doc Comments + // TODO note + u64, +); + +struct MyTuple( + #[cfg(unix)] // some comment + u64, + #[cfg(not(unix))] /*block comment */ + u32, +); + +struct MyTuple( + #[cfg(unix)] + // some comment + u64, + #[cfg(not(unix))] + /*block comment */ + u32, +); + +struct MyTuple( + #[cfg(unix)] // some comment + pub u64, + #[cfg(not(unix))] /*block comment */ + pub(crate) u32, +); + +struct MyTuple( + /// Doc Comments + /* TODO note to add more to Doc Comments */ + pub u32, + /// Doc Comments + // TODO note + pub(crate) u64, +); + +struct MyStruct { + #[cfg(unix)] // some comment + a: u64, + #[cfg(not(unix))] /*block comment */ + b: u32, +} + +struct MyStruct { + #[cfg(unix)] // some comment + pub a: u64, + #[cfg(not(unix))] /*block comment */ + pub(crate) b: u32, +} + +struct MyStruct { + /// Doc Comments + /* TODO note to add more to Doc Comments */ + a: u32, + /// Doc Comments + // TODO note + b: u64, +} + +struct MyStruct { + /// Doc Comments + /* TODO note to add more to Doc Comments */ + pub a: u32, + /// Doc Comments + // TODO note + pub(crate) b: u64, +} diff --git a/src/tools/rustfmt/tests/source/struct_lits.rs b/src/tools/rustfmt/tests/source/struct_lits.rs new file mode 100644 index 000000000..c5aaf7ef8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/struct_lits.rs @@ -0,0 +1,143 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// Struct literal expressions. + +fn main() { + let x = Bar; + + // Comment + let y = Foo {a: x }; + + Foo { a: foo() /* comment*/, /* comment*/ b: bar(), ..something }; + + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: f(), b: b(), }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: f(), b: b(), }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + // Comment + a: foo(), // Comment + // Comment + b: bar(), // Comment + }; + + Foo { a:Bar, + b:f() }; + + Quux { x: if cond { bar(); }, y: baz() }; + + A { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item + }; + + Some(Data::MethodCallData(MethodCallData { + span: sub_span.unwrap(), + scope: self.enclosing_scope(id), + ref_id: def_id, + decl_id: Some(decl_id), + })); + + Diagram { /* o This graph demonstrates how + * / \ significant whitespace is + * o o preserved. + * /|\ \ + * o o o o */ + graph: G, } +} + +fn matcher() { + TagTerminatedByteMatcher { + matcher: ByteMatcher { + pattern: b"<HTML", + mask: b"\xFF\xDF\xDF\xDF\xDF\xFF", + }, + }; +} + +fn issue177() { + struct Foo<T> { memb: T } + let foo = Foo::<i64> { memb: 10 }; +} + +fn issue201() { + let s = S{a:0, .. b}; +} + +fn issue201_2() { + let s = S{a: S2{ .. c}, .. b}; +} + +fn issue278() { + let s = S { + a: 0, + // + b: 0, + }; + let s1 = S { + a: 0, + // foo + // + // bar + b: 0, + }; +} + +fn struct_exprs() { + Foo + { a : 1, b:f( 2)}; + Foo{a:1,b:f(2),..g(3)}; + LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongStruct { ..base }; + IntrinsicISizesContribution { content_intrinsic_sizes: IntrinsicISizes { minimum_inline_size: 0, }, }; +} + +fn issue123() { + Foo { a: b, c: d, e: f }; + + Foo { a: bb, c: dd, e: ff }; + + Foo { a: ddddddddddddddddddddd, b: cccccccccccccccccccccccccccccccccccccc }; +} + +fn issue491() { + Foo { + guard: None, + arm: 0, // Comment + }; + + Foo { + arm: 0, // Comment + }; + + Foo { a: aaaaaaaaaa, b: bbbbbbbb, c: cccccccccc, d: dddddddddd, /* a comment */ + e: eeeeeeeee }; +} + +fn issue698() { + Record { + ffffffffffffffffffffffffffields: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + }; + Record { + ffffffffffffffffffffffffffields: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + } +} + +fn issue835() { + MyStruct {}; + MyStruct { /* a comment */ }; + MyStruct { + // Another comment + }; + MyStruct {} +} + +fn field_init_shorthand() { + MyStruct { x, y, z }; + MyStruct { x, y, z, .. base }; + Foo { aaaaaaaaaa, bbbbbbbb, cccccccccc, dddddddddd, /* a comment */ + eeeeeeeee }; + Record { ffffffffffffffffffffffffffieldsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa }; +} diff --git a/src/tools/rustfmt/tests/source/struct_lits_multiline.rs b/src/tools/rustfmt/tests/source/struct_lits_multiline.rs new file mode 100644 index 000000000..256ba1bbd --- /dev/null +++ b/src/tools/rustfmt/tests/source/struct_lits_multiline.rs @@ -0,0 +1,81 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-struct_lit_single_line: false + +// Struct literal expressions. + +fn main() { + let x = Bar; + + // Comment + let y = Foo {a: x }; + + Foo { a: foo() /* comment*/, /* comment*/ b: bar(), ..something }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(), b: bar(), }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(), b: bar(), }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + // Comment + a: foo(), // Comment + // Comment + b: bar(), // Comment + }; + + Foo { a:Bar, + b:foo() }; + + Quux { x: if cond { bar(); }, y: baz() }; + + A { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item + }; + + Some(Data::MethodCallData(MethodCallData { + span: sub_span.unwrap(), + scope: self.enclosing_scope(id), + ref_id: def_id, + decl_id: Some(decl_id), + })); + + Diagram { /* o This graph demonstrates how + * / \ significant whitespace is + * o o preserved. + * /|\ \ + * o o o o */ + graph: G, } +} + +fn matcher() { + TagTerminatedByteMatcher { + matcher: ByteMatcher { + pattern: b"<HTML", + mask: b"\xFF\xDF\xDF\xDF\xDF\xFF", + }, + }; +} + +fn issue177() { + struct Foo<T> { memb: T } + let foo = Foo::<i64> { memb: 10 }; +} + +fn issue201() { + let s = S{a:0, .. b}; +} + +fn issue201_2() { + let s = S{a: S2{ .. c}, .. b}; +} + +fn issue491() { + Foo { + guard: None, + arm: 0, // Comment + }; +} diff --git a/src/tools/rustfmt/tests/source/struct_lits_visual.rs b/src/tools/rustfmt/tests/source/struct_lits_visual.rs new file mode 100644 index 000000000..e84652e9e --- /dev/null +++ b/src/tools/rustfmt/tests/source/struct_lits_visual.rs @@ -0,0 +1,46 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-indent_style: Visual + +// Struct literal expressions. + +fn main() { + let x = Bar; + + // Comment + let y = Foo {a: x }; + + Foo { a: foo() /* comment*/, /* comment*/ b: bar(), ..something }; + + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: f(), b: b(), }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + // Comment + a: foo(), // Comment + // Comment + b: bar(), // Comment + }; + + Foo { a:Bar, + b:f() }; + + Quux { x: if cond { bar(); }, y: baz() }; + + Baz { x: yxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, z: zzzzz // test + }; + + A { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item + }; + + Diagram { /* o This graph demonstrates how + * / \ significant whitespace is + * o o preserved. + * /|\ \ + * o o o o */ + graph: G, } +} diff --git a/src/tools/rustfmt/tests/source/struct_lits_visual_multiline.rs b/src/tools/rustfmt/tests/source/struct_lits_visual_multiline.rs new file mode 100644 index 000000000..d2990f8da --- /dev/null +++ b/src/tools/rustfmt/tests/source/struct_lits_visual_multiline.rs @@ -0,0 +1,44 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-indent_style: Visual +// rustfmt-struct_lit_single_line: false + +// Struct literal expressions. + +fn main() { + let x = Bar; + + // Comment + let y = Foo {a: x }; + + Foo { a: foo() /* comment*/, /* comment*/ b: bar(), ..something }; + + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(), b: bar(), }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + // Comment + a: foo(), // Comment + // Comment + b: bar(), // Comment + }; + + Foo { a:Bar, + b:foo() }; + + Quux { x: if cond { bar(); }, y: baz() }; + + A { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item + }; + + Diagram { /* o This graph demonstrates how + * / \ significant whitespace is + * o o preserved. + * /|\ \ + * o o o o */ + graph: G, } +} diff --git a/src/tools/rustfmt/tests/source/struct_tuple_visual.rs b/src/tools/rustfmt/tests/source/struct_tuple_visual.rs new file mode 100644 index 000000000..f95f3fe4f --- /dev/null +++ b/src/tools/rustfmt/tests/source/struct_tuple_visual.rs @@ -0,0 +1,36 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-indent_style: Visual +fn foo() { + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(f(), b()); + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(// Comment + foo(), /* Comment */ + // Comment + bar() /* Comment */); + + Foo(Bar, f()); + + Quux(if cond { + bar(); + }, + baz()); + + Baz(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + zzzzz /* test */); + + A(// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit + // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante + // hendrerit. Donec et mollis dolor. + item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + Item); + + Diagram(// o This graph demonstrates how + // / \ significant whitespace is + // o o preserved. + // /|\ \ + // o o o o + G) +} diff --git a/src/tools/rustfmt/tests/source/structs.rs b/src/tools/rustfmt/tests/source/structs.rs new file mode 100644 index 000000000..537151b27 --- /dev/null +++ b/src/tools/rustfmt/tests/source/structs.rs @@ -0,0 +1,298 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + + /// A Doc comment +#[AnAttribute] +pub struct Foo { + #[rustfmt::skip] + f : SomeType, // Comment beside a field + f: SomeType, // Comment beside a field + // Comment on a field + #[AnAttribute] + g: SomeOtherType, + /// A doc comment on a field + h: AThirdType, + pub i: TypeForPublicField +} + +// Destructuring +fn foo() { + S { x: 5, + ..}; + Struct {..} = Struct { a: 1, b: 4 }; + Struct { a, .. } = Struct { a: 1, b: 2, c: 3}; + TupleStruct(a,.., b) = TupleStruct(1, 2); + TupleStruct( ..) = TupleStruct(3, 4); + TupleStruct(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, .., bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) = TupleStruct(1, 2); +} + +// #1095 +struct S<T: /* comment */> { + t: T, +} + +// #1029 +pub struct Foo { + #[doc(hidden)] + // This will NOT get deleted! + bar: String, // hi +} + +// #1029 +struct X { + // `x` is an important number. + #[allow(unused)] // TODO: use + x: u32, +} + +// #410 +#[allow(missing_docs)] +pub struct Writebatch<K: Key> { + #[allow(dead_code)] //only used for holding the internal pointer + writebatch: RawWritebatch, + marker: PhantomData<K>, +} + +struct Bar; + +struct NewType(Type, OtherType); + +struct +NewInt <T: Copy>(pub i32, SomeType /* inline comment */, T /* sup */ + + + ); + +struct Qux<'a, + N: Clone + 'a, + E: Clone + 'a, + G: Labeller<'a, N, E> + GraphWalk<'a, N, E>, + W: Write + Copy> +( + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // Comment + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, + #[AnAttr] + // Comment + /// Testdoc + G, + pub W, +); + +struct Tuple(/*Comment 1*/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + /* Comment 2 */ BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,); + +// With a where-clause and generics. +pub struct Foo<'a, Y: Baz> + where X: Whatever +{ + f: SomeType, // Comment beside a field +} + +struct Baz { + + a: A, // Comment A + b: B, // Comment B + c: C, // Comment C + +} + +struct Baz { + a: A, // Comment A + + b: B, // Comment B + + + + + c: C, // Comment C +} + +struct Baz { + + a: A, + + b: B, + c: C, + + + + + d: D + +} + +struct Baz +{ + // Comment A + a: A, + + // Comment B +b: B, + // Comment C + c: C,} + +// Will this be a one-liner? +struct Tuple( + A, //Comment + B +); + +pub struct State<F: FnMut() -> time::Timespec> { now: F } + +pub struct State<F: FnMut() -> ()> { now: F } + +pub struct State<F: FnMut()> { now: F } + +struct Palette { /// A map of indices in the palette to a count of pixels in approximately that color + foo: i32} + +// Splitting a single line comment into a block previously had a misalignment +// when the field had attributes +struct FieldsWithAttributes { + // Pre Comment + #[rustfmt::skip] pub host:String, // Post comment BBBBBBBBBBBBBB BBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBB BBBBBBBBBBB + //Another pre comment + #[attr1] + #[attr2] pub id: usize // CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCC CCCCCCCCCCCC +} + +struct Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: node::Handle<IdRef<'id, Node<K, V>>, + Type, + NodeType>, +} + +struct Foo<T>(T); +struct Foo<T>(T) where T: Copy, T: Eq; +struct Foo<T>(TTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUU); +struct Foo<T>(TTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTT) where T: PartialEq; +struct Foo<T>(TTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTTTT) where T: PartialEq; +struct Foo<T>(TTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUUUUUU, TTTTTTTTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUU) where T: PartialEq; +struct Foo<T>(TTTTTTTTTTTTTTTTT, // Foo + UUUUUUUUUUUUUUUUUUUUUUUU /* Bar */, + // Baz + TTTTTTTTTTTTTTTTTTT, + // Qux (FIXME #572 - doc comment) + UUUUUUUUUUUUUUUUUUU); + +mod m { + struct X<T> where T: Sized { + a: T, + } +} + +struct Foo<T>(TTTTTTTTTTTTTTTTTTT, + /// Qux + UUUUUUUUUUUUUUUUUUU); + +struct Issue677 { + pub ptr: *const libc::c_void, + pub trace: fn( obj: + *const libc::c_void, tracer : *mut JSTracer ), +} + +struct Foo {} +struct Foo { + } +struct Foo { + // comment + } +struct Foo { + // trailing space -> + + + } +struct Foo { /* comment */ } +struct Foo( /* comment */ ); + +struct LongStruct { + a: A, + the_quick_brown_fox_jumps_over_the_lazy_dog:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +} + +struct Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: node::Handle<IdRef<'id, Node<Key, Value>>, + Type, + NodeType>, +} + +struct Foo<C=()>(String); + +// #1364 +fn foo() { + convex_shape.set_point(0, &Vector2f { x: 400.0, y: 100.0 }); + convex_shape.set_point(1, &Vector2f { x: 500.0, y: 70.0 }); + convex_shape.set_point(2, &Vector2f { x: 450.0, y: 100.0 }); + convex_shape.set_point(3, &Vector2f { x: 580.0, y: 150.0 }); +} + +// Vertical alignment +struct Foo { + aaaaa: u32, // a + + b: u32, // b + cc: u32, // cc + + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 1 + yy: u32, // comment2 + zzz: u32, // comment3 + + aaaaaa: u32, // comment4 + bb: u32, // comment5 + // separate + dd: u32, // comment7 + c: u32, // comment6 + + aaaaaaa: u32, /* multi + * line + * comment + */ + b: u32, // hi + + do_not_push_this_comment1: u32, // comment1 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + please_do_not_push_this_comment3: u32, // comment3 + + do_not_push_this_comment1: u32, // comment1 + // separate + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + please_do_not_push_this_comment3: u32, // comment3 + + do_not_push_this_comment1: u32, // comment1 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + // separate + please_do_not_push_this_comment3: u32, // comment3 +} + +// structs with long identifier +struct Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong {} +struct Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong {} +struct Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong {} +struct Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong { x: i32 } + +// structs with visibility, do not duplicate visibility (#2110). +pub(in self) struct Foo{} +pub(super) struct Foo{} +pub(crate) struct Foo{} +pub(in self) struct Foo(); +pub(super) struct Foo(); +pub(crate) struct Foo(); + +// #2125 +pub struct ReadinessCheckRegistry(Mutex<HashMap<Arc<String>, Box<Fn() -> ReadinessCheck + Sync + Send>>>); + +// #2144 unit struct with generics +struct MyBox<T:?Sized>; +struct MyBoxx<T, S> where T: ?Sized, S: Clone; + +// #2208 +struct Test { + /// foo + #[serde(default)] + pub join: Vec<String>, + #[serde(default)] pub tls: bool, +} + +// #2818 +struct Paren((i32)) where i32: Trait; +struct Parens((i32, i32)) where i32: Trait; diff --git a/src/tools/rustfmt/tests/source/trailing-comma-never.rs b/src/tools/rustfmt/tests/source/trailing-comma-never.rs new file mode 100644 index 000000000..c74267cd1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/trailing-comma-never.rs @@ -0,0 +1,45 @@ +// rustfmt-trailing_comma: Never + +enum X { + A, + B, +} + +enum Y { + A, + B +} + +enum TupX { + A(u32), + B(i32, u16), +} + +enum TupY { + A(u32), + B(i32, u16) +} + +enum StructX { + A { + s: u16, + }, + B { + u: u32, + i: i32, + }, +} + +enum StructY { + A { + s: u16, + }, + B { + u: u32, + i: i32, + } +} + +static XXX: [i8; 64] = [ +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1, 1, 1, +]; diff --git a/src/tools/rustfmt/tests/source/trailing_commas.rs b/src/tools/rustfmt/tests/source/trailing_commas.rs new file mode 100644 index 000000000..3e5fcc808 --- /dev/null +++ b/src/tools/rustfmt/tests/source/trailing_commas.rs @@ -0,0 +1,47 @@ +// rustfmt-match_block_trailing_comma: true +// rustfmt-trailing_comma: Always + +fn main() { + match foo { + x => {} + y => { + foo(); + } + _ => x + } +} + +fn f<S, T>(x: T, y: S) -> T where T: P, S: Q +{ + x +} + +impl Trait for T where T: P +{ + fn f(x: T) -> T where T: Q + R + { + x + } +} + +struct Pair<S, T> where T: P, S: P + Q { + a: T, + b: S +} + +struct TupPair<S, T> (S, T) where T: P, S: P + Q; + +enum E<S, T> where S: P, T: P { + A {a: T}, +} + +type Double<T> where T: P, T: Q = Pair<T, T>; + +extern "C" { + fn f<S, T>(x: T, y: S) -> T where T: P, S: Q; +} + +trait Q<S, T> where T: P, S: R +{ + fn f<U, V>(self, x: T, y: S, z: U) -> Self where U: P, V: P; +} diff --git a/src/tools/rustfmt/tests/source/trailing_comments/hard_tabs.rs b/src/tools/rustfmt/tests/source/trailing_comments/hard_tabs.rs new file mode 100644 index 000000000..88249aa5f --- /dev/null +++ b/src/tools/rustfmt/tests/source/trailing_comments/hard_tabs.rs @@ -0,0 +1,21 @@ +// rustfmt-version: Two +// rustfmt-wrap_comments: true +// rustfmt-hard_tabs: true + +impl Foo { + fn foo() { + bar(); // comment 1 + // comment 2 + // comment 3 + baz(); + } +} + +fn lorem_ipsum() { + let f = bar(); // Donec consequat mi. Quisque vitae dolor. Integer lobortis. Maecenas id nulla. Lorem. + // Id turpis. Nam posuere lectus vitae nibh. Etiam tortor orci, sagittis malesuada, rhoncus quis, hendrerit eget, libero. Quisque commodo nulla at nunc. Mauris consequat, enim vitae venenatis sollicitudin, dolor orci bibendum enim, a sagittis nulla nunc quis elit. Phasellus augue. Nunc suscipit, magna tincidunt lacinia faucibus, lacus tellus ornare purus, a pulvinar lacus orci eget nibh. Maecenas sed nibh non lacus tempor faucibus. In hac habitasse platea dictumst. Vivamus a orci at nulla tristique condimentum. Donec arcu quam, dictum accumsan, convallis accumsan, cursus sit amet, ipsum. In pharetra sagittis nunc. + let b = baz(); + + let normalized = self.ctfont.all_traits().normalized_weight(); // [-1.0, 1.0] + // TODO(emilio): It may make sense to make this range [.01, 10.0], to align with css-fonts-4's range of [1, 1000]. +} diff --git a/src/tools/rustfmt/tests/source/trailing_comments/soft_tabs.rs b/src/tools/rustfmt/tests/source/trailing_comments/soft_tabs.rs new file mode 100644 index 000000000..7845f713b --- /dev/null +++ b/src/tools/rustfmt/tests/source/trailing_comments/soft_tabs.rs @@ -0,0 +1,21 @@ +// rustfmt-version: Two +// rustfmt-wrap_comments: true + +pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast +// Multicast using broadcst. add. + +pub const SQ_CRETAB: u16 = 0x000e; // CREATE TABLE +pub const SQ_DRPTAB: u16 = 0x000f; // DROP TABLE +pub const SQ_CREIDX: u16 = 0x0010; // CREATE INDEX +//const SQ_DRPIDX: u16 = 0x0011; // DROP INDEX +//const SQ_GRANT: u16 = 0x0012; // GRANT +//const SQ_REVOKE: u16 = 0x0013; // REVOKE + +fn foo() { + let f = bar(); // Donec consequat mi. Quisque vitae dolor. Integer lobortis. Maecenas id nulla. Lorem. + // Id turpis. Nam posuere lectus vitae nibh. Etiam tortor orci, sagittis malesuada, rhoncus quis, hendrerit eget, libero. Quisque commodo nulla at nunc. Mauris consequat, enim vitae venenatis sollicitudin, dolor orci bibendum enim, a sagittis nulla nunc quis elit. Phasellus augue. Nunc suscipit, magna tincidunt lacinia faucibus, lacus tellus ornare purus, a pulvinar lacus orci eget nibh. Maecenas sed nibh non lacus tempor faucibus. In hac habitasse platea dictumst. Vivamus a orci at nulla tristique condimentum. Donec arcu quam, dictum accumsan, convallis accumsan, cursus sit amet, ipsum. In pharetra sagittis nunc. + let b = baz(); + + let normalized = self.ctfont.all_traits().normalized_weight(); // [-1.0, 1.0] + // TODO(emilio): It may make sense to make this range [.01, 10.0], to align with css-fonts-4's range of [1, 1000]. +} diff --git a/src/tools/rustfmt/tests/source/trait.rs b/src/tools/rustfmt/tests/source/trait.rs new file mode 100644 index 000000000..b6db9e159 --- /dev/null +++ b/src/tools/rustfmt/tests/source/trait.rs @@ -0,0 +1,183 @@ +// Test traits + +trait Foo { + fn bar(x: i32 ) -> Baz< U> { Baz::new() + } + + fn baz(a: AAAAAAAAAAAAAAAAAAAAAA, +b: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB) +-> RetType; + + fn foo(a: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // Another comment +b: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB) + -> RetType ; // Some comment + + fn baz(&mut self ) -> i32 ; + +fn increment(& mut self, x: i32 ); + + fn read(&mut self, x: BufReader<R> /* Used to be MemReader */) + where R: Read; +} + +pub trait WriteMessage { + fn write_message (&mut self, &FrontendMessage) -> io::Result<()>; +} + +trait Runnable { + fn handler(self: & Runnable ); +} + +trait TraitWithExpr { + fn fn_with_expr(x: [i32; 1]); +} + +trait Test { + fn read_struct<T, F>(&mut self, s_name: &str, len: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error>; +} + +trait T<> {} + +trait Foo { type Bar: Baz; type Inner: Foo = Box< Foo >; } + +trait ConstCheck<T>:Foo where T: Baz { + const J: i32; +} + +trait Tttttttttttttttttttttttttttttttttttttttttttttttttttttttttt<T> + where T: Foo {} + +trait Ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt<T> where T: Foo {} + +trait FooBar<T> : Tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt where J: Bar { fn test(); } + +trait WhereList<T, J> where T: Foo, J: Bar {} + +trait X /* comment */ {} +trait Y // comment +{ +} + +// #2055 +pub trait Foo: +// A and C +A + C +// and B + + B +{} + +// #2158 +trait Foo { + type ItRev = <MergingUntypedTimeSeries<SliceSeries<SliceWindow>> as UntypedTimeSeries>::IterRev; + type IteRev = <MergingUntypedTimeSeries<SliceSeries<SliceWindow>> as UntypedTimeSeries>::IterRev; +} + +// #2331 +trait MyTrait<AAAAAAAAAAAAAAAAAAAA, BBBBBBBBBBBBBBBBBBBB, CCCCCCCCCCCCCCCCCCCC, DDDDDDDDDDDDDDDDDDDD> { + fn foo() {} +} + +// Trait aliases +trait FooBar = + Foo + + Bar; +trait FooBar <A, B, C>= + Foo + + Bar; +pub trait FooBar = + Foo + + Bar; +pub trait FooBar <A, B, C>= + Foo + + Bar; +trait AAAAAAAAAAAAAAAAAA = BBBBBBBBBBBBBBBBBBB + CCCCCCCCCCCCCCCCCCCCCCCCCCCCC + DDDDDDDDDDDDDDDDDD; +pub trait AAAAAAAAAAAAAAAAAA = BBBBBBBBBBBBBBBBBBB + CCCCCCCCCCCCCCCCCCCCCCCCCCCCC + DDDDDDDDDDDDDDDDDD; +trait AAAAAAAAAAAAAAAAAAA = BBBBBBBBBBBBBBBBBBB + CCCCCCCCCCCCCCCCCCCCCCCCCCCCC + DDDDDDDDDDDDDDDDDD; +trait AAAAAAAAAAAAAAAAAA = BBBBBBBBBBBBBBBBBBB + CCCCCCCCCCCCCCCCCCCCCCCCCCCCC + DDDDDDDDDDDDDDDDDDD; +trait AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<A, B, C, D, E> = FooBar; +trait AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<A, B, C, D, E> = FooBar; +#[rustfmt::skip] +trait FooBar = Foo + + Bar; + +// #2637 +auto trait Example {} +pub auto trait PubExample {} +pub unsafe auto trait PubUnsafeExample {} + +// #3006 +trait Foo<'a> { + type Bar< 'a >; +} + +impl<'a> Foo<'a> for i32 { + type Bar< 'a > = i32; +} + +// #3092 +pub mod test { + pub trait ATraitWithALooongName {} + pub trait ATrait + :ATraitWithALooongName + ATraitWithALooongName + ATraitWithALooongName + ATraitWithALooongName +{ +} +} + +// Trait aliases with where clauses. +trait A = where for<'b> &'b Self: Send; + +trait B = where for<'b> &'b Self: Send + Clone + Copy + SomeTrait + AAAAAAAA + BBBBBBB + CCCCCCCCCC; +trait B = where for<'b> &'b Self: Send + Clone + Copy + SomeTrait + AAAAAAAA + BBBBBBB + CCCCCCCCCCC; +trait B = where + for<'b> &'b Self: +Send + Clone + Copy + SomeTrait + AAAAAAAA + BBBBBBB + CCCCCCCCCCCCCCCCCCCCCCC; +trait B = where + for<'b> &'b Self: +Send + Clone + Copy + SomeTrait + AAAAAAAA + BBBBBBB + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC; + +trait B = where + for<'b> &'b Self: +Send + + Clone + + Copy + + SomeTrait + + AAAAAAAA + + BBBBBBB + + CCCCCCCCC + + DDDDDDD + + DDDDDDDD + + DDDDDDDDD + + EEEEEEE; + +trait A<'a, 'b, 'c> = Debug<T> + Foo where for<'b> &'b Self: Send; + +trait B<'a, 'b, 'c> = Debug<T> +Foo +where for<'b> &'b Self: +Send + + Clone + + Copy + + SomeTrait + + AAAAAAAA + + BBBBBBB + + CCCCCCCCC + + DDDDDDD; + +trait B<'a, 'b, 'c,T> = Debug<'a, T> where for<'b> &'b Self: +Send + + Clone + + Copy + + SomeTrait + + AAAAAAAA + + BBBBBBB + + CCCCCCCCC + + DDDDDDD + + DDDDDDDD + + DDDDDDDDD + + EEEEEEE; + +trait Visible { + pub const C: i32; + pub type T; + pub fn f(); + pub fn g() {} +} diff --git a/src/tools/rustfmt/tests/source/try-conversion.rs b/src/tools/rustfmt/tests/source/try-conversion.rs new file mode 100644 index 000000000..ed83ee9e1 --- /dev/null +++ b/src/tools/rustfmt/tests/source/try-conversion.rs @@ -0,0 +1,18 @@ +// rustfmt-use_try_shorthand: true + +fn main() { + let x = try!(some_expr()); + + let y = try!(a.very.loooooooooooooooooooooooooooooooooooooong().chain().inside().weeeeeeeeeeeeeee()).test().0.x; +} + +fn test() { + a? +} + +fn issue1291() { + try!(fs::create_dir_all(&gitfiledir).chain_err(|| { + format!("failed to create the {} submodule directory for the workarea", + name) + })); +} diff --git a/src/tools/rustfmt/tests/source/try_block.rs b/src/tools/rustfmt/tests/source/try_block.rs new file mode 100644 index 000000000..2e8d61f7e --- /dev/null +++ b/src/tools/rustfmt/tests/source/try_block.rs @@ -0,0 +1,30 @@ +// rustfmt-edition: 2018 + +fn main() -> Result<(), !> { + let _x: Option<_> = try { + 4 + }; + + try {} +} + +fn baz() -> Option<i32> { + if (1 == 1) { + return try { + 5 + }; + } + + // test + let x: Option<()> = try { + // try blocks are great + }; + + let y: Option<i32> = try { + 6 + }; // comment + + let x: Option<i32> = try { baz()?; baz()?; baz()?; 7 }; + + return None; +} diff --git a/src/tools/rustfmt/tests/source/tuple.rs b/src/tools/rustfmt/tests/source/tuple.rs new file mode 100644 index 000000000..9a0f979fb --- /dev/null +++ b/src/tools/rustfmt/tests/source/tuple.rs @@ -0,0 +1,63 @@ +// Test tuple litterals + +fn foo() { + let a = (a, a, a, a, a); + let aaaaaaaaaaaaaaaa = (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaa, aaaaaaaaaaaaaa); + let aaaaaaaaaaaaaaaaaaaaaa = (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaaaaaaaaaaaaa, + aaaa); + let a = (a,); + + let b = (// This is a comment + b, // Comment + b /* Trailing comment */); + + // #1063 + foo(x.0 .0); +} + +fn a() { + ((aaaaaaaa, + aaaaaaaaaaaaa, + aaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaa, + aaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaa),) +} + +fn b() { + ((bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb), + bbbbbbbbbbbbbbbbbb) +} + +fn issue550() { + self.visitor.visit_volume(self.level.sector_id(sector), (floor_y, + if is_sky_flat(ceil_tex) {from_wad_height(self.height_range.1)} else {ceil_y})); +} + +fn issue775() { + if indent { + let a = mk_object(&[("a".to_string(), Boolean(true)), + ("b".to_string(), + Array(vec![mk_object(&[("c".to_string(), + String("\x0c\r".to_string()))]), + mk_object(&[("d".to_string(), String("".to_string()))])]))]); + } +} + +fn issue1725() { + bench_antialiased_lines!(bench_draw_antialiased_line_segment_diagonal, (10, 10), (450, 450)); + bench_antialiased_lines!(bench_draw_antialiased_line_segment_shallow, (10, 10), (450, 80)); +} + +fn issue_4355() { + let _ = ((1,),).0.0; +} + +// https://github.com/rust-lang/rustfmt/issues/4410 +impl Drop for LockGuard { + fn drop(&mut self) { + LockMap::unlock(&self.0.0, &self.0.1); + } +} diff --git a/src/tools/rustfmt/tests/source/tuple_v2.rs b/src/tools/rustfmt/tests/source/tuple_v2.rs new file mode 100644 index 000000000..922303383 --- /dev/null +++ b/src/tools/rustfmt/tests/source/tuple_v2.rs @@ -0,0 +1,5 @@ +// rustfmt-version: Two + +fn issue_4355() { + let _ = ((1,),).0 .0; +} diff --git a/src/tools/rustfmt/tests/source/type-ascription.rs b/src/tools/rustfmt/tests/source/type-ascription.rs new file mode 100644 index 000000000..4874094cc --- /dev/null +++ b/src/tools/rustfmt/tests/source/type-ascription.rs @@ -0,0 +1,10 @@ + +fn main() { + let xxxxxxxxxxx = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy : SomeTrait<AA, BB, CC>; + + let xxxxxxxxxxxxxxx = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; + + let z = funk(yyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, wwwwww): AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; + + x : u32 - 1u32 / 10f32 : u32 +} diff --git a/src/tools/rustfmt/tests/source/type.rs b/src/tools/rustfmt/tests/source/type.rs new file mode 100644 index 000000000..61ef73a3c --- /dev/null +++ b/src/tools/rustfmt/tests/source/type.rs @@ -0,0 +1,168 @@ +// rustfmt-normalize_comments: true +fn types() { + let x: [ Vec < _ > ] = []; + let y: * mut [ SomeType ; konst_funk() ] = expr(); + let z: (/*#digits*/ usize, /*exp*/ i16) = funk(); + let z: ( usize /*#digits*/ , i16 /*exp*/ ) = funk(); +} + +struct F { + f: extern "C" fn(x: u8, ... /* comment */), + g: extern "C" fn(x: u8,/* comment */ ...), + h: extern "C" fn(x: u8, ... ), + i: extern "C" fn(x: u8, /* comment 4*/ y: String, // comment 3 + z: Foo, /* comment */ .../* comment 2*/ ), +} + +fn issue_1006(def_id_to_string: for<'a, 'b> unsafe fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String) {} + +fn impl_trait_fn_1() -> impl Fn(i32) -> Option<u8> {} + +fn impl_trait_fn_2<E>() -> impl Future<Item=&'a i64,Error=E> {} + +fn issue_1234() { + do_parse!(name: take_while1!(is_token) >> (Header)) +} + +// #2510 +impl CombineTypes { + pub fn pop_callback( + &self, + query_id: Uuid, + ) -> Option< + ( + ProjectId, + Box<FnMut(&ProjectState, serde_json::Value, bool) -> () + Sync + Send>, + ), + > { + self.query_callbacks()(&query_id) + } +} + +// #2859 +pub fn do_something<'a, T: Trait1 + Trait2 + 'a>(&fooo: u32) -> impl Future< + Item = ( + impl Future<Item = ( + ), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, +impl Future<Item = (), Error = SomeError > + 'a, + ), + Error = SomeError, + > + + + 'a { +} + +pub fn do_something<'a, T: Trait1 + Trait2 + 'a>( &fooo: u32, +) -> impl Future< + Item = ( +impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + ), + Error = SomeError, + > + + Future< + Item = ( + impl Future<Item = (), Error = SomeError> + 'a, +impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + ), + Error = SomeError, + > + + Future< + Item = ( + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + ), + Error = SomeError, + > + + + 'a + 'b + + 'c { +} + +// #3051 +token![impl]; +token![ impl ]; + +// #3060 +macro_rules! foo { + ($foo_api: ty) => { + type Target = ( $foo_api ) + 'static; + } +} + +type Target = ( FooAPI ) + 'static; + +// #3137 +fn foo<T>(t: T) +where + T: ( FnOnce() -> () ) + Clone, + U: ( FnOnce() -> () ) + 'static, +{ +} + +// #3117 +fn issue3117() { + { + { + { + { + { + { + { + { + let opt: &mut Option<MyLongTypeHere> = + unsafe { &mut *self.future.get() }; + } + } + } + } + } + } + } + } +} + +// #3139 +fn issue3139() { + assert_eq!( + to_json_value(&None :: <i32>).unwrap(), + json!( { "test": None :: <i32> } ) + ); +} + +// #3180 +fn foo(a: SomeLongComplexType, b: SomeOtherLongComplexType) -> Box<Future<Item = AnotherLongType, Error = ALongErrorType>> { +} + +type MyFn = fn(a: SomeLongComplexType, b: SomeOtherLongComplexType,) -> Box<Future<Item = AnotherLongType, Error = ALongErrorType>>; + +// Const bound + +trait T: ~ const Super {} + +const fn not_quite_const<S: ~ const T>() -> i32 { <S as T>::CONST } + +struct S<T:~ const ? Sized>(std::marker::PhantomData<T>); + +impl ~ const T {} + +fn apit(_: impl ~ const T) {} + +fn rpit() -> impl ~ const T { S } + +pub struct Foo<T: Trait>(T); +impl<T: ~ const Trait> Foo<T> { + fn new(t: T) -> Self { + Self(t) + } +} + +// #4357 +type T = typeof( +1); +impl T for .. { +} diff --git a/src/tools/rustfmt/tests/source/type_alias.rs b/src/tools/rustfmt/tests/source/type_alias.rs new file mode 100644 index 000000000..58c807f40 --- /dev/null +++ b/src/tools/rustfmt/tests/source/type_alias.rs @@ -0,0 +1,34 @@ +// rustfmt-normalize_comments: true + +type PrivateTest<'a, I> = (Box<Parser<Input=I, Output=char> + 'a>, Box<Parser<Input=I, Output=char> + 'a>); + +pub type PublicTest<'a, I, O> = Result<Vec<MyLongType>, Box<Parser<Input=I, Output=char> + 'a>, Box<Parser<Input=I, Output=char> + 'a>>; + +pub type LongGenericListTest<'a, 'b, 'c, 'd, LONGPARAMETERNAME, LONGPARAMETERNAME, LONGPARAMETERNAME, A, B, C> = Option<Vec<MyType>>; + +pub type Exactly100CharsTest<'a, 'b, 'c, 'd, LONGPARAMETERNAME, LONGPARAMETERNAME, A, B> = Vec<i32>; + +pub type Exactly101CharsTest<'a, 'b, 'c, 'd, LONGPARAMETERNAME, LONGPARAMETERNAME, A, B> = Vec<Test>; + +pub type Exactly100CharsToEqualTest<'a, 'b, 'c, 'd, LONGPARAMETERNAME, LONGPARAMETERNAME, A, B, C> = Vec<i32>; + +pub type GenericsFitButNotEqualTest<'a, 'b, 'c, 'd, LONGPARAMETERNAME, LONGPARAMETERNAME, A1, B, C> = Vec<i32>; + +pub type CommentTest< /* Lifetime */ 'a + , + // Type + T + > = (); + + +pub type WithWhereClause<LONGPARAMETERNAME, T> where T: Clone, LONGPARAMETERNAME: Clone + Eq + OtherTrait = Option<T>; + +pub type Exactly100CharstoEqualWhereTest<T, U, PARAMET> where T: Clone + Ord + Eq + SomeOtherTrait = Option<T>; + +pub type Exactly101CharstoEqualWhereTest<T, U, PARAMETE> where T: Clone + Ord + Eq + SomeOtherTrait = Option<T>; + +type RegisterPlugin = unsafe fn(pt: *const c_char, plugin: *mut c_void, data: *mut CallbackData); + +// #1683 +pub type Between<Lhs, Rhs> = super::operators::Between<Lhs, super::operators::And<AsExpr<Rhs, Lhs>, AsExpr<Rhs, Lhs>>>; +pub type NotBetween<Lhs, Rhs> = super::operators::NotBetween<Lhs, super::operators::And<AsExpr<Rhs, Lhs>, AsExpr<Rhs, Lhs>>>; diff --git a/src/tools/rustfmt/tests/source/unicode.rs b/src/tools/rustfmt/tests/source/unicode.rs new file mode 100644 index 000000000..4c2119af5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/unicode.rs @@ -0,0 +1,33 @@ +// rustfmt-wrap_comments: true + +fn foo() { + let s = "this line goes to 100: ͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶ"; + let s = 42; + + // a comment of length 80, with the starting sigil: ҘҘҘҘҘҘҘҘҘҘ ҘҘҘҘҘҘҘҘҘҘҘҘҘҘ + let s = 42; +} + +pub fn bar(config: &Config) { + let csv = RefCell::new(create_csv(config, "foo")); + { + let mut csv = csv.borrow_mut(); + for (i1, i2, i3) in iproduct!(0..2, 0..3, 0..3) { + csv.write_field(format!("γ[{}.{}.{}]", i1, i2, i3)) + .unwrap(); + csv.write_field(format!("d[{}.{}.{}]", i1, i2, i3)) + .unwrap(); + csv.write_field(format!("i[{}.{}.{}]", i1, i2, i3)) + .unwrap(); + } + csv.write_record(None::<&[u8]>).unwrap(); + } +} + +// The NotUnicode line is below 100 wrt chars but over it wrt String::len +fn baz() { + let our_error_b = result_b_from_func.or_else(|e| match e { + NotPresent => Err(e).chain_err(|| "env var wasn't provided"), + NotUnicode(_) => Err(e).chain_err(|| "env var was very very very borkæ–‡å—化ã"), + }); +} diff --git a/src/tools/rustfmt/tests/source/unions.rs b/src/tools/rustfmt/tests/source/unions.rs new file mode 100644 index 000000000..53630788f --- /dev/null +++ b/src/tools/rustfmt/tests/source/unions.rs @@ -0,0 +1,195 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + + /// A Doc comment +#[AnAttribute] +pub union Foo { + #[rustfmt::skip] + f : SomeType, // Comment beside a field + f: SomeType, // Comment beside a field + // Comment on a field + #[AnAttribute] + g: SomeOtherType, + /// A doc comment on a field + h: AThirdType, + pub i: TypeForPublicField +} + +// #1029 +pub union Foo { + #[doc(hidden)] + // This will NOT get deleted! + bar: String, // hi +} + +// #1029 +union X { + // `x` is an important number. + #[allow(unused)] // TODO: use + x: u32, +} + +// #410 +#[allow(missing_docs)] +pub union Writebatch<K: Key> { + #[allow(dead_code)] //only used for holding the internal pointer + writebatch: RawWritebatch, + marker: PhantomData<K>, +} + +// With a where-clause and generics. +pub union Foo<'a, Y: Baz> + where X: Whatever +{ + f: SomeType, // Comment beside a field +} + +union Baz { + + a: A, // Comment A + b: B, // Comment B + c: C, // Comment C + +} + +union Baz { + a: A, // Comment A + + b: B, // Comment B + + + + + c: C, // Comment C +} + +union Baz { + + a: A, + + b: B, + c: C, + + + + + d: D + +} + +union Baz +{ + // Comment A + a: A, + + // Comment B +b: B, + // Comment C + c: C,} + +pub union State<F: FnMut() -> time::Timespec> { now: F } + +pub union State<F: FnMut() -> ()> { now: F } + +pub union State<F: FnMut()> { now: F } + +union Palette { /// A map of indices in the palette to a count of pixels in approximately that color + foo: i32} + +// Splitting a single line comment into a block previously had a misalignment +// when the field had attributes +union FieldsWithAttributes { + // Pre Comment + #[rustfmt::skip] pub host:String, // Post comment BBBBBBBBBBBBBB BBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBB BBBBBBBBBBB + //Another pre comment + #[attr1] + #[attr2] pub id: usize // CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCC CCCCCCCCCCCC +} + +union Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: node::Handle<IdRef<'id, Node<K, V>>, + Type, + NodeType>, +} + +mod m { + union X<T> where T: Sized { + a: T, + } +} + +union Issue677 { + pub ptr: *const libc::c_void, + pub trace: fn( obj: + *const libc::c_void, tracer : *mut JSTracer ), +} + +union Foo {} +union Foo { + } +union Foo { + // comment + } +union Foo { + // trailing space -> + + + } +union Foo { /* comment */ } + +union LongUnion { + a: A, + the_quick_brown_fox_jumps_over_the_lazy_dog:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +} + +union Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: node::Handle<IdRef<'id, Node<Key, Value>>, + Type, + NodeType>, +} + +// #1364 +fn foo() { + convex_shape.set_point(0, &Vector2f { x: 400.0, y: 100.0 }); + convex_shape.set_point(1, &Vector2f { x: 500.0, y: 70.0 }); + convex_shape.set_point(2, &Vector2f { x: 450.0, y: 100.0 }); + convex_shape.set_point(3, &Vector2f { x: 580.0, y: 150.0 }); +} + +// Vertical alignment +union Foo { + aaaaa: u32, // a + + b: u32, // b + cc: u32, // cc + + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 1 + yy: u32, // comment2 + zzz: u32, // comment3 + + aaaaaa: u32, // comment4 + bb: u32, // comment5 + // separate + dd: u32, // comment7 + c: u32, // comment6 + + aaaaaaa: u32, /* multi + * line + * comment + */ + b: u32, // hi + + do_not_push_this_comment1: u32, // comment1 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + please_do_not_push_this_comment3: u32, // comment3 + + do_not_push_this_comment1: u32, // comment1 + // separate + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + please_do_not_push_this_comment3: u32, // comment3 + + do_not_push_this_comment1: u32, // comment1 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + // separate + please_do_not_push_this_comment3: u32, // comment3 +} diff --git a/src/tools/rustfmt/tests/source/unsafe-mod.rs b/src/tools/rustfmt/tests/source/unsafe-mod.rs new file mode 100644 index 000000000..9996b0627 --- /dev/null +++ b/src/tools/rustfmt/tests/source/unsafe-mod.rs @@ -0,0 +1,7 @@ +// These are supported by rustc syntactically but not semantically. + +#[cfg(any())] +unsafe mod m { } + +#[cfg(any())] +unsafe extern "C++" { } diff --git a/src/tools/rustfmt/tests/source/visibility.rs b/src/tools/rustfmt/tests/source/visibility.rs new file mode 100644 index 000000000..1c5919ccf --- /dev/null +++ b/src/tools/rustfmt/tests/source/visibility.rs @@ -0,0 +1,8 @@ +// #2398 +pub mod outer_mod { + pub mod inner_mod { + pub ( in outer_mod ) fn outer_mod_visible_fn() {} + pub ( super ) fn super_mod_visible_fn() {} + pub ( self ) fn inner_mod_visible_fn() {} + } +} diff --git a/src/tools/rustfmt/tests/source/visual-fn-type.rs b/src/tools/rustfmt/tests/source/visual-fn-type.rs new file mode 100644 index 000000000..67dad5fa4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/visual-fn-type.rs @@ -0,0 +1,10 @@ +// rustfmt-indent_style: Visual +type CNodeSetAtts = unsafe extern "C" fn(node: *const RsvgNode, + node_impl: *const RsvgCNodeImpl, + handle: *const RsvgHandle, + pbag: *const PropertyBag) + ; +type CNodeDraw = unsafe extern "C" fn(node: *const RsvgNode, + node_impl: *const RsvgCNodeImpl, + draw_ctx: *const RsvgDrawingCtx, + dominate: i32); diff --git a/src/tools/rustfmt/tests/source/where-clause-rfc.rs b/src/tools/rustfmt/tests/source/where-clause-rfc.rs new file mode 100644 index 000000000..219a9bddb --- /dev/null +++ b/src/tools/rustfmt/tests/source/where-clause-rfc.rs @@ -0,0 +1,73 @@ +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) where T: FOo, U: Bar { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) where T: FOo { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape, shape: &Shape) where T: FOo, U: Bar { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape, shape: &Shape) where T: FOo { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) -> Option<String> where T: FOo, U: Bar { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) -> Option<String> where T: FOo { + let mut effects = HashMap::new(); +} + +pub trait Test { + fn very_long_method_name<F>(self, f: F) -> MyVeryLongReturnType where F: FnMut(Self::Item) -> bool; + + fn exactly_100_chars1<F>(self, f: F) -> MyVeryLongReturnType where F: FnMut(Self::Item) -> bool; +} + +fn very_long_function_name<F>(very_long_argument: F) -> MyVeryLongReturnType where F: FnMut(Self::Item) -> bool { } + +struct VeryLongTupleStructName<A, B, C, D, E>(LongLongTypename, LongLongTypename, i32, i32) where A: LongTrait; + +struct Exactly100CharsToSemicolon<A, B, C, D, E> + (LongLongTypename, i32, i32) + where A: LongTrait1234; + +struct AlwaysOnNextLine<LongLongTypename, LongTypename, A, B, C, D, E, F> where A: LongTrait { + x: i32 +} + +pub trait SomeTrait<T> + where + T: Something + Sync + Send + Display + Debug + Copy + Hash + Debug + Display + Write + Read + FromStr +{ +} + +// #2020 +impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { + fn elaborate_bounds<F>(&mut self, bounds: &[ty::PolyTraitRef<'tcx>], mut mk_cand: F) + where F: for<'b> FnMut(&mut ProbeContext<'b, 'gcx, 'tcx>, ty::PolyTraitRef<'tcx>, ty::AssociatedItem), + { + // ... + } +} + +// #2497 +fn handle_update<'a, Tab, Conn, R, C>(executor: &Executor<PooledConnection<ConnectionManager<Conn>>>, change_set: &'a C) -> ExecutionResult +where &'a C: Identifiable + AsChangeset<Target = Tab> + HasTable<Table = Tab>, + <&'a C as AsChangeset>::Changeset: QueryFragment<Conn::Backend>, + Tab: Table + HasTable<Table = Tab>, + Tab::PrimaryKey: EqAll<<&'a C as Identifiable>::Id>, + Tab::FromClause: QueryFragment<Conn::Backend>, + Tab: FindDsl<<&'a C as Identifiable>::Id>, + Find<Tab, <&'a C as Identifiable>::Id>: IntoUpdateTarget<Table = Tab>, + <Find<Tab, <&'a C as Identifiable>::Id> as IntoUpdateTarget>::WhereClause: QueryFragment<Conn::Backend>, + Tab::Query: FilterDsl<<Tab::PrimaryKey as EqAll<<&'a C as Identifiable>::Id>>::Output>, + Filter<Tab::Query, <Tab::PrimaryKey as EqAll<<&'a C as Identifiable>::Id>>::Output>: LimitDsl, + Limit<Filter<Tab::Query, <Tab::PrimaryKey as EqAll<<&'a C as Identifiable>::Id>>::Output>>: QueryDsl + BoxedDsl< 'a, Conn::Backend, Output = BoxedSelectStatement<'a, R::SqlType, Tab, Conn::Backend>>, + R: LoadingHandler<Conn, Table = Tab, SqlType = Tab::SqlType> + GraphQLType<TypeInfo = (), Context = ()>, { + unimplemented!() +} diff --git a/src/tools/rustfmt/tests/source/where-clause.rs b/src/tools/rustfmt/tests/source/where-clause.rs new file mode 100644 index 000000000..2a9160825 --- /dev/null +++ b/src/tools/rustfmt/tests/source/where-clause.rs @@ -0,0 +1,58 @@ +// rustfmt-indent_style: Visual + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) where T: FOo, U: Bar { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) where T: FOo { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape, shape: &Shape) where T: FOo, U: Bar { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape, shape: &Shape) where T: FOo { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) -> Option<String> where T: FOo, U: Bar { + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) -> Option<String> where T: FOo { + let mut effects = HashMap::new(); +} + +pub trait Test { + fn very_long_method_name<F>(self, f: F) -> MyVeryLongReturnType where F: FnMut(Self::Item) -> bool; + + fn exactly_100_chars1<F>(self, f: F) -> MyVeryLongReturnType where F: FnMut(Self::Item) -> bool; +} + +fn very_long_function_name<F>(very_long_argument: F) -> MyVeryLongReturnType where F: FnMut(Self::Item) -> bool { } + +struct VeryLongTupleStructName<A, B, C, D, E>(LongLongTypename, LongLongTypename, i32, i32) where A: LongTrait; + +struct Exactly100CharsToSemicolon<A, B, C, D, E> + (LongLongTypename, i32, i32) + where A: LongTrait1234; + +struct AlwaysOnNextLine<LongLongTypename, LongTypename, A, B, C, D, E, F> where A: LongTrait { + x: i32 +} + +pub trait SomeTrait<T> + where + T: Something + Sync + Send + Display + Debug + Copy + Hash + Debug + Display + Write + Read + FromStr +{ +} + +// #2020 +impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { + fn elaborate_bounds<F>(&mut self, bounds: &[ty::PolyTraitRef<'tcx>], mut mk_cand: F) + where F: for<'b> FnMut(&mut ProbeContext<'b, 'gcx, 'tcx>, ty::PolyTraitRef<'tcx>, ty::AssociatedItem), + { + // ... + } +} diff --git a/src/tools/rustfmt/tests/source/width-heuristics.rs b/src/tools/rustfmt/tests/source/width-heuristics.rs new file mode 100644 index 000000000..a591218b4 --- /dev/null +++ b/src/tools/rustfmt/tests/source/width-heuristics.rs @@ -0,0 +1,28 @@ +// rustfmt-max_width: 120 + +// elems on multiple lines for max_width 100, but same line for max_width 120 +fn foo(e: Enum) { + match e { + Enum::Var { + elem1, + elem2, + elem3, + } => { + return; + } + } +} + +// elems not on same line for either max_width 100 or 120 +fn bar(e: Enum) { + match e { + Enum::Var { + elem1, + elem2, + elem3, + elem4, + } => { + return; + } + } +} diff --git a/src/tools/rustfmt/tests/source/wrap_comments_should_not_imply_format_doc_comments.rs b/src/tools/rustfmt/tests/source/wrap_comments_should_not_imply_format_doc_comments.rs new file mode 100644 index 000000000..78b3ce146 --- /dev/null +++ b/src/tools/rustfmt/tests/source/wrap_comments_should_not_imply_format_doc_comments.rs @@ -0,0 +1,16 @@ +// rustfmt-wrap_comments: true + +/// Foo +/// +/// # Example +/// ``` +/// # #![cfg_attr(not(dox), feature(cfg_target_feature, target_feature, stdsimd))] +/// # #![cfg_attr(not(dox), no_std)] +/// fn foo() { } +/// ``` +/// +fn foo() {} + +/// A long commment for wrapping +/// This is a long long long long long long long long long long long long long long long long long long long long sentence. +fn bar() {} diff --git a/src/tools/rustfmt/tests/target/5131_crate.rs b/src/tools/rustfmt/tests/target/5131_crate.rs new file mode 100644 index 000000000..557d66703 --- /dev/null +++ b/src/tools/rustfmt/tests/target/5131_crate.rs @@ -0,0 +1,9 @@ +// rustfmt-imports_granularity: Crate + +use foo::{ + a, b, b as b2, + b::{f, g, g as g2}, + c, + d::e, +}; +use qux::{h, h as h2, i}; diff --git a/src/tools/rustfmt/tests/target/5131_module.rs b/src/tools/rustfmt/tests/target/5131_module.rs new file mode 100644 index 000000000..763024d6f --- /dev/null +++ b/src/tools/rustfmt/tests/target/5131_module.rs @@ -0,0 +1,32 @@ +// rustfmt-imports_granularity: Module + +#![allow(dead_code)] + +mod a { + pub mod b { + pub struct Data { + pub a: i32, + } + } + + use crate::a::b::{Data, Data as Data2}; + + pub fn data(a: i32) -> Data { + Data { a } + } + + pub fn data2(a: i32) -> Data2 { + Data2 { a } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + pub fn test() { + data(1); + data2(1); + } + } +} diff --git a/src/tools/rustfmt/tests/target/5131_one.rs b/src/tools/rustfmt/tests/target/5131_one.rs new file mode 100644 index 000000000..a086dae5a --- /dev/null +++ b/src/tools/rustfmt/tests/target/5131_one.rs @@ -0,0 +1,12 @@ +// rustfmt-imports_granularity: One + +pub use foo::{x, x as x2, y}; +use { + bar::{ + a, + b::{self, f, g}, + c, + d::{e, e as e2}, + }, + qux::{h, i}, +}; diff --git a/src/tools/rustfmt/tests/target/alignment_2633/block_style.rs b/src/tools/rustfmt/tests/target/alignment_2633/block_style.rs new file mode 100644 index 000000000..f13e8a876 --- /dev/null +++ b/src/tools/rustfmt/tests/target/alignment_2633/block_style.rs @@ -0,0 +1,10 @@ +// rustfmt-struct_field_align_threshold: 50 + +fn func() { + Ok(ServerInformation { + name: unwrap_message_string(items.get(0)), + vendor: unwrap_message_string(items.get(1)), + version: unwrap_message_string(items.get(2)), + spec_version: unwrap_message_string(items.get(3)), + }); +} diff --git a/src/tools/rustfmt/tests/target/alignment_2633/horizontal_tactic.rs b/src/tools/rustfmt/tests/target/alignment_2633/horizontal_tactic.rs new file mode 100644 index 000000000..a381945fd --- /dev/null +++ b/src/tools/rustfmt/tests/target/alignment_2633/horizontal_tactic.rs @@ -0,0 +1,13 @@ +// rustfmt-struct_field_align_threshold: 5 + +#[derive(Fail, Debug, Clone)] +pub enum BuildError { + LineTooLong { length: usize, limit: usize }, + DisallowedByte { b: u8, pos: usize }, + ContainsNewLine { pos: usize }, +} + +enum Foo { + A { a: usize, bbbbb: () }, + B { a: (), bbbbb: () }, +} diff --git a/src/tools/rustfmt/tests/target/alignment_2633/visual_style.rs b/src/tools/rustfmt/tests/target/alignment_2633/visual_style.rs new file mode 100644 index 000000000..7d21b599a --- /dev/null +++ b/src/tools/rustfmt/tests/target/alignment_2633/visual_style.rs @@ -0,0 +1,9 @@ +// rustfmt-struct_field_align_threshold: 50 +// rustfmt-indent_style: Visual + +fn func() { + Ok(ServerInformation { name: unwrap_message_string(items.get(0)), + vendor: unwrap_message_string(items.get(1)), + version: unwrap_message_string(items.get(2)), + spec_version: unwrap_message_string(items.get(3)), }); +} diff --git a/src/tools/rustfmt/tests/target/array_comment.rs b/src/tools/rustfmt/tests/target/array_comment.rs new file mode 100644 index 000000000..93e1f5f40 --- /dev/null +++ b/src/tools/rustfmt/tests/target/array_comment.rs @@ -0,0 +1,18 @@ +// Issue 2842 +// The comment should not make the last line shorter + +static XXX: [i8; 64] = [ + 1, // Comment + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +]; + +static XXX: [i8; 64] = [ + 1, // Comment + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +]; + +static XXX: [i8; 64] = [ + 1, // Comment + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, +]; diff --git a/src/tools/rustfmt/tests/target/assignment.rs b/src/tools/rustfmt/tests/target/assignment.rs new file mode 100644 index 000000000..1a70d8481 --- /dev/null +++ b/src/tools/rustfmt/tests/target/assignment.rs @@ -0,0 +1,39 @@ +// Test assignment + +fn main() { + let some_var: Type; + + let mut mutable; + + let variable = + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA::BBBBBBBBBBBBBBBBBBBBBB::CCCCCCCCCCCCCCCCCCCCCC::EEEEEE; + + variable = + LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG; + + let single_line_fit = DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD; + + single_line_fit = 5; + single_lit_fit >>= 10; + + // #2791 + let x = 2; +} + +fn break_meee() { + { + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) = match (block_start, block_end, block_size) { + x => 1, + _ => 2, + }; + } +} + +// #2018 +pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str = + "Unsized tuple coercion is not stable enough for use and is subject to change"; diff --git a/src/tools/rustfmt/tests/target/associated-items.rs b/src/tools/rustfmt/tests/target/associated-items.rs new file mode 100644 index 000000000..1b0a828d0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/associated-items.rs @@ -0,0 +1,3 @@ +fn main() { + println!("{}", <bool as ::std::default::Default>::default()); +} diff --git a/src/tools/rustfmt/tests/target/associated-types-bounds-wrapping.rs b/src/tools/rustfmt/tests/target/associated-types-bounds-wrapping.rs new file mode 100644 index 000000000..8aaeee3b1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/associated-types-bounds-wrapping.rs @@ -0,0 +1,6 @@ +// Test proper wrapping of long associated type bounds + +pub trait HttpService { + type WsService: 'static + + Service<Request = WsCommand, Response = WsResponse, Error = ServerError>; +} diff --git a/src/tools/rustfmt/tests/target/associated_type_bounds.rs b/src/tools/rustfmt/tests/target/associated_type_bounds.rs new file mode 100644 index 000000000..2dcbd65f8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/associated_type_bounds.rs @@ -0,0 +1,13 @@ +// See #3657 - https://github.com/rust-lang/rustfmt/issues/3657 + +#![feature(associated_type_bounds)] + +fn f<I: Iterator<Item: Clone>>() {} + +fn g<I: Iterator<Item: Clone>>() {} + +fn h<I: Iterator<Item: Clone>>() {} + +fn i<I: Iterator<Item: Clone>>() {} + +fn j<I: Iterator<Item: Clone + 'a>>() {} diff --git a/src/tools/rustfmt/tests/target/associated_type_defaults.rs b/src/tools/rustfmt/tests/target/associated_type_defaults.rs new file mode 100644 index 000000000..d0a081337 --- /dev/null +++ b/src/tools/rustfmt/tests/target/associated_type_defaults.rs @@ -0,0 +1,4 @@ +#![feature(associated_type_defaults)] +trait Foo { + type Bar = (); +} diff --git a/src/tools/rustfmt/tests/target/async_block.rs b/src/tools/rustfmt/tests/target/async_block.rs new file mode 100644 index 000000000..137d849c9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/async_block.rs @@ -0,0 +1,35 @@ +// rustfmt-edition: 2018 + +fn main() { + let x = async { Ok(()) }; +} + +fn baz() { + // test + let x = async { + // async blocks are great + Ok(()) + }; + + let y = async { Ok(()) }; // comment + + spawn(a, async move { + action(); + Ok(()) + }); + + spawn(a, async move || { + action(); + Ok(()) + }); + + spawn(a, static async || { + action(); + Ok(()) + }); + + spawn(a, static async move || { + action(); + Ok(()) + }); +} diff --git a/src/tools/rustfmt/tests/target/async_closure.rs b/src/tools/rustfmt/tests/target/async_closure.rs new file mode 100644 index 000000000..9364e7dcc --- /dev/null +++ b/src/tools/rustfmt/tests/target/async_closure.rs @@ -0,0 +1,22 @@ +// rustfmt-edition: 2018 + +fn main() { + let async_closure = async { + let x = 3; + x + }; + + let f = async /* comment */ { + let x = 3; + x + }; + + let g = async /* comment */ move { + let x = 3; + x + }; + + let f = |x| async { + println!("hello, world"); + }; +} diff --git a/src/tools/rustfmt/tests/target/async_fn.rs b/src/tools/rustfmt/tests/target/async_fn.rs new file mode 100644 index 000000000..ac151dddb --- /dev/null +++ b/src/tools/rustfmt/tests/target/async_fn.rs @@ -0,0 +1,24 @@ +// rustfmt-edition: 2018 + +async fn bar() -> Result<(), ()> { + Ok(()) +} + +pub async fn baz() -> Result<(), ()> { + Ok(()) +} + +async unsafe fn foo() { + async move { Ok(()) } +} + +async unsafe fn rust() { + async move { + // comment + Ok(()) + } +} + +async fn await_try() { + something.await?; +} diff --git a/src/tools/rustfmt/tests/target/attrib-block-expr.rs b/src/tools/rustfmt/tests/target/attrib-block-expr.rs new file mode 100644 index 000000000..1e9557dc0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/attrib-block-expr.rs @@ -0,0 +1,58 @@ +fn issue_2073() { + let x = { + #![my_attr] + do_something() + }; + + let x = #[my_attr] + { + do_something() + }; + + let x = #[my_attr] + {}; + + { + #![just_an_attribute] + }; + + let z = #[attr1] + #[attr2] + { + body() + }; + + x = |y| { + #![inner] + }; + + x = |y| #[outer] + {}; + + x = |y| { + //! ynot + }; + + x = |y| #[outer] + unsafe {}; + + let x = unsafe { + #![my_attr] + do_something() + }; + + let x = #[my_attr] + unsafe { + do_something() + }; + + // This is a dumb but possible case + let x = #[my_attr] + unsafe {}; + + x = |y| #[outer] + #[outer2] + unsafe { + //! Comment + }; +} diff --git a/src/tools/rustfmt/tests/target/attrib-extern-crate.rs b/src/tools/rustfmt/tests/target/attrib-extern-crate.rs new file mode 100644 index 000000000..ed64a0aeb --- /dev/null +++ b/src/tools/rustfmt/tests/target/attrib-extern-crate.rs @@ -0,0 +1,17 @@ +// Attributes on extern crate. + +#[Attr1] +extern crate Bar; +#[Attr2] +#[Attr2] +extern crate Baz; +extern crate Foo; + +fn foo() { + #[Attr1] + extern crate Bar; + #[Attr2] + #[Attr2] + extern crate Baz; + extern crate Foo; +} diff --git a/src/tools/rustfmt/tests/target/attrib.rs b/src/tools/rustfmt/tests/target/attrib.rs new file mode 100644 index 000000000..7e61f68d7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/attrib.rs @@ -0,0 +1,271 @@ +// rustfmt-wrap_comments: true +// Test attributes and doc comments are preserved. +#![doc( + html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", + test(attr(deny(warnings))) +)] + +//! Doc comment + +#![attribute] + +//! Crate doc comment + +// Comment + +// Comment on attribute +#![the(attribute)] + +// Another comment + +/// Blah blah blah. +/// Blah blah blah. +/// Blah blah blah. +/// Blah blah blah. + +/// Blah blah blah. +impl Bar { + /// Blah blah blooo. + /// Blah blah blooo. + /// Blah blah blooo. + /// Blah blah blooo. + #[an_attribute] + #[doc = "an attribute that shouldn't be normalized to a doc comment"] + fn foo(&mut self) -> isize {} + + /// Blah blah bing. + /// Blah blah bing. + /// Blah blah bing. + + /// Blah blah bing. + /// Blah blah bing. + /// Blah blah bing. + pub fn f2(self) { + (foo, bar) + } + + #[another_attribute] + fn f3(self) -> Dog {} + + /// Blah blah bing. + + #[attrib1] + /// Blah blah bing. + #[attrib2] + // Another comment that needs rewrite because it's tooooooooooooooooooooooooooooooo + // loooooooooooong. + /// Blah blah bing. + fn f4(self) -> Cat {} + + // We want spaces around `=` + #[cfg(feature = "nightly")] + fn f5(self) -> Monkey {} +} + +// #984 +struct Foo { + #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] + foo: usize, +} + +// #1668 + +/// Default path (*nix) +#[cfg(all( + unix, + not(target_os = "macos"), + not(target_os = "ios"), + not(target_os = "android") +))] +fn foo() { + #[cfg(target_os = "freertos")] + match port_id { + 'a' | 'A' => GpioPort { + port_address: GPIO_A, + }, + 'b' | 'B' => GpioPort { + port_address: GPIO_B, + }, + _ => panic!(), + } + + #[cfg_attr(not(target_os = "freertos"), allow(unused_variables))] + let x = 3; +} + +// #1777 +#[test] +#[should_panic(expected = "(")] +#[should_panic(expected = /* ( */ "(")] +#[should_panic(/* ((((( */expected /* ((((( */= /* ((((( */ "("/* ((((( */)] +#[should_panic( + /* (((((((( *//* + (((((((((()(((((((( */ + expected = "(" + // (((((((( +)] +fn foo() {} + +// #1799 +fn issue_1799() { + #[allow(unreachable_code)] // https://github.com/rust-lang/rust/issues/43336 + Some(Err(error)); + + #[allow(unreachable_code)] + // https://github.com/rust-lang/rust/issues/43336 + Some(Err(error)); +} + +// Formatting inner attributes +fn inner_attributes() { + #![this_is_an_inner_attribute(foo)] + + foo(); +} + +impl InnerAttributes() { + #![this_is_an_inner_attribute(foo)] + + fn foo() {} +} + +mod InnerAttributes { + #![this_is_an_inner_attribute(foo)] +} + +fn attributes_on_statements() { + // Local + #[attr(on(local))] + let x = 3; + + // Item + #[attr(on(item))] + use foo; + + // Expr + #[attr(on(expr))] + {} + + // Semi + #[attr(on(semi))] + foo(); + + // Mac + #[attr(on(mac))] + foo!(); +} + +// Large derives +#[derive( + Add, Sub, Mul, Div, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Serialize, Mul, +)] + +/// Foo bar baz + +#[derive( + Add, + Sub, + Mul, + Div, + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + Debug, + Hash, + Serialize, + Deserialize, +)] +pub struct HP(pub u8); + +// Long `#[doc = "..."]` +struct A { + #[doc = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] + b: i32, +} + +// #2647 +#[cfg( + feature = "this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +)] +pub fn foo() {} + +// path attrs +#[clippy::bar] +#[clippy::bar(a, b, c)] +pub fn foo() {} + +mod issue_2620 { + #[derive(Debug, StructOpt)] + #[structopt(about = "Display information about the character on FF Logs")] + pub struct Params { + #[structopt(help = "The server the character is on")] + server: String, + #[structopt(help = "The character's first name")] + first_name: String, + #[structopt(help = "The character's last name")] + last_name: String, + #[structopt( + short = "j", + long = "job", + help = "The job to look at", + parse(try_from_str) + )] + job: Option<Job>, + } +} + +// #2969 +#[cfg(not(all( + feature = "std", + any( + target_os = "linux", + target_os = "android", + target_os = "netbsd", + target_os = "dragonfly", + target_os = "haiku", + target_os = "emscripten", + target_os = "solaris", + target_os = "cloudabi", + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "redox", + target_os = "fuchsia", + windows, + all(target_arch = "wasm32", feature = "stdweb"), + all(target_arch = "wasm32", feature = "wasm-bindgen"), + ) +)))] +type Os = NoSource; + +// #3313 +fn stmt_expr_attributes() { + let foo; + #[must_use] + foo = false; +} + +// #3509 +fn issue3509() { + match MyEnum { + MyEnum::Option1 if cfg!(target_os = "windows") => + #[cfg(target_os = "windows")] + { + 1 + } + } + match MyEnum { + MyEnum::Option1 if cfg!(target_os = "windows") => + { + #[cfg(target_os = "windows")] + 1 + } + } +} diff --git a/src/tools/rustfmt/tests/target/big-impl-block.rs b/src/tools/rustfmt/tests/target/big-impl-block.rs new file mode 100644 index 000000000..e3728caba --- /dev/null +++ b/src/tools/rustfmt/tests/target/big-impl-block.rs @@ -0,0 +1,82 @@ +// #1357 +impl<'a, Select, From, Distinct, Where, Order, Limit, Offset, Groupby, DB> InternalBoxedDsl<'a, DB> + for SelectStatement<Select, From, Distinct, Where, Order, Limit, Offset, GroupBy> +where + DB: Backend, + Select: QueryFragment<DB> + SelectableExpression<From> + 'a, + Distinct: QueryFragment<DB> + 'a, + Where: Into<Option<Box<QueryFragment<DB> + 'a>>>, + Order: QueryFragment<DB> + 'a, + Limit: QueryFragment<DB> + 'a, + Offset: QueryFragment<DB> + 'a, +{ + type Output = BoxedSelectStatement<'a, Select::SqlTypeForSelect, From, DB>; + + fn internal_into_boxed(self) -> Self::Output { + BoxedSelectStatement::new( + Box::new(self.select), + self.from, + Box::new(self.distinct), + self.where_clause.into(), + Box::new(self.order), + Box::new(self.limit), + Box::new(self.offset), + ) + } +} + +// #1369 +impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> Foo + for Bar +{ + fn foo() {} +} +impl Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + for Bar +{ + fn foo() {} +} +impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + for Bar +{ + fn foo() {} +} +impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> Foo + for Bar< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, + > +{ + fn foo() {} +} +impl Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + for Bar< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, + > +{ + fn foo() {} +} +impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + for Bar< + ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName, + > +{ + fn foo() {} +} + +// #1689 +impl<M, S, F, X> SubSelectDirect<M, S, F, X> +where + M: select::Selector, + S: event::Stream, + F: for<'t> FnMut(transform::Api<'t, Stream<ContentStream<S>>>) -> transform::Api<'t, X>, + X: event::Stream, +{ +} diff --git a/src/tools/rustfmt/tests/target/big-impl-visual.rs b/src/tools/rustfmt/tests/target/big-impl-visual.rs new file mode 100644 index 000000000..04b0a83fd --- /dev/null +++ b/src/tools/rustfmt/tests/target/big-impl-visual.rs @@ -0,0 +1,65 @@ +// rustfmt-indent_style: Visual + +// #1357 +impl<'a, Select, From, Distinct, Where, Order, Limit, Offset, Groupby, DB> InternalBoxedDsl<'a, DB> + for SelectStatement<Select, From, Distinct, Where, Order, Limit, Offset, GroupBy> + where DB: Backend, + Select: QueryFragment<DB> + SelectableExpression<From> + 'a, + Distinct: QueryFragment<DB> + 'a, + Where: Into<Option<Box<QueryFragment<DB> + 'a>>>, + Order: QueryFragment<DB> + 'a, + Limit: QueryFragment<DB> + 'a, + Offset: QueryFragment<DB> + 'a +{ + type Output = BoxedSelectStatement<'a, Select::SqlTypeForSelect, From, DB>; + + fn internal_into_boxed(self) -> Self::Output { + BoxedSelectStatement::new(Box::new(self.select), + self.from, + Box::new(self.distinct), + self.where_clause.into(), + Box::new(self.order), + Box::new(self.limit), + Box::new(self.offset)) + } +} + +// #1369 +impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> Foo + for Bar +{ + fn foo() {} +} +impl Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + for Bar +{ + fn foo() {} +} +impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + for Bar +{ + fn foo() {} +} +impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> Foo + for Bar<ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName> +{ + fn foo() {} +} +impl Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + for Bar<ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName> +{ + fn foo() {} +} +impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> + for Bar<ExcessivelyLongGenericName, + ExcessivelyLongGenericName, + AnotherExcessivelyLongGenericName> +{ + fn foo() {} +} diff --git a/src/tools/rustfmt/tests/target/binary-expr.rs b/src/tools/rustfmt/tests/target/binary-expr.rs new file mode 100644 index 000000000..93115b282 --- /dev/null +++ b/src/tools/rustfmt/tests/target/binary-expr.rs @@ -0,0 +1,16 @@ +// Binary expressions + +fn foo() { + // 100 + let x = aaaaaaaaaa || bbbbbbbbbb || cccccccccc || dddddddddd && eeeeeeeeee || ffffffffff || ggg; + // 101 + let x = + aaaaaaaaaa || bbbbbbbbbb || cccccccccc || dddddddddd && eeeeeeeeee || ffffffffff || gggg; + // 104 + let x = aaaaaaaaaa + || bbbbbbbbbb + || cccccccccc + || dddddddddd && eeeeeeeeee + || ffffffffff + || gggggggg; +} diff --git a/src/tools/rustfmt/tests/target/binop-separator-back/bitwise.rs b/src/tools/rustfmt/tests/target/binop-separator-back/bitwise.rs new file mode 100644 index 000000000..ce32c05ef --- /dev/null +++ b/src/tools/rustfmt/tests/target/binop-separator-back/bitwise.rs @@ -0,0 +1,18 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ^ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ & + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ | + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ << + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ >> + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} diff --git a/src/tools/rustfmt/tests/target/binop-separator-back/comp.rs b/src/tools/rustfmt/tests/target/binop-separator-back/comp.rs new file mode 100644 index 000000000..efd837bcf --- /dev/null +++ b/src/tools/rustfmt/tests/target/binop-separator-back/comp.rs @@ -0,0 +1,33 @@ +// rustfmt-binop_separator: Back + +fn main() { + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ < + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ <= + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ > + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ >= + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ == + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } +} diff --git a/src/tools/rustfmt/tests/target/binop-separator-back/logic.rs b/src/tools/rustfmt/tests/target/binop-separator-back/logic.rs new file mode 100644 index 000000000..5f69fd5f5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/binop-separator-back/logic.rs @@ -0,0 +1,10 @@ +// rustfmt-binop_separator: Back + +fn main() { + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ && + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ || + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } +} diff --git a/src/tools/rustfmt/tests/target/binop-separator-back/math.rs b/src/tools/rustfmt/tests/target/binop-separator-back/math.rs new file mode 100644 index 000000000..7a3f27e73 --- /dev/null +++ b/src/tools/rustfmt/tests/target/binop-separator-back/math.rs @@ -0,0 +1,23 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ - + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} diff --git a/src/tools/rustfmt/tests/target/binop-separator-back/patterns.rs b/src/tools/rustfmt/tests/target/binop-separator-back/patterns.rs new file mode 100644 index 000000000..2e5971352 --- /dev/null +++ b/src/tools/rustfmt/tests/target/binop-separator-back/patterns.rs @@ -0,0 +1,11 @@ +// rustfmt-binop_separator: Back + +fn main() { + match val { + ThisIsA::ReallyLongPatternNameToHelpOverflowTheNextValueOntoTheNextLine | + ThisIsA::SecondValueSeparatedByAPipe | + ThisIsA::ThirdValueSeparatedByAPipe => { + // + } + } +} diff --git a/src/tools/rustfmt/tests/target/binop-separator-back/range.rs b/src/tools/rustfmt/tests/target/binop-separator-back/range.rs new file mode 100644 index 000000000..19e5a81cd --- /dev/null +++ b/src/tools/rustfmt/tests/target/binop-separator-back/range.rs @@ -0,0 +1,9 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.. + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ..= + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} diff --git a/src/tools/rustfmt/tests/target/break-and-continue.rs b/src/tools/rustfmt/tests/target/break-and-continue.rs new file mode 100644 index 000000000..c01d8a078 --- /dev/null +++ b/src/tools/rustfmt/tests/target/break-and-continue.rs @@ -0,0 +1,23 @@ +// break and continue formatting + +#![feature(loop_break_value)] + +fn main() { + 'a: loop { + break 'a; + } + + let mut done = false; + 'b: while !done { + done = true; + continue 'b; + } + + let x = loop { + break 5; + }; + + let x = 'c: loop { + break 'c 5; + }; +} diff --git a/src/tools/rustfmt/tests/target/catch.rs b/src/tools/rustfmt/tests/target/catch.rs new file mode 100644 index 000000000..ffe694f8e --- /dev/null +++ b/src/tools/rustfmt/tests/target/catch.rs @@ -0,0 +1,22 @@ +// rustfmt-edition: 2018 +#![feature(try_blocks)] + +fn main() { + let x = try { foo()? }; + + let x = try /* Invisible comment */ { foo()? }; + + let x = try { unsafe { foo()? } }; + + let y = match (try { foo()? }) { + _ => (), + }; + + try { + foo()?; + }; + + try { + // Regular try block + }; +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/arch/aarch64.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/aarch64.rs new file mode 100644 index 000000000..91c51ed89 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/aarch64.rs @@ -0,0 +1,98 @@ +//! Aarch64 run-time features. + +/// Checks if `aarch64` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal, stdsimd)] +macro_rules! is_aarch64_feature_detected { + ("neon") => { + // FIXME: this should be removed once we rename Aarch64 neon to asimd + cfg!(target_feature = "neon") || $crate::detect::check_for($crate::detect::Feature::asimd) + }; + ("asimd") => { + cfg!(target_feature = "neon") || $crate::detect::check_for($crate::detect::Feature::asimd) + }; + ("pmull") => { + cfg!(target_feature = "pmull") || $crate::detect::check_for($crate::detect::Feature::pmull) + }; + ("fp") => { + cfg!(target_feature = "fp") || $crate::detect::check_for($crate::detect::Feature::fp) + }; + ("fp16") => { + cfg!(target_feature = "fp16") || $crate::detect::check_for($crate::detect::Feature::fp16) + }; + ("sve") => { + cfg!(target_feature = "sve") || $crate::detect::check_for($crate::detect::Feature::sve) + }; + ("crc") => { + cfg!(target_feature = "crc") || $crate::detect::check_for($crate::detect::Feature::crc) + }; + ("crypto") => { + cfg!(target_feature = "crypto") + || $crate::detect::check_for($crate::detect::Feature::crypto) + }; + ("lse") => { + cfg!(target_feature = "lse") || $crate::detect::check_for($crate::detect::Feature::lse) + }; + ("rdm") => { + cfg!(target_feature = "rdm") || $crate::detect::check_for($crate::detect::Feature::rdm) + }; + ("rcpc") => { + cfg!(target_feature = "rcpc") || $crate::detect::check_for($crate::detect::Feature::rcpc) + }; + ("dotprod") => { + cfg!(target_feature = "dotprod") + || $crate::detect::check_for($crate::detect::Feature::dotprod) + }; + ("ras") => { + compile_error!("\"ras\" feature cannot be detected at run-time") + }; + ("v8.1a") => { + compile_error!("\"v8.1a\" feature cannot be detected at run-time") + }; + ("v8.2a") => { + compile_error!("\"v8.2a\" feature cannot be detected at run-time") + }; + ("v8.3a") => { + compile_error!("\"v8.3a\" feature cannot be detected at run-time") + }; + ($t:tt,) => { + is_aarch64_feature_detected!($t); + }; + ($t:tt) => { + compile_error!(concat!("unknown aarch64 target feature: ", $t)) + }; +} + +/// ARM Aarch64 CPU Feature enum. Each variant denotes a position in a bitset +/// for a particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// ARM Advanced SIMD (ASIMD) + asimd, + /// Polynomial Multiply + pmull, + /// Floating point support + fp, + /// Half-float support. + fp16, + /// Scalable Vector Extension (SVE) + sve, + /// CRC32 (Cyclic Redundancy Check) + crc, + /// Crypto: AES + PMULL + SHA1 + SHA2 + crypto, + /// Atomics (Large System Extension) + lse, + /// Rounding Double Multiply (ASIMDRDM) + rdm, + /// Release consistent Processor consistent (RcPc) + rcpc, + /// Vector Dot-Product (ASIMDDP) + dotprod, +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/arch/arm.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/arm.rs new file mode 100644 index 000000000..90c61fed8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/arm.rs @@ -0,0 +1,47 @@ +//! Run-time feature detection on ARM Aarch32. + +/// Checks if `arm` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal, stdsimd)] +macro_rules! is_arm_feature_detected { + ("neon") => { + cfg!(target_feature = "neon") || $crate::detect::check_for($crate::detect::Feature::neon) + }; + ("pmull") => { + cfg!(target_feature = "pmull") || $crate::detect::check_for($crate::detect::Feature::pmull) + }; + ("v7") => { + compile_error!("\"v7\" feature cannot be detected at run-time") + }; + ("vfp2") => { + compile_error!("\"vfp2\" feature cannot be detected at run-time") + }; + ("vfp3") => { + compile_error!("\"vfp3\" feature cannot be detected at run-time") + }; + ("vfp4") => { + compile_error!("\"vfp4\" feature cannot be detected at run-time") + }; + ($t:tt,) => { + is_arm_feature_detected!($t); + }; + ($t:tt) => { + compile_error!(concat!("unknown arm target feature: ", $t)) + }; +} + +/// ARM CPU Feature enum. Each variant denotes a position in a bitset for a +/// particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// ARM Advanced SIMD (NEON) - Aarch32 + neon, + /// Polynomial Multiply + pmull, +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/arch/mips.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/mips.rs new file mode 100644 index 000000000..2397a0906 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/mips.rs @@ -0,0 +1,30 @@ +//! Run-time feature detection on MIPS. + +/// Checks if `mips` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal, stdsimd)] +macro_rules! is_mips_feature_detected { + ("msa") => { + cfg!(target_feature = "msa") || $crate::detect::check_for($crate::detect::Feature::msa) + }; + ($t:tt,) => { + is_mips_feature_detected!($t); + }; + ($t:tt) => { + compile_error!(concat!("unknown mips target feature: ", $t)) + }; +} + +/// MIPS CPU Feature enum. Each variant denotes a position in a bitset for a +/// particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// MIPS SIMD Architecture (MSA) + msa, +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/arch/mips64.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/mips64.rs new file mode 100644 index 000000000..d378defc5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/mips64.rs @@ -0,0 +1,30 @@ +//! Run-time feature detection on MIPS64. + +/// Checks if `mips64` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal, stdsimd)] +macro_rules! is_mips64_feature_detected { + ("msa") => { + cfg!(target_feature = "msa") || $crate::detect::check_for($crate::detect::Feature::msa) + }; + ($t:tt,) => { + is_mips64_feature_detected!($t); + }; + ($t:tt) => { + compile_error!(concat!("unknown mips64 target feature: ", $t)) + }; +} + +/// MIPS64 CPU Feature enum. Each variant denotes a position in a bitset +/// for a particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// MIPS SIMD Architecture (MSA) + msa, +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/arch/powerpc.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/powerpc.rs new file mode 100644 index 000000000..e7a9daac6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/powerpc.rs @@ -0,0 +1,42 @@ +//! Run-time feature detection on PowerPC. + +/// Checks if `powerpc` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal, stdsimd)] +macro_rules! is_powerpc_feature_detected { + ("altivec") => { + cfg!(target_feature = "altivec") + || $crate::detect::check_for($crate::detect::Feature::altivec) + }; + ("vsx") => { + cfg!(target_feature = "vsx") || $crate::detect::check_for($crate::detect::Feature::vsx) + }; + ("power8") => { + cfg!(target_feature = "power8") + || $crate::detect::check_for($crate::detect::Feature::power8) + }; + ($t:tt,) => { + is_powerpc_feature_detected!($t); + }; + ($t:tt) => { + compile_error!(concat!("unknown powerpc target feature: ", $t)) + }; +} + +/// PowerPC CPU Feature enum. Each variant denotes a position in a bitset +/// for a particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// Altivec + altivec, + /// VSX + vsx, + /// Power8 + power8, +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/arch/powerpc64.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/powerpc64.rs new file mode 100644 index 000000000..c10220269 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/powerpc64.rs @@ -0,0 +1,42 @@ +//! Run-time feature detection on PowerPC64. + +/// Checks if `powerpc64` feature is enabled. +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +#[allow_internal_unstable(stdsimd_internal, stdsimd)] +macro_rules! is_powerpc64_feature_detected { + ("altivec") => { + cfg!(target_feature = "altivec") + || $crate::detect::check_for($crate::detect::Feature::altivec) + }; + ("vsx") => { + cfg!(target_feature = "vsx") || $crate::detect::check_for($crate::detect::Feature::vsx) + }; + ("power8") => { + cfg!(target_feature = "power8") + || $crate::detect::check_for($crate::detect::Feature::power8) + }; + ($t:tt,) => { + is_powerpc64_feature_detected!($t); + }; + ($t:tt) => { + compile_error!(concat!("unknown powerpc64 target feature: ", $t)) + }; +} + +/// PowerPC64 CPU Feature enum. Each variant denotes a position in a bitset +/// for a particular feature. +/// +/// PLEASE: do not use this, it is an implementation detail subject to change. +#[doc(hidden)] +#[allow(non_camel_case_types)] +#[repr(u8)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// Altivec + altivec, + /// VSX + vsx, + /// Power8 + power8, +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/arch/x86.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/x86.rs new file mode 100644 index 000000000..02d5eed1c --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/x86.rs @@ -0,0 +1,333 @@ +//! This module implements minimal run-time feature detection for x86. +//! +//! The features are detected using the `detect_features` function below. +//! This function uses the CPUID instruction to read the feature flags from the +//! CPU and encodes them in a `usize` where each bit position represents +//! whether a feature is available (bit is set) or unavailable (bit is cleared). +//! +//! The enum `Feature` is used to map bit positions to feature names, and the +//! the `__crate::detect::check_for!` macro is used to map string literals (e.g., +//! "avx") to these bit positions (e.g., `Feature::avx`). +//! +//! The run-time feature detection is performed by the +//! `__crate::detect::check_for(Feature) -> bool` function. On its first call, +//! this functions queries the CPU for the available features and stores them +//! in a global `AtomicUsize` variable. The query is performed by just checking +//! whether the feature bit in this global variable is set or cleared. + +/// A macro to test at *runtime* whether a CPU feature is available on +/// x86/x86-64 platforms. +/// +/// This macro is provided in the standard library and will detect at runtime +/// whether the specified CPU feature is detected. This does **not** resolve at +/// compile time unless the specified feature is already enabled for the entire +/// crate. Runtime detection currently relies mostly on the `cpuid` instruction. +/// +/// This macro only takes one argument which is a string literal of the feature +/// being tested for. The feature names supported are the lowercase versions of +/// the ones defined by Intel in [their documentation][docs]. +/// +/// ## Supported arguments +/// +/// This macro supports the same names that `#[target_feature]` supports. Unlike +/// `#[target_feature]`, however, this macro does not support names separated +/// with a comma. Instead testing for multiple features must be done through +/// separate macro invocations for now. +/// +/// Supported arguments are: +/// +/// * `"aes"` +/// * `"pclmulqdq"` +/// * `"rdrand"` +/// * `"rdseed"` +/// * `"tsc"` +/// * `"mmx"` +/// * `"sse"` +/// * `"sse2"` +/// * `"sse3"` +/// * `"ssse3"` +/// * `"sse4.1"` +/// * `"sse4.2"` +/// * `"sse4a"` +/// * `"sha"` +/// * `"avx"` +/// * `"avx2"` +/// * `"avx512f"` +/// * `"avx512cd"` +/// * `"avx512er"` +/// * `"avx512pf"` +/// * `"avx512bw"` +/// * `"avx512dq"` +/// * `"avx512vl"` +/// * `"avx512ifma"` +/// * `"avx512vbmi"` +/// * `"avx512vpopcntdq"` +/// * `"f16c"` +/// * `"fma"` +/// * `"bmi1"` +/// * `"bmi2"` +/// * `"abm"` +/// * `"lzcnt"` +/// * `"tbm"` +/// * `"popcnt"` +/// * `"fxsr"` +/// * `"xsave"` +/// * `"xsaveopt"` +/// * `"xsaves"` +/// * `"xsavec"` +/// * `"adx"` +/// * `"rtm"` +/// +/// [docs]: https://software.intel.com/sites/landingpage/IntrinsicsGuide +#[macro_export] +#[stable(feature = "simd_x86", since = "1.27.0")] +#[allow_internal_unstable(stdsimd_internal, stdsimd)] +macro_rules! is_x86_feature_detected { + ("aes") => { + cfg!(target_feature = "aes") || $crate::detect::check_for($crate::detect::Feature::aes) + }; + ("pclmulqdq") => { + cfg!(target_feature = "pclmulqdq") + || $crate::detect::check_for($crate::detect::Feature::pclmulqdq) + }; + ("rdrand") => { + cfg!(target_feature = "rdrand") + || $crate::detect::check_for($crate::detect::Feature::rdrand) + }; + ("rdseed") => { + cfg!(target_feature = "rdseed") + || $crate::detect::check_for($crate::detect::Feature::rdseed) + }; + ("tsc") => { + cfg!(target_feature = "tsc") || $crate::detect::check_for($crate::detect::Feature::tsc) + }; + ("mmx") => { + cfg!(target_feature = "mmx") || $crate::detect::check_for($crate::detect::Feature::mmx) + }; + ("sse") => { + cfg!(target_feature = "sse") || $crate::detect::check_for($crate::detect::Feature::sse) + }; + ("sse2") => { + cfg!(target_feature = "sse2") || $crate::detect::check_for($crate::detect::Feature::sse2) + }; + ("sse3") => { + cfg!(target_feature = "sse3") || $crate::detect::check_for($crate::detect::Feature::sse3) + }; + ("ssse3") => { + cfg!(target_feature = "ssse3") || $crate::detect::check_for($crate::detect::Feature::ssse3) + }; + ("sse4.1") => { + cfg!(target_feature = "sse4.1") + || $crate::detect::check_for($crate::detect::Feature::sse4_1) + }; + ("sse4.2") => { + cfg!(target_feature = "sse4.2") + || $crate::detect::check_for($crate::detect::Feature::sse4_2) + }; + ("sse4a") => { + cfg!(target_feature = "sse4a") || $crate::detect::check_for($crate::detect::Feature::sse4a) + }; + ("sha") => { + cfg!(target_feature = "sha") || $crate::detect::check_for($crate::detect::Feature::sha) + }; + ("avx") => { + cfg!(target_feature = "avx") || $crate::detect::check_for($crate::detect::Feature::avx) + }; + ("avx2") => { + cfg!(target_feature = "avx2") || $crate::detect::check_for($crate::detect::Feature::avx2) + }; + ("avx512f") => { + cfg!(target_feature = "avx512f") + || $crate::detect::check_for($crate::detect::Feature::avx512f) + }; + ("avx512cd") => { + cfg!(target_feature = "avx512cd") + || $crate::detect::check_for($crate::detect::Feature::avx512cd) + }; + ("avx512er") => { + cfg!(target_feature = "avx512er") + || $crate::detect::check_for($crate::detect::Feature::avx512er) + }; + ("avx512pf") => { + cfg!(target_feature = "avx512pf") + || $crate::detect::check_for($crate::detect::Feature::avx512pf) + }; + ("avx512bw") => { + cfg!(target_feature = "avx512bw") + || $crate::detect::check_for($crate::detect::Feature::avx512bw) + }; + ("avx512dq") => { + cfg!(target_feature = "avx512dq") + || $crate::detect::check_for($crate::detect::Feature::avx512dq) + }; + ("avx512vl") => { + cfg!(target_Feature = "avx512vl") + || $crate::detect::check_for($crate::detect::Feature::avx512vl) + }; + ("avx512ifma") => { + cfg!(target_feature = "avx512ifma") + || $crate::detect::check_for($crate::detect::Feature::avx512_ifma) + }; + ("avx512vbmi") => { + cfg!(target_feature = "avx512vbmi") + || $crate::detect::check_for($crate::detect::Feature::avx512_vbmi) + }; + ("avx512vpopcntdq") => { + cfg!(target_feature = "avx512vpopcntdq") + || $crate::detect::check_for($crate::detect::Feature::avx512_vpopcntdq) + }; + ("f16c") => { + cfg!(target_feature = "f16c") || $crate::detect::check_for($crate::detect::Feature::f16c) + }; + ("fma") => { + cfg!(target_feature = "fma") || $crate::detect::check_for($crate::detect::Feature::fma) + }; + ("bmi1") => { + cfg!(target_feature = "bmi1") || $crate::detect::check_for($crate::detect::Feature::bmi) + }; + ("bmi2") => { + cfg!(target_feature = "bmi2") || $crate::detect::check_for($crate::detect::Feature::bmi2) + }; + ("abm") => { + cfg!(target_feature = "abm") || $crate::detect::check_for($crate::detect::Feature::abm) + }; + ("lzcnt") => { + cfg!(target_feature = "lzcnt") || $crate::detect::check_for($crate::detect::Feature::abm) + }; + ("tbm") => { + cfg!(target_feature = "tbm") || $crate::detect::check_for($crate::detect::Feature::tbm) + }; + ("popcnt") => { + cfg!(target_feature = "popcnt") + || $crate::detect::check_for($crate::detect::Feature::popcnt) + }; + ("fxsr") => { + cfg!(target_feature = "fxsr") || $crate::detect::check_for($crate::detect::Feature::fxsr) + }; + ("xsave") => { + cfg!(target_feature = "xsave") || $crate::detect::check_for($crate::detect::Feature::xsave) + }; + ("xsaveopt") => { + cfg!(target_feature = "xsaveopt") + || $crate::detect::check_for($crate::detect::Feature::xsaveopt) + }; + ("xsaves") => { + cfg!(target_feature = "xsaves") + || $crate::detect::check_for($crate::detect::Feature::xsaves) + }; + ("xsavec") => { + cfg!(target_feature = "xsavec") + || $crate::detect::check_for($crate::detect::Feature::xsavec) + }; + ("cmpxchg16b") => { + cfg!(target_feature = "cmpxchg16b") + || $crate::detect::check_for($crate::detect::Feature::cmpxchg16b) + }; + ("adx") => { + cfg!(target_feature = "adx") || $crate::detect::check_for($crate::detect::Feature::adx) + }; + ("rtm") => { + cfg!(target_feature = "rtm") || $crate::detect::check_for($crate::detect::Feature::rtm) + }; + ($t:tt,) => { + is_x86_feature_detected!($t); + }; + ($t:tt) => { + compile_error!(concat!("unknown target feature: ", $t)) + }; +} + +/// X86 CPU Feature enum. Each variant denotes a position in a bitset for a +/// particular feature. +/// +/// This is an unstable implementation detail subject to change. +#[allow(non_camel_case_types)] +#[repr(u8)] +#[doc(hidden)] +#[unstable(feature = "stdsimd_internal", issue = "0")] +pub enum Feature { + /// AES (Advanced Encryption Standard New Instructions AES-NI) + aes, + /// CLMUL (Carry-less Multiplication) + pclmulqdq, + /// RDRAND + rdrand, + /// RDSEED + rdseed, + /// TSC (Time Stamp Counter) + tsc, + /// MMX + mmx, + /// SSE (Streaming SIMD Extensions) + sse, + /// SSE2 (Streaming SIMD Extensions 2) + sse2, + /// SSE3 (Streaming SIMD Extensions 3) + sse3, + /// SSSE3 (Supplemental Streaming SIMD Extensions 3) + ssse3, + /// SSE4.1 (Streaming SIMD Extensions 4.1) + sse4_1, + /// SSE4.2 (Streaming SIMD Extensions 4.2) + sse4_2, + /// SSE4a (Streaming SIMD Extensions 4a) + sse4a, + /// SHA + sha, + /// AVX (Advanced Vector Extensions) + avx, + /// AVX2 (Advanced Vector Extensions 2) + avx2, + /// AVX-512 F (Foundation) + avx512f, + /// AVX-512 CD (Conflict Detection Instructions) + avx512cd, + /// AVX-512 ER (Exponential and Reciprocal Instructions) + avx512er, + /// AVX-512 PF (Prefetch Instructions) + avx512pf, + /// AVX-512 BW (Byte and Word Instructions) + avx512bw, + /// AVX-512 DQ (Doubleword and Quadword) + avx512dq, + /// AVX-512 VL (Vector Length Extensions) + avx512vl, + /// AVX-512 IFMA (Integer Fused Multiply Add) + avx512_ifma, + /// AVX-512 VBMI (Vector Byte Manipulation Instructions) + avx512_vbmi, + /// AVX-512 VPOPCNTDQ (Vector Population Count Doubleword and + /// Quadword) + avx512_vpopcntdq, + /// F16C (Conversions between IEEE-754 `binary16` and `binary32` formats) + f16c, + /// FMA (Fused Multiply Add) + fma, + /// BMI1 (Bit Manipulation Instructions 1) + bmi, + /// BMI1 (Bit Manipulation Instructions 2) + bmi2, + /// ABM (Advanced Bit Manipulation) on AMD / LZCNT (Leading Zero + /// Count) on Intel + abm, + /// TBM (Trailing Bit Manipulation) + tbm, + /// POPCNT (Population Count) + popcnt, + /// FXSR (Floating-point context fast save and restor) + fxsr, + /// XSAVE (Save Processor Extended States) + xsave, + /// XSAVEOPT (Save Processor Extended States Optimized) + xsaveopt, + /// XSAVES (Save Processor Extended States Supervisor) + xsaves, + /// XSAVEC (Save Processor Extended States Compacted) + xsavec, + /// CMPXCH16B, a 16-byte compare-and-swap instruction + cmpxchg16b, + /// ADX, Intel ADX (Multi-Precision Add-Carry Instruction Extensions) + adx, + /// RTM, Intel (Restricted Transactional Memory) + rtm, +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/bit.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/bit.rs new file mode 100644 index 000000000..578f0b16b --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/bit.rs @@ -0,0 +1,9 @@ +//! Bit manipulation utilities. + +/// Tests the `bit` of `x`. +#[allow(dead_code)] +#[inline] +pub(crate) fn test(x: usize, bit: u32) -> bool { + debug_assert!(bit < 32, "bit index out-of-bounds"); + x & (1 << bit) != 0 +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/cache.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/cache.rs new file mode 100644 index 000000000..92bc4b58d --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/cache.rs @@ -0,0 +1,164 @@ +//! Caches run-time feature detection so that it only needs to be computed +//! once. + +#![allow(dead_code)] // not used on all platforms + +use crate::sync::atomic::Ordering; + +#[cfg(target_pointer_width = "64")] +use crate::sync::atomic::AtomicU64; + +#[cfg(target_pointer_width = "32")] +use crate::sync::atomic::AtomicU32; + +/// Sets the `bit` of `x`. +#[inline] +const fn set_bit(x: u64, bit: u32) -> u64 { + x | 1 << bit +} + +/// Tests the `bit` of `x`. +#[inline] +const fn test_bit(x: u64, bit: u32) -> bool { + x & (1 << bit) != 0 +} + +/// Maximum number of features that can be cached. +const CACHE_CAPACITY: u32 = 63; + +/// This type is used to initialize the cache +#[derive(Copy, Clone)] +pub(crate) struct Initializer(u64); + +#[allow(clippy::use_self)] +impl Default for Initializer { + fn default() -> Self { + Initializer(0) + } +} + +impl Initializer { + /// Tests the `bit` of the cache. + #[allow(dead_code)] + #[inline] + pub(crate) fn test(self, bit: u32) -> bool { + // FIXME: this way of making sure that the cache is large enough is + // brittle. + debug_assert!( + bit < CACHE_CAPACITY, + "too many features, time to increase the cache size!" + ); + test_bit(self.0, bit) + } + + /// Sets the `bit` of the cache. + #[inline] + pub(crate) fn set(&mut self, bit: u32) { + // FIXME: this way of making sure that the cache is large enough is + // brittle. + debug_assert!( + bit < CACHE_CAPACITY, + "too many features, time to increase the cache size!" + ); + let v = self.0; + self.0 = set_bit(v, bit); + } +} + +/// This global variable is a cache of the features supported by the CPU. +static CACHE: Cache = Cache::uninitialized(); + +/// Feature cache with capacity for `CACHE_CAPACITY` features. +/// +/// Note: the last feature bit is used to represent an +/// uninitialized cache. +#[cfg(target_pointer_width = "64")] +struct Cache(AtomicU64); + +#[cfg(target_pointer_width = "64")] +#[allow(clippy::use_self)] +impl Cache { + /// Creates an uninitialized cache. + #[allow(clippy::declare_interior_mutable_const)] + const fn uninitialized() -> Self { + Cache(AtomicU64::new(u64::max_value())) + } + /// Is the cache uninitialized? + #[inline] + pub(crate) fn is_uninitialized(&self) -> bool { + self.0.load(Ordering::Relaxed) == u64::max_value() + } + + /// Is the `bit` in the cache set? + #[inline] + pub(crate) fn test(&self, bit: u32) -> bool { + test_bit(CACHE.0.load(Ordering::Relaxed), bit) + } + + /// Initializes the cache. + #[inline] + pub(crate) fn initialize(&self, value: Initializer) { + self.0.store(value.0, Ordering::Relaxed); + } +} + +/// Feature cache with capacity for `CACHE_CAPACITY` features. +/// +/// Note: the last feature bit is used to represent an +/// uninitialized cache. +#[cfg(target_pointer_width = "32")] +struct Cache(AtomicU32, AtomicU32); + +#[cfg(target_pointer_width = "32")] +impl Cache { + /// Creates an uninitialized cache. + const fn uninitialized() -> Self { + Cache( + AtomicU32::new(u32::max_value()), + AtomicU32::new(u32::max_value()), + ) + } + /// Is the cache uninitialized? + #[inline] + pub(crate) fn is_uninitialized(&self) -> bool { + self.1.load(Ordering::Relaxed) == u32::max_value() + } + + /// Is the `bit` in the cache set? + #[inline] + pub(crate) fn test(&self, bit: u32) -> bool { + if bit < 32 { + test_bit(CACHE.0.load(Ordering::Relaxed) as u64, bit) + } else { + test_bit(CACHE.1.load(Ordering::Relaxed) as u64, bit - 32) + } + } + + /// Initializes the cache. + #[inline] + pub(crate) fn initialize(&self, value: Initializer) { + let lo: u32 = value.0 as u32; + let hi: u32 = (value.0 >> 32) as u32; + self.0.store(lo, Ordering::Relaxed); + self.1.store(hi, Ordering::Relaxed); + } +} + +/// Tests the `bit` of the storage. If the storage has not been initialized, +/// initializes it with the result of `f()`. +/// +/// On its first invocation, it detects the CPU features and caches them in the +/// `CACHE` global variable as an `AtomicU64`. +/// +/// It uses the `Feature` variant to index into this variable as a bitset. If +/// the bit is set, the feature is enabled, and otherwise it is disabled. +#[inline] +pub(crate) fn test<F>(bit: u32, f: F) -> bool +where + F: FnOnce() -> Initializer, +{ + if CACHE.is_uninitialized() { + CACHE.initialize(f()); + } + CACHE.test(bit) +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/error_macros.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/error_macros.rs new file mode 100644 index 000000000..6769757ed --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/error_macros.rs @@ -0,0 +1,150 @@ +//! The `is_{target_arch}_feature_detected!` macro are only available on their +//! architecture. These macros provide a better error messages when the user +//! attempts to call them in a different architecture. + +/// Prevents compilation if `is_x86_feature_detected` is used somewhere +/// else than `x86` and `x86_64` targets. +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_x86_feature_detected { + ($t: tt) => { + compile_error!( + r#" + is_x86_feature_detected can only be used on x86 and x86_64 targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + if is_x86_feature_detected(...) { ... } + } + "# + ) + }; +} + +/// Prevents compilation if `is_arm_feature_detected` is used somewhere else +/// than `ARM` targets. +#[cfg(not(target_arch = "arm"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_arm_feature_detected { + ($t:tt) => { + compile_error!( + r#" + is_arm_feature_detected can only be used on ARM targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "arm")] { + if is_arm_feature_detected(...) { ... } + } + "# + ) + }; +} + +/// Prevents compilation if `is_aarch64_feature_detected` is used somewhere else +/// than `aarch64` targets. +#[cfg(not(target_arch = "aarch64"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_aarch64_feature_detected { + ($t: tt) => { + compile_error!( + r#" + is_aarch64_feature_detected can only be used on AArch64 targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "aarch64")] { + if is_aarch64_feature_detected(...) { ... } + } + "# + ) + }; +} + +/// Prevents compilation if `is_powerpc_feature_detected` is used somewhere else +/// than `PowerPC` targets. +#[cfg(not(target_arch = "powerpc"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_powerpc_feature_detected { + ($t:tt) => { + compile_error!( + r#" +is_powerpc_feature_detected can only be used on PowerPC targets. +You can prevent it from being used in other architectures by +guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "powerpc")] { + if is_powerpc_feature_detected(...) { ... } + } +"# + ) + }; +} + +/// Prevents compilation if `is_powerpc64_feature_detected` is used somewhere +/// else than `PowerPC64` targets. +#[cfg(not(target_arch = "powerpc64"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_powerpc64_feature_detected { + ($t:tt) => { + compile_error!( + r#" +is_powerpc64_feature_detected can only be used on PowerPC64 targets. +You can prevent it from being used in other architectures by +guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "powerpc64")] { + if is_powerpc64_feature_detected(...) { ... } + } +"# + ) + }; +} + +/// Prevents compilation if `is_mips_feature_detected` is used somewhere else +/// than `MIPS` targets. +#[cfg(not(target_arch = "mips"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_mips_feature_detected { + ($t:tt) => { + compile_error!( + r#" + is_mips_feature_detected can only be used on MIPS targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "mips")] { + if is_mips_feature_detected(...) { ... } + } + "# + ) + }; +} + +/// Prevents compilation if `is_mips64_feature_detected` is used somewhere else +/// than `MIPS64` targets. +#[cfg(not(target_arch = "mips64"))] +#[macro_export] +#[unstable(feature = "stdsimd", issue = "27731")] +macro_rules! is_mips64_feature_detected { + ($t:tt) => { + compile_error!( + r#" + is_mips64_feature_detected can only be used on MIPS64 targets. + You can prevent it from being used in other architectures by + guarding it behind a cfg(target_arch) as follows: + + #[cfg(target_arch = "mips64")] { + if is_mips64_feature_detected(...) { ... } + } + "# + ) + }; +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/mod.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/mod.rs new file mode 100644 index 000000000..f446e88ee --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/mod.rs @@ -0,0 +1,85 @@ +//! This module implements run-time feature detection. +//! +//! The `is_{arch}_feature_detected!("feature-name")` macros take the name of a +//! feature as a string-literal, and return a boolean indicating whether the +//! feature is enabled at run-time or not. +//! +//! These macros do two things: +//! * map the string-literal into an integer stored as a `Feature` enum, +//! * call a `os::check_for(x: Feature)` function that returns `true` if the +//! feature is enabled. +//! +//! The `Feature` enums are also implemented in the `arch/{target_arch}.rs` +//! modules. +//! +//! The `check_for` functions are, in general, Operating System dependent. Most +//! architectures do not allow user-space programs to query the feature bits +//! due to security concerns (x86 is the big exception). These functions are +//! implemented in the `os/{target_os}.rs` modules. + +#[macro_use] +mod error_macros; + +cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + #[path = "arch/x86.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "arm")] { + #[path = "arch/arm.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "aarch64")] { + #[path = "arch/aarch64.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "powerpc")] { + #[path = "arch/powerpc.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "powerpc64")] { + #[path = "arch/powerpc64.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "mips")] { + #[path = "arch/mips.rs"] + #[macro_use] + mod arch; + } else if #[cfg(target_arch = "mips64")] { + #[path = "arch/mips64.rs"] + #[macro_use] + mod arch; + } else { + // Unimplemented architecture: + mod arch { + pub enum Feature { + Null + } + } + } +} +pub use self::arch::Feature; + +mod bit; +mod cache; + +cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + // On x86/x86_64 no OS specific functionality is required. + #[path = "os/x86.rs"] + mod os; + } else if #[cfg(all(target_os = "linux", feature = "use_std"))] { + #[path = "os/linux/mod.rs"] + mod os; + } else if #[cfg(target_os = "freebsd")] { + #[cfg(target_arch = "aarch64")] + #[path = "os/aarch64.rs"] + mod aarch64; + #[path = "os/freebsd/mod.rs"] + mod os; + } else { + #[path = "os/other.rs"] + mod os; + } +} +pub use self::os::check_for; diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/aarch64.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/aarch64.rs new file mode 100644 index 000000000..9adc938a2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/aarch64.rs @@ -0,0 +1,88 @@ +//! Run-time feature detection for Aarch64 on any OS that emulates the mrs instruction. +//! +//! On FreeBSD >= 12.0, Linux >= 4.11 and other operating systems, it is possible to use +//! privileged system registers from userspace to check CPU feature support. +//! +//! AArch64 system registers ID_AA64ISAR0_EL1, ID_AA64PFR0_EL1, ID_AA64ISAR1_EL1 +//! have bits dedicated to features like AdvSIMD, CRC32, AES, atomics (LSE), etc. +//! Each part of the register indicates the level of support for a certain feature, e.g. +//! when ID_AA64ISAR0_EL1\[7:4\] is >= 1, AES is supported; when it's >= 2, PMULL is supported. +//! +//! For proper support of [SoCs where different cores have different capabilities](https://medium.com/@jadr2ddude/a-big-little-problem-a-tale-of-big-little-gone-wrong-e7778ce744bb), +//! the OS has to always report only the features supported by all cores, like [FreeBSD does](https://reviews.freebsd.org/D17137#393947). +//! +//! References: +//! +//! - [Zircon implementation](https://fuchsia.googlesource.com/zircon/+/master/kernel/arch/arm64/feature.cpp) +//! - [Linux documentation](https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt) + +use crate::detect::{cache, Feature}; + +/// Try to read the features from the system registers. +/// +/// This will cause SIGILL if the current OS is not trapping the mrs instruction. +pub(crate) fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + + { + let mut enable_feature = |f, enable| { + if enable { + value.set(f as u32); + } + }; + + // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0 + let aa64isar0: u64; + unsafe { + asm!("mrs $0, ID_AA64ISAR0_EL1" : "=r"(aa64isar0)); + } + + let aes = bits_shift(aa64isar0, 7, 4) >= 1; + let pmull = bits_shift(aa64isar0, 7, 4) >= 2; + let sha1 = bits_shift(aa64isar0, 11, 8) >= 1; + let sha2 = bits_shift(aa64isar0, 15, 12) >= 1; + enable_feature(Feature::pmull, pmull); + // Crypto is specified as AES + PMULL + SHA1 + SHA2 per LLVM/hosts.cpp + enable_feature(Feature::crypto, aes && pmull && sha1 && sha2); + enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 1); + enable_feature(Feature::crc, bits_shift(aa64isar0, 19, 16) >= 1); + + // ID_AA64PFR0_EL1 - Processor Feature Register 0 + let aa64pfr0: u64; + unsafe { + asm!("mrs $0, ID_AA64PFR0_EL1" : "=r"(aa64pfr0)); + } + + let fp = bits_shift(aa64pfr0, 19, 16) < 0xF; + let fphp = bits_shift(aa64pfr0, 19, 16) >= 1; + let asimd = bits_shift(aa64pfr0, 23, 20) < 0xF; + let asimdhp = bits_shift(aa64pfr0, 23, 20) >= 1; + enable_feature(Feature::fp, fp); + enable_feature(Feature::fp16, fphp); + // SIMD support requires float support - if half-floats are + // supported, it also requires half-float support: + enable_feature(Feature::asimd, fp && asimd && (!fphp | asimdhp)); + // SIMD extensions require SIMD support: + enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1); + enable_feature( + Feature::dotprod, + asimd && bits_shift(aa64isar0, 47, 44) >= 1, + ); + enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1); + + // ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1 + let aa64isar1: u64; + unsafe { + asm!("mrs $0, ID_AA64ISAR1_EL1" : "=r"(aa64isar1)); + } + + enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1); + } + + value +} + +#[inline] +fn bits_shift(x: u64, high: usize, low: usize) -> u64 { + (x >> low) & ((1 << (high - low + 1)) - 1) +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/aarch64.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/aarch64.rs new file mode 100644 index 000000000..97fe40f80 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/aarch64.rs @@ -0,0 +1,28 @@ +//! Run-time feature detection for Aarch64 on FreeBSD. + +use super::super::aarch64::detect_features; +use crate::detect::{cache, Feature}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +#[cfg(test)] +mod tests { + #[test] + fn dump() { + println!("asimd: {:?}", is_aarch64_feature_detected!("asimd")); + println!("pmull: {:?}", is_aarch64_feature_detected!("pmull")); + println!("fp: {:?}", is_aarch64_feature_detected!("fp")); + println!("fp16: {:?}", is_aarch64_feature_detected!("fp16")); + println!("sve: {:?}", is_aarch64_feature_detected!("sve")); + println!("crc: {:?}", is_aarch64_feature_detected!("crc")); + println!("crypto: {:?}", is_aarch64_feature_detected!("crypto")); + println!("lse: {:?}", is_aarch64_feature_detected!("lse")); + println!("rdm: {:?}", is_aarch64_feature_detected!("rdm")); + println!("rcpc: {:?}", is_aarch64_feature_detected!("rcpc")); + println!("dotprod: {:?}", is_aarch64_feature_detected!("dotprod")); + } +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/arm.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/arm.rs new file mode 100644 index 000000000..7aa040075 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/arm.rs @@ -0,0 +1,27 @@ +//! Run-time feature detection for ARM on FreeBSD + +use super::auxvec; +use crate::detect::{cache, Feature}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + if let Ok(auxv) = auxvec::auxv() { + enable_feature(&mut value, Feature::neon, auxv.hwcap & 0x00001000 != 0); + enable_feature(&mut value, Feature::pmull, auxv.hwcap2 & 0x00000002 != 0); + return value; + } + value +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/auxvec.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/auxvec.rs new file mode 100644 index 000000000..c595ec459 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/auxvec.rs @@ -0,0 +1,94 @@ +//! Parses ELF auxiliary vectors. +#![cfg_attr(any(target_arch = "arm", target_arch = "powerpc64"), allow(dead_code))] + +/// Key to access the CPU Hardware capabilities bitfield. +pub(crate) const AT_HWCAP: usize = 25; +/// Key to access the CPU Hardware capabilities 2 bitfield. +pub(crate) const AT_HWCAP2: usize = 26; + +/// Cache HWCAP bitfields of the ELF Auxiliary Vector. +/// +/// If an entry cannot be read all the bits in the bitfield are set to zero. +/// This should be interpreted as all the features being disabled. +#[derive(Debug, Copy, Clone)] +pub(crate) struct AuxVec { + pub hwcap: usize, + pub hwcap2: usize, +} + +/// ELF Auxiliary Vector +/// +/// The auxiliary vector is a memory region in a running ELF program's stack +/// composed of (key: usize, value: usize) pairs. +/// +/// The keys used in the aux vector are platform dependent. For FreeBSD, they are +/// defined in [sys/elf_common.h][elf_common_h]. The hardware capabilities of a given +/// CPU can be queried with the `AT_HWCAP` and `AT_HWCAP2` keys. +/// +/// Note that run-time feature detection is not invoked for features that can +/// be detected at compile-time. +/// +/// [elf_common.h]: https://svnweb.freebsd.org/base/release/12.0.0/sys/sys/elf_common.h?revision=341707 +pub(crate) fn auxv() -> Result<AuxVec, ()> { + if let Ok(hwcap) = archauxv(AT_HWCAP) { + if let Ok(hwcap2) = archauxv(AT_HWCAP2) { + if hwcap != 0 && hwcap2 != 0 { + return Ok(AuxVec { hwcap, hwcap2 }); + } + } + } + Err(()) +} + +/// Tries to read the `key` from the auxiliary vector. +fn archauxv(key: usize) -> Result<usize, ()> { + use crate::mem; + + #[derive(Copy, Clone)] + #[repr(C)] + pub struct Elf_Auxinfo { + pub a_type: usize, + pub a_un: unnamed, + } + #[derive(Copy, Clone)] + #[repr(C)] + pub union unnamed { + pub a_val: libc::c_long, + pub a_ptr: *mut libc::c_void, + pub a_fcn: Option<unsafe extern "C" fn() -> ()>, + } + + let mut auxv: [Elf_Auxinfo; 27] = [Elf_Auxinfo { + a_type: 0, + a_un: unnamed { a_val: 0 }, + }; 27]; + + let mut len: libc::c_uint = mem::size_of_val(&auxv) as libc::c_uint; + + unsafe { + let mut mib = [ + libc::CTL_KERN, + libc::KERN_PROC, + libc::KERN_PROC_AUXV, + libc::getpid(), + ]; + + let ret = libc::sysctl( + mib.as_mut_ptr(), + mib.len() as u32, + &mut auxv as *mut _ as *mut _, + &mut len as *mut _ as *mut _, + 0 as *mut libc::c_void, + 0, + ); + + if ret != -1 { + for i in 0..auxv.len() { + if auxv[i].a_type == key { + return Ok(auxv[i].a_un.a_val as usize); + } + } + } + } + return Ok(0); +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/mod.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/mod.rs new file mode 100644 index 000000000..1a5338a35 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/mod.rs @@ -0,0 +1,22 @@ +//! Run-time feature detection on FreeBSD + +mod auxvec; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::check_for; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::check_for; + } else if #[cfg(target_arch = "powerpc64")] { + mod powerpc; + pub use self::powerpc::check_for; + } else { + use crate::arch::detect::Feature; + /// Performs run-time feature detection. + pub fn check_for(_x: Feature) -> bool { + false + } + } +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/powerpc.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/powerpc.rs new file mode 100644 index 000000000..203e5cd7f --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/freebsd/powerpc.rs @@ -0,0 +1,27 @@ +//! Run-time feature detection for PowerPC on FreeBSD. + +use super::auxvec; +use crate::detect::{cache, Feature}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + if let Ok(auxv) = auxvec::auxv() { + enable_feature(&mut value, Feature::altivec, auxv.hwcap & 0x10000000 != 0); + enable_feature(&mut value, Feature::vsx, auxv.hwcap & 0x00000080 != 0); + enable_feature(&mut value, Feature::power8, auxv.hwcap2 & 0x80000000 != 0); + return value; + } + value +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/aarch64.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/aarch64.rs new file mode 100644 index 000000000..8d874f228 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/aarch64.rs @@ -0,0 +1,160 @@ +//! Run-time feature detection for Aarch64 on Linux. + +use super::{auxvec, cpuinfo}; +use crate::detect::{bit, cache, Feature}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector, and if that fails, try +/// to read them from /proc/cpuinfo. +fn detect_features() -> cache::Initializer { + if let Ok(auxv) = auxvec::auxv() { + let hwcap: AtHwcap = auxv.into(); + return hwcap.cache(); + } + if let Ok(c) = cpuinfo::CpuInfo::new() { + let hwcap: AtHwcap = c.into(); + return hwcap.cache(); + } + cache::Initializer::default() +} + +/// These values are part of the platform-specific [asm/hwcap.h][hwcap] . +/// +/// [hwcap]: https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h +struct AtHwcap { + fp: bool, // 0 + asimd: bool, // 1 + // evtstrm: bool, // 2 + aes: bool, // 3 + pmull: bool, // 4 + sha1: bool, // 5 + sha2: bool, // 6 + crc32: bool, // 7 + atomics: bool, // 8 + fphp: bool, // 9 + asimdhp: bool, // 10 + // cpuid: bool, // 11 + asimdrdm: bool, // 12 + // jscvt: bool, // 13 + // fcma: bool, // 14 + lrcpc: bool, // 15 + // dcpop: bool, // 16 + // sha3: bool, // 17 + // sm3: bool, // 18 + // sm4: bool, // 19 + asimddp: bool, // 20 + // sha512: bool, // 21 + sve: bool, // 22 +} + +impl From<auxvec::AuxVec> for AtHwcap { + /// Reads AtHwcap from the auxiliary vector. + fn from(auxv: auxvec::AuxVec) -> Self { + AtHwcap { + fp: bit::test(auxv.hwcap, 0), + asimd: bit::test(auxv.hwcap, 1), + // evtstrm: bit::test(auxv.hwcap, 2), + aes: bit::test(auxv.hwcap, 3), + pmull: bit::test(auxv.hwcap, 4), + sha1: bit::test(auxv.hwcap, 5), + sha2: bit::test(auxv.hwcap, 6), + crc32: bit::test(auxv.hwcap, 7), + atomics: bit::test(auxv.hwcap, 8), + fphp: bit::test(auxv.hwcap, 9), + asimdhp: bit::test(auxv.hwcap, 10), + // cpuid: bit::test(auxv.hwcap, 11), + asimdrdm: bit::test(auxv.hwcap, 12), + // jscvt: bit::test(auxv.hwcap, 13), + // fcma: bit::test(auxv.hwcap, 14), + lrcpc: bit::test(auxv.hwcap, 15), + // dcpop: bit::test(auxv.hwcap, 16), + // sha3: bit::test(auxv.hwcap, 17), + // sm3: bit::test(auxv.hwcap, 18), + // sm4: bit::test(auxv.hwcap, 19), + asimddp: bit::test(auxv.hwcap, 20), + // sha512: bit::test(auxv.hwcap, 21), + sve: bit::test(auxv.hwcap, 22), + } + } +} + +impl From<cpuinfo::CpuInfo> for AtHwcap { + /// Reads AtHwcap from /proc/cpuinfo . + fn from(c: cpuinfo::CpuInfo) -> Self { + let f = &c.field("Features"); + AtHwcap { + // 64-bit names. FIXME: In 32-bit compatibility mode /proc/cpuinfo will + // map some of the 64-bit names to some 32-bit feature names. This does not + // cover that yet. + fp: f.has("fp"), + asimd: f.has("asimd"), + // evtstrm: f.has("evtstrm"), + aes: f.has("aes"), + pmull: f.has("pmull"), + sha1: f.has("sha1"), + sha2: f.has("sha2"), + crc32: f.has("crc32"), + atomics: f.has("atomics"), + fphp: f.has("fphp"), + asimdhp: f.has("asimdhp"), + // cpuid: f.has("cpuid"), + asimdrdm: f.has("asimdrdm"), + // jscvt: f.has("jscvt"), + // fcma: f.has("fcma"), + lrcpc: f.has("lrcpc"), + // dcpop: f.has("dcpop"), + // sha3: f.has("sha3"), + // sm3: f.has("sm3"), + // sm4: f.has("sm4"), + asimddp: f.has("asimddp"), + // sha512: f.has("sha512"), + sve: f.has("sve"), + } + } +} + +impl AtHwcap { + /// Initializes the cache from the feature -bits. + /// + /// The features are enabled approximately like in LLVM host feature detection: + /// https://github.com/llvm-mirror/llvm/blob/master/lib/Support/Host.cpp#L1273 + fn cache(self) -> cache::Initializer { + let mut value = cache::Initializer::default(); + { + let mut enable_feature = |f, enable| { + if enable { + value.set(f as u32); + } + }; + + enable_feature(Feature::fp, self.fp); + // Half-float support requires float support + enable_feature(Feature::fp16, self.fp && self.fphp); + enable_feature(Feature::pmull, self.pmull); + enable_feature(Feature::crc, self.crc32); + enable_feature(Feature::lse, self.atomics); + enable_feature(Feature::rcpc, self.lrcpc); + + // SIMD support requires float support - if half-floats are + // supported, it also requires half-float support: + let asimd = self.fp && self.asimd && (!self.fphp | self.asimdhp); + enable_feature(Feature::asimd, asimd); + // SIMD extensions require SIMD support: + enable_feature(Feature::rdm, self.asimdrdm && asimd); + enable_feature(Feature::dotprod, self.asimddp && asimd); + enable_feature(Feature::sve, self.sve && asimd); + + // Crypto is specified as AES + PMULL + SHA1 + SHA2 per LLVM/hosts.cpp + enable_feature( + Feature::crypto, + self.aes && self.pmull && self.sha1 && self.sha2, + ); + } + value + } +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/arm.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/arm.rs new file mode 100644 index 000000000..9c89500cc --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/arm.rs @@ -0,0 +1,52 @@ +//! Run-time feature detection for ARM on Linux. + +use super::{auxvec, cpuinfo}; +use crate::detect::{bit, cache, Feature}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector, and if that fails, try +/// to read them from /proc/cpuinfo. +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + // The values are part of the platform-specific [asm/hwcap.h][hwcap] + // + // [hwcap]: https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h + if let Ok(auxv) = auxvec::auxv() { + enable_feature(&mut value, Feature::neon, bit::test(auxv.hwcap, 12)); + enable_feature(&mut value, Feature::pmull, bit::test(auxv.hwcap2, 1)); + return value; + } + + if let Ok(c) = cpuinfo::CpuInfo::new() { + enable_feature( + &mut value, + Feature::neon, + c.field("Features").has("neon") && !has_broken_neon(&c), + ); + enable_feature(&mut value, Feature::pmull, c.field("Features").has("pmull")); + return value; + } + value +} + +/// Is the CPU known to have a broken NEON unit? +/// +/// See https://crbug.com/341598. +fn has_broken_neon(cpuinfo: &cpuinfo::CpuInfo) -> bool { + cpuinfo.field("CPU implementer") == "0x51" + && cpuinfo.field("CPU architecture") == "7" + && cpuinfo.field("CPU variant") == "0x1" + && cpuinfo.field("CPU part") == "0x04d" + && cpuinfo.field("CPU revision") == "0" +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/auxvec.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/auxvec.rs new file mode 100644 index 000000000..6ebae67fb --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/auxvec.rs @@ -0,0 +1,304 @@ +//! Parses ELF auxiliary vectors. +#![cfg_attr(not(target_arch = "aarch64"), allow(dead_code))] + +#[cfg(feature = "std_detect_file_io")] +use crate::{fs::File, io::Read}; + +/// Key to access the CPU Hardware capabilities bitfield. +pub(crate) const AT_HWCAP: usize = 16; +/// Key to access the CPU Hardware capabilities 2 bitfield. +#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] +pub(crate) const AT_HWCAP2: usize = 26; + +/// Cache HWCAP bitfields of the ELF Auxiliary Vector. +/// +/// If an entry cannot be read all the bits in the bitfield are set to zero. +/// This should be interpreted as all the features being disabled. +#[derive(Debug, Copy, Clone)] +pub(crate) struct AuxVec { + pub hwcap: usize, + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + pub hwcap2: usize, +} + +/// ELF Auxiliary Vector +/// +/// The auxiliary vector is a memory region in a running ELF program's stack +/// composed of (key: usize, value: usize) pairs. +/// +/// The keys used in the aux vector are platform dependent. For Linux, they are +/// defined in [linux/auxvec.h][auxvec_h]. The hardware capabilities of a given +/// CPU can be queried with the `AT_HWCAP` and `AT_HWCAP2` keys. +/// +/// There is no perfect way of reading the auxiliary vector. +/// +/// - If the `std_detect_dlsym_getauxval` cargo feature is enabled, this will use +/// `getauxval` if its linked to the binary, and otherwise proceed to a fallback implementation. +/// When `std_detect_dlsym_getauxval` is disabled, this will assume that `getauxval` is +/// linked to the binary - if that is not the case the behavior is undefined. +/// - Otherwise, if the `std_detect_file_io` cargo feature is enabled, it will +/// try to read `/proc/self/auxv`. +/// - If that fails, this function returns an error. +/// +/// Note that run-time feature detection is not invoked for features that can +/// be detected at compile-time. Also note that if this function returns an +/// error, cpuinfo still can (and will) be used to try to perform run-time +/// feature detecton on some platforms. +/// +/// For more information about when `getauxval` is available check the great +/// [`auxv` crate documentation][auxv_docs]. +/// +/// [auxvec_h]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/auxvec.h +/// [auxv_docs]: https://docs.rs/auxv/0.3.3/auxv/ +pub(crate) fn auxv() -> Result<AuxVec, ()> { + #[cfg(feature = "std_detect_dlsym_getauxval")] + { + // Try to call a dynamically-linked getauxval function. + if let Ok(hwcap) = getauxval(AT_HWCAP) { + // Targets with only AT_HWCAP: + #[cfg(any(target_arch = "aarch64", target_arch = "mips", target_arch = "mips64"))] + { + if hwcap != 0 { + return Ok(AuxVec { hwcap }); + } + } + + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + if let Ok(hwcap2) = getauxval(AT_HWCAP2) { + if hwcap != 0 && hwcap2 != 0 { + return Ok(AuxVec { hwcap, hwcap2 }); + } + } + } + drop(hwcap); + } + #[cfg(feature = "std_detect_file_io")] + { + // If calling getauxval fails, try to read the auxiliary vector from + // its file: + auxv_from_file("/proc/self/auxv") + } + #[cfg(not(feature = "std_detect_file_io"))] + { + Err(()) + } + } + + #[cfg(not(feature = "std_detect_dlsym_getauxval"))] + { + let hwcap = unsafe { ffi_getauxval(AT_HWCAP) }; + + // Targets with only AT_HWCAP: + #[cfg(any(target_arch = "aarch64", target_arch = "mips", target_arch = "mips64"))] + { + if hwcap != 0 { + return Ok(AuxVec { hwcap }); + } + } + + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + let hwcap2 = unsafe { ffi_getauxval(AT_HWCAP2) }; + if hwcap != 0 && hwcap2 != 0 { + return Ok(AuxVec { hwcap, hwcap2 }); + } + } + } +} + +/// Tries to read the `key` from the auxiliary vector by calling the +/// dynamically-linked `getauxval` function. If the function is not linked, +/// this function return `Err`. +#[cfg(feature = "std_detect_dlsym_getauxval")] +fn getauxval(key: usize) -> Result<usize, ()> { + use libc; + pub type F = unsafe extern "C" fn(usize) -> usize; + unsafe { + let ptr = libc::dlsym(libc::RTLD_DEFAULT, "getauxval\0".as_ptr() as *const _); + if ptr.is_null() { + return Err(()); + } + + let ffi_getauxval: F = mem::transmute(ptr); + Ok(ffi_getauxval(key)) + } +} + +/// Tries to read the auxiliary vector from the `file`. If this fails, this +/// function returns `Err`. +#[cfg(feature = "std_detect_file_io")] +fn auxv_from_file(file: &str) -> Result<AuxVec, ()> { + let mut file = File::open(file).map_err(|_| ())?; + + // See <https://github.com/torvalds/linux/blob/v3.19/include/uapi/linux/auxvec.h>. + // + // The auxiliary vector contains at most 32 (key,value) fields: from + // `AT_EXECFN = 31` to `AT_NULL = 0`. That is, a buffer of + // 2*32 `usize` elements is enough to read the whole vector. + let mut buf = [0_usize; 64]; + { + let raw: &mut [u8; 64 * mem::size_of::<usize>()] = unsafe { mem::transmute(&mut buf) }; + file.read(raw).map_err(|_| ())?; + } + auxv_from_buf(&buf) +} + +/// Tries to interpret the `buffer` as an auxiliary vector. If that fails, this +/// function returns `Err`. +#[cfg(feature = "std_detect_file_io")] +fn auxv_from_buf(buf: &[usize; 64]) -> Result<AuxVec, ()> { + // Targets with only AT_HWCAP: + #[cfg(any(target_arch = "aarch64", target_arch = "mips", target_arch = "mips64"))] + { + for el in buf.chunks(2) { + match el[0] { + AT_HWCAP => return Ok(AuxVec { hwcap: el[1] }), + _ => (), + } + } + } + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + let mut hwcap = None; + let mut hwcap2 = None; + for el in buf.chunks(2) { + match el[0] { + AT_HWCAP => hwcap = Some(el[1]), + AT_HWCAP2 => hwcap2 = Some(el[1]), + _ => (), + } + } + + if let (Some(hwcap), Some(hwcap2)) = (hwcap, hwcap2) { + return Ok(AuxVec { hwcap, hwcap2 }); + } + } + drop(buf); + Err(()) +} + +#[cfg(test)] +mod tests { + extern crate auxv as auxv_crate; + use super::*; + + // Reads the Auxiliary Vector key from /proc/self/auxv + // using the auxv crate. + #[cfg(feature = "std_detect_file_io")] + fn auxv_crate_getprocfs(key: usize) -> Option<usize> { + use self::auxv_crate::procfs::search_procfs_auxv; + use self::auxv_crate::AuxvType; + let k = key as AuxvType; + match search_procfs_auxv(&[k]) { + Ok(v) => Some(v[&k] as usize), + Err(_) => None, + } + } + + // Reads the Auxiliary Vector key from getauxval() + // using the auxv crate. + #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] + fn auxv_crate_getauxval(key: usize) -> Option<usize> { + use self::auxv_crate::getauxval::Getauxval; + use self::auxv_crate::AuxvType; + let q = auxv_crate::getauxval::NativeGetauxval {}; + match q.getauxval(key as AuxvType) { + Ok(v) => Some(v as usize), + Err(_) => None, + } + } + + // FIXME: on mips/mips64 getauxval returns 0, and /proc/self/auxv + // does not always contain the AT_HWCAP key under qemu. + #[cfg(not(any(target_arch = "mips", target_arch = "mips64", target_arch = "powerpc")))] + #[test] + fn auxv_crate() { + let v = auxv(); + if let Some(hwcap) = auxv_crate_getauxval(AT_HWCAP) { + let rt_hwcap = v.expect("failed to find hwcap key").hwcap; + assert_eq!(rt_hwcap, hwcap); + } + + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + if let Some(hwcap2) = auxv_crate_getauxval(AT_HWCAP2) { + let rt_hwcap2 = v.expect("failed to find hwcap2 key").hwcap2; + assert_eq!(rt_hwcap2, hwcap2); + } + } + } + + #[test] + fn auxv_dump() { + if let Ok(auxvec) = auxv() { + println!("{:?}", auxvec); + } else { + println!("both getauxval() and reading /proc/self/auxv failed!"); + } + } + + #[cfg(feature = "std_detect_file_io")] + cfg_if! { + if #[cfg(target_arch = "arm")] { + #[test] + fn linux_rpi3() { + let file = concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-rpi3.auxv"); + println!("file: {}", file); + let v = auxv_from_file(file).unwrap(); + assert_eq!(v.hwcap, 4174038); + assert_eq!(v.hwcap2, 16); + } + + #[test] + #[should_panic] + fn linux_macos_vb() { + let file = concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/macos-virtualbox-linux-x86-4850HQ.auxv"); + println!("file: {}", file); + let v = auxv_from_file(file).unwrap(); + // this file is incomplete (contains hwcap but not hwcap2), we + // want to fall back to /proc/cpuinfo in this case, so + // reading should fail. assert_eq!(v.hwcap, 126614527); + // assert_eq!(v.hwcap2, 0); + } + } else if #[cfg(target_arch = "aarch64")] { + #[test] + fn linux_x64() { + let file = concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-x64-i7-6850k.auxv"); + println!("file: {}", file); + let v = auxv_from_file(file).unwrap(); + assert_eq!(v.hwcap, 3219913727); + } + } + } + + #[test] + #[cfg(feature = "std_detect_file_io")] + fn auxv_dump_procfs() { + if let Ok(auxvec) = auxv_from_file("/proc/self/auxv") { + println!("{:?}", auxvec); + } else { + println!("reading /proc/self/auxv failed!"); + } + } + + #[test] + fn auxv_crate_procfs() { + let v = auxv(); + if let Some(hwcap) = auxv_crate_getprocfs(AT_HWCAP) { + assert_eq!(v.unwrap().hwcap, hwcap); + } + + // Targets with AT_HWCAP and AT_HWCAP2: + #[cfg(any(target_arch = "arm", target_arch = "powerpc64"))] + { + if let Some(hwcap2) = auxv_crate_getprocfs(AT_HWCAP2) { + assert_eq!(v.unwrap().hwcap2, hwcap2); + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/cpuinfo.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/cpuinfo.rs new file mode 100644 index 000000000..f76c48a4b --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/cpuinfo.rs @@ -0,0 +1,300 @@ +//! Parses /proc/cpuinfo +#![cfg_attr(not(target_arch = "arm"), allow(dead_code))] + +extern crate std; +use self::std::{fs::File, io, io::Read, prelude::v1::*}; + +/// cpuinfo +pub(crate) struct CpuInfo { + raw: String, +} + +impl CpuInfo { + /// Reads /proc/cpuinfo into CpuInfo. + pub(crate) fn new() -> Result<Self, io::Error> { + let mut file = File::open("/proc/cpuinfo")?; + let mut cpui = Self { raw: String::new() }; + file.read_to_string(&mut cpui.raw)?; + Ok(cpui) + } + /// Returns the value of the cpuinfo `field`. + pub(crate) fn field(&self, field: &str) -> CpuInfoField { + for l in self.raw.lines() { + if l.trim().starts_with(field) { + return CpuInfoField::new(l.split(": ").nth(1)); + } + } + CpuInfoField(None) + } + + /// Returns the `raw` contents of `/proc/cpuinfo` + #[cfg(test)] + fn raw(&self) -> &String { + &self.raw + } + + #[cfg(test)] + fn from_str(other: &str) -> Result<Self, ::std::io::Error> { + Ok(Self { + raw: String::from(other), + }) + } +} + +/// Field of cpuinfo +#[derive(Debug)] +pub(crate) struct CpuInfoField<'a>(Option<&'a str>); + +impl<'a> PartialEq<&'a str> for CpuInfoField<'a> { + fn eq(&self, other: &&'a str) -> bool { + match self.0 { + None => other.is_empty(), + Some(f) => f == other.trim(), + } + } +} + +impl<'a> CpuInfoField<'a> { + pub(crate) fn new<'b>(v: Option<&'b str>) -> CpuInfoField<'b> { + match v { + None => CpuInfoField::<'b>(None), + Some(f) => CpuInfoField::<'b>(Some(f.trim())), + } + } + /// Does the field exist? + #[cfg(test)] + pub(crate) fn exists(&self) -> bool { + self.0.is_some() + } + /// Does the field contain `other`? + pub(crate) fn has(&self, other: &str) -> bool { + match self.0 { + None => other.is_empty(), + Some(f) => { + let other = other.trim(); + for v in f.split(' ') { + if v == other { + return true; + } + } + false + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn raw_dump() { + let cpuinfo = CpuInfo::new().unwrap(); + if cpuinfo.field("vendor_id") == "GenuineIntel" { + assert!(cpuinfo.field("flags").exists()); + assert!(!cpuinfo.field("vendor33_id").exists()); + assert!(cpuinfo.field("flags").has("sse")); + assert!(!cpuinfo.field("flags").has("avx314")); + } + println!("{}", cpuinfo.raw()); + } + + const CORE_DUO_T6500: &str = r"processor : 0 +vendor_id : GenuineIntel +cpu family : 6 +model : 23 +model name : Intel(R) Core(TM)2 Duo CPU T6500 @ 2.10GHz +stepping : 10 +microcode : 0xa0b +cpu MHz : 1600.000 +cache size : 2048 KB +physical id : 0 +siblings : 2 +core id : 0 +cpu cores : 2 +apicid : 0 +initial apicid : 0 +fdiv_bug : no +hlt_bug : no +f00f_bug : no +coma_bug : no +fpu : yes +fpu_exception : yes +cpuid level : 13 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm +bogomips : 4190.43 +clflush size : 64 +cache_alignment : 64 +address sizes : 36 bits physical, 48 bits virtual +power management: +"; + + #[test] + fn core_duo_t6500() { + let cpuinfo = CpuInfo::from_str(CORE_DUO_T6500).unwrap(); + assert_eq!(cpuinfo.field("vendor_id"), "GenuineIntel"); + assert_eq!(cpuinfo.field("cpu family"), "6"); + assert_eq!(cpuinfo.field("model"), "23"); + assert_eq!( + cpuinfo.field("model name"), + "Intel(R) Core(TM)2 Duo CPU T6500 @ 2.10GHz" + ); + assert_eq!( + cpuinfo.field("flags"), + "fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm" + ); + assert!(cpuinfo.field("flags").has("fpu")); + assert!(cpuinfo.field("flags").has("dtherm")); + assert!(cpuinfo.field("flags").has("sse2")); + assert!(!cpuinfo.field("flags").has("avx")); + } + + const ARM_CORTEX_A53: &str = r"Processor : AArch64 Processor rev 3 (aarch64) + processor : 0 + processor : 1 + processor : 2 + processor : 3 + processor : 4 + processor : 5 + processor : 6 + processor : 7 + Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 + CPU implementer : 0x41 + CPU architecture: AArch64 + CPU variant : 0x0 + CPU part : 0xd03 + CPU revision : 3 + + Hardware : HiKey Development Board + "; + + #[test] + fn arm_cortex_a53() { + let cpuinfo = CpuInfo::from_str(ARM_CORTEX_A53).unwrap(); + assert_eq!( + cpuinfo.field("Processor"), + "AArch64 Processor rev 3 (aarch64)" + ); + assert_eq!( + cpuinfo.field("Features"), + "fp asimd evtstrm aes pmull sha1 sha2 crc32" + ); + assert!(cpuinfo.field("Features").has("pmull")); + assert!(!cpuinfo.field("Features").has("neon")); + assert!(cpuinfo.field("Features").has("asimd")); + } + + const ARM_CORTEX_A57: &str = r"Processor : Cortex A57 Processor rev 1 (aarch64) +processor : 0 +processor : 1 +processor : 2 +processor : 3 +Features : fp asimd aes pmull sha1 sha2 crc32 wp half thumb fastmult vfp edsp neon vfpv3 tlsi vfpv4 idiva idivt +CPU implementer : 0x41 +CPU architecture: 8 +CPU variant : 0x1 +CPU part : 0xd07 +CPU revision : 1"; + + #[test] + fn arm_cortex_a57() { + let cpuinfo = CpuInfo::from_str(ARM_CORTEX_A57).unwrap(); + assert_eq!( + cpuinfo.field("Processor"), + "Cortex A57 Processor rev 1 (aarch64)" + ); + assert_eq!( + cpuinfo.field("Features"), + "fp asimd aes pmull sha1 sha2 crc32 wp half thumb fastmult vfp edsp neon vfpv3 tlsi vfpv4 idiva idivt" + ); + assert!(cpuinfo.field("Features").has("pmull")); + assert!(cpuinfo.field("Features").has("neon")); + assert!(cpuinfo.field("Features").has("asimd")); + } + + const POWER8E_POWERKVM: &str = r"processor : 0 +cpu : POWER8E (raw), altivec supported +clock : 3425.000000MHz +revision : 2.1 (pvr 004b 0201) + +processor : 1 +cpu : POWER8E (raw), altivec supported +clock : 3425.000000MHz +revision : 2.1 (pvr 004b 0201) + +processor : 2 +cpu : POWER8E (raw), altivec supported +clock : 3425.000000MHz +revision : 2.1 (pvr 004b 0201) + +processor : 3 +cpu : POWER8E (raw), altivec supported +clock : 3425.000000MHz +revision : 2.1 (pvr 004b 0201) + +timebase : 512000000 +platform : pSeries +model : IBM pSeries (emulated by qemu) +machine : CHRP IBM pSeries (emulated by qemu)"; + + #[test] + fn power8_powerkvm() { + let cpuinfo = CpuInfo::from_str(POWER8E_POWERKVM).unwrap(); + assert_eq!(cpuinfo.field("cpu"), "POWER8E (raw), altivec supported"); + + assert!(cpuinfo.field("cpu").has("altivec")); + } + + const POWER5P: &str = r"processor : 0 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 1 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 2 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 3 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 4 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 5 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 6 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +processor : 7 +cpu : POWER5+ (gs) +clock : 1900.098000MHz +revision : 2.1 (pvr 003b 0201) + +timebase : 237331000 +platform : pSeries +machine : CHRP IBM,9133-55A"; + + #[test] + fn power5p() { + let cpuinfo = CpuInfo::from_str(POWER5P).unwrap(); + assert_eq!(cpuinfo.field("cpu"), "POWER5+ (gs)"); + + assert!(!cpuinfo.field("cpu").has("altivec")); + } +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/mips.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/mips.rs new file mode 100644 index 000000000..46a47fb7b --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/mips.rs @@ -0,0 +1,31 @@ +//! Run-time feature detection for MIPS on Linux. + +use super::auxvec; +use crate::detect::{bit, cache, Feature}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector, and if that fails, try +/// to read them from `/proc/cpuinfo`. +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + // The values are part of the platform-specific [asm/hwcap.h][hwcap] + // + // [hwcap]: https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h + if let Ok(auxv) = auxvec::auxv() { + enable_feature(&mut value, Feature::msa, bit::test(auxv.hwcap, 1)); + return value; + } + // TODO: fall back via `cpuinfo`. + value +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/mod.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/mod.rs new file mode 100644 index 000000000..e02d5e6dc --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/mod.rs @@ -0,0 +1,28 @@ +//! Run-time feature detection on Linux + +mod auxvec; + +#[cfg(feature = "std_detect_file_io")] +mod cpuinfo; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::check_for; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::check_for; + } else if #[cfg(any(target_arch = "mips", target_arch = "mips64"))] { + mod mips; + pub use self::mips::check_for; + } else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] { + mod powerpc; + pub use self::powerpc::check_for; + } else { + use crate::detect::Feature; + /// Performs run-time feature detection. + pub fn check_for(_x: Feature) -> bool { + false + } + } +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/powerpc.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/powerpc.rs new file mode 100644 index 000000000..dc19bc8ed --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/linux/powerpc.rs @@ -0,0 +1,41 @@ +//! Run-time feature detection for PowerPC on Linux. + +use super::{auxvec, cpuinfo}; +use crate::detect::{cache, Feature}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Try to read the features from the auxiliary vector, and if that fails, try +/// to read them from /proc/cpuinfo. +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + // The values are part of the platform-specific [asm/cputable.h][cputable] + // + // [cputable]: https://github.com/torvalds/linux/blob/master/arch/powerpc/include/uapi/asm/cputable.h + if let Ok(auxv) = auxvec::auxv() { + // note: the PowerPC values are the mask to do the test (instead of the + // index of the bit to test like in ARM and Aarch64) + enable_feature(&mut value, Feature::altivec, auxv.hwcap & 0x10000000 != 0); + enable_feature(&mut value, Feature::vsx, auxv.hwcap & 0x00000080 != 0); + enable_feature(&mut value, Feature::power8, auxv.hwcap2 & 0x80000000 != 0); + return value; + } + + // PowerPC's /proc/cpuinfo lacks a proper Feature field, + // but `altivec` support is indicated in the `cpu` field. + if let Ok(c) = cpuinfo::CpuInfo::new() { + enable_feature(&mut value, Feature::altivec, c.field("cpu").has("altivec")); + return value; + } + value +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/other.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/other.rs new file mode 100644 index 000000000..23e399ea7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/other.rs @@ -0,0 +1,9 @@ +//! Other operating systems + +use crate::detect::Feature; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(_x: Feature) -> bool { + false +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/x86.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/x86.rs new file mode 100644 index 000000000..2e228aa37 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/x86.rs @@ -0,0 +1,367 @@ +//! x86 run-time feature detection is OS independent. + +#[cfg(target_arch = "x86")] +use crate::arch::x86::*; +#[cfg(target_arch = "x86_64")] +use crate::arch::x86_64::*; + +use crate::mem; + +use crate::detect::{bit, cache, Feature}; + +/// Performs run-time feature detection. +#[inline] +pub fn check_for(x: Feature) -> bool { + cache::test(x as u32, detect_features) +} + +/// Run-time feature detection on x86 works by using the CPUID instruction. +/// +/// The [CPUID Wikipedia page][wiki_cpuid] contains +/// all the information about which flags to set to query which values, and in +/// which registers these are reported. +/// +/// The definitive references are: +/// - [Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2: +/// Instruction Set Reference, A-Z][intel64_ref]. +/// - [AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and +/// System Instructions][amd64_ref]. +/// +/// [wiki_cpuid]: https://en.wikipedia.org/wiki/CPUID +/// [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +/// [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +#[allow(clippy::similar_names)] +fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + + // If the x86 CPU does not support the CPUID instruction then it is too + // old to support any of the currently-detectable features. + if !has_cpuid() { + return value; + } + + // Calling `__cpuid`/`__cpuid_count` from here on is safe because the CPU + // has `cpuid` support. + + // 0. EAX = 0: Basic Information: + // - EAX returns the "Highest Function Parameter", that is, the maximum + // leaf value for subsequent calls of `cpuinfo` in range [0, + // 0x8000_0000]. - The vendor ID is stored in 12 u8 ascii chars, + // returned in EBX, EDX, and ECX (in that order): + let (max_basic_leaf, vendor_id) = unsafe { + let CpuidResult { + eax: max_basic_leaf, + ebx, + ecx, + edx, + } = __cpuid(0); + let vendor_id: [[u8; 4]; 3] = [ + mem::transmute(ebx), + mem::transmute(edx), + mem::transmute(ecx), + ]; + let vendor_id: [u8; 12] = mem::transmute(vendor_id); + (max_basic_leaf, vendor_id) + }; + + if max_basic_leaf < 1 { + // Earlier Intel 486, CPUID not implemented + return value; + } + + // EAX = 1, ECX = 0: Queries "Processor Info and Feature Bits"; + // Contains information about most x86 features. + let CpuidResult { + ecx: proc_info_ecx, + edx: proc_info_edx, + .. + } = unsafe { __cpuid(0x0000_0001_u32) }; + + // EAX = 7, ECX = 0: Queries "Extended Features"; + // Contains information about bmi,bmi2, and avx2 support. + let (extended_features_ebx, extended_features_ecx) = if max_basic_leaf >= 7 { + let CpuidResult { ebx, ecx, .. } = unsafe { __cpuid(0x0000_0007_u32) }; + (ebx, ecx) + } else { + (0, 0) // CPUID does not support "Extended Features" + }; + + // EAX = 0x8000_0000, ECX = 0: Get Highest Extended Function Supported + // - EAX returns the max leaf value for extended information, that is, + // `cpuid` calls in range [0x8000_0000; u32::MAX]: + let CpuidResult { + eax: extended_max_basic_leaf, + .. + } = unsafe { __cpuid(0x8000_0000_u32) }; + + // EAX = 0x8000_0001, ECX=0: Queries "Extended Processor Info and Feature + // Bits" + let extended_proc_info_ecx = if extended_max_basic_leaf >= 1 { + let CpuidResult { ecx, .. } = unsafe { __cpuid(0x8000_0001_u32) }; + ecx + } else { + 0 + }; + + { + // borrows value till the end of this scope: + let mut enable = |r, rb, f| { + if bit::test(r as usize, rb) { + value.set(f as u32); + } + }; + + enable(proc_info_ecx, 0, Feature::sse3); + enable(proc_info_ecx, 1, Feature::pclmulqdq); + enable(proc_info_ecx, 9, Feature::ssse3); + enable(proc_info_ecx, 13, Feature::cmpxchg16b); + enable(proc_info_ecx, 19, Feature::sse4_1); + enable(proc_info_ecx, 20, Feature::sse4_2); + enable(proc_info_ecx, 23, Feature::popcnt); + enable(proc_info_ecx, 25, Feature::aes); + enable(proc_info_ecx, 29, Feature::f16c); + enable(proc_info_ecx, 30, Feature::rdrand); + enable(extended_features_ebx, 18, Feature::rdseed); + enable(extended_features_ebx, 19, Feature::adx); + enable(extended_features_ebx, 11, Feature::rtm); + enable(proc_info_edx, 4, Feature::tsc); + enable(proc_info_edx, 23, Feature::mmx); + enable(proc_info_edx, 24, Feature::fxsr); + enable(proc_info_edx, 25, Feature::sse); + enable(proc_info_edx, 26, Feature::sse2); + enable(extended_features_ebx, 29, Feature::sha); + + enable(extended_features_ebx, 3, Feature::bmi); + enable(extended_features_ebx, 8, Feature::bmi2); + + // `XSAVE` and `AVX` support: + let cpu_xsave = bit::test(proc_info_ecx as usize, 26); + if cpu_xsave { + // 0. Here the CPU supports `XSAVE`. + + // 1. Detect `OSXSAVE`, that is, whether the OS is AVX enabled and + // supports saving the state of the AVX/AVX2 vector registers on + // context-switches, see: + // + // - [intel: is avx enabled?][is_avx_enabled], + // - [mozilla: sse.cpp][mozilla_sse_cpp]. + // + // [is_avx_enabled]: https://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled + // [mozilla_sse_cpp]: https://hg.mozilla.org/mozilla-central/file/64bab5cbb9b6/mozglue/build/SSE.cpp#l190 + let cpu_osxsave = bit::test(proc_info_ecx as usize, 27); + + if cpu_osxsave { + // 2. The OS must have signaled the CPU that it supports saving and + // restoring the: + // + // * SSE -> `XCR0.SSE[1]` + // * AVX -> `XCR0.AVX[2]` + // * AVX-512 -> `XCR0.AVX-512[7:5]`. + // + // by setting the corresponding bits of `XCR0` to `1`. + // + // This is safe because the CPU supports `xsave` + // and the OS has set `osxsave`. + let xcr0 = unsafe { _xgetbv(0) }; + // Test `XCR0.SSE[1]` and `XCR0.AVX[2]` with the mask `0b110 == 6`: + let os_avx_support = xcr0 & 6 == 6; + // Test `XCR0.AVX-512[7:5]` with the mask `0b1110_0000 == 224`: + let os_avx512_support = xcr0 & 224 == 224; + + // Only if the OS and the CPU support saving/restoring the AVX + // registers we enable `xsave` support: + if os_avx_support { + // See "13.3 ENABLING THE XSAVE FEATURE SET AND XSAVE-ENABLED + // FEATURES" in the "Intel® 64 and IA-32 Architectures Software + // Developer’s Manual, Volume 1: Basic Architecture": + // + // "Software enables the XSAVE feature set by setting + // CR4.OSXSAVE[bit 18] to 1 (e.g., with the MOV to CR4 + // instruction). If this bit is 0, execution of any of XGETBV, + // XRSTOR, XRSTORS, XSAVE, XSAVEC, XSAVEOPT, XSAVES, and XSETBV + // causes an invalid-opcode exception (#UD)" + // + enable(proc_info_ecx, 26, Feature::xsave); + + // For `xsaveopt`, `xsavec`, and `xsaves` we need to query: + // Processor Extended State Enumeration Sub-leaf (EAX = 0DH, + // ECX = 1): + if max_basic_leaf >= 0xd { + let CpuidResult { + eax: proc_extended_state1_eax, + .. + } = unsafe { __cpuid_count(0xd_u32, 1) }; + enable(proc_extended_state1_eax, 0, Feature::xsaveopt); + enable(proc_extended_state1_eax, 1, Feature::xsavec); + enable(proc_extended_state1_eax, 3, Feature::xsaves); + } + + // FMA (uses 256-bit wide registers): + enable(proc_info_ecx, 12, Feature::fma); + + // And AVX/AVX2: + enable(proc_info_ecx, 28, Feature::avx); + enable(extended_features_ebx, 5, Feature::avx2); + + // For AVX-512 the OS also needs to support saving/restoring + // the extended state, only then we enable AVX-512 support: + if os_avx512_support { + enable(extended_features_ebx, 16, Feature::avx512f); + enable(extended_features_ebx, 17, Feature::avx512dq); + enable(extended_features_ebx, 21, Feature::avx512_ifma); + enable(extended_features_ebx, 26, Feature::avx512pf); + enable(extended_features_ebx, 27, Feature::avx512er); + enable(extended_features_ebx, 28, Feature::avx512cd); + enable(extended_features_ebx, 30, Feature::avx512bw); + enable(extended_features_ebx, 31, Feature::avx512vl); + enable(extended_features_ecx, 1, Feature::avx512_vbmi); + enable(extended_features_ecx, 14, Feature::avx512_vpopcntdq); + } + } + } + } + + // This detects ABM on AMD CPUs and LZCNT on Intel CPUs. + // On intel CPUs with popcnt, lzcnt implements the + // "missing part" of ABM, so we map both to the same + // internal feature. + // + // The `is_x86_feature_detected!("lzcnt")` macro then + // internally maps to Feature::abm. + enable(extended_proc_info_ecx, 5, Feature::abm); + // As Hygon Dhyana originates from AMD technology and shares most of the architecture with + // AMD's family 17h, but with different CPU Vendor ID("HygonGenuine")/Family series + // number(Family 18h). + // + // For CPUID feature bits, Hygon Dhyana(family 18h) share the same definition with AMD + // family 17h. + // + // Related AMD CPUID specification is https://www.amd.com/system/files/TechDocs/25481.pdf. + // Related Hygon kernel patch can be found on + // http://lkml.kernel.org/r/5ce86123a7b9dad925ac583d88d2f921040e859b.1538583282.git.puwen@hygon.cn + if vendor_id == *b"AuthenticAMD" || vendor_id == *b"HygonGenuine" { + // These features are available on AMD arch CPUs: + enable(extended_proc_info_ecx, 6, Feature::sse4a); + enable(extended_proc_info_ecx, 21, Feature::tbm); + } + } + + value +} + +#[cfg(test)] +mod tests { + extern crate cupid; + + #[test] + fn dump() { + println!("aes: {:?}", is_x86_feature_detected!("aes")); + println!("pclmulqdq: {:?}", is_x86_feature_detected!("pclmulqdq")); + println!("rdrand: {:?}", is_x86_feature_detected!("rdrand")); + println!("rdseed: {:?}", is_x86_feature_detected!("rdseed")); + println!("tsc: {:?}", is_x86_feature_detected!("tsc")); + println!("sse: {:?}", is_x86_feature_detected!("sse")); + println!("sse2: {:?}", is_x86_feature_detected!("sse2")); + println!("sse3: {:?}", is_x86_feature_detected!("sse3")); + println!("ssse3: {:?}", is_x86_feature_detected!("ssse3")); + println!("sse4.1: {:?}", is_x86_feature_detected!("sse4.1")); + println!("sse4.2: {:?}", is_x86_feature_detected!("sse4.2")); + println!("sse4a: {:?}", is_x86_feature_detected!("sse4a")); + println!("sha: {:?}", is_x86_feature_detected!("sha")); + println!("avx: {:?}", is_x86_feature_detected!("avx")); + println!("avx2: {:?}", is_x86_feature_detected!("avx2")); + println!("avx512f {:?}", is_x86_feature_detected!("avx512f")); + println!("avx512cd {:?}", is_x86_feature_detected!("avx512cd")); + println!("avx512er {:?}", is_x86_feature_detected!("avx512er")); + println!("avx512pf {:?}", is_x86_feature_detected!("avx512pf")); + println!("avx512bw {:?}", is_x86_feature_detected!("avx512bw")); + println!("avx512dq {:?}", is_x86_feature_detected!("avx512dq")); + println!("avx512vl {:?}", is_x86_feature_detected!("avx512vl")); + println!("avx512_ifma {:?}", is_x86_feature_detected!("avx512ifma")); + println!("avx512_vbmi {:?}", is_x86_feature_detected!("avx512vbmi")); + println!( + "avx512_vpopcntdq {:?}", + is_x86_feature_detected!("avx512vpopcntdq") + ); + println!("fma: {:?}", is_x86_feature_detected!("fma")); + println!("abm: {:?}", is_x86_feature_detected!("abm")); + println!("bmi: {:?}", is_x86_feature_detected!("bmi1")); + println!("bmi2: {:?}", is_x86_feature_detected!("bmi2")); + println!("tbm: {:?}", is_x86_feature_detected!("tbm")); + println!("popcnt: {:?}", is_x86_feature_detected!("popcnt")); + println!("lzcnt: {:?}", is_x86_feature_detected!("lzcnt")); + println!("fxsr: {:?}", is_x86_feature_detected!("fxsr")); + println!("xsave: {:?}", is_x86_feature_detected!("xsave")); + println!("xsaveopt: {:?}", is_x86_feature_detected!("xsaveopt")); + println!("xsaves: {:?}", is_x86_feature_detected!("xsaves")); + println!("xsavec: {:?}", is_x86_feature_detected!("xsavec")); + println!("cmpxchg16b: {:?}", is_x86_feature_detected!("cmpxchg16b")); + println!("adx: {:?}", is_x86_feature_detected!("adx")); + println!("rtm: {:?}", is_x86_feature_detected!("rtm")); + } + + #[test] + fn compare_with_cupid() { + let information = cupid::master().unwrap(); + assert_eq!(is_x86_feature_detected!("aes"), information.aesni()); + assert_eq!( + is_x86_feature_detected!("pclmulqdq"), + information.pclmulqdq() + ); + assert_eq!(is_x86_feature_detected!("rdrand"), information.rdrand()); + assert_eq!(is_x86_feature_detected!("rdseed"), information.rdseed()); + assert_eq!(is_x86_feature_detected!("tsc"), information.tsc()); + assert_eq!(is_x86_feature_detected!("sse"), information.sse()); + assert_eq!(is_x86_feature_detected!("sse2"), information.sse2()); + assert_eq!(is_x86_feature_detected!("sse3"), information.sse3()); + assert_eq!(is_x86_feature_detected!("ssse3"), information.ssse3()); + assert_eq!(is_x86_feature_detected!("sse4.1"), information.sse4_1()); + assert_eq!(is_x86_feature_detected!("sse4.2"), information.sse4_2()); + assert_eq!(is_x86_feature_detected!("sse4a"), information.sse4a()); + assert_eq!(is_x86_feature_detected!("sha"), information.sha()); + assert_eq!(is_x86_feature_detected!("avx"), information.avx()); + assert_eq!(is_x86_feature_detected!("avx2"), information.avx2()); + assert_eq!(is_x86_feature_detected!("avx512f"), information.avx512f()); + assert_eq!(is_x86_feature_detected!("avx512cd"), information.avx512cd()); + assert_eq!(is_x86_feature_detected!("avx512er"), information.avx512er()); + assert_eq!(is_x86_feature_detected!("avx512pf"), information.avx512pf()); + assert_eq!(is_x86_feature_detected!("avx512bw"), information.avx512bw()); + assert_eq!(is_x86_feature_detected!("avx512dq"), information.avx512dq()); + assert_eq!(is_x86_feature_detected!("avx512vl"), information.avx512vl()); + assert_eq!( + is_x86_feature_detected!("avx512ifma"), + information.avx512_ifma() + ); + assert_eq!( + is_x86_feature_detected!("avx512vbmi"), + information.avx512_vbmi() + ); + assert_eq!( + is_x86_feature_detected!("avx512vpopcntdq"), + information.avx512_vpopcntdq() + ); + assert_eq!(is_x86_feature_detected!("fma"), information.fma()); + assert_eq!(is_x86_feature_detected!("bmi1"), information.bmi1()); + assert_eq!(is_x86_feature_detected!("bmi2"), information.bmi2()); + assert_eq!(is_x86_feature_detected!("popcnt"), information.popcnt()); + assert_eq!(is_x86_feature_detected!("abm"), information.lzcnt()); + assert_eq!(is_x86_feature_detected!("tbm"), information.tbm()); + assert_eq!(is_x86_feature_detected!("lzcnt"), information.lzcnt()); + assert_eq!(is_x86_feature_detected!("xsave"), information.xsave()); + assert_eq!(is_x86_feature_detected!("xsaveopt"), information.xsaveopt()); + assert_eq!( + is_x86_feature_detected!("xsavec"), + information.xsavec_and_xrstor() + ); + assert_eq!( + is_x86_feature_detected!("xsaves"), + information.xsaves_xrstors_and_ia32_xss() + ); + assert_eq!( + is_x86_feature_detected!("cmpxchg16b"), + information.cmpxchg16b(), + ); + assert_eq!(is_x86_feature_detected!("adx"), information.adx(),); + assert_eq!(is_x86_feature_detected!("rtm"), information.rtm(),); + } +} diff --git a/src/tools/rustfmt/tests/target/cfg_if/lib.rs b/src/tools/rustfmt/tests/target/cfg_if/lib.rs new file mode 100644 index 000000000..8b3bb304f --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/lib.rs @@ -0,0 +1,49 @@ +//! Run-time feature detection for the Rust standard library. +//! +//! To detect whether a feature is enabled in the system running the binary +//! use one of the appropriate macro for the target: +//! +//! * `x86` and `x86_64`: [`is_x86_feature_detected`] +//! * `arm`: [`is_arm_feature_detected`] +//! * `aarch64`: [`is_aarch64_feature_detected`] +//! * `mips`: [`is_mips_feature_detected`] +//! * `mips64`: [`is_mips64_feature_detected`] +//! * `powerpc`: [`is_powerpc_feature_detected`] +//! * `powerpc64`: [`is_powerpc64_feature_detected`] + +#![unstable(feature = "stdsimd", issue = "27731")] +#![feature(const_fn, staged_api, stdsimd, doc_cfg, allow_internal_unstable)] +#![allow(clippy::shadow_reuse)] +#![deny(clippy::missing_inline_in_public_items)] +#![cfg_attr(target_os = "linux", feature(linkage))] +#![cfg_attr(all(target_os = "freebsd", target_arch = "aarch64"), feature(asm))] +#![cfg_attr(stdsimd_strict, deny(warnings))] +#![cfg_attr(test, allow(unused_imports))] +#![no_std] + +#[macro_use] +extern crate cfg_if; + +cfg_if! { + if #[cfg(feature = "std_detect_file_io")] { + #[cfg_attr(test, macro_use(println))] + extern crate std; + + #[allow(unused_imports)] + use std::{arch, fs, io, mem, sync}; + } else { + #[cfg(test)] + #[macro_use(println)] + extern crate std; + + #[allow(unused_imports)] + use core::{arch, mem, sync}; + } +} + +#[cfg(feature = "std_detect_dlsym_getauxval")] +extern crate libc; + +#[doc(hidden)] +#[unstable(feature = "stdsimd", issue = "27731")] +pub mod detect; diff --git a/src/tools/rustfmt/tests/target/cfg_if/mod.rs b/src/tools/rustfmt/tests/target/cfg_if/mod.rs new file mode 100644 index 000000000..b630e7ff3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_if/mod.rs @@ -0,0 +1,5 @@ +//! `std_detect` + +#[doc(hidden)] // unstable implementation detail +#[unstable(feature = "stdsimd", issue = "27731")] +pub mod detect; diff --git a/src/tools/rustfmt/tests/target/cfg_mod/bar.rs b/src/tools/rustfmt/tests/target/cfg_mod/bar.rs new file mode 100644 index 000000000..20dc5b4a0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_mod/bar.rs @@ -0,0 +1,3 @@ +fn bar() -> &str { + "bar" +} diff --git a/src/tools/rustfmt/tests/target/cfg_mod/dir/dir1/dir2/wasm32.rs b/src/tools/rustfmt/tests/target/cfg_mod/dir/dir1/dir2/wasm32.rs new file mode 100644 index 000000000..ac437e422 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_mod/dir/dir1/dir2/wasm32.rs @@ -0,0 +1,3 @@ +fn wasm32() -> &str { + "wasm32" +} diff --git a/src/tools/rustfmt/tests/target/cfg_mod/dir/dir1/dir3/wasm32.rs b/src/tools/rustfmt/tests/target/cfg_mod/dir/dir1/dir3/wasm32.rs new file mode 100644 index 000000000..ac437e422 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_mod/dir/dir1/dir3/wasm32.rs @@ -0,0 +1,3 @@ +fn wasm32() -> &str { + "wasm32" +} diff --git a/src/tools/rustfmt/tests/target/cfg_mod/foo.rs b/src/tools/rustfmt/tests/target/cfg_mod/foo.rs new file mode 100644 index 000000000..053c8e6f3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_mod/foo.rs @@ -0,0 +1,3 @@ +fn foo() -> &str { + "foo" +} diff --git a/src/tools/rustfmt/tests/target/cfg_mod/mod.rs b/src/tools/rustfmt/tests/target/cfg_mod/mod.rs new file mode 100644 index 000000000..45ba86f11 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_mod/mod.rs @@ -0,0 +1,10 @@ +#[cfg_attr(feature = "foo", path = "foo.rs")] +#[cfg_attr(not(feture = "foo"), path = "bar.rs")] +mod sub_mod; + +#[cfg_attr(target_arch = "wasm32", path = "dir/dir1/dir2/wasm32.rs")] +#[cfg_attr(not(target_arch = "wasm32"), path = "dir/dir1/dir3/wasm32.rs")] +mod wasm32; + +#[some_attr(path = "somewhere.rs")] +mod other; diff --git a/src/tools/rustfmt/tests/target/cfg_mod/other.rs b/src/tools/rustfmt/tests/target/cfg_mod/other.rs new file mode 100644 index 000000000..5929b8dcf --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_mod/other.rs @@ -0,0 +1,3 @@ +fn other() -> &str { + "other" +} diff --git a/src/tools/rustfmt/tests/target/cfg_mod/wasm32.rs b/src/tools/rustfmt/tests/target/cfg_mod/wasm32.rs new file mode 100644 index 000000000..ac437e422 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_mod/wasm32.rs @@ -0,0 +1,3 @@ +fn wasm32() -> &str { + "wasm32" +} diff --git a/src/tools/rustfmt/tests/target/chains-visual.rs b/src/tools/rustfmt/tests/target/chains-visual.rs new file mode 100644 index 000000000..76ef99a4b --- /dev/null +++ b/src/tools/rustfmt/tests/target/chains-visual.rs @@ -0,0 +1,158 @@ +// rustfmt-indent_style: Visual +// Test chain formatting. + +fn main() { + // Don't put chains on a single line if it wasn't so in source. + let a = b.c.d.1.foo(|x| x + 1); + + bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc + .ddddddddddddddddddddddddddd(); + + bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc + .ddddddddddddddddddddddddddd + .eeeeeeee(); + + // Test case where first chain element isn't a path, but is shorter than + // the size of a tab. + x().y(|| match cond() { + true => (), + false => (), + }); + + loong_func().quux(move || if true { 1 } else { 2 }); + + some_fuuuuuuuuunction().method_call_a(aaaaa, bbbbb, |c| { + let x = c; + x + }); + + some_fuuuuuuuuunction().method_call_a(aaaaa, bbbbb, |c| { + let x = c; + x + }) + .method_call_b(aaaaa, bbbbb, |c| { + let x = c; + x + }); + + fffffffffffffffffffffffffffffffffff(a, { + SCRIPT_TASK_ROOT.with(|root| { + *root.borrow_mut() = Some(&script_task); + }); + }); + + let suuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuum = + xxxxxxx.map(|x| x + 5) + .map(|x| x / 2) + .fold(0, |acc, x| acc + x); + + aaaaaaaaaaaaaaaa.map(|x| { + x += 1; + x + }) + .filter(some_mod::some_filter) +} + +fn floaters() { + let z = Foo { field1: val1, + field2: val2 }; + + let x = Foo { field1: val1, + field2: val2 }.method_call() + .method_call(); + + let y = if cond { val1 } else { val2 }.method_call(); + + { + match x { + PushParam => { + // params are 1-indexed + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }].clone()); + } + } + } + + if cond { + some(); + } else { + none(); + }.bar() + .baz(); + + Foo { x: val }.baz(|| { + force(); + multiline(); + }) + .quux(); + + Foo { y: i_am_multi_line, + z: ok }.baz(|| { + force(); + multiline(); + }) + .quux(); + + a + match x { + true => "yay!", + false => "boo!", + }.bar() +} + +fn is_replaced_content() -> bool { + constellat.send(ConstellationMsg::ViewportConstrained(self.id, constraints)) + .unwrap(); +} + +fn issue587() { + a.b::<()>(c); + + std::mem::transmute(dl.symbol::<()>("init").unwrap()) +} + +fn issue_1389() { + let names = String::from_utf8(names)?.split('|') + .map(str::to_owned) + .collect(); +} + +fn issue1217() -> Result<Mnemonic, Error> { + let random_chars: String = OsRng::new()?.gen_ascii_chars() + .take(self.bit_length) + .collect(); + + Ok(Mnemonic::new(&random_chars)) +} + +fn issue1236(options: Vec<String>) -> Result<Option<String>> { + let process = Command::new("dmenu").stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .chain_err(|| "failed to spawn dmenu")?; +} + +fn issue1434() { + for _ in 0..100 { + let prototype_id = + PrototypeIdData::from_reader::<_, B>(&mut self.file_cursor).chain_err(|| { + format!("could not read prototype ID at offset {:#010x}", + current_offset) + })?; + } +} + +fn issue2264() { + { + something.function() + .map(|| { + if let a_very_very_very_very_very_very_very_very_long_variable = + compute_this_variable() + { + println!("Hello"); + } + }) + .collect(); + } +} diff --git a/src/tools/rustfmt/tests/target/chains.rs b/src/tools/rustfmt/tests/target/chains.rs new file mode 100644 index 000000000..292da2981 --- /dev/null +++ b/src/tools/rustfmt/tests/target/chains.rs @@ -0,0 +1,306 @@ +// rustfmt-use_small_heuristics: Off +// Test chain formatting. + +fn main() { + let a = b.c.d.1.foo(|x| x + 1); + + bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddd(); + + bbbbbbbbbbbbbbbbbbb + .ccccccccccccccccccccccccccccccccccccc + .ddddddddddddddddddddddddddd + .eeeeeeee(); + + let f = fooooooooooooooooooooooooooooooooooooooooooooooooooo + .baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar; + + // Test case where first chain element isn't a path, but is shorter than + // the size of a tab. + x().y(|| match cond() { + true => (), + false => (), + }); + + loong_func().quux(move || { + if true { + 1 + } else { + 2 + } + }); + + some_fuuuuuuuuunction().method_call_a(aaaaa, bbbbb, |c| { + let x = c; + x + }); + + some_fuuuuuuuuunction() + .method_call_a(aaaaa, bbbbb, |c| { + let x = c; + x + }) + .method_call_b(aaaaa, bbbbb, |c| { + let x = c; + x + }); + + fffffffffffffffffffffffffffffffffff(a, { + SCRIPT_TASK_ROOT.with(|root| { + *root.borrow_mut() = Some(&script_task); + }); + }); + + let suuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuum = + xxxxxxx.map(|x| x + 5).map(|x| x / 2).fold(0, |acc, x| acc + x); + + body.fold(Body::new(), |mut body, chunk| { + body.extend(chunk); + Ok(body) + }) + .and_then(move |body| { + let req = Request::from_parts(parts, body); + f(req).map_err(|_| io::Error::new(io::ErrorKind::Other, "")) + }); + + aaaaaaaaaaaaaaaa + .map(|x| { + x += 1; + x + }) + .filter(some_mod::some_filter) +} + +fn floaters() { + let z = Foo { + field1: val1, + field2: val2, + }; + + let x = Foo { + field1: val1, + field2: val2, + } + .method_call() + .method_call(); + + let y = if cond { + val1 + } else { + val2 + } + .method_call(); + + { + match x { + PushParam => { + // params are 1-indexed + stack.push( + mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone(), + ); + } + } + } + + if cond { + some(); + } else { + none(); + } + .bar() + .baz(); + + Foo { + x: val, + } + .baz(|| { + force(); + multiline(); + }) + .quux(); + + Foo { + y: i_am_multi_line, + z: ok, + } + .baz(|| { + force(); + multiline(); + }) + .quux(); + + a + match x { + true => "yay!", + false => "boo!", + } + .bar() +} + +fn is_replaced_content() -> bool { + constellat.send(ConstellationMsg::ViewportConstrained(self.id, constraints)).unwrap(); +} + +fn issue587() { + a.b::<()>(c); + + std::mem::transmute(dl.symbol::<()>("init").unwrap()) +} + +fn try_shorthand() { + let x = expr?; + let y = expr.kaas()?.test(); + let loooooooooooooooooooooooooooooooooooooooooong = + does_this?.look?.good?.should_we_break?.after_the_first_question_mark?; + let yyyy = expr?.another?.another?.another?.another?.another?.another?.another?.another?.test(); + let zzzz = expr?.another?.another?.another?.another?; + let aaa = x??????????????????????????????????????????????????????????????????????????; + + let y = a + .very + .loooooooooooooooooooooooooooooooooooooong() + .chain() + .inside() + .weeeeeeeeeeeeeee()? + .test() + .0 + .x; + + parameterized(f, substs, def_id, Ns::Value, &[], |tcx| tcx.lookup_item_type(def_id).generics)?; + fooooooooooooooooooooooooooo()? + .bar()? + .baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz()?; +} + +fn issue_1004() { + match *self { + ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i), + ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i), + ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i), + }?; + + ty::tls::with(|tcx| { + let tap = ty::Binder(TraitAndProjections(principal, projections)); + in_binder(f, tcx, &ty::Binder(""), Some(tap)) + })?; +} + +fn issue1392() { + test_method( + r#" + if foo { + a(); + } + else { + b(); + } + "# + .trim(), + ); +} + +// #2067 +impl Settings { + fn save(&self) -> Result<()> { + let mut file = File::create(&settings_path) + .chain_err(|| ErrorKind::WriteError(settings_path.clone()))?; + } +} + +fn issue2126() { + { + { + { + { + { + let x = self + .span_from(sub_span.expect("No span found for struct arant variant")); + self.sspanpan_from_span( + sub_span.expect("No span found for struct variant"), + ); + let x = self.spanpan_from_span( + sub_span.expect("No span found for struct variant"), + )?; + } + } + } + } + } +} + +// #2200 +impl Foo { + pub fn from_ast(diagnostic: &::errors::Handler, attrs: &[ast::Attribute]) -> Attributes { + let other_attrs = attrs + .iter() + .filter_map(|attr| { + attr.with_desugared_doc(|attr| { + if attr.check_name("doc") { + if let Some(mi) = attr.meta() { + if let Some(value) = mi.value_str() { + doc_strings.push(DocFragment::Include( + line, attr.span, filename, contents, + )); + } + } + } + }) + }) + .collect(); + } +} + +// #2415 +// Avoid orphan in chain +fn issue2415() { + let base_url = (|| { + // stuff + + Ok((|| { + // stuff + Some(value.to_string()) + })() + .ok_or("")?) + })() + .unwrap_or_else(|_: Box<::std::error::Error>| String::from("")); +} + +impl issue_2786 { + fn thing(&self) { + foo(|a| { + println!("a"); + println!("b"); + }) + .bar(|c| { + println!("a"); + println!("b"); + }) + .baz(|c| { + println!("a"); + println!("b"); + }) + } +} + +fn issue_2773() { + let bar = Some(0); + bar.or_else(|| { + // do stuff + None + }) + .or_else(|| { + // do other stuff + None + }) + .and_then(|val| { + // do this stuff + None + }); +} + +fn issue_3034() { + disallowed_headers.iter().any(|header| *header == name) + || disallowed_header_prefixes.iter().any(|prefix| name.starts_with(prefix)) +} diff --git a/src/tools/rustfmt/tests/target/chains_with_comment.rs b/src/tools/rustfmt/tests/target/chains_with_comment.rs new file mode 100644 index 000000000..522d70713 --- /dev/null +++ b/src/tools/rustfmt/tests/target/chains_with_comment.rs @@ -0,0 +1,137 @@ +// Chains with comment. + +fn main() { + let x = y // comment + .z; + + foo // foo + // comment after parent + .x + .y + // comment 1 + .bar() // comment after bar() + // comment 2 + .foobar + // comment after + // comment 3 + .baz(x, y, z); + + self.rev_dep_graph + .iter() + // Remove nodes that are not dirty + .filter(|&(unit, _)| dirties.contains(&unit)) + // Retain only dirty dependencies of the ones that are dirty + .map(|(k, deps)| { + ( + k.clone(), + deps.iter() + .cloned() + .filter(|d| dirties.contains(&d)) + .collect(), + ) + }); + + let y = expr /* comment */ + .kaas()? + // comment + .test(); + let loooooooooooooooooooooooooooooooooooooooooong = does_this? + .look? + .good? + .should_we_break? + .after_the_first_question_mark?; + let zzzz = expr? // comment after parent + // comment 0 + .another??? // comment 1 + .another???? // comment 2 + .another? // comment 3 + .another?; + + let y = a + .very + .loooooooooooooooooooooooooooooooooooooong() /* comment */ + .chain() + .inside() /* comment */ + .weeeeeeeeeeeeeee()? + .test() + .0 + .x; + + parameterized(f, substs, def_id, Ns::Value, &[], |tcx| { + tcx.lookup_item_type(def_id).generics + })?; + fooooooooooooooooooooooooooo()? + .bar()? + .baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz()?; + + // #2559 + App::new("cargo-cache") + .version(crate_version!()) + .bin_name("cargo") + .about("Manage cargo cache") + .author("matthiaskrgr") + .subcommand( + SubCommand::with_name("cache") + .version(crate_version!()) + .bin_name("cargo-cache") + .about("Manage cargo cache") + .author("matthiaskrgr") + .arg(&list_dirs) + .arg(&remove_dir) + .arg(&gc_repos) + .arg(&info) + .arg(&keep_duplicate_crates) + .arg(&dry_run) + .arg(&auto_clean) + .arg(&auto_clean_expensive), + ) // subcommand + .arg(&list_dirs); +} + +// #2177 +impl Foo { + fn dirty_rev_dep_graph( + &self, + dirties: &HashSet<UnitKey>, + ) -> HashMap<UnitKey, HashSet<UnitKey>> { + let dirties = self.transitive_dirty_units(dirties); + trace!("transitive_dirty_units: {:?}", dirties); + + self.rev_dep_graph + .iter() + // Remove nodes that are not dirty + .filter(|&(unit, _)| dirties.contains(&unit)) + // Retain only dirty dependencies of the ones that are dirty + .map(|(k, deps)| { + ( + k.clone(), + deps.iter() + .cloned() + .filter(|d| dirties.contains(&d)) + .collect(), + ) + }) + } +} + +// #2907 +fn foo() { + let x = foo + .bar??? // comment + .baz; + let x = foo + .bar??? + // comment + .baz; + let x = foo + .bar??? // comment + // comment + .baz; + let x = foo + .bar??????????????? // comment + // comment + // comment + // comment + // comment + .baz; +} diff --git a/src/tools/rustfmt/tests/target/closure-block-inside-macro.rs b/src/tools/rustfmt/tests/target/closure-block-inside-macro.rs new file mode 100644 index 000000000..b3ddfb512 --- /dev/null +++ b/src/tools/rustfmt/tests/target/closure-block-inside-macro.rs @@ -0,0 +1,9 @@ +// #1547 +fuzz_target!(|data: &[u8]| if let Some(first) = data.first() { + let index = *first as usize; + if index >= ENCODINGS.len() { + return; + } + let encoding = ENCODINGS[index]; + dispatch_test(encoding, &data[1..]); +}); diff --git a/src/tools/rustfmt/tests/target/closure.rs b/src/tools/rustfmt/tests/target/closure.rs new file mode 100644 index 000000000..e8b4ff7a9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/closure.rs @@ -0,0 +1,256 @@ +// rustfmt-normalize_comments: true +// Closures + +fn main() { + let square = (|i: i32| i * i); + + let commented = |// first + a, // argument + // second + b: WithType, // argument + // ignored + _| { + ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + ) + }; + + let block_body = move |xxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + ref yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy| { + xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy + }; + + let loooooooooooooong_name = |field| { + // format comments. + if field.node.attrs.len() > 0 { + field.node.attrs[0].span.lo() + } else { + field.span.lo() + } + }; + + let unblock_me = |trivial| closure(); + + let empty = |arg| {}; + + let simple = |arg| { + // comment formatting + foo(arg) + }; + + let test = || { + do_something(); + do_something_else(); + }; + + let arg_test = + |big_argument_name, test123| looooooooooooooooooong_function_naaaaaaaaaaaaaaaaame(); + + let arg_test = + |big_argument_name, test123| looooooooooooooooooong_function_naaaaaaaaaaaaaaaaame(); + + let simple_closure = move || -> () {}; + + let closure = |input: Ty| -> Option<String> { foo() }; + + let closure_with_return_type = + |aaaaaaaaaaaaaaaaaaaaaaarg1, aaaaaaaaaaaaaaaaaaaaaaarg2| -> Strong { "sup".to_owned() }; + + |arg1, arg2, _, _, arg3, arg4| { + let temp = arg4 + arg3; + arg2 * arg1 - temp + }; + + let block_body_with_comment = args.iter().map(|a| { + // Emitting only dep-info is possible only for final crate type, as + // as others may emit required metadata for dependent crate types + if a.starts_with("--emit") && is_final_crate_type && !self.workspace_mode { + "--emit=dep-info" + } else { + a + } + }); + + for<> || -> () {}; + for<> || -> () {}; + for<> || -> () {}; + + for<'a, 'b, 'c> |_: &'a (), _: &'b (), _: &'c ()| -> () {}; +} + +fn issue311() { + let func = |x| println!("{}", x); + + (func)(0.0); +} + +fn issue863() { + let closure = |x| match x { + 0 => true, + _ => false, + } == true; +} + +fn issue934() { + let hash: &Fn(&&Block) -> u64 = &|block| -> u64 { + let mut h = SpanlessHash::new(cx); + h.hash_block(block); + h.finish() + }; + + let hash: &Fn(&&Block) -> u64 = &|block| -> u64 { + let mut h = SpanlessHash::new(cx); + h.hash_block(block); + h.finish(); + }; +} + +impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { + pub fn eq_expr(&self, left: &Expr, right: &Expr) -> bool { + match (&left.node, &right.node) { + (&ExprBinary(l_op, ref ll, ref lr), &ExprBinary(r_op, ref rl, ref rr)) => { + l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) + || swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| { + l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) + }) + } + } + } +} + +fn foo() { + lifetimes_iter___map(|lasdfasfd| { + let hi = if l.bounds.is_empty() { + l.lifetime.span.hi() + }; + }); +} + +fn issue1405() { + open_raw_fd(fd, b'r').and_then(|file| { + Capture::new_raw(None, |_, err| unsafe { raw::pcap_fopen_offline(file, err) }) + }); +} + +fn issue1466() { + let vertex_buffer = frame.scope(|ctx| { + let buffer = ctx.create_host_visible_buffer::<VertexBuffer<Vertex>>(&vertices); + ctx.create_device_local_buffer(buffer) + }); +} + +fn issue470() { + { + { + { + let explicit_arg_decls = + explicit_arguments + .into_iter() + .enumerate() + .map(|(index, (ty, pattern))| { + let lvalue = Lvalue::Arg(index as u32); + block = this.pattern( + block, + argument_extent, + hair::PatternRef::Hair(pattern), + &lvalue, + ); + ArgDecl { ty: ty } + }); + } + } + } +} + +// #1509 +impl Foo { + pub fn bar(&self) { + Some(SomeType { + push_closure_out_to_100_chars: iter(otherwise_it_works_ok.into_iter().map(|f| Ok(f))), + }) + } +} + +fn issue1329() { + aaaaaaaaaaaaaaaa + .map(|x| { + x += 1; + x + }) + .filter +} + +fn issue325() { + let f = + || unsafe { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }; +} + +fn issue1697() { + Test.func_a( + A_VERY_LONG_CONST_VARIABLE_NAME, + move |arg1, arg2, arg3, arg4| arg1 + arg2 + arg3 + arg4, + ) +} + +fn issue1694() { + foooooo( + |_referencefffffffff: _, _target_reference: _, _oid: _, _target_oid: _| { + format!("refs/pull/{}/merge", pr_id) + }, + ) +} + +fn issue1713() { + rayon::join( + || recurse(left, is_less, pred, limit), + || recurse(right, is_less, Some(pivot), limit), + ); + + rayon::join( + 1, + || recurse(left, is_less, pred, limit), + 2, + || recurse(right, is_less, Some(pivot), limit), + ); +} + +fn issue2063() { + |ctx: Ctx<(String, String)>| -> io::Result<Response> { + Ok(Response::new().with_body(ctx.params.0)) + } +} + +fn issue1524() { + let f = |x| x; + let f = |x| x; + let f = |x| x; + let f = |x| x; + let f = |x| x; +} + +fn issue2171() { + foo(|| unsafe { + if PERIPHERALS { + loop {} + } else { + PERIPHERALS = true; + } + }) +} + +fn issue2207() { + a.map(|_| { + unsafe { a_very_very_very_very_very_very_very_long_function_name_or_anything_else() } + .to_string() + }) +} + +fn issue2262() { + result + .init(&mut result.slave.borrow_mut(), &mut (result.strategy)()) + .map_err(|factory| Error { + factory, + slave: None, + })?; +} diff --git a/src/tools/rustfmt/tests/target/comment-inside-const.rs b/src/tools/rustfmt/tests/target/comment-inside-const.rs new file mode 100644 index 000000000..f847f2c69 --- /dev/null +++ b/src/tools/rustfmt/tests/target/comment-inside-const.rs @@ -0,0 +1,9 @@ +fn issue982() { + const SOME_CONSTANT: u32 = + // Explanation why SOME_CONSTANT needs FLAG_A to be set. + FLAG_A | + // Explanation why SOME_CONSTANT needs FLAG_B to be set. + FLAG_B | + // Explanation why SOME_CONSTANT needs FLAG_C to be set. + FLAG_C; +} diff --git a/src/tools/rustfmt/tests/target/comment-not-disappear.rs b/src/tools/rustfmt/tests/target/comment-not-disappear.rs new file mode 100644 index 000000000..b1fa0ff6f --- /dev/null +++ b/src/tools/rustfmt/tests/target/comment-not-disappear.rs @@ -0,0 +1,38 @@ +// All the comments here should not disappear. + +fn a() { + match x { + X | + // A comment + Y => {} + }; +} + +fn b() { + match x { + X => + // A comment + { + y + } + } +} + +fn c() { + a() /* ... */; +} + +fn foo() -> Vec<i32> { + (0..11) + .map(|x| + // This comment disappears. + if x % 2 == 0 { x } else { x * 2 }) + .collect() +} + +fn calc_page_len(prefix_len: usize, sofar: usize) -> usize { + 2 // page type and flags + + 1 // stored depth + + 2 // stored count + + prefix_len + sofar // sum of size of all the actual items +} diff --git a/src/tools/rustfmt/tests/target/comment.rs b/src/tools/rustfmt/tests/target/comment.rs new file mode 100644 index 000000000..b987c8a44 --- /dev/null +++ b/src/tools/rustfmt/tests/target/comment.rs @@ -0,0 +1,93 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +//! Doc comment +fn test() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam + //! lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam + + // comment + // comment2 + + code(); // leave this comment alone! + // ok? + + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a + // diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam + // viverra nec consectetur ante hendrerit. Donec et mollis dolor. + // Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam + // tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut + // libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit + // amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis + // felis, pulvinar a semper sed, adipiscing id dolor. + + // Very looooooooooooooooooooooooooooooooooooooooooooooooooooooooong comment + // that should be split + + // println!("{:?}", rewrite_comment(subslice, + // false, + // comment_width, + // self.block_indent, + // self.config) + // .unwrap()); + + funk(); // dontchangeme + // or me + + // #1388 + const EXCEPTION_PATHS: &'static [&'static str] = &[ + // std crates + "src/libstd/sys/", // Platform-specific code for std lives here. + "src/bootstrap", + ]; +} + +/// test123 +fn doc_comment() {} + +fn chains() { + foo.bar(|| { + let x = 10; + // comment + x + }) +} + +fn issue_1086() { + // +} + +// random comment + +fn main() { // Test +} + +// #1643 +fn some_fn() // some comment +{ +} + +fn some_fn1() +// some comment +{ +} + +fn some_fn2() // some comment +{ +} + +fn some_fn3() // some comment some comment some comment some comment some comment some comment so +{ +} + +fn some_fn4() +// some comment some comment some comment some comment some comment some comment some comment +{ +} + +// #1603 +pub enum Foo { + A, // `/** **/` + B, // `/*!` + C, +} diff --git a/src/tools/rustfmt/tests/target/comment2.rs b/src/tools/rustfmt/tests/target/comment2.rs new file mode 100644 index 000000000..04f84a15c --- /dev/null +++ b/src/tools/rustfmt/tests/target/comment2.rs @@ -0,0 +1,5 @@ +// rustfmt-wrap_comments: true + +/// This is a long line that angers rustfmt. Rustfmt shall deal with it swiftly +/// and justly. +pub mod foo {} diff --git a/src/tools/rustfmt/tests/target/comment3.rs b/src/tools/rustfmt/tests/target/comment3.rs new file mode 100644 index 000000000..3a810590d --- /dev/null +++ b/src/tools/rustfmt/tests/target/comment3.rs @@ -0,0 +1,6 @@ +// rustfmt-wrap_comments: true + +//! This is a long line that angers rustfmt. Rustfmt shall deal with it swiftly +//! and justly. + +pub mod foo {} diff --git a/src/tools/rustfmt/tests/target/comment4.rs b/src/tools/rustfmt/tests/target/comment4.rs new file mode 100644 index 000000000..e2ef7de97 --- /dev/null +++ b/src/tools/rustfmt/tests/target/comment4.rs @@ -0,0 +1,51 @@ +#![allow(dead_code)] // bar + +//! Doc comment +fn test() { + // comment + // comment2 + + code(); /* leave this comment alone! + * ok? */ + + /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a + * diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam + * viverra nec consectetur ante hendrerit. Donec et mollis dolor. + * Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam + * tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut + * libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit + * amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis + * felis, pulvinar a semper sed, adipiscing id dolor. */ + + // Very loooooooooooooooooooooooooooooooooooooooooooooooooooooooong comment that should be split + + // println!("{:?}", rewrite_comment(subslice, + // false, + // comment_width, + // self.block_indent, + // self.config) + // .unwrap()); + + funk(); //dontchangeme + // or me +} + +/// test123 +fn doc_comment() {} + +/* +Regression test for issue #956 + +(some very important text) +*/ + +/* +fn debug_function() { + println!("hello"); +} +// */ + +#[link_section=".vectors"] +#[no_mangle] // Test this attribute is preserved. +#[cfg_attr(rustfmt, rustfmt::skip)] +pub static ISSUE_1284: [i32; 16] = []; diff --git a/src/tools/rustfmt/tests/target/comment5.rs b/src/tools/rustfmt/tests/target/comment5.rs new file mode 100644 index 000000000..82d171e6f --- /dev/null +++ b/src/tools/rustfmt/tests/target/comment5.rs @@ -0,0 +1,16 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +//@ special comment +//@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec adiam lectus. +//@ Sed sit amet ipsum mauris. Maecenas congue ligula ac quam +//@ +//@ foo +fn test() {} + +//@@@ another special comment +//@@@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec adiam +//@@@ lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam +//@@@ +//@@@ foo +fn bar() {} diff --git a/src/tools/rustfmt/tests/target/comment6.rs b/src/tools/rustfmt/tests/target/comment6.rs new file mode 100644 index 000000000..565fee632 --- /dev/null +++ b/src/tools/rustfmt/tests/target/comment6.rs @@ -0,0 +1,14 @@ +// rustfmt-wrap_comments: true + +// Pendant la nuit du 9 mars 1860, les nuages, se confondant avec la mer, +// limitaient à quelques brasses la portée de la vue. Sur cette mer démontée, +// dont les lames déferlaient en projetant des lueurs livides, un léger bâtiment +// fuyait presque à sec de toile. + +pub mod foo {} + +// ゆく河の流れは絶えずして、しかももとの水にあらず。淀みに浮かぶうたかたは、 +// かつ消えかつ結びて、久しくとどまりたるためしなし。世の中にある人とすみかと、 +// またかくのごとし。 + +pub mod bar {} diff --git a/src/tools/rustfmt/tests/target/comment_crlf_newline.rs b/src/tools/rustfmt/tests/target/comment_crlf_newline.rs new file mode 100644 index 000000000..aab9e94d9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/comment_crlf_newline.rs @@ -0,0 +1,4 @@ +// rustfmt-normalize_comments: true +// Block comments followed by CRLF newlines should not an extra newline at the end + +// Something else diff --git a/src/tools/rustfmt/tests/target/comments-fn.rs b/src/tools/rustfmt/tests/target/comments-fn.rs new file mode 100644 index 000000000..1f43bd93b --- /dev/null +++ b/src/tools/rustfmt/tests/target/comments-fn.rs @@ -0,0 +1,38 @@ +// Test comments on functions are preserved. + +// Comment on foo. +fn foo<F, G>( + a: aaaaaaaaaaaaa, // A comment + b: bbbbbbbbbbbbb, // a second comment + c: ccccccccccccc, + // Newline comment + d: ddddddddddddd, + // A multi line comment + // between args. + e: eeeeeeeeeeeee, /* comment before paren */ +) -> bar +where + F: Foo, // COmment after where-clause + G: Goo, // final comment +{ +} + +fn bar<F /* comment on F */, G /* comment on G */>() {} + +fn baz() -> Baz /* Comment after return type */ {} + +fn some_fn<T>() +where + T: Eq, // some comment +{ +} + +fn issue458<F>(a: &str, f: F) +// comment1 +where + // comment2 + F: FnOnce(&str) -> bool, +{ + f(a); + () +} diff --git a/src/tools/rustfmt/tests/target/comments-in-lists/format-doc-comments.rs b/src/tools/rustfmt/tests/target/comments-in-lists/format-doc-comments.rs new file mode 100644 index 000000000..be4b7a8c4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/comments-in-lists/format-doc-comments.rs @@ -0,0 +1,94 @@ +// rustfmt-format_code_in_doc_comments: true + +// https://github.com/rust-lang/rustfmt/issues/4420 +enum Minimal { + Example, + //[thisisremoved thatsleft + // canbeanything +} + +struct Minimal2 { + Example: usize, + //[thisisremoved thatsleft + // canbeanything +} + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec<i32> = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } +} diff --git a/src/tools/rustfmt/tests/target/comments-in-lists/wrap-comments-false.rs b/src/tools/rustfmt/tests/target/comments-in-lists/wrap-comments-false.rs new file mode 100644 index 000000000..db4da6223 --- /dev/null +++ b/src/tools/rustfmt/tests/target/comments-in-lists/wrap-comments-false.rs @@ -0,0 +1,83 @@ +// rustfmt-normalize_comments: true + +// https://github.com/rust-lang/rustfmt/issues/4909 +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec<i32> = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } +} diff --git a/src/tools/rustfmt/tests/target/comments-in-lists/wrap-comments-not-normalized.rs b/src/tools/rustfmt/tests/target/comments-in-lists/wrap-comments-not-normalized.rs new file mode 100644 index 000000000..9b9147eb1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/comments-in-lists/wrap-comments-not-normalized.rs @@ -0,0 +1,142 @@ +// rustfmt-wrap_comments: true + +// https://github.com/rust-lang/rustfmt/issues/4909 +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec<i32> = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } + + match a { + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + } +} diff --git a/src/tools/rustfmt/tests/target/comments-in-lists/wrap-comments-true.rs b/src/tools/rustfmt/tests/target/comments-in-lists/wrap-comments-true.rs new file mode 100644 index 000000000..c1531d22a --- /dev/null +++ b/src/tools/rustfmt/tests/target/comments-in-lists/wrap-comments-true.rs @@ -0,0 +1,143 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +// https://github.com/rust-lang/rustfmt/issues/4909 +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec<i32> = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } + + match a { + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + } +} diff --git a/src/tools/rustfmt/tests/target/configs/blank_lines_lower_bound/1.rs b/src/tools/rustfmt/tests/target/configs/blank_lines_lower_bound/1.rs new file mode 100644 index 000000000..9706699dc --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/blank_lines_lower_bound/1.rs @@ -0,0 +1,16 @@ +// rustfmt-blank_lines_lower_bound: 1 + +fn foo() {} + +fn bar() {} + +// comment +fn foobar() {} + +fn foo1() {} + +fn bar1() {} + +// comment + +fn foobar1() {} diff --git a/src/tools/rustfmt/tests/target/configs/brace_style/fn_always_next_line.rs b/src/tools/rustfmt/tests/target/configs/brace_style/fn_always_next_line.rs new file mode 100644 index 000000000..2755a2646 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/brace_style/fn_always_next_line.rs @@ -0,0 +1,19 @@ +// rustfmt-brace_style: AlwaysNextLine +// Function brace style + +fn lorem() +{ + // body +} + +fn lorem(ipsum: usize) +{ + // body +} + +fn lorem<T>(ipsum: T) +where + T: Add + Sub + Mul + Div, +{ + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/brace_style/fn_prefer_same_line.rs b/src/tools/rustfmt/tests/target/configs/brace_style/fn_prefer_same_line.rs new file mode 100644 index 000000000..23f98b6dd --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/brace_style/fn_prefer_same_line.rs @@ -0,0 +1,16 @@ +// rustfmt-brace_style: PreferSameLine +// Function brace style + +fn lorem() { + // body +} + +fn lorem(ipsum: usize) { + // body +} + +fn lorem<T>(ipsum: T) +where + T: Add + Sub + Mul + Div, { + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/brace_style/fn_same_line_where.rs b/src/tools/rustfmt/tests/target/configs/brace_style/fn_same_line_where.rs new file mode 100644 index 000000000..2afe59943 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/brace_style/fn_same_line_where.rs @@ -0,0 +1,17 @@ +// rustfmt-brace_style: SameLineWhere +// Function brace style + +fn lorem() { + // body +} + +fn lorem(ipsum: usize) { + // body +} + +fn lorem<T>(ipsum: T) +where + T: Add + Sub + Mul + Div, +{ + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/brace_style/item_always_next_line.rs b/src/tools/rustfmt/tests/target/configs/brace_style/item_always_next_line.rs new file mode 100644 index 000000000..c13018630 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/brace_style/item_always_next_line.rs @@ -0,0 +1,25 @@ +// rustfmt-brace_style: AlwaysNextLine +// Item brace style + +enum Foo {} + +struct Bar {} + +struct Lorem +{ + ipsum: bool, +} + +struct Dolor<T> +where + T: Eq, +{ + sit: T, +} + +#[cfg(test)] +mod tests +{ + #[test] + fn it_works() {} +} diff --git a/src/tools/rustfmt/tests/target/configs/brace_style/item_prefer_same_line.rs b/src/tools/rustfmt/tests/target/configs/brace_style/item_prefer_same_line.rs new file mode 100644 index 000000000..5143d7517 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/brace_style/item_prefer_same_line.rs @@ -0,0 +1,18 @@ +// rustfmt-brace_style: PreferSameLine +// Item brace style + +struct Lorem { + ipsum: bool, +} + +struct Dolor<T> +where + T: Eq, { + sit: T, +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() {} +} diff --git a/src/tools/rustfmt/tests/target/configs/brace_style/item_same_line_where.rs b/src/tools/rustfmt/tests/target/configs/brace_style/item_same_line_where.rs new file mode 100644 index 000000000..8a3b28526 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/brace_style/item_same_line_where.rs @@ -0,0 +1,19 @@ +// rustfmt-brace_style: SameLineWhere +// Item brace style + +struct Lorem { + ipsum: bool, +} + +struct Dolor<T> +where + T: Eq, +{ + sit: T, +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() {} +} diff --git a/src/tools/rustfmt/tests/target/configs/chain_width/always.rs b/src/tools/rustfmt/tests/target/configs/chain_width/always.rs new file mode 100644 index 000000000..b16d25251 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/chain_width/always.rs @@ -0,0 +1,29 @@ +// rustfmt-chain_width: 1 +// setting an unachievable chain_width to always get chains +// on separate lines + +struct Fluent {} + +impl Fluent { + fn blorp(&self) -> &Self { + self + } +} + +fn main() { + let test = Fluent {}; + + // should be left alone + test.blorp(); + + // should be wrapped + test.blorp() + .blorp(); + test.blorp() + .blorp() + .blorp(); + test.blorp() + .blorp() + .blorp() + .blorp(); +} diff --git a/src/tools/rustfmt/tests/target/configs/chain_width/small.rs b/src/tools/rustfmt/tests/target/configs/chain_width/small.rs new file mode 100644 index 000000000..2f2f72777 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/chain_width/small.rs @@ -0,0 +1,32 @@ +// rustfmt-chain_width: 40 + +struct Fluent {} + +impl Fluent { + fn blorp(&self) -> &Self { + self + } +} + +fn main() { + let test = Fluent {}; + + // should not be wrapped + test.blorp(); + test.blorp().blorp(); + test.blorp().blorp().blorp(); + test.blorp().blorp().blorp().blorp(); + + // should be wrapped + test.blorp() + .blorp() + .blorp() + .blorp() + .blorp(); + test.blorp() + .blorp() + .blorp() + .blorp() + .blorp() + .blorp(); +} diff --git a/src/tools/rustfmt/tests/target/configs/chain_width/tiny.rs b/src/tools/rustfmt/tests/target/configs/chain_width/tiny.rs new file mode 100644 index 000000000..960d245f8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/chain_width/tiny.rs @@ -0,0 +1,26 @@ +// rustfmt-chain_width: 20 + +struct Fluent {} + +impl Fluent { + fn blorp(&self) -> &Self { + self + } +} + +fn main() { + let test = Fluent {}; + + // should not be wrapped + test.blorp(); + test.blorp().blorp(); + + // should be wrapped + test.blorp() + .blorp() + .blorp(); + test.blorp() + .blorp() + .blorp() + .blorp(); +} diff --git a/src/tools/rustfmt/tests/target/configs/combine_control_expr/false.rs b/src/tools/rustfmt/tests/target/configs/combine_control_expr/false.rs new file mode 100644 index 000000000..5ada9b1dd --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/combine_control_expr/false.rs @@ -0,0 +1,134 @@ +// rustfmt-indent_style: Block +// rustfmt-combine_control_expr: false + +// Combining openings and closings. See rust-lang/fmt-rfcs#61. + +fn main() { + // Call + foo(bar( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // Mac + foo(foo!( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // MethodCall + foo(x.foo::<Bar, Baz>( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // Block + foo!({ + foo(); + bar(); + }); + + // Closure + foo(|x| { + let y = x + 1; + y + }); + + // Match + foo(match opt { + Some(x) => x, + None => y, + }); + + // Struct + foo(Bar { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + }); + + // If + foo!( + if x { + foo(); + } else { + bar(); + } + ); + + // IfLet + foo!( + if let Some(..) = x { + foo(); + } else { + bar(); + } + ); + + // While + foo!( + while x { + foo(); + bar(); + } + ); + + // WhileLet + foo!( + while let Some(..) = x { + foo(); + bar(); + } + ); + + // ForLoop + foo!( + for x in y { + foo(); + bar(); + } + ); + + // Loop + foo!( + loop { + foo(); + bar(); + } + ); + + // Tuple + foo(( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // AddrOf + foo(&bar( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // Box + foo(box Bar { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + }); + + // Unary + foo(!bar( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // Try + foo(bar( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )?); + + // Cast + foo(Bar { + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + } as i64); +} diff --git a/src/tools/rustfmt/tests/target/configs/combine_control_expr/true.rs b/src/tools/rustfmt/tests/target/configs/combine_control_expr/true.rs new file mode 100644 index 000000000..52acd2649 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/combine_control_expr/true.rs @@ -0,0 +1,122 @@ +// rustfmt-indent_style: Block +// rustfmt-combine_control_expr: true + +// Combining openings and closings. See rust-lang/fmt-rfcs#61. + +fn main() { + // Call + foo(bar( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // Mac + foo(foo!( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // MethodCall + foo(x.foo::<Bar, Baz>( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // Block + foo!({ + foo(); + bar(); + }); + + // Closure + foo(|x| { + let y = x + 1; + y + }); + + // Match + foo(match opt { + Some(x) => x, + None => y, + }); + + // Struct + foo(Bar { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + }); + + // If + foo!(if x { + foo(); + } else { + bar(); + }); + + // IfLet + foo!(if let Some(..) = x { + foo(); + } else { + bar(); + }); + + // While + foo!(while x { + foo(); + bar(); + }); + + // WhileLet + foo!(while let Some(..) = x { + foo(); + bar(); + }); + + // ForLoop + foo!(for x in y { + foo(); + bar(); + }); + + // Loop + foo!(loop { + foo(); + bar(); + }); + + // Tuple + foo(( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // AddrOf + foo(&bar( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // Box + foo(box Bar { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + }); + + // Unary + foo(!bar( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )); + + // Try + foo(bar( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + )?); + + // Cast + foo(Bar { + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + } as i64); +} diff --git a/src/tools/rustfmt/tests/target/configs/comment_width/above.rs b/src/tools/rustfmt/tests/target/configs/comment_width/above.rs new file mode 100644 index 000000000..ddfecda65 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/comment_width/above.rs @@ -0,0 +1,8 @@ +// rustfmt-comment_width: 40 +// rustfmt-wrap_comments: true +// Comment width + +fn main() { + // Lorem ipsum dolor sit amet, + // consectetur adipiscing elit. +} diff --git a/src/tools/rustfmt/tests/target/configs/comment_width/below.rs b/src/tools/rustfmt/tests/target/configs/comment_width/below.rs new file mode 100644 index 000000000..abbc5930c --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/comment_width/below.rs @@ -0,0 +1,7 @@ +// rustfmt-comment_width: 80 +// rustfmt-wrap_comments: true +// Comment width + +fn main() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. +} diff --git a/src/tools/rustfmt/tests/target/configs/comment_width/ignore.rs b/src/tools/rustfmt/tests/target/configs/comment_width/ignore.rs new file mode 100644 index 000000000..c86e71c28 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/comment_width/ignore.rs @@ -0,0 +1,7 @@ +// rustfmt-comment_width: 40 +// rustfmt-wrap_comments: false +// Comment width + +fn main() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. +} diff --git a/src/tools/rustfmt/tests/target/configs/condense_wildcard_suffixes/false.rs b/src/tools/rustfmt/tests/target/configs/condense_wildcard_suffixes/false.rs new file mode 100644 index 000000000..3b967f35a --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/condense_wildcard_suffixes/false.rs @@ -0,0 +1,6 @@ +// rustfmt-condense_wildcard_suffixes: false +// Condense wildcard suffixes + +fn main() { + let (lorem, ipsum, _, _) = (1, 2, 3, 4); +} diff --git a/src/tools/rustfmt/tests/target/configs/condense_wildcard_suffixes/true.rs b/src/tools/rustfmt/tests/target/configs/condense_wildcard_suffixes/true.rs new file mode 100644 index 000000000..4f880abe8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/condense_wildcard_suffixes/true.rs @@ -0,0 +1,6 @@ +// rustfmt-condense_wildcard_suffixes: true +// Condense wildcard suffixes + +fn main() { + let (lorem, ipsum, ..) = (1, 2, 3, 4); +} diff --git a/src/tools/rustfmt/tests/target/configs/control_brace_style/always_next_line.rs b/src/tools/rustfmt/tests/target/configs/control_brace_style/always_next_line.rs new file mode 100644 index 000000000..7dc06f207 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/control_brace_style/always_next_line.rs @@ -0,0 +1,18 @@ +// rustfmt-control_brace_style: AlwaysNextLine +// Control brace style + +fn main() { + if lorem + { + println!("ipsum!"); + } + else + { + println!("dolor!"); + } + match magi + { + Homura => "Akemi", + Madoka => "Kaname", + } +} diff --git a/src/tools/rustfmt/tests/target/configs/control_brace_style/always_same_line.rs b/src/tools/rustfmt/tests/target/configs/control_brace_style/always_same_line.rs new file mode 100644 index 000000000..993b6b681 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/control_brace_style/always_same_line.rs @@ -0,0 +1,14 @@ +// rustfmt-control_brace_style: AlwaysSameLine +// Control brace style + +fn main() { + if lorem { + println!("ipsum!"); + } else { + println!("dolor!"); + } + match magi { + Homura => "Akemi", + Madoka => "Kaname", + } +} diff --git a/src/tools/rustfmt/tests/target/configs/control_brace_style/closing_next_line.rs b/src/tools/rustfmt/tests/target/configs/control_brace_style/closing_next_line.rs new file mode 100644 index 000000000..013852ee7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/control_brace_style/closing_next_line.rs @@ -0,0 +1,15 @@ +// rustfmt-control_brace_style: ClosingNextLine +// Control brace style + +fn main() { + if lorem { + println!("ipsum!"); + } + else { + println!("dolor!"); + } + match magi { + Homura => "Akemi", + Madoka => "Kaname", + } +} diff --git a/src/tools/rustfmt/tests/target/configs/disable_all_formatting/false.rs b/src/tools/rustfmt/tests/target/configs/disable_all_formatting/false.rs new file mode 100644 index 000000000..1a0477ddb --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/disable_all_formatting/false.rs @@ -0,0 +1,10 @@ +// rustfmt-disable_all_formatting: false +// Disable all formatting + +fn main() { + if lorem { + println!("ipsum!"); + } else { + println!("dolor!"); + } +} diff --git a/src/tools/rustfmt/tests/target/configs/disable_all_formatting/true.rs b/src/tools/rustfmt/tests/target/configs/disable_all_formatting/true.rs new file mode 100644 index 000000000..736ccf569 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/disable_all_formatting/true.rs @@ -0,0 +1,6 @@ +// rustfmt-disable_all_formatting: true +// Disable all formatting + +fn main() { + if lorem{println!("ipsum!");}else{println!("dolor!");} +} diff --git a/src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/100.rs b/src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/100.rs new file mode 100644 index 000000000..c010a28aa --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/100.rs @@ -0,0 +1,16 @@ +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 100 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { +/// Self::from_bytes_manual_slice(v, 0, v.len()) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { + Self::from_bytes_manual_slice(v, 0, v.len()) + } +} diff --git a/src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/100_greater_max_width.rs b/src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/100_greater_max_width.rs new file mode 100644 index 000000000..6bcb99b91 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/100_greater_max_width.rs @@ -0,0 +1,29 @@ +// rustfmt-max_width: 50 +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 100 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes( +/// v: &[u8], +/// ) -> Result<Self, ParserError> { +/// Self::from_bytes_manual_slice( +/// v, +/// 0, +/// v.len(), +/// ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes( + v: &[u8], + ) -> Result<Self, ParserError> { + Self::from_bytes_manual_slice( + v, + 0, + v.len(), + ) + } +} diff --git a/src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/50.rs b/src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/50.rs new file mode 100644 index 000000000..e8ab6f28b --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/50.rs @@ -0,0 +1,22 @@ +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 50 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes( +/// v: &[u8], +/// ) -> Result<Self, ParserError> { +/// Self::from_bytes_manual_slice( +/// v, +/// 0, +/// v.len(), +/// ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result<Self, ParserError> { + Self::from_bytes_manual_slice(v, 0, v.len()) + } +} diff --git a/src/tools/rustfmt/tests/target/configs/empty_item_single_line/false.rs b/src/tools/rustfmt/tests/target/configs/empty_item_single_line/false.rs new file mode 100644 index 000000000..174fe330a --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/empty_item_single_line/false.rs @@ -0,0 +1,14 @@ +// rustfmt-empty_item_single_line: false +// Empty impl on single line + +impl Lorem { +} + +impl Ipsum { +} + +fn lorem() { +} + +fn lorem() { +} diff --git a/src/tools/rustfmt/tests/target/configs/empty_item_single_line/true.rs b/src/tools/rustfmt/tests/target/configs/empty_item_single_line/true.rs new file mode 100644 index 000000000..0755485fe --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/empty_item_single_line/true.rs @@ -0,0 +1,10 @@ +// rustfmt-empty_item_single_line: true +// Empty impl on single line + +impl Lorem {} + +impl Ipsum {} + +fn lorem() {} + +fn lorem() {} diff --git a/src/tools/rustfmt/tests/target/configs/enum_discrim_align_threshold/40.rs b/src/tools/rustfmt/tests/target/configs/enum_discrim_align_threshold/40.rs new file mode 100644 index 000000000..3ed66039c --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/enum_discrim_align_threshold/40.rs @@ -0,0 +1,34 @@ +// rustfmt-enum_discrim_align_threshold: 40
+
+enum Standard {
+ A = 1,
+ Bcdef = 2,
+}
+
+enum NoDiscrims {
+ ThisIsAFairlyLongEnumVariantWithoutDiscrimLongerThan40,
+ A = 1,
+ ThisIsAnotherFairlyLongEnumVariantWithoutDiscrimLongerThan40,
+ Bcdef = 2,
+}
+
+enum TooLong {
+ ThisOneHasDiscrimAaaaaaaaaaaaaaaaaaaaaaChar40 = 10,
+ A = 1,
+ Bcdef = 2,
+}
+
+enum Borderline {
+ ThisOneHasDiscrimAaaaaaaaaaaaaaaaaaaaaa = 10,
+ A = 1,
+ Bcdef = 2,
+}
+
+// Live specimen from #1686
+enum LongWithSmallDiff {
+ SceneColorimetryEstimates = 0x73636F65,
+ SceneAppearanceEstimates = 0x73617065,
+ FocalPlaneColorimetryEstimates = 0x66706365,
+ ReflectionHardcopyOriginalColorimetry = 0x72686F63,
+ ReflectionPrintOutputColorimetry = 0x72706F63,
+}
diff --git a/src/tools/rustfmt/tests/target/configs/error_on_line_overflow/false.rs b/src/tools/rustfmt/tests/target/configs/error_on_line_overflow/false.rs new file mode 100644 index 000000000..fa70ae783 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/error_on_line_overflow/false.rs @@ -0,0 +1,6 @@ +// rustfmt-error_on_line_overflow: false +// Error on line overflow + +fn main() { + let lorem_ipsum_dolor_sit_amet_consectetur_adipiscing_elit_lorem_ipsum_dolor_sit_amet_consectetur_adipiscing_elit; +} diff --git a/src/tools/rustfmt/tests/target/configs/error_on_unformatted/false.rs b/src/tools/rustfmt/tests/target/configs/error_on_unformatted/false.rs new file mode 100644 index 000000000..6a78374e2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/error_on_unformatted/false.rs @@ -0,0 +1,12 @@ +// rustfmt-error_on_unformatted: false +// Error on line overflow comment or string literals. + +// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +fn main() { + // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + let x = " "; + let a = " + +"; +} diff --git a/src/tools/rustfmt/tests/target/configs/fn_args_layout/compressed.rs b/src/tools/rustfmt/tests/target/configs/fn_args_layout/compressed.rs new file mode 100644 index 000000000..f189446e2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/fn_args_layout/compressed.rs @@ -0,0 +1,22 @@ +// rustfmt-fn_args_layout: Compressed +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem( + ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, + adipiscing: Adipiscing, elit: Elit, + ); + + fn lorem( + ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, + adipiscing: Adipiscing, elit: Elit, + ) { + // body + } +} diff --git a/src/tools/rustfmt/tests/target/configs/fn_args_layout/tall.rs b/src/tools/rustfmt/tests/target/configs/fn_args_layout/tall.rs new file mode 100644 index 000000000..20f308973 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/fn_args_layout/tall.rs @@ -0,0 +1,32 @@ +// rustfmt-fn_args_layout: Tall +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: onsectetur, + adipiscing: Adipiscing, + elit: Elit, + ); + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: onsectetur, + adipiscing: Adipiscing, + elit: Elit, + ) { + // body + } +} diff --git a/src/tools/rustfmt/tests/target/configs/fn_args_layout/vertical.rs b/src/tools/rustfmt/tests/target/configs/fn_args_layout/vertical.rs new file mode 100644 index 000000000..6c695a75d --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/fn_args_layout/vertical.rs @@ -0,0 +1,42 @@ +// rustfmt-fn_args_layout: Vertical +// Function arguments density + +trait Lorem { + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + ); + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + ) { + // body + } + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: onsectetur, + adipiscing: Adipiscing, + elit: Elit, + ); + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: onsectetur, + adipiscing: Adipiscing, + elit: Elit, + ) { + // body + } +} diff --git a/src/tools/rustfmt/tests/target/configs/fn_single_line/false.rs b/src/tools/rustfmt/tests/target/configs/fn_single_line/false.rs new file mode 100644 index 000000000..3d092f0c0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/fn_single_line/false.rs @@ -0,0 +1,11 @@ +// rustfmt-fn_single_line: false +// Single-expression function on single line + +fn lorem() -> usize { + 42 +} + +fn lorem() -> usize { + let ipsum = 42; + ipsum +} diff --git a/src/tools/rustfmt/tests/target/configs/fn_single_line/true.rs b/src/tools/rustfmt/tests/target/configs/fn_single_line/true.rs new file mode 100644 index 000000000..10d94e02f --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/fn_single_line/true.rs @@ -0,0 +1,9 @@ +// rustfmt-fn_single_line: true +// Single-expression function on single line + +fn lorem() -> usize { 42 } + +fn lorem() -> usize { + let ipsum = 42; + ipsum +} diff --git a/src/tools/rustfmt/tests/target/configs/force_explicit_abi/false.rs b/src/tools/rustfmt/tests/target/configs/force_explicit_abi/false.rs new file mode 100644 index 000000000..3c48f8e0c --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/force_explicit_abi/false.rs @@ -0,0 +1,6 @@ +// rustfmt-force_explicit_abi: false +// Force explicit abi + +extern { + pub static lorem: c_int; +} diff --git a/src/tools/rustfmt/tests/target/configs/force_explicit_abi/true.rs b/src/tools/rustfmt/tests/target/configs/force_explicit_abi/true.rs new file mode 100644 index 000000000..90f5a8c4e --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/force_explicit_abi/true.rs @@ -0,0 +1,6 @@ +// rustfmt-force_explicit_abi: true +// Force explicit abi + +extern "C" { + pub static lorem: c_int; +} diff --git a/src/tools/rustfmt/tests/target/configs/force_multiline_block/false.rs b/src/tools/rustfmt/tests/target/configs/force_multiline_block/false.rs new file mode 100644 index 000000000..7cb4cac1d --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/force_multiline_block/false.rs @@ -0,0 +1,20 @@ +// rustfmt-force_multiline_blocks: false +// Option forces multiline match arm and closure bodies to be wrapped in a block + +fn main() { + match lorem { + Lorem::Ipsum => { + if ipsum { + println!("dolor"); + } + } + Lorem::Dolor => println!("amet"), + } +} + +fn main() { + result.and_then(|maybe_value| match maybe_value { + None => Err("oops"), + Some(value) => Ok(1), + }); +} diff --git a/src/tools/rustfmt/tests/target/configs/force_multiline_block/true.rs b/src/tools/rustfmt/tests/target/configs/force_multiline_block/true.rs new file mode 100644 index 000000000..aec50afe5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/force_multiline_block/true.rs @@ -0,0 +1,22 @@ +// rustfmt-force_multiline_blocks: true +// Option forces multiline match arm and closure bodies to be wrapped in a block + +fn main() { + match lorem { + Lorem::Ipsum => { + if ipsum { + println!("dolor"); + } + } + Lorem::Dolor => println!("amet"), + } +} + +fn main() { + result.and_then(|maybe_value| { + match maybe_value { + None => Err("oops"), + Some(value) => Ok(1), + } + }); +} diff --git a/src/tools/rustfmt/tests/target/configs/format_generated_files/false.rs b/src/tools/rustfmt/tests/target/configs/format_generated_files/false.rs new file mode 100644 index 000000000..dec1e00d1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/format_generated_files/false.rs @@ -0,0 +1,8 @@ +// @generated +// rustfmt-format_generated_files: false + +fn main() +{ + println!("hello, world") + ; +} diff --git a/src/tools/rustfmt/tests/target/configs/format_generated_files/true.rs b/src/tools/rustfmt/tests/target/configs/format_generated_files/true.rs new file mode 100644 index 000000000..5fea7e8b3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/format_generated_files/true.rs @@ -0,0 +1,6 @@ +// @generated +// rustfmt-format_generated_files: true + +fn main() { + println!("hello, world"); +} diff --git a/src/tools/rustfmt/tests/target/configs/format_macro_bodies/false.rs b/src/tools/rustfmt/tests/target/configs/format_macro_bodies/false.rs new file mode 100644 index 000000000..ec871b25b --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/format_macro_bodies/false.rs @@ -0,0 +1,6 @@ +// rustfmt-format_macro_bodies: false + +macro_rules! foo { + ($a: ident : $b: ty) => { $a(42): $b; }; + ($a: ident $b: ident $c: ident) => { $a=$b+$c; }; +} diff --git a/src/tools/rustfmt/tests/target/configs/format_macro_bodies/true.rs b/src/tools/rustfmt/tests/target/configs/format_macro_bodies/true.rs new file mode 100644 index 000000000..9dc2524c3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/format_macro_bodies/true.rs @@ -0,0 +1,10 @@ +// rustfmt-format_macro_bodies: true + +macro_rules! foo { + ($a: ident : $b: ty) => { + $a(42): $b; + }; + ($a: ident $b: ident $c: ident) => { + $a = $b + $c; + }; +} diff --git a/src/tools/rustfmt/tests/target/configs/format_macro_matchers/false.rs b/src/tools/rustfmt/tests/target/configs/format_macro_matchers/false.rs new file mode 100644 index 000000000..3966d21be --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/format_macro_matchers/false.rs @@ -0,0 +1,10 @@ +// rustfmt-format_macro_matchers: false + +macro_rules! foo { + ($a: ident : $b: ty) => { + $a(42): $b; + }; + ($a: ident $b: ident $c: ident) => { + $a = $b + $c; + }; +} diff --git a/src/tools/rustfmt/tests/target/configs/format_macro_matchers/true.rs b/src/tools/rustfmt/tests/target/configs/format_macro_matchers/true.rs new file mode 100644 index 000000000..e113af96f --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/format_macro_matchers/true.rs @@ -0,0 +1,10 @@ +// rustfmt-format_macro_matchers: true + +macro_rules! foo { + ($a:ident : $b:ty) => { + $a(42): $b; + }; + ($a:ident $b:ident $c:ident) => { + $a = $b + $c; + }; +} diff --git a/src/tools/rustfmt/tests/target/configs/format_strings/false.rs b/src/tools/rustfmt/tests/target/configs/format_strings/false.rs new file mode 100644 index 000000000..ecca0d7d1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/format_strings/false.rs @@ -0,0 +1,8 @@ +// rustfmt-format_strings: false +// rustfmt-max_width: 50 +// rustfmt-error_on_line_overflow: false +// Force format strings + +fn main() { + let lorem = "ipsum dolor sit amet consectetur adipiscing elit lorem ipsum dolor sit"; +} diff --git a/src/tools/rustfmt/tests/target/configs/format_strings/true.rs b/src/tools/rustfmt/tests/target/configs/format_strings/true.rs new file mode 100644 index 000000000..fdd5ab2c9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/format_strings/true.rs @@ -0,0 +1,9 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 +// Force format strings + +fn main() { + let lorem = "ipsum dolor sit amet \ + consectetur adipiscing elit \ + lorem ipsum dolor sit"; +} diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/One-merge_imports.rs b/src/tools/rustfmt/tests/target/configs/group_imports/One-merge_imports.rs new file mode 100644 index 000000000..52e0e1c5a --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/group_imports/One-merge_imports.rs @@ -0,0 +1,14 @@ +// rustfmt-group_imports: One +// rustfmt-imports_granularity: Crate +use super::{ + schema::{Context, Payload}, + update::convert_publish_payload, +}; +use crate::models::Event; +use alloc::{alloc::Layout, vec::Vec}; +use broker::database::PooledConnection; +use chrono::Utc; +use core::f32; +use juniper::{FieldError, FieldResult}; +use std::sync::Arc; +use uuid::Uuid; diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/One-nested.rs b/src/tools/rustfmt/tests/target/configs/group_imports/One-nested.rs new file mode 100644 index 000000000..5b6485482 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/group_imports/One-nested.rs @@ -0,0 +1,6 @@ +// rustfmt-group_imports: One +mod test { + use crate::foo::bar; + use crate::foo::bar2; + use std::path; +} diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/One-no_reorder.rs b/src/tools/rustfmt/tests/target/configs/group_imports/One-no_reorder.rs new file mode 100644 index 000000000..015e841d0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/group_imports/One-no_reorder.rs @@ -0,0 +1,12 @@ +// rustfmt-group_imports: One +// rustfmt-reorder_imports: false +use chrono::Utc; +use super::update::convert_publish_payload; +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; +use std::sync::Arc; +use broker::database::PooledConnection; +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/One.rs b/src/tools/rustfmt/tests/target/configs/group_imports/One.rs new file mode 100644 index 000000000..3094c7ae1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/group_imports/One.rs @@ -0,0 +1,11 @@ +// rustfmt-group_imports: One +use super::schema::{Context, Payload}; +use super::update::convert_publish_payload; +use crate::models::Event; +use alloc::alloc::Layout; +use broker::database::PooledConnection; +use chrono::Utc; +use core::f32; +use juniper::{FieldError, FieldResult}; +use std::sync::Arc; +use uuid::Uuid; diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-merge_imports.rs b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-merge_imports.rs new file mode 100644 index 000000000..5e4064dd8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-merge_imports.rs @@ -0,0 +1,16 @@ +// rustfmt-group_imports: StdExternalCrate +// rustfmt-imports_granularity: Crate +use alloc::{alloc::Layout, vec::Vec}; +use core::f32; +use std::sync::Arc; + +use broker::database::PooledConnection; +use chrono::Utc; +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; + +use super::{ + schema::{Context, Payload}, + update::convert_publish_payload, +}; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-nested.rs b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-nested.rs new file mode 100644 index 000000000..daf23375c --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-nested.rs @@ -0,0 +1,7 @@ +// rustfmt-group_imports: StdExternalCrate +mod test { + use std::path; + + use crate::foo::bar; + use crate::foo::bar2; +} diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-no_reorder.rs b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-no_reorder.rs new file mode 100644 index 000000000..76d3d6ccb --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-no_reorder.rs @@ -0,0 +1,15 @@ +// rustfmt-group_imports: StdExternalCrate +// rustfmt-reorder_imports: false + +use alloc::alloc::Layout; +use std::sync::Arc; +use core::f32; + +use chrono::Utc; +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use broker::database::PooledConnection; + +use super::update::convert_publish_payload; +use super::schema::{Context, Payload}; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-non_consecutive.rs b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-non_consecutive.rs new file mode 100644 index 000000000..ecc8ede02 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-non_consecutive.rs @@ -0,0 +1,18 @@ +// rustfmt-group_imports: StdExternalCrate +use alloc::alloc::Layout; + +use chrono::Utc; +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; + +use super::update::convert_publish_payload; + +extern crate uuid; + +use core::f32; +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate.rs b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate.rs new file mode 100644 index 000000000..080257968 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate.rs @@ -0,0 +1,13 @@ +// rustfmt-group_imports: StdExternalCrate +use alloc::alloc::Layout; +use core::f32; +use std::sync::Arc; + +use broker::database::PooledConnection; +use chrono::Utc; +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; + +use super::schema::{Context, Payload}; +use super::update::convert_publish_payload; +use crate::models::Event; diff --git a/src/tools/rustfmt/tests/target/configs/hard_tabs/false.rs b/src/tools/rustfmt/tests/target/configs/hard_tabs/false.rs new file mode 100644 index 000000000..ccfb53d8c --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/hard_tabs/false.rs @@ -0,0 +1,6 @@ +// rustfmt-hard_tabs: false +// Hard tabs + +fn lorem() -> usize { + 42 // spaces before 42 +} diff --git a/src/tools/rustfmt/tests/target/configs/hard_tabs/true.rs b/src/tools/rustfmt/tests/target/configs/hard_tabs/true.rs new file mode 100644 index 000000000..3ed4e4f20 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/hard_tabs/true.rs @@ -0,0 +1,6 @@ +// rustfmt-hard_tabs: true +// Hard tabs + +fn lorem() -> usize { + 42 // spaces before 42 +} diff --git a/src/tools/rustfmt/tests/target/configs/imports_indent/block.rs b/src/tools/rustfmt/tests/target/configs/imports_indent/block.rs new file mode 100644 index 000000000..84c3b26bd --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/imports_indent/block.rs @@ -0,0 +1,7 @@ +// rustfmt-imports_indent: Block + +use lists::{ + definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape, + struct_lit_tactic, write_list, DefinitiveListTactic, ListFormatting, ListItem, ListTactic, + SeparatorTactic, +}; diff --git a/src/tools/rustfmt/tests/target/configs/imports_layout/horizontal_vertical.rs b/src/tools/rustfmt/tests/target/configs/imports_layout/horizontal_vertical.rs new file mode 100644 index 000000000..4a63556d4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/imports_layout/horizontal_vertical.rs @@ -0,0 +1,18 @@ +// rustfmt-imports_indent: Block +// rustfmt-imports_layout: HorizontalVertical + +use comment::{contains_comment, recover_comment_removed, rewrite_comment, FindUncommented}; +use lists::{ + definitive_tactic, + itemize_list, + shape_for_tactic, + struct_lit_formatting, + struct_lit_shape, + struct_lit_tactic, + write_list, + DefinitiveListTactic, + ListFormatting, + ListItem, + ListTactic, + SeparatorTactic, +}; diff --git a/src/tools/rustfmt/tests/target/configs/imports_layout/merge_mixed.rs b/src/tools/rustfmt/tests/target/configs/imports_layout/merge_mixed.rs new file mode 100644 index 000000000..bc0da92ff --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/imports_layout/merge_mixed.rs @@ -0,0 +1,5 @@ +// rustfmt-imports_indent: Block +// rustfmt-imports_granularity: Crate +// rustfmt-imports_layout: Mixed + +use std::{fmt, io, str, str::FromStr}; diff --git a/src/tools/rustfmt/tests/target/configs/imports_layout/mixed.rs b/src/tools/rustfmt/tests/target/configs/imports_layout/mixed.rs new file mode 100644 index 000000000..5d3349a01 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/imports_layout/mixed.rs @@ -0,0 +1,9 @@ +// rustfmt-imports_indent: Block +// rustfmt-imports_layout: Mixed + +use comment::{contains_comment, recover_comment_removed, rewrite_comment, FindUncommented}; +use lists::{ + definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape, + struct_lit_tactic, write_list, DefinitiveListTactic, ListFormatting, ListItem, ListTactic, + SeparatorTactic, +}; diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_args.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_args.rs new file mode 100644 index 000000000..80f4e1333 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_args.rs @@ -0,0 +1,47 @@ +// rustfmt-indent_style: Block +// Function arguments layout + +fn lorem() {} + +fn lorem(ipsum: usize) {} + +fn lorem( + ipsum: usize, + dolor: usize, + sit: usize, + amet: usize, + consectetur: usize, + adipiscing: usize, + elit: usize, +) { + // body +} + +// #1441 +extern "system" { + pub fn GetConsoleHistoryInfo( + console_history_info: *mut ConsoleHistoryInfo, + ) -> Boooooooooooooool; +} + +// rustfmt should not add trailing comma for variadic function. See #1623. +extern "C" { + pub fn variadic_fn( + first_parameter: FirstParameterType, + second_parameter: SecondParameterType, + ... + ); +} + +// #1652 +fn deconstruct( + foo: Bar, +) -> ( + SocketAddr, + Header, + Method, + RequestUri, + HttpVersion, + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +) { +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_array.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_array.rs new file mode 100644 index 000000000..5d458248c --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_array.rs @@ -0,0 +1,14 @@ +// rustfmt-indent_style: Block +// Array layout + +fn main() { + let lorem = vec![ + "ipsum", + "dolor", + "sit", + "amet", + "consectetur", + "adipiscing", + "elit", + ]; +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_call.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_call.rs new file mode 100644 index 000000000..19c44dc01 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_call.rs @@ -0,0 +1,151 @@ +// rustfmt-indent_style: Block +// Function call style + +fn main() { + lorem( + "lorem", + "ipsum", + "dolor", + "sit", + "amet", + "consectetur", + "adipiscing", + "elit", + ); + // #1501 + let hyper = Arc::new(Client::with_connector( + HttpsConnector::new(TlsClient::new()), + )); + + // chain + let x = yooooooooooooo + .fooooooooooooooo + .baaaaaaaaaaaaar(hello, world); + + // #1380 + { + { + let creds = self + .client + .client_credentials(&self.config.auth.oauth2.id, &self.config.auth.oauth2.secret)?; + } + } + + // nesting macro and function call + try!(foo( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + )); + try!(foo(try!( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ))); +} + +// #1521 +impl Foo { + fn map_pixel_to_coords(&self, point: &Vector2i, view: &View) -> Vector2f { + unsafe { + Vector2f::from_raw(ffi::sfRenderTexture_mapPixelToCoords( + self.render_texture, + point.raw(), + view.raw(), + )) + } + } +} + +fn issue1420() { + given( + r#" + # Getting started + ... + "#, + ) + .running(waltz) +} + +// #1563 +fn query(conn: &Connection) -> Result<()> { + conn.query_row( + r#" + SELECT title, date + FROM posts, + WHERE DATE(date) = $1 + "#, + &[], + |row| Post { + title: row.get(0), + date: row.get(1), + }, + )?; + + Ok(()) +} + +// #1449 +fn future_rayon_wait_1_thread() { + // run with only 1 worker thread; this would deadlock if we couldn't make progress + let mut result = None; + ThreadPool::new(Configuration::new().num_threads(1)) + .unwrap() + .install(|| { + scope(|s| { + use std::sync::mpsc::channel; + let (tx, rx) = channel(); + let a = s.spawn_future(lazy(move || Ok::<usize, ()>(rx.recv().unwrap()))); + // ^^^^ FIXME: why is this needed? + let b = s.spawn_future(a.map(|v| v + 1)); + let c = s.spawn_future(b.map(|v| v + 1)); + s.spawn(move |_| tx.send(20).unwrap()); + result = Some(c.rayon_wait().unwrap()); + }); + }); + assert_eq!(result, Some(22)); +} + +// #1494 +impl Cursor { + fn foo() { + self.cur_type() + .num_template_args() + .or_else(|| { + let n: c_int = unsafe { clang_Cursor_getNumTemplateArguments(self.x) }; + + if n >= 0 { + Some(n as u32) + } else { + debug_assert_eq!(n, -1); + None + } + }) + .or_else(|| { + let canonical = self.canonical(); + if canonical != *self { + canonical.num_template_args() + } else { + None + } + }); + } +} + +fn issue1581() { + bootstrap.checks.register("PERSISTED_LOCATIONS", move || { + if locations2.0.inner_mut.lock().poisoned { + Check::new( + State::Error, + "Persisted location storage is poisoned due to a write failure", + ) + } else { + Check::new(State::Healthy, "Persisted location storage is healthy") + } + }); +} + +fn issue1651() { + { + let type_list: Vec<_> = + try_opt!(types.iter().map(|ty| ty.rewrite(context, shape)).collect()); + } +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_chain.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_chain.rs new file mode 100644 index 000000000..23340a4ab --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_chain.rs @@ -0,0 +1,12 @@ +// rustfmt-indent_style: Block +// Chain indent + +fn main() { + let lorem = ipsum + .dolor() + .sit() + .amet() + .consectetur() + .adipiscing() + .elite(); +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_generic.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_generic.rs new file mode 100644 index 000000000..c4fcaaf65 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_generic.rs @@ -0,0 +1,22 @@ +// rustfmt-indent_style: Block +// Generics indent + +fn lorem< + Ipsum: Eq = usize, + Dolor: Eq = usize, + Sit: Eq = usize, + Amet: Eq = usize, + Adipiscing: Eq = usize, + Consectetur: Eq = usize, + Elit: Eq = usize, +>( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + adipiscing: Adipiscing, + consectetur: Consectetur, + elit: Elit, +) -> T { + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_struct_lit.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_struct_lit.rs new file mode 100644 index 000000000..656b56226 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_struct_lit.rs @@ -0,0 +1,9 @@ +// rustfmt-indent_style: Block +// Struct literal-style + +fn main() { + let lorem = Lorem { + ipsum: dolor, + sit: amet, + }; +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_tab_spaces_call.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_tab_spaces_call.rs new file mode 100644 index 000000000..5531e61dd --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_tab_spaces_call.rs @@ -0,0 +1,14 @@ +// rustfmt-indent_style: Block +// rustfmt-max_width: 80 +// rustfmt-tab_spaces: 2 + +// #1427 +fn main() { + exceptaions::config(move || { + ( + NmiConfig {}, + HardFaultConfig {}, + SysTickConfig { gpio_sbsrr }, + ) + }); +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/one.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/one.rs new file mode 100644 index 000000000..6b9489bef --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/one.rs @@ -0,0 +1,12 @@ +// rustfmt-version: One +// rustfmt-error_on_line_overflow: false +// rustfmt-indent_style: Block + +// rustfmt should not add trailing comma when rewriting macro. See #1528. +fn a() { + panic!("this is a long string that goes past the maximum line length causing rustfmt to insert a comma here:"); + foo( + a, + oooptoptoptoptptooptoptoptoptptooptoptoptoptptoptoptoptoptpt(), + ); +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/two.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/two.rs new file mode 100644 index 000000000..4f4292e5f --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/two.rs @@ -0,0 +1,14 @@ +// rustfmt-version: Two +// rustfmt-error_on_line_overflow: false +// rustfmt-indent_style: Block + +// rustfmt should not add trailing comma when rewriting macro. See #1528. +fn a() { + panic!( + "this is a long string that goes past the maximum line length causing rustfmt to insert a comma here:" + ); + foo( + a, + oooptoptoptoptptooptoptoptoptptooptoptoptoptptoptoptoptoptpt(), + ); +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_where_pred.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_where_pred.rs new file mode 100644 index 000000000..ad7e0b8f3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_where_pred.rs @@ -0,0 +1,12 @@ +// rustfmt-indent_style: Block +// Where predicate indent + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T +where + Ipsum: Eq, + Dolor: Eq, + Sit: Eq, + Amet: Eq, +{ + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/default.rs b/src/tools/rustfmt/tests/target/configs/indent_style/default.rs new file mode 100644 index 000000000..a8f0902b3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/default.rs @@ -0,0 +1,11 @@ +// rustfmt-indent_style: Visual +// Where style + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T + where Ipsum: Eq, + Dolor: Eq, + Sit: Eq, + Amet: Eq +{ + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/rfc_control.rs b/src/tools/rustfmt/tests/target/configs/indent_style/rfc_control.rs new file mode 100644 index 000000000..6619d8b26 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/rfc_control.rs @@ -0,0 +1,39 @@ +// rustfmt-indent_style: Block + +// #1618 +fn main() { + loop { + if foo { + if ((right_paddle_speed < 0.) && (right_paddle.position().y - paddle_size.y / 2. > 5.)) + || ((right_paddle_speed > 0.) + && (right_paddle.position().y + paddle_size.y / 2. < game_height as f32 - 5.)) + { + foo + } + if ai_timer.elapsed_time().as_microseconds() > ai_time.as_microseconds() { + if ball.position().y + ball_radius > right_paddle.position().y + paddle_size.y / 2. + { + foo + } + } + } + } +} + +fn issue1656() { + { + { + match rewrite { + Some(ref body_str) + if (!body_str.contains('\n') && body_str.len() <= arm_shape.width) + || !context.config.match_arm_blocks() + || (extend && first_line_width(body_str) <= arm_shape.width) + || is_block => + { + return None; + } + _ => {} + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/rfc_where.rs b/src/tools/rustfmt/tests/target/configs/indent_style/rfc_where.rs new file mode 100644 index 000000000..a7b9a4f02 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/rfc_where.rs @@ -0,0 +1,12 @@ +// rustfmt-indent_style: Block +// Where style + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T +where + Ipsum: Eq, + Dolor: Eq, + Sit: Eq, + Amet: Eq, +{ + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/visual_args.rs b/src/tools/rustfmt/tests/target/configs/indent_style/visual_args.rs new file mode 100644 index 000000000..04c2eaee3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/visual_args.rs @@ -0,0 +1,40 @@ +// rustfmt-indent_style: Visual +// Function arguments layout + +fn lorem() {} + +fn lorem(ipsum: usize) {} + +fn lorem(ipsum: usize, + dolor: usize, + sit: usize, + amet: usize, + consectetur: usize, + adipiscing: usize, + elit: usize) { + // body +} + +// #1922 +extern "C" { + pub fn LAPACKE_csytrs_rook_work(matrix_layout: c_int, + uplo: c_char, + n: lapack_int, + nrhs: lapack_int, + a: *const lapack_complex_float, + lda: lapack_int, + ipiv: *const lapack_int, + b: *mut lapack_complex_float, + ldb: lapack_int) + -> lapack_int; + + pub fn LAPACKE_csytrs_rook_work(matrix_layout: c_int, + uplo: c_char, + n: lapack_int, + nrhs: lapack_int, + lda: lapack_int, + ipiv: *const lapack_int, + b: *mut lapack_complex_float, + ldb: lapack_int) + -> lapack_int; +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/visual_array.rs b/src/tools/rustfmt/tests/target/configs/indent_style/visual_array.rs new file mode 100644 index 000000000..1da6ff237 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/visual_array.rs @@ -0,0 +1,12 @@ +// rustfmt-indent_style: Visual +// Array layout + +fn main() { + let lorem = vec!["ipsum", + "dolor", + "sit", + "amet", + "consectetur", + "adipiscing", + "elit"]; +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/visual_call.rs b/src/tools/rustfmt/tests/target/configs/indent_style/visual_call.rs new file mode 100644 index 000000000..5454c44ef --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/visual_call.rs @@ -0,0 +1,13 @@ +// rustfmt-indent_style: Visual +// Function call style + +fn main() { + lorem("lorem", + "ipsum", + "dolor", + "sit", + "amet", + "consectetur", + "adipiscing", + "elit"); +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/visual_chain.rs b/src/tools/rustfmt/tests/target/configs/indent_style/visual_chain.rs new file mode 100644 index 000000000..569f3d8b8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/visual_chain.rs @@ -0,0 +1,11 @@ +// rustfmt-indent_style: Visual +// Chain indent + +fn main() { + let lorem = ipsum.dolor() + .sit() + .amet() + .consectetur() + .adipiscing() + .elite(); +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/visual_generics.rs b/src/tools/rustfmt/tests/target/configs/indent_style/visual_generics.rs new file mode 100644 index 000000000..491075a14 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/visual_generics.rs @@ -0,0 +1,20 @@ +// rustfmt-indent_style: Visual +// Generics indent + +fn lorem<Ipsum: Eq = usize, + Dolor: Eq = usize, + Sit: Eq = usize, + Amet: Eq = usize, + Adipiscing: Eq = usize, + Consectetur: Eq = usize, + Elit: Eq = usize>( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + adipiscing: Adipiscing, + consectetur: Consectetur, + elit: Elit) + -> T { + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/visual_struct_lit.rs b/src/tools/rustfmt/tests/target/configs/indent_style/visual_struct_lit.rs new file mode 100644 index 000000000..ec49021d3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/visual_struct_lit.rs @@ -0,0 +1,7 @@ +// rustfmt-indent_style: Visual +// Struct literal-style + +fn main() { + let lorem = Lorem { ipsum: dolor, + sit: amet }; +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/visual_trailing_comma.rs b/src/tools/rustfmt/tests/target/configs/indent_style/visual_trailing_comma.rs new file mode 100644 index 000000000..9738d397d --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/visual_trailing_comma.rs @@ -0,0 +1,7 @@ +// rustfmt-error_on_line_overflow: false +// rustfmt-indent_style: Visual + +// rustfmt should not add trailing comma when rewriting macro. See #1528. +fn a() { + panic!("this is a long string that goes past the maximum line length causing rustfmt to insert a comma here:"); +} diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/visual_where_pred.rs b/src/tools/rustfmt/tests/target/configs/indent_style/visual_where_pred.rs new file mode 100644 index 000000000..45799dcd5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/indent_style/visual_where_pred.rs @@ -0,0 +1,11 @@ +// rustfmt-indent_style: Visual +// Where predicate indent + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T + where Ipsum: Eq, + Dolor: Eq, + Sit: Eq, + Amet: Eq +{ + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/match_arm_blocks/false.rs b/src/tools/rustfmt/tests/target/configs/match_arm_blocks/false.rs new file mode 100644 index 000000000..7a9834168 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/match_arm_blocks/false.rs @@ -0,0 +1,12 @@ +// rustfmt-match_arm_blocks: false +// Wrap match-arms + +fn main() { + match lorem { + true => + foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(x), + false => { + println!("{}", sit) + } + } +} diff --git a/src/tools/rustfmt/tests/target/configs/match_arm_blocks/true.rs b/src/tools/rustfmt/tests/target/configs/match_arm_blocks/true.rs new file mode 100644 index 000000000..eb9e34059 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/match_arm_blocks/true.rs @@ -0,0 +1,13 @@ +// rustfmt-match_arm_blocks: true +// Wrap match-arms + +fn main() { + match lorem { + true => { + foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(x) + } + false => { + println!("{}", sit) + } + } +} diff --git a/src/tools/rustfmt/tests/target/configs/match_arm_leading_pipes/always.rs b/src/tools/rustfmt/tests/target/configs/match_arm_leading_pipes/always.rs new file mode 100644 index 000000000..f2af81eac --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/match_arm_leading_pipes/always.rs @@ -0,0 +1,27 @@ +// rustfmt-match_arm_leading_pipes: Always + +fn foo() { + match foo { + | "foo" | "bar" => {} + | "baz" + | "something relatively long" + | "something really really really realllllllllllllly long" => println!("x"), + | "qux" => println!("y"), + | _ => {} + } +} + +fn issue_3973() { + match foo { + | "foo" | "bar" => {} + | _ => {} + } +} + +fn bar() { + match baz { + | "qux" => {} + | "foo" | "bar" => {} + | _ => {} + } +} diff --git a/src/tools/rustfmt/tests/target/configs/match_arm_leading_pipes/never.rs b/src/tools/rustfmt/tests/target/configs/match_arm_leading_pipes/never.rs new file mode 100644 index 000000000..345014e4b --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/match_arm_leading_pipes/never.rs @@ -0,0 +1,27 @@ +// rustfmt-match_arm_leading_pipes: Never + +fn foo() { + match foo { + "foo" | "bar" => {} + "baz" + | "something relatively long" + | "something really really really realllllllllllllly long" => println!("x"), + "qux" => println!("y"), + _ => {} + } +} + +fn issue_3973() { + match foo { + "foo" | "bar" => {} + _ => {} + } +} + +fn bar() { + match baz { + "qux" => {} + "foo" | "bar" => {} + _ => {} + } +} diff --git a/src/tools/rustfmt/tests/target/configs/match_arm_leading_pipes/preserve.rs b/src/tools/rustfmt/tests/target/configs/match_arm_leading_pipes/preserve.rs new file mode 100644 index 000000000..477557584 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/match_arm_leading_pipes/preserve.rs @@ -0,0 +1,35 @@ +// rustfmt-match_arm_leading_pipes: Preserve + +fn foo() { + match foo { + | "foo" | "bar" => {} + | "baz" + | "something relatively long" + | "something really really really realllllllllllllly long" => println!("x"), + | "qux" => println!("y"), + _ => {} + } +} + +fn issue_3973() { + match foo { + | "foo" | "bar" => {} + _ => {} + } +} + +fn bar() { + match baz { + "qux" => {} + "foo" | "bar" => {} + _ => {} + } +} + +fn f(x: NonAscii) -> bool { + match x { + // foo + | Éfgh => true, + _ => false, + } +} diff --git a/src/tools/rustfmt/tests/target/configs/match_block_trailing_comma/false.rs b/src/tools/rustfmt/tests/target/configs/match_block_trailing_comma/false.rs new file mode 100644 index 000000000..70e02955f --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/match_block_trailing_comma/false.rs @@ -0,0 +1,11 @@ +// rustfmt-match_block_trailing_comma: false +// Match block trailing comma + +fn main() { + match lorem { + Lorem::Ipsum => { + println!("ipsum"); + } + Lorem::Dolor => println!("dolor"), + } +} diff --git a/src/tools/rustfmt/tests/target/configs/match_block_trailing_comma/true.rs b/src/tools/rustfmt/tests/target/configs/match_block_trailing_comma/true.rs new file mode 100644 index 000000000..b78b046dc --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/match_block_trailing_comma/true.rs @@ -0,0 +1,11 @@ +// rustfmt-match_block_trailing_comma: true +// Match block trailing comma + +fn main() { + match lorem { + Lorem::Ipsum => { + println!("ipsum"); + }, + Lorem::Dolor => println!("dolor"), + } +} diff --git a/src/tools/rustfmt/tests/target/configs/merge_derives/true.rs b/src/tools/rustfmt/tests/target/configs/merge_derives/true.rs new file mode 100644 index 000000000..4d0148b1c --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/merge_derives/true.rs @@ -0,0 +1,40 @@ +// rustfmt-merge_derives: true +// Merge multiple derives to a single one. + +#[bar] +#[derive(Eq, PartialEq)] +#[foo] +#[derive(Debug)] +#[foobar] +#[derive(Copy, Clone)] +pub enum Foo {} + +#[derive(Eq, PartialEq, Debug)] +#[foobar] +#[derive(Copy, Clone)] +pub enum Bar {} + +#[derive(Eq, PartialEq, Debug, Copy, Clone)] +pub enum FooBar {} + +mod foo { + #[bar] + #[derive(Eq, PartialEq)] + #[foo] + #[derive(Debug)] + #[foobar] + #[derive(Copy, Clone)] + pub enum Foo {} +} + +mod bar { + #[derive(Eq, PartialEq, Debug)] + #[foobar] + #[derive(Copy, Clone)] + pub enum Bar {} +} + +mod foobar { + #[derive(Eq, PartialEq, Debug, Copy, Clone)] + pub enum FooBar {} +} diff --git a/src/tools/rustfmt/tests/target/configs/normalize_comments/false.rs b/src/tools/rustfmt/tests/target/configs/normalize_comments/false.rs new file mode 100644 index 000000000..488962ed9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/normalize_comments/false.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_comments: false +// Normalize comments + +// Lorem ipsum: +fn dolor() -> usize {} + +/* sit amet: */ +fn adipiscing() -> usize {} + +// #652 +//////////////////////////////////////////////////////////////////////////////// +// Basic slice extension methods +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/tools/rustfmt/tests/target/configs/normalize_comments/true.rs b/src/tools/rustfmt/tests/target/configs/normalize_comments/true.rs new file mode 100644 index 000000000..0bdbe08ab --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/normalize_comments/true.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_comments: true +// Normalize comments + +// Lorem ipsum: +fn dolor() -> usize {} + +// sit amet: +fn adipiscing() -> usize {} + +// #652 +//////////////////////////////////////////////////////////////////////////////// +// Basic slice extension methods +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/tools/rustfmt/tests/target/configs/normalize_doc_attributes/false.rs b/src/tools/rustfmt/tests/target/configs/normalize_doc_attributes/false.rs new file mode 100644 index 000000000..f8eb64273 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/normalize_doc_attributes/false.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_doc_attributes: false +// Normalize doc attributes + +#![doc = " Example documentation"] + +#[doc = " Example item documentation"] +pub enum Foo {} + +#[doc = " Lots of space"] +pub enum Bar {} + +#[doc = "no leading space"] +pub mod FooBar {} diff --git a/src/tools/rustfmt/tests/target/configs/normalize_doc_attributes/true.rs b/src/tools/rustfmt/tests/target/configs/normalize_doc_attributes/true.rs new file mode 100644 index 000000000..fadab985b --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/normalize_doc_attributes/true.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_doc_attributes: true +// Normalize doc attributes + +//! Example documentation + +/// Example item documentation +pub enum Foo {} + +/// Lots of space +pub enum Bar {} + +///no leading space +pub mod FooBar {} diff --git a/src/tools/rustfmt/tests/target/configs/remove_nested_parens/remove_nested_parens.rs b/src/tools/rustfmt/tests/target/configs/remove_nested_parens/remove_nested_parens.rs new file mode 100644 index 000000000..d896042c3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/remove_nested_parens/remove_nested_parens.rs @@ -0,0 +1,5 @@ +// rustfmt-remove_nested_parens: true + +fn main() { + (foo()); +} diff --git a/src/tools/rustfmt/tests/target/configs/reorder_impl_items/false.rs b/src/tools/rustfmt/tests/target/configs/reorder_impl_items/false.rs new file mode 100644 index 000000000..beb99f0fb --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_impl_items/false.rs @@ -0,0 +1,11 @@ +// rustfmt-reorder_impl_items: false + +struct Dummy; + +impl Iterator for Dummy { + fn next(&mut self) -> Option<Self::Item> { + None + } + + type Item = i32; +} diff --git a/src/tools/rustfmt/tests/target/configs/reorder_impl_items/true.rs b/src/tools/rustfmt/tests/target/configs/reorder_impl_items/true.rs new file mode 100644 index 000000000..f2294412a --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_impl_items/true.rs @@ -0,0 +1,11 @@ +// rustfmt-reorder_impl_items: true + +struct Dummy; + +impl Iterator for Dummy { + type Item = i32; + + fn next(&mut self) -> Option<Self::Item> { + None + } +} diff --git a/src/tools/rustfmt/tests/target/configs/reorder_imports/false.rs b/src/tools/rustfmt/tests/target/configs/reorder_imports/false.rs new file mode 100644 index 000000000..4b85684dc --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_imports/false.rs @@ -0,0 +1,7 @@ +// rustfmt-reorder_imports: false +// Reorder imports + +use lorem; +use ipsum; +use dolor; +use sit; diff --git a/src/tools/rustfmt/tests/target/configs/reorder_imports/true.rs b/src/tools/rustfmt/tests/target/configs/reorder_imports/true.rs new file mode 100644 index 000000000..e4ff7295f --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_imports/true.rs @@ -0,0 +1,19 @@ +// rustfmt-reorder_imports: true +// Reorder imports + +use dolor; +use ipsum; +use lorem; +use sit; + +fn foo() { + use A; + use B; + use C; + + bar(); + + use D; + use E; + use F; +} diff --git a/src/tools/rustfmt/tests/target/configs/reorder_modules/dolor/mod.rs b/src/tools/rustfmt/tests/target/configs/reorder_modules/dolor/mod.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_modules/dolor/mod.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/target/configs/reorder_modules/false.rs b/src/tools/rustfmt/tests/target/configs/reorder_modules/false.rs new file mode 100644 index 000000000..56b1aa03e --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_modules/false.rs @@ -0,0 +1,7 @@ +// rustfmt-reorder_modules: false +// Reorder modules + +mod lorem; +mod ipsum; +mod dolor; +mod sit; diff --git a/src/tools/rustfmt/tests/target/configs/reorder_modules/ipsum/mod.rs b/src/tools/rustfmt/tests/target/configs/reorder_modules/ipsum/mod.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_modules/ipsum/mod.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/target/configs/reorder_modules/lorem/mod.rs b/src/tools/rustfmt/tests/target/configs/reorder_modules/lorem/mod.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_modules/lorem/mod.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/target/configs/reorder_modules/sit/mod.rs b/src/tools/rustfmt/tests/target/configs/reorder_modules/sit/mod.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_modules/sit/mod.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/target/configs/reorder_modules/true.rs b/src/tools/rustfmt/tests/target/configs/reorder_modules/true.rs new file mode 100644 index 000000000..18361e88b --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/reorder_modules/true.rs @@ -0,0 +1,7 @@ +// rustfmt-reorder_modules: true +// Reorder modules + +mod dolor; +mod ipsum; +mod lorem; +mod sit; diff --git a/src/tools/rustfmt/tests/target/configs/short_array_element_width_threshold/10.rs b/src/tools/rustfmt/tests/target/configs/short_array_element_width_threshold/10.rs new file mode 100644 index 000000000..78c4adba1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/short_array_element_width_threshold/10.rs @@ -0,0 +1,11 @@ +// rustfmt-short_array_element_width_threshold: 10 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} diff --git a/src/tools/rustfmt/tests/target/configs/short_array_element_width_threshold/20.rs b/src/tools/rustfmt/tests/target/configs/short_array_element_width_threshold/20.rs new file mode 100644 index 000000000..608469065 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/short_array_element_width_threshold/20.rs @@ -0,0 +1,8 @@ +// rustfmt-short_array_element_width_threshold: 20 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, 0xaaaaaaaaaaaaaaaa, 0xbbbbbbbbbbbbbbbb, 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} diff --git a/src/tools/rustfmt/tests/target/configs/short_array_element_width_threshold/greater_than_max_width.rs b/src/tools/rustfmt/tests/target/configs/short_array_element_width_threshold/greater_than_max_width.rs new file mode 100644 index 000000000..710b6fe7c --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/short_array_element_width_threshold/greater_than_max_width.rs @@ -0,0 +1,12 @@ +// rustfmt-max_width: 20 +// rustfmt-short_array_element_width_threshold: 30 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} diff --git a/src/tools/rustfmt/tests/target/configs/skip_children/foo/mod.rs b/src/tools/rustfmt/tests/target/configs/skip_children/foo/mod.rs new file mode 100644 index 000000000..d7ff6cdb8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/skip_children/foo/mod.rs @@ -0,0 +1,3 @@ +fn skip_formatting_this() { + println ! ( "Skip this" ) ; +} diff --git a/src/tools/rustfmt/tests/target/configs/skip_children/true.rs b/src/tools/rustfmt/tests/target/configs/skip_children/true.rs new file mode 100644 index 000000000..33fd782b4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/skip_children/true.rs @@ -0,0 +1,4 @@ +// rustfmt-skip_children: true + +mod foo; +mod void; diff --git a/src/tools/rustfmt/tests/target/configs/space_before_colon/true.rs b/src/tools/rustfmt/tests/target/configs/space_before_colon/true.rs new file mode 100644 index 000000000..e2895b5d7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/space_before_colon/true.rs @@ -0,0 +1,11 @@ +// rustfmt-space_before_colon: true +// Space before colon + +fn lorem<T : Eq>(t : T) { + let ipsum : Dolor = sit; +} + +const LOREM : Lorem = Lorem { + ipsum : dolor, + sit : amet, +}; diff --git a/src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs b/src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs new file mode 100644 index 000000000..72b1be480 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs @@ -0,0 +1,34 @@ +// rustfmt-spaces_around_ranges: false +// Spaces around ranges + +fn main() { + let lorem = 0..10; + let ipsum = 0..=10; + + match lorem { + 1..5 => foo(), + _ => bar, + } + + match lorem { + 1..=5 => foo(), + _ => bar, + } + + match lorem { + 1...5 => foo(), + _ => bar, + } +} + +fn half_open() { + match [5..4, 99..105, 43..44] { + [_, 99.., _] => {} + [_, ..105, _] => {} + _ => {} + }; + + if let ..=5 = 0 {} + if let ..5 = 0 {} + if let 5.. = 0 {} +} diff --git a/src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs b/src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs new file mode 100644 index 000000000..c56fdbb02 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs @@ -0,0 +1,34 @@ +// rustfmt-spaces_around_ranges: true +// Spaces around ranges + +fn main() { + let lorem = 0 .. 10; + let ipsum = 0 ..= 10; + + match lorem { + 1 .. 5 => foo(), + _ => bar, + } + + match lorem { + 1 ..= 5 => foo(), + _ => bar, + } + + match lorem { + 1 ... 5 => foo(), + _ => bar, + } +} + +fn half_open() { + match [5 .. 4, 99 .. 105, 43 .. 44] { + [_, 99 .., _] => {} + [_, .. 105, _] => {} + _ => {} + }; + + if let ..= 5 = 0 {} + if let .. 5 = 0 {} + if let 5 .. = 0 {} +} diff --git a/src/tools/rustfmt/tests/target/configs/struct_field_align_threshold/20.rs b/src/tools/rustfmt/tests/target/configs/struct_field_align_threshold/20.rs new file mode 100644 index 000000000..12a523e9d --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/struct_field_align_threshold/20.rs @@ -0,0 +1,471 @@ +// rustfmt-struct_field_align_threshold: 20 +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-error_on_line_overflow: false + +struct Foo { + x: u32, + yy: u32, // comment + zzz: u32, +} + +pub struct Bar { + x: u32, + yy: u32, + zzz: u32, + + xxxxxxx: u32, +} + +fn main() { + let foo = Foo { + x: 0, + yy: 1, + zzz: 2, + }; + + let bar = Bar { + x: 0, + yy: 1, + zzz: 2, + + xxxxxxx: 3, + }; +} + +/// A Doc comment +#[AnAttribute] +pub struct Foo { + #[rustfmt::skip] + f : SomeType, // Comment beside a field + f: SomeType, // Comment beside a field + // Comment on a field + #[AnAttribute] + g: SomeOtherType, + /// A doc comment on a field + h: AThirdType, + pub i: TypeForPublicField, +} + +// #1029 +pub struct Foo { + #[doc(hidden)] + // This will NOT get deleted! + bar: String, // hi +} + +// #1029 +struct X { + // `x` is an important number. + #[allow(unused)] // TODO: use + x: u32, +} + +// #410 +#[allow(missing_docs)] +pub struct Writebatch<K: Key> { + #[allow(dead_code)] // only used for holding the internal pointer + writebatch: RawWritebatch, + marker: PhantomData<K>, +} + +struct Bar; + +struct NewType(Type, OtherType); + +struct NewInt<T: Copy>( + pub i32, + SomeType, // inline comment + T, // sup +); + +struct Qux< + 'a, + N: Clone + 'a, + E: Clone + 'a, + G: Labeller<'a, N, E> + GraphWalk<'a, N, E>, + W: Write + Copy, +>( + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // Comment + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, + #[AnAttr] + // Comment + /// Testdoc + G, + pub W, +); + +struct Tuple( + // Comment 1 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + // Comment 2 + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, +); + +// With a where-clause and generics. +pub struct Foo<'a, Y: Baz> +where + X: Whatever, +{ + f: SomeType, // Comment beside a field +} + +struct Baz { + a: A, // Comment A + b: B, // Comment B + c: C, // Comment C +} + +struct Baz { + a: A, // Comment A + + b: B, // Comment B + + c: C, // Comment C +} + +struct Baz { + a: A, + + b: B, + c: C, + + d: D, +} + +struct Baz { + // Comment A + a: A, + + // Comment B + b: B, + // Comment C + c: C, +} + +// Will this be a one-liner? +struct Tuple( + A, // Comment + B, +); + +pub struct State<F: FnMut() -> time::Timespec> { + now: F, +} + +pub struct State<F: FnMut() -> ()> { + now: F, +} + +pub struct State<F: FnMut()> { + now: F, +} + +struct Palette { + /// A map of indices in the palette to a count of pixels in approximately + /// that color + foo: i32, +} + +// Splitting a single line comment into a block previously had a misalignment +// when the field had attributes +struct FieldsWithAttributes { + // Pre Comment + #[rustfmt::skip] pub host:String, /* Post comment BBBBBBBBBBBBBB BBBBBBBBBBBBBBBB + * BBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBB BBBBBBBBBBB */ + // Another pre comment + #[attr1] + #[attr2] + pub id: usize, /* CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCC + * CCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCC CCCCCCCCCCCC */ +} + +struct Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: + node::Handle<IdRef<'id, Node<K, V>>, Type, NodeType>, +} + +struct Foo<T>(T); +struct Foo<T>(T) +where + T: Copy, + T: Eq; +struct Foo<T>( + TTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUUUU, + TTTTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUU, +); +struct Foo<T>( + TTTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUUUU, + TTTTTTTTTTTTTTTTTTT, +) +where + T: PartialEq; +struct Foo<T>( + TTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUUUU, + TTTTTTTTTTTTTTTTTTTTT, +) +where + T: PartialEq; +struct Foo<T>( + TTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUUUU, + TTTTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUU, +) +where + T: PartialEq; +struct Foo<T>( + TTTTTTTTTTTTTTTTT, // Foo + UUUUUUUUUUUUUUUUUUUUUUUU, // Bar + // Baz + TTTTTTTTTTTTTTTTTTT, + // Qux (FIXME #572 - doc comment) + UUUUUUUUUUUUUUUUUUU, +); + +mod m { + struct X<T> + where + T: Sized, + { + a: T, + } +} + +struct Foo<T>( + TTTTTTTTTTTTTTTTTTT, + /// Qux + UUUUUUUUUUUUUUUUUUU, +); + +struct Issue677 { + pub ptr: *const libc::c_void, + pub trace: fn(obj: *const libc::c_void, tracer: *mut JSTracer), +} + +struct Foo {} +struct Foo {} +struct Foo { + // comment +} +struct Foo { + // trailing space -> +} +struct Foo { + // comment +} +struct Foo( + // comment +); + +struct LongStruct { + a: A, + the_quick_brown_fox_jumps_over_the_lazy_dog: + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +} + +struct Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: + node::Handle<IdRef<'id, Node<Key, Value>>, Type, NodeType>, +} + +struct Foo<C = ()>(String); + +// #1364 +fn foo() { + convex_shape.set_point(0, &Vector2f { x: 400.0, y: 100.0 }); + convex_shape.set_point(1, &Vector2f { x: 500.0, y: 70.0 }); + convex_shape.set_point(2, &Vector2f { x: 450.0, y: 100.0 }); + convex_shape.set_point(3, &Vector2f { x: 580.0, y: 150.0 }); +} + +fn main() { + let x = Bar; + + // Comment + let y = Foo { a: x }; + + Foo { + a: foo(), // comment + // comment + b: bar(), + ..something + }; + + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: f(), b: b() }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + a: f(), + b: b(), + }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + // Comment + a: foo(), // Comment + // Comment + b: bar(), // Comment + }; + + Foo { a: Bar, b: f() }; + + Quux { + x: if cond { + bar(); + }, + y: baz(), + }; + + A { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit + // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante + // hendrerit. Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item, + }; + + Some(Data::MethodCallData(MethodCallData { + span: sub_span.unwrap(), + scope: self.enclosing_scope(id), + ref_id: def_id, + decl_id: Some(decl_id), + })); + + Diagram { + // o This graph demonstrates how + // / \ significant whitespace is + // o o preserved. + // /|\ \ + // o o o o + graph: G, + } +} + +fn matcher() { + TagTerminatedByteMatcher { + matcher: ByteMatcher { + pattern: b"<HTML", + mask: b"\xFF\xDF\xDF\xDF\xDF\xFF", + }, + }; +} + +fn issue177() { + struct Foo<T> { + memb: T, + } + let foo = Foo::<i64> { memb: 10 }; +} + +fn issue201() { + let s = S { a: 0, ..b }; +} + +fn issue201_2() { + let s = S { a: S2 { ..c }, ..b }; +} + +fn issue278() { + let s = S { + a: 0, + // + b: 0, + }; + let s1 = S { + a: 0, + // foo + // + // bar + b: 0, + }; +} + +fn struct_exprs() { + Foo { a: 1, b: f(2) }; + Foo { + a: 1, + b: f(2), + ..g(3) + }; + LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongStruct { + ..base + }; + IntrinsicISizesContribution { + content_intrinsic_sizes: IntrinsicISizes { + minimum_inline_size: 0, + }, + }; +} + +fn issue123() { + Foo { a: b, c: d, e: f }; + + Foo { + a: bb, + c: dd, + e: ff, + }; + + Foo { + a: ddddddddddddddddddddd, + b: cccccccccccccccccccccccccccccccccccccc, + }; +} + +fn issue491() { + Foo { + guard: None, + arm: 0, // Comment + }; + + Foo { + arm: 0, // Comment + }; + + Foo { + a: aaaaaaaaaa, + b: bbbbbbbb, + c: cccccccccc, + d: dddddddddd, // a comment + e: eeeeeeeee, + }; +} + +fn issue698() { + Record { + ffffffffffffffffffffffffffields: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + }; + Record { + ffffffffffffffffffffffffffields: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + } +} + +fn issue835() { + MyStruct {}; + MyStruct { /* a comment */ }; + MyStruct { + // Another comment + }; + MyStruct {} +} + +fn field_init_shorthand() { + MyStruct { x, y, z }; + MyStruct { x, y, z, ..base }; + Foo { + aaaaaaaaaa, + bbbbbbbb, + cccccccccc, + dddddddddd, // a comment + eeeeeeeee, + }; + Record { + ffffffffffffffffffffffffffieldsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + }; +} diff --git a/src/tools/rustfmt/tests/target/configs/struct_lit_single_line/false.rs b/src/tools/rustfmt/tests/target/configs/struct_lit_single_line/false.rs new file mode 100644 index 000000000..e2732b5a7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/struct_lit_single_line/false.rs @@ -0,0 +1,9 @@ +// rustfmt-struct_lit_single_line: false +// Struct literal multiline-style + +fn main() { + let lorem = Lorem { + ipsum: dolor, + sit: amet, + }; +} diff --git a/src/tools/rustfmt/tests/target/configs/tab_spaces/2.rs b/src/tools/rustfmt/tests/target/configs/tab_spaces/2.rs new file mode 100644 index 000000000..85961706e --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/tab_spaces/2.rs @@ -0,0 +1,14 @@ +// rustfmt-tab_spaces: 2 +// rustfmt-max_width: 30 +// rustfmt-indent_style: Block +// Tab spaces + +fn lorem() { + let ipsum = dolor(); + let sit = vec![ + "amet", + "consectetur", + "adipiscing", + "elit.", + ]; +} diff --git a/src/tools/rustfmt/tests/target/configs/tab_spaces/4.rs b/src/tools/rustfmt/tests/target/configs/tab_spaces/4.rs new file mode 100644 index 000000000..524a55121 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/tab_spaces/4.rs @@ -0,0 +1,14 @@ +// rustfmt-tab_spaces: 4 +// rustfmt-max_width: 30 +// rustfmt-indent_style: Block +// Tab spaces + +fn lorem() { + let ipsum = dolor(); + let sit = vec![ + "amet", + "consectetur", + "adipiscing", + "elit.", + ]; +} diff --git a/src/tools/rustfmt/tests/target/configs/trailing_comma/always.rs b/src/tools/rustfmt/tests/target/configs/trailing_comma/always.rs new file mode 100644 index 000000000..951dc6809 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/trailing_comma/always.rs @@ -0,0 +1,14 @@ +// rustfmt-trailing_comma: Always +// Trailing comma + +fn main() { + let Lorem { ipsum, dolor, sit, } = amet; + let Lorem { + ipsum, + dolor, + sit, + amet, + consectetur, + adipiscing, + } = elit; +} diff --git a/src/tools/rustfmt/tests/target/configs/trailing_comma/never.rs b/src/tools/rustfmt/tests/target/configs/trailing_comma/never.rs new file mode 100644 index 000000000..ae0e50f96 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/trailing_comma/never.rs @@ -0,0 +1,35 @@ +// rustfmt-trailing_comma: Never +// Trailing comma + +fn main() { + let Lorem { ipsum, dolor, sit } = amet; + let Lorem { + ipsum, + dolor, + sit, + amet, + consectetur, + adipiscing + } = elit; + + // #1544 + if let VrMsg::ClientReply { + request_num: reply_req_num, + value, + .. + } = msg + { + let _ = safe_assert_eq!(reply_req_num, request_num, op); + return Ok((request_num, op, value)); + } + + // #1710 + pub struct FileInput { + input: StringInput, + file_name: OsString + } + match len { + Some(len) => Ok(new(self.input, self.pos + len)), + None => Err(self) + } +} diff --git a/src/tools/rustfmt/tests/target/configs/trailing_comma/vertical.rs b/src/tools/rustfmt/tests/target/configs/trailing_comma/vertical.rs new file mode 100644 index 000000000..7283cde8d --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/trailing_comma/vertical.rs @@ -0,0 +1,14 @@ +// rustfmt-trailing_comma: Vertical +// Trailing comma + +fn main() { + let Lorem { ipsum, dolor, sit } = amet; + let Lorem { + ipsum, + dolor, + sit, + amet, + consectetur, + adipiscing, + } = elit; +} diff --git a/src/tools/rustfmt/tests/target/configs/trailing_semicolon/false.rs b/src/tools/rustfmt/tests/target/configs/trailing_semicolon/false.rs new file mode 100644 index 000000000..9fa746e9c --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/trailing_semicolon/false.rs @@ -0,0 +1,27 @@ +// rustfmt-trailing_semicolon: false + +#![feature(loop_break_value)] + +fn main() { + 'a: loop { + break 'a + } + + let mut done = false; + 'b: while !done { + done = true; + continue 'b + } + + let x = loop { + break 5 + }; + + let x = 'c: loop { + break 'c 5 + }; +} + +fn foo() -> usize { + return 0 +} diff --git a/src/tools/rustfmt/tests/target/configs/trailing_semicolon/true.rs b/src/tools/rustfmt/tests/target/configs/trailing_semicolon/true.rs new file mode 100644 index 000000000..61b6843d6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/trailing_semicolon/true.rs @@ -0,0 +1,27 @@ +// rustfmt-trailing_semicolon: true + +#![feature(loop_break_value)] + +fn main() { + 'a: loop { + break 'a; + } + + let mut done = false; + 'b: while !done { + done = true; + continue 'b; + } + + let x = loop { + break 5; + }; + + let x = 'c: loop { + break 'c 5; + }; +} + +fn foo() -> usize { + return 0; +} diff --git a/src/tools/rustfmt/tests/target/configs/type_punctuation_density/compressed.rs b/src/tools/rustfmt/tests/target/configs/type_punctuation_density/compressed.rs new file mode 100644 index 000000000..6571e448e --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/type_punctuation_density/compressed.rs @@ -0,0 +1,41 @@ +// rustfmt-type_punctuation_density: Compressed +// Type punctuation density + +fn lorem<Ipsum: Dolor+Sit=Amet>() { + // body +} + +struct Foo<T: Eq+Clone, U> +where + U: Eq+Clone, { + // body +} + +trait Foo<'a, T=usize> +where + T: 'a+Eq+Clone, +{ + type Bar: Eq+Clone; +} + +trait Foo: Eq+Clone { + // body +} + +impl<T> Foo<'a> for Bar +where + for<'a> T: 'a+Eq+Clone, +{ + // body +} + +fn foo<'a, 'b, 'c>() +where + 'a: 'b+'c, +{ + // body +} + +fn Foo<T=Foo, Output=Expr<'tcx>+Foo>() { + let i = 6; +} diff --git a/src/tools/rustfmt/tests/target/configs/type_punctuation_density/wide.rs b/src/tools/rustfmt/tests/target/configs/type_punctuation_density/wide.rs new file mode 100644 index 000000000..01546c7b0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/type_punctuation_density/wide.rs @@ -0,0 +1,41 @@ +// rustfmt-type_punctuation_density: Wide +// Type punctuation density + +fn lorem<Ipsum: Dolor + Sit = Amet>() { + // body +} + +struct Foo<T: Eq + Clone, U> +where + U: Eq + Clone, { + // body +} + +trait Foo<'a, T = usize> +where + T: 'a + Eq + Clone, +{ + type Bar: Eq + Clone; +} + +trait Foo: Eq + Clone { + // body +} + +impl<T> Foo<'a> for Bar +where + for<'a> T: 'a + Eq + Clone, +{ + // body +} + +fn foo<'a, 'b, 'c>() +where + 'a: 'b + 'c, +{ + // body +} + +fn Foo<T = Foo, Output = Expr<'tcx> + Foo>() { + let i = 6; +} diff --git a/src/tools/rustfmt/tests/target/configs/use_field_init_shorthand/false.rs b/src/tools/rustfmt/tests/target/configs/use_field_init_shorthand/false.rs new file mode 100644 index 000000000..743304468 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/use_field_init_shorthand/false.rs @@ -0,0 +1,15 @@ +// rustfmt-use_field_init_shorthand: false +// Use field initialization shorthand if possible. + +fn main() { + let a = Foo { x: x, y: y, z: z }; + + let b = Bar { + x: x, + y: y, + #[attr] + z: z, + #[rustfmt::skip] + skipped: skipped, + }; +} diff --git a/src/tools/rustfmt/tests/target/configs/use_field_init_shorthand/true.rs b/src/tools/rustfmt/tests/target/configs/use_field_init_shorthand/true.rs new file mode 100644 index 000000000..8b80e8153 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/use_field_init_shorthand/true.rs @@ -0,0 +1,15 @@ +// rustfmt-use_field_init_shorthand: true +// Use field initialization shorthand if possible. + +fn main() { + let a = Foo { x, y, z }; + + let b = Bar { + x, + y, + #[attr] + z, + #[rustfmt::skip] + skipped: skipped, + }; +} diff --git a/src/tools/rustfmt/tests/target/configs/use_small_heuristics/default.rs b/src/tools/rustfmt/tests/target/configs/use_small_heuristics/default.rs new file mode 100644 index 000000000..d67bd9aaf --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/use_small_heuristics/default.rs @@ -0,0 +1,26 @@ +// rustfmt-use_small_heuristics: Default + +enum Lorem { + Ipsum, + Dolor(bool), + Sit { amet: Consectetur, adipiscing: Elit }, +} + +fn main() { + lorem( + "lorem", + "ipsum", + "dolor", + "sit", + "amet", + "consectetur", + "adipiscing", + ); + + let lorem = Lorem { + ipsum: dolor, + sit: amet, + }; + + let lorem = if ipsum { dolor } else { sit }; +} diff --git a/src/tools/rustfmt/tests/target/configs/use_small_heuristics/max.rs b/src/tools/rustfmt/tests/target/configs/use_small_heuristics/max.rs new file mode 100644 index 000000000..785dfbea0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/use_small_heuristics/max.rs @@ -0,0 +1,15 @@ +// rustfmt-use_small_heuristics: Max + +enum Lorem { + Ipsum, + Dolor(bool), + Sit { amet: Consectetur, adipiscing: Elit }, +} + +fn main() { + lorem("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing"); + + let lorem = Lorem { ipsum: dolor, sit: amet }; + + let lorem = if ipsum { dolor } else { sit }; +} diff --git a/src/tools/rustfmt/tests/target/configs/use_small_heuristics/off.rs b/src/tools/rustfmt/tests/target/configs/use_small_heuristics/off.rs new file mode 100644 index 000000000..f76392d24 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/use_small_heuristics/off.rs @@ -0,0 +1,25 @@ +// rustfmt-use_small_heuristics: Off + +enum Lorem { + Ipsum, + Dolor(bool), + Sit { + amet: Consectetur, + adipiscing: Elit, + }, +} + +fn main() { + lorem("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing"); + + let lorem = Lorem { + ipsum: dolor, + sit: amet, + }; + + let lorem = if ipsum { + dolor + } else { + sit + }; +} diff --git a/src/tools/rustfmt/tests/target/configs/use_try_shorthand/false.rs b/src/tools/rustfmt/tests/target/configs/use_try_shorthand/false.rs new file mode 100644 index 000000000..de7f8b4a5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/use_try_shorthand/false.rs @@ -0,0 +1,6 @@ +// rustfmt-use_try_shorthand: false +// Use try! shorthand + +fn main() { + let lorem = try!(ipsum.map(|dolor| dolor.sit())); +} diff --git a/src/tools/rustfmt/tests/target/configs/use_try_shorthand/true.rs b/src/tools/rustfmt/tests/target/configs/use_try_shorthand/true.rs new file mode 100644 index 000000000..d3aa03579 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/use_try_shorthand/true.rs @@ -0,0 +1,6 @@ +// rustfmt-use_try_shorthand: true +// Use try! shorthand + +fn main() { + let lorem = ipsum.map(|dolor| dolor.sit())?; +} diff --git a/src/tools/rustfmt/tests/target/configs/where_single_line/true-with-brace-style.rs b/src/tools/rustfmt/tests/target/configs/where_single_line/true-with-brace-style.rs new file mode 100644 index 000000000..ec7f79b68 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/where_single_line/true-with-brace-style.rs @@ -0,0 +1,22 @@ +// rustfmt-brace_style: SameLineWhere +// rustfmt-where_single_line: true + +fn lorem_multi_line_clauseless<Ipsum, Dolor, Sit, Amet>( + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee, +) -> T { + // body +} + +fn lorem_multi_line_clauseless<Ipsum, Dolor, Sit, Amet>( + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee, +) { + // body +} diff --git a/src/tools/rustfmt/tests/target/configs/where_single_line/true.rs b/src/tools/rustfmt/tests/target/configs/where_single_line/true.rs new file mode 100644 index 000000000..7f816459e --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/where_single_line/true.rs @@ -0,0 +1,30 @@ +// rustfmt-where_single_line: true +// Where style + +fn lorem_two_items<Ipsum, Dolor, Sit, Amet>() -> T +where + Ipsum: Eq, + Lorem: Eq, +{ + // body +} + +fn lorem_multi_line<Ipsum, Dolor, Sit, Amet>( + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee, +) -> T +where + Ipsum: Eq, +{ + // body +} + +fn lorem<Ipsum, Dolor, Sit, Amet>() -> T +where Ipsum: Eq { + // body +} + +unsafe impl Sync for Foo where (): Send {} diff --git a/src/tools/rustfmt/tests/target/configs/wrap_comments/false.rs b/src/tools/rustfmt/tests/target/configs/wrap_comments/false.rs new file mode 100644 index 000000000..48ecd88ac --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/wrap_comments/false.rs @@ -0,0 +1,8 @@ +// rustfmt-wrap_comments: false +// rustfmt-max_width: 50 +// rustfmt-error_on_line_overflow: false +// Wrap comments + +fn main() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +} diff --git a/src/tools/rustfmt/tests/target/configs/wrap_comments/true.rs b/src/tools/rustfmt/tests/target/configs/wrap_comments/true.rs new file mode 100644 index 000000000..4096fd4d8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/configs/wrap_comments/true.rs @@ -0,0 +1,20 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 50 +// Wrap comments + +fn main() { + // Lorem ipsum dolor sit amet, consectetur + // adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna + // aliqua. Ut enim ad minim veniam, quis + // nostrud exercitation ullamco laboris nisi + // ut aliquip ex ea commodo consequat. +} + +fn code_block() { + // ```rust + // let x = 3; + // + // println!("x = {}", x); + // ``` +} diff --git a/src/tools/rustfmt/tests/target/const_generics.rs b/src/tools/rustfmt/tests/target/const_generics.rs new file mode 100644 index 000000000..b30b7b58c --- /dev/null +++ b/src/tools/rustfmt/tests/target/const_generics.rs @@ -0,0 +1,37 @@ +struct Message { + field2: Vec<"MessageEntity">, + field3: Vec<1>, + field4: Vec<2, 3>, +} + +struct RectangularArray<T, const WIDTH: usize, const HEIGHT: usize> { + array: [[T; WIDTH]; HEIGHT], +} + +fn main() { + const X: usize = 7; + let x: RectangularArray<i32, 2, 4>; + let y: RectangularArray<i32, X, { 2 * 2 }>; +} + +fn foo<const X: usize>() { + const Y: usize = X * 2; + static Z: (usize, usize) = (X, X); + + struct Foo([i32; X]); +} + +type Foo<const N: usize> = [i32; N + 1]; + +pub trait Foo: Bar<{ Baz::COUNT }> { + const ASD: usize; +} + +// #4263 +fn const_generics_on_params< + // AAAA + const BBBB: usize, + /* CCCC */ + const DDDD: usize, +>() { +} diff --git a/src/tools/rustfmt/tests/target/control-brace-style-always-next-line.rs b/src/tools/rustfmt/tests/target/control-brace-style-always-next-line.rs new file mode 100644 index 000000000..054a3075c --- /dev/null +++ b/src/tools/rustfmt/tests/target/control-brace-style-always-next-line.rs @@ -0,0 +1,50 @@ +// rustfmt-control_brace_style: AlwaysNextLine + +fn main() { + loop + { + (); + (); + } + + 'label: loop + // loop comment + { + (); + } + + cond = true; + while cond + { + (); + } + + 'while_label: while cond + { + // while comment + (); + } + + for obj in iter + { + for sub_obj in obj + { + 'nested_while_label: while cond + { + (); + } + } + } + + match some_var + { + // match comment + pattern0 => val0, + pattern1 => val1, + pattern2 | pattern3 => + { + do_stuff(); + val2 + } + }; +} diff --git a/src/tools/rustfmt/tests/target/control-brace-style-always-same-line.rs b/src/tools/rustfmt/tests/target/control-brace-style-always-same-line.rs new file mode 100644 index 000000000..cf3f82dfc --- /dev/null +++ b/src/tools/rustfmt/tests/target/control-brace-style-always-same-line.rs @@ -0,0 +1,40 @@ +fn main() { + loop { + (); + (); + } + + 'label: loop + // loop comment + { + (); + } + + cond = true; + while cond { + (); + } + + 'while_label: while cond { + // while comment + (); + } + + for obj in iter { + for sub_obj in obj { + 'nested_while_label: while cond { + (); + } + } + } + + match some_var { + // match comment + pattern0 => val0, + pattern1 => val1, + pattern2 | pattern3 => { + do_stuff(); + val2 + } + }; +} diff --git a/src/tools/rustfmt/tests/target/doc-attrib.rs b/src/tools/rustfmt/tests/target/doc-attrib.rs new file mode 100644 index 000000000..36527b7cd --- /dev/null +++ b/src/tools/rustfmt/tests/target/doc-attrib.rs @@ -0,0 +1,131 @@ +// rustfmt-wrap_comments: true +// rustfmt-normalize_doc_attributes: true + +// Only doc = "" attributes should be normalized +//! Example doc attribute comment +//! Example doc attribute comment with 10 leading spaces +#![doc( + html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", + test(attr(deny(warnings))) +)] + +// Long `#[doc = "..."]` +struct A { + /// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + b: i32, +} + +/// The `nodes` and `edges` method each return instantiations of `Cow<[T]>` to +/// leave implementers the freedom to create entirely new vectors or to pass +/// back slices into internally owned vectors. +struct B { + b: i32, +} + +/// Level 1 comment +mod tests { + /// Level 2 comment + impl A { + /// Level 3 comment + fn f() { + /// Level 4 comment + fn g() {} + } + } +} + +struct C { + /// item doc attrib comment + // regular item comment + b: i32, + + // regular item comment + /// item doc attrib comment + c: i32, +} + +// non-regression test for regular attributes, from #2647 +#[cfg( + feature = "this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +)] +pub fn foo() {} + +// path attrs +#[clippy::bar] +#[clippy::bar(a, b, c)] +pub fn foo() {} + +mod issue_2620 { + #[derive(Debug, StructOpt)] + #[structopt(about = "Display information about the character on FF Logs")] + pub struct Params { + #[structopt(help = "The server the character is on")] + server: String, + #[structopt(help = "The character's first name")] + first_name: String, + #[structopt(help = "The character's last name")] + last_name: String, + #[structopt( + short = "j", + long = "job", + help = "The job to look at", + parse(try_from_str) + )] + job: Option<Job>, + } +} + +// non-regression test for regular attributes, from #2969 +#[cfg(not(all( + feature = "std", + any( + target_os = "linux", + target_os = "android", + target_os = "netbsd", + target_os = "dragonfly", + target_os = "haiku", + target_os = "emscripten", + target_os = "solaris", + target_os = "cloudabi", + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "redox", + target_os = "fuchsia", + windows, + all(target_arch = "wasm32", feature = "stdweb"), + all(target_arch = "wasm32", feature = "wasm-bindgen"), + ) +)))] +type Os = NoSource; + +// use cases from bindgen needing precise control over leading spaces +/// <div rustbindgen accessor></div> +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct ContradictAccessors { + ///<foo>no leading spaces here</foo> + pub mBothAccessors: ::std::os::raw::c_int, + /// <div rustbindgen accessor="false"></div> + pub mNoAccessors: ::std::os::raw::c_int, + /// <div rustbindgen accessor="unsafe"></div> + pub mUnsafeAccessors: ::std::os::raw::c_int, + /// <div rustbindgen accessor="immutable"></div> + pub mImmutableAccessor: ::std::os::raw::c_int, +} + +/// \brief MPI structure +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct mbedtls_mpi { + ///< integer sign + pub s: ::std::os::raw::c_int, + ///< total # of limbs + pub n: ::std::os::raw::c_ulong, + ///< pointer to limbs + pub p: *mut mbedtls_mpi_uint, +} diff --git a/src/tools/rustfmt/tests/target/doc-comment-with-example.rs b/src/tools/rustfmt/tests/target/doc-comment-with-example.rs new file mode 100644 index 000000000..c5a4e779e --- /dev/null +++ b/src/tools/rustfmt/tests/target/doc-comment-with-example.rs @@ -0,0 +1,11 @@ +// rustfmt-format_code_in_doc_comments: true + +/// Foo +/// +/// # Example +/// ``` +/// # #![cfg_attr(not(dox), feature(cfg_target_feature, target_feature, stdsimd))] +/// # #![cfg_attr(not(dox), no_std)] +/// fn foo() {} +/// ``` +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/doc-of-generic-item.rs b/src/tools/rustfmt/tests/target/doc-of-generic-item.rs new file mode 100644 index 000000000..2efc5e09a --- /dev/null +++ b/src/tools/rustfmt/tests/target/doc-of-generic-item.rs @@ -0,0 +1,14 @@ +// Non-doc pre-comment of Foo +/// doc of Foo +// Non-doc post-comment of Foo +struct Foo< + // Non-doc pre-comment of 'a + /// doc of 'a + 'a, + // Non-doc pre-comment of T + /// doc of T + T, + // Non-doc pre-comment of N + /// doc of N + const N: item, +>; diff --git a/src/tools/rustfmt/tests/target/doc.rs b/src/tools/rustfmt/tests/target/doc.rs new file mode 100644 index 000000000..0f9e2d21c --- /dev/null +++ b/src/tools/rustfmt/tests/target/doc.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true +// Part of multiple.rs + +// sadfsdfa +// sdffsdfasdf diff --git a/src/tools/rustfmt/tests/target/dyn_trait.rs b/src/tools/rustfmt/tests/target/dyn_trait.rs new file mode 100644 index 000000000..b6e2810a5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/dyn_trait.rs @@ -0,0 +1,27 @@ +#![feature(dyn_trait)] + +fn main() { + // #2506 + // checks rustfmt doesn't remove dyn + trait MyTrait { + fn method(&self) -> u64; + } + fn f1(a: Box<dyn MyTrait>) {} + + // checks if line wrap works correctly + trait Very_______________________Long__________________Name_______________________________Trait + { + fn method(&self) -> u64; + } + + fn f2( + a: Box< + dyn Very_______________________Long__________________Name____________________Trait + + 'static, + >, + ) { + } + + // #2582 + let _: &dyn (::std::any::Any) = &msg; +} diff --git a/src/tools/rustfmt/tests/target/else-if-brace-style-always-next-line.rs b/src/tools/rustfmt/tests/target/else-if-brace-style-always-next-line.rs new file mode 100644 index 000000000..31e12cfa0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/else-if-brace-style-always-next-line.rs @@ -0,0 +1,53 @@ +// rustfmt-control_brace_style: AlwaysNextLine + +fn main() { + if false + { + (); + (); + } + + if false + // lone if comment + { + (); + (); + } + + let a = if 0 > 1 { unreachable!() } else { 0x0 }; + + if true + { + (); + } + else if false + { + (); + (); + } + else + { + (); + (); + (); + } + + if true + // else-if-chain if comment + { + (); + } + else if false + // else-if-chain else-if comment + { + (); + (); + } + else + // else-if-chain else comment + { + (); + (); + (); + } +} diff --git a/src/tools/rustfmt/tests/target/else-if-brace-style-always-same-line.rs b/src/tools/rustfmt/tests/target/else-if-brace-style-always-same-line.rs new file mode 100644 index 000000000..07b71fd79 --- /dev/null +++ b/src/tools/rustfmt/tests/target/else-if-brace-style-always-same-line.rs @@ -0,0 +1,43 @@ +fn main() { + if false { + (); + (); + } + + if false + // lone if comment + { + (); + (); + } + + let a = if 0 > 1 { unreachable!() } else { 0x0 }; + + if true { + (); + } else if false { + (); + (); + } else { + (); + (); + (); + } + + if true + // else-if-chain if comment + { + (); + } else if false + // else-if-chain else-if comment + { + (); + (); + } else + // else-if-chain else comment + { + (); + (); + (); + } +} diff --git a/src/tools/rustfmt/tests/target/else-if-brace-style-closing-next-line.rs b/src/tools/rustfmt/tests/target/else-if-brace-style-closing-next-line.rs new file mode 100644 index 000000000..c99807dc0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/else-if-brace-style-closing-next-line.rs @@ -0,0 +1,49 @@ +// rustfmt-control_brace_style: ClosingNextLine + +fn main() { + if false { + (); + (); + } + + if false + // lone if comment + { + (); + (); + } + + let a = if 0 > 1 { unreachable!() } else { 0x0 }; + + if true { + (); + } + else if false { + (); + (); + } + else { + (); + (); + (); + } + + if true + // else-if-chain if comment + { + (); + } + else if false + // else-if-chain else-if comment + { + (); + (); + } + else + // else-if-chain else comment + { + (); + (); + (); + } +} diff --git a/src/tools/rustfmt/tests/target/empty-item-single-line-false.rs b/src/tools/rustfmt/tests/target/empty-item-single-line-false.rs new file mode 100644 index 000000000..bf7f70e7c --- /dev/null +++ b/src/tools/rustfmt/tests/target/empty-item-single-line-false.rs @@ -0,0 +1,41 @@ +// rustfmt-brace_style: AlwaysNextLine +// rustfmt-empty_item_single_line: false + +fn function() +{ +} + +struct Struct {} + +enum Enum {} + +trait Trait +{ +} + +impl<T> Trait for T +{ +} + +trait Trait2<T> +where + T: Copy + Display + Write + Read + FromStr, +{ +} + +trait Trait3<T> +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, +{ +} diff --git a/src/tools/rustfmt/tests/target/empty-tuple-no-conversion-to-unit-struct.rs b/src/tools/rustfmt/tests/target/empty-tuple-no-conversion-to-unit-struct.rs new file mode 100644 index 000000000..0b9a15e8a --- /dev/null +++ b/src/tools/rustfmt/tests/target/empty-tuple-no-conversion-to-unit-struct.rs @@ -0,0 +1,12 @@ +enum TestEnum { + Arm1(), + Arm2, +} + +fn foo() { + let test = TestEnum::Arm1; + match test { + TestEnum::Arm1() => {} + TestEnum::Arm2 => {} + } +} diff --git a/src/tools/rustfmt/tests/target/empty_file.rs b/src/tools/rustfmt/tests/target/empty_file.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/target/empty_file.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/target/enum.rs b/src/tools/rustfmt/tests/target/enum.rs new file mode 100644 index 000000000..9a25126b4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/enum.rs @@ -0,0 +1,289 @@ +// rustfmt-wrap_comments: true +// Enums test + +#[atrr] +pub enum Test { + A, + B(u32, A /* comment */, SomeType), + /// Doc comment + C, +} + +pub enum Foo<'a, Y: Baz> +where + X: Whatever, +{ + A, +} + +enum EmtpyWithComment { + // Some comment +} + +// C-style enum +enum Bar { + A = 1, + #[someAttr(test)] + B = 2, // comment + C, +} + +enum LongVariants { + First( + LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG, // comment + VARIANT, + ), + // This is the second variant + Second, +} + +enum StructLikeVariants { + Normal(u32, String), + StructLike { + x: i32, // Test comment + // Pre-comment + #[Attr50] + y: SomeType, // Aanother Comment + }, + SL { + a: A, + }, +} + +enum X { + CreateWebGLPaintTask( + Size2D<i32>, + GLContextAttributes, + IpcSender<Result<(IpcSender<CanvasMsg>, usize), String>>, + ), // This is a post comment +} + +pub enum EnumWithAttributes { + //This is a pre comment + // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + TupleVar(usize, usize, usize), /* AAAA AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA + * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA */ + // Pre Comment + #[rustfmt::skip] + SkippedItem(String,String,), // Post-comment + #[another_attr] + #[attr2] + ItemStruct { + x: usize, + y: usize, + }, /* Comment AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA */ + // And another + ForcedPreflight, /* AAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA */ +} + +pub enum SingleTuple { + // Pre Comment AAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + Match(usize, usize, String), /* Post-comment AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA */ +} + +pub enum SingleStruct { + Match { name: String, loc: usize }, // Post-comment +} + +pub enum GenericEnum<I, T> +where + I: Iterator<Item = T>, +{ + // Pre Comment + Left { list: I, root: T }, // Post-comment + Right { list: I, root: T }, // Post Comment +} + +enum EmtpyWithComment { + // Some comment +} + +enum TestFormatFails { + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +} + +fn nested_enum_test() { + if true { + enum TestEnum { + One( + usize, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + usize, + ), /* AAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAA + * AAAAAAAAAAAAAAAAAAAAAA */ + Two, /* AAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + * AAAAAAAAAAAAAAAAAA */ + } + enum TestNestedFormatFail { + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + } + } +} + +pub struct EmtpyWithComment { + // FIXME: Implement this struct +} + +// #1115 +pub enum Bencoding<'i> { + Str(&'i [u8]), + Int(i64), + List(Vec<Bencoding<'i>>), + /// A bencoded dict value. The first element the slice of bytes in the + /// source that the dict is composed of. The second is the dict, decoded + /// into an ordered map. + // TODO make Dict "structlike" AKA name the two values. + Dict(&'i [u8], BTreeMap<&'i [u8], Bencoding<'i>>), +} + +// #1261 +pub enum CoreResourceMsg { + SetCookieForUrl( + ServoUrl, + #[serde( + deserialize_with = "::hyper_serde::deserialize", + serialize_with = "::hyper_serde::serialize" + )] + Cookie, + CookieSource, + ), +} + +enum Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +{} +enum Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +{} +enum Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +{} +enum Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +{ + Foo, +} + +// #1046 +pub enum Entry<'a, K: 'a, V: 'a> { + Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>), + Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>), +} + +// #2081 +pub enum ForegroundColor { + CYAN = + (winapi::FOREGROUND_INTENSITY | winapi::FOREGROUND_GREEN | winapi::FOREGROUND_BLUE) as u16, +} + +// #2098 +pub enum E<'a> { + V(<std::slice::Iter<'a, Xxxxxxxxxxxxxx> as Iterator>::Item), +} + +// #1809 +enum State { + TryRecv { + pos: usize, + lap: u8, + closed_count: usize, + }, + Subscribe { + pos: usize, + }, + IsReady { + pos: usize, + ready: bool, + }, + Unsubscribe { + pos: usize, + lap: u8, + id_woken: usize, + }, + FinalTryRecv { + pos: usize, + id_woken: usize, + }, + TimedOut, + Disconnected, +} + +// #2190 +#[derive(Debug, Fail)] +enum AnError { + #[fail( + display = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + )] + UnexpectedSingleToken { token: syn::Token }, +} + +// #2193 +enum WidthOf101 { + #[fail(display = ".....................................................")] + Io(::std::io::Error), + #[fail(display = ".....................................................")] + Ioo(::std::io::Error), + Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(::std::io::Error), + Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + ::std::io::Error, + ), +} + +// #2389 +pub enum QlError { + #[fail(display = "Parsing error: {}", 0)] + LexError(parser::lexer::LexError), + #[fail(display = "Parsing error: {:?}", 0)] + ParseError(parser::ParseError), + #[fail(display = "Validation error: {:?}", 0)] + ValidationError(Vec<validation::Error>), + #[fail(display = "Execution error: {}", 0)] + ExecutionError(String), + // (from, to) + #[fail(display = "Translation error: from {} to {}", 0, 1)] + TranslationError(String, String), + // (kind, input, expected) + #[fail( + display = "aaaaaaaaaaaaCould not find {}: Found: {}, expected: {:?}", + 0, 1, 2 + )] + ResolveError(&'static str, String, Option<String>), +} + +// #2594 +enum Foo {} +enum Bar {} + +// #3562 +enum PublishedFileVisibility { + Public = + sys::ERemoteStoragePublishedFileVisibility_k_ERemoteStoragePublishedFileVisibilityPublic, + FriendsOnly = sys::ERemoteStoragePublishedFileVisibility_k_ERemoteStoragePublishedFileVisibilityFriendsOnly, + Private = + sys::ERemoteStoragePublishedFileVisibility_k_ERemoteStoragePublishedFileVisibilityPrivate, +} + +// #3771 +//#![feature(arbitrary_enum_discriminant)] +#[repr(u32)] +pub enum E { + A { + a: u32, + } = 0x100, + B { + field1: u32, + field2: u8, + field3: m::M, + } = 0x300, // comment +} diff --git a/src/tools/rustfmt/tests/target/existential_type.rs b/src/tools/rustfmt/tests/target/existential_type.rs new file mode 100644 index 000000000..ffc206875 --- /dev/null +++ b/src/tools/rustfmt/tests/target/existential_type.rs @@ -0,0 +1,23 @@ +// Opaque type. + +#![feature(type_alias_impl_trait)] + +pub type Adder<F, T> +where + T: Clone, + F: Copy, += impl Fn(T) -> T; + +pub type Adderrr<T> = impl Fn(T) -> T; + +impl Foo for Bar { + type E = impl Trait; +} + +pub type Adder_without_impl<F, T> +where + T: Clone, + F: Copy, += Fn(T) -> T; + +pub type Adderrr_without_impl<T> = Fn(T) -> T; diff --git a/src/tools/rustfmt/tests/target/expr-block.rs b/src/tools/rustfmt/tests/target/expr-block.rs new file mode 100644 index 000000000..c57700650 --- /dev/null +++ b/src/tools/rustfmt/tests/target/expr-block.rs @@ -0,0 +1,305 @@ +// Test expressions with block formatting. + +fn arrays() { + []; + let empty = []; + + let foo = [a_long_name, a_very_lng_name, a_long_name]; + + let foo = [ + a_long_name, + a_very_lng_name, + a_long_name, + a_very_lng_name, + a_long_name, + a_very_lng_name, + a_long_name, + a_very_lng_name, + ]; + + vec![ + a_long_name, + a_very_lng_name, + a_long_name, + a_very_lng_name, + a_long_name, + a_very_lng_name, + a_very_lng_name, + ]; + + [ + a_long_name, + a_very_lng_name, + a_long_name, + a_very_lng_name, + a_long_name, + a_very_lng_name, + a_very_lng_name, + ] +} + +fn arrays() { + let x = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, + ]; + + let y = [/* comment */ 1, 2 /* post comment */, 3]; + + let xy = [ + strukt { + test123: value_one_two_three_four, + turbo: coolio(), + }, + /* comment */ 1, + ]; + + let a = WeightedChoice::new(&mut [ + Weighted { weight: x, item: 0 }, + Weighted { weight: 1, item: 1 }, + Weighted { weight: x, item: 2 }, + Weighted { weight: 1, item: 3 }, + ]); + + let z = [ + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + yyyyyyyyyyyyyyyyyyyyyyyyyyy, + zzzzzzzzzzzzzzzzz, + q, + ]; + + [1 + 3, 4, 5, 6, 7, 7, fncall::<Vec<_>>(3 - 1)] +} + +fn function_calls() { + let items = itemize_list( + context.source_map, + args.iter(), + ")", + |item| item.span.lo(), + |item| item.span.hi(), + |item| { + item.rewrite( + context, + Shape { + width: remaining_width, + ..nested_shape + }, + ) + }, + span.lo(), + span.hi(), + ); + + itemize_list( + context.source_map, + args.iter(), + ")", + |item| item.span.lo(), + |item| item.span.hi(), + |item| { + item.rewrite( + context, + Shape { + width: remaining_width, + ..nested_shape + }, + ) + }, + span.lo(), + span.hi(), + ) +} + +fn macros() { + baz!( + do_not, add, trailing, commas, inside, of, function, like, macros, even, if_they, are, long + ); + + baz!(one_item_macro_which_is_also_loooooooooooooooooooooooooooooooooooooooooooooooong); + + let _ = match option { + None => baz!( + function, + like, + macro_as, + expression, + which, + is, + loooooooooooooooong + ), + Some(p) => baz!(one_item_macro_as_expression_which_is_also_loooooooooooooooong), + }; +} + +fn issue_1450() { + if selfstate + .compare_exchandsfasdsdfgsdgsdfgsdfgsdfgsdfgsdfgfsfdsage_weak( + STATE_PARKED, + STATE_UNPARKED, + Release, + Relaxed, + Release, + Relaxed, + ) + .is_ok() + { + return; + } +} + +fn foo() { + if real_total <= limit + && !pre_line_comments + && !items.into_iter().any(|item| item.as_ref().is_multiline()) + { + DefinitiveListTactic::Horizontal + } +} + +fn combine_block() { + foo(Bar { + x: value, + y: value2, + }); + + foo((Bar { + x: value, + y: value2, + },)); + + foo(( + 1, + 2, + 3, + Bar { + x: value, + y: value2, + }, + )); + + foo((1, 2, 3, |x| { + let y = x + 1; + let z = y + 1; + z + })); + + let opt = Some(Struct( + long_argument_one, + long_argument_two, + long_argggggggg, + )); + + do_thing(|param| { + action(); + foo(param) + }); + + do_thing(x, |param| { + action(); + foo(param) + }); + + do_thing( + x, + (1, 2, 3, |param| { + action(); + foo(param) + }), + ); + + Ok(some_function( + lllllllllong_argument_one, + lllllllllong_argument_two, + lllllllllllllllllllllllllllllong_argument_three, + )); + + foo( + thing, + bar( + param2, + pparam1param1param1param1param1param1param1param1param1param1aram1, + param3, + ), + ); + + foo.map_or(|| { + Ok(SomeStruct { + f1: 0, + f2: 0, + f3: 0, + }) + }); + + match opt { + Some(x) => somefunc(anotherfunc( + long_argument_one, + long_argument_two, + long_argument_three, + )), + Some(x) => |x| { + let y = x + 1; + let z = y + 1; + z + }, + Some(x) => (1, 2, |x| { + let y = x + 1; + let z = y + 1; + z + }), + Some(x) => SomeStruct { + f1: long_argument_one, + f2: long_argument_two, + f3: long_argument_three, + }, + None => Ok(SomeStruct { + f1: long_argument_one, + f2: long_argument_two, + f3: long_argument_three, + }), + }; + + match x { + y => func(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), + _ => func( + x, + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, + zzz, + ), + } +} + +fn issue_1862() { + foo( + /* bar = */ None, + something_something, + /* baz = */ None, + /* This comment waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay too long to be kept on the same line */ + None, + /* com */ + this_last_arg_is_tooooooooooooooooooooooooooooooooo_long_to_be_kept_with_the_pre_comment, + ) +} + +fn issue_3025() { + foo( + // This describes the argument below. + /* bar = */ None, + // This describes the argument below. + something_something, + // This describes the argument below. */ + None, + // This describes the argument below. + /* This comment waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay too long to be kept on the same line */ + None, + // This describes the argument below. + /* com */ + this_last_arg_is_tooooooooooooooooooooooooooooooooo_long_to_be_kept_with_the_pre_comment, + ) +} + +fn issue_1878() { + let channel: &str = seq + .next_element()? + .ok_or_else(|| de::Error::invalid_length(2, &self))?; +} diff --git a/src/tools/rustfmt/tests/target/expr-overflow-delimited.rs b/src/tools/rustfmt/tests/target/expr-overflow-delimited.rs new file mode 100644 index 000000000..b00e81fcd --- /dev/null +++ b/src/tools/rustfmt/tests/target/expr-overflow-delimited.rs @@ -0,0 +1,120 @@ +// rustfmt-overflow_delimited_expr: true + +fn combine_blocklike() { + do_thing(|param| { + action(); + foo(param) + }); + + do_thing(x, |param| { + action(); + foo(param) + }); + + do_thing( + x, + // I'll be discussing the `action` with your para(m)legal counsel + |param| { + action(); + foo(param) + }, + ); + + do_thing(Bar { + x: value, + y: value2, + }); + + do_thing(x, Bar { + x: value, + y: value2, + }); + + do_thing( + x, + // Let me tell you about that one time at the `Bar` + Bar { + x: value, + y: value2, + }, + ); + + do_thing(&[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ]); + + do_thing(x, &[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ]); + + do_thing( + x, + // Just admit it; my list is longer than can be folded on to one line + &[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing(vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ]); + + do_thing(x, vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ]); + + do_thing( + x, + // Just admit it; my list is longer than can be folded on to one line + vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + x, + (1, 2, 3, |param| { + action(); + foo(param) + }), + ); +} + +fn combine_struct_sample() { + let identity = verify(&ctx, VerifyLogin { + type_: LoginType::Username, + username: args.username.clone(), + password: Some(args.password.clone()), + domain: None, + })?; +} + +fn combine_macro_sample() { + rocket::ignite() + .mount("/", routes![ + http::auth::login, + http::auth::logout, + http::cors::options, + http::action::dance, + http::action::sleep, + ]) + .launch(); +} diff --git a/src/tools/rustfmt/tests/target/expr.rs b/src/tools/rustfmt/tests/target/expr.rs new file mode 100644 index 000000000..84df802bc --- /dev/null +++ b/src/tools/rustfmt/tests/target/expr.rs @@ -0,0 +1,671 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// Test expressions + +fn foo() -> bool { + let boxed: Box<i32> = box 5; + let referenced = &5; + + let very_long_variable_name = (a + first + simple + test); + let very_long_variable_name = + (a + first + simple + test + AAAAAAAAAAAAA + BBBBBBBBBBBBBBBBB + b + c); + + let is_internalxxxx = + self.source_map.span_to_filename(s) == self.source_map.span_to_filename(m.inner); + + let some_val = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa * bbbb + / (bbbbbb - function_call(x, *very_long_pointer, y)) + + 1000; + + some_ridiculously_loooooooooooooooooooooong_function( + 10000 * 30000000000 + 40000 / 1002200000000 - 50000 * sqrt(-1), + trivial_value, + ); + (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + a + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aaaaa); + + { + for _ in 0..10 {} + } + + { + { + { + {} + } + } + } + + if 1 + 2 > 0 { + let result = 5; + result + } else { + 4 + }; + + if let Some(x) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { + // Nothing + } + + if let Some(x) = + (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) + {} + + if let ( + some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple, + ) = 1 + 2 + 3 + {} + + if let ( + some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple, + ) = 1111 + 2222 + {} + + if let ( + some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple, + ) = 1 + 2 + 3 + {} + + if let ast::ItemKind::Trait(_, unsafety, ref generics, ref type_param_bounds, ref trait_items) = + item.node + { + // nothing + } + + let test = if true { 5 } else { 3 }; + + if cond() { + something(); + } else if different_cond() { + something_else(); + } else { + // Check subformatting + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + } + + // #2884 + let _ = [0; { + struct Foo; + impl Foo { + const fn get(&self) -> usize { + 5 + } + }; + Foo.get() + }]; +} + +fn bar() { + let range = + (111111111 + 333333333333333333 + 1111 + 400000000000000000)..(2222 + 2333333333333333); + + let another_range = 5..some_func(a, b /* comment */); + + for _ in 1.. { + call_forever(); + } + + syntactically_correct( + loop { + sup('?'); + }, + if cond { 0 } else { 1 }, + ); + + let third = ..10; + let infi_range = ..; + let foo = 1..; + let bar = 5; + let nonsense = (10..0)..(0..10); + + loop { + if true { + break; + } + } + + let x = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + a, + ); +} + +fn baz() { + unsafe /* {}{}{}{{{{}} */ { + let foo = 1u32; + } + + unsafe /* very looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong + * comment */ { + } + + unsafe /* So this is a very long comment. + * Multi-line, too. + * Will it still format correctly? */ { + } + + unsafe { + // Regular unsafe block + } + + unsafe { foo() } + + unsafe { + foo(); + } + + // #2289 + let identifier_0 = unsafe { this_is_58_chars_long_and_line_is_93_chars_long_xxxxxxxxxx }; + let identifier_1 = unsafe { this_is_59_chars_long_and_line_is_94_chars_long_xxxxxxxxxxx }; + let identifier_2 = unsafe { this_is_65_chars_long_and_line_is_100_chars_long_xxxxxxxxxxxxxxxx }; + let identifier_3 = + unsafe { this_is_66_chars_long_and_line_is_101_chars_long_xxxxxxxxxxxxxxxxx }; +} + +// Test some empty blocks. +fn qux() { + {} + // FIXME this one could be done better. + { /* a block with a comment */ } + {} + { + // A block with a comment. + } +} + +fn issue227() { + { + let handler = + box DocumentProgressHandler::new(addr, DocumentProgressTask::DOMContentLoaded); + } +} + +fn issue184(source: &str) { + for c in source.chars() { + if index < 'a' { + continue; + } + } +} + +fn arrays() { + let x = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, + ]; + + let y = [/* comment */ 1, 2 /* post comment */, 3]; + + let xy = [ + strukt { + test123: value_one_two_three_four, + turbo: coolio(), + }, + // comment + 1, + ]; + + let a = WeightedChoice::new(&mut [ + Weighted { + weightweight: x, + item: 0, + }, + Weighted { + weightweight: 1, + item: 1, + }, + Weighted { + weightweight: x, + item: 2, + }, + Weighted { + weightweight: 1, + item: 3, + }, + ]); + + let z = [ + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + yyyyyyyyyyyyyyyyyyyyyyyyyyy, + zzzzzzzzzzzzzzzzzz, + q, + ]; + + [1 + 3, 4, 5, 6, 7, 7, fncall::<Vec<_>>(3 - 1)] +} + +fn returns() { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + && return; + + return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; +} + +fn addrof() { + &mut (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb); + &(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb); + + // raw reference operator + &raw const a; + &raw mut b; +} + +fn casts() { + fn unpack(packed: u32) -> [u16; 2] { + [(packed >> 16) as u16, (packed >> 0) as u16] + } + + let some_trait_xxx = xxxxxxxxxxx + xxxxxxxxxxxxx as SomeTraitXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; + let slightly_longer_trait = + yyyyyyyyy + yyyyyyyyyyy as SomeTraitYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY; +} + +fn indices() { + let x = (aaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccc) + [x + y + z]; + let y = (aaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccc) + [xxxxx + yyyyy + zzzzz]; + let z = xxxxxxxxxx + .x() + .y() + .zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz()[aaaaa]; + let z = xxxxxxxxxx + .x() + .y() + .zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz() + [aaaaa]; +} + +fn repeats() { + let x = [aaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccc; + x + y + z]; + let y = [aaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccc; + xxxxx + yyyyy + zzzzz]; +} + +fn blocks() { + if 1 + 1 == 2 { + println!("yay arithmetix!"); + }; +} + +fn issue767() { + if false { + if false { + } else { + // A let binding here seems necessary to trigger it. + let _ = (); + } + } else if let false = false { + } +} + +fn ranges() { + let x = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + let y = + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + let z = ..=x; + + // #1766 + let x = [0. ..10.0]; + let x = [0. ..=10.0]; + + a..=b + + // the expr below won't compile because inclusive ranges need a defined end + // let a = 0 ..= ; +} + +fn if_else() { + let exact = diff / (if size == 0 { 1 } else { size }); + + let cx = tp1.x + any * radius * if anticlockwise { 1.0 } else { -1.0 }; +} + +fn complex_if_else() { + if let Some(x) = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx { + } else if let Some(x) = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx { + ha(); + } else if xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxx { + yo(); + } else if let Some(x) = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + { + ha(); + } else if xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxx + { + yo(); + } +} + +fn issue1106() { + { + if let hir::ItemEnum(ref enum_def, ref generics) = + self.ast_map.expect_item(enum_node_id).node + {} + } + + for entry in WalkDir::new(path) + .into_iter() + .filter_entry(|entry| exclusions.filter_entry(entry)) + {} +} + +fn issue1570() { + a_very_long_function_name({ some_func(1, { 1 }) }) +} + +fn issue1714() { + v = &mut { v }[mid..]; + let (left, right) = { v }.split_at_mut(mid); +} + +// Multi-lined index should be put on the next line if it fits in one line. +fn issue1749() { + { + { + { + if self.shape[(r as f32 + self.x_offset) as usize] + [(c as f32 + self.y_offset) as usize] + != 0 + { + // hello + } + } + } + } +} + +// #1172 +fn newlines_between_list_like_expr() { + foo( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, + zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, + ); + + vec![ + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, + zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, + ]; + + match x { + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + | yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy + | zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz => foo(a, b, c), + _ => bar(), + }; +} + +fn issue2178() { + Ok(result + .iter() + .map(|item| ls_util::rls_to_location(item)) + .collect()) +} + +// #2493 +impl Foo { + fn bar(&self) { + { + let x = match () { + () => { + let i; + i == self + .install_config + .storage + .experimental_compressed_block_size as usize + } + }; + } + } +} + +fn dots() { + .. .. ..; // (.. (.. (..))) + ..= ..= ..; + (..).. ..; // ((..) .. (..)) +} + +// #2676 +// A function call with a large single argument. +fn foo() { + let my_var = Mutex::new( + RpcClientType::connect(server_iddd).chain_err(|| "Unable to create RPC client")?, + ); +} + +// #2704 +// Method call with prefix and suffix. +fn issue2704() { + // We should not combine the callee with a multi-lined method call. + let requires = requires.set( + &requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total(), + ); + let requires = requires.set( + box requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total(), + ); + let requires = requires.set( + requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total() as u32, + ); + let requires = requires.set( + requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total()?, + ); + let requires = requires.set( + !requires0 + .concat(&requires1) + .concat(&requires2) + .distinct_total(), + ); + // We should combine a small callee with an argument. + bar(vec![22] + .into_iter() + .map(|x| x * 2) + .filter(|_| true) + .collect()); + // But we should not combine a long callee with an argument. + barrrr( + vec![22] + .into_iter() + .map(|x| x * 2) + .filter(|_| true) + .collect(), + ); +} + +// #2782 +fn issue2782() { + { + let f = { + let f = { + { + match f { + F(f, _) => loop { + let f = { + match f { + F(f, _) => match f { + F(f, _) => loop { + let f = { + let f = { + match f { + '-' => F(f, ()), + } + }; + }; + }, + }, + } + }; + }, + } + } + }; + }; + } +} + +fn issue_2802() { + function_to_fill_this_line(some_arg, some_arg, some_arg) + * a_very_specific_length(specific_length_arg) + * very_specific_length(Foo { + a: some_much_much_longer_value, + }) + * some_value +} + +fn issue_3003() { + let mut path: PathBuf = [ + env!("CARGO_MANIFEST_DIR"), + "tests", + "support", + "dejavu-fonts-ttf-2.37", + "ttf", + ] + .iter() + .collect(); +} + +fn issue3226() { + { + { + { + return Err( + ErrorKind::ManagementInterfaceError("Server exited unexpectedly").into(), + ); + } + } + } + { + { + { + break Err( + ErrorKind::ManagementInterfaceError("Server exited unexpectedlyy").into(), + ); + } + } + } +} + +// #3457 +fn issue3457() { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + { + println!("Test"); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +} + +// #3498 +static REPRO: &[usize] = &[ + #[cfg(feature = "zero")] + 0, +]; + +fn overflow_with_attr() { + foo( + #[cfg(feature = "zero")] + 0, + ); + foobar( + #[cfg(feature = "zero")] + 0, + ); + foobar( + x, + y, + #[cfg(feature = "zero")] + {}, + ); +} + +// https://github.com/rust-lang/rustfmt/issues/3765 +fn foo() { + async { + // Do + // some + // work + } + .await; + + async { + // Do + // some + // work + } + .await; +} + +fn underscore() { + _ = 1; + _; + [_, a, _] = [1, 2, 3]; + (a, _) = (8, 9); + TupleStruct(_, a) = TupleStruct(2, 2); + + let _: usize = foo(_, _); +} diff --git a/src/tools/rustfmt/tests/target/extern.rs b/src/tools/rustfmt/tests/target/extern.rs new file mode 100644 index 000000000..d1741360c --- /dev/null +++ b/src/tools/rustfmt/tests/target/extern.rs @@ -0,0 +1,97 @@ +// rustfmt-normalize_comments: true + +extern crate foo; +extern crate foo as bar; + +extern crate chrono; +extern crate dotenv; +extern crate futures; + +extern crate bar; +extern crate foo; + +// #2315 +extern crate proc_macro; +extern crate proc_macro2; + +// #3128 +extern crate serde; // 1.0.78 +extern crate serde_derive; // 1.0.78 +extern crate serde_json; // 1.0.27 + +extern "C" { + fn c_func(x: *mut *mut libc::c_void); + + fn c_func( + x: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX, + y: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY, + ); + + #[test123] + fn foo() -> uint64_t; + + pub fn bar(); +} + +extern "C" { + fn DMR_GetDevice( + pHDev: *mut HDEV, + searchMode: DeviceSearchMode, + pSearchString: *const c_char, + devNr: c_uint, + wildcard: c_char, + ) -> TDMR_ERROR; + + fn quux() -> (); // Post comment + + pub type Foo; + + type Bar; +} + +extern "Rust" { + static ext: u32; + // Some comment. + pub static mut var: SomeType; +} + +extern "C" { + fn syscall( + number: libc::c_long, // comment 1 + // comm 2 + ... // sup? + ) -> libc::c_long; + + fn foo(x: *const c_char, ...) -> libc::c_long; +} + +extern "C" { + pub fn freopen( + filename: *const c_char, + mode: *const c_char, + mode2: *const c_char, + mode3: *const c_char, + file: *mut FILE, + ) -> *mut FILE; + + const fn foo() -> *mut Bar; + unsafe fn foo() -> *mut Bar; + + pub(super) const fn foo() -> *mut Bar; + pub(crate) unsafe fn foo() -> *mut Bar; +} + +extern "C" {} + +macro_rules! x { + ($tt:tt) => {}; +} + +extern "macros" { + x!(ident); + x!(#); + x![ident]; + x![#]; + x! {ident} + x! {#} +} diff --git a/src/tools/rustfmt/tests/target/extern_not_explicit.rs b/src/tools/rustfmt/tests/target/extern_not_explicit.rs new file mode 100644 index 000000000..b55b64d05 --- /dev/null +++ b/src/tools/rustfmt/tests/target/extern_not_explicit.rs @@ -0,0 +1,18 @@ +// rustfmt-force_explicit_abi: false + +extern { + fn some_fn() -> (); +} + +extern fn sup() {} + +type funky_func = extern fn( + unsafe extern "rust-call" fn( + *const JSJitInfo, + *mut JSContext, + HandleObject, + *mut libc::c_void, + u32, + *mut JSVal, + ) -> u8, +); diff --git a/src/tools/rustfmt/tests/target/file-lines-1.rs b/src/tools/rustfmt/tests/target/file-lines-1.rs new file mode 100644 index 000000000..13820ec29 --- /dev/null +++ b/src/tools/rustfmt/tests/target/file-lines-1.rs @@ -0,0 +1,30 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-1.rs","range":[4,8]}] + +fn floaters() { + let x = Foo { + field1: val1, + field2: val2, + } + .method_call() + .method_call(); + + let y = if cond { + val1 + } else { + val2 + } + .method_call(); + + { + match x { + PushParam => { + // comment + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/file-lines-2.rs b/src/tools/rustfmt/tests/target/file-lines-2.rs new file mode 100644 index 000000000..bc25698c2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/file-lines-2.rs @@ -0,0 +1,24 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-2.rs","range":[10,15]}] + +fn floaters() { + let x = Foo { + field1: val1, + field2: val2, + } + .method_call().method_call(); + + let y = if cond { val1 } else { val2 }.method_call(); + + { + match x { + PushParam => { + // comment + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/file-lines-3.rs b/src/tools/rustfmt/tests/target/file-lines-3.rs new file mode 100644 index 000000000..77d6fb263 --- /dev/null +++ b/src/tools/rustfmt/tests/target/file-lines-3.rs @@ -0,0 +1,25 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-3.rs","range":[4,8]},{"file":"tests/source/file-lines-3.rs","range":[10,15]}] + +fn floaters() { + let x = Foo { + field1: val1, + field2: val2, + } + .method_call() + .method_call(); + + let y = if cond { val1 } else { val2 }.method_call(); + + { + match x { + PushParam => { + // comment + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/file-lines-4.rs b/src/tools/rustfmt/tests/target/file-lines-4.rs new file mode 100644 index 000000000..83928bf6f --- /dev/null +++ b/src/tools/rustfmt/tests/target/file-lines-4.rs @@ -0,0 +1,30 @@ +// rustfmt-file_lines: [] +// (Test that nothing is formatted if an empty array is specified.) + +fn floaters() { + let x = Foo { + field1: val1, + field2: val2, + } + .method_call().method_call(); + + let y = if cond { + val1 + } else { + val2 + } + .method_call(); + // aaaaaaaaaaaaa + { + match x { + PushParam => { + // comment + stack.push(mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/file-lines-5.rs b/src/tools/rustfmt/tests/target/file-lines-5.rs new file mode 100644 index 000000000..3966dc063 --- /dev/null +++ b/src/tools/rustfmt/tests/target/file-lines-5.rs @@ -0,0 +1,17 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-5.rs","range":[3,5]}] + +struct A { + t: i64, +} + +mod foo { + fn bar() { + // test + let i = 12; + // test + } + // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + fn baz() { + let j = 15; + } +} diff --git a/src/tools/rustfmt/tests/target/file-lines-6.rs b/src/tools/rustfmt/tests/target/file-lines-6.rs new file mode 100644 index 000000000..8a092df86 --- /dev/null +++ b/src/tools/rustfmt/tests/target/file-lines-6.rs @@ -0,0 +1,18 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-6.rs","range":[9,10]}] + +struct A { + t: i64, +} + +mod foo { + fn bar() { + // test + let i = 12; + // test + } + + fn baz() { +/// + let j = 15; + } +} diff --git a/src/tools/rustfmt/tests/target/file-lines-7.rs b/src/tools/rustfmt/tests/target/file-lines-7.rs new file mode 100644 index 000000000..62d913d88 --- /dev/null +++ b/src/tools/rustfmt/tests/target/file-lines-7.rs @@ -0,0 +1,21 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-7.rs","range":[8,15]}] + +struct A { + t: i64, +} + +mod foo { + fn bar() { + // test + let i = 12; + // test + } + + fn baz() { + + + + /// + let j = 15; + } +} diff --git a/src/tools/rustfmt/tests/target/file-lines-item.rs b/src/tools/rustfmt/tests/target/file-lines-item.rs new file mode 100644 index 000000000..8d39eb609 --- /dev/null +++ b/src/tools/rustfmt/tests/target/file-lines-item.rs @@ -0,0 +1,21 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-item.rs","range":[6,8]}] + +use foo::{c, b, a}; +use bar; + +fn foo() { + bar(); +} + +impl Drop for Context { + fn drop(&mut self) { + } +} + +impl Bar for Baz { + fn foo() { + bar( + baz, // Who knows? + ) + } +} diff --git a/src/tools/rustfmt/tests/target/fn-args-with-last-line-comment.rs b/src/tools/rustfmt/tests/target/fn-args-with-last-line-comment.rs new file mode 100644 index 000000000..27e0e0965 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-args-with-last-line-comment.rs @@ -0,0 +1,24 @@ +// #1587 +pub trait X { + fn a(&self) -> &'static str; + fn bcd( + &self, + c: &str, // comment on this arg + d: u16, // comment on this arg + e: &Vec<String>, // comment on this arg + ) -> Box<Q>; +} + +// #1595 +fn foo( + arg1: LongTypeName, + arg2: LongTypeName, + arg3: LongTypeName, + arg4: LongTypeName, + arg5: LongTypeName, + arg6: LongTypeName, + arg7: LongTypeName, + //arg8: LongTypeName, +) { + // do stuff +} diff --git a/src/tools/rustfmt/tests/target/fn-custom-2.rs b/src/tools/rustfmt/tests/target/fn-custom-2.rs new file mode 100644 index 000000000..0e723396c --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-custom-2.rs @@ -0,0 +1,77 @@ +// Test different indents. + +fn foo( + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee, +) { + foo(); +} + +fn bar< + 'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW, +>( + a: Aaaaaaaaaaaaaaa, +) { + bar(); +} + +fn baz() +where + X: TTTTTTTT, +{ + baz(); +} + +fn qux() +where + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, +{ + baz(); +} + +impl Foo { + fn foo( + self, + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee, + ) { + foo(); + } + + fn bar< + 'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW, + >( + a: Aaaaaaaaaaaaaaa, + ) { + bar(); + } + + fn baz() + where + X: TTTTTTTT, + { + baz(); + } +} + +struct Foo< + TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUU, + VVVVVVVVVVVVVVVVVVVVVVVVVVV, + WWWWWWWWWWWWWWWWWWWWWWWW, +> { + foo: Foo, +} diff --git a/src/tools/rustfmt/tests/target/fn-custom-3.rs b/src/tools/rustfmt/tests/target/fn-custom-3.rs new file mode 100644 index 000000000..bfafe4536 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-custom-3.rs @@ -0,0 +1,71 @@ +// Test different indents. + +fn foo( + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee, +) { + foo(); +} + +fn bar< + 'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW, +>( + a: Aaaaaaaaaaaaaaa, +) { + bar(); +} + +fn qux() +where + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, +{ + baz(); +} + +fn qux() +where + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, +{ + baz(); +} + +impl Foo { + fn foo( + self, + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee, + ) { + foo(); + } + + fn bar< + 'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW, + >( + a: Aaaaaaaaaaaaaaa, + ) { + bar(); + } +} + +struct Foo< + TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUU, + VVVVVVVVVVVVVVVVVVVVVVVVVVV, + WWWWWWWWWWWWWWWWWWWWWWWW, +> { + foo: Foo, +} diff --git a/src/tools/rustfmt/tests/target/fn-custom-4.rs b/src/tools/rustfmt/tests/target/fn-custom-4.rs new file mode 100644 index 000000000..5de16e251 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-custom-4.rs @@ -0,0 +1,26 @@ +// Test different indents. + +fn qux() +where + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, +{ + baz(); +} + +fn qux() +where + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, +{ + baz(); +} + +fn qux(a: Aaaaaaaaaaaaaaaaa) +where + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, +{ + baz(); +} diff --git a/src/tools/rustfmt/tests/target/fn-custom-6.rs b/src/tools/rustfmt/tests/target/fn-custom-6.rs new file mode 100644 index 000000000..e891f4d58 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-custom-6.rs @@ -0,0 +1,71 @@ +// rustfmt-brace_style: PreferSameLine +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) -> String { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) +where + T: UUUUUUUUUUU, { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) where + T: UUUUUUUUUUU, { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String +where + T: UUUUUUUUUUU, { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) -> String +where + T: UUUUUUUUUUU, { + bar(); +} + +trait Test { + fn foo(a: u8) {} + + fn bar(a: u8) -> String {} +} diff --git a/src/tools/rustfmt/tests/target/fn-custom-7.rs b/src/tools/rustfmt/tests/target/fn-custom-7.rs new file mode 100644 index 000000000..2c20ac5a7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-custom-7.rs @@ -0,0 +1,36 @@ +// rustfmt-normalize_comments: true +// rustfmt-fn_args_layout: Vertical +// rustfmt-brace_style: AlwaysNextLine + +// Case with only one variable. +fn foo(a: u8) -> u8 +{ + bar() +} + +// Case with 2 variables and some pre-comments. +fn foo( + a: u8, // Comment 1 + b: u8, // Comment 2 +) -> u8 +{ + bar() +} + +// Case with 2 variables and some post-comments. +fn foo( + // Comment 1 + a: u8, + // Comment 2 + b: u8, +) -> u8 +{ + bar() +} + +trait Test +{ + fn foo(a: u8) {} + + fn bar(a: u8) -> String {} +} diff --git a/src/tools/rustfmt/tests/target/fn-custom-8.rs b/src/tools/rustfmt/tests/target/fn-custom-8.rs new file mode 100644 index 000000000..29af3fca7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-custom-8.rs @@ -0,0 +1,77 @@ +// rustfmt-brace_style: PreferSameLine +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) -> String { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) +where + T: UUUUUUUUUUU, { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) where + T: UUUUUUUUUUU, { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String +where + T: UUUUUUUUUUU, { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) -> String +where + T: UUUUUUUUUUU, { + bar(); +} + +trait Test { + fn foo(a: u8) {} + + fn bar(a: u8) -> String {} + + fn bar(a: u8) -> String + where + Foo: foooo, + Bar: barrr, { + } +} diff --git a/src/tools/rustfmt/tests/target/fn-custom.rs b/src/tools/rustfmt/tests/target/fn-custom.rs new file mode 100644 index 000000000..2eb2a973d --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-custom.rs @@ -0,0 +1,19 @@ +// rustfmt-fn_args_layout: Compressed +// Test some of the ways function signatures can be customised. + +// Test compressed layout of args. +fn foo( + a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee, +) { + foo(); +} + +impl Foo { + fn foo( + self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee, + ) { + foo(); + } +} diff --git a/src/tools/rustfmt/tests/target/fn-param-attributes.rs b/src/tools/rustfmt/tests/target/fn-param-attributes.rs new file mode 100644 index 000000000..829575518 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-param-attributes.rs @@ -0,0 +1,64 @@ +// https://github.com/rust-lang/rustfmt/issues/3623 + +fn foo(#[cfg(something)] x: i32, y: i32) -> i32 { + x + y +} + +fn foo_b(#[cfg(something)] x: i32, y: i32) -> i32 { + x + y +} + +fn add( + #[cfg(something)] + #[deny(C)] + x: i32, + y: i32, +) -> i32 { + x + y +} + +struct NamedSelfRefStruct {} +impl NamedSelfRefStruct { + fn foo(#[cfg(something)] self: &Self) {} +} + +struct MutStruct {} +impl MutStruct { + fn foo(#[cfg(foo)] &mut self, #[deny(C)] b: i32) {} +} + +fn main() { + let c = |#[allow(C)] a: u32, + #[cfg(something)] b: i32, + #[cfg_attr(something, cfg(nothing))] + #[deny(C)] + c: i32| {}; + let _ = c(1, 2); +} + +pub fn bar( + /// bar + #[test] + a: u32, + /// Bar + #[must_use] + /// Baz + #[no_mangle] + b: i32, +) { +} + +fn abc( + #[foo] + #[bar] + param: u32, +) { + // ... +} + +fn really_really_really_loooooooooooooooooooong( + #[cfg(some_even_longer_config_feature_that_keeps_going_and_going_and_going_forever_and_ever_and_ever_on_and_on)] + b: i32, +) { + // ... +} diff --git a/src/tools/rustfmt/tests/target/fn-simple.rs b/src/tools/rustfmt/tests/target/fn-simple.rs new file mode 100644 index 000000000..e72526936 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-simple.rs @@ -0,0 +1,120 @@ +// rustfmt-normalize_comments: true + +fn simple( + // pre-comment on a function!? + i: i32, // yes, it's possible! + response: NoWay, // hose +) { + fn op( + x: Typ, + key: &[u8], + upd: Box< + Fn( + Option<&memcache::Item>, + ) -> (memcache::Status, Result<memcache::Item, Option<String>>), + >, + ) -> MapResult { + } + + "cool" +} + +fn weird_comment( + // /*/ double level */ comment + x: Hello, // /*/* triple, even */*/ + // Does this work? + y: World, +) { + simple(/* does this preserve comments now? */ 42, NoWay) +} + +fn generic<T>(arg: T) -> &SomeType +where + T: Fn( + // First arg + A, + // Second argument + B, + C, + D, + // pre comment + E, // last comment + ) -> &SomeType, +{ + arg(a, b, c, d, e) +} + +fn foo() -> ! {} + +pub fn http_fetch_async( + listener: Box<AsyncCORSResponseListener + Send>, + script_chan: Box<ScriptChan + Send>, +) { +} + +fn some_func<T: Box<Trait + Bound>>(val: T) {} + +fn zzzzzzzzzzzzzzzzzzzz<Type, NodeType>( + selff: Type, + mut handle: node::Handle<IdRef<'id, Node<K, V>>, Type, NodeType>, +) -> SearchStack<'a, K, V, Type, NodeType> { +} + +unsafe fn generic_call( + cx: *mut JSContext, + argc: libc::c_uint, + vp: *mut JSVal, + is_lenient: bool, + call: unsafe extern "C" fn( + *const JSJitInfo, + *mut JSContext, + HandleObject, + *mut libc::c_void, + u32, + *mut JSVal, + ) -> u8, +) { + let f: fn(_, _) -> _ = panic!(); +} + +pub fn start_export_thread<C: CryptoSchemee + 'static>( + database: &Database, + crypto_scheme: &C, + block_size: usize, + source_path: &Path, +) -> BonzoResult<mpsc::Consumer<'static, FileInstruction>> { +} + +pub fn waltz(cwd: &Path) -> CliAssert { + { + { + formatted_comment = + rewrite_comment(comment, block_style, width, offset, formatting_fig); + } + } +} + +// #2003 +mod foo { + fn __bindgen_test_layout_i_open0_c_open1_char_a_open2_char_close2_close1_close0_instantiation() + { + foo(); + } +} + +// #2082 +pub(crate) fn init() {} + +pub(crate) fn init() {} + +// #2630 +fn make_map<T, F: (Fn(&T) -> String)>(records: &Vec<T>, key_fn: F) -> HashMap<String, usize> {} + +// #2956 +fn bar( + beans: Asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf, + spam: bool, + eggs: bool, +) -> bool { + unimplemented!(); +} diff --git a/src/tools/rustfmt/tests/target/fn-single-line/version_one.rs b/src/tools/rustfmt/tests/target/fn-single-line/version_one.rs new file mode 100644 index 000000000..013b2cd72 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-single-line/version_one.rs @@ -0,0 +1,71 @@ +// rustfmt-fn_single_line: true +// rustfmt-version: One +// Test single-line functions. + +fn foo_expr() { 1 } + +fn foo_stmt() { foo(); } + +fn foo_decl_local() { let z = 5; } + +fn foo_decl_item(x: &mut i32) { x = 3; } + +fn empty() {} + +fn foo_return() -> String { "yay" } + +fn foo_where() -> T +where + T: Sync, +{ + let x = 2; +} + +fn fooblock() { + { + "inner-block" + } +} + +fn fooblock2(x: i32) { + let z = match x { + _ => 2, + }; +} + +fn comment() { + // this is a test comment + 1 +} + +fn comment2() { + // multi-line comment + let z = 2; + 1 +} + +fn only_comment() { + // Keep this here +} + +fn aaaaaaaaaaaaaaaaa_looooooooooooooooooooooong_name() { + let z = "aaaaaaawwwwwwwwwwwwwwwwwwwwwwwwwwww"; +} + +fn lots_of_space() { 1 } + +fn mac() -> Vec<i32> { vec![] } + +trait CoolTypes { + fn dummy(&self) {} +} + +trait CoolerTypes { + fn dummy(&self) {} +} + +fn Foo<T>() +where + T: Bar, +{ +} diff --git a/src/tools/rustfmt/tests/target/fn-single-line/version_two.rs b/src/tools/rustfmt/tests/target/fn-single-line/version_two.rs new file mode 100644 index 000000000..b8053d4c2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-single-line/version_two.rs @@ -0,0 +1,67 @@ +// rustfmt-fn_single_line: true +// rustfmt-version: Two +// Test single-line functions. + +fn foo_expr() { 1 } + +fn foo_stmt() { foo(); } + +fn foo_decl_local() { let z = 5; } + +fn foo_decl_item(x: &mut i32) { x = 3; } + +fn empty() {} + +fn foo_return() -> String { "yay" } + +fn foo_where() -> T +where + T: Sync, +{ + let x = 2; +} + +fn fooblock() { { "inner-block" } } + +fn fooblock2(x: i32) { + let z = match x { + _ => 2, + }; +} + +fn comment() { + // this is a test comment + 1 +} + +fn comment2() { + // multi-line comment + let z = 2; + 1 +} + +fn only_comment() { + // Keep this here +} + +fn aaaaaaaaaaaaaaaaa_looooooooooooooooooooooong_name() { + let z = "aaaaaaawwwwwwwwwwwwwwwwwwwwwwwwwwww"; +} + +fn lots_of_space() { 1 } + +fn mac() -> Vec<i32> { vec![] } + +trait CoolTypes { + fn dummy(&self) {} +} + +trait CoolerTypes { + fn dummy(&self) {} +} + +fn Foo<T>() +where + T: Bar, +{ +} diff --git a/src/tools/rustfmt/tests/target/fn-ty.rs b/src/tools/rustfmt/tests/target/fn-ty.rs new file mode 100644 index 000000000..7d48f3b32 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn-ty.rs @@ -0,0 +1,14 @@ +fn f( + xxxxxxxxxxxxxxxxxx: fn(a, b, b) -> a, + xxxxxxxxxxxxxxxxxx: fn() -> a, + xxxxxxxxxxxxxxxxxx: fn(a, b, b), + xxxxxxxxxxxxxxxxxx: fn(), + xxxxxxxxxxxxxxxxxx: fn(a, b, b) -> !, + xxxxxxxxxxxxxxxxxx: fn() -> !, +) where + F1: Fn(a, b, b) -> a, + F2: Fn(a, b, b), + F3: Fn(), + F4: Fn() -> u32, +{ +} diff --git a/src/tools/rustfmt/tests/target/fn.rs b/src/tools/rustfmt/tests/target/fn.rs new file mode 100644 index 000000000..0ad775ee1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn.rs @@ -0,0 +1,120 @@ +// Tests different fns + +fn foo(a: AAAA, b: BBB, c: CCC) -> RetType {} + +fn foo(a: AAAA, b: BBB /* some, weird, inline comment */, c: CCC) -> RetType +where + T: Blah, +{ +} + +fn foo(a: AAA /* (comment) */) +where + T: Blah, +{ +} + +fn foo( + a: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + b: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, +) -> RetType +where + T: Blah, +{ +} + +fn foo<U, T>( + a: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + b: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, +) -> RetType +where + T: Blah, + U: dsfasdfasdfasd, +{ +} + +fn foo<U: Fn(A) -> B /* paren inside generics */>() {} + +impl Foo { + fn with_no_errors<T, F>(&mut self, f: F) -> T + where + F: FnOnce(&mut Resolver) -> T, + { + } + + fn foo(mut self, mut bar: u32) {} + + fn bar(self, mut bazz: u32) {} +} + +pub fn render< + 'a, + N: Clone + 'a, + E: Clone + 'a, + G: Labeller<'a, N, E> + GraphWalk<'a, N, E>, + W: Write, +>( + g: &'a G, + w: &mut W, +) -> io::Result<()> { + render_opts(g, w, &[]) +} + +const fn foo() { + x; +} + +pub const fn foo() { + x; +} + +impl Foo { + const fn foo() { + x; + } +} + +fn homura<T: Deref<Target = i32>>(_: T) {} + +fn issue377() -> (Box<CompositorProxy + Send>, Box<CompositorReceiver>) {} + +fn main() { + let _ = function(move || 5); + let _ = move || 42; + let _ = || unsafe { abort() }; +} + +// With inner attributes. +fn inner() { + #![inline] + x +} + +#[cfg_attr(rustfmt, rustfmt::skip)] +fn foo(a: i32) -> i32 { + // comment + if a > 0 { 1 } else { 2 } +} + +fn ______________________baz( + a: i32, +) -> *mut ::std::option::Option< + extern "C" fn(arg1: i32, _____________________a: i32, arg3: i32) -> (), +> { +} + +pub fn check_path<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + path: &hir::Path, + id: ast::NodeId, + cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<Depecation>), +) { +} + +pub fn check_path<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + path: &hir::Path, + id: ast::NodeId, + cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<Deprecation>), +) { +} diff --git a/src/tools/rustfmt/tests/target/fn_args_indent-block.rs b/src/tools/rustfmt/tests/target/fn_args_indent-block.rs new file mode 100644 index 000000000..f5232a488 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn_args_indent-block.rs @@ -0,0 +1,143 @@ +// rustfmt-normalize_comments: true + +fn foo() { + foo(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) -> String { + bar(); +} + +fn foo(a: u8 /* Comment 1 */, b: u8 /* Comment 2 */) -> u8 { + bar() +} + +fn foo( + a: u8, // Comment 1 + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, // Comment 2 +) -> u8 { + bar() +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, +) -> String +where + X: Fooooo, + Y: Baaar, +{ + bar(); +} + +fn foo() -> T { + foo(); +} + +fn foo() -> T +where + X: Foooo, + Y: Baaar, +{ + foo(); +} + +fn foo() +where + X: Foooo, +{ +} + +fn foo() +where + X: Foooo, + Y: Baaar, +{ +} + +fn foo() -> ( + Loooooooooooooooooooooong, + Reeeeeeeeeeeeeeeeeeeeeeeeturn, + iiiiiiiiis, + Looooooooooooooooong, +) { + foo(); +} + +fn foo<g: G>() { + foo(); +} + +fn foo< + L: Loooooooooooooooooooooong, + G: Geeeeeeeeeeeneric, + I: iiiiiiiiis, + L: Looooooooooooooooong, +>() { + foo(); +} + +fn foo<L: Loooooooooooooooooooong, G: Geeeeeeeeeeneric, I: iiiiiiiiis, L: Loooooooooooooooong>() { + foo(); +} + +trait Test { + fn foo(a: u8) {} + + fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee, + ) -> String { + } +} + +fn foo<L: Loooooooooooooooooooong, G: Geeeeeeeeeeneric, I: iiiiiiiiis, L: Loooooooooooooooong>( + a: Aaaaaaaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, +) { + foo(); +} + +fn foo() -> ( + Looooooooooooooooooooooooooong, + Reeeeeeeeeeeeeeeeeeeeeeeeeeeeeturn, + iiiiiiiiiiiiiis, + Loooooooooooooooooooooong, +) { + foo(); +} diff --git a/src/tools/rustfmt/tests/target/fn_args_layout-vertical.rs b/src/tools/rustfmt/tests/target/fn_args_layout-vertical.rs new file mode 100644 index 000000000..da0ac981d --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn_args_layout-vertical.rs @@ -0,0 +1,39 @@ +// rustfmt-fn_args_layout: Vertical + +// Empty list should stay on one line. +fn do_bar() -> u8 { + bar() +} + +// A single argument should stay on the same line. +fn do_bar(a: u8) -> u8 { + bar() +} + +// Multiple arguments should each get their own line. +fn do_bar( + a: u8, + mut b: u8, + c: &u8, + d: &mut u8, + closure: &Fn(i32) -> i32, +) -> i32 { + // This feature should not affect closures. + let bar = |x: i32, y: i32| -> i32 { x + y }; + bar(a, b) +} + +// If the first argument doesn't fit on the same line with the function name, +// the whole list should probably be pushed to the next line with hanging +// indent. That's not what happens though, so check current behaviour instead. +// In any case, it should maintain single argument per line. +fn do_this_that_and_the_other_thing( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: u8, + b: u8, + c: u8, + d: u8, +) { + this(); + that(); + the_other_thing(); +} diff --git a/src/tools/rustfmt/tests/target/fn_once.rs b/src/tools/rustfmt/tests/target/fn_once.rs new file mode 100644 index 000000000..42b8f98e7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/fn_once.rs @@ -0,0 +1,8 @@ +struct Add(usize); + +impl FnOnce<(usize,)> for Add { + type Output = Add; + extern "rust-call" fn call_once(self, to: (usize,)) -> Add { + Add(self.0 + to.0) + } +} diff --git a/src/tools/rustfmt/tests/target/format_strings/issue-202.rs b/src/tools/rustfmt/tests/target/format_strings/issue-202.rs new file mode 100644 index 000000000..2a2c24140 --- /dev/null +++ b/src/tools/rustfmt/tests/target/format_strings/issue-202.rs @@ -0,0 +1,25 @@ +// rustfmt-format_strings: true + +#[test] +fn compile_empty_program() { + let result = get_result(); + let expected = "; ModuleID = \'foo\' + +; Function Attrs: nounwind +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0 + +declare i32 @write(i32, i8*, i32) + +declare i32 @putchar(i32) + +declare i32 @getchar() + +define i32 @main() { +entry: + ret i32 0 +} + +attributes #0 = { nounwind } +"; + assert_eq!(result, CString::new(expected).unwrap()); +} diff --git a/src/tools/rustfmt/tests/target/format_strings/issue-2833.rs b/src/tools/rustfmt/tests/target/format_strings/issue-2833.rs new file mode 100644 index 000000000..704835325 --- /dev/null +++ b/src/tools/rustfmt/tests/target/format_strings/issue-2833.rs @@ -0,0 +1,15 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 80 + +fn test1() { + let expected = "\ +but Doctor Watson has to have it taken out for him and dusted, +"; +} + +fn test2() { + let expected = "\ +[Omitted long matching line] +but Doctor Watson has to have it taken out for him and dusted, +"; +} diff --git a/src/tools/rustfmt/tests/target/format_strings/issue-3263.rs b/src/tools/rustfmt/tests/target/format_strings/issue-3263.rs new file mode 100644 index 000000000..72f7e9cc6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/format_strings/issue-3263.rs @@ -0,0 +1,26 @@ +// rustfmt-format_strings: true +// rustfmt-newline_style: Windows + +#[test] +fn compile_empty_program() { + let result = get_result(); + let expected = "; ModuleID = \'foo\' + +; Function Attrs: nounwind +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0 + +declare i32 @write(i32, i8*, i32) + +declare i32 @putchar(i32) + +declare i32 @getchar() + +define i32 @main() { +entry: + ret i32 0 +} + +attributes #0 = { nounwind } +"; + assert_eq!(result, CString::new(expected).unwrap()); +} diff --git a/src/tools/rustfmt/tests/target/format_strings/issue-687.rs b/src/tools/rustfmt/tests/target/format_strings/issue-687.rs new file mode 100644 index 000000000..21d292f9e --- /dev/null +++ b/src/tools/rustfmt/tests/target/format_strings/issue-687.rs @@ -0,0 +1,10 @@ +// rustfmt-format_strings: true + +fn foo() -> &'static str { + let sql = "ATTACH DATABASE ':memory:' AS my_attached; + BEGIN; + CREATE TABLE my_attached.foo(x INTEGER); + INSERT INTO my_attached.foo VALUES(42); + END;"; + sql +} diff --git a/src/tools/rustfmt/tests/target/format_strings/issue564.rs b/src/tools/rustfmt/tests/target/format_strings/issue564.rs new file mode 100644 index 000000000..d9ef077c2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/format_strings/issue564.rs @@ -0,0 +1,7 @@ +// rustfmt-format_strings: true + +const USAGE: &'static str = " +Usage: codegen project <name> <digits> <len> <codes> <prizes> <step> <shift> + codegen regenerate <name> + codegen verify <name> <code> +"; diff --git a/src/tools/rustfmt/tests/target/hard-tabs.rs b/src/tools/rustfmt/tests/target/hard-tabs.rs new file mode 100644 index 000000000..aca7e09c0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/hard-tabs.rs @@ -0,0 +1,98 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-hard_tabs: true + +fn main() { + let x = Bar; + + let y = Foo { a: x }; + + Foo { + a: foo(), // comment + // comment + b: bar(), + ..something + }; + + fn foo(a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32) { + } + + let str = "AAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAa"; + + if let ( + some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple, + ) = 1 + 2 + 3 + {} + + if cond() { + something(); + } else if different_cond() { + something_else(); + } else { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + } + + unsafe /* very looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong + * comment */ { + } + + unsafe /* So this is a very long comment. + * Multi-line, too. + * Will it still format correctly? */ { + } + + let chain = funktion_kall() + .go_to_next_line_with_tab() + .go_to_next_line_with_tab() + .go_to_next_line_with_tab(); + + let z = [ + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + yyyyyyyyyyyyyyyyyyyyyyyyyyy, + zzzzzzzzzzzzzzzzzz, + q, + ]; + + fn generic<T>(arg: T) -> &SomeType + where + T: Fn( + // First arg + A, + // Second argument + B, + C, + D, + // pre comment + E, // last comment + ) -> &SomeType, + { + arg(a, b, c, d, e) + } + + loong_func().quux(move || if true { 1 } else { 2 }); + + fffffffffffffffffffffffffffffffffff(a, { + SCRIPT_TASK_ROOT.with(|root| { + *root.borrow_mut() = Some(&script_task); + }); + }); + a.b.c.d(); + + x().y(|| match cond() { + true => (), + false => (), + }); +} + +// #2296 +impl Foo { + // a comment + // on multiple lines + fn foo() { + // another comment + // on multiple lines + let x = true; + } +} diff --git a/src/tools/rustfmt/tests/target/hello.rs b/src/tools/rustfmt/tests/target/hello.rs new file mode 100644 index 000000000..d9f90b0b5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/hello.rs @@ -0,0 +1,8 @@ +// rustfmt-config: small_tabs.toml +// rustfmt-target: hello.rs + +// Smoke test - hello world. + +fn main() { + println!("Hello world!"); +} diff --git a/src/tools/rustfmt/tests/target/hex_literal_lower.rs b/src/tools/rustfmt/tests/target/hex_literal_lower.rs new file mode 100644 index 000000000..5c27fded1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/hex_literal_lower.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Lower +fn main() { + let h1 = 0xcafe_5ea7; + let h2 = 0xcafe_f00du32; +} diff --git a/src/tools/rustfmt/tests/target/hex_literal_preserve.rs b/src/tools/rustfmt/tests/target/hex_literal_preserve.rs new file mode 100644 index 000000000..e8774d0bb --- /dev/null +++ b/src/tools/rustfmt/tests/target/hex_literal_preserve.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Preserve +fn main() { + let h1 = 0xcAfE_5Ea7; + let h2 = 0xCaFe_F00du32; +} diff --git a/src/tools/rustfmt/tests/target/hex_literal_upper.rs b/src/tools/rustfmt/tests/target/hex_literal_upper.rs new file mode 100644 index 000000000..48bb93d2c --- /dev/null +++ b/src/tools/rustfmt/tests/target/hex_literal_upper.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Upper +fn main() { + let h1 = 0xCAFE_5EA7; + let h2 = 0xCAFE_F00Du32; +} diff --git a/src/tools/rustfmt/tests/target/if_while_or_patterns.rs b/src/tools/rustfmt/tests/target/if_while_or_patterns.rs new file mode 100644 index 000000000..61a357afc --- /dev/null +++ b/src/tools/rustfmt/tests/target/if_while_or_patterns.rs @@ -0,0 +1,38 @@ +#![feature(if_while_or_patterns)] + +fn main() { + if let 0 | 1 = 0 { + println!("hello, world"); + }; + + if let aaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbbbbbbbbbbbbbbbbbbb | cccccccccccccccc | d_100 = 0 { + println!("hello, world"); + } + + if let aaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbbbbbbbbbbbbbbb | ccccccccccccccccccccc | d_101 = 0 + { + println!("hello, world"); + } + + if let aaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbbbbbbbbbbbbbbb | ccccccccccccccccccccc | d_103 = + 0 + { + println!("hello, world"); + } + + if let aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | bbbbbbbbbbbbbbbbbbbbbbb + | ccccccccccccccccccccc + | d_105 = 0 + { + println!("hello, world"); + } + + while let xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx + | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx | xxx = foo_bar( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + cccccccccccccccccccccccccccccccccccccccc, + ) { + println!("hello, world"); + } +} diff --git a/src/tools/rustfmt/tests/target/immovable_generators.rs b/src/tools/rustfmt/tests/target/immovable_generators.rs new file mode 100644 index 000000000..0bf7a2d91 --- /dev/null +++ b/src/tools/rustfmt/tests/target/immovable_generators.rs @@ -0,0 +1,7 @@ +#![feature(generators)] + +unsafe fn foo() { + let mut ga = static || { + yield 1; + }; +} diff --git a/src/tools/rustfmt/tests/target/impl.rs b/src/tools/rustfmt/tests/target/impl.rs new file mode 100644 index 000000000..f37fbcf1f --- /dev/null +++ b/src/tools/rustfmt/tests/target/impl.rs @@ -0,0 +1,43 @@ +// Test impls + +impl<T> JSTraceable for SmallVec<[T; 1]> {} + +impl<K, V, NodeRef: Deref<Target = Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Internal> { + // Keep this. +} + +impl<V> Test<V> +where + V: Clone, // This comment is NOT removed by formatting! +{ + pub fn new(value: V) -> Self { + Test { + cloned_value: value.clone(), + value, + } + } +} + +impl X<T> /* comment */ {} +impl Y<T> // comment +{ +} + +impl<T> Foo for T +// comment1 +where + // comment2 + // blah + T: Clone, +{ +} + +// #1823 +default impl Trait for X {} +default unsafe impl Trait for Y {} +pub default unsafe impl Trait for Z {} + +// #2212 +impl ConstWithDefault { + default const CAN_RECONSTRUCT_QUERY_KEY: bool = false; +} diff --git a/src/tools/rustfmt/tests/target/impls.rs b/src/tools/rustfmt/tests/target/impls.rs new file mode 100644 index 000000000..99e02990e --- /dev/null +++ b/src/tools/rustfmt/tests/target/impls.rs @@ -0,0 +1,252 @@ +// rustfmt-normalize_comments: true +impl Foo for Bar { + fn foo() { + "hi" + } +} + +pub impl Foo for Bar { + // Associated Constants + const Baz: i32 = 16; + // Associated Types + type FooBar = usize; + // Comment 1 + fn foo() { + "hi" + } + // Comment 2 + fn foo() { + "hi" + } + // Comment 3 +} + +#[inherent] +impl Visible for Bar { + pub const C: i32; + pub type T; + pub fn f(); + pub fn g() {} +} + +pub unsafe impl<'a, 'b, X, Y: Foo<Bar>> !Foo<'a, X> for Bar<'b, Y> +where + X: Foo<'a, Z>, +{ + fn foo() { + "hi" + } +} + +impl<'a, 'b, X, Y: Foo<Bar>> Foo<'a, X> for Bar<'b, Y> +where + X: Fooooooooooooooooooooooooooooo<'a, Z>, +{ + fn foo() { + "hi" + } +} + +impl<'a, 'b, X, Y: Foo<Bar>> Foo<'a, X> for Bar<'b, Y> +where + X: Foooooooooooooooooooooooooooo<'a, Z>, +{ + fn foo() { + "hi" + } +} + +impl<T> Foo for Bar<T> where T: Baz {} + +impl<T> Foo for Bar<T> +where + T: Baz, +{ + // Comment +} + +impl Foo { + fn foo() {} +} + +impl Boo { + // BOO + fn boo() {} + // FOO +} + +mod a { + impl Foo { + // Hello! + fn foo() {} + } +} + +mod b { + mod a { + impl Foo { + fn foo() {} + } + } +} + +impl Foo { + add_fun!(); +} + +impl Blah { + fn boop() {} + add_fun!(); +} + +impl X { + fn do_parse(mut self: X) {} +} + +impl Y5000 { + fn bar(self: X<'a, 'b>, y: Y) {} + + fn bad(&self, (x, y): CoorT) {} + + fn turbo_bad(self: X<'a, 'b>, (x, y): CoorT) {} +} + +pub impl<T> Foo for Bar<T> +where + T: Foo, +{ + fn foo() { + "hi" + } +} + +pub impl<T, Z> Foo for Bar<T, Z> +where + T: Foo, + Z: Baz, +{ +} + +mod m { + impl<T> PartialEq for S<T> + where + T: PartialEq, + { + fn eq(&self, other: &Self) { + true + } + } + + impl<T> PartialEq for S<T> where T: PartialEq {} +} + +impl<BorrowType, K, V, NodeType, HandleType> + Handle<NodeRef<BorrowType, K, V, NodeType>, HandleType> +{ +} + +impl<BorrowType, K, V, NodeType, HandleType> PartialEq + for Handle<NodeRef<BorrowType, K, V, NodeType>, HandleType> +{ +} + +mod x { + impl<A, B, C, D> Foo + where + A: 'static, + B: 'static, + C: 'static, + D: 'static, + { + } +} + +impl<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNodeFoo> + Issue1249<ConcreteThreadSafeLayoutNode> +{ + // Creates a new flow constructor. + fn foo() {} +} + +// #1600 +impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> { + fn drop() {} +} + +// #1168 +pub trait Number: + Copy + + Eq + + Not<Output = Self> + + Shl<u8, Output = Self> + + Shr<u8, Output = Self> + + BitAnd<Self, Output = Self> + + BitOr<Self, Output = Self> + + BitAndAssign + + BitOrAssign +{ + // test + fn zero() -> Self; +} + +// #1642 +pub trait SomeTrait: + Clone + + Eq + + PartialEq + + Ord + + PartialOrd + + Default + + Hash + + Debug + + Display + + Write + + Read + + FromStr +{ + // comment +} + +// #1995 +impl Foo { + fn f( + S { + aaaaaaaaaa: aaaaaaaaaa, + bbbbbbbbbb: bbbbbbbbbb, + cccccccccc: cccccccccc, + }: S, + ) -> u32 { + 1 + } +} + +// #2491 +impl<'a, 'b, 'c> SomeThing<Something> + for ( + &'a mut SomethingLong, + &'b mut SomethingLong, + &'c mut SomethingLong, + ) +{ + fn foo() {} +} + +// #2746 +impl<'seq1, 'seq2, 'body, 'scope, Channel> + Adc12< + Dual, + MasterRunningDma<'seq1, 'body, 'scope, Channel>, + SlaveRunningDma<'seq2, 'body, 'scope>, + > +where + Channel: DmaChannel, +{ +} + +// #4084 +impl const std::default::Default for Struct { + #[inline] + fn default() -> Self { + Self { f: 12.5 } + } +} diff --git a/src/tools/rustfmt/tests/target/imports/import-fencepost-length.rs b/src/tools/rustfmt/tests/target/imports/import-fencepost-length.rs new file mode 100644 index 000000000..fd09d50d7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/import-fencepost-length.rs @@ -0,0 +1,7 @@ +use aaaaaaaaaaaaaaa::bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; +use aaaaaaaaaaaaaaa::{ + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, dddddddd, +}; +use aaaaaaaaaaaaaaa::{ + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddd, +}; diff --git a/src/tools/rustfmt/tests/target/imports/imports-impl-only-use.rs b/src/tools/rustfmt/tests/target/imports/imports-impl-only-use.rs new file mode 100644 index 000000000..d290d8d91 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports-impl-only-use.rs @@ -0,0 +1,4 @@ +#![feature(underscore_imports)] + +use attr; +use std::iter::Iterator as _; diff --git a/src/tools/rustfmt/tests/target/imports/imports-reorder-lines-and-items.rs b/src/tools/rustfmt/tests/target/imports/imports-reorder-lines-and-items.rs new file mode 100644 index 000000000..98a5afe43 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports-reorder-lines-and-items.rs @@ -0,0 +1,7 @@ +use std::cmp::{a, b, c, d}; +use std::ddd::aaa; +use std::ddd::{a, b, c as g, d as p}; +/// This comment should stay with `use std::str;` +use std::str; +// This comment should stay with `use std::ddd:bbb;` +use std::ddd::bbb; diff --git a/src/tools/rustfmt/tests/target/imports/imports-reorder-lines.rs b/src/tools/rustfmt/tests/target/imports/imports-reorder-lines.rs new file mode 100644 index 000000000..5b85503b5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports-reorder-lines.rs @@ -0,0 +1,31 @@ +use std::cmp::{a, b, c, d}; +use std::cmp::{b, e, f, g}; +use std::ddd::aaa; +use std::str; +// This comment should stay with `use std::ddd;` +use std::ddd; +use std::ddd::bbb; + +mod test {} + +use aaa; +use aaa::bbb; +use aaa::*; + +mod test {} +// If item names are equal, order by rename + +use test::{a as bb, b}; +use test::{a as aa, c}; + +mod test {} +// If item names are equal, order by rename - no rename comes before a rename + +use test::{a as bb, b}; +use test::{a, c}; + +mod test {} +// `self` always comes first + +use test::{self as bb, b}; +use test::{a as aa, c}; diff --git a/src/tools/rustfmt/tests/target/imports/imports-reorder.rs b/src/tools/rustfmt/tests/target/imports/imports-reorder.rs new file mode 100644 index 000000000..84e97c022 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports-reorder.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true + +use path::{self /* self */, /* A */ A, B /* B */, C}; + +use {aa, ab, ac, b, Z}; diff --git a/src/tools/rustfmt/tests/target/imports/imports.rs b/src/tools/rustfmt/tests/target/imports/imports.rs new file mode 100644 index 000000000..87584d89f --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports.rs @@ -0,0 +1,129 @@ +// rustfmt-normalize_comments: true + +// Imports. + +// Long import. +use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ + ItemA, ItemB, +}; +use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ + ItemA, ItemB, +}; +use rustc_ast::ast::{ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic}; + +use list::{ + // Another item + AnotherItem, // Another Comment + // Last Item + LastItem, + // Some item + SomeItem, // Comment +}; + +use test::{/* A */ self /* B */, Other /* C */}; + +pub use rustc_ast::ast::{Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath, Expr_}; +use rustc_ast::{self}; +use Foo::{Bar, Baz}; +use {Bar /* comment */, /* Pre-comment! */ Foo}; + +use std::io; +use std::io::{self}; + +mod Foo { + pub use rustc_ast::ast::{ + ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, + }; + + mod Foo2 { + pub use rustc_ast::ast::{ + self, ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, + }; + } +} + +fn test() { + use Baz::*; + use Qux; +} + +// Simple imports +use bar::quux as kaas; +use foo; +use foo::bar::baz; + +// With aliases. +use foo::qux as bar; +use foo::{self as bar}; +use foo::{self as bar, baz}; +use foo::{baz, qux as bar}; + +// With absolute paths +use foo; +use foo::Bar; +use foo::{Bar, Baz}; +use Foo; +use {Bar, Baz}; + +// Root globs +use *; +use *; + +// spaces used to cause glob imports to disappear (#1356) +use super::*; +use foo::issue_1356::*; + +// We shouldn't remove imports which have attributes attached (#1858) +#[cfg(unix)] +use self::unix::{}; + +// nested imports +use foo::{ + a, b, + bar::{ + baz, + foo::{a, b, cxxxxxxxxxxxxx, yyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz}, + qux, xxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, + }, + boo, c, +}; + +use fooo::{ + baar::foobar::{ + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, + zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, + }, + bar, + bar::*, + x, y, z, +}; + +use exonum::{ + api::{Api, ApiError}, + blockchain::{self, BlockProof, Blockchain, Transaction, TransactionSet}, + crypto::{Hash, PublicKey}, + helpers::Height, + node::TransactionSend, + storage::{ListProof, MapProof}, +}; + +// nested imports with a single sub-tree. +use a::b::c::d; +use a::b::c::*; +use a::b::c::{xxx, yyy, zzz}; + +// #2645 +/// This line is not affected. +// This line is deleted. +use c; + +// #2670 +#[macro_use] +use imports_with_attr; + +// #2888 +use std::f64::consts::{E, PI, SQRT_2}; + +// #3273 +#[rustfmt::skip] +use std::fmt::{self, {Display, Formatter}}; diff --git a/src/tools/rustfmt/tests/target/imports/imports_2021_edition.rs b/src/tools/rustfmt/tests/target/imports/imports_2021_edition.rs new file mode 100644 index 000000000..34dcc866a --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports_2021_edition.rs @@ -0,0 +1,3 @@ +// rustfmt-edition: 2021 + +use ::happy::new::year; diff --git a/src/tools/rustfmt/tests/target/imports/imports_block_indent.rs b/src/tools/rustfmt/tests/target/imports/imports_block_indent.rs new file mode 100644 index 000000000..8c90f7ce2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports_block_indent.rs @@ -0,0 +1,4 @@ +// #2569 +use apns2::request::notification::{ + Notificatio, NotificationBuilder, Priority, SilentNotificationBuilder, +}; diff --git a/src/tools/rustfmt/tests/target/imports/imports_granularity_crate.rs b/src/tools/rustfmt/tests/target/imports/imports_granularity_crate.rs new file mode 100644 index 000000000..36e01558f --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports_granularity_crate.rs @@ -0,0 +1,59 @@ +// rustfmt-imports_granularity: Crate + +use a::{a, b, c, d, e, f, g}; + +#[doc(hidden)] +use a::b; +use a::{c, d}; + +#[doc(hidden)] +use a::b; +use a::{c, d, e}; + +use foo::{a, b, c}; +pub use foo::{bar, foobar}; + +use a::b::c::{d, xxx, yyy, zzz, *}; + +// https://github.com/rust-lang/rustfmt/issues/3808 +use d::{self}; +use e::{self as foo}; +use f::{self, b}; +use g::{self, a, b}; +use h::a; +use i::a::{self}; +use j::a::{self}; + +use k::{a, b, c, d}; +use l::{a, b, c, d}; + +use b::q::{self /* After b::q::self */}; +use b::r; // After b::r +use b::s::{ + a, + b, // After b::s::b +}; +use b::t::{/* Before b::t::self */ self}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::{ + c, d, e, + u::{a, b}, +}; +use b::{ + f::g, + h::{i, j}, /* After b::h group */ +}; +use b::{ + /* Before b::l group */ l::{self, m, n::o, p::*}, + q, +}; diff --git a/src/tools/rustfmt/tests/target/imports/imports_granularity_default-with-dups.rs b/src/tools/rustfmt/tests/target/imports/imports_granularity_default-with-dups.rs new file mode 100644 index 000000000..5da6d588e --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports_granularity_default-with-dups.rs @@ -0,0 +1,6 @@ +use crate::lexer; +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::tokens::TokenData; +use crate::lexer::{self}; +use crate::lexer::{self, tokens::TokenData}; diff --git a/src/tools/rustfmt/tests/target/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs b/src/tools/rustfmt/tests/target/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs new file mode 100644 index 000000000..ed4df544d --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs @@ -0,0 +1,7 @@ +// rustfmt-imports_granularity: Item +// rustfmt-reorder_imports: false +// rustfmt-group_imports: StdExternalCrate + +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{self}; diff --git a/src/tools/rustfmt/tests/target/imports/imports_granularity_item-with-dups.rs b/src/tools/rustfmt/tests/target/imports/imports_granularity_item-with-dups.rs new file mode 100644 index 000000000..00df37f93 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports_granularity_item-with-dups.rs @@ -0,0 +1,5 @@ +// rustfmt-imports_granularity: Item + +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{self}; diff --git a/src/tools/rustfmt/tests/target/imports/imports_granularity_item.rs b/src/tools/rustfmt/tests/target/imports/imports_granularity_item.rs new file mode 100644 index 000000000..d2f5496fd --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports_granularity_item.rs @@ -0,0 +1,45 @@ +// rustfmt-imports_granularity: Item + +use a::b; +use a::c; +use a::d; +use a::f::g; +use a::h::i; +use a::h::j; +use a::l::m; +use a::l::n::o; +use a::l::p::*; +use a::l::{self}; +use a::q::{self}; + +use b::c; +use b::d; +use b::e; +use b::q::{self /* After b::q::self */}; +use b::r; // After b::r +use b::s::{ + a, + b, // After b::s::b +}; +use b::t::{/* Before b::t::self */ self}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::u::a; +use b::u::b; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::{ + f::g, + h::{i, j}, /* After b::h group */ +}; +use b::{ + /* Before b::l group */ l::{self, m, n::o, p::*}, + q, +}; diff --git a/src/tools/rustfmt/tests/target/imports/imports_granularity_module.rs b/src/tools/rustfmt/tests/target/imports/imports_granularity_module.rs new file mode 100644 index 000000000..14f341016 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports/imports_granularity_module.rs @@ -0,0 +1,55 @@ +// rustfmt-imports_granularity: Module + +use a::b::c; +use a::d::e; +use a::f; +use a::g::{h, i}; +use a::j::k::{self, l}; +use a::j::{self, m}; +use a::n::o::p; +use a::n::q; +pub use a::r::s; +pub use a::t; +use b::c::d; +use b::{self}; + +use foo::e; +#[cfg(test)] +use foo::{a::b, c::d}; + +use bar::{ + // comment + a::b, + // more comment + c::d, + e::f, +}; + +use b::q::{self /* After b::q::self */}; +use b::r; // After b::r +use b::s::{ + a, + b, // After b::s::b +}; +use b::t::{/* Before b::t::self */ self}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::u::{a, b}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::{c, d, e}; +use b::{ + f::g, + h::{i, j}, /* After b::h group */ +}; +use b::{ + /* Before b::l group */ l::{self, m, n::o, p::*}, + q, +}; diff --git a/src/tools/rustfmt/tests/target/imports_granularity_one.rs b/src/tools/rustfmt/tests/target/imports_granularity_one.rs new file mode 100644 index 000000000..da4c6678d --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports_granularity_one.rs @@ -0,0 +1,109 @@ +// rustfmt-imports_granularity: One + +use { + a::{ + aa::*, + ab, + ac::{aca, acb}, + }, + b, +}; + +use { + a::{self as x, aa, ab}, + b::ba, +}; + +use a::{ + aa::{aaa, *}, + ab::aba as x, +}; + +#[cfg(test)] +use a::{ab, ac::aca}; +#[cfg(test)] +use b::{ + ba, bb, + bc::bca::{bcaa, bcab}, +}; +use { + a::{aa, ad::ada}, + b, +}; + +pub use { + a::{aa, ae}, + b::{bb, bc::bca}, +}; +use { + a::{ab, ac, ad}, + b::ba, +}; + +use { + a::{ + aa::{aaa, *}, + ab, + ac::{aca, acb}, + }, + b::{ + ba, + bb::{self, bba}, + }, +}; + +use { + crate::{a, b::ba}, + c::ca, +}; + +use { + super::{a, b::ba}, + c::ca, +}; + +use { + super::b, + crate::a, + c::{self, ca}, +}; + +use a::{ + // some comment + aa::{aaa, aab}, + ab, + // another comment + ac::aca, +}; +use {a::ad::ada, b as x}; + +use b::q::{self /* After b::q::self */}; +use b::r; // After b::r +use b::s::{ + a, + b, // After b::s::b +}; +use b::t::{/* Before b::t::self */ self}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::{ + c, d, e, + u::{a, b}, +}; +use b::{ + f::g, + h::{i, j}, /* After b::h group */ +}; +use b::{ + /* Before b::l group */ l::{self, m, n::o, p::*}, + q, +}; diff --git a/src/tools/rustfmt/tests/target/imports_raw_identifiers/version_One.rs b/src/tools/rustfmt/tests/target/imports_raw_identifiers/version_One.rs new file mode 100644 index 000000000..bc4b5b135 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports_raw_identifiers/version_One.rs @@ -0,0 +1,5 @@ +// rustfmt-version:One + +use websocket::client::ClientBuilder; +use websocket::r#async::futures::Stream; +use websocket::result::WebSocketError; diff --git a/src/tools/rustfmt/tests/target/imports_raw_identifiers/version_Two.rs b/src/tools/rustfmt/tests/target/imports_raw_identifiers/version_Two.rs new file mode 100644 index 000000000..22bfe9312 --- /dev/null +++ b/src/tools/rustfmt/tests/target/imports_raw_identifiers/version_Two.rs @@ -0,0 +1,5 @@ +// rustfmt-version:Two + +use websocket::r#async::futures::Stream; +use websocket::client::ClientBuilder; +use websocket::result::WebSocketError; diff --git a/src/tools/rustfmt/tests/target/indented-impl.rs b/src/tools/rustfmt/tests/target/indented-impl.rs new file mode 100644 index 000000000..eff579ddd --- /dev/null +++ b/src/tools/rustfmt/tests/target/indented-impl.rs @@ -0,0 +1,13 @@ +// rustfmt-brace_style: AlwaysNextLine +mod x +{ + struct X(i8); + + impl Y for X + { + fn y(self) -> () + { + println!("ok"); + } + } +} diff --git a/src/tools/rustfmt/tests/target/inner-module-path/b.rs b/src/tools/rustfmt/tests/target/inner-module-path/b.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/target/inner-module-path/b.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/target/inner-module-path/c/d.rs b/src/tools/rustfmt/tests/target/inner-module-path/c/d.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/tools/rustfmt/tests/target/inner-module-path/c/d.rs @@ -0,0 +1 @@ + diff --git a/src/tools/rustfmt/tests/target/inner-module-path/lib.rs b/src/tools/rustfmt/tests/target/inner-module-path/lib.rs new file mode 100644 index 000000000..60d246dd5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/inner-module-path/lib.rs @@ -0,0 +1,8 @@ +#[path = "."] +mod a { + mod b; +} + +mod c { + mod d; +} diff --git a/src/tools/rustfmt/tests/target/invalid-rust-code-in-doc-comment.rs b/src/tools/rustfmt/tests/target/invalid-rust-code-in-doc-comment.rs new file mode 100644 index 000000000..f8479d4e3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/invalid-rust-code-in-doc-comment.rs @@ -0,0 +1,18 @@ +// rustfmt-format_code_in_doc_comments: true + +/// ```rust +/// if (true) { … } +/// ``` +fn a() {} + +/// ```rust +/// if foo() { +/// … +/// } +/// ``` +fn a() {} + +/// ```rust +/// k1 == k2 ⇒ hash(k1) == hash(k2) +/// ``` +pub struct a; diff --git a/src/tools/rustfmt/tests/target/issue-1021.rs b/src/tools/rustfmt/tests/target/issue-1021.rs new file mode 100644 index 000000000..ba1029d4e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1021.rs @@ -0,0 +1,22 @@ +// rustfmt-normalize_comments: true +fn main() { + match x { + S(true, .., true) => (), + S(true, ..) => (), + S(.., true) => (), + S(..) => (), + S(_) => (), + S(/* .. */ ..) => (), + S(/* .. */ .., true) => (), + } + + match y { + (true, .., true) => (), + (true, ..) => (), + (.., true) => (), + (..) => (), + (_,) => (), + (/* .. */ ..) => (), + (/* .. */ .., true) => (), + } +} diff --git a/src/tools/rustfmt/tests/target/issue-1049.rs b/src/tools/rustfmt/tests/target/issue-1049.rs new file mode 100644 index 000000000..c788519ca --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1049.rs @@ -0,0 +1,29 @@ +// Test overlong function signature +pub unsafe fn reborrow_mut( + &mut X: Abcde, +) -> Handle<NodeRef<marker::Mut, K, V, NodeType>, HandleType> { +} + +pub fn merge( + mut X: Abcdef, +) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge> { +} + +impl Handle { + pub fn merge( + a: Abcd, + ) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge> { + } +} + +// Long function without return type that should not be reformatted. +fn veeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {} + +fn veeeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) { +} + +fn veeeeeeeeeeeeeeeeeeeeeeery_long_name( + a: FirstTypeeeeeeeeee, + b: SecondTypeeeeeeeeeeeeeeeeeeeeeee, +) { +} diff --git a/src/tools/rustfmt/tests/target/issue-1055.rs b/src/tools/rustfmt/tests/target/issue-1055.rs new file mode 100644 index 000000000..ee143e792 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1055.rs @@ -0,0 +1,3 @@ +fn issue_1055() { + let foo = (|| {})(); +} diff --git a/src/tools/rustfmt/tests/target/issue-1096.rs b/src/tools/rustfmt/tests/target/issue-1096.rs new file mode 100644 index 000000000..de78e7364 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1096.rs @@ -0,0 +1,71 @@ +struct StructA<T> /* comment 1 */ { + t: T, +} + +struct StructB<T> /* comment 2 */; + +struct StructC /* comment 3 */; + +struct StructD /* comment 4 */ { + t: usize, +} + +struct StructE<T> +/* comment 5 */ +where + T: Clone, +{ + t: usize, +} + +struct StructF +/* comment 6 */ +where + T: Clone, +{ + t: usize, +} + +struct StructG<T> +/* comment 7 */ +// why a line comment?? +{ + t: T, +} + +struct StructH<T> +/* comment 8 */ +// why a line comment?? +where + T: Clone, +{ + t: T, +} + +enum EnumA<T> /* comment 8 */ { + Field(T), +} + +enum EnumB /* comment 9 */ { + Field, +} + +// Issue 2781 +struct StructX1<T> +// where +// T: Clone +{ + inner: String, +} + +struct StructX2< + T, + U: Iterator<Item = String>, + V: Iterator<Item = String>, + W: Iterator<Item = String>, +> +// where +// T: Clone +{ + inner: String, +} diff --git a/src/tools/rustfmt/tests/target/issue-1111.rs b/src/tools/rustfmt/tests/target/issue-1111.rs new file mode 100644 index 000000000..2e1a89ad7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1111.rs @@ -0,0 +1 @@ +use bar; diff --git a/src/tools/rustfmt/tests/target/issue-1113.rs b/src/tools/rustfmt/tests/target/issue-1113.rs new file mode 100644 index 000000000..1245bcd05 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1113.rs @@ -0,0 +1,33 @@ +pub fn foo() -> fmt::Result +//pub fn writeStringToken +{ + panic!() +} + +pub fn foo() -> fmt::Result // pub fn writeStringToken +{ + panic!() +} + +pub fn foo() -> fmt::Result /* pub fn writeStringToken */ { + panic!() +} + +pub fn foo() -> fmt::Result +/* pub fn writeStringToken */ { + panic!() +} + +pub fn foo() -> fmt::Result +/* pub fn writeStringToken */ +{ + panic!() +} + +pub fn foo() -> fmt::Result /* + * + * + */ +{ + panic!() +} diff --git a/src/tools/rustfmt/tests/target/issue-1120.rs b/src/tools/rustfmt/tests/target/issue-1120.rs new file mode 100644 index 000000000..f44597e7d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1120.rs @@ -0,0 +1,11 @@ +// rustfmt-reorder_imports: true + +// Ensure that a use at the start of an inline module is correctly formatted. +mod foo { + use bar; +} + +// Ensure that an indented `use` gets the correct indentation. +mod foo { + use bar; +} diff --git a/src/tools/rustfmt/tests/target/issue-1124.rs b/src/tools/rustfmt/tests/target/issue-1124.rs new file mode 100644 index 000000000..f0fc485a3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1124.rs @@ -0,0 +1,21 @@ +// rustfmt-reorder_imports: true + +use a; +use b; +use c; +use d; +// The previous line has a space after the `use a;` + +mod a { + use a; + use b; + use c; + use d; +} + +use z; + +use y; + +use a; +use x; diff --git a/src/tools/rustfmt/tests/target/issue-1127.rs b/src/tools/rustfmt/tests/target/issue-1127.rs new file mode 100644 index 000000000..fb09036d1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1127.rs @@ -0,0 +1,25 @@ +// rustfmt-max_width: 120 +// rustfmt-match_arm_blocks: false +// rustfmt-match_block_trailing_comma: true + +fn a_very_very_very_very_very_very_very_very_very_very_very_long_function_name() -> i32 { + 42 +} + +enum TestEnum { + AVeryVeryLongEnumName, + AnotherVeryLongEnumName, + TheLastVeryLongEnumName, +} + +fn main() { + let var = TestEnum::AVeryVeryLongEnumName; + let num = match var { + TestEnum::AVeryVeryLongEnumName => + a_very_very_very_very_very_very_very_very_very_very_very_long_function_name(), + TestEnum::AnotherVeryLongEnumName => + a_very_very_very_very_very_very_very_very_very_very_very_long_function_name(), + TestEnum::TheLastVeryLongEnumName => + a_very_very_very_very_very_very_very_very_very_very_very_long_function_name(), + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-1158.rs b/src/tools/rustfmt/tests/target/issue-1158.rs new file mode 100644 index 000000000..2abfa5a29 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1158.rs @@ -0,0 +1,3 @@ +trait T { + itemmacro!(this, is.now().formatted(yay)); +} diff --git a/src/tools/rustfmt/tests/target/issue-1177.rs b/src/tools/rustfmt/tests/target/issue-1177.rs new file mode 100644 index 000000000..dcda39728 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1177.rs @@ -0,0 +1,7 @@ +// rustfmt-normalize_comments: true +fn main() { + // Line Comment + // Block Comment + + let d = 5; +} diff --git a/src/tools/rustfmt/tests/target/issue-1192.rs b/src/tools/rustfmt/tests/target/issue-1192.rs new file mode 100644 index 000000000..432fe8cce --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1192.rs @@ -0,0 +1,3 @@ +fn main() { + assert!(true); +} diff --git a/src/tools/rustfmt/tests/target/issue-1210/a.rs b/src/tools/rustfmt/tests/target/issue-1210/a.rs new file mode 100644 index 000000000..94c1b44e5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1210/a.rs @@ -0,0 +1,16 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 + +impl Foo { + fn cxx(&self, target: &str) -> &Path { + match self.cxx.get(target) { + Some(p) => p.path(), + None => panic!( + "\n\ntarget `{}` is not \ + configured as a host, + only as a target\n\n", + target + ), + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-1210/b.rs b/src/tools/rustfmt/tests/target/issue-1210/b.rs new file mode 100644 index 000000000..a7b1e3bcd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1210/b.rs @@ -0,0 +1,16 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 + +impl Foo { + fn cxx(&self, target: &str) -> &Path { + match self.cxx.get(target) { + Some(p) => p.path(), + None => panic!( + "\ntarget `{}`: is not, \ + configured as a host, + only as a target\n\n", + target + ), + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-1210/c.rs b/src/tools/rustfmt/tests/target/issue-1210/c.rs new file mode 100644 index 000000000..183d79f92 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1210/c.rs @@ -0,0 +1,7 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 + +const foo: String = + "trailing_spaces!! + keep them! Amet neque. Praesent \ + rhoncus eros non velit."; diff --git a/src/tools/rustfmt/tests/target/issue-1210/d.rs b/src/tools/rustfmt/tests/target/issue-1210/d.rs new file mode 100644 index 000000000..9279e6fc9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1210/d.rs @@ -0,0 +1,4 @@ +// rustfmt-wrap_comments: true + +// trailing_spaces_in_comment!! +// remove those from above diff --git a/src/tools/rustfmt/tests/target/issue-1210/e.rs b/src/tools/rustfmt/tests/target/issue-1210/e.rs new file mode 100644 index 000000000..55f80c6c3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1210/e.rs @@ -0,0 +1,11 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 50 + +// explicit line breaks should be kept in order to preserve the layout + +const foo: String = + "Suspendisse vel augue at felis tincidunt \ + sollicitudin. Fusce arcu. + Duis et odio et leo + sollicitudin consequat. Aliquam \ + lobortis. Phasellus condimentum."; diff --git a/src/tools/rustfmt/tests/target/issue-1211.rs b/src/tools/rustfmt/tests/target/issue-1211.rs new file mode 100644 index 000000000..de4c5c87e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1211.rs @@ -0,0 +1,13 @@ +fn main() { + for iface in &ifaces { + match iface.addr { + get_if_addrs::IfAddr::V4(ref addr) => match addr.broadcast { + Some(ip) => { + sock.send_to(&buf, (ip, 8765)).expect("foobar"); + } + _ => (), + }, + _ => (), + }; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-1214.rs b/src/tools/rustfmt/tests/target/issue-1214.rs new file mode 100644 index 000000000..c622abb3a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1214.rs @@ -0,0 +1,8 @@ +/*! +# Example + +``` + // Here goes some example +``` + */ +struct Item; diff --git a/src/tools/rustfmt/tests/target/issue-1216.rs b/src/tools/rustfmt/tests/target/issue-1216.rs new file mode 100644 index 000000000..d727c158a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1216.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true +enum E { + A, //* I am not a block comment (caused panic) + B, +} diff --git a/src/tools/rustfmt/tests/target/issue-1239.rs b/src/tools/rustfmt/tests/target/issue-1239.rs new file mode 100644 index 000000000..e950200b1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1239.rs @@ -0,0 +1,11 @@ +fn foo() { + let with_alignment = if condition__uses_alignment_for_first_if__0 + || condition__uses_alignment_for_first_if__1 + || condition__uses_alignment_for_first_if__2 + { + } else if condition__no_alignment_for_later_else__0 + || condition__no_alignment_for_later_else__1 + || condition__no_alignment_for_later_else__2 + { + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-1247.rs b/src/tools/rustfmt/tests/target/issue-1247.rs new file mode 100644 index 000000000..16c63e0f5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1247.rs @@ -0,0 +1,8 @@ +// rustfmt-max_width: 80 + +fn foo() { + polyfill::slice::fill( + &mut self.pending[padding_pos..(self.algorithm.block_len - 8)], + 0, + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-1255.rs b/src/tools/rustfmt/tests/target/issue-1255.rs new file mode 100644 index 000000000..2d4633844 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1255.rs @@ -0,0 +1,10 @@ +// Test for issue #1255 +// Default annotation incorrectly removed on associated types +#![feature(specialization)] + +trait Trait { + type Type; +} +impl<T> Trait for T { + default type Type = u64; // 'default' should not be removed +} diff --git a/src/tools/rustfmt/tests/target/issue-1278.rs b/src/tools/rustfmt/tests/target/issue-1278.rs new file mode 100644 index 000000000..e25376561 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1278.rs @@ -0,0 +1,9 @@ +// rustfmt-indent_style = "block" + +#![feature(pub_restricted)] + +mod inner_mode { + pub(super) fn func_name(abc: i32) -> i32 { + abc + } +} diff --git a/src/tools/rustfmt/tests/target/issue-1350.rs b/src/tools/rustfmt/tests/target/issue-1350.rs new file mode 100644 index 000000000..2cf65509c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1350.rs @@ -0,0 +1,14 @@ +// rustfmt-max_width: 120 +// rustfmt-comment_width: 110 + +impl Struct { + fn fun() { + let result = match <R::RequestResult as serde::Deserialize>::deserialize(&json) { + Ok(v) => v, + Err(e) => match <R::ErrorResult as serde::Deserialize>::deserialize(&json) { + Ok(v) => return Err(Error::with_json(v)), + Err(e2) => return Err(Error::with_json(e)), + }, + }; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-1366.rs b/src/tools/rustfmt/tests/target/issue-1366.rs new file mode 100644 index 000000000..eee147baa --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1366.rs @@ -0,0 +1,13 @@ +fn main() { + fn f() -> Option<i32> { + Some("fffffffsssssssssddddssssfffffddddff") + .map(|s| s) + .map(|s| s.to_string()) + .map(|res| match Some(res) { + Some(ref s) if s == "" => 41, + Some(_) => 42, + _ => 43, + }) + } + println!("{:?}", f()) +} diff --git a/src/tools/rustfmt/tests/target/issue-1397.rs b/src/tools/rustfmt/tests/target/issue-1397.rs new file mode 100644 index 000000000..86b7a7841 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1397.rs @@ -0,0 +1,25 @@ +pub enum TransactionState { + Committed(i64), +} + +pub enum Packet { + Transaction { state: TransactionState }, +} + +fn baz(p: Packet) { + loop { + loop { + loop { + loop { + if let Packet::Transaction { + state: TransactionState::Committed(ts, ..), + .. + } = p + { + unreachable!() + } + } + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-1468.rs b/src/tools/rustfmt/tests/target/issue-1468.rs new file mode 100644 index 000000000..4c14a0f74 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1468.rs @@ -0,0 +1,29 @@ +fn issue1468() { + euc_jp_decoder_functions!({ + let trail_minus_offset = byte.wrapping_sub(0xA1); + // Fast-track Hiragana (60% according to Lunde) + // and Katakana (10% according to Lunde). + if jis0208_lead_minus_offset == 0x03 && trail_minus_offset < 0x53 { + // Hiragana + handle.write_upper_bmp(0x3041 + trail_minus_offset as u16) + } else if jis0208_lead_minus_offset == 0x04 && trail_minus_offset < 0x56 { + // Katakana + handle.write_upper_bmp(0x30A1 + trail_minus_offset as u16) + } else if trail_minus_offset > (0xFE - 0xA1) { + if byte < 0x80 { + return ( + DecoderResult::Malformed(1, 0), + unread_handle_trail.unread(), + handle.written(), + ); + } + return ( + DecoderResult::Malformed(2, 0), + unread_handle_trail.consumed(), + handle.written(), + ); + } else { + unreachable!(); + } + }); +} diff --git a/src/tools/rustfmt/tests/target/issue-1598.rs b/src/tools/rustfmt/tests/target/issue-1598.rs new file mode 100644 index 000000000..c7e02c961 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1598.rs @@ -0,0 +1,6 @@ +fn main() { + //foo + /* + */ + format!("hello"); +} diff --git a/src/tools/rustfmt/tests/target/issue-1624.rs b/src/tools/rustfmt/tests/target/issue-1624.rs new file mode 100644 index 000000000..477fc2735 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1624.rs @@ -0,0 +1,6 @@ +// #1624 +pub unsafe fn some_long_function_name( + arg1: Type1, + arg2: Type2, +) -> (SomeLongTypeName, AnotherLongTypeName, AnotherLongTypeName) { +} diff --git a/src/tools/rustfmt/tests/target/issue-1681.rs b/src/tools/rustfmt/tests/target/issue-1681.rs new file mode 100644 index 000000000..902765302 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1681.rs @@ -0,0 +1,21 @@ +// rustfmt-max_width: 80 + +// We would like to surround closure body with block when overflowing the last +// argument of function call if the last argument has condition and without +// block it may go multi lines. +fn foo() { + refmut_map_result(self.cache.borrow_mut(), |cache| { + match cache.entry(cache_key) { + Occupied(entry) => Ok(entry.into_mut()), + Vacant(entry) => { + let statement = { + let sql = try!(entry.key().sql(source)); + prepare_fn(&sql) + }; + + Ok(entry.insert(try!(statement))) + } + } + }) + .map(MaybeCached::Cached) +} diff --git a/src/tools/rustfmt/tests/target/issue-1693.rs b/src/tools/rustfmt/tests/target/issue-1693.rs new file mode 100644 index 000000000..85421a123 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1693.rs @@ -0,0 +1,10 @@ +fn issue1693() { + let pixel_data = vec![ + ( + f16::from_f32(0.82), + f16::from_f32(1.78), + f16::from_f32(0.21) + ); + 256 * 256 + ]; +} diff --git a/src/tools/rustfmt/tests/target/issue-1703.rs b/src/tools/rustfmt/tests/target/issue-1703.rs new file mode 100644 index 000000000..4079ef4cf --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1703.rs @@ -0,0 +1,9 @@ +// rustfmt should not remove doc comments or comments inside attributes. + +/** +This function has a block doc comment. + */ +fn test_function() {} + +#[foo /* do not remove this! */] +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/issue-1800.rs b/src/tools/rustfmt/tests/target/issue-1800.rs new file mode 100644 index 000000000..06c5cfd05 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1800.rs @@ -0,0 +1,3 @@ +#![doc(html_root_url = "http://example.com")] +#[cfg(feature = "foo")] +fn a() {} diff --git a/src/tools/rustfmt/tests/target/issue-1802.rs b/src/tools/rustfmt/tests/target/issue-1802.rs new file mode 100644 index 000000000..ef7ee8910 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1802.rs @@ -0,0 +1,9 @@ +// rustfmt-tab_spaces: 2 +// rustfmt-max_width: 30 + +enum F { + X { + a: dddddddddddddd, + b: eeeeeeeeeeeeeee, + }, +} diff --git a/src/tools/rustfmt/tests/target/issue-1824.rs b/src/tools/rustfmt/tests/target/issue-1824.rs new file mode 100644 index 000000000..1c4c2db46 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1824.rs @@ -0,0 +1,5 @@ +pub trait Ingredient +where + Self: Send, +{ +} diff --git a/src/tools/rustfmt/tests/target/issue-1914.rs b/src/tools/rustfmt/tests/target/issue-1914.rs new file mode 100644 index 000000000..d2d532af1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-1914.rs @@ -0,0 +1,7 @@ +// rustfmt-max_width: 80 + +extern "C" { + #[link_name = "_ZN7MyClass26example_check_no_collisionE"] + pub static mut MyClass_example_check_no_collision: + *const ::std::os::raw::c_int; +} diff --git a/src/tools/rustfmt/tests/target/issue-2025.rs b/src/tools/rustfmt/tests/target/issue-2025.rs new file mode 100644 index 000000000..38bf369be --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2025.rs @@ -0,0 +1,4 @@ +// See if rustfmt removes empty lines on top of the file. +pub fn foo() { + println!("hello, world"); +} diff --git a/src/tools/rustfmt/tests/target/issue-2103.rs b/src/tools/rustfmt/tests/target/issue-2103.rs new file mode 100644 index 000000000..5a043d54b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2103.rs @@ -0,0 +1,14 @@ +struct X +where + i32: Sized, +{ + x: i32, +} + +struct X +// with comment +where + i32: Sized, +{ + x: i32, +} diff --git a/src/tools/rustfmt/tests/target/issue-2111.rs b/src/tools/rustfmt/tests/target/issue-2111.rs new file mode 100644 index 000000000..42c1862e8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2111.rs @@ -0,0 +1,26 @@ +// An import with single line comments. +use super::{ + DelayChoice, + Destinations, + Holding, + LodaModel, + MethodDescription, + ModelBehaviour, + ModelEdges, + ModelProperties, + ModelRequestGraph, + ModelSelector, + RequestDescription, + StringMap, + Switch, + // ModelMetaData, + // Generated, + // SecondsString, + // DateString, + // ModelConfiguration, + // ModelRequests, + // RestResponse, + // RestResponseCode, + // UniformHolding + SCHEMA_VERSIONS, +}; diff --git a/src/tools/rustfmt/tests/target/issue-2123.rs b/src/tools/rustfmt/tests/target/issue-2123.rs new file mode 100644 index 000000000..5e9917b40 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2123.rs @@ -0,0 +1,6 @@ +// rustfmt-wrap_comments: true + +//hello +//world + +fn main() {} diff --git a/src/tools/rustfmt/tests/target/issue-2164.rs b/src/tools/rustfmt/tests/target/issue-2164.rs new file mode 100644 index 000000000..dbf92107c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2164.rs @@ -0,0 +1,135 @@ +// A stress test against code generated by bindgen. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct emacs_env_25 { + pub size: isize, + pub private_members: *mut emacs_env_private, + pub make_global_ref: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, any_reference: emacs_value) -> emacs_value, + >, + pub free_global_ref: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, global_reference: emacs_value), + >, + pub non_local_exit_check: + ::std::option::Option<unsafe extern "C" fn(env: *mut emacs_env) -> emacs_funcall_exit>, + pub non_local_exit_clear: ::std::option::Option<unsafe extern "C" fn(env: *mut emacs_env)>, + pub non_local_exit_get: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + non_local_exit_symbol_out: *mut emacs_value, + non_local_exit_data_out: *mut emacs_value, + ) -> emacs_funcall_exit, + >, + pub non_local_exit_signal: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + non_local_exit_symbol: emacs_value, + non_local_exit_data: emacs_value, + ), + >, + pub non_local_exit_throw: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, tag: emacs_value, value: emacs_value), + >, + pub make_function: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + min_arity: isize, + max_arity: isize, + function: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + nargs: isize, + args: *mut emacs_value, + arg1: *mut ::libc::c_void, + ) -> emacs_value, + >, + documentation: *const ::libc::c_char, + data: *mut ::libc::c_void, + ) -> emacs_value, + >, + pub funcall: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + function: emacs_value, + nargs: isize, + args: *mut emacs_value, + ) -> emacs_value, + >, + pub intern: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + symbol_name: *const ::libc::c_char, + ) -> emacs_value, + >, + pub type_of: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, value: emacs_value) -> emacs_value, + >, + pub is_not_nil: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, value: emacs_value) -> bool, + >, + pub eq: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, a: emacs_value, b: emacs_value) -> bool, + >, + pub extract_integer: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, value: emacs_value) -> intmax_t, + >, + pub make_integer: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, value: intmax_t) -> emacs_value, + >, + pub extract_float: + ::std::option::Option<unsafe extern "C" fn(env: *mut emacs_env, value: emacs_value) -> f64>, + pub make_float: + ::std::option::Option<unsafe extern "C" fn(env: *mut emacs_env, value: f64) -> emacs_value>, + pub copy_string_contents: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + value: emacs_value, + buffer: *mut ::libc::c_char, + size_inout: *mut isize, + ) -> bool, + >, + pub make_string: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + contents: *const ::libc::c_char, + length: isize, + ) -> emacs_value, + >, + pub make_user_ptr: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + fin: ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::libc::c_void)>, + ptr: *mut ::libc::c_void, + ) -> emacs_value, + >, + pub get_user_ptr: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, uptr: emacs_value) -> *mut ::libc::c_void, + >, + pub set_user_ptr: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, uptr: emacs_value, ptr: *mut ::libc::c_void), + >, + pub get_user_finalizer: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::libc::c_void, + env: *mut emacs_env, + uptr: emacs_value, + ) -> ::std::option::Option< + unsafe extern "C" fn(arg1: *mut ::libc::c_void, env: *mut emacs_env, uptr: emacs_value), + >, + >, + pub set_user_finalizer: ::std::option::Option< + unsafe extern "C" fn( + env: *mut emacs_env, + uptr: emacs_value, + fin: ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::libc::c_void)>, + ), + >, + pub vec_get: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, vec: emacs_value, i: isize) -> emacs_value, + >, + pub vec_set: ::std::option::Option< + unsafe extern "C" fn(env: *mut emacs_env, vec: emacs_value, i: isize, val: emacs_value), + >, + pub vec_size: + ::std::option::Option<unsafe extern "C" fn(env: *mut emacs_env, vec: emacs_value) -> isize>, +} diff --git a/src/tools/rustfmt/tests/target/issue-2179/one.rs b/src/tools/rustfmt/tests/target/issue-2179/one.rs new file mode 100644 index 000000000..3f98acc8d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2179/one.rs @@ -0,0 +1,37 @@ +// rustfmt-version: One +// rustfmt-error_on_line_overflow: false + +fn issue_2179() { + let (opts, rustflags, clear_env_rust_log) = { + // We mustn't lock configuration for the whole build process + let rls_config = rls_config.lock().unwrap(); + + let opts = CargoOptions::new(&rls_config); + trace!("Cargo compilation options:\n{:?}", opts); + let rustflags = prepare_cargo_rustflags(&rls_config); + + // Warn about invalid specified bin target or package depending on current mode + // TODO: Return client notifications along with diagnostics to inform the user + if !rls_config.workspace_mode { + let cur_pkg_targets = ws.current().unwrap().targets(); + + if let &Some(ref build_bin) = rls_config.build_bin.as_ref() { + let mut bins = cur_pkg_targets.iter().filter(|x| x.is_bin()); + if let None = bins.find(|x| x.name() == build_bin) { + warn!( + "cargo - couldn't find binary `{}` specified in `build_bin` configuration", + build_bin + ); + } + } + } else { + for package in &opts.package { + if let None = ws.members().find(|x| x.name() == package) { + warn!("cargo - couldn't find member package `{}` specified in `analyze_package` configuration", package); + } + } + } + + (opts, rustflags, rls_config.clear_env_rust_log) + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-2179/two.rs b/src/tools/rustfmt/tests/target/issue-2179/two.rs new file mode 100644 index 000000000..96531509e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2179/two.rs @@ -0,0 +1,40 @@ +// rustfmt-version: Two +// rustfmt-error_on_line_overflow: false + +fn issue_2179() { + let (opts, rustflags, clear_env_rust_log) = { + // We mustn't lock configuration for the whole build process + let rls_config = rls_config.lock().unwrap(); + + let opts = CargoOptions::new(&rls_config); + trace!("Cargo compilation options:\n{:?}", opts); + let rustflags = prepare_cargo_rustflags(&rls_config); + + // Warn about invalid specified bin target or package depending on current mode + // TODO: Return client notifications along with diagnostics to inform the user + if !rls_config.workspace_mode { + let cur_pkg_targets = ws.current().unwrap().targets(); + + if let &Some(ref build_bin) = rls_config.build_bin.as_ref() { + let mut bins = cur_pkg_targets.iter().filter(|x| x.is_bin()); + if let None = bins.find(|x| x.name() == build_bin) { + warn!( + "cargo - couldn't find binary `{}` specified in `build_bin` configuration", + build_bin + ); + } + } + } else { + for package in &opts.package { + if let None = ws.members().find(|x| x.name() == package) { + warn!( + "cargo - couldn't find member package `{}` specified in `analyze_package` configuration", + package + ); + } + } + } + + (opts, rustflags, rls_config.clear_env_rust_log) + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-2197.rs b/src/tools/rustfmt/tests/target/issue-2197.rs new file mode 100644 index 000000000..d42c08e19 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2197.rs @@ -0,0 +1,17 @@ +// rustfmt-max_width: 79 +// rustfmt-wrap_comments: true + +/// ```rust +/// unsafe fn sum_sse2(x: i32x4) -> i32 { +/// let x = vendor::_mm_add_epi32( +/// x, +/// vendor::_mm_srli_si128(x.into(), 8).into(), +/// ); +/// let x = vendor::_mm_add_epi32( +/// x, +/// vendor::_mm_srli_si128(x.into(), 4).into(), +/// ); +/// vendor::_mm_cvtsi128_si32(x) +/// } +/// ``` +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/issue-2256.rs b/src/tools/rustfmt/tests/target/issue-2256.rs new file mode 100644 index 000000000..0a59c3083 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2256.rs @@ -0,0 +1,7 @@ +// こんにちは +use std::borrow::Cow; + +/* comment 1 */ +/* comment 2 */ + +/* comment 3 */ diff --git a/src/tools/rustfmt/tests/target/issue-2324.rs b/src/tools/rustfmt/tests/target/issue-2324.rs new file mode 100644 index 000000000..9211b24d8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2324.rs @@ -0,0 +1,7 @@ +// nested function calls with cast. +fn main() { + self.ptr + .set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) as *mut T); + self.ptr + .set(intrinsics::arith_offset(self.ptr.get(), mem::size_of::<T>() as isize) as *mut u8); +} diff --git a/src/tools/rustfmt/tests/target/issue-2329.rs b/src/tools/rustfmt/tests/target/issue-2329.rs new file mode 100644 index 000000000..e36e9546b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2329.rs @@ -0,0 +1,30 @@ +// Comments with characters which must be represented by multibyte. + +// フー +use foo; +// バー +use bar; + +impl MyStruct { + // コメント + fn f1() {} // こんにちは + fn f2() {} // ありがとう + // コメント +} + +trait MyTrait { + // コメント + fn f1() {} // こんにちは + fn f2() {} // ありがとう + // コメント +} + +fn main() { + // コメント + let x = 1; // X + println!( + "x = {}", // xの値 + x, // X + ); + // コメント +} diff --git a/src/tools/rustfmt/tests/target/issue-2342.rs b/src/tools/rustfmt/tests/target/issue-2342.rs new file mode 100644 index 000000000..f9c26857e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2342.rs @@ -0,0 +1,6 @@ +// rustfmt-max_width: 80 + +struct Foo { + #[cfg(feature = "serde")] + bytes: [[u8; 17]; 5], // Same size as signature::ED25519_PKCS8_V2_LEN +} diff --git a/src/tools/rustfmt/tests/target/issue-2346.rs b/src/tools/rustfmt/tests/target/issue-2346.rs new file mode 100644 index 000000000..07817221a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2346.rs @@ -0,0 +1,4 @@ +// rustfmt-normalize_comments: true +// the following empty comment should not have any trailing space added. +// +fn main() {} diff --git a/src/tools/rustfmt/tests/target/issue-2401.rs b/src/tools/rustfmt/tests/target/issue-2401.rs new file mode 100644 index 000000000..ec8f27b73 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2401.rs @@ -0,0 +1,7 @@ +// rustfmt-hard_tabs = true +// rustfmt-normalize_comments = true + +/// ``` +/// println!("Hello, World!"); +/// ``` +fn main() {} diff --git a/src/tools/rustfmt/tests/target/issue-2445.rs b/src/tools/rustfmt/tests/target/issue-2445.rs new file mode 100644 index 000000000..1bc7752fd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2445.rs @@ -0,0 +1,21 @@ +test!(RunPassPretty { + // comment + path: "src/test/run-pass/pretty", + mode: "pretty", + suite: "run-pass", + default: false, + host: true // should, force, , no trailing comma here +}); + +test!(RunPassPretty { + // comment + path: "src/test/run-pass/pretty", + mode: "pretty", + suite: "run-pass", + default: false, + host: true, // should, , preserve, the trailing comma +}); + +test!(Test { + field: i32, // comment +}); diff --git a/src/tools/rustfmt/tests/target/issue-2446.rs b/src/tools/rustfmt/tests/target/issue-2446.rs new file mode 100644 index 000000000..be62e9c9c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2446.rs @@ -0,0 +1,9 @@ +enum Issue2446 { + V { + f: u8, // x + }, +} + +enum Issue2446TrailingCommentsOnly { + V { f: u8 /* */ }, +} diff --git a/src/tools/rustfmt/tests/target/issue-2479.rs b/src/tools/rustfmt/tests/target/issue-2479.rs new file mode 100644 index 000000000..3683ab220 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2479.rs @@ -0,0 +1,12 @@ +// Long attributes. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum POLARITYR { + #[doc = "Task mode: No effect on pin from OUT[n] task. Event mode: no IN[n] event generated on pin activity."] + NONE, + #[doc = "Task mode: Set pin from OUT[n] task. Event mode: Generate IN[n] event when rising edge on pin."] + LOTOHI, + #[doc = "Task mode: Clear pin from OUT[n] task. Event mode: Generate IN[n] event when falling edge on pin."] + HITOLO, + #[doc = "Task mode: Toggle pin from OUT[n]. Event mode: Generate IN[n] when any change on pin."] + TOGGLE, +} diff --git a/src/tools/rustfmt/tests/target/issue-2482/a.rs b/src/tools/rustfmt/tests/target/issue-2482/a.rs new file mode 100644 index 000000000..fbbcb52a8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2482/a.rs @@ -0,0 +1,9 @@ +// rustfmt-reorder_modules: true + +// Do not reorder inline modules. + +mod c; +mod a { + fn a() {} +} +mod b; diff --git a/src/tools/rustfmt/tests/target/issue-2482/b.rs b/src/tools/rustfmt/tests/target/issue-2482/b.rs new file mode 100644 index 000000000..40a8d9421 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2482/b.rs @@ -0,0 +1 @@ +pub fn b() {} diff --git a/src/tools/rustfmt/tests/target/issue-2482/c.rs b/src/tools/rustfmt/tests/target/issue-2482/c.rs new file mode 100644 index 000000000..d93754551 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2482/c.rs @@ -0,0 +1 @@ +pub fn c() {} diff --git a/src/tools/rustfmt/tests/target/issue-2496.rs b/src/tools/rustfmt/tests/target/issue-2496.rs new file mode 100644 index 000000000..60c4f55dd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2496.rs @@ -0,0 +1,14 @@ +// rustfmt-indent_style: Visual +fn main() { + match option { + None => some_function(first_reasonably_long_argument, + second_reasonably_long_argument), + } +} + +fn main() { + match option { + None => some_function(first_reasonably_long_argument, + second_reasonably_long_argument), + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2520.rs b/src/tools/rustfmt/tests/target/issue-2520.rs new file mode 100644 index 000000000..7c134d397 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2520.rs @@ -0,0 +1,13 @@ +// rustfmt-normalize_comments: true +// rustfmt-format_code_in_doc_comments: true + +//! ```rust +//! println!("hello, world"); +//! ``` + +#![deny(missing_docs)] + +//! ```rust +//! println!("hello, world"); + +#![deny(missing_docs)] diff --git a/src/tools/rustfmt/tests/target/issue-2523.rs b/src/tools/rustfmt/tests/target/issue-2523.rs new file mode 100644 index 000000000..612f93249 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2523.rs @@ -0,0 +1,20 @@ +// rustfmt-normalize_comments: true +// rustfmt-format_code_in_doc_comments: true + +// Do not unindent macro calls in comment with unformattable syntax. +//! ```rust +//! let x = 3 ; +//! some_macro!(pub fn fn foo() ( +//! println!("Don't unindent me!"); +//! )); +//! ``` + +// Format items that appear as arguments of macro call. +//! ```rust +//! let x = 3; +//! some_macro!( +//! pub fn foo() { +//! println!("Don't unindent me!"); +//! } +//! ); +//! ``` diff --git a/src/tools/rustfmt/tests/target/issue-2526.rs b/src/tools/rustfmt/tests/target/issue-2526.rs new file mode 100644 index 000000000..7dd58aba3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2526.rs @@ -0,0 +1,8 @@ +// Test that rustfmt will not warn about comments exceeding max width around lifetime. +// See #2526. + +// comment comment comment comment comment comment comment comment comment comment comment comment comment +fn foo() -> F<'a> { + bar() +} +// comment comment comment comment comment comment comment comment comment comment comment comment comment diff --git a/src/tools/rustfmt/tests/target/issue-2551.rs b/src/tools/rustfmt/tests/target/issue-2551.rs new file mode 100644 index 000000000..d7b0d625b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2551.rs @@ -0,0 +1,3 @@ +mcro!(func(A { + a: 12345667800111111111111, +})); diff --git a/src/tools/rustfmt/tests/target/issue-2554.rs b/src/tools/rustfmt/tests/target/issue-2554.rs new file mode 100644 index 000000000..d5f0563a6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2554.rs @@ -0,0 +1,13 @@ +// #2554 +// Do not add the beginning vert to the first match arm's pattern. + +fn main() { + match foo(|_| { + bar(|_| { + // + }) + }) { + Ok(()) => (), + Err(_) => (), + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2582.rs b/src/tools/rustfmt/tests/target/issue-2582.rs new file mode 100644 index 000000000..f328e4d9d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2582.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/src/tools/rustfmt/tests/target/issue-2641.rs b/src/tools/rustfmt/tests/target/issue-2641.rs new file mode 100644 index 000000000..fbf5326c3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2641.rs @@ -0,0 +1,3 @@ +macro_rules! a { + () => {{}}; +} diff --git a/src/tools/rustfmt/tests/target/issue-2644.rs b/src/tools/rustfmt/tests/target/issue-2644.rs new file mode 100644 index 000000000..a87e4c0b4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2644.rs @@ -0,0 +1,8 @@ +// rustfmt-max_width: 80 +fn foo(e: Enum) { + match e { + Enum::Var { element1, element2 } => { + return; + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2673-nonmodrs-mods/foo.rs b/src/tools/rustfmt/tests/target/issue-2673-nonmodrs-mods/foo.rs new file mode 100644 index 000000000..5340816d6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2673-nonmodrs-mods/foo.rs @@ -0,0 +1,4 @@ +// rustfmt-config: skip_children.toml +mod bar; + +mod baz {} diff --git a/src/tools/rustfmt/tests/target/issue-2673-nonmodrs-mods/foo/bar.rs b/src/tools/rustfmt/tests/target/issue-2673-nonmodrs-mods/foo/bar.rs new file mode 100644 index 000000000..9ceacd59d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2673-nonmodrs-mods/foo/bar.rs @@ -0,0 +1 @@ +fn dummy() {} diff --git a/src/tools/rustfmt/tests/target/issue-2673-nonmodrs-mods/lib.rs b/src/tools/rustfmt/tests/target/issue-2673-nonmodrs-mods/lib.rs new file mode 100644 index 000000000..82425de56 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2673-nonmodrs-mods/lib.rs @@ -0,0 +1,6 @@ +#![feature(non_modrs_mods)] + +// Test that submodules in non-mod.rs files work. This is just an idempotence +// test since we just want to verify that rustfmt doesn't fail. + +mod foo; diff --git a/src/tools/rustfmt/tests/target/issue-2728.rs b/src/tools/rustfmt/tests/target/issue-2728.rs new file mode 100644 index 000000000..6cb41b75b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2728.rs @@ -0,0 +1,8 @@ +// rustfmt-wrap_comments: true +// rustfmt-newline_style: Windows + +//! ```rust +//! extern crate uom; +//! ``` + +fn main() {} diff --git a/src/tools/rustfmt/tests/target/issue-2759.rs b/src/tools/rustfmt/tests/target/issue-2759.rs new file mode 100644 index 000000000..b7176ec66 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2759.rs @@ -0,0 +1,65 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 89 + +// Code block in doc comments that will exceed max width. +/// ```rust +/// extern crate actix_web; +/// use actix_web::{actix, server, App, HttpResponse}; +/// +/// fn main() { +/// // Run actix system, this method actually starts all async processes +/// actix::System::run(|| { +/// server::new(|| App::new().resource("/", |r| r.h(|_| HttpResponse::Ok()))) +/// .bind("127.0.0.1:0") +/// .expect("Can not bind to 127.0.0.1:0") +/// .start(); +/// # actix::Arbiter::system().do_send(actix::msgs::SystemExit(0)); +/// }); +/// } +/// ``` +fn foo() {} + +// Code block in doc comments without the closing '```'. +/// ```rust +/// # extern crate actix_web; +/// use actix_web::{App, HttpResponse, http}; +/// +/// fn main() { +/// let app = App::new() +/// .resource( +/// "/", |r| r.method(http::Method::GET).f(|r| HttpResponse::Ok())) +/// .finish(); +/// } +fn bar() {} + +// `#` with indent. +/// ```rust +/// # use std::thread; +/// # extern crate actix_web; +/// use actix_web::{server, App, HttpResponse}; +/// +/// struct State1; +/// +/// struct State2; +/// +/// fn main() { +/// # thread::spawn(|| { +/// server::new(|| { +/// vec![ +/// App::with_state(State1) +/// .prefix("/app1") +/// .resource("/", |r| r.f(|r| HttpResponse::Ok())) +/// .boxed(), +/// App::with_state(State2) +/// .prefix("/app2") +/// .resource("/", |r| r.f(|r| HttpResponse::Ok())) +/// .boxed(), +/// ] +/// }) +/// .bind("127.0.0.1:8080") +/// .unwrap() +/// .run() +/// # }); +/// } +/// ``` +fn foobar() {} diff --git a/src/tools/rustfmt/tests/target/issue-2761.rs b/src/tools/rustfmt/tests/target/issue-2761.rs new file mode 100644 index 000000000..ae4086617 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2761.rs @@ -0,0 +1,15 @@ +const DATA: &'static [u8] = &[ + 0x42, 0x50, 0x54, 0x44, //type + 0x23, 0x00, 0x00, 0x00, //size + 0x00, 0x00, 0x04, 0x00, //flags + 0xEC, 0x0C, 0x00, 0x00, //id + 0x00, 0x00, 0x00, 0x00, //revision + 0x2B, 0x00, //version + 0x00, 0x00, //unknown + 0x42, 0x50, 0x54, 0x4E, //field type + 0x1D, 0x00, //field size + 0x19, 0x00, 0x00, 0x00, //decompressed field size + 0x75, 0xc5, 0x21, 0x0d, 0x00, 0x00, 0x08, 0x05, 0xd1, 0x6c, //field data (compressed) + 0x6c, 0xdc, 0x57, 0x48, 0x3c, 0xfd, 0x5b, 0x5c, 0x02, 0xd4, //field data (compressed) + 0x6b, 0x32, 0xb5, 0xdc, 0xa3, //field data (compressed) +]; diff --git a/src/tools/rustfmt/tests/target/issue-2781.rs b/src/tools/rustfmt/tests/target/issue-2781.rs new file mode 100644 index 000000000..f144d716b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2781.rs @@ -0,0 +1,11 @@ +pub // Oh, no. A line comment. +struct Foo {} + +pub /* Oh, no. A block comment. */ struct Foo {} + +mod inner { + pub // Oh, no. A line comment. + struct Foo {} + + pub /* Oh, no. A block comment. */ struct Foo {} +} diff --git a/src/tools/rustfmt/tests/target/issue-2794.rs b/src/tools/rustfmt/tests/target/issue-2794.rs new file mode 100644 index 000000000..951c0af20 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2794.rs @@ -0,0 +1,12 @@ +// rustfmt-indent_style: Block +// rustfmt-imports_indent: Block +// rustfmt-imports_layout: Vertical + +use std::{ + env, + fs, + io::{ + Read, + Write, + }, +}; diff --git a/src/tools/rustfmt/tests/target/issue-2810.rs b/src/tools/rustfmt/tests/target/issue-2810.rs new file mode 100644 index 000000000..34140c7a1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2810.rs @@ -0,0 +1,14 @@ +// rustfmt-newline_style: Windows + +#[macro_export] +macro_rules! hmmm___ffi_error { + ($result:ident) => { + pub struct $result { + success: bool, + } + + impl $result { + pub fn foo(self) {} + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-2835.rs b/src/tools/rustfmt/tests/target/issue-2835.rs new file mode 100644 index 000000000..21e8ce411 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2835.rs @@ -0,0 +1,4 @@ +// rustfmt-brace_style: AlwaysNextLine +// rustfmt-fn_single_line: true + +fn lorem() -> i32 { 42 } diff --git a/src/tools/rustfmt/tests/target/issue-2863.rs b/src/tools/rustfmt/tests/target/issue-2863.rs new file mode 100644 index 000000000..35a80f7a6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2863.rs @@ -0,0 +1,54 @@ +// rustfmt-reorder_impl_items: true + +impl<T> IntoIterator for SafeVec<T> { + type Bar = u32; + type BarFoo = u32; + type FooBar = u32; + // comment on FoooooBar + type FoooooBar = u32; + type IntoIter = self::IntoIter<T>; + type Item = T; + + type E = impl Trait; + type F = impl Trait; + + const AnotherConst: i32 = 100; + const SomeConst: i32 = 100; + + // comment on foo() + fn foo() { + println!("hello, world"); + } + + fn foo1() { + println!("hello, world"); + } + + fn foo2() { + println!("hello, world"); + } + + fn foo3() { + println!("hello, world"); + } + + fn foo4() { + println!("hello, world"); + } + + fn foo5() { + println!("hello, world"); + } + + fn foo6() { + println!("hello, world"); + } + + fn foo7() { + println!("hello, world"); + } + + fn foo8() { + println!("hello, world"); + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2869.rs b/src/tools/rustfmt/tests/target/issue-2869.rs new file mode 100644 index 000000000..6a68c2d95 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2869.rs @@ -0,0 +1,41 @@ +// rustfmt-struct_field_align_threshold: 50 + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "PascalCase")] +struct AuditLog1 { + creation_time: String, + id: String, + operation: String, + organization_id: String, + record_type: u32, + result_status: Option<String>, + #[serde(rename = "ClientIP")] + client_ip: Option<IpAddr>, + object_id: String, + actor: Option<Vec<IDType>>, + actor_context_id: Option<String>, + actor_ip_address: Option<IpAddr>, + azure_active_directory_event_type: Option<u8>, + + #[serde(rename = "very")] + aaaaa: String, + #[serde(rename = "cool")] + bb: i32, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "PascalCase")] +struct AuditLog2 { + creation_time: String, + id: String, + operation: String, + organization_id: String, + record_type: u32, + result_status: Option<String>, + client_ip: Option<IpAddr>, + object_id: String, + actor: Option<Vec<IDType>>, + actor_context_id: Option<String>, + actor_ip_address: Option<IpAddr>, + azure_active_directory_event_type: Option<u8>, +} diff --git a/src/tools/rustfmt/tests/target/issue-2896.rs b/src/tools/rustfmt/tests/target/issue-2896.rs new file mode 100644 index 000000000..6fb6b12ed --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2896.rs @@ -0,0 +1,165 @@ +extern crate differential_dataflow; +extern crate rand; +extern crate timely; + +use rand::{Rng, SeedableRng, StdRng}; + +use timely::dataflow::operators::*; + +use differential_dataflow::input::InputSession; +use differential_dataflow::operators::*; +use differential_dataflow::AsCollection; + +// mod loglikelihoodratio; + +fn main() { + // define a new timely dataflow computation. + timely::execute_from_args(std::env::args().skip(6), move |worker| { + // capture parameters of the experiment. + let users: usize = std::env::args().nth(1).unwrap().parse().unwrap(); + let items: usize = std::env::args().nth(2).unwrap().parse().unwrap(); + let scale: usize = std::env::args().nth(3).unwrap().parse().unwrap(); + let batch: usize = std::env::args().nth(4).unwrap().parse().unwrap(); + let noisy: bool = std::env::args().nth(5).unwrap() == "noisy"; + + let index = worker.index(); + let peers = worker.peers(); + + let (input, probe) = worker.dataflow(|scope| { + // input of (user, item) collection. + let (input, occurrences) = scope.new_input(); + let occurrences = occurrences.as_collection(); + + //TODO adjust code to only work with upper triangular half of cooccurrence matrix + + /* Compute the cooccurrence matrix C = A'A from the binary interaction matrix A. */ + let cooccurrences = occurrences + .join_map(&occurrences, |_user, &item_a, &item_b| (item_a, item_b)) + .filter(|&(item_a, item_b)| item_a != item_b) + .count(); + + /* compute the rowsums of C indicating how often we encounter individual items. */ + let row_sums = occurrences.map(|(_user, item)| item).count(); + + // row_sums.inspect(|record| println!("[row_sums] {:?}", record)); + + /* Join the cooccurrence pairs with the corresponding row sums. */ + let mut cooccurrences_with_row_sums = cooccurrences + .map(|((item_a, item_b), num_cooccurrences)| (item_a, (item_b, num_cooccurrences))) + .join_map( + &row_sums, + |&item_a, &(item_b, num_cooccurrences), &row_sum_a| { + assert!(row_sum_a > 0); + (item_b, (item_a, num_cooccurrences, row_sum_a)) + }, + ) + .join_map( + &row_sums, + |&item_b, &(item_a, num_cooccurrences, row_sum_a), &row_sum_b| { + assert!(row_sum_a > 0); + assert!(row_sum_b > 0); + (item_a, (item_b, num_cooccurrences, row_sum_a, row_sum_b)) + }, + ); + + // cooccurrences_with_row_sums + // .inspect(|record| println!("[cooccurrences_with_row_sums] {:?}", record)); + + // //TODO compute top-k "similar items" per item + // /* Compute LLR scores for each item pair. */ + // let llr_scores = cooccurrences_with_row_sums.map( + // |(item_a, (item_b, num_cooccurrences, row_sum_a, row_sum_b))| { + + // println!( + // "[llr_scores] item_a={} item_b={}, num_cooccurrences={} row_sum_a={} row_sum_b={}", + // item_a, item_b, num_cooccurrences, row_sum_a, row_sum_b); + + // let k11: isize = num_cooccurrences; + // let k12: isize = row_sum_a as isize - k11; + // let k21: isize = row_sum_b as isize - k11; + // let k22: isize = 10000 - k12 - k21 + k11; + + // let llr_score = loglikelihoodratio::log_likelihood_ratio(k11, k12, k21, k22); + + // ((item_a, item_b), llr_score) + // }); + + if noisy { + cooccurrences_with_row_sums = + cooccurrences_with_row_sums.inspect(|x| println!("change: {:?}", x)); + } + + let probe = cooccurrences_with_row_sums.probe(); + /* + // produce the (item, item) collection + let cooccurrences = occurrences + .join_map(&occurrences, |_user, &item_a, &item_b| (item_a, item_b)); + // count the occurrences of each item. + let counts = cooccurrences + .map(|(item_a,_)| item_a) + .count(); + // produce ((item1, item2), count1, count2, count12) tuples + let cooccurrences_with_counts = cooccurrences + .join_map(&counts, |&item_a, &item_b, &count_item_a| (item_b, (item_a, count_item_a))) + .join_map(&counts, |&item_b, &(item_a, count_item_a), &count_item_b| { + ((item_a, item_b), count_item_a, count_item_b) + }); + let probe = cooccurrences_with_counts + .inspect(|x| println!("change: {:?}", x)) + .probe(); + */ + (input, probe) + }); + + let seed: &[_] = &[1, 2, 3, index]; + let mut rng1: StdRng = SeedableRng::from_seed(seed); // rng for edge additions + let mut rng2: StdRng = SeedableRng::from_seed(seed); // rng for edge deletions + + let mut input = InputSession::from(input); + + for count in 0..scale { + if count % peers == index { + let user = rng1.gen_range(0, users); + let item = rng1.gen_range(0, items); + // println!("[INITIAL INPUT] ({}, {})", user, item); + input.insert((user, item)); + } + } + + // load the initial data up! + while probe.less_than(input.time()) { + worker.step(); + } + + for round in 1.. { + for element in (round * batch)..((round + 1) * batch) { + if element % peers == index { + // advance the input timestamp. + input.advance_to(round * batch); + // insert a new item. + let user = rng1.gen_range(0, users); + let item = rng1.gen_range(0, items); + if noisy { + println!("[INPUT: insert] ({}, {})", user, item); + } + input.insert((user, item)); + // remove an old item. + let user = rng2.gen_range(0, users); + let item = rng2.gen_range(0, items); + if noisy { + println!("[INPUT: remove] ({}, {})", user, item); + } + input.remove((user, item)); + } + } + + input.advance_to(round * batch); + input.flush(); + + while probe.less_than(input.time()) { + worker.step(); + } + } + }) + .unwrap(); +} diff --git a/src/tools/rustfmt/tests/target/issue-2916.rs b/src/tools/rustfmt/tests/target/issue-2916.rs new file mode 100644 index 000000000..fb07cc806 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2916.rs @@ -0,0 +1,2 @@ +a_macro!(name<Param1, Param2>, +); diff --git a/src/tools/rustfmt/tests/target/issue-2917/minimal.rs b/src/tools/rustfmt/tests/target/issue-2917/minimal.rs new file mode 100644 index 000000000..e81e1e6a5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2917/minimal.rs @@ -0,0 +1,8 @@ +macro_rules! foo { + () => { + // comment + /* + + */ + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-2917/packed_simd.rs b/src/tools/rustfmt/tests/target/issue-2917/packed_simd.rs new file mode 100644 index 000000000..274614f83 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2917/packed_simd.rs @@ -0,0 +1,63 @@ +// rustfmt-wrap_comments: true +//! Implements `From` and `Into` for vector types. + +macro_rules! impl_from_vector { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | $source:ident) => { + impl From<$source> for $id { + #[inline] + fn from(source: $source) -> Self { + fn static_assert_same_number_of_lanes<T, U>() + where + T: crate::sealed::Simd, + U: crate::sealed::Simd<LanesType = T::LanesType>, + { + } + use llvm::simd_cast; + static_assert_same_number_of_lanes::<$id, $source>(); + Simd(unsafe { simd_cast(source.0) }) + } + } + + // FIXME: `Into::into` is not inline, but due to + // the blanket impl in `std`, which is not + // marked `default`, we cannot override it here with + // specialization. + /* + impl Into<$id> for $source { + #[inline] + fn into(self) -> $id { + unsafe { simd_cast(self) } + } + } + */ + + test_if! { + $test_tt: + interpolate_idents! { + mod [$id _from_ $source] { + use super::*; + #[test] + fn from() { + assert_eq!($id::lanes(), $source::lanes()); + let source: $source = Default::default(); + let vec: $id = Default::default(); + + let e = $id::from(source); + assert_eq!(e, vec); + + let e: $id = source.into(); + assert_eq!(e, vec); + } + } + } + } + }; +} + +macro_rules! impl_from_vectors { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | $($source:ident),*) => { + $( + impl_from_vector!([$elem_ty; $elem_count]: $id | $test_tt | $source); + )* + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2922.rs b/src/tools/rustfmt/tests/target/issue-2922.rs new file mode 100644 index 000000000..501f78c78 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2922.rs @@ -0,0 +1,10 @@ +// rustfmt-indent_style: Visual +struct Functions { + RunListenServer: unsafe extern "C" fn(*mut c_void, + *mut c_char, + *mut c_char, + *mut c_char, + *mut c_void, + *mut c_void) + -> c_int, +} diff --git a/src/tools/rustfmt/tests/target/issue-2927-2.rs b/src/tools/rustfmt/tests/target/issue-2927-2.rs new file mode 100644 index 000000000..e895783ba --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2927-2.rs @@ -0,0 +1,7 @@ +// rustfmt-edition: 2015 +#![feature(rust_2018_preview, uniform_paths)] +use futures::prelude::*; +use http_03::cli::Cli; +use hyper::{service::service_fn_ok, Body, Response, Server}; +use log::{error, info, log}; +use structopt::StructOpt; diff --git a/src/tools/rustfmt/tests/target/issue-2927.rs b/src/tools/rustfmt/tests/target/issue-2927.rs new file mode 100644 index 000000000..3267be28d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2927.rs @@ -0,0 +1,7 @@ +// rustfmt-edition: 2018 +#![feature(rust_2018_preview, uniform_paths)] +use ::log::{error, info, log}; +use futures::prelude::*; +use http_03::cli::Cli; +use hyper::{service::service_fn_ok, Body, Response, Server}; +use structopt::StructOpt; diff --git a/src/tools/rustfmt/tests/target/issue-2930.rs b/src/tools/rustfmt/tests/target/issue-2930.rs new file mode 100644 index 000000000..41e763a7c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2930.rs @@ -0,0 +1,5 @@ +// rustfmt-indent_style: Visual +fn main() { + let (first_variable, second_variable) = (this_is_something_with_an_extraordinarily_long_name, + this_variable_name_is_also_pretty_long); +} diff --git a/src/tools/rustfmt/tests/target/issue-2936.rs b/src/tools/rustfmt/tests/target/issue-2936.rs new file mode 100644 index 000000000..1d6eb6d60 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2936.rs @@ -0,0 +1,21 @@ +struct AStruct { + A: u32, + B: u32, + C: u32, +} + +impl Something for AStruct { + fn a_func() { + match a_val { + ContextualParseError::InvalidMediaRule(ref err) => { + let err: &CStr = match err.kind { + ParseErrorKind::Custom(StyleParseErrorKind::MediaQueryExpectedFeatureName( + .., + )) => { + cstr!("PEMQExpectedFeatureName") + } + }; + } + }; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2941.rs b/src/tools/rustfmt/tests/target/issue-2941.rs new file mode 100644 index 000000000..3c6c702c2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2941.rs @@ -0,0 +1,5 @@ +// rustfmt-wrap_comments: true + +//! ``` +//! \ +//! ``` diff --git a/src/tools/rustfmt/tests/target/issue-2955.rs b/src/tools/rustfmt/tests/target/issue-2955.rs new file mode 100644 index 000000000..799cd36e2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2955.rs @@ -0,0 +1,6 @@ +// rustfmt-condense_wildcard_suffixes: true +fn main() { + match (1, 2, 3) { + (..) => (), + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2973.rs b/src/tools/rustfmt/tests/target/issue-2973.rs new file mode 100644 index 000000000..86574bd86 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2973.rs @@ -0,0 +1,158 @@ +#[cfg(test)] +mod test { + summary_test! { + tokenize_recipe_interpolation_eol, + "foo: # some comment + {{hello}} +", + "foo: \ + {{hello}} \ + {{ahah}}", + "N:#$>^{N}$<.", + } + + summary_test! { + tokenize_strings, + r#"a = "'a'" + '"b"' + "'c'" + '"d"'#echo hello"#, + r#"N="+'+"+'#."#, + } + + summary_test! { + tokenize_recipe_interpolation_eol, + "foo: # some comment + {{hello}} +", + "N:#$>^{N}$<.", + } + + summary_test! { + tokenize_recipe_interpolation_eof, + "foo: # more comments + {{hello}} +# another comment +", + "N:#$>^{N}$<#$.", + } + + summary_test! { + tokenize_recipe_complex_interpolation_expression, + "foo: #lol\n {{a + b + \"z\" + blarg}}", + "N:#$>^{N+N+\"+N}<.", + } + + summary_test! { + tokenize_recipe_multiple_interpolations, + "foo:,#ok\n {{a}}0{{b}}1{{c}}", + "N:,#$>^{N}_{N}_{N}<.", + } + + summary_test! { + tokenize_junk, + "bob + +hello blah blah blah : a b c #whatever + ", + "N$$NNNN:NNN#$.", + } + + summary_test! { + tokenize_empty_lines, + " +# this does something +hello: + asdf + bsdf + + csdf + + dsdf # whatever + +# yolo + ", + "$#$N:$>^_$^_$$^_$$^_$$<#$.", + } + + summary_test! { + tokenize_comment_before_variable, + " +# +A='1' +echo: + echo {{A}} + ", + "$#$N='$N:$>^_{N}$<.", + } + + summary_test! { + tokenize_interpolation_backticks, + "hello:\n echo {{`echo hello` + `echo goodbye`}}", + "N:$>^_{`+`}<.", + } + + summary_test! { + tokenize_assignment_backticks, + "a = `echo hello` + `echo goodbye`", + "N=`+`.", + } + + summary_test! { + tokenize_multiple, + " +hello: + a + b + + c + + d + +# hello +bob: + frank + ", + + "$N:$>^_$^_$$^_$$^_$$<#$N:$>^_$<.", + } + + summary_test! { + tokenize_comment, + "a:=#", + "N:=#." + } + + summary_test! { + tokenize_comment_with_bang, + "a:=#foo!", + "N:=#." + } + + summary_test! { + tokenize_order, + r" +b: a + @mv a b + +a: + @touch F + @touch a + +d: c + @rm c + +c: b + @mv b c", + "$N:N$>^_$$<N:$>^_$^_$$<N:N$>^_$$<N:N$>^_<.", + } + + summary_test! { + tokenize_parens, + r"((())) )abc(+", + "((())))N(+.", + } + + summary_test! { + crlf_newline, + "#\r\n#asdf\r\n", + "#$#$.", + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2976.rs b/src/tools/rustfmt/tests/target/issue-2976.rs new file mode 100644 index 000000000..51c94a84b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2976.rs @@ -0,0 +1,3 @@ +fn a(_ /*comment*/: u8 /* toto */) {} +fn b(/*comment*/ _: u8 /* tata */) {} +fn c(_: /*comment*/ u8) {} diff --git a/src/tools/rustfmt/tests/target/issue-2977/block.rs b/src/tools/rustfmt/tests/target/issue-2977/block.rs new file mode 100644 index 000000000..d376e370c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2977/block.rs @@ -0,0 +1,11 @@ +macro_rules! atomic_bits { + ($ldrex:expr) => { + execute(|| { + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + }) + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-2977/impl.rs b/src/tools/rustfmt/tests/target/issue-2977/impl.rs new file mode 100644 index 000000000..8d7bb9414 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2977/impl.rs @@ -0,0 +1,44 @@ +macro_rules! atomic_bits { + // the println macro cannot be rewritten because of the asm macro + ($type:ty, $ldrex:expr, $strex:expr) => { + impl AtomicBits for $type { + unsafe fn load_excl(address: usize) -> Self { + let raw: $type; + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + raw + } + + unsafe fn store_excl(self, address: usize) -> bool { + let status: $type; + println!("{}", + status); + status == 0 + } + } + }; + + // the println macro should be rewritten here + ($type:ty) => { + fn some_func(self) { + let status: $type; + println!("{}", status); + } + }; + + // unrewritale macro in func + ($type:ty, $ldrex:expr) => { + unsafe fn load_excl(address: usize) -> Self { + let raw: $type; + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + raw + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2977/item.rs b/src/tools/rustfmt/tests/target/issue-2977/item.rs new file mode 100644 index 000000000..857065ca9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2977/item.rs @@ -0,0 +1,11 @@ +macro_rules! atomic_bits { + ($ldrex:expr) => { + some_macro!(pub fn foo() { + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + }) + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-2977/trait.rs b/src/tools/rustfmt/tests/target/issue-2977/trait.rs new file mode 100644 index 000000000..ae20668cd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2977/trait.rs @@ -0,0 +1,44 @@ +macro_rules! atomic_bits { + // the println macro cannot be rewritten because of the asm macro + ($type:ty, $ldrex:expr, $strex:expr) => { + trait $type { + unsafe fn load_excl(address: usize) -> Self { + let raw: $type; + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + raw + } + + unsafe fn store_excl(self, address: usize) -> bool { + let status: $type; + println!("{}", + status); + status == 0 + } + } + }; + + // the println macro should be rewritten here + ($type:ty) => { + fn some_func(self) { + let status: $type; + println!("{}", status); + } + }; + + // unrewritale macro in func + ($type:ty, $ldrex:expr) => { + unsafe fn load_excl(address: usize) -> Self { + let raw: $type; + asm!($ldrex + : "=r"(raw) + : "r"(address) + : + : "volatile"); + raw + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2985.rs b/src/tools/rustfmt/tests/target/issue-2985.rs new file mode 100644 index 000000000..faad85923 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2985.rs @@ -0,0 +1,36 @@ +// rustfmt-indent_style: Visual +fn foo() { + { + { + let extra_encoder_settings = extra_encoder_settings.iter() + .filter_map(|&(name, value)| { + value.split() + .next() + .something() + .something2() + .something3() + .something4() + }); + let extra_encoder_settings = extra_encoder_settings.iter() + .filter_map(|&(name, value)| { + value.split() + .next() + .something() + .something2() + .something3() + .something4() + }) + .something(); + if let Some(subpod) = pod.subpods.iter().find(|s| { + !s.plaintext + .as_ref() + .map(String::as_ref) + .unwrap_or("") + .is_empty() + }) + { + do_something(); + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-2995.rs b/src/tools/rustfmt/tests/target/issue-2995.rs new file mode 100644 index 000000000..890da8def --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-2995.rs @@ -0,0 +1,7 @@ +fn issue_2995() { + // '\u{2028}' is inserted in the code below. + + [0, 1]; + [0, /* */ 1]; + [0, 1]; +} diff --git a/src/tools/rustfmt/tests/target/issue-3029.rs b/src/tools/rustfmt/tests/target/issue-3029.rs new file mode 100644 index 000000000..a7ac5c32b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3029.rs @@ -0,0 +1,94 @@ +fn keep_if() { + { + { + { + EvaluateJSReply::NumberValue( + if FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_if_let() { + { + { + { + EvaluateJSReply::NumberValue( + if let Some(e) = FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_for() { + { + { + { + EvaluateJSReply::NumberValue( + for conv in FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_loop() { + { + { + { + EvaluateJSReply::NumberValue(loop { + FromJSValConvertible::from_jsval(cx, rval.handle(), ()); + }) + } + } + } +} + +fn keep_while() { + { + { + { + EvaluateJSReply::NumberValue( + while FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_while_let() { + { + { + { + EvaluateJSReply::NumberValue( + while let Some(e) = FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + unimplemented!(); + }, + ) + } + } + } +} + +fn keep_match() { + { + { + EvaluateJSReply::NumberValue( + match FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + Ok(ConversionResult::Success(v)) => v, + _ => unreachable!(), + }, + ) + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3032.rs b/src/tools/rustfmt/tests/target/issue-3032.rs new file mode 100644 index 000000000..3533a81fb --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3032.rs @@ -0,0 +1,36 @@ +pub fn get_array_index_from_id(_cx: *mut JSContext, id: HandleId) -> Option<u32> { + let raw_id = id.into(); + unsafe { + if RUST_JSID_IS_INT(raw_id) { + return Some(RUST_JSID_TO_INT(raw_id) as u32); + } + None + } + // If `id` is length atom, `-1`, otherwise: + /*return if JSID_IS_ATOM(id) { + let atom = JSID_TO_ATOM(id); + //let s = *GetAtomChars(id); + if s > 'a' && s < 'z' { + return -1; + } + + let i = 0; + let str = AtomToLinearString(JSID_TO_ATOM(id)); + return if StringIsArray(str, &mut i) != 0 { i } else { -1 } + } else { + IdToInt32(cx, id); + }*/ +} + +impl Foo { + fn bar() -> usize { + 42 + /* a block comment */ + } + + fn baz() -> usize { + 42 + // this is a line + /* a block comment */ + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3038.rs b/src/tools/rustfmt/tests/target/issue-3038.rs new file mode 100644 index 000000000..3c398b825 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3038.rs @@ -0,0 +1,29 @@ +impl HTMLTableElement { + fn func() { + if number_of_row_elements == 0 { + if let Some(last_tbody) = node + .rev_children() + .filter_map(DomRoot::downcast::<Element>) + .find(|n| { + n.is::<HTMLTableSectionElement>() && n.local_name() == &local_name!("tbody") + }) + { + last_tbody + .upcast::<Node>() + .AppendChild(new_row.upcast::<Node>()) + .expect("InsertRow failed to append first row."); + } + } + + if number_of_row_elements == 0 { + if let Some(last_tbody) = node.find(|n| { + n.is::<HTMLTableSectionElement>() && n.local_name() == &local_name!("tbody") + }) { + last_tbody + .upcast::<Node>() + .AppendChild(new_row.upcast::<Node>()) + .expect("InsertRow failed to append first row."); + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3043.rs b/src/tools/rustfmt/tests/target/issue-3043.rs new file mode 100644 index 000000000..b54e244a4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3043.rs @@ -0,0 +1,5 @@ +// rustfmt-edition: 2018 + +use ::std::vec::Vec; + +fn main() {} diff --git a/src/tools/rustfmt/tests/target/issue-3049.rs b/src/tools/rustfmt/tests/target/issue-3049.rs new file mode 100644 index 000000000..fad154354 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3049.rs @@ -0,0 +1,45 @@ +// rustfmt-indent_style: Visual +fn main() { + something.aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .bench_function(|| { + let x = hello(); + }); + + something.aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .bench_function(arg, || { + let x = hello(); + }); + + something.aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .aaaaaaaaaaaa() + .bench_function(arg, + || { + let x = hello(); + }, + arg); + + AAAAAAAAAAA.function(|| { + let _ = (); + }); + + AAAAAAAAAAA.chain().function(|| { + let _ = (); + }) +} diff --git a/src/tools/rustfmt/tests/target/issue-3055/backtick.rs b/src/tools/rustfmt/tests/target/issue-3055/backtick.rs new file mode 100644 index 000000000..f5bae8d3d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3055/backtick.rs @@ -0,0 +1,10 @@ +// rustfmt-wrap_comments: true + +/// Simple block +/// +/// ```text +/// ` +/// ``` +fn main() { + println!("Hello, world!"); +} diff --git a/src/tools/rustfmt/tests/target/issue-3055/empty-code-block.rs b/src/tools/rustfmt/tests/target/issue-3055/empty-code-block.rs new file mode 100644 index 000000000..566f7ef9b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3055/empty-code-block.rs @@ -0,0 +1,18 @@ +// rustfmt-wrap_comments: true + +/// Simple block +/// +/// ``` +/// ``` +/// +/// ```no_run +/// ``` +/// +/// ```should_panic +/// ``` +/// +/// ```compile_fail +/// ``` +fn main() { + println!("Hello, world!"); +} diff --git a/src/tools/rustfmt/tests/target/issue-3055/original.rs b/src/tools/rustfmt/tests/target/issue-3055/original.rs new file mode 100644 index 000000000..2df6adbb5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3055/original.rs @@ -0,0 +1,42 @@ +// rustfmt-wrap_comments: true +// rustfmt-format_code_in_doc_comments: true + +/// Vestibulum elit nibh, rhoncus non, euismod sit amet, pretium eu, enim. Nunc +/// commodo ultricies dui. +/// +/// Should not format with text attribute +/// ```text +/// .--------------. +/// | v +/// Park <- Idle -> Poll -> Probe -> Download -> Install -> Reboot +/// ^ ^ ' ' ' +/// ' ' ' ' ' +/// ' `--------' ' ' +/// `---------------' ' ' +/// `--------------------------' ' +/// `-------------------------------------' +/// ``` +/// +/// Should not format with ignore attribute +/// ```text +/// .--------------. +/// | v +/// Park <- Idle -> Poll -> Probe -> Download -> Install -> Reboot +/// ^ ^ ' ' ' +/// ' ' ' ' ' +/// ' `--------' ' ' +/// `---------------' ' ' +/// `--------------------------' ' +/// `-------------------------------------' +/// ``` +/// +/// Should format with rust attribute +/// ```rust +/// let x = 42; +/// ``` +/// +/// Should format with no attribute as it defaults to rust +/// ``` +/// let x = 42; +/// ``` +fn func() {} diff --git a/src/tools/rustfmt/tests/target/issue-3059.rs b/src/tools/rustfmt/tests/target/issue-3059.rs new file mode 100644 index 000000000..f750c1287 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3059.rs @@ -0,0 +1,8 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 80 + +/// Vestibulum elit nibh, rhoncus non, euismod sit amet, pretium eu, enim. Nunc +/// commodo ultricies dui. Cras gravida rutrum massa. Donec accumsan mattis +/// turpis. Quisque sem. Quisque elementum sapien iaculis augue. In dui sem, +/// congue sit amet, feugiat quis, lobortis at, eros. +fn func4() {} diff --git a/src/tools/rustfmt/tests/target/issue-3066.rs b/src/tools/rustfmt/tests/target/issue-3066.rs new file mode 100644 index 000000000..d4dccc97e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3066.rs @@ -0,0 +1,7 @@ +// rustfmt-indent_style: Visual +fn main() { + Struct { field: aaaaaaaaaaa }; + Struct { field: aaaaaaaaaaaa }; + Struct { field: value, + field2: value2 }; +} diff --git a/src/tools/rustfmt/tests/target/issue-3105.rs b/src/tools/rustfmt/tests/target/issue-3105.rs new file mode 100644 index 000000000..4f1123805 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3105.rs @@ -0,0 +1,48 @@ +// rustfmt-wrap_comments: true + +/// Although the indentation of the skipped method is off, it shouldn't be +/// changed. +/// +/// ``` +/// pub unsafe fn _mm256_shufflehi_epi16(a: __m256i, imm8: i32) -> __m256i { +/// let imm8 = (imm8 & 0xFF) as u8; +/// let a = a.as_i16x16(); +/// macro_rules! shuffle_done { +/// ($x01:expr, $x23:expr, $x45:expr, $x67:expr) => { +/// #[cfg_attr(rustfmt, rustfmt_skip)] +/// simd_shuffle16(a, a, [ +/// 0, 1, 2, 3, 4+$x01, 4+$x23, 4+$x45, 4+$x67, +/// 8, 9, 10, 11, 12+$x01, 12+$x23, 12+$x45, 12+$x67 +/// ]); +/// }; +/// } +/// } +/// ``` +pub unsafe fn _mm256_shufflehi_epi16(a: __m256i, imm8: i32) -> __m256i { + let imm8 = (imm8 & 0xFF) as u8; + let a = a.as_i16x16(); + macro_rules! shuffle_done { + ($x01:expr, $x23:expr, $x45:expr, $x67:expr) => { + #[cfg_attr(rustfmt, rustfmt_skip)] + simd_shuffle16(a, a, [ + 0, 1, 2, 3, 4+$x01, 4+$x23, 4+$x45, 4+$x67, + 8, 9, 10, 11, 12+$x01, 12+$x23, 12+$x45, 12+$x67 + ]); + }; + } +} + +/// The skipped method shouldn't right-shift +pub unsafe fn _mm256_shufflehi_epi32(a: __m256i, imm8: i32) -> __m256i { + let imm8 = (imm8 & 0xFF) as u8; + let a = a.as_i16x16(); + macro_rules! shuffle_done { + ($x01:expr, $x23:expr, $x45:expr, $x67:expr) => { + #[cfg_attr(rustfmt, rustfmt_skip)] + simd_shuffle32(a, a, [ + 0, 1, 2, 3, 4+$x01, 4+$x23, 4+$x45, 4+$x67, + 8, 9, 10, 11, 12+$x01, 12+$x23, 12+$x45, 12+$x67 + ]); + }; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3118.rs b/src/tools/rustfmt/tests/target/issue-3118.rs new file mode 100644 index 000000000..ce73a5c78 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3118.rs @@ -0,0 +1,11 @@ +use { + crate::foo::bar, + bytes::{Buf, BufMut}, + std::io, +}; + +mod foo { + pub mod bar {} +} + +fn main() {} diff --git a/src/tools/rustfmt/tests/target/issue-3124.rs b/src/tools/rustfmt/tests/target/issue-3124.rs new file mode 100644 index 000000000..1083050d8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3124.rs @@ -0,0 +1,14 @@ +pub fn fail1() { + // Some comment. + /**/// +} + +pub fn fail2() { + // Some comment. + /**/ +} + +pub fn fail3() { + // Some comment. + // +} diff --git a/src/tools/rustfmt/tests/target/issue-3131.rs b/src/tools/rustfmt/tests/target/issue-3131.rs new file mode 100644 index 000000000..c7304dd55 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3131.rs @@ -0,0 +1,8 @@ +fn main() { + match 3 { + t if match t { + _ => true, + } => {} + _ => {} + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3132.rs b/src/tools/rustfmt/tests/target/issue-3132.rs new file mode 100644 index 000000000..4dffe0ab8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3132.rs @@ -0,0 +1,15 @@ +// rustfmt-version: Two + +fn test() { + /* + a + */ + let x = 42; + /* + aaa + "line 1 + line 2 + line 3" + */ + let x = 42; +} diff --git a/src/tools/rustfmt/tests/target/issue-3153.rs b/src/tools/rustfmt/tests/target/issue-3153.rs new file mode 100644 index 000000000..39e569c0d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3153.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: true + +/// This may panic if: +/// - there are fewer than `max_header_bytes` bytes preceding the body +/// - there are fewer than `max_footer_bytes` bytes following the body +/// - the sum of the body bytes and post-body bytes is less than the sum of +/// `min_body_and_padding_bytes` and `max_footer_bytes` (in other words, the +/// minimum body and padding byte requirement is not met) +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/issue-3158.rs b/src/tools/rustfmt/tests/target/issue-3158.rs new file mode 100644 index 000000000..4bbbdc1d0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3158.rs @@ -0,0 +1,74 @@ +// rustfmt-format_code_in_doc_comments: true + +/// Should format +/// ```rust +/// assert!(false); +/// ``` +/// +/// Should format +/// ```rust,should_panic +/// assert!(false); +/// ``` +/// +/// Should format +/// ```rust,should_panic,edition2018 +/// assert!(false); +/// ``` +/// +/// Should format +/// ```rust , should_panic , edition2018 +/// assert!(false); +/// ``` +/// +/// Should not format +/// ```ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (not all are rust) +/// ```rust,ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```compile_fail +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```rust,compile_fail +/// assert!( false ); +/// ``` +/// +/// Various unspecified ones that should format +/// ``` +/// assert!(false); +/// ``` +/// +/// ```, +/// assert!(false); +/// ``` +/// +/// ```,,,,, +/// assert!(false); +/// ``` +/// +/// ```,,, rust ,, +/// assert!(false); +/// ``` +/// +/// Should not format +/// ```,,, rust , ignore, +/// assert!( false ); +/// ``` +/// +/// Few empty ones +/// ``` +/// ``` +/// +/// ```rust +/// ``` +/// +/// ```ignore +/// ``` +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/issue-3182.rs b/src/tools/rustfmt/tests/target/issue-3182.rs new file mode 100644 index 000000000..d8de84438 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3182.rs @@ -0,0 +1,10 @@ +// rustfmt-max_width: 79 +// rustfmt-wrap_comments: true + +/// ```rust +/// # #![cfg_attr(not(dox), feature(cfg_target_feature, target_feature, stdsimd)not(dox), feature(cfg_target_feature, target_feature, stdsimd))] +/// +/// // Est lectus hendrerit lorem, eget dignissim orci nisl sit amet massa. Etiam volutpat lobortis eros. +/// let x = 42; +/// ``` +fn func() {} diff --git a/src/tools/rustfmt/tests/target/issue-3184.rs b/src/tools/rustfmt/tests/target/issue-3184.rs new file mode 100644 index 000000000..f8d9b169f --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3184.rs @@ -0,0 +1,5 @@ +/*/ +struct Error{ + message: String, +} +*/ diff --git a/src/tools/rustfmt/tests/target/issue-3194.rs b/src/tools/rustfmt/tests/target/issue-3194.rs new file mode 100644 index 000000000..a9614913e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3194.rs @@ -0,0 +1,52 @@ +mod m { + struct S + where + A: B; +} + +mod n { + struct Foo + where + A: B, + { + foo: usize, + } +} + +mod o { + enum Bar + where + A: B, + { + Bar, + } +} + +mod with_comments { + mod m { + struct S + /* before where */ + where + A: B; /* after where */ + } + + mod n { + struct Foo + /* before where */ + where + A: B, /* after where */ + { + foo: usize, + } + } + + mod o { + enum Bar + /* before where */ + where + A: B, /* after where */ + { + Bar, + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3198.rs b/src/tools/rustfmt/tests/target/issue-3198.rs new file mode 100644 index 000000000..9291f181d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3198.rs @@ -0,0 +1,67 @@ +impl TestTrait { + fn foo_one_pre(/* Important comment1 */ self) {} + + fn foo_one_post(self /* Important comment1 */) {} + + fn foo_pre(/* Important comment1 */ self, /* Important comment2 */ a: i32) {} + + fn foo_post(self /* Important comment1 */, a: i32 /* Important comment2 */) {} + + fn bar_pre(/* Important comment1 */ &mut self, /* Important comment2 */ a: i32) {} + + fn bar_post(&mut self /* Important comment1 */, a: i32 /* Important comment2 */) {} + + fn baz_pre( + /* Important comment1 */ + self: X<'a, 'b>, + /* Important comment2 */ + a: i32, + ) { + } + + fn baz_post( + self: X<'a, 'b>, /* Important comment1 */ + a: i32, /* Important comment2 */ + ) { + } + + fn baz_tree_pre( + /* Important comment1 */ + self: X<'a, 'b>, + /* Important comment2 */ + a: i32, + /* Important comment3 */ + b: i32, + ) { + } + + fn baz_tree_post( + self: X<'a, 'b>, /* Important comment1 */ + a: i32, /* Important comment2 */ + b: i32, /* Important comment3 */ + ) { + } + + fn multi_line( + self: X<'a, 'b>, /* Important comment1-1 */ + /* Important comment1-2 */ + a: i32, /* Important comment2 */ + b: i32, /* Important comment3 */ + ) { + } + + fn two_line_comment( + self: X<'a, 'b>, /* Important comment1-1 + Important comment1-2 */ + a: i32, /* Important comment2 */ + b: i32, /* Important comment3 */ + ) { + } + + fn no_first_line_comment( + self: X<'a, 'b>, + /* Important comment2 */ a: i32, + /* Important comment3 */ b: i32, + ) { + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3213/version_one.rs b/src/tools/rustfmt/tests/target/issue-3213/version_one.rs new file mode 100644 index 000000000..307903b12 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3213/version_one.rs @@ -0,0 +1,13 @@ +// rustfmt-version: One + +fn foo() { + match 0 { + 0 => { + return AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + } + 1 => { + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + } + _ => "", + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-3213/version_two.rs b/src/tools/rustfmt/tests/target/issue-3213/version_two.rs new file mode 100644 index 000000000..de93d04ba --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3213/version_two.rs @@ -0,0 +1,13 @@ +// rustfmt-version: Two + +fn foo() { + match 0 { + 0 => { + return AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; + } + 1 => { + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + } + _ => "", + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-3217.rs b/src/tools/rustfmt/tests/target/issue-3217.rs new file mode 100644 index 000000000..5121320a0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3217.rs @@ -0,0 +1,24 @@ +#![feature(label_break_value)] + +fn main() { + let mut res = 0; + 's_39: { + if res == 0i32 { + println!("Hello, world!"); + } + } + 's_40: loop { + println!("res = {}", res); + res += 1; + if res == 3i32 { + break 's_40; + } + } + let toto = || { + if true { + 42 + } else { + 24 + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-3224.rs b/src/tools/rustfmt/tests/target/issue-3224.rs new file mode 100644 index 000000000..6476d2117 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3224.rs @@ -0,0 +1,11 @@ +// rustfmt-wrap_comments: true + +//! Test: +//! * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +//! * [`examples/simple`] – Demonstrates use of the [`init`] API with plain +//! structs. +//! * [`examples/simple_flatbuffer`] – Demonstrates use of the [`init`] API with +//! FlatBuffers. +//! * [`examples/gravity`] – Demonstrates use of the [`RLBot::set_game_state`] +//! API +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/issue-3227/one.rs b/src/tools/rustfmt/tests/target/issue-3227/one.rs new file mode 100644 index 000000000..fcc833100 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3227/one.rs @@ -0,0 +1,13 @@ +// rustfmt-version: One + +fn main() { + thread::spawn(|| { + while true { + println!("iteration"); + } + }); + + thread::spawn(|| loop { + println!("iteration"); + }); +} diff --git a/src/tools/rustfmt/tests/target/issue-3227/two.rs b/src/tools/rustfmt/tests/target/issue-3227/two.rs new file mode 100644 index 000000000..374ab5430 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3227/two.rs @@ -0,0 +1,15 @@ +// rustfmt-version: Two + +fn main() { + thread::spawn(|| { + while true { + println!("iteration"); + } + }); + + thread::spawn(|| { + loop { + println!("iteration"); + } + }); +} diff --git a/src/tools/rustfmt/tests/target/issue-3234.rs b/src/tools/rustfmt/tests/target/issue-3234.rs new file mode 100644 index 000000000..c7d9d42bd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3234.rs @@ -0,0 +1,14 @@ +macro_rules! fuzz_target { + (|$data:ident: &[u8]| $body:block) => {}; +} + +fuzz_target!(|data: &[u8]| { + if let Ok(app_img) = AppImage::parse(data) { + if let Ok(app_img) = + app_img.sign_for_secureboot(include_str!("../../test-data/signing-key")) + { + assert!(app_img.is_signed()); + Gbl::from_app_image(app_img).to_bytes(); + } + } +}); diff --git a/src/tools/rustfmt/tests/target/issue-3241.rs b/src/tools/rustfmt/tests/target/issue-3241.rs new file mode 100644 index 000000000..60b452abd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3241.rs @@ -0,0 +1,11 @@ +// rustfmt-edition: 2018 + +use ::baz::{bar, foo}; +use ::ignore; +use ::ignore::some::more; +use ::*; +use ::{bar, foo}; + +fn main() { + println!("Hello, world!"); +} diff --git a/src/tools/rustfmt/tests/target/issue-3253/bar.rs b/src/tools/rustfmt/tests/target/issue-3253/bar.rs new file mode 100644 index 000000000..6c6ab945b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3253/bar.rs @@ -0,0 +1,2 @@ +// Empty +fn empty() {} diff --git a/src/tools/rustfmt/tests/target/issue-3253/foo.rs b/src/tools/rustfmt/tests/target/issue-3253/foo.rs new file mode 100644 index 000000000..1a42a1015 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3253/foo.rs @@ -0,0 +1,3 @@ +pub fn hello() { + println!("Hello World!"); +} diff --git a/src/tools/rustfmt/tests/target/issue-3253/lib.rs b/src/tools/rustfmt/tests/target/issue-3253/lib.rs new file mode 100644 index 000000000..3eef586bd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3253/lib.rs @@ -0,0 +1,14 @@ +#[macro_use] +extern crate cfg_if; + +cfg_if! { + if #[cfg(target_family = "unix")] { + mod foo; + #[path = "paths/bar_foo.rs"] + mod bar_foo; + } else { + mod bar; + #[path = "paths/foo_bar.rs"] + mod foo_bar; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3253/paths/bar_foo.rs b/src/tools/rustfmt/tests/target/issue-3253/paths/bar_foo.rs new file mode 100644 index 000000000..f7e1de29a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3253/paths/bar_foo.rs @@ -0,0 +1,3 @@ +fn foo_decl_item(x: &mut i32) { + x = 3; +} diff --git a/src/tools/rustfmt/tests/target/issue-3253/paths/excluded.rs b/src/tools/rustfmt/tests/target/issue-3253/paths/excluded.rs new file mode 100644 index 000000000..9ab88414d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3253/paths/excluded.rs @@ -0,0 +1,17 @@ +// This module is not imported in the cfg_if macro in lib.rs so it is ignored +// while the foo and bar mods are formatted. +// Check the corresponding file in tests/source/issue-3253/paths/excluded.rs + + + + + fn Foo<T>() where T: Bar { +} + + + +trait CoolerTypes { fn dummy(&self) { +} +} + + diff --git a/src/tools/rustfmt/tests/target/issue-3253/paths/foo_bar.rs b/src/tools/rustfmt/tests/target/issue-3253/paths/foo_bar.rs new file mode 100644 index 000000000..f52ac11b7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3253/paths/foo_bar.rs @@ -0,0 +1,5 @@ +fn Foo<T>() +where + T: Bar, +{ +} diff --git a/src/tools/rustfmt/tests/target/issue-3265.rs b/src/tools/rustfmt/tests/target/issue-3265.rs new file mode 100644 index 000000000..7db1dbd8b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3265.rs @@ -0,0 +1,14 @@ +// rustfmt-newline_style: Windows +#[cfg(test)] +mod test { + summary_test! { + tokenize_recipe_interpolation_eol, + "foo: # some comment + {{hello}} +", + "foo: \ + {{hello}} \ + {{ahah}}", + "N:#$>^{N}$<.", + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3270/one.rs b/src/tools/rustfmt/tests/target/issue-3270/one.rs new file mode 100644 index 000000000..78de94732 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3270/one.rs @@ -0,0 +1,12 @@ +// rustfmt-version: One + +pub fn main() { + /* let s = String::from( + " + hello + world + ", + ); */ + + assert_eq!(s, "\nhello\nworld\n"); +} diff --git a/src/tools/rustfmt/tests/target/issue-3270/two.rs b/src/tools/rustfmt/tests/target/issue-3270/two.rs new file mode 100644 index 000000000..e48b59213 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3270/two.rs @@ -0,0 +1,12 @@ +// rustfmt-version: Two + +pub fn main() { + /* let s = String::from( + " +hello +world +", + ); */ + + assert_eq!(s, "\nhello\nworld\n"); +} diff --git a/src/tools/rustfmt/tests/target/issue-3270/wrap.rs b/src/tools/rustfmt/tests/target/issue-3270/wrap.rs new file mode 100644 index 000000000..7435c5f08 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3270/wrap.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: true +// rustfmt-version: Two + +// check that a line below max_width does not get over the limit when wrapping +// it in a block comment +fn func() { + let x = 42; + /* + let something = "one line line line line line line line line line line line line line + two lines + three lines"; + */ +} diff --git a/src/tools/rustfmt/tests/target/issue-3272/v1.rs b/src/tools/rustfmt/tests/target/issue-3272/v1.rs new file mode 100644 index 000000000..aab201027 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3272/v1.rs @@ -0,0 +1,15 @@ +// rustfmt-version: One + +fn main() { + assert!(HAYSTACK + .par_iter() + .find_any(|&&x| x[0] % 1000 == 999) + .is_some()); + + assert( + HAYSTACK + .par_iter() + .find_any(|&&x| x[0] % 1000 == 999) + .is_some(), + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-3272/v2.rs b/src/tools/rustfmt/tests/target/issue-3272/v2.rs new file mode 100644 index 000000000..a42a2fccd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3272/v2.rs @@ -0,0 +1,17 @@ +// rustfmt-version: Two + +fn main() { + assert!( + HAYSTACK + .par_iter() + .find_any(|&&x| x[0] % 1000 == 999) + .is_some() + ); + + assert( + HAYSTACK + .par_iter() + .find_any(|&&x| x[0] % 1000 == 999) + .is_some(), + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-3278/version_one.rs b/src/tools/rustfmt/tests/target/issue-3278/version_one.rs new file mode 100644 index 000000000..580679fba --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3278/version_one.rs @@ -0,0 +1,8 @@ +// rustfmt-version: One + +pub fn parse_conditional<'a, I: 'a>( +) -> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a +where + I: Stream<Item = char>, +{ +} diff --git a/src/tools/rustfmt/tests/target/issue-3278/version_two.rs b/src/tools/rustfmt/tests/target/issue-3278/version_two.rs new file mode 100644 index 000000000..c17b1742d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3278/version_two.rs @@ -0,0 +1,8 @@ +// rustfmt-version: Two + +pub fn parse_conditional<'a, I: 'a>() +-> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a +where + I: Stream<Item = char>, +{ +} diff --git a/src/tools/rustfmt/tests/target/issue-3295/two.rs b/src/tools/rustfmt/tests/target/issue-3295/two.rs new file mode 100644 index 000000000..3e669a0bb --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3295/two.rs @@ -0,0 +1,14 @@ +// rustfmt-version: Two +pub enum TestEnum { + a, + b, +} + +fn the_test(input: TestEnum) { + match input { + TestEnum::a => String::from("aaa"), + TestEnum::b => String::from( + "this is a very very very very very very very very very very very very very very very ong string", + ), + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-3302.rs b/src/tools/rustfmt/tests/target/issue-3302.rs new file mode 100644 index 000000000..146cb9838 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3302.rs @@ -0,0 +1,43 @@ +// rustfmt-version: Two + +macro_rules! moo1 { + () => { + bar! { + " +" + } + }; +} + +macro_rules! moo2 { + () => { + bar! { + " +" + } + }; +} + +macro_rules! moo3 { + () => { + 42 + /* + bar! { + " + toto +tata" + } + */ + }; +} + +macro_rules! moo4 { + () => { + bar! { + " + foo + bar +baz" + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-3304.rs b/src/tools/rustfmt/tests/target/issue-3304.rs new file mode 100644 index 000000000..cc1910ce2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3304.rs @@ -0,0 +1,42 @@ +// rustfmt-error_on_line_overflow: true + +#[rustfmt::skip] use one::two::three::four::five::six::seven::eight::night::ten::eleven::twelve::thirteen::fourteen::fiveteen; +#[rustfmt::skip] + +use one::two::three::four::five::six::seven::eight::night::ten::eleven::twelve::thirteen::fourteen::fiveteen; + +macro_rules! test_macro { + ($($id:ident),*) => {}; +} + +macro_rules! test_macro2 { + ($($id:ident),*) => { + 1 + }; +} + +fn main() { + #[rustfmt::skip] test_macro! { one, two, three, four, five, six, seven, eight, night, ten, eleven, twelve, thirteen, fourteen, fiveteen }; + #[rustfmt::skip] + + test_macro! { one, two, three, four, five, six, seven, eight, night, ten, eleven, twelve, thirteen, fourteen, fiveteen }; +} + +fn test_local() { + #[rustfmt::skip] let x = test_macro! { one, two, three, four, five, six, seven, eight, night, ten, eleven, twelve, thirteen, fourteen, fiveteen }; + #[rustfmt::skip] + + let x = test_macro! { one, two, three, four, five, six, seven, eight, night, ten, eleven, twelve, thirteen, fourteen, fiveteen }; +} + +fn test_expr(_: [u32]) -> u32 { + #[rustfmt::skip] test_expr([9999999999999, 9999999999999, 9999999999999, 9999999999999, 9999999999999, 9999999999999, 9999999999999, 9999999999999]); + #[rustfmt::skip] + + test_expr([9999999999999, 9999999999999, 9999999999999, 9999999999999, 9999999999999, 9999999999999, 9999999999999, 9999999999999]) +} + +#[rustfmt::skip] mod test { use one::two::three::four::five::six::seven::eight::night::ten::eleven::twelve::thirteen::fourteen::fiveteen; } +#[rustfmt::skip] + +mod test { use one::two::three::four::five::six::seven::eight::night::ten::eleven::twelve::thirteen::fourteen::fiveteen; } diff --git a/src/tools/rustfmt/tests/target/issue-3314.rs b/src/tools/rustfmt/tests/target/issue-3314.rs new file mode 100644 index 000000000..1cd32afb0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3314.rs @@ -0,0 +1,5 @@ +/*code +/*code*/ +if true { + println!("1"); +}*/ diff --git a/src/tools/rustfmt/tests/target/issue-3343.rs b/src/tools/rustfmt/tests/target/issue-3343.rs new file mode 100644 index 000000000..d0497758e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3343.rs @@ -0,0 +1,44 @@ +// rustfmt-inline_attribute_width: 50 + +#[cfg(feature = "alloc")] use core::slice; + +#[cfg(feature = "alloc")] use total_len_is::_50__; + +#[cfg(feature = "alloc")] +use total_len_is::_51___; + +#[cfg(feature = "alloc")] extern crate len_is_50_; + +#[cfg(feature = "alloc")] +extern crate len_is_51__; + +/// this is a comment to test is_sugared_doc property +use core::convert; + +#[fooooo] +#[barrrrr] +use total_len_is_::_51______; + +#[cfg(not(all( + feature = "std", + any( + target_os = "linux", + target_os = "android", + target_os = "netbsd", + target_os = "dragonfly", + target_os = "haiku", + target_os = "emscripten", + target_os = "solaris", + target_os = "cloudabi", + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "redox", + target_os = "fuchsia", + windows, + all(target_arch = "wasm32", feature = "stdweb"), + all(target_arch = "wasm32", feature = "wasm-bindgen"), + ) +)))] +use core::slice; diff --git a/src/tools/rustfmt/tests/target/issue-3423.rs b/src/tools/rustfmt/tests/target/issue-3423.rs new file mode 100644 index 000000000..cd6025177 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3423.rs @@ -0,0 +1,5 @@ +/* a nice comment with a trailing whitespace */ +fn foo() {} + +/* a nice comment with a trailing tab */ +fn bar() {} diff --git a/src/tools/rustfmt/tests/target/issue-3434/lib.rs b/src/tools/rustfmt/tests/target/issue-3434/lib.rs new file mode 100644 index 000000000..2fd7aea21 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3434/lib.rs @@ -0,0 +1,57 @@ +#![rustfmt::skip::macros(skip_macro_mod)] + +mod no_entry; + +#[rustfmt::skip::macros(html, skip_macro)] +fn main() { + let macro_result1 = html! { <div> +this should be skipped</div> + } + .to_string(); + + let macro_result2 = not_skip_macro! { <div> + this should be mangled</div> + } + .to_string(); + + skip_macro! { +this should be skipped +}; + + foo(); +} + +fn foo() { + let macro_result1 = html! { <div> + this should be mangled</div> + } + .to_string(); +} + +fn bar() { + let macro_result1 = skip_macro_mod! { <div> +this should be skipped</div> + } + .to_string(); +} + +fn visitor_made_from_same_context() { + let pair = ( + || { + foo!(<div> + this should be mangled</div> + ); + skip_macro_mod!(<div> +this should be skipped</div> + ); + }, + || { + foo!(<div> + this should be mangled</div> + ); + skip_macro_mod!(<div> +this should be skipped</div> + ); + }, + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-3434/no_entry.rs b/src/tools/rustfmt/tests/target/issue-3434/no_entry.rs new file mode 100644 index 000000000..a2ecf2c2f --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3434/no_entry.rs @@ -0,0 +1,19 @@ +#[rustfmt::skip::macros(another_macro)] +fn foo() { + another_macro!( +This should be skipped. + ); +} + +fn bar() { + skip_macro_mod!( +This should be skipped. + ); +} + +fn baz() { + let macro_result1 = no_skip_macro! { <div> + this should be mangled</div> + } + .to_string(); +} diff --git a/src/tools/rustfmt/tests/target/issue-3434/not_skip_macro.rs b/src/tools/rustfmt/tests/target/issue-3434/not_skip_macro.rs new file mode 100644 index 000000000..c90d09744 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3434/not_skip_macro.rs @@ -0,0 +1,8 @@ +#[this::is::not::skip::macros(ouch)] + +fn main() { + let macro_result1 = ouch! { <div> + this should be mangled</div> + } + .to_string(); +} diff --git a/src/tools/rustfmt/tests/target/issue-3442.rs b/src/tools/rustfmt/tests/target/issue-3442.rs new file mode 100644 index 000000000..3664c50ee --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3442.rs @@ -0,0 +1,10 @@ +// rustfmt-file_lines: [{"file":"tests/target/issue-3442.rs","range":[5,5]},{"file":"tests/target/issue-3442.rs","range":[8,8]}] + +extern crate alpha; // comment 1 +extern crate beta; // comment 2 +#[allow(aaa)] // comment 3 +#[macro_use] +extern crate gamma; +#[allow(bbb)] // comment 4 +#[macro_use] +extern crate lazy_static; diff --git a/src/tools/rustfmt/tests/target/issue-3465.rs b/src/tools/rustfmt/tests/target/issue-3465.rs new file mode 100644 index 000000000..9e2680f0f --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3465.rs @@ -0,0 +1,42 @@ +fn main() { + ((((((((((((((((((((((((((((((((((((((((((0) + 1) + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1) + + 1); +} diff --git a/src/tools/rustfmt/tests/target/issue-3494/crlf.rs b/src/tools/rustfmt/tests/target/issue-3494/crlf.rs new file mode 100644 index 000000000..cae615a06 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3494/crlf.rs @@ -0,0 +1,8 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-3494/crlf.rs","range":[4,5]}] + +pub fn main() {
+ let world1 = "world"; + println!("Hello, {}!", world1);
+let world2 = "world"; println!("Hello, {}!", world2);
+let world3 = "world"; println!("Hello, {}!", world3);
+}
diff --git a/src/tools/rustfmt/tests/target/issue-3494/lf.rs b/src/tools/rustfmt/tests/target/issue-3494/lf.rs new file mode 100644 index 000000000..60aafe19a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3494/lf.rs @@ -0,0 +1,8 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-3494/lf.rs","range":[4,5]}] + +pub fn main() { + let world1 = "world"; + println!("Hello, {}!", world1); +let world2 = "world"; println!("Hello, {}!", world2); +let world3 = "world"; println!("Hello, {}!", world3); +} diff --git a/src/tools/rustfmt/tests/target/issue-3499.rs b/src/tools/rustfmt/tests/target/issue-3499.rs new file mode 100644 index 000000000..88fd7f7e1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3499.rs @@ -0,0 +1 @@ +test![]; diff --git a/src/tools/rustfmt/tests/target/issue-3508.rs b/src/tools/rustfmt/tests/target/issue-3508.rs new file mode 100644 index 000000000..5f4e15658 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3508.rs @@ -0,0 +1,22 @@ +fn foo<F>(foo2: F) +where + F: Fn( + // this comment is deleted + ), +{ +} + +fn foo_block<F>(foo2: F) +where + F: Fn(/* this comment is deleted */), +{ +} + +fn bar( + bar2: impl Fn( + // this comment is deleted + ), +) { +} + +fn bar_block(bar2: impl Fn(/* this comment is deleted */)) {} diff --git a/src/tools/rustfmt/tests/target/issue-3515.rs b/src/tools/rustfmt/tests/target/issue-3515.rs new file mode 100644 index 000000000..b59d03c6c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3515.rs @@ -0,0 +1,6 @@ +// rustfmt-reorder_imports: false + +use std::fmt::{self, Display}; +use std::collections::HashMap; + +fn main() {} diff --git a/src/tools/rustfmt/tests/target/issue-3532.rs b/src/tools/rustfmt/tests/target/issue-3532.rs new file mode 100644 index 000000000..f41902620 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3532.rs @@ -0,0 +1,6 @@ +fn foo(a: T) { + match a { + 1 => {} + 0 => {} // _ => panic!("doesn't format!"), + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3539.rs b/src/tools/rustfmt/tests/target/issue-3539.rs new file mode 100644 index 000000000..aa2fa72ec --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3539.rs @@ -0,0 +1,8 @@ +use std::io::Error; + +fn main() { + let _read_num: fn() -> Result<(i32), Error> = || -> Result<(i32), Error> { + let a = 1; + Ok(a) + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-3554.rs b/src/tools/rustfmt/tests/target/issue-3554.rs new file mode 100644 index 000000000..4ece90403 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3554.rs @@ -0,0 +1,4 @@ +#![feature(const_generics)] + +pub struct S<const N: usize>; +impl S<{ 0 }> {} diff --git a/src/tools/rustfmt/tests/target/issue-3567.rs b/src/tools/rustfmt/tests/target/issue-3567.rs new file mode 100644 index 000000000..3cf08628d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3567.rs @@ -0,0 +1,3 @@ +fn check() { + vec![vec!(0; 10); 10]; +} diff --git a/src/tools/rustfmt/tests/target/issue-3568.rs b/src/tools/rustfmt/tests/target/issue-3568.rs new file mode 100644 index 000000000..a146f3df2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3568.rs @@ -0,0 +1 @@ +use a::b::{self}; diff --git a/src/tools/rustfmt/tests/target/issue-3585/extern_crate.rs b/src/tools/rustfmt/tests/target/issue-3585/extern_crate.rs new file mode 100644 index 000000000..dc7c9e024 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3585/extern_crate.rs @@ -0,0 +1,10 @@ +// rustfmt-inline_attribute_width: 100 + +#[macro_use] extern crate static_assertions; + +#[cfg(unix)] extern crate static_assertions; + +// a comment before the attribute +#[macro_use] +// some comment after +extern crate static_assertions; diff --git a/src/tools/rustfmt/tests/target/issue-3585/reorder_imports_disabled.rs b/src/tools/rustfmt/tests/target/issue-3585/reorder_imports_disabled.rs new file mode 100644 index 000000000..f9637729b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3585/reorder_imports_disabled.rs @@ -0,0 +1,8 @@ +// rustfmt-inline_attribute_width: 100 +// rustfmt-reorder_imports: false + +#[cfg(unix)] extern crate crateb; +#[cfg(unix)] extern crate cratea; + +#[cfg(unix)] use crateb; +#[cfg(unix)] use cratea; diff --git a/src/tools/rustfmt/tests/target/issue-3585/reorder_imports_enabled.rs b/src/tools/rustfmt/tests/target/issue-3585/reorder_imports_enabled.rs new file mode 100644 index 000000000..d040d0ed3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3585/reorder_imports_enabled.rs @@ -0,0 +1,8 @@ +// rustfmt-inline_attribute_width: 100 +// rustfmt-reorder_imports: true + +#[cfg(unix)] extern crate cratea; +#[cfg(unix)] extern crate crateb; + +#[cfg(unix)] use cratea; +#[cfg(unix)] use crateb; diff --git a/src/tools/rustfmt/tests/target/issue-3585/use.rs b/src/tools/rustfmt/tests/target/issue-3585/use.rs new file mode 100644 index 000000000..c76a9eaac --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3585/use.rs @@ -0,0 +1,5 @@ +// rustfmt-inline_attribute_width: 100 + +#[macro_use] use static_assertions; + +#[cfg(unix)] use static_assertions; diff --git a/src/tools/rustfmt/tests/target/issue-3595.rs b/src/tools/rustfmt/tests/target/issue-3595.rs new file mode 100644 index 000000000..3e06538a4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3595.rs @@ -0,0 +1,4 @@ +struct ReqMsg(); +struct RespMsg(); + +pub type TestType = fn() -> (ReqMsg, fn(RespMsg) -> ()); diff --git a/src/tools/rustfmt/tests/target/issue-3601.rs b/src/tools/rustfmt/tests/target/issue-3601.rs new file mode 100644 index 000000000..c86ca24e7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3601.rs @@ -0,0 +1,11 @@ +#![feature(const_generics)] + +trait A { + fn foo(&self); +} + +pub struct B<const N: usize>([usize; N]); + +impl<const N: usize> A for B<{ N }> { + fn foo(&self) {} +} diff --git a/src/tools/rustfmt/tests/target/issue-3614/version_one.rs b/src/tools/rustfmt/tests/target/issue-3614/version_one.rs new file mode 100644 index 000000000..8ab283047 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3614/version_one.rs @@ -0,0 +1,15 @@ +// rustfmt-version: One + +fn main() { + let toto = || { + if true { + 42 + } else { + 24 + } + }; + + { + T + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3614/version_two.rs b/src/tools/rustfmt/tests/target/issue-3614/version_two.rs new file mode 100644 index 000000000..5d6f8e7a3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3614/version_two.rs @@ -0,0 +1,8 @@ +// rustfmt-version: Two + +fn main() { + let toto = || { + if true { 42 } else { 24 } + }; + { T } +} diff --git a/src/tools/rustfmt/tests/target/issue-3636.rs b/src/tools/rustfmt/tests/target/issue-3636.rs new file mode 100644 index 000000000..d467ed738 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3636.rs @@ -0,0 +1,8 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-3636.rs","range":[4,7]},{"file":"tests/target/issue-3636.rs","range":[3,6]}] + +fn foo() { + let x = 42; + let y = 42; + let z = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + let z = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +} diff --git a/src/tools/rustfmt/tests/target/issue-3639.rs b/src/tools/rustfmt/tests/target/issue-3639.rs new file mode 100644 index 000000000..e8fddce2d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3639.rs @@ -0,0 +1,5 @@ +trait Foo {} +struct Bar {} +struct Bax; +struct Baz(String); +impl Foo for Bar {} diff --git a/src/tools/rustfmt/tests/target/issue-3645.rs b/src/tools/rustfmt/tests/target/issue-3645.rs new file mode 100644 index 000000000..14bf96e63 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3645.rs @@ -0,0 +1,3 @@ +mod x { + use super::self as x; +} diff --git a/src/tools/rustfmt/tests/target/issue-3651.rs b/src/tools/rustfmt/tests/target/issue-3651.rs new file mode 100644 index 000000000..4a95a1712 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3651.rs @@ -0,0 +1,7 @@ +fn f() -> Box< + dyn FnMut() -> Thing< + WithType = LongItemName, + Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger, + >, +> { +} diff --git a/src/tools/rustfmt/tests/target/issue-3665/lib.rs b/src/tools/rustfmt/tests/target/issue-3665/lib.rs new file mode 100644 index 000000000..c313f3203 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3665/lib.rs @@ -0,0 +1,31 @@ +#![rustfmt::skip::attributes(skip_mod_attr)] + +mod sub_mod; + +#[rustfmt::skip::attributes(other, skip_attr)] +fn main() { + #[other(should, +skip, + this, format)] + struct S {} + + #[skip_attr(should, skip, +this, format,too)] + fn doesnt_mater() {} + + #[skip_mod_attr(should, skip, +this, format, + enerywhere)] + fn more() {} + + #[not_skip(not, skip, me)] + struct B {} +} + +#[other(should, not, skip, this, format, here)] +fn foo() {} + +#[skip_mod_attr(should, skip, +this, format,in, master, + and, sub, module)] +fn bar() {} diff --git a/src/tools/rustfmt/tests/target/issue-3665/not_skip_attribute.rs b/src/tools/rustfmt/tests/target/issue-3665/not_skip_attribute.rs new file mode 100644 index 000000000..a4e8b9487 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3665/not_skip_attribute.rs @@ -0,0 +1,4 @@ +#![this::is::not::skip::attribute(ouch)] + +#[ouch(not, skip, me)] +fn main() {} diff --git a/src/tools/rustfmt/tests/target/issue-3665/sub_mod.rs b/src/tools/rustfmt/tests/target/issue-3665/sub_mod.rs new file mode 100644 index 000000000..30a2b0fd9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3665/sub_mod.rs @@ -0,0 +1,13 @@ +#[rustfmt::skip::attributes(more_skip)] +#[more_skip(should, + skip, +this, format)] +fn foo() {} + +#[skip_mod_attr(should, skip, +this, format,in, master, + and, sub, module)] +fn bar() {} + +#[skip_attr(should, not, skip, this, attribute, here)] +fn baz() {} diff --git a/src/tools/rustfmt/tests/target/issue-3672.rs b/src/tools/rustfmt/tests/target/issue-3672.rs new file mode 100644 index 000000000..8cc3d3fd2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3672.rs @@ -0,0 +1,3 @@ +fn main() { + let x = 5; +} diff --git a/src/tools/rustfmt/tests/target/issue-3675.rs b/src/tools/rustfmt/tests/target/issue-3675.rs new file mode 100644 index 000000000..62d986e77 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3675.rs @@ -0,0 +1,6 @@ +fn main() { + println!( + "{}", // comment + 111 + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-3701/one.rs b/src/tools/rustfmt/tests/target/issue-3701/one.rs new file mode 100644 index 000000000..9d1ef9eed --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3701/one.rs @@ -0,0 +1,12 @@ +// rustfmt-version: One + +fn build_sorted_static_get_entry_names( + mut entries: Vec<(u8, &'static str)>, +) -> (impl Fn( + AlphabeticalTraversal, + Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>, +) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>> + + Send + + Sync + + 'static) { +} diff --git a/src/tools/rustfmt/tests/target/issue-3701/two.rs b/src/tools/rustfmt/tests/target/issue-3701/two.rs new file mode 100644 index 000000000..62ffc9d82 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3701/two.rs @@ -0,0 +1,14 @@ +// rustfmt-version: Two + +fn build_sorted_static_get_entry_names( + mut entries: Vec<(u8, &'static str)>, +) -> ( + impl Fn( + AlphabeticalTraversal, + Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>, + ) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>> + + Send + + Sync + + 'static +) { +} diff --git a/src/tools/rustfmt/tests/target/issue-3709.rs b/src/tools/rustfmt/tests/target/issue-3709.rs new file mode 100644 index 000000000..0f3eae048 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3709.rs @@ -0,0 +1,10 @@ +// rustfmt-edition: 2018 + +macro_rules! token { + ($t:tt) => {}; +} + +fn main() { + token!(dyn); + token!(dyn); +} diff --git a/src/tools/rustfmt/tests/target/issue-3711.rs b/src/tools/rustfmt/tests/target/issue-3711.rs new file mode 100644 index 000000000..62d986e77 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3711.rs @@ -0,0 +1,6 @@ +fn main() { + println!( + "{}", // comment + 111 + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-3717.rs b/src/tools/rustfmt/tests/target/issue-3717.rs new file mode 100644 index 000000000..b769cd3ec --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3717.rs @@ -0,0 +1,7 @@ +fn main() { + { + #[rustfmt::skip] + let _ = + [1]; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3718.rs b/src/tools/rustfmt/tests/target/issue-3718.rs new file mode 100644 index 000000000..8ad21ffc7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3718.rs @@ -0,0 +1,7 @@ +fn main() { + let x: &[i32] = &[2, 2]; + match x { + [_a, _] => println!("Wrong username or password"), + _ => println!("Logged in"), + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3740.rs b/src/tools/rustfmt/tests/target/issue-3740.rs new file mode 100644 index 000000000..995a6bee3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3740.rs @@ -0,0 +1,8 @@ +impl<T, const SIZE: usize> IntoNormalized for Vector<T, { SIZE }> +where + Vector<T, { SIZE }>: Div<Vector<T, { SIZE }>>, + for<'a> &'a Vector<T, { SIZE }>: IntoLength<Output = T>, +{ + type Output = Vector<T, { SIZE }>; + fn into_normalized(self) -> Self::Output {} +} diff --git a/src/tools/rustfmt/tests/target/issue-3741.rs b/src/tools/rustfmt/tests/target/issue-3741.rs new file mode 100644 index 000000000..34d22dc91 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3741.rs @@ -0,0 +1,5 @@ +pub enum PublishedFileVisibility { + Public = sys::ERemoteStoragePublishedFileVisibility_k_ERemoteStoragePublishedFileVisibilityPublic as i32, + FriendsOnly = sys::ERemoteStoragePublishedFileVisibility_k_ERemoteStoragePublishedFileVisibilityFriendsOnly as i32, + Private = sys::ERemoteStoragePublishedFileVisibility_k_ERemoteStoragePublishedFileVisibilityPrivate as i32, +} diff --git a/src/tools/rustfmt/tests/target/issue-3750.rs b/src/tools/rustfmt/tests/target/issue-3750.rs new file mode 100644 index 000000000..6875f8d38 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3750.rs @@ -0,0 +1,15 @@ +// rustfmt-imports_granularity: Crate + +pub mod foo { + pub mod bar { + pub struct Bar; + } + + pub fn bar() {} +} + +use foo::{bar, bar::Bar}; + +fn main() { + bar(); +} diff --git a/src/tools/rustfmt/tests/target/issue-3751.rs b/src/tools/rustfmt/tests/target/issue-3751.rs new file mode 100644 index 000000000..e5a03956e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3751.rs @@ -0,0 +1,10 @@ +// rustfmt-format_code_in_doc_comments: true + +//! Empty pound line +//! +//! ```rust +//! # +//! # fn main() { +//! foo(); +//! # } +//! ``` diff --git a/src/tools/rustfmt/tests/target/issue-3759.rs b/src/tools/rustfmt/tests/target/issue-3759.rs new file mode 100644 index 000000000..b53f5391a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3759.rs @@ -0,0 +1,27 @@ +fn main() { + let Test { + #[cfg(feature = "test")] + x, + } = Test { + #[cfg(feature = "test")] + x: 1, + }; + + let Test { + #[cfg(feature = "test")] + // comment + x, + } = Test { + #[cfg(feature = "test")] + x: 1, + }; + + let Test { + // comment + #[cfg(feature = "test")] + x, + } = Test { + #[cfg(feature = "test")] + x: 1, + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-3779/ice.rs b/src/tools/rustfmt/tests/target/issue-3779/ice.rs new file mode 100644 index 000000000..cde21412d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3779/ice.rs @@ -0,0 +1,3 @@ +pub fn bar() { + 1x; +} diff --git a/src/tools/rustfmt/tests/target/issue-3779/lib.rs b/src/tools/rustfmt/tests/target/issue-3779/lib.rs new file mode 100644 index 000000000..a5673a4db --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3779/lib.rs @@ -0,0 +1,9 @@ +// rustfmt-unstable: true +// rustfmt-config: issue-3779.toml + +#[path = "ice.rs"] +mod ice; + +fn foo() { + println!("abc"); +} diff --git a/src/tools/rustfmt/tests/target/issue-3786.rs b/src/tools/rustfmt/tests/target/issue-3786.rs new file mode 100644 index 000000000..d90cba15d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3786.rs @@ -0,0 +1,9 @@ +fn main() { + let _ = r#" +this is a very long string exceeded maximum width in this case maximum 100. (current this line width is about 115) +"#; + + let _with_newline = r#" +this is a very long string exceeded maximum width in this case maximum 100. (current this line width is about 115) +"#; +} diff --git a/src/tools/rustfmt/tests/target/issue-3787.rs b/src/tools/rustfmt/tests/target/issue-3787.rs new file mode 100644 index 000000000..32cf7e3d7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3787.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: true + +//! URLs in items +//! * [This is a link with a very loooooooooooooooooooooooooooooooooooooooooong URL.](https://example.com/This/is/a/link/with/a/very/loooooooooooooooooooooooooooooooooooooooooong/URL) +//! * This is a [link](https://example.com/This/is/a/link/with/a/very/loooooooooooooooooooooooooooooooooooooooooong/URL) +//! with a very loooooooooooooooooooooooooooooooooooooooooong URL. +//! * there is no link here: In hac habitasse platea dictumst. Maecenas in +//! ligula. Duis tincidunt odio sollicitudin quam. Nullam non mauris. +//! Phasellus lacinia, velit sit amet bibendum euismod, leo diam interdum +//! ligula, eu scelerisque sem purus in tellus. +fn main() { + println!("Hello, world!"); +} diff --git a/src/tools/rustfmt/tests/target/issue-3815.rs b/src/tools/rustfmt/tests/target/issue-3815.rs new file mode 100644 index 000000000..eff27e2de --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3815.rs @@ -0,0 +1,4 @@ +pub type Type = impl Deref<Target = i8>; + +pub type Type = + impl VeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeryLongType<Target = i8>; diff --git a/src/tools/rustfmt/tests/target/issue-3840/version-one_hard-tabs.rs b/src/tools/rustfmt/tests/target/issue-3840/version-one_hard-tabs.rs new file mode 100644 index 000000000..4aa905ce9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3840/version-one_hard-tabs.rs @@ -0,0 +1,25 @@ +// rustfmt-hard_tabs: true + +impl< + Target: FromEvent<A> + FromEvent<B>, + A: Widget2<Ctx = C>, + B: Widget2<Ctx = C>, + C: for<'a> CtxFamily<'a>, + > Widget2 for WidgetEventLifter<Target, A, B> +{ + type Ctx = C; + type Event = Vec<Target>; +} + +mod foo { + impl< + Target: FromEvent<A> + FromEvent<B>, + A: Widget2<Ctx = C>, + B: Widget2<Ctx = C>, + C: for<'a> CtxFamily<'a>, + > Widget2 for WidgetEventLifter<Target, A, B> + { + type Ctx = C; + type Event = Vec<Target>; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3840/version-one_soft-tabs.rs b/src/tools/rustfmt/tests/target/issue-3840/version-one_soft-tabs.rs new file mode 100644 index 000000000..099e68018 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3840/version-one_soft-tabs.rs @@ -0,0 +1,23 @@ +impl< + Target: FromEvent<A> + FromEvent<B>, + A: Widget2<Ctx = C>, + B: Widget2<Ctx = C>, + C: for<'a> CtxFamily<'a>, + > Widget2 for WidgetEventLifter<Target, A, B> +{ + type Ctx = C; + type Event = Vec<Target>; +} + +mod foo { + impl< + Target: FromEvent<A> + FromEvent<B>, + A: Widget2<Ctx = C>, + B: Widget2<Ctx = C>, + C: for<'a> CtxFamily<'a>, + > Widget2 for WidgetEventLifter<Target, A, B> + { + type Ctx = C; + type Event = Vec<Target>; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3840/version-two_hard-tabs.rs b/src/tools/rustfmt/tests/target/issue-3840/version-two_hard-tabs.rs new file mode 100644 index 000000000..084db3d14 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3840/version-two_hard-tabs.rs @@ -0,0 +1,26 @@ +// rustfmt-hard_tabs: true +// rustfmt-version: Two + +impl< + Target: FromEvent<A> + FromEvent<B>, + A: Widget2<Ctx = C>, + B: Widget2<Ctx = C>, + C: for<'a> CtxFamily<'a>, +> Widget2 for WidgetEventLifter<Target, A, B> +{ + type Ctx = C; + type Event = Vec<Target>; +} + +mod foo { + impl< + Target: FromEvent<A> + FromEvent<B>, + A: Widget2<Ctx = C>, + B: Widget2<Ctx = C>, + C: for<'a> CtxFamily<'a>, + > Widget2 for WidgetEventLifter<Target, A, B> + { + type Ctx = C; + type Event = Vec<Target>; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3840/version-two_soft-tabs.rs b/src/tools/rustfmt/tests/target/issue-3840/version-two_soft-tabs.rs new file mode 100644 index 000000000..bc59b0baa --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3840/version-two_soft-tabs.rs @@ -0,0 +1,25 @@ +// rustfmt-version: Two + +impl< + Target: FromEvent<A> + FromEvent<B>, + A: Widget2<Ctx = C>, + B: Widget2<Ctx = C>, + C: for<'a> CtxFamily<'a>, +> Widget2 for WidgetEventLifter<Target, A, B> +{ + type Ctx = C; + type Event = Vec<Target>; +} + +mod foo { + impl< + Target: FromEvent<A> + FromEvent<B>, + A: Widget2<Ctx = C>, + B: Widget2<Ctx = C>, + C: for<'a> CtxFamily<'a>, + > Widget2 for WidgetEventLifter<Target, A, B> + { + type Ctx = C; + type Event = Vec<Target>; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-3845.rs b/src/tools/rustfmt/tests/target/issue-3845.rs new file mode 100644 index 000000000..877c05b86 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3845.rs @@ -0,0 +1,8 @@ +fn main() { + || { + #[allow(deprecated)] + { + u8::max_value() + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-3882.rs b/src/tools/rustfmt/tests/target/issue-3882.rs new file mode 100644 index 000000000..5eb442af9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3882.rs @@ -0,0 +1,4 @@ +// rustfmt-version: Two +fn bar(_t: T, // bar +) { +} diff --git a/src/tools/rustfmt/tests/target/issue-3974.rs b/src/tools/rustfmt/tests/target/issue-3974.rs new file mode 100644 index 000000000..a9f992ebd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-3974.rs @@ -0,0 +1,10 @@ +fn emulate_foreign_item() { + match link_name { + // A comment here will duplicate the attribute + #[rustfmt::skip] + | "pthread_mutexattr_init" + | "pthread_mutexattr_settype" + | "pthread_mutex_init" + => {} + } +} diff --git a/src/tools/rustfmt/tests/target/issue-4018.rs b/src/tools/rustfmt/tests/target/issue-4018.rs new file mode 100644 index 000000000..cef3be061 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4018.rs @@ -0,0 +1,11 @@ +fn main() { + /* extra comment */ +} + +fn main() { + println!(""); + // comment 1 + // comment 2 + // comment 3 + // comment 4 +} diff --git a/src/tools/rustfmt/tests/target/issue-4020.rs b/src/tools/rustfmt/tests/target/issue-4020.rs new file mode 100644 index 000000000..f29ecec02 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4020.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: true + +/** foobar */ +const foo1: u32 = 0; + +/** + * foobar + */ +const foo2: u32 = 0; diff --git a/src/tools/rustfmt/tests/target/issue-4029.rs b/src/tools/rustfmt/tests/target/issue-4029.rs new file mode 100644 index 000000000..314d01805 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4029.rs @@ -0,0 +1,7 @@ +// issue #4029 +#[derive(Debug, Clone, Default Hash)] +struct S; + +// issue #3898 +#[derive(Debug, Clone, Default,, Hash)] +struct T; diff --git a/src/tools/rustfmt/tests/target/issue-4036/one.rs b/src/tools/rustfmt/tests/target/issue-4036/one.rs new file mode 100644 index 000000000..54e490b7f --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4036/one.rs @@ -0,0 +1,12 @@ +// rustfmt-format_strings: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "We asserted that `buffer.len()` is exactly `$n` so we can expect \ + `ApInt::from_iter` to be successful.", + ) + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-4036/three.rs b/src/tools/rustfmt/tests/target/issue-4036/three.rs new file mode 100644 index 000000000..394dc8633 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4036/three.rs @@ -0,0 +1,17 @@ +// rustfmt-format_strings: true +// rustfmt-hard_tabs: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor \ + incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis \ + nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \ + Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu \ + fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \ + culpa qui officia deserunt mollit anim id est laborum.", + ) + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-4036/two.rs b/src/tools/rustfmt/tests/target/issue-4036/two.rs new file mode 100644 index 000000000..01cafa76b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4036/two.rs @@ -0,0 +1,16 @@ +// rustfmt-format_strings: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor \ + incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis \ + nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \ + Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu \ + fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \ + culpa qui officia deserunt mollit anim id est laborum.", + ) + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-4068.rs b/src/tools/rustfmt/tests/target/issue-4068.rs new file mode 100644 index 000000000..cd8a1f276 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4068.rs @@ -0,0 +1,3 @@ +fn main() { + extern "C" fn packet_records_options_impl_layout_length_encoding_option_len_multiplier(); +} diff --git a/src/tools/rustfmt/tests/target/issue-4079.rs b/src/tools/rustfmt/tests/target/issue-4079.rs new file mode 100644 index 000000000..1871c5b8a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4079.rs @@ -0,0 +1,11 @@ +// rustfmt-wrap_comments: true + +/*! + * Lorem ipsum dolor sit amet, consectetur adipiscing elit. In lacinia + * ullamcorper lorem, non hendrerit enim convallis ut. Curabitur id sem + * volutpat + */ + +/*! Lorem ipsum dolor sit amet, consectetur adipiscing elit. In lacinia + * ullamcorper lorem, non hendrerit enim convallis ut. Curabitur id sem + * volutpat */ diff --git a/src/tools/rustfmt/tests/target/issue-4115.rs b/src/tools/rustfmt/tests/target/issue-4115.rs new file mode 100644 index 000000000..0dd7bdbd0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4115.rs @@ -0,0 +1,8 @@ +#[derive( + A, + B, + C, + D, + // E, +)] +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/issue-4120.rs b/src/tools/rustfmt/tests/target/issue-4120.rs new file mode 100644 index 000000000..a7d461dcf --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4120.rs @@ -0,0 +1,85 @@ +fn main() { + let x = if true { + 1 + // In if + } else { + 0 + // In else + }; + + let x = if true { + 1 + /* In if */ + } else { + 0 + /* In else */ + }; + + let z = if true { + if true { + 1 + + // In if level 2 + } else { + 2 + } + } else { + 3 + }; + + let a = if true { + 1 + // In if + } else { + 0 + // In else + }; + + let a = if true { + 1 + + // In if + } else { + 0 + // In else + }; + + let b = if true { + 1 + + // In if + } else { + 0 + // In else + }; + + let c = if true { + 1 + + // In if + } else { + 0 + // In else + }; + for i in 0..2 { + println!("Something"); + // In for + } + + for i in 0..2 { + println!("Something"); + /* In for */ + } + + extern "C" { + fn first(); + + // In foreign mod + } + + extern "C" { + fn first(); + + /* In foreign mod */ + } +} diff --git a/src/tools/rustfmt/tests/target/issue-4152.rs b/src/tools/rustfmt/tests/target/issue-4152.rs new file mode 100644 index 000000000..80f9ff5e3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4152.rs @@ -0,0 +1,18 @@ +// rustfmt-hard_tabs: true + +macro_rules! bit { + ($bool:expr) => { + if $bool { + 1; + 1 + } else { + 0; + 0 + } + }; +} +macro_rules! add_one { + ($vec:expr) => {{ + $vec.push(1); + }}; +} diff --git a/src/tools/rustfmt/tests/target/issue-4159.rs b/src/tools/rustfmt/tests/target/issue-4159.rs new file mode 100644 index 000000000..2f8cf20da --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4159.rs @@ -0,0 +1,18 @@ +extern "C" { + type A: Ord; + + type A<'a> + where + 'a: 'static; + + type A<T: Ord> + where + T: 'static; + + type A = u8; + + type A<'a: 'static, T: Ord + 'static>: Eq + PartialEq + where + T: 'static + Copy, + = Vec<u8>; +} diff --git a/src/tools/rustfmt/tests/target/issue-4243.rs b/src/tools/rustfmt/tests/target/issue-4243.rs new file mode 100644 index 000000000..67fa1d2a3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4243.rs @@ -0,0 +1,28 @@ +fn main() { + type A: AA /*AA*/ + /*AB*/ AB + AC = AA + /*AA*/ + + + /*AB*/ + AB + + AC; + + type B: BA /*BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA*/ + + /*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/ BB + + BC = BA /*BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA*/ + + /*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/ BB + + BC; + + type C: CA // CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + // CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + + // CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + // CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + CB + + CC = CA // CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + // CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + + // CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + // CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + CB + + CC; +} diff --git a/src/tools/rustfmt/tests/target/issue-4244.rs b/src/tools/rustfmt/tests/target/issue-4244.rs new file mode 100644 index 000000000..8958ba99e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4244.rs @@ -0,0 +1,20 @@ +pub struct SS {} + +pub type A /* A Comment */ = SS; + +pub type B // Comment + // B + = SS; + +pub type C + /* Comment C */ + = SS; + +pub trait D<T> { + type E /* Comment E */ = SS; +} + +type F<'a: 'static, T: Ord + 'static>: Eq + PartialEq +where + T: 'static + Copy, /* x */ += Vec<u8>; diff --git a/src/tools/rustfmt/tests/target/issue-4245.rs b/src/tools/rustfmt/tests/target/issue-4245.rs new file mode 100644 index 000000000..e3d40eb42 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4245.rs @@ -0,0 +1,34 @@ +fn a( + a: & // Comment + // Another comment + 'a File, +) { +} + +fn b(b: & /* Another Comment */ 'a File) {} + +fn c(c: &'a /*Comment */ mut /*Comment */ File) {} + +fn d( + c: & // Comment + 'b // Multi Line + // Comment + mut // Multi Line + // Comment + File, +) { +} + +fn e( + c: & // Comment + File, +) { +} + +fn d( + c: & // Comment + mut // Multi Line + // Comment + File, +) { +} diff --git a/src/tools/rustfmt/tests/target/issue-4310.rs b/src/tools/rustfmt/tests/target/issue-4310.rs new file mode 100644 index 000000000..6cf494fc5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4310.rs @@ -0,0 +1,9 @@ +#![feature(const_generics)] + +fn foo< + const N: [u8; { + struct Inner<'a>(&'a ()); + 3 + }], +>() { +} diff --git a/src/tools/rustfmt/tests/target/issue-4312.rs b/src/tools/rustfmt/tests/target/issue-4312.rs new file mode 100644 index 000000000..b36b0efdb --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4312.rs @@ -0,0 +1,22 @@ +// issue 4312 +fn main() { + /* " */ + println!("Hello, world!"); + /* abc " */ + println!("Hello, world!"); + /* " abc */ + println!("Hello, world!"); + let y = 4; + let x = match 1 + y == 3 { + True => 3, + False => 4, + /* " unreachable */ + }; +} + +// issue 4806 +enum X { + A, + B, + /*"*/ +} diff --git a/src/tools/rustfmt/tests/target/issue-4313.rs b/src/tools/rustfmt/tests/target/issue-4313.rs new file mode 100644 index 000000000..c390ee6ba --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4313.rs @@ -0,0 +1,5 @@ +extern "C" { + fn f() { + fn g() {} + } +} diff --git a/src/tools/rustfmt/tests/target/issue-4382.rs b/src/tools/rustfmt/tests/target/issue-4382.rs new file mode 100644 index 000000000..740fa9bfe --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4382.rs @@ -0,0 +1,10 @@ +pub const NAME_MAX: usize = { + #[cfg(target_os = "linux")] + { + 1024 + } + #[cfg(target_os = "freebsd")] + { + 255 + } +}; diff --git a/src/tools/rustfmt/tests/target/issue-4398.rs b/src/tools/rustfmt/tests/target/issue-4398.rs new file mode 100644 index 000000000..2ca894528 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4398.rs @@ -0,0 +1,19 @@ +impl Struct { + /// Documentation for `foo` + #[rustfmt::skip] // comment on why use a skip here + pub fn foo(&self) {} +} + +impl Struct { + /// Documentation for `foo` + #[rustfmt::skip] // comment on why use a skip here + pub fn foo(&self) {} +} + +/// Documentation for `Struct` +#[rustfmt::skip] // comment +impl Struct { + /// Documentation for `foo` + #[rustfmt::skip] // comment on why use a skip here + pub fn foo(&self) {} +} diff --git a/src/tools/rustfmt/tests/target/issue-4427.rs b/src/tools/rustfmt/tests/target/issue-4427.rs new file mode 100644 index 000000000..c8a37ead8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4427.rs @@ -0,0 +1,30 @@ +const A: usize = + // Some constant + 2; + +const B: usize = + /* constant */ + 3; + +const C: usize = /* foo */ 5; + +const D: usize = // baz + /* Some constant */ + /* ba */ + { + 3 + // foo + }; +const E: usize = /* foo */ 5; +const F: usize = { 7 }; +const G: usize = + /* foooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000xx00 */ + 5; +const H: usize = /* asdfasdf */ + match G > 1 { + true => 1, + false => 3, + }; + +pub static FOO_BAR: Vec<u8> = //f + { vec![] }; diff --git a/src/tools/rustfmt/tests/target/issue-447.rs b/src/tools/rustfmt/tests/target/issue-447.rs new file mode 100644 index 000000000..d41cdb65c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-447.rs @@ -0,0 +1,40 @@ +// rustfmt-normalize_comments: true + +fn main() { + if + // shouldn't be dropped + // shouldn't be dropped + cond + // shouldn't be dropped + // shouldn't be dropped + { + } + // shouldn't be dropped + // shouldn't be dropped + else + // shouldn't be dropped + // shouldn't be dropped + if + // shouldn't be dropped + // shouldn't be dropped + cond + // shouldn't be dropped + // shouldn't be dropped + { + } + // shouldn't be dropped + // shouldn't be dropped + else + // shouldn't be dropped + // shouldn't be dropped + { + } + + if + // shouldn't be dropped + // shouldn't be dropped + let Some(x) = y + // shouldn't be dropped + // shouldn't be dropped + {} +} diff --git a/src/tools/rustfmt/tests/target/issue-4530.rs b/src/tools/rustfmt/tests/target/issue-4530.rs new file mode 100644 index 000000000..296dc559a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4530.rs @@ -0,0 +1,9 @@ +// rustfmt-version: Two +fn main() { + let [ + aaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + cccccccccccccccccccccccccc, + ddddddddddddddddddddddddd, + ] = panic!(); +} diff --git a/src/tools/rustfmt/tests/target/issue-4577.rs b/src/tools/rustfmt/tests/target/issue-4577.rs new file mode 100644 index 000000000..1bd9eb6b8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4577.rs @@ -0,0 +1,15 @@ +fn main() { + let s: String = "ABAABBAA" + .chars() + .filter(|c| if *c == 'A' { true } else { false }) + .map(|c| -> char { + if c == 'A' { + '0' + } else { + '1' + } + }) + .collect(); + + println!("{}", s); +} diff --git a/src/tools/rustfmt/tests/target/issue-4603.rs b/src/tools/rustfmt/tests/target/issue-4603.rs new file mode 100644 index 000000000..e8c368a24 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4603.rs @@ -0,0 +1,47 @@ +// Formatting when original macro snippet is used + +// Original issue #4603 code +#![feature(or_patterns)] +macro_rules! t_or_f { + () => { + (true // some comment + | false) + }; +} + +// Other test cases variations +macro_rules! RULES { + () => { + ( + xxxxxxx // COMMENT + | yyyyyyy + ) + }; +} +macro_rules! RULES { + () => { + (xxxxxxx // COMMENT + | yyyyyyy) + }; +} + +fn main() { + macro_rules! RULES { + () => { + (xxxxxxx // COMMENT + | yyyyyyy) + }; + } +} + +macro_rules! RULES { + () => { + (xxxxxxx /* COMMENT */ | yyyyyyy) + }; +} +macro_rules! RULES { + () => { + (xxxxxxx /* COMMENT */ + | yyyyyyy) + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-4615/minimum_example.rs b/src/tools/rustfmt/tests/target/issue-4615/minimum_example.rs new file mode 100644 index 000000000..223b89b81 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4615/minimum_example.rs @@ -0,0 +1,5 @@ +info!( + //debug + "{}: sending function_code={:04x} data={:04x} crc=0x{:04X} data={:02X?}", + self.name, function_code, data, crc, output_cmd +); diff --git a/src/tools/rustfmt/tests/target/issue-4646.rs b/src/tools/rustfmt/tests/target/issue-4646.rs new file mode 100644 index 000000000..4e149399f --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4646.rs @@ -0,0 +1,20 @@ +trait Foo { + fn bar(&self) + // where + // Self: Bar + ; +} + +trait Foo { + fn bar(&self) + // where + // Self: Bar + ; +} + +trait Foo { + fn bar(&self) + // where + // Self: Bar + ; +} diff --git a/src/tools/rustfmt/tests/target/issue-4656/format_me_please.rs b/src/tools/rustfmt/tests/target/issue-4656/format_me_please.rs new file mode 100644 index 000000000..421e195a2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4656/format_me_please.rs @@ -0,0 +1 @@ +pub fn hello() {} diff --git a/src/tools/rustfmt/tests/target/issue-4656/lib.rs b/src/tools/rustfmt/tests/target/issue-4656/lib.rs new file mode 100644 index 000000000..5dac91b8a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4656/lib.rs @@ -0,0 +1,7 @@ +extern crate cfg_if; + +cfg_if::cfg_if! { + if #[cfg(target_family = "unix")] { + mod format_me_please; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-4656/lib2.rs b/src/tools/rustfmt/tests/target/issue-4656/lib2.rs new file mode 100644 index 000000000..b17fffc58 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4656/lib2.rs @@ -0,0 +1,3 @@ +its_a_macro! { + // Contents +} diff --git a/src/tools/rustfmt/tests/target/issue-4791/buggy.rs b/src/tools/rustfmt/tests/target/issue-4791/buggy.rs new file mode 100644 index 000000000..fff58be99 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4791/buggy.rs @@ -0,0 +1,14 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-trailing_comma: Never + +struct Foo { + group_a: u8, + + group_b: u8 +} + +struct Bar { + group_a: u8, + + group_b: u8 +} diff --git a/src/tools/rustfmt/tests/target/issue-4791/issue_4928.rs b/src/tools/rustfmt/tests/target/issue-4791/issue_4928.rs new file mode 100644 index 000000000..588656b53 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4791/issue_4928.rs @@ -0,0 +1,70 @@ +// rustfmt-brace_style: SameLineWhere +// rustfmt-comment_width: 100 +// rustfmt-edition: 2018 +// rustfmt-fn_args_layout: Compressed +// rustfmt-hard_tabs: false +// rustfmt-match_block_trailing_comma: true +// rustfmt-max_width: 100 +// rustfmt-merge_derives: false +// rustfmt-newline_style: Unix +// rustfmt-normalize_doc_attributes: true +// rustfmt-overflow_delimited_expr: true +// rustfmt-reorder_imports: false +// rustfmt-reorder_modules: true +// rustfmt-struct_field_align_threshold: 20 +// rustfmt-tab_spaces: 4 +// rustfmt-trailing_comma: Never +// rustfmt-use_small_heuristics: Max +// rustfmt-use_try_shorthand: true +// rustfmt-wrap_comments: true + +/// Lorem ipsum dolor sit amet. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] +pub struct BufferAttr { + /* NOTE: Blah blah blah blah blah. */ + /// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt + /// ut labore et dolore magna aliqua. Morbi quis commodo odio aenean sed adipiscing. Nunc + /// congue nisi vitae suscipit tellus mauris a. Consectetur adipiscing elit pellentesque + /// habitant morbi tristique senectus. + pub foo: u32, + + /// Elit eget gravida cum sociis natoque penatibus et magnis dis. Consequat semper viverra nam + /// libero. Accumsan in nisl nisi scelerisque eu. Pellentesque id nibh tortor id aliquet. Sed + /// velit dignissim sodales ut. Facilisis sed odio morbi quis commodo odio aenean sed. Et + /// ultrices neque ornare aenean euismod elementum. Condimentum lacinia quis vel eros donec ac + /// odio tempor. + /// + /// Lacinia at quis risus sed vulputate odio ut enim. Etiam erat velit scelerisque in dictum. + /// Nibh tellus molestie nunc non blandit massa enim nec. Nascetur ridiculus mus mauris vitae. + pub bar: u32, + + /// Mi proin sed libero enim sed faucibus turpis. Amet consectetur adipiscing elit duis + /// tristique sollicitudin nibh sit amet. Congue quisque egestas diam in arcu cursus euismod + /// quis viverra. Cum sociis natoque penatibus et magnis dis parturient montes. Enim sit amet + /// venenatis urna cursus eget nunc scelerisque viverra. Cras semper auctor neque vitae tempus + /// quam pellentesque. Tortor posuere ac ut consequat semper viverra nam libero justo. Vitae + /// auctor eu augue ut lectus arcu bibendum at. Faucibus vitae aliquet nec ullamcorper sit amet + /// risus nullam. Maecenas accumsan lacus vel facilisis volutpat. Arcu non odio euismod + /// lacinia. + /// + /// [`FooBar::beep()`]: crate::foobar::FooBar::beep + /// [`FooBar::boop()`]: crate::foobar::FooBar::boop + /// [`foobar::BazBaq::BEEP_BOOP`]: crate::foobar::BazBaq::BEEP_BOOP + pub baz: u32, + + /// Eu consequat ac felis donec et odio pellentesque diam. Ut eu sem integer vitae justo eget. + /// Consequat ac felis donec et odio pellentesque diam volutpat. + pub baq: u32, + + /// Amet consectetur adipiscing elit pellentesque habitant. Ut morbi tincidunt augue interdum + /// velit euismod in pellentesque. Imperdiet sed euismod nisi porta lorem. Nec tincidunt + /// praesent semper feugiat. Facilisis leo vel fringilla est. Egestas diam in arcu cursus + /// euismod quis viverra. Sagittis eu volutpat odio facilisis mauris sit amet. Posuere morbi + /// leo urna molestie at. + /// + /// Pretium aenean pharetra magna ac. Nisl condimentum id venenatis a condimentum vitae. Semper + /// quis lectus nulla at volutpat diam ut venenatis tellus. Egestas tellus rutrum tellus + /// pellentesque eu tincidunt tortor aliquam. + pub foobar: u32 +} diff --git a/src/tools/rustfmt/tests/target/issue-4791/no_trailing_comma.rs b/src/tools/rustfmt/tests/target/issue-4791/no_trailing_comma.rs new file mode 100644 index 000000000..4a3716396 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4791/no_trailing_comma.rs @@ -0,0 +1,8 @@ +// rustfmt-struct_field_align_threshold: 0 +// rustfmt-trailing_comma: Never + +pub struct Baz { + group_a: u8, + + group_b: u8 +} diff --git a/src/tools/rustfmt/tests/target/issue-4791/trailing_comma.rs b/src/tools/rustfmt/tests/target/issue-4791/trailing_comma.rs new file mode 100644 index 000000000..29a224b3f --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4791/trailing_comma.rs @@ -0,0 +1,14 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-trailing_comma: Always + +struct Foo { + group_a: u8, + + group_b: u8, +} + +struct Bar { + group_a: u8, + + group_b: u8, +} diff --git a/src/tools/rustfmt/tests/target/issue-4816/lib.rs b/src/tools/rustfmt/tests/target/issue-4816/lib.rs new file mode 100644 index 000000000..246e775e1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4816/lib.rs @@ -0,0 +1,35 @@ +#![feature(const_generics_defaults)] +struct Foo<const N: usize = 1, const N2: usize = 2>; +struct Bar<const N: usize, const N2: usize = { N + 1 }>; +struct Lots< + const N1BlahFooUwU: usize = { 10 + 28 + 1872 / 10 * 3 }, + const N2SecondParamOhmyyy: usize = { N1BlahFooUwU / 2 + 10 * 2 }, +>; +struct NamesRHard<const N: usize = { 1 + 1 + 1 + 1 + 1 + 1 }>; +struct FooBar< + const LessThan100ButClose: usize = { + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + }, +>; +struct FooBarrrrrrrr< + const N: usize = { + 13478234326456456444323871 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + }, +>; diff --git a/src/tools/rustfmt/tests/target/issue-4908-2.rs b/src/tools/rustfmt/tests/target/issue-4908-2.rs new file mode 100644 index 000000000..023b323cb --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4908-2.rs @@ -0,0 +1,20 @@ +#![feature(more_qualified_paths)] + +fn main() { + // destructure through a qualified path + let <Foo as A>::Assoc { br } = StructStruct { br: 2 }; +} + +struct StructStruct { + br: i8, +} + +struct Foo; + +trait A { + type Assoc; +} + +impl A for Foo { + type Assoc = StructStruct; +} diff --git a/src/tools/rustfmt/tests/target/issue-4908.rs b/src/tools/rustfmt/tests/target/issue-4908.rs new file mode 100644 index 000000000..ac5357abe --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4908.rs @@ -0,0 +1,34 @@ +#![feature(more_qualified_paths)] + +mod foo_bar { + pub enum Example { + Example1 {}, + Example2 {}, + } +} + +fn main() { + foo!(crate::foo_bar::Example, Example1); + + let i1 = foo_bar::Example::Example1 {}; + + assert_eq!(i1.foo_example(), 1); + + let i2 = foo_bar::Example::Example2 {}; + + assert_eq!(i2.foo_example(), 2); +} + +#[macro_export] +macro_rules! foo { + ($struct:path, $variant:ident) => { + impl $struct { + pub fn foo_example(&self) -> i32 { + match self { + <$struct>::$variant { .. } => 1, + _ => 2, + } + } + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-4926/deeply_nested_struct.rs b/src/tools/rustfmt/tests/target/issue-4926/deeply_nested_struct.rs new file mode 100644 index 000000000..072cf2f66 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4926/deeply_nested_struct.rs @@ -0,0 +1,38 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + a: 1_000, + b: 1_000, + .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs b/src/tools/rustfmt/tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs new file mode 100644 index 000000000..c7bc7f729 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs @@ -0,0 +1,44 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, + .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs b/src/tools/rustfmt/tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs new file mode 100644 index 000000000..697931625 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs @@ -0,0 +1,54 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + a: 1_000, + b: 1_000, + c: 1_000, + d: 1_000, + e: 1_000, + f: 1_000, + g: 1_000, + h: 1_000, + i: 1_000, + j: 1_000, + .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-4926/enum_struct_field.rs b/src/tools/rustfmt/tests/target/issue-4926/enum_struct_field.rs new file mode 100644 index 000000000..2471df846 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4926/enum_struct_field.rs @@ -0,0 +1,41 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-enum_discrim_align_threshold: 30 +// rustfmt-imports_layout: HorizontalVertical + +#[derive(Default)] +struct InnerStructA { + bbbbbbbbb: i32, + cccccccc: i32, +} + +enum SomeEnumNamedD { + E(InnerStructA), + F { + ggggggggggggggggggggggggg: bool, + h: bool, + }, +} + +impl SomeEnumNamedD { + fn f_variant() -> Self { + Self::F { + ggggggggggggggggggggggggg: true, + h: true, + } + } +} + +fn main() { + let kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk = SomeEnumNamedD::f_variant(); + let something_we_care_about = matches!( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, + SomeEnumNamedD::F { + ggggggggggggggggggggggggg: true, + .. + } + ); + + if something_we_care_about { + println!("Yup it happened"); + } +} diff --git a/src/tools/rustfmt/tests/target/issue-4926/minimum_example.rs b/src/tools/rustfmt/tests/target/issue-4926/minimum_example.rs new file mode 100644 index 000000000..06e184274 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4926/minimum_example.rs @@ -0,0 +1,10 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, +} + +fn test(x: X) { + let y = matches!(x, X { a: 1, .. }); +} diff --git a/src/tools/rustfmt/tests/target/issue-4926/struct_with_long_field_names.rs b/src/tools/rustfmt/tests/target/issue-4926/struct_with_long_field_names.rs new file mode 100644 index 000000000..ac4674ab5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4926/struct_with_long_field_names.rs @@ -0,0 +1,24 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let y = matches!( + x, + X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, + .. + } + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-4926/struct_with_many_fields.rs b/src/tools/rustfmt/tests/target/issue-4926/struct_with_many_fields.rs new file mode 100644 index 000000000..96dfe14bf --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4926/struct_with_many_fields.rs @@ -0,0 +1,34 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let y = matches!( + x, + X { + a: 1_000, + b: 1_000, + c: 1_000, + d: 1_000, + e: 1_000, + f: 1_000, + g: 1_000, + h: 1_000, + i: 1_000, + j: 1_000, + .. + } + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-4984/minimum_example.rs b/src/tools/rustfmt/tests/target/issue-4984/minimum_example.rs new file mode 100644 index 000000000..f0599c5d6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4984/minimum_example.rs @@ -0,0 +1,2 @@ +#[derive(/*Debug, */ Clone)] +struct Foo; diff --git a/src/tools/rustfmt/tests/target/issue-4984/multi_line_derive.rs b/src/tools/rustfmt/tests/target/issue-4984/multi_line_derive.rs new file mode 100644 index 000000000..5fbd9784a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4984/multi_line_derive.rs @@ -0,0 +1,26 @@ +#[derive( + /* ---------- Some really important comment that just had to go inside the derive --------- */ + Debug, + Clone, + Eq, + PartialEq, +)] +struct Foo { + a: i32, + b: T, +} + +#[derive( + /* + Some really important comment that just had to go inside the derive. + Also had to be put over multiple lines + */ + Debug, + Clone, + Eq, + PartialEq, +)] +struct Bar { + a: i32, + b: T, +} diff --git a/src/tools/rustfmt/tests/target/issue-4984/multiple_comments_within.rs b/src/tools/rustfmt/tests/target/issue-4984/multiple_comments_within.rs new file mode 100644 index 000000000..d2924f0d0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4984/multiple_comments_within.rs @@ -0,0 +1,11 @@ +#[derive( + /* ---------- Some really important comment that just had to go inside the derive --------- */ + Debug, + Clone, + /* Another comment */ Eq, + PartialEq, +)] +struct Foo { + a: i32, + b: T, +} diff --git a/src/tools/rustfmt/tests/target/issue-4984/should_not_change.rs b/src/tools/rustfmt/tests/target/issue-4984/should_not_change.rs new file mode 100644 index 000000000..e46ee5110 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-4984/should_not_change.rs @@ -0,0 +1,5 @@ +#[derive(Clone, Debug, Eq, PartialEq)] +struct Foo; + +#[derive(Clone)] +struct Bar; diff --git a/src/tools/rustfmt/tests/target/issue-5005/minimum_example.rs b/src/tools/rustfmt/tests/target/issue-5005/minimum_example.rs new file mode 100644 index 000000000..11cc645fa --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5005/minimum_example.rs @@ -0,0 +1,9 @@ +#![feature(more_qualified_paths)] +macro_rules! show { + ($ty:ty, $ex:expr) => { + match $ex { + <$ty>::A(_val) => println!("got a"), // formatting should not remove <$ty>:: + <$ty>::B => println!("got b"), + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-5009/1_minimum_example.rs b/src/tools/rustfmt/tests/target/issue-5009/1_minimum_example.rs new file mode 100644 index 000000000..55836f4bf --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5009/1_minimum_example.rs @@ -0,0 +1,4 @@ +fn main() { + // the "in" inside the pattern produced invalid syntax + for variable_in_here /* ... */ in 0..1 {} +} diff --git a/src/tools/rustfmt/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs b/src/tools/rustfmt/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs new file mode 100644 index 000000000..d83590c68 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs @@ -0,0 +1,3 @@ +fn main() { + for in_in_in_in_in_in_in_in /* ... */ in 0..1 {} +} diff --git a/src/tools/rustfmt/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs b/src/tools/rustfmt/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs new file mode 100644 index 000000000..9c8007239 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs @@ -0,0 +1,5 @@ +fn main() { + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 {} + } +} diff --git a/src/tools/rustfmt/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs b/src/tools/rustfmt/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs new file mode 100644 index 000000000..a716d0d30 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs @@ -0,0 +1,13 @@ +fn main() { + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 { + if false { + + } else if false { + + } else { + + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs b/src/tools/rustfmt/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs new file mode 100644 index 000000000..41ea46d4c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs @@ -0,0 +1,15 @@ +fn main() { + let in_ = false; + + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 { + if in_ { + + } else if in_ { + + } else { + + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs b/src/tools/rustfmt/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs new file mode 100644 index 000000000..789e54f7e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs @@ -0,0 +1,32 @@ +fn main() { + for variable_in_a /* ... */ in 0..1 { + for variable_in_b /* ... */ in 0..1 { + for variable_in_c /* ... */ in 0..1 { + for variable_in_d /* ... */ in 0..1 { + for variable_in_e /* ... */ in 0..1 { + for variable_in_f /* ... */ in 0..1 { + for variable_in_g /* ... */ in 0..1 { + for variable_in_h /* ... */ in 0..1 { + for variable_in_i /* ... */ in 0..1 { + for variable_in_j /* ... */ in 0..1 { + for variable_in_k /* ... */ in 0..1 { + for variable_in_l /* ... */ in 0..1 { + for variable_in_m /* ... */ in 0..1 { + for variable_in_n /* ... */ in 0..1 { + for variable_in_o /* ... */ in 0..1 { + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-5011.rs b/src/tools/rustfmt/tests/target/issue-5011.rs new file mode 100644 index 000000000..9ad4a1929 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5011.rs @@ -0,0 +1,8 @@ +pub(crate) struct ASlash( + // hello + i32, +); + +pub(crate) struct AStar(/* hello */ i32); + +pub(crate) struct BStar(/* hello */ i32); diff --git a/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_always.rs b/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_always.rs new file mode 100644 index 000000000..ff9c40fbb --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_always.rs @@ -0,0 +1,8 @@ +// rustfmt-trailing_comma: Always + +pub struct Matrix<T, const R: usize, const C: usize,> +where + [T; R * C]:, +{ + contents: [T; R * C], +} diff --git a/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_never.rs b/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_never.rs new file mode 100644 index 000000000..2fac8eae5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_never.rs @@ -0,0 +1,8 @@ +// rustfmt-trailing_comma: Never + +pub struct Matrix<T, const R: usize, const C: usize> +where + [T; R * C]: +{ + contents: [T; R * C] +} diff --git a/src/tools/rustfmt/tests/target/issue-5023.rs b/src/tools/rustfmt/tests/target/issue-5023.rs new file mode 100644 index 000000000..4e84c7d98 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5023.rs @@ -0,0 +1,23 @@ +// rustfmt-wrap_comments: true + +/// A comment to test special unicode characters on boundaries +/// 是,是,是,是,是,是,是,是,是,是,是,是 it should break right here +/// this goes to the next line +fn main() { + if xxx { + let xxx = xxx + .into_iter() + .filter(|(xxx, xxx)| { + if let Some(x) = Some(1) { + // xxxxxxxxxxxxxxxxxx, xxxxxxxxxxxx, xxxxxxxxxxxxxxxxxxxx xxx xxxxxxx, xxxxx xxx + // xxxxxxxxxx. xxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxx xxx xxxxxxx + // 是sdfadsdfxxxxxxxxx,sdfaxxxxxx_xxxxx_masdfaonxxx, + if false { + return true; + } + } + false + }) + .collect(); + } +} diff --git a/src/tools/rustfmt/tests/target/issue-5030.rs b/src/tools/rustfmt/tests/target/issue-5030.rs new file mode 100644 index 000000000..8ac3888bd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5030.rs @@ -0,0 +1,21 @@ +// rustfmt-imports_granularity: Item +// rustfmt-group_imports: One + +// Confirm that attributes are duplicated to all items in the use statement +#[cfg(feature = "foo")] +use std::collections::HashMap; +#[cfg(feature = "foo")] +use std::collections::HashSet; + +// Separate the imports below from the ones above +const A: usize = 0; + +// Copying attrs works with import grouping as well +#[cfg(feature = "spam")] +use qux::bar; +#[cfg(feature = "spam")] +use qux::baz; +#[cfg(feature = "foo")] +use std::collections::HashMap; +#[cfg(feature = "foo")] +use std::collections::HashSet; diff --git a/src/tools/rustfmt/tests/target/issue-5033/minimum_example.rs b/src/tools/rustfmt/tests/target/issue-5033/minimum_example.rs new file mode 100644 index 000000000..0e7df41de --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5033/minimum_example.rs @@ -0,0 +1,8 @@ +// leading comment + +#![rustfmt::skip] +fn main() { + println!("main"); // commented +} + +// post comment diff --git a/src/tools/rustfmt/tests/target/issue-5033/nested_modules.rs b/src/tools/rustfmt/tests/target/issue-5033/nested_modules.rs new file mode 100644 index 000000000..7a11133b6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5033/nested_modules.rs @@ -0,0 +1,11 @@ +#![rustfmt::skip] + +mod a { + mod b { + + } + + // trailing comment b +} + +// trailing comment a diff --git a/src/tools/rustfmt/tests/target/issue-5042/multi-line_comment_with_trailing_comma.rs b/src/tools/rustfmt/tests/target/issue-5042/multi-line_comment_with_trailing_comma.rs new file mode 100644 index 000000000..1ae1212b4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5042/multi-line_comment_with_trailing_comma.rs @@ -0,0 +1,24 @@ +fn main() { + // 5042 deals with trailing commas, not the indentation issue of these comments + // When a future PR fixes the inentation issues these test can be updated + let _ = std::ops::Add::add( + 10, 20, // ... + // ..., + ); + + let _ = std::ops::Add::add( + 10, 20, /* ... */ + // ..., + ); + + let _ = std::ops::Add::add( + 10, 20, // ..., + // ..., + ); + + let _ = std::ops::Add::add( + 10, 20, // ..., + /* ... + */ + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-5042/multi-line_comment_without_trailing_comma.rs b/src/tools/rustfmt/tests/target/issue-5042/multi-line_comment_without_trailing_comma.rs new file mode 100644 index 000000000..30d174664 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5042/multi-line_comment_without_trailing_comma.rs @@ -0,0 +1,24 @@ +fn main() { + // 5042 deals with trailing commas, not the indentation issue of these comments + // When a future PR fixes the inentation issues these test can be updated + let _ = std::ops::Add::add( + 10, 20, // ... + // ... + ); + + let _ = std::ops::Add::add( + 10, 20, /* ... */ + // ... + ); + + let _ = std::ops::Add::add( + 10, 20, // ... + // ... + ); + + let _ = std::ops::Add::add( + 10, 20, // ... + /* ... + */ + ); +} diff --git a/src/tools/rustfmt/tests/target/issue-5042/single-line_comment_with_trailing_comma.rs b/src/tools/rustfmt/tests/target/issue-5042/single-line_comment_with_trailing_comma.rs new file mode 100644 index 000000000..87b651dd2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5042/single-line_comment_with_trailing_comma.rs @@ -0,0 +1,7 @@ +fn main() { + let _ = std::ops::Add::add( + 10, 20, // ..., + ); + + let _ = std::ops::Add::add(10, 20 /* ... */); +} diff --git a/src/tools/rustfmt/tests/target/issue-5042/single-line_comment_without_trailing_comma.rs b/src/tools/rustfmt/tests/target/issue-5042/single-line_comment_without_trailing_comma.rs new file mode 100644 index 000000000..116df86a4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5042/single-line_comment_without_trailing_comma.rs @@ -0,0 +1,7 @@ +fn main() { + let _ = std::ops::Add::add( + 10, 20, // ... + ); + + let _ = std::ops::Add::add(10, 20 /* ... */); +} diff --git a/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs b/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs new file mode 100644 index 000000000..c7122c676 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Always +// rustfmt-struct_lit_single_line: false +// rustfmt-struct_lit_width: 0 + +fn main() { + let Foo { + a, + .. + } = b; +} diff --git a/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs b/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs new file mode 100644 index 000000000..68e89c417 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Never +// rustfmt-struct_lit_single_line: false +// rustfmt-struct_lit_width: 0 + +fn main() { + let Foo { + a, + .. + } = b; +} diff --git a/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs b/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs new file mode 100644 index 000000000..3368f0703 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Always +// rustfmt-struct_lit_single_line: false + +// There is an issue with how this is formatted. +// formatting should look like ./multi_line_struct_trailing_comma_always_struct_lit_width_0.rs +fn main() { + let Foo { + a, .. + } = b; +} diff --git a/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs b/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs new file mode 100644 index 000000000..cf63c4c98 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Never +// rustfmt-struct_lit_single_line: false + +// There is an issue with how this is formatted. +// formatting should look like ./multi_line_struct_trailing_comma_never_struct_lit_width_0.rs +fn main() { + let Foo { + a, .. + } = b; +} diff --git a/src/tools/rustfmt/tests/target/issue-5066/with_trailing_comma_always.rs b/src/tools/rustfmt/tests/target/issue-5066/with_trailing_comma_always.rs new file mode 100644 index 000000000..e20bcec93 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5066/with_trailing_comma_always.rs @@ -0,0 +1,5 @@ +// rustfmt-trailing_comma: Always + +fn main() { + let Foo { a, .. } = b; +} diff --git a/src/tools/rustfmt/tests/target/issue-5066/with_trailing_comma_never.rs b/src/tools/rustfmt/tests/target/issue-5066/with_trailing_comma_never.rs new file mode 100644 index 000000000..8b95bb137 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5066/with_trailing_comma_never.rs @@ -0,0 +1,5 @@ +// rustfmt-trailing_comma: Never + +fn main() { + let Foo { a, .. } = b; +} diff --git a/src/tools/rustfmt/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs b/src/tools/rustfmt/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs new file mode 100644 index 000000000..f4801de01 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs @@ -0,0 +1,33 @@ +// rustfmt-wrap_comments: false + +fn main() { + { + { + { + { + { + { + { + { + { + { + { + // - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + // * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + /* - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + + /* * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs b/src/tools/rustfmt/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs new file mode 100644 index 000000000..b289c9f85 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs @@ -0,0 +1,49 @@ +// rustfmt-wrap_comments: true + +fn main() { + { + { + { + { + { + { + { + { + { + { + { + // - aaaa aaaaaaaaa aaaaaaaaa + // aaaaaaaaa aaaaaaaaa + // bbbbbbbbbb bbbbbbbbb + // bbbbbbbbb ccc cccccccccc + // ccccccc cccccccc + + // * aaaa aaaaaaaaa aaaaaaaaa + // aaaaaaaaa aaaaaaaaa + // bbbbbbbbbb bbbbbbbbb + // bbbbbbbbb ccc cccccccccc + // ccccccc cccccccc + + /* - aaaa aaaaaaaaa aaaaaaaaa + * aaaaaaaaa aaaaaaaaa + * bbbbbbbbbb bbbbbbbbb + * bbbbbbbbb ccc cccccccccc + * ccccccc cccccccc */ + + /* * aaaa aaaaaaaaa aaaaaaaaa + * aaaaaaaaa aaaaaaaaa + * bbbbbbbbbb bbbbbbbbb + * bbbbbbbbb ccc cccccccccc + * ccccccc cccccccc */ + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/src/tools/rustfmt/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs b/src/tools/rustfmt/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs new file mode 100644 index 000000000..60beed1b0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: false + +// - some itemized block 1 +// - some itemized block 2 + +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 + */ + +/* + * * some itemized block 7 + * * some itemized block 8 + */ diff --git a/src/tools/rustfmt/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs b/src/tools/rustfmt/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000..84fba4b7c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: true + +// - some itemized block 1 +// - some itemized block 2 + +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 + */ + +/* + * * some itemized block 7 + * * some itemized block 8 + */ diff --git a/src/tools/rustfmt/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs b/src/tools/rustfmt/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs new file mode 100644 index 000000000..d1bf44f6c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs @@ -0,0 +1,37 @@ +// rustfmt-wrap_comments: false + +// Some text +// - some itemized block 1 +// - some itemized block 2 +// Some more text +// - some itemized block 3 +// - some itemized block 4 +// Even more text + +// Some text +// * some itemized block 5 +// * some itemized block 6 +// Some more text +// * some itemized block 7 +// * some itemized block 8 +// Even more text + +/* + * Some text + * - some itemized block 9 + * - some itemized block 10 + * Some more text + * - some itemized block 11 + * - some itemized block 12 + * Even more text + */ + +/* + * Some text + * * some itemized block 13 + * * some itemized block 14 + * Some more text + * * some itemized block 15 + * * some itemized block 16 + * Even more text + */ diff --git a/src/tools/rustfmt/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs b/src/tools/rustfmt/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000..f767491f9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs @@ -0,0 +1,37 @@ +// rustfmt-wrap_comments: true + +// Some text +// - some itemized block 1 +// - some itemized block 2 +// Some more text +// - some itemized block 3 +// - some itemized block 4 +// Even more text + +// Some text +// * some itemized block 5 +// * some itemized block 6 +// Some more text +// * some itemized block 7 +// * some itemized block 8 +// Even more text + +/* + * Some text + * - some itemized block 9 + * - some itemized block 10 + * Some more text + * - some itemized block 11 + * - some itemized block 12 + * Even more text + */ + +/* + * Some text + * * some itemized block 13 + * * some itemized block 14 + * Some more text + * * some itemized block 15 + * * some itemized block 16 + * Even more text + */ diff --git a/src/tools/rustfmt/tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs b/src/tools/rustfmt/tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs new file mode 100644 index 000000000..2cd85c787 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: false + +// - some itemized block 1 + +// * some itemized block 2 + +/* - some itemized block 3 */ + +/* * some itemized block 4 */ diff --git a/src/tools/rustfmt/tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs b/src/tools/rustfmt/tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000..e9f343d75 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: true + +// - some itemized block 1 + +// * some itemized block 2 + +/* - some itemized block 3 */ + +/* * some itemized block 4 */ diff --git a/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs b/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs new file mode 100644 index 000000000..97bb7733d --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs @@ -0,0 +1,19 @@ +// rustfmt-wrap_comments: false + +// +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs b/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000..c8af8383e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs @@ -0,0 +1,27 @@ +// rustfmt-wrap_comments: true + +// +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +// +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ + +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ diff --git a/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs b/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs new file mode 100644 index 000000000..75cc42c0e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: false + +// +// - some itemized block 1 +// - some itemized block 2 + +// +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 */ + +/* + * * some itemized block 7 + * * some itemized block 8 */ diff --git a/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs b/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs new file mode 100644 index 000000000..ef2c8f90c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: true + +// +// - some itemized block 1 +// - some itemized block 2 + +// +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 */ + +/* + * * some itemized block 7 + * * some itemized block 8 */ diff --git a/src/tools/rustfmt/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs b/src/tools/rustfmt/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs new file mode 100644 index 000000000..c826cc5d4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: false + +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/src/tools/rustfmt/tests/target/issue-5088/very_long_comment_wrap_comments_true.rs b/src/tools/rustfmt/tests/target/issue-5088/very_long_comment_wrap_comments_true.rs new file mode 100644 index 000000000..7f764dbd8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5088/very_long_comment_wrap_comments_true.rs @@ -0,0 +1,21 @@ +// rustfmt-wrap_comments: true + +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ + +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ diff --git a/src/tools/rustfmt/tests/target/issue-5095.rs b/src/tools/rustfmt/tests/target/issue-5095.rs new file mode 100644 index 000000000..6981a6580 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5095.rs @@ -0,0 +1,27 @@ +// rustfmt-wrap_comments: true + +pub mod a_long_name { + pub mod b_long_name { + pub mod c_long_name { + pub mod d_long_name { + pub mod e_long_name { + pub struct Bananas; + impl Bananas { + pub fn fantastic() {} + } + + pub mod f_long_name { + pub struct Apples; + } + } + } + } + } +} + +/// Check out [my other struct] ([`Bananas`]) and [the method it has]. +/// +/// [my other struct]: a_long_name::b_long_name::c_long_name::d_long_name::e_long_name::f_long_name::Apples +/// [`Bananas`]: a_long_name::b_long_name::c_long_name::d_long_name::e_long_name::Bananas::fantastic() +/// [the method it has]: a_long_name::b_long_name::c_long_name::d_long_name::e_long_name::Bananas::fantastic() +pub struct A; diff --git a/src/tools/rustfmt/tests/target/issue-510.rs b/src/tools/rustfmt/tests/target/issue-510.rs new file mode 100644 index 000000000..a166b6849 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-510.rs @@ -0,0 +1,41 @@ +impl ISizeAndMarginsComputer for AbsoluteNonReplaced { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { + let (inline_start, inline_size, margin_inline_start, margin_inline_end) = match ( + inline_startssssssxxxxxxsssssxxxxxxxxxssssssxxx, + inline_startssssssxxxxxxsssssxxxxxxxxxssssssxxx, + ) { + (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => { + let margin_start = inline_start_margin.specified_or_zero(); + let margin_end = inline_end_margin.specified_or_zero(); + // Now it is the same situation as inline-start Specified and inline-end + // and inline-size Auto. + // + // Set inline-end to zero to calculate inline-size. + let inline_size = block.get_shrink_to_fit_inline_size( + available_inline_size - (margin_start + margin_end), + ); + (Au(0), inline_size, margin_start, margin_end) + } + }; + + let (inline_start, inline_size, margin_inline_start, margin_inline_end) = + match (inline_start, inline_end, computed_inline_size) { + (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => { + let margin_start = inline_start_margin.specified_or_zero(); + let margin_end = inline_end_margin.specified_or_zero(); + // Now it is the same situation as inline-start Specified and inline-end + // and inline-size Auto. + // + // Set inline-end to zero to calculate inline-size. + let inline_size = block.get_shrink_to_fit_inline_size( + available_inline_size - (margin_start + margin_end), + ); + (Au(0), inline_size, margin_start, margin_end) + } + }; + } +} diff --git a/src/tools/rustfmt/tests/target/issue-5125/attributes_in_formal_fuction_parameter.rs b/src/tools/rustfmt/tests/target/issue-5125/attributes_in_formal_fuction_parameter.rs new file mode 100644 index 000000000..5d1679328 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5125/attributes_in_formal_fuction_parameter.rs @@ -0,0 +1,6 @@ +fn foo( + #[unused] a: <u16 as intercom::type_system::ExternType< + intercom::type_system::AutomationTypeSystem, + >>::ForeignType, +) { +} diff --git a/src/tools/rustfmt/tests/target/issue-5125/long_parameter_in_different_positions.rs b/src/tools/rustfmt/tests/target/issue-5125/long_parameter_in_different_positions.rs new file mode 100644 index 000000000..cab20381c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5125/long_parameter_in_different_positions.rs @@ -0,0 +1,24 @@ +fn middle( + a: usize, + b: <u16 as intercom::type_system::ExternType< + intercom::type_system::AutomationTypeSystem, + >>::ForeignType, + c: bool, +) { +} + +fn last( + a: usize, + b: <u16 as intercom::type_system::ExternType< + intercom::type_system::AutomationTypeSystem, + >>::ForeignType, +) { +} + +fn first( + a: <u16 as intercom::type_system::ExternType< + intercom::type_system::AutomationTypeSystem, + >>::ForeignType, + b: usize, +) { +} diff --git a/src/tools/rustfmt/tests/target/issue-5125/minimum_example.rs b/src/tools/rustfmt/tests/target/issue-5125/minimum_example.rs new file mode 100644 index 000000000..8003e6696 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5125/minimum_example.rs @@ -0,0 +1,6 @@ +fn foo( + a: <u16 as intercom::type_system::ExternType< + intercom::type_system::AutomationTypeSystem, + >>::ForeignType, +) { +} diff --git a/src/tools/rustfmt/tests/target/issue-5125/with_leading_and_inline_comments.rs b/src/tools/rustfmt/tests/target/issue-5125/with_leading_and_inline_comments.rs new file mode 100644 index 000000000..2340b2f34 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5125/with_leading_and_inline_comments.rs @@ -0,0 +1,7 @@ +fn foo( + // Pre Comment + a: <u16 as intercom::type_system::ExternType< + intercom::type_system::AutomationTypeSystem, + >>::ForeignType, // Inline comment +) { +} diff --git a/src/tools/rustfmt/tests/target/issue-5151/minimum_example.rs b/src/tools/rustfmt/tests/target/issue-5151/minimum_example.rs new file mode 100644 index 000000000..2ed3d936e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5151/minimum_example.rs @@ -0,0 +1,16 @@ +#![feature(more_qualified_paths)] + +struct Struct {} + +trait Trait { + type Type; +} + +impl Trait for Struct { + type Type = Self; +} + +fn main() { + // keep the qualified path details + let _ = <Struct as Trait>::Type {}; +} diff --git a/src/tools/rustfmt/tests/target/issue-5157/indented_itemized_markdown_blockquote.rs b/src/tools/rustfmt/tests/target/issue-5157/indented_itemized_markdown_blockquote.rs new file mode 100644 index 000000000..e47677f20 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5157/indented_itemized_markdown_blockquote.rs @@ -0,0 +1,6 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a +/// > sample_state relative to each DataReader. The sample_state can +/// > either be READ or NOT_READ. +fn block_quote() {} diff --git a/src/tools/rustfmt/tests/target/issue-5157/nested_itemized_markdown_blockquote.rs b/src/tools/rustfmt/tests/target/issue-5157/nested_itemized_markdown_blockquote.rs new file mode 100644 index 000000000..079510442 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5157/nested_itemized_markdown_blockquote.rs @@ -0,0 +1,18 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a +/// > sample_state relative to each DataReader. The sample_state can either be +/// > READ or NOT_READ. +/// +/// > > For each sample received, the middleware internally maintains a +/// > > sample_state relative to each DataReader. The sample_state can either be +/// > > READ or NOT_READ. +/// +/// > > > For each sample received, the middleware internally maintains a +/// > > > sample_state relative to each DataReader. The sample_state can either +/// > > > be READ or NOT_READ. +/// +/// > > > > > > > > For each sample received, the middleware internally +/// > > > > > > > > maintains a sample_state relative to each DataReader. The +/// > > > > > > > > sample_state can either be READ or NOT_READ. +fn block_quote() {} diff --git a/src/tools/rustfmt/tests/target/issue-5157/support_itemized_markdown_blockquote.rs b/src/tools/rustfmt/tests/target/issue-5157/support_itemized_markdown_blockquote.rs new file mode 100644 index 000000000..029ee37d2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5157/support_itemized_markdown_blockquote.rs @@ -0,0 +1,6 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a +/// > sample_state relative to each DataReader. The sample_state can either be +/// > READ or NOT_READ. +fn block_quote() {} diff --git a/src/tools/rustfmt/tests/target/issue-5238/markdown_header_wrap_comments_false.rs b/src/tools/rustfmt/tests/target/issue-5238/markdown_header_wrap_comments_false.rs new file mode 100644 index 000000000..229c6e575 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5238/markdown_header_wrap_comments_false.rs @@ -0,0 +1,11 @@ +// rustfmt-wrap_comments: false + +/// no markdown header so rustfmt should wrap this comment when `format_code_in_doc_comments = true` and `wrap_comments = true` +fn not_documented_with_markdown_header() { + // This is just a normal inline comment so rustfmt should wrap this comment when `wrap_comments = true` +} + +/// # We're using a markdown header here so rustfmt should refuse to wrap this comment in all circumstances +fn documented_with_markdown_header() { + // # We're using a markdown header in an inline comment. rustfmt should be able to wrap this comment when `wrap_comments = true` +} diff --git a/src/tools/rustfmt/tests/target/issue-5238/markdown_header_wrap_comments_true.rs b/src/tools/rustfmt/tests/target/issue-5238/markdown_header_wrap_comments_true.rs new file mode 100644 index 000000000..87dae58ec --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5238/markdown_header_wrap_comments_true.rs @@ -0,0 +1,14 @@ +// rustfmt-wrap_comments: true + +/// no markdown header so rustfmt should wrap this comment when +/// `format_code_in_doc_comments = true` and `wrap_comments = true` +fn not_documented_with_markdown_header() { + // This is just a normal inline comment so rustfmt should wrap this comment + // when `wrap_comments = true` +} + +/// # We're using a markdown header here so rustfmt should refuse to wrap this comment in all circumstances +fn documented_with_markdown_header() { + // # We're using a markdown header in an inline comment. rustfmt should be + // able to wrap this comment when `wrap_comments = true` +} diff --git a/src/tools/rustfmt/tests/target/issue-5260.rs b/src/tools/rustfmt/tests/target/issue-5260.rs new file mode 100644 index 000000000..171f6fa51 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5260.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: true + +/// [MyType](VeryLongPathToMyType::NoLineBreak::Here::Okay::ThatWouldBeNice::Thanks) +fn documented_with_longtype() { + // # We're using a long type link, rustfmt should not break line + // on the type when `wrap_comments = true` +} + +/// VeryLongPathToMyType::JustMyType::But::VeryVery::Long::NoLineBreak::Here::Okay::ThatWouldBeNice::Thanks +fn documented_with_verylongtype() { + // # We're using a long type link, rustfmt should not break line + // on the type when `wrap_comments = true` +} diff --git a/src/tools/rustfmt/tests/target/issue-5270/merge_derives_false.rs b/src/tools/rustfmt/tests/target/issue-5270/merge_derives_false.rs new file mode 100644 index 000000000..3b6f7e669 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5270/merge_derives_false.rs @@ -0,0 +1,62 @@ +// rustfmt-merge_derives:false + +#[rustfmt::skip::attributes(derive)] +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct DoNotMergeDerives { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[rustfmt::skip::attributes(derive)] +#[derive(Clone)] +struct DoNotMergeDerivesSkipInMiddle { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +#[rustfmt::skip::attributes(derive)] +struct DoNotMergeDerivesSkipAtEnd { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct MergeDerives { + field: String, +} + +mod inner_attribute_derive_skip { + #![rustfmt::skip::attributes(derive)] + + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +#[rustfmt::skip::attributes(derive)] +mod outer_attribute_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +mod no_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct MergeDerives { + field: String, + } +} diff --git a/src/tools/rustfmt/tests/target/issue-5270/merge_derives_true.rs b/src/tools/rustfmt/tests/target/issue-5270/merge_derives_true.rs new file mode 100644 index 000000000..5f488b454 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-5270/merge_derives_true.rs @@ -0,0 +1,60 @@ +// rustfmt-merge_derives:true + +#[rustfmt::skip::attributes(derive)] +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct DoNotMergeDerives { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[rustfmt::skip::attributes(derive)] +#[derive(Clone)] +struct DoNotMergeDerivesSkipInMiddle { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +#[rustfmt::skip::attributes(derive)] +struct DoNotMergeDerivesSkipAtEnd { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField, Clone)] +struct MergeDerives { + field: String, +} + +mod inner_attribute_derive_skip { + #![rustfmt::skip::attributes(derive)] + + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +#[rustfmt::skip::attributes(derive)] +mod outer_attribute_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +mod no_derive_skip { + #[allow(dead_code)] + #[derive(StructField, Clone)] + struct MergeDerives { + field: String, + } +} diff --git a/src/tools/rustfmt/tests/target/issue-539.rs b/src/tools/rustfmt/tests/target/issue-539.rs new file mode 100644 index 000000000..adeb33555 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-539.rs @@ -0,0 +1,3 @@ +// rustfmt-normalize_comments: true +// FIXME (#3300): Should allow items to be anonymous. Right now +// we just use dummy names for anon items. diff --git a/src/tools/rustfmt/tests/target/issue-64.rs b/src/tools/rustfmt/tests/target/issue-64.rs new file mode 100644 index 000000000..c06606302 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-64.rs @@ -0,0 +1,7 @@ +// Regression test for issue 64 + +pub fn header_name<T: Header>() -> &'static str { + let name = <T as Header>::header_name(); + let func = <T as Header>::header_name; + name +} diff --git a/src/tools/rustfmt/tests/target/issue-683.rs b/src/tools/rustfmt/tests/target/issue-683.rs new file mode 100644 index 000000000..adeb33555 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-683.rs @@ -0,0 +1,3 @@ +// rustfmt-normalize_comments: true +// FIXME (#3300): Should allow items to be anonymous. Right now +// we just use dummy names for anon items. diff --git a/src/tools/rustfmt/tests/target/issue-691.rs b/src/tools/rustfmt/tests/target/issue-691.rs new file mode 100644 index 000000000..7473d070e --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-691.rs @@ -0,0 +1,9 @@ +// rustfmt-normalize_comments: true + +//! `std` or `core` and simply link to this library. In case the target +//! platform has no hardware +//! support for some operation, software implementations provided by this +//! library will be used automagically. +// TODO: provide instructions to override default libm link and how to link to +// this library. +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/issue-770.rs b/src/tools/rustfmt/tests/target/issue-770.rs new file mode 100644 index 000000000..5fbedd7b7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-770.rs @@ -0,0 +1,10 @@ +fn main() { + if false { + if false { + } else { + // A let binding here seems necessary to trigger it. + let _ = (); + } + } else if let false = false { + } +} diff --git a/src/tools/rustfmt/tests/target/issue-811.rs b/src/tools/rustfmt/tests/target/issue-811.rs new file mode 100644 index 000000000..b7a89b5d0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-811.rs @@ -0,0 +1,19 @@ +trait FooTrait<T>: Sized { + type Bar: BarTrait<T>; +} + +trait BarTrait<T>: Sized { + type Baz; + fn foo(); +} + +type Foo<T: FooTrait> = <<T as FooTrait<U>>::Bar as BarTrait<U>>::Baz; +type Bar<T: BarTrait> = <T as BarTrait<U>>::Baz; + +fn some_func<T: FooTrait<U>, U>() { + <<T as FooTrait<U>>::Bar as BarTrait<U>>::foo(); +} + +fn some_func<T: BarTrait<U>>() { + <T as BarTrait<U>>::foo(); +} diff --git a/src/tools/rustfmt/tests/target/issue-831.rs b/src/tools/rustfmt/tests/target/issue-831.rs new file mode 100644 index 000000000..1d6327c21 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-831.rs @@ -0,0 +1,9 @@ +fn main() { + let y = a.iter().any(|x| { + println!("a"); + }) || b.iter().any(|x| { + println!("b"); + }) || c.iter().any(|x| { + println!("c"); + }); +} diff --git a/src/tools/rustfmt/tests/target/issue-850.rs b/src/tools/rustfmt/tests/target/issue-850.rs new file mode 100644 index 000000000..c939716a6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-850.rs @@ -0,0 +1 @@ +const unsafe fn x() {} diff --git a/src/tools/rustfmt/tests/target/issue-855.rs b/src/tools/rustfmt/tests/target/issue-855.rs new file mode 100644 index 000000000..0430cc629 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-855.rs @@ -0,0 +1,27 @@ +fn main() { + 'running: loop { + for event in event_pump.poll_iter() { + match event { + Event::Quit { .. } + | Event::KeyDown { + keycode: Some(Keycode::Escape), + .. + } => break 'running, + } + } + } +} + +fn main2() { + 'running: loop { + for event in event_pump.poll_iter() { + match event { + Event::Quit { .. } + | Event::KeyDownXXXXXXXXXXXXX { + keycode: Some(Keycode::Escape), + .. + } => break 'running, + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-913.rs b/src/tools/rustfmt/tests/target/issue-913.rs new file mode 100644 index 000000000..a2b5800a7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-913.rs @@ -0,0 +1,22 @@ +mod client { + impl Client { + fn test(self) -> Result<()> { + let next_state = match self.state { + State::V5(v5::State::Command(v5::coand::State::WriteVersion(ref mut response))) => { + let x = reformat.meeee(); + } + }; + + let next_state = match self.state { + State::V5(v5::State::Command(v5::comand::State::WriteVersion( + ref mut response, + ))) => { + // The pattern cannot be formatted in a way that the match stays + // within the column limit. The rewrite should therefore be + // skipped. + let x = dont.reformat.meeee(); + } + }; + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue-945.rs b/src/tools/rustfmt/tests/target/issue-945.rs new file mode 100644 index 000000000..d46c69a4f --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-945.rs @@ -0,0 +1,17 @@ +impl Bar { + default const unsafe fn foo() { + "hi" + } +} + +impl Baz { + default unsafe extern "C" fn foo() { + "hi" + } +} + +impl Foo for Bar { + default fn foo() { + "hi" + } +} diff --git a/src/tools/rustfmt/tests/target/issue-977.rs b/src/tools/rustfmt/tests/target/issue-977.rs new file mode 100644 index 000000000..3784a3874 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-977.rs @@ -0,0 +1,16 @@ +// rustfmt-normalize_comments: true + +trait NameC { + // comment +} +struct FooC { + // comment +} +enum MooC { + // comment +} +mod BarC { // comment +} +extern "C" { + // comment +} diff --git a/src/tools/rustfmt/tests/target/issue_3839.rs b/src/tools/rustfmt/tests/target/issue_3839.rs new file mode 100644 index 000000000..b7bdf4c75 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_3839.rs @@ -0,0 +1,8 @@ +struct Foo { + a: i32, + /* + asd + */ + // foo + b: i32, +} diff --git a/src/tools/rustfmt/tests/target/issue_3844.rs b/src/tools/rustfmt/tests/target/issue_3844.rs new file mode 100644 index 000000000..81d208346 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_3844.rs @@ -0,0 +1,3 @@ +fn main() { + || {}; +} diff --git a/src/tools/rustfmt/tests/target/issue_3853.rs b/src/tools/rustfmt/tests/target/issue_3853.rs new file mode 100644 index 000000000..eae59eff9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_3853.rs @@ -0,0 +1,47 @@ +fn by_ref_with_block_before_ident() { + if let Some(ref /*def*/ state) = foo { + println!("asdfasdfasdf"); + } +} + +fn mut_block_before_ident() { + if let Some(mut /*def*/ state) = foo { + println!("123"); + } +} + +fn ref_and_mut_blocks_before_ident() { + if let Some(ref /*abc*/ mut /*def*/ state) = foo { + println!("deefefefefefwea"); + } +} + +fn sub_pattern() { + let foo @ /*foo*/ bar(f) = 42; +} + +fn no_prefix_block_before_ident() { + if let Some(/*def*/ state) = foo { + println!("129387123123"); + } +} + +fn issue_3853() { + if let Some(ref /*mut*/ state) = foo {} +} + +fn double_slash_comment_between_lhs_and_rhs() { + if let Some(e) = + // self.foo.bar(e, tx) + packet.transaction.state.committed + { + // body + println!("a2304712836123"); + } +} + +fn block_comment_between_lhs_and_rhs() { + if let Some(ref /*def*/ mut /*abc*/ state) = /*abc*/ foo { + println!("asdfasdfasdf"); + } +} diff --git a/src/tools/rustfmt/tests/target/issue_3854.rs b/src/tools/rustfmt/tests/target/issue_3854.rs new file mode 100644 index 000000000..3051335c2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_3854.rs @@ -0,0 +1,3 @@ +fn main() { + println!("{:?}", -1. ..1.); +} diff --git a/src/tools/rustfmt/tests/target/issue_3868.rs b/src/tools/rustfmt/tests/target/issue_3868.rs new file mode 100644 index 000000000..067241359 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_3868.rs @@ -0,0 +1,9 @@ +fn foo() {} + +fn bar() { + for _ in 0..1 {} +} + +fn baz() { + (); +} diff --git a/src/tools/rustfmt/tests/target/issue_3934.rs b/src/tools/rustfmt/tests/target/issue_3934.rs new file mode 100644 index 000000000..68f9fd0ae --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_3934.rs @@ -0,0 +1,8 @@ +mod repro { + pub fn push() -> Result<(), ()> { + self.api.map_api_result(|api| { + #[allow(deprecated)] + match api.apply_extrinsic_before_version_4_with_context()? {} + }) + } +} diff --git a/src/tools/rustfmt/tests/target/issue_3937.rs b/src/tools/rustfmt/tests/target/issue_3937.rs new file mode 100644 index 000000000..806731085 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_3937.rs @@ -0,0 +1,13 @@ +// rustfmt-format_code_in_doc_comments:true + +struct Foo { + // a: i32, + // + // b: i32, +} + +struct Foo { + a: i32, + // + // b: i32, +} diff --git a/src/tools/rustfmt/tests/target/issue_4031.rs b/src/tools/rustfmt/tests/target/issue_4031.rs new file mode 100644 index 000000000..065d5395c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4031.rs @@ -0,0 +1,21 @@ +fn foo() { + with_woff2_glyf_table("tests/fonts/woff2/SFNT-TTF-Composite.woff2", |glyf| { + let actual = glyf + .records + .iter() + .map(|glyph| match glyph { + GlyfRecord::Parsed( + found @ Glyph { + data: GlyphData::Composite { .. }, + .. + }, + ) => Some(found), + _ => None, + }) + .find(|candidate| candidate.is_some()) + .unwrap() + .unwrap(); + + assert_eq!(*actual, expected) + }); +} diff --git a/src/tools/rustfmt/tests/target/issue_4032.rs b/src/tools/rustfmt/tests/target/issue_4032.rs new file mode 100644 index 000000000..2e7e624ca --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4032.rs @@ -0,0 +1,18 @@ +fn a1( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] + a: u8, +) { +} +fn b1( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] + bb: u8, +) { +} +fn a2( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] a: u8, +) { +} +fn b2( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] bb: u8, +) { +} diff --git a/src/tools/rustfmt/tests/target/issue_4049.rs b/src/tools/rustfmt/tests/target/issue_4049.rs new file mode 100644 index 000000000..fe025a0f6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4049.rs @@ -0,0 +1,26 @@ +// rustfmt-max_width: 110 +// rustfmt-use_small_heuristics: Max +// rustfmt-hard_tabs: true +// rustfmt-use_field_init_shorthand: true +// rustfmt-overflow_delimited_expr: true + +// https://github.com/rust-lang/rustfmt/issues/4049 +fn foo() { + { + { + if let Some(MpcEv::PlayDrum(pitch, vel)) = + // self.mpc.handle_input(e, /*btn_ctrl_down,*/ tx_launch_to_daw, state_view) + self.mpc.handle_input(e, &mut MyBorrowedState { tx_launch_to_daw, state_view }) + { + println!("bar"); + } + + if let Some(e) = + // self.note_input.handle_input(e, /*btn_ctrl_down,*/ tx_launch_to_daw, state_view) + self.note_input.handle_input(e, &mut MyBorrowedState { tx_launch_to_daw, state_view }) + { + println!("baz"); + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/issue_4057.rs b/src/tools/rustfmt/tests/target/issue_4057.rs new file mode 100644 index 000000000..467e67bca --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4057.rs @@ -0,0 +1,15 @@ +// rustfmt-format_code_in_doc_comments: true + +/// ``` +/// # #[rustversion::since(1.36)] +/// # fn dox() { +/// # use std::pin::Pin; +/// # type Projection<'a> = &'a (); +/// # type ProjectionRef<'a> = &'a (); +/// # trait Dox { +/// fn project_ex(self: Pin<&mut Self>) -> Projection<'_>; +/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>; +/// # } +/// # } +/// ``` +struct Foo; diff --git a/src/tools/rustfmt/tests/target/issue_4086.rs b/src/tools/rustfmt/tests/target/issue_4086.rs new file mode 100644 index 000000000..959d3b3d4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4086.rs @@ -0,0 +1,2 @@ +#[cfg(any())] +extern "C++" {} diff --git a/src/tools/rustfmt/tests/target/issue_4110.rs b/src/tools/rustfmt/tests/target/issue_4110.rs new file mode 100644 index 000000000..4a58c3946 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4110.rs @@ -0,0 +1,55 @@ +fn bindings() { + let err = match (place_desc, explanation) { + ( + Some(ref name), + BorrowExplanation::MustBeValidFor { + category: + category @ (ConstraintCategory::Return + | ConstraintCategory::CallArgument + | ConstraintCategory::OpaqueType), + from_closure: false, + ref region_name, + span, + .. + }, + ) if borrow_spans.for_generator() | borrow_spans.for_closure() => self + .report_escaping_closure_capture( + borrow_spans, + borrow_span, + region_name, + category, + span, + &format!("`{}`", name), + ), + ( + ref name, + BorrowExplanation::MustBeValidFor { + category: ConstraintCategory::Assignment, + from_closure: false, + region_name: + RegionName { + source: RegionNameSource::AnonRegionFromUpvar(upvar_span, ref upvar_name), + .. + }, + span, + .. + }, + ) => self.report_escaping_data(borrow_span, name, upvar_span, upvar_name, span), + (Some(name), explanation) => self.report_local_value_does_not_live_long_enough( + location, + &name, + &borrow, + drop_span, + borrow_spans, + explanation, + ), + (None, explanation) => self.report_temporary_value_does_not_live_long_enough( + location, + &borrow, + drop_span, + borrow_spans, + proper_span, + explanation, + ), + }; +} diff --git a/src/tools/rustfmt/tests/target/issue_4257.rs b/src/tools/rustfmt/tests/target/issue_4257.rs new file mode 100644 index 000000000..1ebaaf2b6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4257.rs @@ -0,0 +1,18 @@ +#![feature(generic_associated_types)] +#![allow(incomplete_features)] + +trait Trait<T> { + type Type<'a> + where + T: 'a; + fn foo(x: &T) -> Self::Type<'_>; +} +impl<T> Trait<T> for () { + type Type<'a> + where + T: 'a, + = &'a T; + fn foo(x: &T) -> Self::Type<'_> { + x + } +} diff --git a/src/tools/rustfmt/tests/target/issue_4322.rs b/src/tools/rustfmt/tests/target/issue_4322.rs new file mode 100644 index 000000000..0ec054711 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4322.rs @@ -0,0 +1,5 @@ +trait Bar { + type X<'a> + where + Self: 'a; +} diff --git a/src/tools/rustfmt/tests/target/issue_4374.rs b/src/tools/rustfmt/tests/target/issue_4374.rs new file mode 100644 index 000000000..f5bf657bb --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4374.rs @@ -0,0 +1,13 @@ +fn a<F>(_f: F) -> () +where + F: FnOnce() -> (), +{ +} +fn main() { + a(|| { + #[allow(irrefutable_let_patterns)] + while let _ = 0 { + break; + } + }); +} diff --git a/src/tools/rustfmt/tests/target/issue_4467.rs b/src/tools/rustfmt/tests/target/issue_4467.rs new file mode 100644 index 000000000..f5ee96c4c --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4467.rs @@ -0,0 +1,6 @@ +pub fn main() { + #[cfg(feature = "std")] + { + // Comment + } +} diff --git a/src/tools/rustfmt/tests/target/issue_4475.rs b/src/tools/rustfmt/tests/target/issue_4475.rs new file mode 100644 index 000000000..ea6726c5a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4475.rs @@ -0,0 +1,29 @@ +fn main() { + #[cfg(debug_assertions)] + { + println!("DEBUG"); + } +} + +fn main() { + #[cfg(feature = "foo")] + { + /* + let foo = 0 + */ + } +} + +fn main() { + #[cfg(feature = "foo")] + { /* let foo = 0; */ } +} + +fn main() { + #[foo] + #[bar] + #[baz] + { + // let foo = 0; + } +} diff --git a/src/tools/rustfmt/tests/target/issue_4522.rs b/src/tools/rustfmt/tests/target/issue_4522.rs new file mode 100644 index 000000000..5ca70e1c0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4522.rs @@ -0,0 +1,6 @@ +fn main() { + #[cfg(feature = "foo")] + { + // let foo = 0; + } +} diff --git a/src/tools/rustfmt/tests/target/issue_4528.rs b/src/tools/rustfmt/tests/target/issue_4528.rs new file mode 100644 index 000000000..7828804b0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4528.rs @@ -0,0 +1,8 @@ +#![allow(clippy::no_effect)] + +extern "C" { + // N.B., mutability can be easily incorrect in FFI calls -- as + // in C, the default is mutable pointers. + fn ffi(c: *mut u8); + fn int_ffi(c: *mut i32); +} diff --git a/src/tools/rustfmt/tests/target/issue_4545.rs b/src/tools/rustfmt/tests/target/issue_4545.rs new file mode 100644 index 000000000..f87c81036 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4545.rs @@ -0,0 +1,5 @@ +#[derive(Debug, Foo<T>)] +enum Bar {} + +#[derive(Debug, , Default)] +struct Struct(i32); diff --git a/src/tools/rustfmt/tests/target/issue_4573.rs b/src/tools/rustfmt/tests/target/issue_4573.rs new file mode 100644 index 000000000..82cfe4f53 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4573.rs @@ -0,0 +1,245 @@ +// rustmft-version:Two +// rustmft-use_small_heuristics:Max +// rustmft-merge_derives:false +// These are the same rustfmt configuration options that are used +// in the comiler as of ce39461ca75a and 8eb7c58dbb7b +// These are commits in https://github.com/rust-lang/rust + +#![no_std] // inner attribute comment +// inner attribute comment +#![no_implicit_prelude] +// post inner attribute comment + +#[cfg(not(miri))] // inline comment +#[no_link] +extern crate foo; + +// before attributes +#[no_link] +// between attributes +#[cfg(not(miri))] // inline comment +extern crate foo as bar; + +#[cfg(not(miri))] // inline comment +// between attribute and use +use foo; + +#[cfg(not(miri))] // inline comment +use foo; + +/* pre attributre */ +#[cfg(not(miri))] +use foo::bar; + +#[cfg(not(miri))] // inline comment +use foo::bar as FooBar; + +#[cfg(not(miri))] // inline comment +#[allow(unused)] +#[deprecated( + since = "5.2", // inline inner comment + note = "FOO was rarely used. Users should instead use BAR" +)] +#[allow(unused)] +static FOO: i32 = 42; + +#[used] +#[export_name = "FOO"] +#[cfg(not(miri))] // inline comment +#[deprecated( + since = "5.2", + note = "FOO was rarely used. Users should instead use BAR" +)] +static FOO: i32 = 42; + +#[cfg(not(miri))] // inline comment +#[export_name = "FOO"] +static BAR: &'static str = "bar"; + +#[cfg(not(miri))] // inline comment +const BAR: i32 = 42; + +#[cfg(not(miri))] // inline comment +#[no_mangle] +#[link_section = ".example_section"] +fn foo(bar: usize) { + #[cfg(not(miri))] // inline comment + println!("hello world!"); +} + +#[cfg(not(miri))] // inline comment +mod foo {} + +#[cfg(not(miri))] // inline comment +extern "C" { + fn my_c_function(x: i32) -> bool; +} + +#[cfg(not(miri))] // inline comment +#[link(name = "CoreFoundation", kind = "framework")] +extern "C" { + + #[link_name = "actual_symbol_name"] // inline comment + // between attribute and function + fn my_c_function(x: i32) -> bool; +} + +#[cfg(not(miri))] // inline comment +pub extern "C" fn callable_from_c(x: i32) -> bool { + x % 3 == 0 +} + +#[cfg(not(miri))] // inline comment +/* between attribute block comment */ +#[no_mangle] +/* between attribute and type */ +type Foo = Bar<u8>; + +#[no_mangle] +#[cfg(not(miri))] // inline comment +#[non_exhaustive] // inline comment +enum Foo { + Bar, + Baz, +} + +#[no_mangle] +#[cfg(not(miri))] /* inline comment */ +struct Foo<A> { + x: A, +} + +#[cfg(not(miri))] // inline comment +union Foo<A, B> { + x: A, + y: B, +} + +#[cfg(not(miri))] // inline comment +trait Foo {} + +#[cfg(not(miri))] // inline comment +trait Foo = Bar + Quux; + +#[cfg(not(miri))] // inline comment +impl Foo {} + +#[cfg(not(miri))] // inline comment +macro_rules! bar { + (3) => {}; +} + +mod nested { + #[cfg(not(miri))] // inline comment + // between attribute and use + use foo; + + #[cfg(not(miri))] // inline comment + use foo; + + #[cfg(not(miri))] // inline comment + use foo::bar; + + #[cfg(not(miri))] // inline comment + use foo::bar as FooBar; + + #[cfg(not(miri))] // inline comment + static FOO: i32 = 42; + + #[cfg(not(miri))] // inline comment + static FOO: i32 = 42; + + #[cfg(not(miri))] // inline comment + static FOO: &'static str = "bar"; + + #[cfg(not(miri))] // inline comment + const FOO: i32 = 42; + + #[cfg(not(miri))] // inline comment + fn foo(bar: usize) { + #[cfg(not(miri))] // inline comment + println!("hello world!"); + } + + #[cfg(not(miri))] // inline comment + mod foo {} + + #[cfg(not(miri))] // inline comment + mod foo {} + + #[cfg(not(miri))] // inline comment + extern "C" { + fn my_c_function(x: i32) -> bool; + } + + #[cfg(not(miri))] // inline comment + #[link(name = "CoreFoundation", kind = "framework")] + extern "C" { + + #[link_name = "actual_symbol_name"] // inline comment + // between attribute and function + fn my_c_function(x: i32) -> bool; + } + + #[cfg(not(miri))] // inline comment + pub extern "C" fn callable_from_c(x: i32) -> bool { + x % 3 == 0 + } + + #[cfg(not(miri))] // inline comment + type Foo = Bar<u8>; + + #[cfg(not(miri))] // inline comment + #[non_exhaustive] // inline comment + enum Foo { + // comment + #[attribute_1] + #[attribute_2] // comment + // comment! + Bar, + /* comment */ + #[attribute_1] + #[attribute_2] /* comment */ + #[attribute_3] + #[attribute_4] + /* comment! */ + Baz, + } + + #[cfg(not(miri))] // inline comment + struct Foo<A> { + x: A, + } + + #[cfg(not(miri))] // inline comment + union Foo<A, B> { + #[attribute_1] + #[attribute_2] /* comment */ + #[attribute_3] + #[attribute_4] // comment + x: A, + y: B, + } + + #[cfg(not(miri))] // inline comment + #[allow(missing_docs)] + trait Foo { + #[must_use] /* comment + * that wrappes to + * the next line */ + fn bar() {} + } + + #[allow(missing_docs)] + #[cfg(not(miri))] // inline comment + trait Foo = Bar + Quux; + + #[allow(missing_docs)] + #[cfg(not(miri))] // inline comment + impl Foo {} + + #[cfg(not(miri))] // inline comment + macro_rules! bar { + (3) => {}; + } +} diff --git a/src/tools/rustfmt/tests/target/issue_4579.rs b/src/tools/rustfmt/tests/target/issue_4579.rs new file mode 100644 index 000000000..7b0a5f3a6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4579.rs @@ -0,0 +1,16 @@ +// rustfmt-hard_tabs: true + +#[macro_export] +macro_rules! main { + () => { + #[spirv(fragment)] + pub fn main_fs( + mut out_color: ::spirv_std::storage_class::Output<Vec4>, + #[spirv(descriptor_set = 1)] + iChannelResolution: ::spirv_std::storage_class::UniformConstant< + [::spirv_std::glam::Vec3A; 4], + >, + ) { + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue_4584.rs b/src/tools/rustfmt/tests/target/issue_4584.rs new file mode 100644 index 000000000..20255bead --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4584.rs @@ -0,0 +1,32 @@ +// rustfmt-indent_style: Visual + +#[derive(Debug)] +pub enum Case { + Upper, + Lower, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Case { + Upper, + Lower, +} + +// NB - This formatting looks potentially off the desired state, but is +// consistent with current behavior. Included here to provide a line wrapped +// derive case with the changes applied to resolve issue #4584 +#[derive(Add, + Sub, + Mul, + Div, + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + Debug, + Hash, + Serialize, + Mul)] +struct Foo {} diff --git a/src/tools/rustfmt/tests/target/issue_4636.rs b/src/tools/rustfmt/tests/target/issue_4636.rs new file mode 100644 index 000000000..a6465e29a --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4636.rs @@ -0,0 +1,13 @@ +pub trait PrettyPrinter<'tcx>: + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > + fmt::Write +{ + // +} diff --git a/src/tools/rustfmt/tests/target/issue_4675.rs b/src/tools/rustfmt/tests/target/issue_4675.rs new file mode 100644 index 000000000..a65f86832 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4675.rs @@ -0,0 +1,8 @@ +macro_rules! foo { + ($s:ident ( $p:pat )) => { + Foo { + name: Name::$s($p), + .. + } + }; +} diff --git a/src/tools/rustfmt/tests/target/issue_4823.rs b/src/tools/rustfmt/tests/target/issue_4823.rs new file mode 100644 index 000000000..de17467c0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4823.rs @@ -0,0 +1,5 @@ +macro_rules! m { + () => { + type Type; + }; +} diff --git a/src/tools/rustfmt/tests/target/issue_4850.rs b/src/tools/rustfmt/tests/target/issue_4850.rs new file mode 100644 index 000000000..7d4da9022 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4850.rs @@ -0,0 +1,4 @@ +impl ThisIsALongStructNameToPushTheWhereToWrapLolololol where + [(); this_is_a_long_const_function_name()]: +{ +} diff --git a/src/tools/rustfmt/tests/target/issue_4854.rs b/src/tools/rustfmt/tests/target/issue_4854.rs new file mode 100644 index 000000000..a81c5a517 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4854.rs @@ -0,0 +1,115 @@ +struct Struct { + // Multiline comment + // should be formatted + // properly. +} + +struct Struct2 { + // This formatting + // Should be changed +} + +struct Struct3( + // This + // is + // correct +); + +struct Struct4( + // This + // is + // not + // correct +); + +struct Struct5 { + /* + Comment block + with many lines. + */ +} + +struct Struct6( + /* + Comment block + with many lines. + */ +); + +struct Struct7 { + /* + Invalid + format + */ +} + +struct Struct8( + /* + Invalid + format + */ +); + +struct Struct9 {/* bar */} + +struct Struct10 { + /* bar + baz + */ +} + +mod module { + struct Struct { + // Multiline comment + // should be formatted + // properly. + } + + struct Struct2 { + // This formatting + // Should be changed + } + + struct Struct3( + // This + // is + // correct + ); + + struct Struct4( + // This + // is + // not + // correct + ); + + struct Struct5 { + /* + Comment block + with many lines. + */ + } + + struct Struct6( + /* + Comment block + with many lines. + */ + ); + + struct Struct7 { + /* + Invalid + format + */ + } + + struct Struct8( + /* + Invalid + format + */ + ); + + struct Struct9 {/* bar */} +} diff --git a/src/tools/rustfmt/tests/target/issue_4868.rs b/src/tools/rustfmt/tests/target/issue_4868.rs new file mode 100644 index 000000000..763a82c32 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4868.rs @@ -0,0 +1,17 @@ +enum NonAscii { + Abcd, + Éfgh, +} + +use NonAscii::*; + +fn f(x: NonAscii) -> bool { + match x { + Éfgh => true, + _ => false, + } +} + +fn main() { + dbg!(f(Abcd)); +} diff --git a/src/tools/rustfmt/tests/target/issue_4911.rs b/src/tools/rustfmt/tests/target/issue_4911.rs new file mode 100644 index 000000000..890a62267 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4911.rs @@ -0,0 +1,9 @@ +#![feature(generic_associated_types)] +#![feature(min_type_alias_impl_trait)] + +impl SomeTrait for SomeType { + type SomeGAT<'a> + where + Self: 'a, + = impl SomeOtherTrait; +} diff --git a/src/tools/rustfmt/tests/target/issue_4936.rs b/src/tools/rustfmt/tests/target/issue_4936.rs new file mode 100644 index 000000000..c19e505fd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4936.rs @@ -0,0 +1,10 @@ +#[discard_params_doc] +trait Trait { + fn foo( + &self, + /// some docs + bar: String, + /// another docs + baz: i32, + ); +} diff --git a/src/tools/rustfmt/tests/target/issue_4943.rs b/src/tools/rustfmt/tests/target/issue_4943.rs new file mode 100644 index 000000000..318f7ebed --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4943.rs @@ -0,0 +1,10 @@ +#![feature(generic_associated_types)] + +impl SomeStruct { + fn process<T>(v: T) -> <Self as GAT>::R<T> + where + Self: GAT<R<T> = T>, + { + SomeStruct::do_something(v) + } +} diff --git a/src/tools/rustfmt/tests/target/issue_4954.rs b/src/tools/rustfmt/tests/target/issue_4954.rs new file mode 100644 index 000000000..aa5e79bef --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4954.rs @@ -0,0 +1,7 @@ +trait Foo { + type Arg<'a>; +} + +struct Bar<T>(T) +where + for<'a> T: Foo<Arg<'a> = ()>; diff --git a/src/tools/rustfmt/tests/target/issue_4963.rs b/src/tools/rustfmt/tests/target/issue_4963.rs new file mode 100644 index 000000000..0c3c13579 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_4963.rs @@ -0,0 +1,9 @@ +mod test { + extern "C" { + fn test(); + } +} + +extern "C" { + fn test(); +} diff --git a/src/tools/rustfmt/tests/target/issue_5027.rs b/src/tools/rustfmt/tests/target/issue_5027.rs new file mode 100644 index 000000000..26d771720 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_5027.rs @@ -0,0 +1,17 @@ +// rustfmt-version: Two + +pub type Iter<'a, D> = impl DoubleEndedIterator<Item = (SomethingSomethingSomethingLongType<D>)> + + ExactSizeIterator + + 'a; + +trait FOo { + pub type Iter<'a, D> = impl DoubleEndedIterator<Item = (SomethingSomethingSomethingLongType<D>)> + + ExactSizeIterator + + 'a; +} + +impl Bar { + type Iter<'a, D> = impl DoubleEndedIterator<Item = (SomethingSomethingSomethingLongType<D>)> + + ExactSizeIterator + + 'a; +} diff --git a/src/tools/rustfmt/tests/target/issue_5086.rs b/src/tools/rustfmt/tests/target/issue_5086.rs new file mode 100644 index 000000000..7a0be06f7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_5086.rs @@ -0,0 +1,2 @@ +#[cfg(any())] +type Type: Bound; diff --git a/src/tools/rustfmt/tests/target/issue_5273.rs b/src/tools/rustfmt/tests/target/issue_5273.rs new file mode 100644 index 000000000..3bb9048a5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_5273.rs @@ -0,0 +1,3 @@ +struct Example<const N: usize = { 1048576 }> { + // +} diff --git a/src/tools/rustfmt/tests/target/issue_5399.rs b/src/tools/rustfmt/tests/target/issue_5399.rs new file mode 100644 index 000000000..17364c389 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_5399.rs @@ -0,0 +1,48 @@ +// rustfmt-max_width: 140 + +impl NotificationRepository { + fn set_status_changed( + &self, + repo_tx_conn: &RepoTxConn, + rid: &RoutableId, + changed_at: NaiveDateTime, + ) -> NukeResult<Option<NotificationStatus>> { + repo_tx_conn.run(move |conn| { + let res = diesel::update(client_notification::table) + .filter( + client_notification::routable_id.eq(DieselRoutableId(rid.clone())).and( + client_notification::changed_at + .lt(changed_at) + .or(client_notification::changed_at.is_null()), + ), + ) + .set(client_notification::changed_at.eq(changed_at)) + .returning(( + client_notification::id, + client_notification::changed_at, + client_notification::polled_at, + client_notification::notified_at, + )) + .get_result::<(Uuid, Option<NaiveDateTime>, Option<NaiveDateTime>, Option<NaiveDateTime>)>(conn) + .optional()?; + + match res { + Some(row) => { + let client_id = client_contract::table + .inner_join(client_notification::table) + .filter(client_notification::id.eq(row.0)) + .select(client_contract::client_id) + .get_result::<Uuid>(conn)?; + + Ok(Some(NotificationStatus { + client_id: client_id.into(), + changed_at: row.1, + polled_at: row.2, + notified_at: row.3, + })) + } + None => Ok(None), + } + }) + } +} diff --git a/src/tools/rustfmt/tests/target/item-brace-style-always-next-line.rs b/src/tools/rustfmt/tests/target/item-brace-style-always-next-line.rs new file mode 100644 index 000000000..4935fac04 --- /dev/null +++ b/src/tools/rustfmt/tests/target/item-brace-style-always-next-line.rs @@ -0,0 +1,71 @@ +// rustfmt-brace_style: AlwaysNextLine + +mod M +{ + enum A + { + A, + } + + struct B + { + b: i32, + } + + // For empty enums and structs, the brace remains on the same line. + enum C {} + + struct D {} + + enum A<T> + where + T: Copy, + { + A, + } + + struct B<T> + where + T: Copy, + { + b: i32, + } + + // For empty enums and structs, the brace remains on the same line. + enum C<T> + where + T: Copy, {} + + struct D<T> + where + T: Copy, {} +} + +fn function() {} + +trait Trait {} + +impl<T> Trait for T {} + +trait Trait2<T> +where + T: Copy + Display + Write + Read + FromStr, +{ +} + +trait Trait3<T> +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, +{ +} diff --git a/src/tools/rustfmt/tests/target/item-brace-style-prefer-same-line.rs b/src/tools/rustfmt/tests/target/item-brace-style-prefer-same-line.rs new file mode 100644 index 000000000..ef8dc028c --- /dev/null +++ b/src/tools/rustfmt/tests/target/item-brace-style-prefer-same-line.rs @@ -0,0 +1,35 @@ +// rustfmt-brace_style: PreferSameLine + +mod M { + enum A { + A, + } + + struct B { + b: i32, + } + + enum C {} + + struct D {} + + enum A<T> + where + T: Copy, { + A, + } + + struct B<T> + where + T: Copy, { + b: i32, + } + + enum C<T> + where + T: Copy, {} + + struct D<T> + where + T: Copy, {} +} diff --git a/src/tools/rustfmt/tests/target/item-brace-style-same-line-where.rs b/src/tools/rustfmt/tests/target/item-brace-style-same-line-where.rs new file mode 100644 index 000000000..fabe5822c --- /dev/null +++ b/src/tools/rustfmt/tests/target/item-brace-style-same-line-where.rs @@ -0,0 +1,37 @@ +mod M { + enum A { + A, + } + + struct B { + b: i32, + } + + // For empty enums and structs, the brace remains on the same line. + enum C {} + + struct D {} + + enum A<T> + where + T: Copy, + { + A, + } + + struct B<T> + where + T: Copy, + { + b: i32, + } + + // For empty enums and structs, the brace remains on the same line. + enum C<T> + where + T: Copy, {} + + struct D<T> + where + T: Copy, {} +} diff --git a/src/tools/rustfmt/tests/target/itemized-blocks/no_wrap.rs b/src/tools/rustfmt/tests/target/itemized-blocks/no_wrap.rs new file mode 100644 index 000000000..de8856382 --- /dev/null +++ b/src/tools/rustfmt/tests/target/itemized-blocks/no_wrap.rs @@ -0,0 +1,47 @@ +// rustfmt-normalize_comments: true +// rustfmt-format_code_in_doc_comments: true + +//! This is a list: +//! * Outer +//! * Outer +//! * Inner +//! * Inner with lots of text so that it could be reformatted something something something lots of text so that it could be reformatted something something something +//! +//! This example shows how to configure fern to output really nicely colored logs +//! - when the log level is error, the whole line is red +//! - when the log level is warn, the whole line is yellow +//! - when the log level is info, the level name is green and the rest of the line is white +//! - when the log level is debug, the whole line is white +//! - when the log level is trace, the whole line is gray ("bright black") + +/// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote +/// theater, i.e., as passed to [`Theater::send`] on the remote actor: +/// * `from` is the sending (remote) [`ActorId`], as reported by the remote theater by theater-specific means +/// * `to` is the receiving (local) [`ActorId`], as requested by the remote theater +/// * `tag` is a tag that identifies the message type +/// * `msg` is the (serialized) message +/// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote +/// theater, i.e., as passed to [`Theater::send`] on the remote actor +fn func1() {} + +/// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote +/// theater, i.e., as passed to [`Theater::send`] on the remote actor: +/// * `from` is the sending (remote) [`ActorId`], as reported by the remote theater by theater-specific means +/// * `to` is the receiving (local) [`ActorId`], as requested by the remote theater +/// * `tag` is a tag that identifies the message type +/// * `msg` is the (serialized) message +/// ``` +/// let x = 42; +/// ``` +fn func2() {} + +/// Look: +/// +/// ``` +/// let x = 42; +/// ``` +/// * `from` is the sending (remote) [`ActorId`], as reported by the remote theater by theater-specific means +/// * `to` is the receiving (local) [`ActorId`], as requested by the remote theater +/// * `tag` is a tag that identifies the message type +/// * `msg` is the (serialized) message +fn func3() {} diff --git a/src/tools/rustfmt/tests/target/itemized-blocks/rewrite_fail.rs b/src/tools/rustfmt/tests/target/itemized-blocks/rewrite_fail.rs new file mode 100644 index 000000000..a118ef6fa --- /dev/null +++ b/src/tools/rustfmt/tests/target/itemized-blocks/rewrite_fail.rs @@ -0,0 +1,14 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 50 + +// This example shows how to configure fern to +// output really nicely colored logs +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +// - when the log level is info, the level +// name is green and the rest of the line is +// white +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +// - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +fn func1() {} diff --git a/src/tools/rustfmt/tests/target/itemized-blocks/urls.rs b/src/tools/rustfmt/tests/target/itemized-blocks/urls.rs new file mode 100644 index 000000000..bc46ea47e --- /dev/null +++ b/src/tools/rustfmt/tests/target/itemized-blocks/urls.rs @@ -0,0 +1,25 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 79 + +//! CMSIS: Cortex Microcontroller Software Interface Standard +//! +//! The version 5 of the standard can be found at: +//! +//! http://arm-software.github.io/CMSIS_5/Core/html/index.html +//! +//! The API reference of the standard can be found at: +//! +//! - example -- http://example.org -- something something something something +//! something something +//! - something something something something something something more -- http://example.org +//! - http://example.org/something/something/something/something/something/something +//! and the rest +//! - Core function access -- http://arm-software.github.io/CMSIS_5/Core/html/group__Core__Register__gr.html +//! - Intrinsic functions for CPU instructions -- http://arm-software.github.io/CMSIS_5/Core/html/group__intrinsic__CPU__gr.html +//! - Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vestibulum sem +//! lacus, commodo vitae. +//! +//! The reference C implementation used as the base of this Rust port can be +//! found at +//! +//! https://github.com/ARM-software/CMSIS_5/blob/5.3.0/CMSIS/Core/Include/cmsis_gcc.h diff --git a/src/tools/rustfmt/tests/target/itemized-blocks/wrap.rs b/src/tools/rustfmt/tests/target/itemized-blocks/wrap.rs new file mode 100644 index 000000000..a4907303c --- /dev/null +++ b/src/tools/rustfmt/tests/target/itemized-blocks/wrap.rs @@ -0,0 +1,89 @@ +// rustfmt-wrap_comments: true +// rustfmt-format_code_in_doc_comments: true +// rustfmt-max_width: 50 + +//! This is a list: +//! * Outer +//! * Outer +//! * Inner +//! * Inner with lots of text so that it could +//! be reformatted something something +//! something lots of text so that it could be +//! reformatted something something something +//! +//! This example shows how to configure fern to +//! output really nicely colored logs +//! - when the log level is error, the whole line +//! is red +//! - when the log level is warn, the whole line +//! is yellow +//! - when the log level is info, the level name +//! is green and the rest of the line is white +//! - when the log level is debug, the whole line +//! is white +//! - when the log level is trace, the whole line +//! is gray ("bright black") + +// This example shows how to configure fern to +// output really nicely colored logs +// - when the log level is error, the whole line +// is red +// - when the log level is warn, the whole line +// is yellow +// - when the log level is info, the level +// name is green and the rest of the line is +// white +// - when the log level is debug, the whole line +// is white +// - when the log level is trace, the whole line +// is gray ("bright black") + +/// All the parameters ***except for +/// `from_theater`*** should be inserted as sent +/// by the remote theater, i.e., as passed to +/// [`Theater::send`] on the remote actor: +/// * `from` is the sending (remote) [`ActorId`], +/// as reported by the remote theater by +/// theater-specific means +/// * `to` is the receiving (local) [`ActorId`], +/// as requested by the remote theater +/// * `tag` is a tag that identifies the message +/// type +/// * `msg` is the (serialized) message +/// All the parameters ***except for +/// `from_theater`*** should be inserted as sent +/// by the remote theater, i.e., as passed to +/// [`Theater::send`] on the remote actor +fn func1() {} + +/// All the parameters ***except for +/// `from_theater`*** should be inserted as sent +/// by the remote theater, i.e., as passed to +/// [`Theater::send`] on the remote actor: +/// * `from` is the sending (remote) [`ActorId`], +/// as reported by the remote theater by +/// theater-specific means +/// * `to` is the receiving (local) [`ActorId`], +/// as requested by the remote theater +/// * `tag` is a tag that identifies the message +/// type +/// * `msg` is the (serialized) message +/// ``` +/// let x = 42; +/// ``` +fn func2() {} + +/// Look: +/// +/// ``` +/// let x = 42; +/// ``` +/// * `from` is the sending (remote) [`ActorId`], +/// as reported by the remote theater by +/// theater-specific means +/// * `to` is the receiving (local) [`ActorId`], +/// as requested by the remote theater +/// * `tag` is a tag that identifies the message +/// type +/// * `msg` is the (serialized) message +fn func3() {} diff --git a/src/tools/rustfmt/tests/target/label_break.rs b/src/tools/rustfmt/tests/target/label_break.rs new file mode 100644 index 000000000..728d78137 --- /dev/null +++ b/src/tools/rustfmt/tests/target/label_break.rs @@ -0,0 +1,28 @@ +// format with label break value. +fn main() { + 'empty_block: {} + + 'block: { + do_thing(); + if condition_not_met() { + break 'block; + } + do_next_thing(); + if condition_not_met() { + break 'block; + } + do_last_thing(); + } + + let result = 'block: { + if foo() { + // comment + break 'block 1; + } + if bar() { + /* comment */ + break 'block 2; + } + 3 + }; +} diff --git a/src/tools/rustfmt/tests/target/large-block.rs b/src/tools/rustfmt/tests/target/large-block.rs new file mode 100644 index 000000000..09e9169f3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/large-block.rs @@ -0,0 +1,5 @@ +fn issue1351() { + std_fmt_Arguments_new_v1_std_rt_begin_panic_fmt_sdfasfasdfasdf({ + static __STATIC_FMTSTR: &'static [&'static str] = &[]; + }); +} diff --git a/src/tools/rustfmt/tests/target/large_vec.rs b/src/tools/rustfmt/tests/target/large_vec.rs new file mode 100644 index 000000000..95d1fc43c --- /dev/null +++ b/src/tools/rustfmt/tests/target/large_vec.rs @@ -0,0 +1,42 @@ +// See #1470. + +impl Environment { + pub fn new_root() -> Rc<RefCell<Environment>> { + let mut env = Environment::new(); + let builtin_functions = &[ + ( + "println", + Function::NativeVoid( + CallSign { + num_params: 0, + variadic: true, + param_types: vec![], + }, + native_println, + ), + ), + ( + "run_http_server", + Function::NativeVoid( + CallSign { + num_params: 1, + variadic: false, + param_types: vec![Some(ConstraintType::Function)], + }, + native_run_http_server, + ), + ), + ( + "len", + Function::NativeReturning( + CallSign { + num_params: 1, + variadic: false, + param_types: vec![None], + }, + native_len, + ), + ), + ]; + } +} diff --git a/src/tools/rustfmt/tests/target/lazy_static.rs b/src/tools/rustfmt/tests/target/lazy_static.rs new file mode 100644 index 000000000..3625e0a5f --- /dev/null +++ b/src/tools/rustfmt/tests/target/lazy_static.rs @@ -0,0 +1,49 @@ +// Format `lazy_static!`. + +lazy_static! { + static ref CONFIG_NAME_REGEX: regex::Regex = + regex::Regex::new(r"^## `([^`]+)`").expect("Failed creating configuration pattern"); + static ref CONFIG_VALUE_REGEX: regex::Regex = regex::Regex::new(r#"^#### `"?([^`"]+)"?`"#) + .expect("Failed creating configuration value pattern"); +} + +// We need to be able to format `lazy_static!` without known syntax. +lazy_static!(xxx, yyyy, zzzzz); + +lazy_static! {} + +// #2354 +lazy_static! { + pub static ref Sbase64_encode_string: ::lisp::LispSubrRef = { + let subr = ::remacs_sys::Lisp_Subr { + header: ::remacs_sys::Lisp_Vectorlike_Header { + size: ((::remacs_sys::PseudovecType::PVEC_SUBR as ::libc::ptrdiff_t) + << ::remacs_sys::PSEUDOVECTOR_AREA_BITS), + }, + function: self::Fbase64_encode_string as *const ::libc::c_void, + min_args: 1i16, + max_args: 2i16, + symbol_name: (b"base64-encode-string\x00").as_ptr() as *const ::libc::c_char, + intspec: ::std::ptr::null(), + doc: ::std::ptr::null(), + lang: ::remacs_sys::Lisp_Subr_Lang_Rust, + }; + unsafe { + let ptr = ::remacs_sys::xmalloc(::std::mem::size_of::<::remacs_sys::Lisp_Subr>()) + as *mut ::remacs_sys::Lisp_Subr; + ::std::ptr::copy_nonoverlapping(&subr, ptr, 1); + ::std::mem::forget(subr); + ::lisp::ExternalPtr::new(ptr) + } + }; +} + +lazy_static! { + static ref FOO: HashMap< + String, + ( + &'static str, + fn(Foo) -> Result<Box<Bar>, Either<FooError, BarError>> + ), + > = HashMap::new(); +} diff --git a/src/tools/rustfmt/tests/target/let_else.rs b/src/tools/rustfmt/tests/target/let_else.rs new file mode 100644 index 000000000..a6e816fb5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/let_else.rs @@ -0,0 +1,3 @@ +fn main() { + let Some(1) = Some(1) else { return }; +} diff --git a/src/tools/rustfmt/tests/target/long-fn-1/version_one.rs b/src/tools/rustfmt/tests/target/long-fn-1/version_one.rs new file mode 100644 index 000000000..05f69953c --- /dev/null +++ b/src/tools/rustfmt/tests/target/long-fn-1/version_one.rs @@ -0,0 +1,29 @@ +// rustfmt-version: One +// Tests that a function which is almost short enough, but not quite, gets +// formatted correctly. + +impl Foo { + fn some_input( + &mut self, + input: Input, + input_path: Option<PathBuf>, + ) -> (Input, Option<PathBuf>) { + } + + fn some_inpu(&mut self, input: Input, input_path: Option<PathBuf>) -> (Input, Option<PathBuf>) { + } +} + +// #1843 +#[allow(non_snake_case)] +pub extern "C" fn Java_com_exonum_binding_storage_indices_ValueSetIndexProxy_nativeContainsByHash( +) -> bool { + false +} + +// #3009 +impl Something { + fn my_function_name_is_way_to_long_but_used_as_a_case_study_or_an_example_its_fine( + ) -> Result<(), String> { + } +} diff --git a/src/tools/rustfmt/tests/target/long-fn-1/version_two.rs b/src/tools/rustfmt/tests/target/long-fn-1/version_two.rs new file mode 100644 index 000000000..32794bccd --- /dev/null +++ b/src/tools/rustfmt/tests/target/long-fn-1/version_two.rs @@ -0,0 +1,29 @@ +// rustfmt-version: Two +// Tests that a function which is almost short enough, but not quite, gets +// formatted correctly. + +impl Foo { + fn some_input( + &mut self, + input: Input, + input_path: Option<PathBuf>, + ) -> (Input, Option<PathBuf>) { + } + + fn some_inpu(&mut self, input: Input, input_path: Option<PathBuf>) -> (Input, Option<PathBuf>) { + } +} + +// #1843 +#[allow(non_snake_case)] +pub extern "C" fn Java_com_exonum_binding_storage_indices_ValueSetIndexProxy_nativeContainsByHash() +-> bool { + false +} + +// #3009 +impl Something { + fn my_function_name_is_way_to_long_but_used_as_a_case_study_or_an_example_its_fine() + -> Result<(), String> { + } +} diff --git a/src/tools/rustfmt/tests/target/long-match-arms-brace-newline.rs b/src/tools/rustfmt/tests/target/long-match-arms-brace-newline.rs new file mode 100644 index 000000000..aeb384e72 --- /dev/null +++ b/src/tools/rustfmt/tests/target/long-match-arms-brace-newline.rs @@ -0,0 +1,15 @@ +// rustfmt-format_strings: true +// rustfmt-max_width: 80 +// rustfmt-control_brace_style: AlwaysNextLine + +fn main() { + match x + { + aaaaaaaa::Bbbbb::Ccccccccccccc(_, Some(ref x)) + if x == "aaaaaaaaaaa aaaaaaa aaaaaa" => + { + Ok(()) + } + _ => Err(x), + } +} diff --git a/src/tools/rustfmt/tests/target/long-use-statement-issue-3154.rs b/src/tools/rustfmt/tests/target/long-use-statement-issue-3154.rs new file mode 100644 index 000000000..877241e3b --- /dev/null +++ b/src/tools/rustfmt/tests/target/long-use-statement-issue-3154.rs @@ -0,0 +1,3 @@ +// rustfmt-reorder_imports: false + +pub use self::super::super::super::root::mozilla::detail::StringClassFlags as nsTStringRepr_ClassFlags; diff --git a/src/tools/rustfmt/tests/target/long_field_access.rs b/src/tools/rustfmt/tests/target/long_field_access.rs new file mode 100644 index 000000000..349d2c2f6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/long_field_access.rs @@ -0,0 +1,4 @@ +fn f() { + block_flow.base.stacking_relative_position_of_display_port = + self.base.stacking_relative_position_of_display_port; +} diff --git a/src/tools/rustfmt/tests/target/loop.rs b/src/tools/rustfmt/tests/target/loop.rs new file mode 100644 index 000000000..f669e7e2c --- /dev/null +++ b/src/tools/rustfmt/tests/target/loop.rs @@ -0,0 +1,34 @@ +fn main() { + loop { + return some_val; + } + + let x = loop { + do_forever(); + }; + + 'label: loop { + // Just comments + } + + 'a: while loooooooooooooooooooooooooooooooooong_variable_name + another_value > some_other_value + { + } + + while aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb { + } + + while aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { + } + + 'b: for xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx in some_iter(arg1, arg2) + { + // do smth + } + + while let Some(i) = x.find('s') { + x.update(); + continue; + continue 'foo; + } +} diff --git a/src/tools/rustfmt/tests/target/macro_not_expr.rs b/src/tools/rustfmt/tests/target/macro_not_expr.rs new file mode 100644 index 000000000..45f85ff2c --- /dev/null +++ b/src/tools/rustfmt/tests/target/macro_not_expr.rs @@ -0,0 +1,7 @@ +macro_rules! test { + ($($t:tt)*) => {}; +} + +fn main() { + test!( a : B => c d ); +} diff --git a/src/tools/rustfmt/tests/target/macro_rules.rs b/src/tools/rustfmt/tests/target/macro_rules.rs new file mode 100644 index 000000000..97444aef4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/macro_rules.rs @@ -0,0 +1,360 @@ +// rustfmt-format_macro_matchers: true + +macro_rules! m { + () => {}; + ($x:ident) => {}; + ($m1:ident, $m2:ident, $x:ident) => {}; + ($($beginning:ident),*; $middle:ident; $($end:ident),*) => {}; + ( + $($beginning:ident),*; + $middle:ident; + $($end:ident),*; + $($beginning:ident),*; + $middle:ident; + $($end:ident),* + ) => {}; + ($name:ident($($dol:tt $var:ident)*) $($body:tt)*) => {}; + ( + $($i:ident : $ty:ty, $def:expr, $stb:expr, $($dstring:tt),+);+ $(;)* + $($i:ident : $ty:ty, $def:expr, $stb:expr, $($dstring:tt),+);+ $(;)* + ) => {}; + ($foo:tt foo[$attr:meta] $name:ident) => {}; + ($foo:tt[$attr:meta] $name:ident) => {}; + ($foo:tt &'a[$attr:meta] $name:ident) => {}; + ($foo:tt foo #[$attr:meta] $name:ident) => {}; + ($foo:tt #[$attr:meta] $name:ident) => {}; + ($foo:tt &'a #[$attr:meta] $name:ident) => {}; + ($x:tt foo bar foo bar foo bar $y:tt => x * y * z $z:tt, $($a:tt),*) => {}; +} + +macro_rules! impl_a_method { + ($n:ident($a:ident : $ta:ty) -> $ret:ty { $body:expr }) => { + fn $n($a: $ta) -> $ret { + $body + } + macro_rules! $n { + ($va: expr) => { + $n($va) + }; + } + }; + ($n:ident($a:ident : $ta:ty, $b:ident : $tb:ty) -> $ret:ty { $body:expr }) => { + fn $n($a: $ta, $b: $tb) -> $ret { + $body + } + macro_rules! $n { + ($va: expr,$vb: expr) => { + $n($va, $vb) + }; + } + }; + ( + $n:ident($a:ident : $ta:ty, $b:ident : $tb:ty, $c:ident : $tc:ty) -> $ret:ty { $body:expr } + ) => { + fn $n($a: $ta, $b: $tb, $c: $tc) -> $ret { + $body + } + macro_rules! $n { + ($va: expr,$vb: expr,$vc: expr) => { + $n($va, $vb, $vc) + }; + } + }; + ( + $n:ident($a:ident : $ta:ty, $b:ident : $tb:ty, $c:ident : $tc:ty, $d:ident : $td:ty) -> + $ret:ty { $body:expr } + ) => { + fn $n($a: $ta, $b: $tb, $c: $tc, $d: $td) -> $ret { + $body + } + macro_rules! $n { + ($va: expr,$vb: expr,$vc: expr,$vd: expr) => { + $n($va, $vb, $vc, $vd) + }; + } + }; +} + +macro_rules! m { + // a + ($expr:expr, $($func:ident)*) => {{ + let x = $expr; + $func(x) + }}; + + /* b */ + () => { + /* c */ + }; + + (@tag) => {}; + + // d + ($item:ident) => { + mod macro_item { + struct $item; + } + }; +} + +macro m2 { + // a + ($expr:expr, $($func:ident)*) => {{ + let x = $expr; + $func(x) + }} + + /* b */ + () => { + /* c */ + } + + (@tag) => {} + + // d + ($item:ident) => { + mod macro_item { + struct $item; + } + } +} + +// #2438, #2476 +macro_rules! m { + () => { + fn foo() { + this_line_is_98_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(); + } + }; +} +macro_rules! m { + () => { + fn foo() { + this_line_is_99_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + ); + } + }; +} +macro_rules! m { + () => { + fn foo() { + this_line_is_100_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + ); + } + }; +} +macro_rules! m { + () => { + fn foo() { + this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + ); + } + }; +} + +// #2439 +macro_rules! m { + ( + $line0_xxxxxxxxxxxxxxxxx:expr, + $line1_xxxxxxxxxxxxxxxxx:expr, + $line2_xxxxxxxxxxxxxxxxx:expr, + $line3_xxxxxxxxxxxxxxxxx:expr, + ) => {}; +} + +// #2466 +// Skip formatting `macro_rules!` that are not using `{}`. +macro_rules! m ( + () => () +); +macro_rules! m [ + () => () +]; + +// #2470 +macro foo($type_name:ident, $docs:expr) { + #[allow(non_camel_case_types)] + #[doc=$docs] + #[derive(Debug, Clone, Copy)] + pub struct $type_name; +} + +// #2534 +macro_rules! foo { + ($a:ident : $b:ty) => {}; + ($a:ident $b:ident $c:ident) => {}; +} + +// #2538 +macro_rules! add_message_to_notes { + ($msg:expr) => {{ + let mut lines = message.lines(); + notes.push_str(&format!("\n{}: {}", level, lines.next().unwrap())); + for line in lines { + notes.push_str(&format!( + "\n{:indent$}{line}", + "", + indent = level.len() + 2, + line = line, + )); + } + }}; +} + +// #2560 +macro_rules! binary { + ($_self:ident, $expr:expr, $lhs:expr, $func:ident) => { + while $_self.matched($expr) { + let op = $_self.get_binary_op()?; + + let rhs = Box::new($_self.$func()?); + + $lhs = Spanned { + span: $lhs.get_span().to(rhs.get_span()), + value: Expression::Binary { + lhs: Box::new($lhs), + op, + rhs, + }, + } + } + }; +} + +// #2558 +macro_rules! m { + ($x:) => {}; + ($($foo:expr)()?) => {}; +} + +// #2749 +macro_rules! foo { + ($(x)* {}) => {}; + ($(x)*()) => {}; + ($(x)*[]) => {}; +} +macro_rules! __wundergraph_expand_sqlite_mutation { + ( + $mutation_name:ident $((context = $($context:tt)*))* { + $( + $entity_name:ident( + $(insert = $insert:ident,)* + $(update = $update:ident,)* + $(delete = $($delete:tt)+)* + ), + )* + } + ) => {}; +} + +// #2607 +macro_rules! bench { + ($ty:ident) => { + criterion_group!( + name = benches; + config = ::common_bench::reduced_samples(); + targets = call, map; + ); + }; +} + +// #2770 +macro_rules! save_regs { + () => { + asm!("push rax + push rcx + push rdx + push rsi + push rdi + push r8 + push r9 + push r10 + push r11" + :::: "intel", "volatile"); + }; +} + +// #2721 +macro_rules! impl_as_byte_slice_arrays { + ($n:expr,) => {}; + ($n:expr, $N:ident, $($NN:ident,)*) => { + impl_as_byte_slice_arrays!($n - 1, $($NN,)*); + + impl<T> AsByteSliceMut for [T; $n] where [T]: AsByteSliceMut { + fn as_byte_slice_mut(&mut self) -> &mut [u8] { + self[..].as_byte_slice_mut() + } + + fn to_le(&mut self) { + self[..].to_le() + } + } + }; + (!div $n:expr,) => {}; + (!div $n:expr, $N:ident, $($NN:ident,)*) => { + impl_as_byte_slice_arrays!(!div $n / 2, $($NN,)*); + + impl<T> AsByteSliceMut for [T; $n] where [T]: AsByteSliceMut { + fn as_byte_slice_mut(&mut self) -> &mut [u8] { + self[..].as_byte_slice_mut() + } + + fn to_le(&mut self) { + self[..].to_le() + } + } + }; +} + +// #2919 +fn foo() { + { + macro_rules! touch_value { + ($func:ident, $value:expr) => {{ + let result = API::get_cached().$func( + self, + key.as_ptr(), + $value, + ffi::VSPropAppendMode::paTouch, + ); + let result = API::get_cached().$func(self, key.as_ptr(), $value, ffi::VSPropAppend); + let result = + API::get_cached().$func(self, key.as_ptr(), $value, ffi::VSPropAppendM); + let result = + APIIIIIIIII::get_cached().$func(self, key.as_ptr(), $value, ffi::VSPropAppendM); + let result = API::get_cached().$func( + self, + key.as_ptr(), + $value, + ffi::VSPropAppendMMMMMMMMMM, + ); + debug_assert!(result == 0); + }}; + } + } +} + +// #2642 +macro_rules! template { + ($name:expr) => { + format_args!( + r##" +"http://example.com" + +# test +"##, + $name + ) + }; +} + +macro_rules! template { + () => { + format_args!( + r" +// + +" + ) + }; +} diff --git a/src/tools/rustfmt/tests/target/macro_rules_semi.rs b/src/tools/rustfmt/tests/target/macro_rules_semi.rs new file mode 100644 index 000000000..84e12d16e --- /dev/null +++ b/src/tools/rustfmt/tests/target/macro_rules_semi.rs @@ -0,0 +1,22 @@ +macro_rules! expr { + (no_semi) => { + return true + }; + (semi) => { + return true; + }; +} + +fn foo() -> bool { + match true { + true => expr!(no_semi), + false if false => { + expr!(semi) + } + false => { + expr!(semi); + } + } +} + +fn main() {} diff --git a/src/tools/rustfmt/tests/target/macros.rs b/src/tools/rustfmt/tests/target/macros.rs new file mode 100644 index 000000000..e930b5037 --- /dev/null +++ b/src/tools/rustfmt/tests/target/macros.rs @@ -0,0 +1,1062 @@ +// rustfmt-normalize_comments: true +// rustfmt-format_macro_matchers: true +itemmacro!(this, is.now().formatted(yay)); + +itemmacro!( + really, + long.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbb() + .is + .formatted() +); + +itemmacro! {this, is.brace().formatted()} + +fn main() { + foo!(); + + foo!(,); + + bar!(a, b, c); + + bar!(a, b, c,); + + baz!(1 + 2 + 3, quux.kaas()); + + quux!( + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + ); + + kaas!( + // comments + a, // post macro + b // another + ); + + trailingcomma!(a, b, c,); + // Preserve trailing comma only when necessary. + ok!(file.seek(SeekFrom::Start( + table.map(|table| fixture.offset(table)).unwrap_or(0), + ))); + + noexpr!( i am not an expression, OK? ); + + vec![a, b, c]; + + vec![ + AAAAAA, + AAAAAA, + AAAAAA, + AAAAAA, + AAAAAA, + AAAAAA, + AAAAAA, + AAAAAA, + AAAAAA, + BBBBB, + 5, + 100 - 30, + 1.33, + b, + b, + b, + ]; + + vec![a /* comment */]; + + // Trailing spaces after a comma + vec![a]; + + vec![a; b]; + vec![a; b]; + vec![a; b]; + + vec![a, b; c]; + vec![a; b, c]; + + vec![ + a; + (|x| { + let y = x + 1; + let z = y + 1; + z + })(2) + ]; + vec![ + a; + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ]; + vec![a; unsafe { x + 1 }]; + + unknown_bracket_macro__comma_should_not_be_stripped![a,]; + + foo(makro!(1, 3)); + + hamkaas! { () }; + + macrowithbraces! {dont, format, me} + + x!(fn); + + some_macro!(); + + some_macro![]; + + some_macro! { + // comment + }; + + some_macro! { + // comment + }; + + some_macro!( + // comment + not function like + ); + + // #1712 + let image = gray_image!( + 00, 01, 02; + 10, 11, 12; + 20, 21, 22); + + // #1092 + chain!(input, a: take!(max_size), || []); + + // #2727 + foo!("bar"); +} + +impl X { + empty_invoc! {} + empty_invoc! {} +} + +fn issue_1279() { + println!("dsfs"); // a comment +} + +fn issue_1555() { + let hello = &format!( + "HTTP/1.1 200 OK\r\nServer: {}\r\n\r\n{}", + "65454654654654654654654655464", "4" + ); +} + +fn issue1178() { + macro_rules! foo { + (#[$attr:meta] $name:ident) => {}; + } + + foo!( + #[doc = "bar"] + baz + ); +} + +fn issue1739() { + sql_function!( + add_rss_item, + add_rss_item_t, + ( + a: types::Integer, + b: types::Timestamptz, + c: types::Text, + d: types::Text, + e: types::Text + ) + ); + + w.slice_mut(s![ + .., + init_size[1] - extreeeeeeeeeeeeeeeeeeeeeeeem..init_size[1], + .. + ]) + .par_map_inplace(|el| *el = 0.); +} + +fn issue_1885() { + let threads = people + .into_iter() + .map(|name| { + chan_select! { + rx.recv() => {} + } + }) + .collect::<Vec<_>>(); +} + +fn issue_1917() { + mod x { + quickcheck! { + fn test(a: String, s: String, b: String) -> TestResult { + if a.find(&s).is_none() { + + TestResult::from_bool(true) + } else { + TestResult::discard() + } + } + } + } +} + +fn issue_1921() { + // Macro with tabs. + lazy_static! { + static ref ONE: u32 = 1; + static ref TWO: u32 = 2; + static ref THREE: u32 = 3; + static ref FOUR: u32 = { + let mut acc = 1; + acc += 1; + acc += 2; + acc + }; + } +} + +// #1577 +fn issue1577() { + let json = json!({ + "foo": "bar", + }); +} + +// #3174 +fn issue_3174() { + let data = if let Some(debug) = error.debug_info() { + json!({ + "errorKind": format!("{:?}", error.err_kind()), + "debugMessage": debug.message, + }) + } else { + json!({ "errorKind": format!("{:?}", error.err_kind()) }) + }; +} + +gfx_pipeline!(pipe { + vbuf: gfx::VertexBuffer<Vertex> = (), + out: gfx::RenderTarget<ColorFormat> = "Target0", +}); + +// #1919 +#[test] +fn __bindgen_test_layout_HandleWithDtor_open0_int_close0_instantiation() { + assert_eq!( + ::std::mem::size_of::<HandleWithDtor<::std::os::raw::c_int>>(), + 8usize, + concat!( + "Size of template specialization: ", + stringify!(HandleWithDtor<::std::os::raw::c_int>) + ) + ); + assert_eq!( + ::std::mem::align_of::<HandleWithDtor<::std::os::raw::c_int>>(), + 8usize, + concat!( + "Alignment of template specialization: ", + stringify!(HandleWithDtor<::std::os::raw::c_int>) + ) + ); +} + +// #878 +macro_rules! try_opt { + ($expr:expr) => { + match $expr { + Some(val) => val, + + None => { + return None; + } + } + }; +} + +// #2214 +// macro call whose argument is an array with trailing comma. +fn issue2214() { + make_test!( + str_searcher_ascii_haystack, + "bb", + "abbcbbd", + [ + Reject(0, 1), + Match(1, 3), + Reject(3, 4), + Match(4, 6), + Reject(6, 7), + ] + ); +} + +fn special_case_macros() { + let p = eprint!(); + let q = eprint!("{}", 1); + let r = eprint!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + let s = eprint!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + let q = eprintln!("{}", 1); + let r = eprintln!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + let s = eprintln!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + let q = format!("{}", 1); + let r = format!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + let s = format!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + let q = format_args!("{}", 1); + let r = format_args!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + let s = format_args!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + let q = print!("{}", 1); + let r = print!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + let s = print!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + let q = println!("{}", 1); + let r = println!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + let s = println!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + let q = unreachable!("{}", 1); + let r = unreachable!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + let s = unreachable!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + debug!("{}", 1); + debug!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + debug!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + error!("{}", 1); + error!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + error!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + info!("{}", 1); + info!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + info!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + panic!("{}", 1); + panic!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + panic!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + warn!("{}", 1); + warn!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + ); + warn!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + assert!(); + assert!(result == 42); + assert!(result == 42, "Ahoy there, {}!", target); + assert!( + result == 42, + "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", + result, + input, + expected + ); + assert!( + result == 42, + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + assert_eq!(); + assert_eq!(left); + assert_eq!(left, right); + assert_eq!(left, right, "Ahoy there, {}!", target); + assert_eq!( + left, right, + "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", + result, input, expected + ); + assert_eq!( + first_realllllllllllly_long_variable_that_doesnt_fit_one_one_line, + second_reallllllllllly_long_variable_that_doesnt_fit_one_one_line, + "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", + result, + input, + expected + ); + assert_eq!( + left + 42, + right, + "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", + result, + input, + expected + ); + assert_eq!( + left, + right, + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + write!(&mut s, "Ahoy there, {}!", target); + write!( + &mut s, + "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", + result, input, expected + ); + write!( + &mut s, + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); + + writeln!(&mut s, "Ahoy there, {}!", target); + writeln!( + &mut s, + "Arr! While plunderin' the hold, we got '{}' when given '{}' (we expected '{}')", + result, input, expected + ); + writeln!( + &mut s, + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ); +} + +// #1209 +impl Foo { + /// foo + pub fn foo(&self) -> Bar<foo!()> {} +} + +// #819 +fn macro_in_pattern_position() { + let x = match y { + foo!() => (), + bar!(a, b, c) => (), + bar!(a, b, c,) => (), + baz!(1 + 2 + 3, quux.kaas()) => (), + quux!( + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + ) => (), + }; +} + +macro foo() {} + +pub macro bar($x:ident + $y:expr;) { + fn foo($x: Foo) { + long_function( + a_long_argument_to_a_long_function_is_what_this_is(AAAAAAAAAAAAAAAAAAAAAAAAAAAA), + $x.bar($y), + ); + } +} + +macro foo() { + // a comment + fn foo() { + // another comment + bar(); + } +} + +// #2574 +macro_rules! test { + () => {{}}; +} + +macro lex_err($kind: ident $(, $body: expr)*) { + Err(QlError::LexError(LexError::$kind($($body,)*))) +} + +// Preserve trailing comma on item-level macro with `()` or `[]`. +methods![get, post, delete,]; +methods!(get, post, delete,); + +// #2588 +macro_rules! m { + () => { + r#" + test + "# + }; +} +fn foo() { + f! {r#" + test + "#}; +} + +// #2591 +fn foo() { + match 0u32 { + 0 => (), + _ => unreachable!(/* obviously */), + } +} + +fn foo() { + let _ = column!(/* here */); +} + +// #2616 +// Preserve trailing comma when using mixed layout for macro call. +fn foo() { + foo!( + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ); + foo!( + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + ); +} + +// #2830 +// Preserve trailing comma-less/ness inside nested macro. +named!( + do_parse_gsv<GsvData>, + map_res!( + do_parse!( + number_of_sentences: map_res!(digit, parse_num::<u16>) + >> char!(',') + >> sentence_index: map_res!(digit, parse_num::<u16>) + >> char!(',') + >> total_number_of_sats: map_res!(digit, parse_num::<u16>) + >> char!(',') + >> sat0: opt!(complete!(parse_gsv_sat_info)) + >> sat1: opt!(complete!(parse_gsv_sat_info)) + >> sat2: opt!(complete!(parse_gsv_sat_info)) + >> sat3: opt!(complete!(parse_gsv_sat_info)) + >> ( + number_of_sentences, + sentence_index, + total_number_of_sats, + sat0, + sat1, + sat2, + sat3 + ) + ), + construct_gsv_data + ) +); + +// #2857 +convert_args!(vec!(1, 2, 3)); + +// #3031 +thread_local!( + /// TLV Holds a set of JSTraceables that need to be rooted + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = RefCell::new(RootedTraceableSet::new()); +); + +thread_local![ + /// TLV Holds a set of JSTraceables that need to be rooted + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = RefCell::new(RootedTraceableSet::new()); + + /// TLV Holds a set of JSTraceables that need to be rooted + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = + RefCell::new(RootedTraceableSet::new(0)); + + /// TLV Holds a set of JSTraceables that need to be rooted + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = + RefCell::new(RootedTraceableSet::new(), xxx, yyy); + + /// TLV Holds a set of JSTraceables that need to be rooted + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = + RefCell::new(RootedTraceableSet::new(1234)); +]; + +fn issue3004() { + foo!(|_| { () }); + stringify!((foo+)); +} + +// #3331 +pub fn fold_abi<V: Fold + ?Sized>(_visitor: &mut V, _i: Abi) -> Abi { + Abi { + extern_token: Token![extern](tokens_helper(_visitor, &_i.extern_token.span)), + name: (_i.name).map(|it| _visitor.fold_lit_str(it)), + } +} + +// #3463 +x! {()} + +// #3746 +f!(match a { + 4 => &[ + (3, false), // Missing + (4, true) // I-frame + ][..], +}); + +// #3583 +foo!(|x = y|); diff --git a/src/tools/rustfmt/tests/target/markdown-comment-with-options.rs b/src/tools/rustfmt/tests/target/markdown-comment-with-options.rs new file mode 100644 index 000000000..ede2bc0d0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/markdown-comment-with-options.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: true + +// Preserve two trailing whitespaces in doc comment, +// but trim any whitespaces in normal comment. + +//! hello world +//! hello world + +/// hello world +/// hello world +/// hello world +fn foo() { + // hello world + // hello world + let x = 3; + println!("x = {}", x); +} diff --git a/src/tools/rustfmt/tests/target/markdown-comment.rs b/src/tools/rustfmt/tests/target/markdown-comment.rs new file mode 100644 index 000000000..71a9921d2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/markdown-comment.rs @@ -0,0 +1,15 @@ +// Preserve two trailing whitespaces in doc comment, +// but trim any whitespaces in normal comment. + +//! hello world +//! hello world + +/// hello world +/// hello world +/// hello world +fn foo() { + // hello world + // hello world + let x = 3; + println!("x = {}", x); +} diff --git a/src/tools/rustfmt/tests/target/match-block-trailing-comma.rs b/src/tools/rustfmt/tests/target/match-block-trailing-comma.rs new file mode 100644 index 000000000..5ab433a2e --- /dev/null +++ b/src/tools/rustfmt/tests/target/match-block-trailing-comma.rs @@ -0,0 +1,26 @@ +// rustfmt-match_block_trailing_comma: true +// Match expressions, no unwrapping of block arms or wrapping of multiline +// expressions. + +fn foo() { + match x { + a => { + "line1"; + "line2" + }, + ThisIsA::Guard if true => { + "line1"; + "line2" + }, + ThisIsA::ReallyLongPattern(ThatWillForce::TheGuard, ToWrapOnto::TheFollowingLine) + if true => + { + "line1"; + "line2" + }, + b => ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + ), + } +} diff --git a/src/tools/rustfmt/tests/target/match-flattening.rs b/src/tools/rustfmt/tests/target/match-flattening.rs new file mode 100644 index 000000000..f246952a0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/match-flattening.rs @@ -0,0 +1,23 @@ +fn main() { + match option { + None => { + if condition { + true + } else { + false + } + } + } +} + +fn main() { + match option { + None => { + if condition { + true + } else { + false + } + } + } +} diff --git a/src/tools/rustfmt/tests/target/match-nowrap-trailing-comma.rs b/src/tools/rustfmt/tests/target/match-nowrap-trailing-comma.rs new file mode 100644 index 000000000..19ef21448 --- /dev/null +++ b/src/tools/rustfmt/tests/target/match-nowrap-trailing-comma.rs @@ -0,0 +1,17 @@ +// rustfmt-match_arm_blocks: false +// rustfmt-match_block_trailing_comma: true +// Match expressions, no unwrapping of block arms or wrapping of multiline +// expressions. + +fn foo() { + match x { + a => { + "line1"; + "line2" + }, + b => ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + ), + } +} diff --git a/src/tools/rustfmt/tests/target/match-nowrap.rs b/src/tools/rustfmt/tests/target/match-nowrap.rs new file mode 100644 index 000000000..9e674b1e2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/match-nowrap.rs @@ -0,0 +1,13 @@ +// rustfmt-match_arm_blocks: false +// Match expressions, no unwrapping of block arms or wrapping of multiline +// expressions. + +fn foo() { + match x { + a => foo(), + b => ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + ), + } +} diff --git a/src/tools/rustfmt/tests/target/match.rs b/src/tools/rustfmt/tests/target/match.rs new file mode 100644 index 000000000..1bf3fb758 --- /dev/null +++ b/src/tools/rustfmt/tests/target/match.rs @@ -0,0 +1,629 @@ +// rustfmt-normalize_comments: true +// Match expressions. + +fn foo() { + // A match expression. + match x { + // Some comment. + a => foo(), + b if 0 < 42 => foo(), + c => { + // Another comment. + // Comment. + an_expression; + foo() + } + Foo(ref bar) => { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + } + Pattern1 | Pattern2 | Pattern3 => false, + Paternnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn + | Paternnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn => blah, + Patternnnnnnnnnnnnnnnnnnn + | Patternnnnnnnnnnnnnnnnnnn + | Patternnnnnnnnnnnnnnnnnnn + | Patternnnnnnnnnnnnnnnnnnn => meh, + + Patternnnnnnnnnnnnnnnnnnn | Patternnnnnnnnnnnnnnnnnnn if looooooooooooooooooong_guard => { + meh + } + + Patternnnnnnnnnnnnnnnnnnnnnnnnn | Patternnnnnnnnnnnnnnnnnnnnnnnnn + if looooooooooooooooooooooooooooooooooooooooong_guard => + { + meh + } + + // Test that earlier patterns can take the guard space + (aaaa, bbbbb, ccccccc, aaaaa, bbbbbbbb, cccccc, aaaa, bbbbbbbb, cccccc, dddddd) + | Patternnnnnnnnnnnnnnnnnnnnnnnnn + if loooooooooooooooooooooooooooooooooooooooooong_guard => {} + + _ => {} + ast::PathParameters::AngleBracketedParameters(ref data) + if data.lifetimes.len() > 0 || data.types.len() > 0 || data.bindings.len() > 0 => {} + } + + let whatever = match something { + /// DOC COMMENT! + Some(_) => 42, + // Comment on an attribute. + #[an_attribute] + // Comment after an attribute. + None => 0, + #[rustfmt::skip] + Blurb => { } + }; +} + +// Test that a match on an overflow line is laid out properly. +fn main() { + let sub_span = + match xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx { + Some(sub_span) => Some(sub_span), + None => sub_span, + }; +} + +// Test that one-line bodies align. +fn main() { + match r { + Variableeeeeeeeeeeeeeeeee => ( + "variable", + vec!["id", "name", "qualname", "value", "type", "scopeid"], + true, + true, + ), + Enummmmmmmmmmmmmmmmmmmmm => ( + "enum", + vec!["id", "qualname", "scopeid", "value"], + true, + true, + ), + Variantttttttttttttttttttttttt => ( + "variant", + vec!["id", "name", "qualname", "type", "value", "scopeid"], + true, + true, + ), + }; + + match x { + y => { /*Block with comment. Preserve me.*/ } + z => { + stmt(); + } + } +} + +fn matches() { + match 1 { + -1 => 10, + 1 => 1, // foo + 2 => 2, + // bar + 3 => 3, + _ => 0, // baz + } +} + +fn match_skip() { + let _ = match Some(1) { + #[rustfmt::skip] + Some( n ) => n, + None => 1, + }; +} + +fn issue339() { + match a { + b => {} + c => {} + d => {} + e => {} + // collapsing here is safe + ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff => {} + // collapsing here exceeds line length + ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffg => { + } + h => { // comment above block + } + i => {} // comment below block + j => { + // comment inside block + } + j2 => { + // comments inside... + } // ... and after + // TODO uncomment when vertical whitespace is handled better + // k => { + // + // // comment with WS above + // } + // l => { + // // comment with ws below + // + // } + m => {} + n => {} + o => {} + p => { // Don't collapse me + } + q => {} + r => {} + s => 0, // s comment + // t comment + t => 1, + u => 2, + v => {} /* funky block + * comment */ + /* final comment */ + } +} + +fn issue355() { + match mac { + a => println!("a", b), + b => vec![1, 2], + c => vec![3; 4], + d => { + println!("a", b) + } + e => { + vec![1, 2] + } + f => { + vec![3; 4] + } + h => println!("a", b), // h comment + i => vec![1, 2], // i comment + j => vec![3; 4], // j comment + // k comment + k => println!("a", b), + // l comment + l => vec![1, 2], + // m comment + m => vec![3; 4], + // Rewrite splits macro + nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn => { + println!("a", b) + } + // Rewrite splits macro + oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo => { + vec![1, 2] + } + // Macro support fails to recognise this macro as splittable + // We push the whole expr to a new line, TODO split this macro as well + pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp => { + vec![3; 4] + } + // q, r and s: Rewrite splits match arm + qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq => { + println!("a", b) + } + rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr => { + vec![1, 2] + } + ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss => { + vec![3; 4] + } + // Funky bracketing styles + t => println! {"a", b}, + u => vec![1, 2], + v => vec![3; 4], + w => println!["a", b], + x => vec![1, 2], + y => vec![3; 4], + // Brackets with comments + tc => println! {"a", b}, // comment + uc => vec![1, 2], // comment + vc => vec![3; 4], // comment + wc => println!["a", b], // comment + xc => vec![1, 2], // comment + yc => vec![3; 4], // comment + yd => looooooooooooooooooooooooooooooooooooooooooooooooooooooooong_func( + aaaaaaaaaa, bbbbbbbbbb, cccccccccc, dddddddddd, + ), + } +} + +fn issue280() { + { + match x { + CompressionMode::DiscardNewline | CompressionMode::CompressWhitespaceNewline => { + ch == '\n' + } + ast::ItemConst(ref typ, ref expr) => { + self.process_static_or_const_item(item, &typ, &expr) + } + } + } +} + +fn issue383() { + match resolution.last_private { + LastImport { .. } => false, + _ => true, + }; +} + +fn issue507() { + match 1 { + 1 => unsafe { std::intrinsics::abort() }, + _ => (), + } +} + +fn issue508() { + match s.type_id() { + Some(NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLCanvasElement, + ))) => true, + Some(NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLObjectElement, + ))) => s.has_object_data(), + Some(NodeTypeId::Element(_)) => false, + } +} + +fn issue496() { + { + { + { + match def { + def::DefConst(def_id) | def::DefAssociatedConst(def_id) => { + match const_eval::lookup_const_by_id(cx.tcx, def_id, Some(self.pat.id)) { + Some(const_expr) => x, + } + } + } + } + } + } +} + +fn issue494() { + { + match stmt.node { + hir::StmtExpr(ref expr, id) | hir::StmtSemi(ref expr, id) => { + result.push(StmtRef::Mirror(Box::new(Stmt { + span: stmt.span, + kind: StmtKind::Expr { + scope: cx.tcx.region_maps.node_extent(id), + expr: expr.to_ref(), + }, + }))) + } + } + } +} + +fn issue386() { + match foo { + BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true, + BiAnd | BiOr | BiAdd | BiSub | BiMul | BiDiv | BiRem | BiBitXor | BiBitAnd | BiBitOr + | BiShl | BiShr => false, + } +} + +fn guards() { + match foo { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + if foooooooooooooo && barrrrrrrrrrrr => {} + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + if foooooooooooooo && barrrrrrrrrrrr => {} + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + if fooooooooooooooooooooo + && (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + || cccccccccccccccccccccccccccccccccccccccc) => {} + } +} + +fn issue1371() { + Some(match type_ { + sfEvtClosed => Closed, + sfEvtResized => { + let e = unsafe { *event.size.as_ref() }; + + Resized { + width: e.width, + height: e.height, + } + } + sfEvtLostFocus => LostFocus, + sfEvtGainedFocus => GainedFocus, + sfEvtTextEntered => TextEntered { + unicode: unsafe { + ::std::char::from_u32((*event.text.as_ref()).unicode) + .expect("Invalid unicode encountered on TextEntered event") + }, + }, + sfEvtKeyPressed => { + let e = unsafe { event.key.as_ref() }; + + KeyPressed { + code: unsafe { ::std::mem::transmute(e.code) }, + alt: e.alt.to_bool(), + ctrl: e.control.to_bool(), + shift: e.shift.to_bool(), + system: e.system.to_bool(), + } + } + sfEvtKeyReleased => { + let e = unsafe { event.key.as_ref() }; + + KeyReleased { + code: unsafe { ::std::mem::transmute(e.code) }, + alt: e.alt.to_bool(), + ctrl: e.control.to_bool(), + shift: e.shift.to_bool(), + system: e.system.to_bool(), + } + } + }) +} + +fn issue1395() { + let bar = Some(true); + let foo = Some(true); + let mut x = false; + bar.and_then(|_| match foo { + None => None, + Some(b) => { + x = true; + Some(b) + } + }); +} + +fn issue1456() { + Ok(Recording { + artists: match reader.evaluate(".//mb:recording/mb:artist-credit/mb:name-credit")? { + Nodeset(nodeset) => { + let res: Result<Vec<ArtistRef>, ReadError> = nodeset + .iter() + .map(|node| { + XPathNodeReader::new(node, &context).and_then(|r| ArtistRef::from_xml(&r)) + }) + .collect(); + res? + } + _ => Vec::new(), + }, + }) +} + +fn issue1460() { + let _ = match foo { + REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT => { + "internal_spec_insert_internal_spec_insert_internal_spec_insert" + } + _ => "reorder_something", + }; +} + +fn issue525() { + foobar( + f, + "{}", + match *self { + TaskState::Started => "started", + TaskState::Success => "success", + TaskState::Failed => "failed", + }, + ); +} + +// #1838, #1839 +fn match_with_near_max_width() { + let (this_line_uses_99_characters_and_is_formatted_properly, x012345) = match some_expression { + _ => unimplemented!(), + }; + + let (should_be_formatted_like_the_line_above_using_100_characters, x0) = match some_expression { + _ => unimplemented!(), + }; + + let (should_put_the_brace_on_the_next_line_using_101_characters, x0000) = match some_expression + { + _ => unimplemented!(), + }; + match m { + Variant::Tag + | Variant::Tag2 + | Variant::Tag3 + | Variant::Tag4 + | Variant::Tag5 + | Variant::Tag6 => {} + } +} + +fn match_with_trailing_spaces() { + match x { + Some(..) => 0, + None => 1, + } +} + +fn issue_2099() { + let a = match x {}; + let b = match x {}; + + match x {} +} + +// #2021 +impl<'tcx> Const<'tcx> { + pub fn from_constval<'a>() -> Const<'tcx> { + let val = match *cv { + ConstVal::Variant(_) | ConstVal::Aggregate(..) | ConstVal::Unevaluated(..) => bug!( + "MIR must not use `{:?}` (aggregates are expanded to MIR rvalues)", + cv + ), + }; + } +} + +// #2151 +fn issue_2151() { + match either { + x => {} + y => (), + } +} + +// #2152 +fn issue_2152() { + match m { + "aaaaaaaaaaaaa" | "bbbbbbbbbbbbb" | "cccccccccccccccccccccccccccccccccccccccccccc" + if true => {} + "bind" | "writev" | "readv" | "sendmsg" | "recvmsg" if android && (aarch64 || x86_64) => { + true + } + } +} + +// #2376 +// Preserve block around expressions with condition. +fn issue_2376() { + let mut x = None; + match x { + Some(0) => { + for i in 1..11 { + x = Some(i); + } + } + Some(ref mut y) => { + while *y < 10 { + *y += 1; + } + } + None => { + while let None = x { + x = Some(10); + } + } + } +} + +// #2621 +// Strip leading `|` in match arm patterns +fn issue_2621() { + let x = Foo::A; + match x { + Foo::A => println!("No vert single condition"), + Foo::B | Foo::C => println!("Center vert two conditions"), + Foo::D => println!("Preceding vert single condition"), + Foo::E | Foo::F => println!("Preceding vert over two lines"), + Foo::G | Foo::H => println!("Trailing vert over two lines"), + // Comment on its own line + Foo::I => println!("With comment"), // Comment after line + } +} + +fn issue_2377() { + match tok { + Tok::Not + | Tok::BNot + | Tok::Plus + | Tok::Minus + | Tok::PlusPlus + | Tok::MinusMinus + | Tok::Void + | Tok::Delete + if prec <= 16 => + { + // code here... + } + Tok::TypeOf if prec <= 16 => {} + } +} + +// #3040 +fn issue_3040() { + { + match foo { + DevtoolScriptControlMsg::WantsLiveNotifications(id, to_send) => { + match documents.find_window(id) { + Some(window) => { + devtools::handle_wants_live_notifications(window.upcast(), to_send) + } + None => return warn!("Message sent to closed pipeline {}.", id), + } + } + } + } +} + +// #3030 +fn issue_3030() { + match input.trim().parse::<f64>() { + Ok(val) + if !( + // A valid number is the same as what rust considers to be valid, + // except for +1., NaN, and Infinity. + val.is_infinite() || val.is_nan() || input.ends_with(".") || input.starts_with("+") + ) => {} + } +} + +fn issue_3005() { + match *token { + Token::Dimension { + value, ref unit, .. + } if num_context.is_ok(context.parsing_mode, value) => { + return NoCalcLength::parse_dimension(context, value, unit) + .map(LengthOrPercentage::Length) + .map_err(|()| location.new_unexpected_token_error(token.clone())); + } + } +} + +// #3774 +fn issue_3774() { + { + { + { + match foo { + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachab(), + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreacha!(), + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => { + unreachabl() + } + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => { + unreachae!() + } + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => { + unreachable() + } + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => { + unreachable!() + } + Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => { + rrunreachable!() + } + } + } + } + } +} + +// #4109 +fn issue_4109() { + match () { + _ => { + #[cfg(debug_assertions)] + { + println!("Foo"); + } + } + } + + match () { + _ => { + #[allow(unsafe_code)] + unsafe {} + } + } +} diff --git a/src/tools/rustfmt/tests/target/match_overflow_expr.rs b/src/tools/rustfmt/tests/target/match_overflow_expr.rs new file mode 100644 index 000000000..b817879d1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/match_overflow_expr.rs @@ -0,0 +1,50 @@ +// rustfmt-overflow_delimited_expr: true + +fn main() { + println!("Foobar: {}", match "input" { + "a" => "", + "b" => "", + "c" => "", + "d" => "", + "e" => "", + "f" => "", + "g" => "", + "h" => "", + "i" => "", + "j" => "", + "k" => "", + "l" => "", + "m" => "", + "n" => "", + "o" => "", + "p" => "", + "q" => "", + "r" => "Rust", + }); +} + +fn main() { + println!( + "Very Long Input String Which Makes It Impossible To Fit On The Same Line: {}", + match "input" { + "a" => "", + "b" => "", + "c" => "", + "d" => "", + "e" => "", + "f" => "", + "g" => "", + "h" => "", + "i" => "", + "j" => "", + "k" => "", + "l" => "", + "m" => "", + "n" => "", + "o" => "", + "p" => "", + "q" => "", + "r" => "Rust", + } + ); +} diff --git a/src/tools/rustfmt/tests/target/max-line-length-in-chars.rs b/src/tools/rustfmt/tests/target/max-line-length-in-chars.rs new file mode 100644 index 000000000..d49fbb7e3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/max-line-length-in-chars.rs @@ -0,0 +1,4 @@ +// rustfmt-max_width: 25 + +// абвгдеёжзийклмнопрст +fn main() {} diff --git a/src/tools/rustfmt/tests/target/merge_imports_true_compat.rs b/src/tools/rustfmt/tests/target/merge_imports_true_compat.rs new file mode 100644 index 000000000..46cd0a3b8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/merge_imports_true_compat.rs @@ -0,0 +1,3 @@ +// rustfmt-merge_imports: true + +use a::{b, c}; diff --git a/src/tools/rustfmt/tests/target/mod-1.rs b/src/tools/rustfmt/tests/target/mod-1.rs new file mode 100644 index 000000000..4118d123d --- /dev/null +++ b/src/tools/rustfmt/tests/target/mod-1.rs @@ -0,0 +1,37 @@ +// Deeply indented modules. + +mod foo { + mod bar { + mod baz {} + } +} + +mod foo { + mod bar { + mod baz { + fn foo() { + bar() + } + } + } + + mod qux {} +} + +mod boxed { + pub use std::boxed::{Box, HEAP}; +} + +pub mod x { + pub fn freopen( + filename: *const c_char, + mode: *const c_char, + mode2: *const c_char, + mode3: *const c_char, + file: *mut FILE, + ) -> *mut FILE { + } +} + +mod y { // sup boooooiiii +} diff --git a/src/tools/rustfmt/tests/target/mod-2.rs b/src/tools/rustfmt/tests/target/mod-2.rs new file mode 100644 index 000000000..1a093bd52 --- /dev/null +++ b/src/tools/rustfmt/tests/target/mod-2.rs @@ -0,0 +1,5 @@ +// Some nested mods + +#[cfg(test)] +mod nestedmod; +pub mod no_new_line_beginning; diff --git a/src/tools/rustfmt/tests/target/mod_skip_child.rs b/src/tools/rustfmt/tests/target/mod_skip_child.rs new file mode 100644 index 000000000..d48c4a37e --- /dev/null +++ b/src/tools/rustfmt/tests/target/mod_skip_child.rs @@ -0,0 +1,2 @@ +// rustfmt-skip_children: true +mod nested_skipped; diff --git a/src/tools/rustfmt/tests/target/mulit-file.rs b/src/tools/rustfmt/tests/target/mulit-file.rs new file mode 100644 index 000000000..1f829b36f --- /dev/null +++ b/src/tools/rustfmt/tests/target/mulit-file.rs @@ -0,0 +1,10 @@ +// Tests that where a single file is referred to in multiple places, we don't +// crash. + +#[cfg(all(foo))] +#[path = "closure.rs"] +pub mod imp; + +#[cfg(all(bar))] +#[path = "closure.rs"] +pub mod imp; diff --git a/src/tools/rustfmt/tests/target/multiline_string_in_macro_def.rs b/src/tools/rustfmt/tests/target/multiline_string_in_macro_def.rs new file mode 100644 index 000000000..dafc738f8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/multiline_string_in_macro_def.rs @@ -0,0 +1,14 @@ +macro_rules! assert_approx_eq { + ($a:expr, $b:expr, $eps:expr) => {{ + let (a, b) = (&$a, &$b); + assert!( + (*a - *b).abs() < $eps, + "assertion failed: `(left !== right)` \ + (left: `{:?}`, right: `{:?}`, expect diff: `{:?}`, real diff: `{:?}`)", + *a, + *b, + $eps, + (*a - *b).abs() + ); + }}; +} diff --git a/src/tools/rustfmt/tests/target/multiple.rs b/src/tools/rustfmt/tests/target/multiple.rs new file mode 100644 index 000000000..ee6ef220c --- /dev/null +++ b/src/tools/rustfmt/tests/target/multiple.rs @@ -0,0 +1,180 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-format_strings: true +// Test of lots of random stuff. +// FIXME split this into multiple, self-contained tests. + +#[attr1] +extern crate foo; +#[attr2] +#[attr3] +extern crate foo; +#[attr1] +extern crate foo; +#[attr2] +#[attr3] +extern crate foo; + +use std::cell::*; +use std::{ + self, any, ascii, borrow, borrow, borrow, borrow, borrow, borrow, borrow, borrow, borrow, + borrow, borrow, boxed, boxed, boxed, boxed, boxed, boxed, boxed, boxed, boxed, boxed, char, + char, char, char, char, char, char, char, char, char, +}; + +mod doc; +mod other; + +// sfdgfffffffffffffffffffffffffffffffffffffffffffffffffffffff +// ffffffffffffffffffffffffffffffffffffffffff + +fn foo(a: isize, b: u32 /* blah blah */, c: f64) {} + +fn foo() -> Box<Write + 'static> +where + 'a: 'b, + for<'a> D<'b>: 'a, +{ + hello!() +} + +fn baz< + 'a: 'b, // comment on 'a + T: SomsssssssssssssssssssssssssssssssssssssssssssssssssssssseType, // comment on T +>( + a: A, + b: B, // comment on b + c: C, +) -> Bob { + #[attr1] + extern crate foo; + #[attr2] + #[attr3] + extern crate foo; + #[attr1] + extern crate foo; + #[attr2] + #[attr3] + extern crate foo; +} + +#[rustfmt::skip] +fn qux(a: dadsfa, // Comment 1 + b: sdfasdfa, // Comment 2 + c: dsfdsafa) // Comment 3 +{ + +} + +/// Blah blah blah. +impl Bar { + fn foo( + &mut self, + a: sdfsdfcccccccccccccccccccccccccccccccccccccccccccccccccc, // comment on a + b: sdfasdfsdfasfs, // closing comment + ) -> isize { + } + + /// Blah blah blah. + pub fn f2(self) { + (foo, bar) + } + + #[an_attribute] + fn f3(self) -> Dog {} +} + +/// The `nodes` and `edges` method each return instantiations of +/// `Cow<[T]>` to leave implementers the freedom to create + +/// entirely new vectors or to pass back slices into internally owned +/// vectors. +pub trait GraphWalk<'a, N, E> { + /// Returns all the nodes in this graph. + fn nodes(&'a self) -> Nodes<'a, N>; + /// Returns all of the edges in this graph. + fn edges(&'a self) -> Edges<'a, E>; + /// The source node for `edge`. + fn source(&'a self, edge: &E) -> N; + /// The target node for `edge`. + fn target(&'a self, edge: &E) -> N; +} + +/// A Doc comment +#[AnAttribute] +pub struct Foo { + #[rustfmt::skip] + f : SomeType, // Comment beside a field + f: SomeType, // Comment beside a field + // Comment on a field + g: SomeOtherType, + /// A doc comment on a field + h: AThirdType, +} + +struct Bar; + +// With a where-clause and generics. +pub struct Foo<'a, Y: Baz> +where + X: Whatever, +{ + f: SomeType, // Comment beside a field +} + +fn foo(ann: &'a (PpAnn + 'a)) {} + +fn main() { + for i in 0i32..4 { + println!("{}", i); + } + + while true { + hello(); + } + + let rc = Cell::new( + 42usize, + 42usize, + Cell::new( + 42usize, + remaining_widthremaining_widthremaining_widthremaining_width, + ), + 42usize, + ); + let rc = RefCell::new(42usize, remaining_width, remaining_width); // a comment + let x = "Hello!!!!!!!!! abcd abcd abcd abcd abcd abcd\n abcd abcd abcd abcd abcd abcd abcd \ + abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd \ + abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd \ + abcd abcd"; + let s = expand(a, b); +} + +fn deconstruct() -> ( + SocketAddr, + Method, + Headers, + RequestUri, + HttpVersion, + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +) { +} + +fn deconstruct( + foo: Bar, +) -> ( + SocketAddr, + Method, + Headers, + RequestUri, + HttpVersion, + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +) { +} + +#[rustfmt::skip] +mod a{ +fn foo(x: T) { + let x: T = dfasdf; +} +} diff --git a/src/tools/rustfmt/tests/target/negative-impl.rs b/src/tools/rustfmt/tests/target/negative-impl.rs new file mode 100644 index 000000000..16ce7e26a --- /dev/null +++ b/src/tools/rustfmt/tests/target/negative-impl.rs @@ -0,0 +1,14 @@ +impl !Display for JoinHandle {} + +impl !Box<JoinHandle> {} + +impl !std::fmt::Display + for JoinHandle<T: std::future::Future + std::marker::Send + std::marker::Sync> +{ +} + +impl + !JoinHandle<T: std::future::Future<Output> + std::marker::Send + std::marker::Sync + 'static> + + 'static +{ +} diff --git a/src/tools/rustfmt/tests/target/nested-if-else.rs b/src/tools/rustfmt/tests/target/nested-if-else.rs new file mode 100644 index 000000000..9a54789dd --- /dev/null +++ b/src/tools/rustfmt/tests/target/nested-if-else.rs @@ -0,0 +1,11 @@ +fn issue1518() { + Some(Object { + field: if a { + a_thing + } else if b { + b_thing + } else { + c_thing + }, + }) +} diff --git a/src/tools/rustfmt/tests/target/nested-visual-block.rs b/src/tools/rustfmt/tests/target/nested-visual-block.rs new file mode 100644 index 000000000..fe7190d0a --- /dev/null +++ b/src/tools/rustfmt/tests/target/nested-visual-block.rs @@ -0,0 +1,60 @@ +fn main() { + // #1078 + let items = itemize_list( + context.source_map, + field_iter, + "}", + |item| match *item { + StructLitField::Regular(ref field) => field.span.lo(), + StructLitField::Base(ref expr) => { + let last_field_hi = fields.last().map_or(span.lo(), |field| field.span.hi()); + let snippet = context.snippet(mk_sp(last_field_hi, expr.span.lo())); + let pos = snippet.find_uncommented("..").unwrap(); + last_field_hi + BytePos(pos as u32) + } + }, + |item| match *item { + StructLitField::Regular(ref field) => field.span.hi(), + StructLitField::Base(ref expr) => expr.span.hi(), + }, + |item| { + match *item { + StructLitField::Regular(ref field) => rewrite_field( + inner_context, + &field, + &Constraints::new(v_budget.checked_sub(1).unwrap_or(0), indent), + ), + StructLitField::Base(ref expr) => { + // 2 = .. + expr.rewrite( + inner_context, + &Constraints::new(try_opt!(v_budget.checked_sub(2)), indent + 2), + ) + .map(|s| format!("..{}", s)) + } + } + }, + context.source_map.span_after(span, "{"), + span.hi(), + ); + + // #1580 + self.0.pool.execute(move || { + let _timer = segments.0.rotate_timer.time(); + if let Err(e) = segments.rotate_async(wal) { + error!("error compacting segment storage WAL", unsafe { error: e.display() }); + } + }); + + // #1581 + bootstrap.checks.register("PERSISTED_LOCATIONS", move || { + if locations2.0.inner_mut.lock().poisoned { + Check::new( + State::Error, + "Persisted location storage is poisoned due to a write failure", + ) + } else { + Check::new(State::Healthy, "Persisted location storage is healthy") + } + }); +} diff --git a/src/tools/rustfmt/tests/target/nested_skipped/mod.rs b/src/tools/rustfmt/tests/target/nested_skipped/mod.rs new file mode 100644 index 000000000..0ab6f081e --- /dev/null +++ b/src/tools/rustfmt/tests/target/nested_skipped/mod.rs @@ -0,0 +1,3 @@ +fn ugly() { + 92; +} diff --git a/src/tools/rustfmt/tests/target/nestedmod/mod.rs b/src/tools/rustfmt/tests/target/nestedmod/mod.rs new file mode 100644 index 000000000..1df462931 --- /dev/null +++ b/src/tools/rustfmt/tests/target/nestedmod/mod.rs @@ -0,0 +1,12 @@ +mod mod2a; +mod mod2b; + +mod mymod1 { + use mod2a::{Bar, Foo}; + mod mod3a; +} + +#[path = "mod2c.rs"] +mod mymod2; + +mod submod2; diff --git a/src/tools/rustfmt/tests/target/nestedmod/mod2a.rs b/src/tools/rustfmt/tests/target/nestedmod/mod2a.rs new file mode 100644 index 000000000..5df457a83 --- /dev/null +++ b/src/tools/rustfmt/tests/target/nestedmod/mod2a.rs @@ -0,0 +1,4 @@ +// This is an empty file containing only +// comments + +// ................... diff --git a/src/tools/rustfmt/tests/target/nestedmod/mod2b.rs b/src/tools/rustfmt/tests/target/nestedmod/mod2b.rs new file mode 100644 index 000000000..9b6ea844e --- /dev/null +++ b/src/tools/rustfmt/tests/target/nestedmod/mod2b.rs @@ -0,0 +1,2 @@ +#[path = "mod2a.rs"] +mod c; diff --git a/src/tools/rustfmt/tests/target/nestedmod/mod2c.rs b/src/tools/rustfmt/tests/target/nestedmod/mod2c.rs new file mode 100644 index 000000000..7db4572e7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/nestedmod/mod2c.rs @@ -0,0 +1,3 @@ +// A standard mod + +fn a() {} diff --git a/src/tools/rustfmt/tests/target/nestedmod/mymod1/mod3a.rs b/src/tools/rustfmt/tests/target/nestedmod/mymod1/mod3a.rs new file mode 100644 index 000000000..ae09d8dda --- /dev/null +++ b/src/tools/rustfmt/tests/target/nestedmod/mymod1/mod3a.rs @@ -0,0 +1,2 @@ +// Another mod +fn a() {} diff --git a/src/tools/rustfmt/tests/target/nestedmod/submod2/a.rs b/src/tools/rustfmt/tests/target/nestedmod/submod2/a.rs new file mode 100644 index 000000000..120b17145 --- /dev/null +++ b/src/tools/rustfmt/tests/target/nestedmod/submod2/a.rs @@ -0,0 +1,6 @@ +// Yet Another mod +// Nested + +use c::a; + +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/nestedmod/submod2/mod.rs b/src/tools/rustfmt/tests/target/nestedmod/submod2/mod.rs new file mode 100644 index 000000000..52f8be910 --- /dev/null +++ b/src/tools/rustfmt/tests/target/nestedmod/submod2/mod.rs @@ -0,0 +1,5 @@ +// Another mod + +mod a; + +use a::a; diff --git a/src/tools/rustfmt/tests/target/no_arg_with_commnet.rs b/src/tools/rustfmt/tests/target/no_arg_with_commnet.rs new file mode 100644 index 000000000..69f61b60f --- /dev/null +++ b/src/tools/rustfmt/tests/target/no_arg_with_commnet.rs @@ -0,0 +1 @@ +fn foo(/* cooment */) {} diff --git a/src/tools/rustfmt/tests/target/no_new_line_beginning.rs b/src/tools/rustfmt/tests/target/no_new_line_beginning.rs new file mode 100644 index 000000000..f328e4d9d --- /dev/null +++ b/src/tools/rustfmt/tests/target/no_new_line_beginning.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/src/tools/rustfmt/tests/target/normalize_doc_attributes_should_not_imply_format_doc_comments.rs b/src/tools/rustfmt/tests/target/normalize_doc_attributes_should_not_imply_format_doc_comments.rs new file mode 100644 index 000000000..562d9565e --- /dev/null +++ b/src/tools/rustfmt/tests/target/normalize_doc_attributes_should_not_imply_format_doc_comments.rs @@ -0,0 +1,15 @@ +// rustfmt-normalize_doc_attributes: true + +/// Foo +/// +/// # Example +/// ``` +/// # #![cfg_attr(not(dox), feature(cfg_target_feature, target_feature, stdsimd))] +/// # #![cfg_attr(not(dox), no_std)] +/// fn foo() { } +/// ``` +/// +fn foo() {} + +///Bar documents +fn bar() {} diff --git a/src/tools/rustfmt/tests/target/normalize_multiline_doc_attribute.rs b/src/tools/rustfmt/tests/target/normalize_multiline_doc_attribute.rs new file mode 100644 index 000000000..890c9bb20 --- /dev/null +++ b/src/tools/rustfmt/tests/target/normalize_multiline_doc_attribute.rs @@ -0,0 +1,12 @@ +// rustfmt-unstable: true +// rustfmt-normalize_doc_attributes: true + +///This comment +///is split +///on multiple lines +fn foo() {} + +/// B1 +/// +/// A1 +fn bar() {} diff --git a/src/tools/rustfmt/tests/target/obsolete_in_place.rs b/src/tools/rustfmt/tests/target/obsolete_in_place.rs new file mode 100644 index 000000000..3f364c1ae --- /dev/null +++ b/src/tools/rustfmt/tests/target/obsolete_in_place.rs @@ -0,0 +1,9 @@ +// #2953 + +macro_rules! demo { + ($a:ident <- $b:expr) => {}; +} + +fn main() { + demo!(i <- 0); +} diff --git a/src/tools/rustfmt/tests/target/one_line_if_v1.rs b/src/tools/rustfmt/tests/target/one_line_if_v1.rs new file mode 100644 index 000000000..b3c6c4cbe --- /dev/null +++ b/src/tools/rustfmt/tests/target/one_line_if_v1.rs @@ -0,0 +1,46 @@ +// rustfmt-version: One + +fn plain_if(x: bool) -> u8 { + if x { + 0 + } else { + 1 + } +} + +fn paren_if(x: bool) -> u8 { + (if x { 0 } else { 1 }) +} + +fn let_if(x: bool) -> u8 { + let x = if x { foo() } else { bar() }; + x +} + +fn return_if(x: bool) -> u8 { + return if x { 0 } else { 1 }; +} + +fn multi_if() { + use std::io; + if x { + foo() + } else { + bar() + } + if x { + foo() + } else { + bar() + } +} + +fn middle_if() { + use std::io; + if x { + foo() + } else { + bar() + } + let x = 1; +} diff --git a/src/tools/rustfmt/tests/target/one_line_if_v2.rs b/src/tools/rustfmt/tests/target/one_line_if_v2.rs new file mode 100644 index 000000000..81ca4c8b8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/one_line_if_v2.rs @@ -0,0 +1,38 @@ +// rustfmt-version: Two + +fn plain_if(x: bool) -> u8 { + if x { 0 } else { 1 } +} + +fn paren_if(x: bool) -> u8 { + (if x { 0 } else { 1 }) +} + +fn let_if(x: bool) -> u8 { + let x = if x { foo() } else { bar() }; + x +} + +fn return_if(x: bool) -> u8 { + return if x { 0 } else { 1 }; +} + +fn multi_if() { + use std::io; + if x { + foo() + } else { + bar() + } + if x { foo() } else { bar() } +} + +fn middle_if() { + use std::io; + if x { + foo() + } else { + bar() + } + let x = 1; +} diff --git a/src/tools/rustfmt/tests/target/other.rs b/src/tools/rustfmt/tests/target/other.rs new file mode 100644 index 000000000..dfce84fcd --- /dev/null +++ b/src/tools/rustfmt/tests/target/other.rs @@ -0,0 +1,5 @@ +// Part of multiple.rs + +fn bob() { + println!("hello other!"); +} diff --git a/src/tools/rustfmt/tests/target/paren.rs b/src/tools/rustfmt/tests/target/paren.rs new file mode 100644 index 000000000..f7714d85d --- /dev/null +++ b/src/tools/rustfmt/tests/target/paren.rs @@ -0,0 +1,6 @@ +fn main() { + let x = (1); + let y = (/* comment */(2)); + let z = ((3)/* comment */); + let a = (4/* comment */); +} diff --git a/src/tools/rustfmt/tests/target/path_clarity/foo.rs b/src/tools/rustfmt/tests/target/path_clarity/foo.rs new file mode 100644 index 000000000..cd247fabf --- /dev/null +++ b/src/tools/rustfmt/tests/target/path_clarity/foo.rs @@ -0,0 +1,2 @@ +// rustfmt-edition: 2018 +mod bar; diff --git a/src/tools/rustfmt/tests/target/path_clarity/foo/bar.rs b/src/tools/rustfmt/tests/target/path_clarity/foo/bar.rs new file mode 100644 index 000000000..b18a7d349 --- /dev/null +++ b/src/tools/rustfmt/tests/target/path_clarity/foo/bar.rs @@ -0,0 +1,3 @@ +pub fn fn_in_bar() { + println!("foo/bar.rs"); +} diff --git a/src/tools/rustfmt/tests/target/paths.rs b/src/tools/rustfmt/tests/target/paths.rs new file mode 100644 index 000000000..0d2ba797e --- /dev/null +++ b/src/tools/rustfmt/tests/target/paths.rs @@ -0,0 +1,28 @@ +// rustfmt-normalize_comments: true + +fn main() { + let constellation_chan = + Constellation::<layout::layout_task::LayoutTask, script::script_task::ScriptTask>::start( + compositor_proxy, + resource_task, + image_cache_task, + font_cache_task, + time_profiler_chan, + mem_profiler_chan, + devtools_chan, + storage_task, + supports_clipboard, + ); + + Quux::< + ParamOne, // Comment 1 + ParamTwo, // Comment 2 + >::some_func(); + + <*mut JSObject>::relocate(entry); + + let x: Foo<A>; + let x: Foo/*::*/<A>; +} + +fn op(foo: Bar, key: &[u8], upd: Fn(Option<&memcache::Item>, Baz) -> Result) -> MapResult {} diff --git a/src/tools/rustfmt/tests/target/pattern-condense-wildcards.rs b/src/tools/rustfmt/tests/target/pattern-condense-wildcards.rs new file mode 100644 index 000000000..a85a16004 --- /dev/null +++ b/src/tools/rustfmt/tests/target/pattern-condense-wildcards.rs @@ -0,0 +1,12 @@ +// rustfmt-normalize_comments: true +// rustfmt-condense_wildcard_suffixes: true + +fn main() { + match x { + Butt(..) => "hah", + Tup(_) => "nah", + Quad(_, _, x, _) => " also no rewrite", + Quad(x, ..) => "condense me pls", + Weird(x, _, _, /* don't condense before */ ..) => "pls work", + } +} diff --git a/src/tools/rustfmt/tests/target/pattern.rs b/src/tools/rustfmt/tests/target/pattern.rs new file mode 100644 index 000000000..576018ac6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/pattern.rs @@ -0,0 +1,98 @@ +// rustfmt-normalize_comments: true +#![feature(exclusive_range_pattern)] +use core::u8::MAX; + +fn main() { + let z = match x { + "pat1" => 1, + (ref x, ref mut y /* comment */) => 2, + }; + + if let <T as Trait>::CONST = ident { + do_smth(); + } + + let Some(ref xyz /* comment! */) = opt; + + if let None = opt2 { + panic!("oh noes"); + } + + let foo @ bar(f) = 42; + let a::foo(..) = 42; + let [] = 42; + let [a, b, c] = 42; + let [a, b, c] = 42; + let [a, b, c, d, e, f, g] = 42; + let foo {} = 42; + let foo { .. } = 42; + let foo { x, y: ref foo, .. } = 42; + let foo { + x, + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: ref foo, + .. + } = 42; + let foo { + x, + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: ref foo, + } = 42; + let foo { + x, + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: ref foo, + .. + }; + let foo { + x, + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: ref foo, + }; + + match b"12" { + [0, 1..MAX] => {} + _ => {} + } +} + +impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> { + fn mutate_fragment(&mut self, fragment: &mut Fragment) { + match **info { + GeneratedContentInfo::ContentItem(ContentItem::Counter( + ref counter_name, + counter_style, + )) => {} + } + } +} + +fn issue_1319() { + if let (Event { .. }, ..) = ev_state {} +} + +fn issue_1874() { + if let Some(()) = x { + y + } +} + +fn combine_patterns() { + let x = match y { + Some(Some(Foo { + z: Bar(..), + a: Bar(..), + b: Bar(..), + })) => z, + _ => return, + }; +} + +fn slice_patterns() { + match b"123" { + [0, ..] => {} + [0, foo] => {} + _ => {} + } +} + +fn issue3728() { + let foo = |(c,)| c; + foo((1,)); +} diff --git a/src/tools/rustfmt/tests/target/preserves_carriage_return_for_unix.rs b/src/tools/rustfmt/tests/target/preserves_carriage_return_for_unix.rs new file mode 100644 index 000000000..e5e0b2865 --- /dev/null +++ b/src/tools/rustfmt/tests/target/preserves_carriage_return_for_unix.rs @@ -0,0 +1,2 @@ +// rustfmt-newline_style: Unix +// Foo
Bar diff --git a/src/tools/rustfmt/tests/target/preserves_carriage_return_for_windows.rs b/src/tools/rustfmt/tests/target/preserves_carriage_return_for_windows.rs new file mode 100644 index 000000000..1085360ee --- /dev/null +++ b/src/tools/rustfmt/tests/target/preserves_carriage_return_for_windows.rs @@ -0,0 +1,2 @@ +// rustfmt-newline_style: Windows +// Foo
Bar diff --git a/src/tools/rustfmt/tests/target/pub-restricted.rs b/src/tools/rustfmt/tests/target/pub-restricted.rs new file mode 100644 index 000000000..0e178ef10 --- /dev/null +++ b/src/tools/rustfmt/tests/target/pub-restricted.rs @@ -0,0 +1,51 @@ +pub(super) enum WriteState<D> { + WriteId { + id: U64Writer, + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteSize { + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteData(Writer<D>), +} + +pub(crate) enum WriteState<D> { + WriteId { + id: U64Writer, + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteSize { + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteData(Writer<D>), +} + +pub(in global::path::to::some_mod) enum WriteState<D> { + WriteId { + id: U64Writer, + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteSize { + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteData(Writer<D>), +} + +pub(in local::path::to::some_mod) enum WriteState<D> { + WriteId { + id: U64Writer, + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteSize { + size: U64Writer, + payload: Option<Writer<D>>, + }, + WriteData(Writer<D>), +} diff --git a/src/tools/rustfmt/tests/target/raw_identifiers.rs b/src/tools/rustfmt/tests/target/raw_identifiers.rs new file mode 100644 index 000000000..6ab0fdf05 --- /dev/null +++ b/src/tools/rustfmt/tests/target/raw_identifiers.rs @@ -0,0 +1,66 @@ +#![feature(custom_attribute)] +#![feature(raw_identifiers)] +#![feature(extern_types)] +#![allow(invalid_type_param_default)] +#![allow(unused_attributes)] + +use r#foo as r#alias_foo; + +// https://github.com/rust-lang/rustfmt/issues/3837 +pub(crate) static r#break: &'static str = "foo"; + +fn main() { + #[r#attr] + r#foo::r#bar(); + + let r#local = r#Struct { r#field: () }; + r#local.r#field = 1; + r#foo.r#barr(); + let r#async = r#foo(r#local); + r#macro!(); + + if let r#sub_pat @ r#Foo(_) = r#Foo(3) {} + + match r#async { + r#Foo | r#Bar => r#foo(), + } +} + +fn r#bar<'a, r#T>(r#x: &'a r#T) {} + +mod r#foo { + pub fn r#bar() {} +} + +enum r#Foo { + r#Bar {}, +} + +struct r#Struct { + r#field: r#FieldType, +} + +trait r#Trait { + type r#Type; +} + +impl r#Trait for r#Impl { + type r#Type = r#u32; + fn r#xxx(r#fjio: r#u32) {} +} + +extern "C" { + type r#ccc; + static r#static_val: u32; +} + +macro_rules! r#macro { + () => {}; +} + +macro_rules! foo { + ($x:expr) => { + let r#catch = $x + 1; + println!("{}", r#catch); + }; +} diff --git a/src/tools/rustfmt/tests/target/remove_blank_lines.rs b/src/tools/rustfmt/tests/target/remove_blank_lines.rs new file mode 100644 index 000000000..de74c81ef --- /dev/null +++ b/src/tools/rustfmt/tests/target/remove_blank_lines.rs @@ -0,0 +1,28 @@ +fn main() { + let x = 1; + + let y = 2; + + println!("x + y = {}", x + y); +} + +fn foo() { + #![attribute] + + let x = 1; + + // comment +} +// comment after item + +// comment before item +fn bar() { + let x = 1; + // comment after statement + + // comment before statement + let y = 2; + let z = 3; + + println!("x + y + z = {}", x + y + z); +} diff --git a/src/tools/rustfmt/tests/target/reorder-impl-items.rs b/src/tools/rustfmt/tests/target/reorder-impl-items.rs new file mode 100644 index 000000000..16efff55b --- /dev/null +++ b/src/tools/rustfmt/tests/target/reorder-impl-items.rs @@ -0,0 +1,15 @@ +// rustfmt-reorder_impl_items: true + +// The ordering of the following impl items should be idempotent. +impl<'a> Command<'a> { + pub fn send_to(&self, w: &mut io::Write) -> io::Result<()> { + match self { + &Command::Data(ref c) => c.send_to(w), + &Command::Vrfy(ref c) => c.send_to(w), + } + } + + pub fn parse(arg: &[u8]) -> Result<Command, ParseError> { + nom_to_result(command(arg)) + } +} diff --git a/src/tools/rustfmt/tests/target/should_not_format_string_when_format_strings_is_not_set.rs b/src/tools/rustfmt/tests/target/should_not_format_string_when_format_strings_is_not_set.rs new file mode 100644 index 000000000..efb755d4a --- /dev/null +++ b/src/tools/rustfmt/tests/target/should_not_format_string_when_format_strings_is_not_set.rs @@ -0,0 +1,16 @@ +// format_strings is false by default. + +println!( + "DirEntry {{ \ + binary_name: {:<64}, \ + context_id: {:>2}, \ + file_size: {:>6}, \ + offset: 0x {:>08X}, \ + actual_crc: 0x{:>08X} \ + }}", + dir_entry.binary_name, + dir_entry.context_id, + dir_entry.file_size, + dir_entry.offset, + dir_entry.actual_crc +); diff --git a/src/tools/rustfmt/tests/target/single-line-if-else.rs b/src/tools/rustfmt/tests/target/single-line-if-else.rs new file mode 100644 index 000000000..98fd793cb --- /dev/null +++ b/src/tools/rustfmt/tests/target/single-line-if-else.rs @@ -0,0 +1,58 @@ +// Format if-else expressions on a single line, when possible. + +fn main() { + let a = if 1 > 2 { unreachable!() } else { 10 }; + + let a = if x { + 1 + } else if y { + 2 + } else { + 3 + }; + + let b = if cond() { + 5 + } else { + // Brief comment. + 10 + }; + + let c = if cond() { + statement(); + + 5 + } else { + 10 + }; + + let d = if let Some(val) = turbo { + "cool" + } else { + "beans" + }; + + if cond() { + statement(); + } else { + other_statement(); + } + + if true { + do_something() + } + + let x = if veeeeeeeeery_loooooong_condition() { + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + } else { + bbbbbbbbbb + }; + + let x = if veeeeeeeeery_loooooong_condition() { + aaaaaaaaaaaaaaaaaaaaaaaaa + } else { + bbbbbbbbbb + }; + + funk(if test() { 1 } else { 2 }, arg2); +} diff --git a/src/tools/rustfmt/tests/target/single-line-macro/v1.rs b/src/tools/rustfmt/tests/target/single-line-macro/v1.rs new file mode 100644 index 000000000..a3aa631ed --- /dev/null +++ b/src/tools/rustfmt/tests/target/single-line-macro/v1.rs @@ -0,0 +1,10 @@ +// rustfmt-version: One + +// #2652 +// Preserve trailing comma inside macro, even if it looks an array. +macro_rules! bar { + ($m:ident) => { + $m!([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,]); + $m!([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]); + }; +} diff --git a/src/tools/rustfmt/tests/target/single-line-macro/v2.rs b/src/tools/rustfmt/tests/target/single-line-macro/v2.rs new file mode 100644 index 000000000..9c6bcf33a --- /dev/null +++ b/src/tools/rustfmt/tests/target/single-line-macro/v2.rs @@ -0,0 +1,14 @@ +// rustfmt-version: Two + +// #2652 +// Preserve trailing comma inside macro, even if it looks an array. +macro_rules! bar { + ($m:ident) => { + $m!([ + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, + ]); + $m!([ + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z + ]); + }; +} diff --git a/src/tools/rustfmt/tests/target/skip.rs b/src/tools/rustfmt/tests/target/skip.rs new file mode 100644 index 000000000..6c9737a33 --- /dev/null +++ b/src/tools/rustfmt/tests/target/skip.rs @@ -0,0 +1,87 @@ +// Test the skip attribute works + +#[rustfmt::skip] +fn foo() { badly; formatted; stuff +; } + +#[rustfmt::skip] +trait Foo +{ +fn foo( +); +} + +impl LateLintPass for UsedUnderscoreBinding { + #[cfg_attr(rustfmt, rustfmt::skip)] + fn check_expr() { // comment + } +} + +fn issue1346() { + #[cfg_attr(rustfmt, rustfmt::skip)] + Box::new(self.inner.call(req).then(move |result| { + match result { + Ok(resp) => Box::new(future::done(Ok(resp))), + Err(e) => { + try_error!(clo_stderr, "{}", e); + Box::new(future::err(e)) + } + } + })) +} + +fn skip_on_statements() { + // Outside block + #[rustfmt::skip] + { + foo; bar; + // junk + } + + { + // Inside block + #![rustfmt::skip] + foo; bar; + // junk + } + + // Semi + #[cfg_attr(rustfmt, rustfmt::skip)] + foo( + 1, 2, 3, 4, + 1, 2, + 1, 2, 3, + ); + + // Local + #[cfg_attr(rustfmt, rustfmt::skip)] + let x = foo( a, b , c); + + // Item + #[cfg_attr(rustfmt, rustfmt::skip)] + use foobar; + + // Mac + #[cfg_attr(rustfmt, rustfmt::skip)] + vec![ + 1, 2, 3, 4, + 1, 2, 3, 4, + 1, 2, 3, 4, + 1, 2, 3, + 1, + 1, 2, + 1, + ]; + + // Expr + #[cfg_attr(rustfmt, rustfmt::skip)] + foo( a, b , c) +} + +// Check that the skip attribute applies to other attributes. +#[rustfmt::skip] +#[cfg +( a , b +)] +fn +main() {} diff --git a/src/tools/rustfmt/tests/target/skip/foo.rs b/src/tools/rustfmt/tests/target/skip/foo.rs new file mode 100644 index 000000000..776658f8f --- /dev/null +++ b/src/tools/rustfmt/tests/target/skip/foo.rs @@ -0,0 +1,5 @@ +#![rustfmt::skip] + +fn +foo() +{} diff --git a/src/tools/rustfmt/tests/target/skip/main.rs b/src/tools/rustfmt/tests/target/skip/main.rs new file mode 100644 index 000000000..2d33bef92 --- /dev/null +++ b/src/tools/rustfmt/tests/target/skip/main.rs @@ -0,0 +1,5 @@ +mod foo; + +fn main() { + println!("Hello, world!"); +} diff --git a/src/tools/rustfmt/tests/target/skip/preserve_trailing_comment.rs b/src/tools/rustfmt/tests/target/skip/preserve_trailing_comment.rs new file mode 100644 index 000000000..f85de3325 --- /dev/null +++ b/src/tools/rustfmt/tests/target/skip/preserve_trailing_comment.rs @@ -0,0 +1,7 @@ +#![rustfmt::skip] + +fn main() { + println!("Hello, world!"); +} + +// Trailing Comment diff --git a/src/tools/rustfmt/tests/target/skip_mod.rs b/src/tools/rustfmt/tests/target/skip_mod.rs new file mode 100644 index 000000000..d770ab349 --- /dev/null +++ b/src/tools/rustfmt/tests/target/skip_mod.rs @@ -0,0 +1,3 @@ +#![rustfmt::skip] +use a :: b +; diff --git a/src/tools/rustfmt/tests/target/soft-wrapping.rs b/src/tools/rustfmt/tests/target/soft-wrapping.rs new file mode 100644 index 000000000..5b4c6d9e8 --- /dev/null +++ b/src/tools/rustfmt/tests/target/soft-wrapping.rs @@ -0,0 +1,15 @@ +// rustfmt-wrap_comments: true +// rustfmt-max_width: 80 +// Soft wrapping for comments. + +// #535, soft wrapping for comments +// Compare the lowest `f32` of both inputs for greater than or equal. The +// lowest 32 bits of the result will be `0xffffffff` if `a.extract(0)` is +// ggreater than or equal `b.extract(0)`, or `0` otherwise. The upper 96 bits +// off the result are the upper 96 bits of `a`. + +/// Compares the lowest `f32` of both inputs for greater than or equal. The +/// lowest 32 bits of the result will be `0xffffffff` if `a.extract(0)` is +/// greater than or equal `b.extract(0)`, or `0` otherwise. The upper 96 bits +/// off the result are the upper 96 bits of `a`. +fn foo() {} diff --git a/src/tools/rustfmt/tests/target/space-not-before-newline.rs b/src/tools/rustfmt/tests/target/space-not-before-newline.rs new file mode 100644 index 000000000..9d75b726a --- /dev/null +++ b/src/tools/rustfmt/tests/target/space-not-before-newline.rs @@ -0,0 +1,8 @@ +struct Foo { + a: (), + // spaces ^^^ to be removed +} +enum Foo { + Bar, + // spaces ^^^ to be removed +} diff --git a/src/tools/rustfmt/tests/target/spaces-around-ranges.rs b/src/tools/rustfmt/tests/target/spaces-around-ranges.rs new file mode 100644 index 000000000..b53e5b58b --- /dev/null +++ b/src/tools/rustfmt/tests/target/spaces-around-ranges.rs @@ -0,0 +1,15 @@ +// rustfmt-spaces_around_ranges: true + +fn bar(v: &[u8]) {} + +fn foo() { + let a = vec![0; 20]; + for j in 0 ..= 20 { + for i in 0 .. 3 { + bar(a[i .. j]); + bar(a[i ..]); + bar(a[.. j]); + bar(a[..= (j + 1)]); + } + } +} diff --git a/src/tools/rustfmt/tests/target/statements.rs b/src/tools/rustfmt/tests/target/statements.rs new file mode 100644 index 000000000..c1e7dc464 --- /dev/null +++ b/src/tools/rustfmt/tests/target/statements.rs @@ -0,0 +1,42 @@ +// FIXME(calebcartwright) - Hopefully one day we can +// elide these redundant semis like we do in other contexts. +fn redundant_item_semis() { + impl Foo { + fn get(&self) -> usize { + 5 + } + }; + + impl Bar { + fn get(&self) -> usize { + 5 + } + } /*asdfsf*/ + ; + + impl Baz { + fn get(&self) -> usize { + 5 + } + } /*asdfsf*/ + + // why would someone do this + ; + + impl Qux { + fn get(&self) -> usize { + 5 + } + } + + // why + ; + + impl Lorem { + fn get(&self) -> usize { + 5 + } + } + // oh why + ; +} diff --git a/src/tools/rustfmt/tests/target/static.rs b/src/tools/rustfmt/tests/target/static.rs new file mode 100644 index 000000000..5daccf3e7 --- /dev/null +++ b/src/tools/rustfmt/tests/target/static.rs @@ -0,0 +1,27 @@ +const FILE_GENERIC_READ: DWORD = + STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE; + +static boolnames: &'static [&'static str] = &[ + "bw", "am", "xsb", "xhp", "xenl", "eo", "gn", "hc", "km", "hs", "in", "db", "da", "mir", + "msgr", "os", "eslok", "xt", "hz", "ul", "xon", "nxon", "mc5i", "chts", "nrrmc", "npc", + "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy", "xvpa", "sam", "cpix", "lpix", "OTbs", + "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr", +]; + +static mut name: SomeType = + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +pub static count: u8 = 10; + +pub const test: &Type = &val; + +impl Color { + pub const WHITE: u32 = 10; +} + +// #1391 +pub const XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: NTSTATUS = + 0 as usize; + +pub const XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: + Yyyyyyyyyyyyyyyyyyyyyyyyyyyy = 1; diff --git a/src/tools/rustfmt/tests/target/string-lit-2.rs b/src/tools/rustfmt/tests/target/string-lit-2.rs new file mode 100644 index 000000000..6b95e25a0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/string-lit-2.rs @@ -0,0 +1,25 @@ +fn main() -> &'static str { + let too_many_lines = "Hello"; + let leave_me = "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss\ + s + jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"; +} + +fn issue_1237() { + let msg = "eedadn\n\ + drvtee\n\ + eandsr\n\ + raavrd\n\ + atevrs\n\ + tsrnev\n\ + sdttsa\n\ + rasrtv\n\ + nssdts\n\ + ntnada\n\ + svetve\n\ + tesnvt\n\ + vntsnd\n\ + vrdear\n\ + dvrsen\n\ + enarar"; +} diff --git a/src/tools/rustfmt/tests/target/string-lit-custom.rs b/src/tools/rustfmt/tests/target/string-lit-custom.rs new file mode 100644 index 000000000..89639b8eb --- /dev/null +++ b/src/tools/rustfmt/tests/target/string-lit-custom.rs @@ -0,0 +1,20 @@ +fn main() { + let expected = "; ModuleID = \'foo\' + +; Function Attrs: nounwind +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0 + +declare i32 @write(i32, i8*, i32) + +declare i32 @putchar(i32) + +declare i32 @getchar() + +define i32 @main() { +entry: + ret i32 0 +} + +attributes #0 = { nounwind } +"; +} diff --git a/src/tools/rustfmt/tests/target/string-lit.rs b/src/tools/rustfmt/tests/target/string-lit.rs new file mode 100644 index 000000000..2d3306107 --- /dev/null +++ b/src/tools/rustfmt/tests/target/string-lit.rs @@ -0,0 +1,63 @@ +// rustfmt-format_strings: true +// Long string literals + +fn main() -> &'static str { + let str = "AAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAaAA \ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAa"; + let str = "AAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAa"; + let str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + let too_many_lines = "Hello"; + + // Make sure we don't break after an escape character. + let odd_length_name = + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; + let even_length_name = + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; + + let really_long_variable_name = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + let raw_string = r#"Do +not +remove +formatting"#; + + filename.replace(" ", "\\"); + + let xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = + funktion("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"); + + let unicode = "a̐éö̲\r\n"; + let unicode2 = "Löwe 老虎 Léopard"; + let unicode3 = "中华Việt Nam"; + let unicode4 = "☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃"; + + "stuffin'" +} + +fn issue682() { + let a = "hello \\ o/"; + let b = a.replace("\\ ", "\\"); +} + +fn issue716() { + println!( + "forall x. mult(e(), x) = x /\\ + forall x. mult(x, x) = e()" + ); +} + +fn issue_1282() { + { + match foo { + Permission::AndroidPermissionAccessLocationExtraCommands => { + "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" + } + } + } +} + +// #1987 +#[link_args = "-s NO_FILESYSTEM=1 -s NO_EXIT_RUNTIME=1 -s EXPORTED_RUNTIME_METHODS=[\"_malloc\"] \ + -s NO_DYNAMIC_EXECUTION=1 -s ELIMINATE_DUPLICATE_FUNCTIONS=1 -s EVAL_CTORS=1"] +extern "C" {} diff --git a/src/tools/rustfmt/tests/target/string_punctuation.rs b/src/tools/rustfmt/tests/target/string_punctuation.rs new file mode 100644 index 000000000..0b8ec1b7f --- /dev/null +++ b/src/tools/rustfmt/tests/target/string_punctuation.rs @@ -0,0 +1,24 @@ +// rustfmt-format_strings: true + +fn main() { + println!( + "ThisIsAReallyLongStringWithNoSpaces.It_should_prefer_to_break_onpunctuation:\ + Likethisssssssssssss" + ); + format!("{}__{}__{}ItShouldOnlyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyNoticeSemicolonsPeriodsColonsAndCommasAndResortToMid-CharBreaksAfterPunctuation{}{}",x,y,z,a,b); + println!( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaalhijalfhiigjapdighjapdigjapdighdapighapdighpaidhg;\ + adopgihadoguaadbadgad,qeoihapethae8t0aet8haetadbjtaeg;\ + ooeouthaoeutgadlgajduabgoiuadogabudogubaodugbadgadgadga;adoughaoeugbaouea" + ); + println!( + "sentuhaesnuthaesnutheasunteahusnaethuseantuihaesntdiastnidaetnuhaideuhsenathe。\ + WeShouldSupportNonAsciiPunctuations§\ + ensuhatheasunteahsuneathusneathuasnuhaesnuhaesnuaethusnaetuheasnuth" + ); + println!( + "ThisIsASampleOfCJKString.祇園精舍の鐘の声、諸行無常の響きあり。娑羅双樹の花の色、\ + 盛者必衰の理をあらはす。奢れる人も久しからず、ただ春の夜の夢のごとし。\ + 猛き者もつひにはほろびぬ、ひとへに風の前の塵に同じ。" + ); +} diff --git a/src/tools/rustfmt/tests/target/struct-field-attributes.rs b/src/tools/rustfmt/tests/target/struct-field-attributes.rs new file mode 100644 index 000000000..0f461b98b --- /dev/null +++ b/src/tools/rustfmt/tests/target/struct-field-attributes.rs @@ -0,0 +1,62 @@ +// #1535 +#![feature(struct_field_attributes)] + +struct Foo { + bar: u64, + + #[cfg(test)] + qux: u64, +} + +fn do_something() -> Foo { + Foo { + bar: 0, + + #[cfg(test)] + qux: 1, + } +} + +fn main() { + do_something(); +} + +// #1462 +struct Foo { + foo: usize, + #[cfg(feature = "include-bar")] + bar: usize, +} + +fn new_foo() -> Foo { + Foo { + foo: 0, + #[cfg(feature = "include-bar")] + bar: 0, + } +} + +// #2044 +pub enum State { + Closure( + #[cfg_attr( + feature = "serde_derive", + serde(state_with = "::serialization::closure") + )] + GcPtr<ClosureData>, + ), +} + +struct Fields( + #[cfg_attr( + feature = "serde_derive", + serde(state_with = "::base::serialization::shared") + )] + Arc<Vec<InternedStr>>, +); + +// #2309 +pub struct A { + #[doc = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"] + pub foos: Vec<bool>, +} diff --git a/src/tools/rustfmt/tests/target/struct_field_doc_comment.rs b/src/tools/rustfmt/tests/target/struct_field_doc_comment.rs new file mode 100644 index 000000000..ebb01a668 --- /dev/null +++ b/src/tools/rustfmt/tests/target/struct_field_doc_comment.rs @@ -0,0 +1,69 @@ +// #5215 +struct MyTuple( + /// Doc Comments + /* TODO note to add more to Doc Comments */ + u32, + /// Doc Comments + // TODO note + u64, +); + +struct MyTuple( + #[cfg(unix)] // some comment + u64, + #[cfg(not(unix))] /*block comment */ u32, +); + +struct MyTuple( + #[cfg(unix)] + // some comment + u64, + #[cfg(not(unix))] + /*block comment */ + u32, +); + +struct MyTuple( + #[cfg(unix)] // some comment + pub u64, + #[cfg(not(unix))] /*block comment */ pub(crate) u32, +); + +struct MyTuple( + /// Doc Comments + /* TODO note to add more to Doc Comments */ + pub u32, + /// Doc Comments + // TODO note + pub(crate) u64, +); + +struct MyStruct { + #[cfg(unix)] // some comment + a: u64, + #[cfg(not(unix))] /*block comment */ b: u32, +} + +struct MyStruct { + #[cfg(unix)] // some comment + pub a: u64, + #[cfg(not(unix))] /*block comment */ pub(crate) b: u32, +} + +struct MyStruct { + /// Doc Comments + /* TODO note to add more to Doc Comments */ + a: u32, + /// Doc Comments + // TODO note + b: u64, +} + +struct MyStruct { + /// Doc Comments + /* TODO note to add more to Doc Comments */ + pub a: u32, + /// Doc Comments + // TODO note + pub(crate) b: u64, +} diff --git a/src/tools/rustfmt/tests/target/struct_lits.rs b/src/tools/rustfmt/tests/target/struct_lits.rs new file mode 100644 index 000000000..d3bc364c3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/struct_lits.rs @@ -0,0 +1,190 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// Struct literal expressions. + +fn main() { + let x = Bar; + + // Comment + let y = Foo { a: x }; + + Foo { + a: foo(), // comment + // comment + b: bar(), + ..something + }; + + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: f(), b: b() }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + a: f(), + b: b(), + }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + // Comment + a: foo(), // Comment + // Comment + b: bar(), // Comment + }; + + Foo { a: Bar, b: f() }; + + Quux { + x: if cond { + bar(); + }, + y: baz(), + }; + + A { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit + // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. + // Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item, + }; + + Some(Data::MethodCallData(MethodCallData { + span: sub_span.unwrap(), + scope: self.enclosing_scope(id), + ref_id: def_id, + decl_id: Some(decl_id), + })); + + Diagram { + // o This graph demonstrates how + // / \ significant whitespace is + // o o preserved. + // /|\ \ + // o o o o + graph: G, + } +} + +fn matcher() { + TagTerminatedByteMatcher { + matcher: ByteMatcher { + pattern: b"<HTML", + mask: b"\xFF\xDF\xDF\xDF\xDF\xFF", + }, + }; +} + +fn issue177() { + struct Foo<T> { + memb: T, + } + let foo = Foo::<i64> { memb: 10 }; +} + +fn issue201() { + let s = S { a: 0, ..b }; +} + +fn issue201_2() { + let s = S { a: S2 { ..c }, ..b }; +} + +fn issue278() { + let s = S { + a: 0, + // + b: 0, + }; + let s1 = S { + a: 0, + // foo + // + // bar + b: 0, + }; +} + +fn struct_exprs() { + Foo { a: 1, b: f(2) }; + Foo { + a: 1, + b: f(2), + ..g(3) + }; + LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongStruct { + ..base + }; + IntrinsicISizesContribution { + content_intrinsic_sizes: IntrinsicISizes { + minimum_inline_size: 0, + }, + }; +} + +fn issue123() { + Foo { a: b, c: d, e: f }; + + Foo { + a: bb, + c: dd, + e: ff, + }; + + Foo { + a: ddddddddddddddddddddd, + b: cccccccccccccccccccccccccccccccccccccc, + }; +} + +fn issue491() { + Foo { + guard: None, + arm: 0, // Comment + }; + + Foo { + arm: 0, // Comment + }; + + Foo { + a: aaaaaaaaaa, + b: bbbbbbbb, + c: cccccccccc, + d: dddddddddd, // a comment + e: eeeeeeeee, + }; +} + +fn issue698() { + Record { + ffffffffffffffffffffffffffields: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + }; + Record { + ffffffffffffffffffffffffffields: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + } +} + +fn issue835() { + MyStruct {}; + MyStruct { /* a comment */ }; + MyStruct { + // Another comment + }; + MyStruct {} +} + +fn field_init_shorthand() { + MyStruct { x, y, z }; + MyStruct { x, y, z, ..base }; + Foo { + aaaaaaaaaa, + bbbbbbbb, + cccccccccc, + dddddddddd, // a comment + eeeeeeeee, + }; + Record { + ffffffffffffffffffffffffffieldsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + }; +} diff --git a/src/tools/rustfmt/tests/target/struct_lits_multiline.rs b/src/tools/rustfmt/tests/target/struct_lits_multiline.rs new file mode 100644 index 000000000..b29aafd05 --- /dev/null +++ b/src/tools/rustfmt/tests/target/struct_lits_multiline.rs @@ -0,0 +1,117 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-struct_lit_single_line: false + +// Struct literal expressions. + +fn main() { + let x = Bar; + + // Comment + let y = Foo { + a: x, + }; + + Foo { + a: foo(), // comment + // comment + b: bar(), + ..something + }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + a: foo(), + b: bar(), + }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + a: foo(), + b: bar(), + }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { + // Comment + a: foo(), // Comment + // Comment + b: bar(), // Comment + }; + + Foo { + a: Bar, + b: foo(), + }; + + Quux { + x: if cond { + bar(); + }, + y: baz(), + }; + + A { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit + // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. + // Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item, + }; + + Some(Data::MethodCallData(MethodCallData { + span: sub_span.unwrap(), + scope: self.enclosing_scope(id), + ref_id: def_id, + decl_id: Some(decl_id), + })); + + Diagram { + // o This graph demonstrates how + // / \ significant whitespace is + // o o preserved. + // /|\ \ + // o o o o + graph: G, + } +} + +fn matcher() { + TagTerminatedByteMatcher { + matcher: ByteMatcher { + pattern: b"<HTML", + mask: b"\xFF\xDF\xDF\xDF\xDF\xFF", + }, + }; +} + +fn issue177() { + struct Foo<T> { + memb: T, + } + let foo = Foo::<i64> { + memb: 10, + }; +} + +fn issue201() { + let s = S { + a: 0, + ..b + }; +} + +fn issue201_2() { + let s = S { + a: S2 { + ..c + }, + ..b + }; +} + +fn issue491() { + Foo { + guard: None, + arm: 0, // Comment + }; +} diff --git a/src/tools/rustfmt/tests/target/struct_lits_visual.rs b/src/tools/rustfmt/tests/target/struct_lits_visual.rs new file mode 100644 index 000000000..a9627fb90 --- /dev/null +++ b/src/tools/rustfmt/tests/target/struct_lits_visual.rs @@ -0,0 +1,49 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-indent_style: Visual + +// Struct literal expressions. + +fn main() { + let x = Bar; + + // Comment + let y = Foo { a: x }; + + Foo { a: foo(), // comment + // comment + b: bar(), + ..something }; + + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: f(), b: b() }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { // Comment + a: foo(), /* Comment */ + // Comment + b: bar() /* Comment */ }; + + Foo { a: Bar, b: f() }; + + Quux { x: if cond { + bar(); + }, + y: baz() }; + + Baz { x: yxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + z: zzzzz /* test */ }; + + A { // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit + // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante + // hendrerit. Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item }; + + Diagram { // o This graph demonstrates how + // / \ significant whitespace is + // o o preserved. + // /|\ \ + // o o o o + graph: G } +} diff --git a/src/tools/rustfmt/tests/target/struct_lits_visual_multiline.rs b/src/tools/rustfmt/tests/target/struct_lits_visual_multiline.rs new file mode 100644 index 000000000..3f43ef0c9 --- /dev/null +++ b/src/tools/rustfmt/tests/target/struct_lits_visual_multiline.rs @@ -0,0 +1,49 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-indent_style: Visual +// rustfmt-struct_lit_single_line: false + +// Struct literal expressions. + +fn main() { + let x = Bar; + + // Comment + let y = Foo { a: x }; + + Foo { a: foo(), // comment + // comment + b: bar(), + ..something }; + + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(), + b: bar() }; + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { // Comment + a: foo(), /* Comment */ + // Comment + b: bar() /* Comment */ }; + + Foo { a: Bar, + b: foo() }; + + Quux { x: if cond { + bar(); + }, + y: baz() }; + + A { // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit + // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante + // hendrerit. Donec et mollis dolor. + first: item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + second: Item }; + + Diagram { // o This graph demonstrates how + // / \ significant whitespace is + // o o preserved. + // /|\ \ + // o o o o + graph: G } +} diff --git a/src/tools/rustfmt/tests/target/struct_tuple_visual.rs b/src/tools/rustfmt/tests/target/struct_tuple_visual.rs new file mode 100644 index 000000000..f95f3fe4f --- /dev/null +++ b/src/tools/rustfmt/tests/target/struct_tuple_visual.rs @@ -0,0 +1,36 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true +// rustfmt-indent_style: Visual +fn foo() { + Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(f(), b()); + + Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(// Comment + foo(), /* Comment */ + // Comment + bar() /* Comment */); + + Foo(Bar, f()); + + Quux(if cond { + bar(); + }, + baz()); + + Baz(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + zzzzz /* test */); + + A(// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit + // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante + // hendrerit. Donec et mollis dolor. + item(), + // Praesent et diam eget libero egestas mattis sit amet vitae augue. + // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. + Item); + + Diagram(// o This graph demonstrates how + // / \ significant whitespace is + // o o preserved. + // /|\ \ + // o o o o + G) +} diff --git a/src/tools/rustfmt/tests/target/structs.rs b/src/tools/rustfmt/tests/target/structs.rs new file mode 100644 index 000000000..4948e37a5 --- /dev/null +++ b/src/tools/rustfmt/tests/target/structs.rs @@ -0,0 +1,358 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +/// A Doc comment +#[AnAttribute] +pub struct Foo { + #[rustfmt::skip] + f : SomeType, // Comment beside a field + f: SomeType, // Comment beside a field + // Comment on a field + #[AnAttribute] + g: SomeOtherType, + /// A doc comment on a field + h: AThirdType, + pub i: TypeForPublicField, +} + +// Destructuring +fn foo() { + S { x: 5, .. }; + Struct { .. } = Struct { a: 1, b: 4 }; + Struct { a, .. } = Struct { a: 1, b: 2, c: 3 }; + TupleStruct(a, .., b) = TupleStruct(1, 2); + TupleStruct(..) = TupleStruct(3, 4); + TupleStruct( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + .., + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + ) = TupleStruct(1, 2); +} + +// #1095 +struct S<T /* comment */> { + t: T, +} + +// #1029 +pub struct Foo { + #[doc(hidden)] + // This will NOT get deleted! + bar: String, // hi +} + +// #1029 +struct X { + // `x` is an important number. + #[allow(unused)] // TODO: use + x: u32, +} + +// #410 +#[allow(missing_docs)] +pub struct Writebatch<K: Key> { + #[allow(dead_code)] // only used for holding the internal pointer + writebatch: RawWritebatch, + marker: PhantomData<K>, +} + +struct Bar; + +struct NewType(Type, OtherType); + +struct NewInt<T: Copy>( + pub i32, + SomeType, // inline comment + T, // sup +); + +struct Qux< + 'a, + N: Clone + 'a, + E: Clone + 'a, + G: Labeller<'a, N, E> + GraphWalk<'a, N, E>, + W: Write + Copy, +>( + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // Comment + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, + #[AnAttr] + // Comment + /// Testdoc + G, + pub W, +); + +struct Tuple( + // Comment 1 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, + // Comment 2 + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, +); + +// With a where-clause and generics. +pub struct Foo<'a, Y: Baz> +where + X: Whatever, +{ + f: SomeType, // Comment beside a field +} + +struct Baz { + a: A, // Comment A + b: B, // Comment B + c: C, // Comment C +} + +struct Baz { + a: A, // Comment A + + b: B, // Comment B + + c: C, // Comment C +} + +struct Baz { + a: A, + + b: B, + c: C, + + d: D, +} + +struct Baz { + // Comment A + a: A, + + // Comment B + b: B, + // Comment C + c: C, +} + +// Will this be a one-liner? +struct Tuple( + A, // Comment + B, +); + +pub struct State<F: FnMut() -> time::Timespec> { + now: F, +} + +pub struct State<F: FnMut() -> ()> { + now: F, +} + +pub struct State<F: FnMut()> { + now: F, +} + +struct Palette { + /// A map of indices in the palette to a count of pixels in approximately + /// that color + foo: i32, +} + +// Splitting a single line comment into a block previously had a misalignment +// when the field had attributes +struct FieldsWithAttributes { + // Pre Comment + #[rustfmt::skip] pub host:String, /* Post comment BBBBBBBBBBBBBB BBBBBBBBBBBBBBBB + * BBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBB BBBBBBBBBBB */ + // Another pre comment + #[attr1] + #[attr2] + pub id: usize, /* CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCC + * CCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCC CCCCCCCCCCCC */ +} + +struct Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: + node::Handle<IdRef<'id, Node<K, V>>, Type, NodeType>, +} + +struct Foo<T>(T); +struct Foo<T>(T) +where + T: Copy, + T: Eq; +struct Foo<T>( + TTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUUUU, + TTTTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUU, +); +struct Foo<T>( + TTTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUUUU, + TTTTTTTTTTTTTTTTTTT, +) +where + T: PartialEq; +struct Foo<T>( + TTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUUUU, + TTTTTTTTTTTTTTTTTTTTT, +) +where + T: PartialEq; +struct Foo<T>( + TTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUUUUUU, + TTTTTTTTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUU, +) +where + T: PartialEq; +struct Foo<T>( + TTTTTTTTTTTTTTTTT, // Foo + UUUUUUUUUUUUUUUUUUUUUUUU, // Bar + // Baz + TTTTTTTTTTTTTTTTTTT, + // Qux (FIXME #572 - doc comment) + UUUUUUUUUUUUUUUUUUU, +); + +mod m { + struct X<T> + where + T: Sized, + { + a: T, + } +} + +struct Foo<T>( + TTTTTTTTTTTTTTTTTTT, + /// Qux + UUUUUUUUUUUUUUUUUUU, +); + +struct Issue677 { + pub ptr: *const libc::c_void, + pub trace: fn(obj: *const libc::c_void, tracer: *mut JSTracer), +} + +struct Foo {} +struct Foo {} +struct Foo { + // comment +} +struct Foo { + // trailing space -> +} +struct Foo { + // comment +} +struct Foo( + // comment +); + +struct LongStruct { + a: A, + the_quick_brown_fox_jumps_over_the_lazy_dog: + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +} + +struct Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: + node::Handle<IdRef<'id, Node<Key, Value>>, Type, NodeType>, +} + +struct Foo<C = ()>(String); + +// #1364 +fn foo() { + convex_shape.set_point(0, &Vector2f { x: 400.0, y: 100.0 }); + convex_shape.set_point(1, &Vector2f { x: 500.0, y: 70.0 }); + convex_shape.set_point(2, &Vector2f { x: 450.0, y: 100.0 }); + convex_shape.set_point(3, &Vector2f { x: 580.0, y: 150.0 }); +} + +// Vertical alignment +struct Foo { + aaaaa: u32, // a + + b: u32, // b + cc: u32, // cc + + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 1 + yy: u32, // comment2 + zzz: u32, // comment3 + + aaaaaa: u32, // comment4 + bb: u32, // comment5 + // separate + dd: u32, // comment7 + c: u32, // comment6 + + aaaaaaa: u32, /* multi + * line + * comment + */ + b: u32, // hi + + do_not_push_this_comment1: u32, // comment1 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + please_do_not_push_this_comment3: u32, // comment3 + + do_not_push_this_comment1: u32, // comment1 + // separate + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + please_do_not_push_this_comment3: u32, // comment3 + + do_not_push_this_comment1: u32, // comment1 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + // separate + please_do_not_push_this_comment3: u32, // comment3 +} + +// structs with long identifier +struct Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +{} +struct Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +{} +struct Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +{} +struct Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +{ + x: i32, +} + +// structs with visibility, do not duplicate visibility (#2110). +pub(self) struct Foo {} +pub(super) struct Foo {} +pub(crate) struct Foo {} +pub(self) struct Foo(); +pub(super) struct Foo(); +pub(crate) struct Foo(); + +// #2125 +pub struct ReadinessCheckRegistry( + Mutex<HashMap<Arc<String>, Box<Fn() -> ReadinessCheck + Sync + Send>>>, +); + +// #2144 unit struct with generics +struct MyBox<T: ?Sized>; +struct MyBoxx<T, S> +where + T: ?Sized, + S: Clone; + +// #2208 +struct Test { + /// foo + #[serde(default)] + pub join: Vec<String>, + #[serde(default)] + pub tls: bool, +} + +// #2818 +struct Paren((i32)) +where + i32: Trait; +struct Parens((i32, i32)) +where + i32: Trait; diff --git a/src/tools/rustfmt/tests/target/trailing-comma-never.rs b/src/tools/rustfmt/tests/target/trailing-comma-never.rs new file mode 100644 index 000000000..ea199f5ff --- /dev/null +++ b/src/tools/rustfmt/tests/target/trailing-comma-never.rs @@ -0,0 +1,35 @@ +// rustfmt-trailing_comma: Never + +enum X { + A, + B +} + +enum Y { + A, + B +} + +enum TupX { + A(u32), + B(i32, u16) +} + +enum TupY { + A(u32), + B(i32, u16) +} + +enum StructX { + A { s: u16 }, + B { u: u32, i: i32 } +} + +enum StructY { + A { s: u16 }, + B { u: u32, i: i32 } +} + +static XXX: [i8; 64] = [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +]; diff --git a/src/tools/rustfmt/tests/target/trailing_commas.rs b/src/tools/rustfmt/tests/target/trailing_commas.rs new file mode 100644 index 000000000..06f0a13b1 --- /dev/null +++ b/src/tools/rustfmt/tests/target/trailing_commas.rs @@ -0,0 +1,78 @@ +// rustfmt-match_block_trailing_comma: true +// rustfmt-trailing_comma: Always + +fn main() { + match foo { + x => {}, + y => { + foo(); + }, + _ => x, + } +} + +fn f<S, T,>(x: T, y: S,) -> T +where + T: P, + S: Q, +{ + x +} + +impl Trait for T +where + T: P, +{ + fn f(x: T,) -> T + where + T: Q + R, + { + x + } +} + +struct Pair<S, T,> +where + T: P, + S: P + Q, +{ + a: T, + b: S, +} + +struct TupPair<S, T,>(S, T,) +where + T: P, + S: P + Q; + +enum E<S, T,> +where + S: P, + T: P, +{ + A { a: T, }, +} + +type Double<T,> +where + T: P, + T: Q, += Pair<T, T,>; + +extern "C" { + fn f<S, T,>(x: T, y: S,) -> T + where + T: P, + S: Q; +} + +trait Q<S, T,> +where + T: P, + S: R, +{ + fn f<U, V,>(self, x: T, y: S, z: U,) -> Self + where + U: P, + V: P; +} diff --git a/src/tools/rustfmt/tests/target/trailing_comments/hard_tabs.rs b/src/tools/rustfmt/tests/target/trailing_comments/hard_tabs.rs new file mode 100644 index 000000000..35e72f1af --- /dev/null +++ b/src/tools/rustfmt/tests/target/trailing_comments/hard_tabs.rs @@ -0,0 +1,30 @@ +// rustfmt-version: Two +// rustfmt-wrap_comments: true +// rustfmt-hard_tabs: true + +impl Foo { + fn foo() { + bar(); // comment 1 + // comment 2 + // comment 3 + baz(); + } +} + +fn lorem_ipsum() { + let f = bar(); // Donec consequat mi. Quisque vitae dolor. Integer lobortis. Maecenas id nulla. Lorem. + // Id turpis. Nam posuere lectus vitae nibh. Etiam tortor orci, sagittis + // malesuada, rhoncus quis, hendrerit eget, libero. Quisque commodo nulla at + // nunc. Mauris consequat, enim vitae venenatis sollicitudin, dolor orci + // bibendum enim, a sagittis nulla nunc quis elit. Phasellus augue. Nunc + // suscipit, magna tincidunt lacinia faucibus, lacus tellus ornare purus, a + // pulvinar lacus orci eget nibh. Maecenas sed nibh non lacus tempor faucibus. + // In hac habitasse platea dictumst. Vivamus a orci at nulla tristique + // condimentum. Donec arcu quam, dictum accumsan, convallis accumsan, cursus sit + // amet, ipsum. In pharetra sagittis nunc. + let b = baz(); + + let normalized = self.ctfont.all_traits().normalized_weight(); // [-1.0, 1.0] + // TODO(emilio): It may make sense to make this range [.01, 10.0], to align + // with css-fonts-4's range of [1, 1000]. +} diff --git a/src/tools/rustfmt/tests/target/trailing_comments/soft_tabs.rs b/src/tools/rustfmt/tests/target/trailing_comments/soft_tabs.rs new file mode 100644 index 000000000..eba943042 --- /dev/null +++ b/src/tools/rustfmt/tests/target/trailing_comments/soft_tabs.rs @@ -0,0 +1,30 @@ +// rustfmt-version: Two +// rustfmt-wrap_comments: true + +pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast +// Multicast using broadcst. add. + +pub const SQ_CRETAB: u16 = 0x000e; // CREATE TABLE +pub const SQ_DRPTAB: u16 = 0x000f; // DROP TABLE +pub const SQ_CREIDX: u16 = 0x0010; // CREATE INDEX +//const SQ_DRPIDX: u16 = 0x0011; // DROP INDEX +//const SQ_GRANT: u16 = 0x0012; // GRANT +//const SQ_REVOKE: u16 = 0x0013; // REVOKE + +fn foo() { + let f = bar(); // Donec consequat mi. Quisque vitae dolor. Integer lobortis. Maecenas id nulla. Lorem. + // Id turpis. Nam posuere lectus vitae nibh. Etiam tortor orci, sagittis + // malesuada, rhoncus quis, hendrerit eget, libero. Quisque commodo nulla at + // nunc. Mauris consequat, enim vitae venenatis sollicitudin, dolor orci + // bibendum enim, a sagittis nulla nunc quis elit. Phasellus augue. Nunc + // suscipit, magna tincidunt lacinia faucibus, lacus tellus ornare purus, a + // pulvinar lacus orci eget nibh. Maecenas sed nibh non lacus tempor faucibus. + // In hac habitasse platea dictumst. Vivamus a orci at nulla tristique + // condimentum. Donec arcu quam, dictum accumsan, convallis accumsan, cursus sit + // amet, ipsum. In pharetra sagittis nunc. + let b = baz(); + + let normalized = self.ctfont.all_traits().normalized_weight(); // [-1.0, 1.0] + // TODO(emilio): It may make sense to make this range [.01, 10.0], to align + // with css-fonts-4's range of [1, 1000]. +} diff --git a/src/tools/rustfmt/tests/target/trait.rs b/src/tools/rustfmt/tests/target/trait.rs new file mode 100644 index 000000000..7f067991b --- /dev/null +++ b/src/tools/rustfmt/tests/target/trait.rs @@ -0,0 +1,220 @@ +// Test traits + +trait Foo { + fn bar(x: i32) -> Baz<U> { + Baz::new() + } + + fn baz(a: AAAAAAAAAAAAAAAAAAAAAA, b: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB) -> RetType; + + fn foo( + a: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // Another comment + b: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, + ) -> RetType; // Some comment + + fn baz(&mut self) -> i32; + + fn increment(&mut self, x: i32); + + fn read(&mut self, x: BufReader<R> /* Used to be MemReader */) + where + R: Read; +} + +pub trait WriteMessage { + fn write_message(&mut self, &FrontendMessage) -> io::Result<()>; +} + +trait Runnable { + fn handler(self: &Runnable); +} + +trait TraitWithExpr { + fn fn_with_expr(x: [i32; 1]); +} + +trait Test { + fn read_struct<T, F>(&mut self, s_name: &str, len: usize, f: F) -> Result<T, Self::Error> + where + F: FnOnce(&mut Self) -> Result<T, Self::Error>; +} + +trait T {} + +trait Foo { + type Bar: Baz; + type Inner: Foo = Box<Foo>; +} + +trait ConstCheck<T>: Foo +where + T: Baz, +{ + const J: i32; +} + +trait Tttttttttttttttttttttttttttttttttttttttttttttttttttttttttt<T> +where + T: Foo, +{ +} + +trait Ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt<T> +where + T: Foo, +{ +} + +trait FooBar<T>: Tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt +where + J: Bar, +{ + fn test(); +} + +trait WhereList<T, J> +where + T: Foo, + J: Bar, +{ +} + +trait X /* comment */ {} +trait Y // comment +{ +} + +// #2055 +pub trait Foo: +// A and C +A + C +// and B + + B +{} + +// #2158 +trait Foo { + type ItRev = <MergingUntypedTimeSeries<SliceSeries<SliceWindow>> as UntypedTimeSeries>::IterRev; + type IteRev = + <MergingUntypedTimeSeries<SliceSeries<SliceWindow>> as UntypedTimeSeries>::IterRev; +} + +// #2331 +trait MyTrait< + AAAAAAAAAAAAAAAAAAAA, + BBBBBBBBBBBBBBBBBBBB, + CCCCCCCCCCCCCCCCCCCC, + DDDDDDDDDDDDDDDDDDDD, +> +{ + fn foo() {} +} + +// Trait aliases +trait FooBar = Foo + Bar; +trait FooBar<A, B, C> = Foo + Bar; +pub trait FooBar = Foo + Bar; +pub trait FooBar<A, B, C> = Foo + Bar; +trait AAAAAAAAAAAAAAAAAA = BBBBBBBBBBBBBBBBBBB + CCCCCCCCCCCCCCCCCCCCCCCCCCCCC + DDDDDDDDDDDDDDDDDD; +pub trait AAAAAAAAAAAAAAAAAA = + BBBBBBBBBBBBBBBBBBB + CCCCCCCCCCCCCCCCCCCCCCCCCCCCC + DDDDDDDDDDDDDDDDDD; +trait AAAAAAAAAAAAAAAAAAA = + BBBBBBBBBBBBBBBBBBB + CCCCCCCCCCCCCCCCCCCCCCCCCCCCC + DDDDDDDDDDDDDDDDDD; +trait AAAAAAAAAAAAAAAAAA = + BBBBBBBBBBBBBBBBBBB + CCCCCCCCCCCCCCCCCCCCCCCCCCCCC + DDDDDDDDDDDDDDDDDDD; +trait AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<A, B, C, D, E> = + FooBar; +trait AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA< + A, + B, + C, + D, + E, +> = FooBar; +#[rustfmt::skip] +trait FooBar = Foo + + Bar; + +// #2637 +auto trait Example {} +pub auto trait PubExample {} +pub unsafe auto trait PubUnsafeExample {} + +// #3006 +trait Foo<'a> { + type Bar<'a>; +} + +impl<'a> Foo<'a> for i32 { + type Bar<'a> = i32; +} + +// #3092 +pub mod test { + pub trait ATraitWithALooongName {} + pub trait ATrait: + ATraitWithALooongName + + ATraitWithALooongName + + ATraitWithALooongName + + ATraitWithALooongName + { + } +} + +// Trait aliases with where clauses. +trait A = where for<'b> &'b Self: Send; + +trait B = where for<'b> &'b Self: Send + Clone + Copy + SomeTrait + AAAAAAAA + BBBBBBB + CCCCCCCCCC; +trait B = + where for<'b> &'b Self: Send + Clone + Copy + SomeTrait + AAAAAAAA + BBBBBBB + CCCCCCCCCCC; +trait B = where + for<'b> &'b Self: + Send + Clone + Copy + SomeTrait + AAAAAAAA + BBBBBBB + CCCCCCCCCCCCCCCCCCCCCCC; +trait B = where + for<'b> &'b Self: Send + + Clone + + Copy + + SomeTrait + + AAAAAAAA + + BBBBBBB + + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC; + +trait B = where + for<'b> &'b Self: Send + + Clone + + Copy + + SomeTrait + + AAAAAAAA + + BBBBBBB + + CCCCCCCCC + + DDDDDDD + + DDDDDDDD + + DDDDDDDDD + + EEEEEEE; + +trait A<'a, 'b, 'c> = Debug<T> + Foo where for<'b> &'b Self: Send; + +trait B<'a, 'b, 'c> = Debug<T> + Foo +where + for<'b> &'b Self: Send + Clone + Copy + SomeTrait + AAAAAAAA + BBBBBBB + CCCCCCCCC + DDDDDDD; + +trait B<'a, 'b, 'c, T> = Debug<'a, T> +where + for<'b> &'b Self: Send + + Clone + + Copy + + SomeTrait + + AAAAAAAA + + BBBBBBB + + CCCCCCCCC + + DDDDDDD + + DDDDDDDD + + DDDDDDDDD + + EEEEEEE; + +trait Visible { + pub const C: i32; + pub type T; + pub fn f(); + pub fn g() {} +} diff --git a/src/tools/rustfmt/tests/target/try-conversion.rs b/src/tools/rustfmt/tests/target/try-conversion.rs new file mode 100644 index 000000000..04992a0a0 --- /dev/null +++ b/src/tools/rustfmt/tests/target/try-conversion.rs @@ -0,0 +1,28 @@ +// rustfmt-use_try_shorthand: true + +fn main() { + let x = some_expr()?; + + let y = a + .very + .loooooooooooooooooooooooooooooooooooooong() + .chain() + .inside() + .weeeeeeeeeeeeeee()? + .test() + .0 + .x; +} + +fn test() { + a? +} + +fn issue1291() { + fs::create_dir_all(&gitfiledir).chain_err(|| { + format!( + "failed to create the {} submodule directory for the workarea", + name + ) + })?; +} diff --git a/src/tools/rustfmt/tests/target/try_block.rs b/src/tools/rustfmt/tests/target/try_block.rs new file mode 100644 index 000000000..19a3f3e14 --- /dev/null +++ b/src/tools/rustfmt/tests/target/try_block.rs @@ -0,0 +1,29 @@ +// rustfmt-edition: 2018 + +fn main() -> Result<(), !> { + let _x: Option<_> = try { 4 }; + + try {} +} + +fn baz() -> Option<i32> { + if (1 == 1) { + return try { 5 }; + } + + // test + let x: Option<()> = try { + // try blocks are great + }; + + let y: Option<i32> = try { 6 }; // comment + + let x: Option<i32> = try { + baz()?; + baz()?; + baz()?; + 7 + }; + + return None; +} diff --git a/src/tools/rustfmt/tests/target/tuple.rs b/src/tools/rustfmt/tests/target/tuple.rs new file mode 100644 index 000000000..68bb2f3bc --- /dev/null +++ b/src/tools/rustfmt/tests/target/tuple.rs @@ -0,0 +1,100 @@ +// Test tuple litterals + +fn foo() { + let a = (a, a, a, a, a); + let aaaaaaaaaaaaaaaa = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaa, + aaaaaaaaaaaaaa, + ); + let aaaaaaaaaaaaaaaaaaaaaa = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaaaaaaaaaaaaa, + aaaa, + ); + let a = (a,); + + let b = ( + // This is a comment + b, // Comment + b, /* Trailing comment */ + ); + + // #1063 + foo(x.0 .0); +} + +fn a() { + (( + aaaaaaaa, + aaaaaaaaaaaaa, + aaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaa, + aaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaa, + ),) +} + +fn b() { + ( + ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + ), + bbbbbbbbbbbbbbbbbb, + ) +} + +fn issue550() { + self.visitor.visit_volume( + self.level.sector_id(sector), + ( + floor_y, + if is_sky_flat(ceil_tex) { + from_wad_height(self.height_range.1) + } else { + ceil_y + }, + ), + ); +} + +fn issue775() { + if indent { + let a = mk_object(&[ + ("a".to_string(), Boolean(true)), + ( + "b".to_string(), + Array(vec![ + mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), + mk_object(&[("d".to_string(), String("".to_string()))]), + ]), + ), + ]); + } +} + +fn issue1725() { + bench_antialiased_lines!( + bench_draw_antialiased_line_segment_diagonal, + (10, 10), + (450, 450) + ); + bench_antialiased_lines!( + bench_draw_antialiased_line_segment_shallow, + (10, 10), + (450, 80) + ); +} + +fn issue_4355() { + let _ = ((1,),).0 .0; +} + +// https://github.com/rust-lang/rustfmt/issues/4410 +impl Drop for LockGuard { + fn drop(&mut self) { + LockMap::unlock(&self.0 .0, &self.0 .1); + } +} diff --git a/src/tools/rustfmt/tests/target/tuple_v2.rs b/src/tools/rustfmt/tests/target/tuple_v2.rs new file mode 100644 index 000000000..ba653291c --- /dev/null +++ b/src/tools/rustfmt/tests/target/tuple_v2.rs @@ -0,0 +1,5 @@ +// rustfmt-version: Two + +fn issue_4355() { + let _ = ((1,),).0.0; +} diff --git a/src/tools/rustfmt/tests/target/type-ascription.rs b/src/tools/rustfmt/tests/target/type-ascription.rs new file mode 100644 index 000000000..a2f082ba4 --- /dev/null +++ b/src/tools/rustfmt/tests/target/type-ascription.rs @@ -0,0 +1,12 @@ +fn main() { + let xxxxxxxxxxx = + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: SomeTrait<AA, BB, CC>; + + let xxxxxxxxxxxxxxx = + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; + + let z = funk(yyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, wwwwww): + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; + + x: u32 - 1u32 / 10f32: u32 +} diff --git a/src/tools/rustfmt/tests/target/type.rs b/src/tools/rustfmt/tests/target/type.rs new file mode 100644 index 000000000..38cf909c2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/type.rs @@ -0,0 +1,175 @@ +// rustfmt-normalize_comments: true +fn types() { + let x: [Vec<_>] = []; + let y: *mut [SomeType; konst_funk()] = expr(); + let z: (/* #digits */ usize, /* exp */ i16) = funk(); + let z: (usize /* #digits */, i16 /* exp */) = funk(); +} + +struct F { + f: extern "C" fn(x: u8, ... /* comment */), + g: extern "C" fn(x: u8, /* comment */ ...), + h: extern "C" fn(x: u8, ...), + i: extern "C" fn( + x: u8, + // comment 4 + y: String, // comment 3 + z: Foo, + // comment + ... // comment 2 + ), +} + +fn issue_1006(def_id_to_string: for<'a, 'b> unsafe fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String) {} + +fn impl_trait_fn_1() -> impl Fn(i32) -> Option<u8> {} + +fn impl_trait_fn_2<E>() -> impl Future<Item = &'a i64, Error = E> {} + +fn issue_1234() { + do_parse!(name: take_while1!(is_token) >> (Header)) +} + +// #2510 +impl CombineTypes { + pub fn pop_callback( + &self, + query_id: Uuid, + ) -> Option<( + ProjectId, + Box<FnMut(&ProjectState, serde_json::Value, bool) -> () + Sync + Send>, + )> { + self.query_callbacks()(&query_id) + } +} + +// #2859 +pub fn do_something<'a, T: Trait1 + Trait2 + 'a>( + &fooo: u32, +) -> impl Future< + Item = ( + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + ), + Error = SomeError, +> + 'a { +} + +pub fn do_something<'a, T: Trait1 + Trait2 + 'a>( + &fooo: u32, +) -> impl Future< + Item = ( + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + ), + Error = SomeError, +> + Future< + Item = ( + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + ), + Error = SomeError, +> + Future< + Item = ( + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + impl Future<Item = (), Error = SomeError> + 'a, + ), + Error = SomeError, +> + 'a + 'b + 'c { +} + +// #3051 +token![impl]; +token![impl]; + +// #3060 +macro_rules! foo { + ($foo_api: ty) => { + type Target = ($foo_api) + 'static; + }; +} + +type Target = (FooAPI) + 'static; + +// #3137 +fn foo<T>(t: T) +where + T: (FnOnce() -> ()) + Clone, + U: (FnOnce() -> ()) + 'static, +{ +} + +// #3117 +fn issue3117() { + { + { + { + { + { + { + { + { + let opt: &mut Option<MyLongTypeHere> = + unsafe { &mut *self.future.get() }; + } + } + } + } + } + } + } + } +} + +// #3139 +fn issue3139() { + assert_eq!( + to_json_value(&None::<i32>).unwrap(), + json!({ "test": None::<i32> }) + ); +} + +// #3180 +fn foo( + a: SomeLongComplexType, + b: SomeOtherLongComplexType, +) -> Box<Future<Item = AnotherLongType, Error = ALongErrorType>> { +} + +type MyFn = fn( + a: SomeLongComplexType, + b: SomeOtherLongComplexType, +) -> Box<Future<Item = AnotherLongType, Error = ALongErrorType>>; + +// Const bound + +trait T: ~const Super {} + +const fn not_quite_const<S: ~const T>() -> i32 { + <S as T>::CONST +} + +struct S<T: ~const ?Sized>(std::marker::PhantomData<T>); + +impl ~const T {} + +fn apit(_: impl ~const T) {} + +fn rpit() -> impl ~const T { + S +} + +pub struct Foo<T: Trait>(T); +impl<T: ~const Trait> Foo<T> { + fn new(t: T) -> Self { + Self(t) + } +} + +// #4357 +type T = typeof(1); +impl T for .. {} diff --git a/src/tools/rustfmt/tests/target/type_alias.rs b/src/tools/rustfmt/tests/target/type_alias.rs new file mode 100644 index 000000000..862f9ecbe --- /dev/null +++ b/src/tools/rustfmt/tests/target/type_alias.rs @@ -0,0 +1,76 @@ +// rustfmt-normalize_comments: true + +type PrivateTest<'a, I> = ( + Box<Parser<Input = I, Output = char> + 'a>, + Box<Parser<Input = I, Output = char> + 'a>, +); + +pub type PublicTest<'a, I, O> = Result< + Vec<MyLongType>, + Box<Parser<Input = I, Output = char> + 'a>, + Box<Parser<Input = I, Output = char> + 'a>, +>; + +pub type LongGenericListTest< + 'a, + 'b, + 'c, + 'd, + LONGPARAMETERNAME, + LONGPARAMETERNAME, + LONGPARAMETERNAME, + A, + B, + C, +> = Option<Vec<MyType>>; + +pub type Exactly100CharsTest<'a, 'b, 'c, 'd, LONGPARAMETERNAME, LONGPARAMETERNAME, A, B> = Vec<i32>; + +pub type Exactly101CharsTest<'a, 'b, 'c, 'd, LONGPARAMETERNAME, LONGPARAMETERNAME, A, B> = + Vec<Test>; + +pub type Exactly100CharsToEqualTest<'a, 'b, 'c, 'd, LONGPARAMETERNAME, LONGPARAMETERNAME, A, B, C> = + Vec<i32>; + +pub type GenericsFitButNotEqualTest< + 'a, + 'b, + 'c, + 'd, + LONGPARAMETERNAME, + LONGPARAMETERNAME, + A1, + B, + C, +> = Vec<i32>; + +pub type CommentTest< + // Lifetime + 'a, + // Type + T, +> = (); + +pub type WithWhereClause<LONGPARAMETERNAME, T> +where + T: Clone, + LONGPARAMETERNAME: Clone + Eq + OtherTrait, += Option<T>; + +pub type Exactly100CharstoEqualWhereTest<T, U, PARAMET> +where + T: Clone + Ord + Eq + SomeOtherTrait, += Option<T>; + +pub type Exactly101CharstoEqualWhereTest<T, U, PARAMETE> +where + T: Clone + Ord + Eq + SomeOtherTrait, += Option<T>; + +type RegisterPlugin = unsafe fn(pt: *const c_char, plugin: *mut c_void, data: *mut CallbackData); + +// #1683 +pub type Between<Lhs, Rhs> = + super::operators::Between<Lhs, super::operators::And<AsExpr<Rhs, Lhs>, AsExpr<Rhs, Lhs>>>; +pub type NotBetween<Lhs, Rhs> = + super::operators::NotBetween<Lhs, super::operators::And<AsExpr<Rhs, Lhs>, AsExpr<Rhs, Lhs>>>; diff --git a/src/tools/rustfmt/tests/target/unicode.rs b/src/tools/rustfmt/tests/target/unicode.rs new file mode 100644 index 000000000..34a4f4634 --- /dev/null +++ b/src/tools/rustfmt/tests/target/unicode.rs @@ -0,0 +1,30 @@ +// rustfmt-wrap_comments: true + +fn foo() { + let s = "this line goes to 100: ͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶͶ"; + let s = 42; + + // a comment of length 80, with the starting sigil: ҘҘҘҘҘҘҘҘҘҘ ҘҘҘҘҘҘҘҘҘҘҘҘҘҘ + let s = 42; +} + +pub fn bar(config: &Config) { + let csv = RefCell::new(create_csv(config, "foo")); + { + let mut csv = csv.borrow_mut(); + for (i1, i2, i3) in iproduct!(0..2, 0..3, 0..3) { + csv.write_field(format!("γ[{}.{}.{}]", i1, i2, i3)).unwrap(); + csv.write_field(format!("d[{}.{}.{}]", i1, i2, i3)).unwrap(); + csv.write_field(format!("i[{}.{}.{}]", i1, i2, i3)).unwrap(); + } + csv.write_record(None::<&[u8]>).unwrap(); + } +} + +// The NotUnicode line is below 100 wrt chars but over it wrt String::len +fn baz() { + let our_error_b = result_b_from_func.or_else(|e| match e { + NotPresent => Err(e).chain_err(|| "env var wasn't provided"), + NotUnicode(_) => Err(e).chain_err(|| "env var was very very very borkæ–‡å—化ã"), + }); +} diff --git a/src/tools/rustfmt/tests/target/unindent_if_else_cond_comment.rs b/src/tools/rustfmt/tests/target/unindent_if_else_cond_comment.rs new file mode 100644 index 000000000..98621b1ee --- /dev/null +++ b/src/tools/rustfmt/tests/target/unindent_if_else_cond_comment.rs @@ -0,0 +1,27 @@ +// Comments on else block. See #1575. + +fn example() { + // `if` comment + if x { + foo(); + // `else if` comment + } else if y { + foo(); + // Comment on `else if`. + // Comment on `else if`. + } else if z { + bar(); + /* + * Multi line comment on `else if` + */ + } else if xx { + bar(); + /* Single line comment on `else if` */ + } else if yy { + foo(); + // `else` comment + } else { + foo(); + // Comment at the end of `else` block + }; +} diff --git a/src/tools/rustfmt/tests/target/unions.rs b/src/tools/rustfmt/tests/target/unions.rs new file mode 100644 index 000000000..8ed16b269 --- /dev/null +++ b/src/tools/rustfmt/tests/target/unions.rs @@ -0,0 +1,198 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +/// A Doc comment +#[AnAttribute] +pub union Foo { + #[rustfmt::skip] + f : SomeType, // Comment beside a field + f: SomeType, // Comment beside a field + // Comment on a field + #[AnAttribute] + g: SomeOtherType, + /// A doc comment on a field + h: AThirdType, + pub i: TypeForPublicField, +} + +// #1029 +pub union Foo { + #[doc(hidden)] + // This will NOT get deleted! + bar: String, // hi +} + +// #1029 +union X { + // `x` is an important number. + #[allow(unused)] // TODO: use + x: u32, +} + +// #410 +#[allow(missing_docs)] +pub union Writebatch<K: Key> { + #[allow(dead_code)] // only used for holding the internal pointer + writebatch: RawWritebatch, + marker: PhantomData<K>, +} + +// With a where-clause and generics. +pub union Foo<'a, Y: Baz> +where + X: Whatever, +{ + f: SomeType, // Comment beside a field +} + +union Baz { + a: A, // Comment A + b: B, // Comment B + c: C, // Comment C +} + +union Baz { + a: A, // Comment A + + b: B, // Comment B + + c: C, // Comment C +} + +union Baz { + a: A, + + b: B, + c: C, + + d: D, +} + +union Baz { + // Comment A + a: A, + + // Comment B + b: B, + // Comment C + c: C, +} + +pub union State<F: FnMut() -> time::Timespec> { + now: F, +} + +pub union State<F: FnMut() -> ()> { + now: F, +} + +pub union State<F: FnMut()> { + now: F, +} + +union Palette { + /// A map of indices in the palette to a count of pixels in approximately + /// that color + foo: i32, +} + +// Splitting a single line comment into a block previously had a misalignment +// when the field had attributes +union FieldsWithAttributes { + // Pre Comment + #[rustfmt::skip] pub host:String, /* Post comment BBBBBBBBBBBBBB BBBBBBBBBBBBBBBB + * BBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBB BBBBBBBBBBB */ + // Another pre comment + #[attr1] + #[attr2] + pub id: usize, /* CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCC + * CCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCC CCCCCCCCCCCC */ +} + +union Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: + node::Handle<IdRef<'id, Node<K, V>>, Type, NodeType>, +} + +mod m { + union X<T> + where + T: Sized, + { + a: T, + } +} + +union Issue677 { + pub ptr: *const libc::c_void, + pub trace: fn(obj: *const libc::c_void, tracer: *mut JSTracer), +} + +union Foo {} +union Foo {} +union Foo { + // comment +} +union Foo { + // trailing space -> +} +union Foo { + // comment +} + +union LongUnion { + a: A, + the_quick_brown_fox_jumps_over_the_lazy_dog: + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, +} + +union Deep { + deeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep: + node::Handle<IdRef<'id, Node<Key, Value>>, Type, NodeType>, +} + +// #1364 +fn foo() { + convex_shape.set_point(0, &Vector2f { x: 400.0, y: 100.0 }); + convex_shape.set_point(1, &Vector2f { x: 500.0, y: 70.0 }); + convex_shape.set_point(2, &Vector2f { x: 450.0, y: 100.0 }); + convex_shape.set_point(3, &Vector2f { x: 580.0, y: 150.0 }); +} + +// Vertical alignment +union Foo { + aaaaa: u32, // a + + b: u32, // b + cc: u32, // cc + + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 1 + yy: u32, // comment2 + zzz: u32, // comment3 + + aaaaaa: u32, // comment4 + bb: u32, // comment5 + // separate + dd: u32, // comment7 + c: u32, // comment6 + + aaaaaaa: u32, /* multi + * line + * comment + */ + b: u32, // hi + + do_not_push_this_comment1: u32, // comment1 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + please_do_not_push_this_comment3: u32, // comment3 + + do_not_push_this_comment1: u32, // comment1 + // separate + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + please_do_not_push_this_comment3: u32, // comment3 + + do_not_push_this_comment1: u32, // comment1 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: u32, // 2 + // separate + please_do_not_push_this_comment3: u32, // comment3 +} diff --git a/src/tools/rustfmt/tests/target/unsafe-mod.rs b/src/tools/rustfmt/tests/target/unsafe-mod.rs new file mode 100644 index 000000000..05ba2f54f --- /dev/null +++ b/src/tools/rustfmt/tests/target/unsafe-mod.rs @@ -0,0 +1,7 @@ +// These are supported by rustc syntactically but not semantically. + +#[cfg(any())] +unsafe mod m {} + +#[cfg(any())] +unsafe extern "C++" {} diff --git a/src/tools/rustfmt/tests/target/visibility.rs b/src/tools/rustfmt/tests/target/visibility.rs new file mode 100644 index 000000000..ca078422c --- /dev/null +++ b/src/tools/rustfmt/tests/target/visibility.rs @@ -0,0 +1,8 @@ +// #2398 +pub mod outer_mod { + pub mod inner_mod { + pub(in outer_mod) fn outer_mod_visible_fn() {} + pub(super) fn super_mod_visible_fn() {} + pub(self) fn inner_mod_visible_fn() {} + } +} diff --git a/src/tools/rustfmt/tests/target/visual-fn-type.rs b/src/tools/rustfmt/tests/target/visual-fn-type.rs new file mode 100644 index 000000000..052acde02 --- /dev/null +++ b/src/tools/rustfmt/tests/target/visual-fn-type.rs @@ -0,0 +1,9 @@ +// rustfmt-indent_style: Visual +type CNodeSetAtts = unsafe extern "C" fn(node: *const RsvgNode, + node_impl: *const RsvgCNodeImpl, + handle: *const RsvgHandle, + pbag: *const PropertyBag); +type CNodeDraw = unsafe extern "C" fn(node: *const RsvgNode, + node_impl: *const RsvgCNodeImpl, + draw_ctx: *const RsvgDrawingCtx, + dominate: i32); diff --git a/src/tools/rustfmt/tests/target/where-clause-rfc.rs b/src/tools/rustfmt/tests/target/where-clause-rfc.rs new file mode 100644 index 000000000..9c43e91d3 --- /dev/null +++ b/src/tools/rustfmt/tests/target/where-clause-rfc.rs @@ -0,0 +1,156 @@ +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) +where + T: FOo, + U: Bar, +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) +where + T: FOo, +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule( + node: &CompoundNode, + rule: &Rule, + args: &[Arg], + shape: &Shape, + shape: &Shape, +) where + T: FOo, + U: Bar, +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule( + node: &CompoundNode, + rule: &Rule, + args: &[Arg], + shape: &Shape, + shape: &Shape, +) where + T: FOo, +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule( + node: &CompoundNode, + rule: &Rule, + args: &[Arg], + shape: &Shape, +) -> Option<String> +where + T: FOo, + U: Bar, +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule( + node: &CompoundNode, + rule: &Rule, + args: &[Arg], + shape: &Shape, +) -> Option<String> +where + T: FOo, +{ + let mut effects = HashMap::new(); +} + +pub trait Test { + fn very_long_method_name<F>(self, f: F) -> MyVeryLongReturnType + where + F: FnMut(Self::Item) -> bool; + + fn exactly_100_chars1<F>(self, f: F) -> MyVeryLongReturnType + where + F: FnMut(Self::Item) -> bool; +} + +fn very_long_function_name<F>(very_long_argument: F) -> MyVeryLongReturnType +where + F: FnMut(Self::Item) -> bool, +{ +} + +struct VeryLongTupleStructName<A, B, C, D, E>(LongLongTypename, LongLongTypename, i32, i32) +where + A: LongTrait; + +struct Exactly100CharsToSemicolon<A, B, C, D, E>(LongLongTypename, i32, i32) +where + A: LongTrait1234; + +struct AlwaysOnNextLine<LongLongTypename, LongTypename, A, B, C, D, E, F> +where + A: LongTrait, +{ + x: i32, +} + +pub trait SomeTrait<T> +where + T: Something + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read + + FromStr, +{ +} + +// #2020 +impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { + fn elaborate_bounds<F>(&mut self, bounds: &[ty::PolyTraitRef<'tcx>], mut mk_cand: F) + where + F: for<'b> FnMut( + &mut ProbeContext<'b, 'gcx, 'tcx>, + ty::PolyTraitRef<'tcx>, + ty::AssociatedItem, + ), + { + // ... + } +} + +// #2497 +fn handle_update<'a, Tab, Conn, R, C>( + executor: &Executor<PooledConnection<ConnectionManager<Conn>>>, + change_set: &'a C, +) -> ExecutionResult +where + &'a C: Identifiable + AsChangeset<Target = Tab> + HasTable<Table = Tab>, + <&'a C as AsChangeset>::Changeset: QueryFragment<Conn::Backend>, + Tab: Table + HasTable<Table = Tab>, + Tab::PrimaryKey: EqAll<<&'a C as Identifiable>::Id>, + Tab::FromClause: QueryFragment<Conn::Backend>, + Tab: FindDsl<<&'a C as Identifiable>::Id>, + Find<Tab, <&'a C as Identifiable>::Id>: IntoUpdateTarget<Table = Tab>, + <Find<Tab, <&'a C as Identifiable>::Id> as IntoUpdateTarget>::WhereClause: + QueryFragment<Conn::Backend>, + Tab::Query: FilterDsl<<Tab::PrimaryKey as EqAll<<&'a C as Identifiable>::Id>>::Output>, + Filter<Tab::Query, <Tab::PrimaryKey as EqAll<<&'a C as Identifiable>::Id>>::Output>: LimitDsl, + Limit<Filter<Tab::Query, <Tab::PrimaryKey as EqAll<<&'a C as Identifiable>::Id>>::Output>>: + QueryDsl + + BoxedDsl< + 'a, + Conn::Backend, + Output = BoxedSelectStatement<'a, R::SqlType, Tab, Conn::Backend>, + >, + R: LoadingHandler<Conn, Table = Tab, SqlType = Tab::SqlType> + + GraphQLType<TypeInfo = (), Context = ()>, +{ + unimplemented!() +} diff --git a/src/tools/rustfmt/tests/target/where-clause.rs b/src/tools/rustfmt/tests/target/where-clause.rs new file mode 100644 index 000000000..eb2f8d5e6 --- /dev/null +++ b/src/tools/rustfmt/tests/target/where-clause.rs @@ -0,0 +1,107 @@ +// rustfmt-indent_style: Visual + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) + where T: FOo, + U: Bar +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, rule: &Rule, args: &[Arg], shape: &Shape) + where T: FOo +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, + rule: &Rule, + args: &[Arg], + shape: &Shape, + shape: &Shape) + where T: FOo, + U: Bar +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, + rule: &Rule, + args: &[Arg], + shape: &Shape, + shape: &Shape) + where T: FOo +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, + rule: &Rule, + args: &[Arg], + shape: &Shape) + -> Option<String> + where T: FOo, + U: Bar +{ + let mut effects = HashMap::new(); +} + +fn reflow_list_node_with_rule(node: &CompoundNode, + rule: &Rule, + args: &[Arg], + shape: &Shape) + -> Option<String> + where T: FOo +{ + let mut effects = HashMap::new(); +} + +pub trait Test { + fn very_long_method_name<F>(self, f: F) -> MyVeryLongReturnType + where F: FnMut(Self::Item) -> bool; + + fn exactly_100_chars1<F>(self, f: F) -> MyVeryLongReturnType + where F: FnMut(Self::Item) -> bool; +} + +fn very_long_function_name<F>(very_long_argument: F) -> MyVeryLongReturnType + where F: FnMut(Self::Item) -> bool +{ +} + +struct VeryLongTupleStructName<A, B, C, D, E>(LongLongTypename, LongLongTypename, i32, i32) + where A: LongTrait; + +struct Exactly100CharsToSemicolon<A, B, C, D, E>(LongLongTypename, i32, i32) where A: LongTrait1234; + +struct AlwaysOnNextLine<LongLongTypename, LongTypename, A, B, C, D, E, F> + where A: LongTrait +{ + x: i32, +} + +pub trait SomeTrait<T> + where T: Something + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read + + FromStr +{ +} + +// #2020 +impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { + fn elaborate_bounds<F>(&mut self, bounds: &[ty::PolyTraitRef<'tcx>], mut mk_cand: F) + where F: for<'b> FnMut(&mut ProbeContext<'b, 'gcx, 'tcx>, + ty::PolyTraitRef<'tcx>, + ty::AssociatedItem) + { + // ... + } +} diff --git a/src/tools/rustfmt/tests/target/width-heuristics.rs b/src/tools/rustfmt/tests/target/width-heuristics.rs new file mode 100644 index 000000000..e177a2152 --- /dev/null +++ b/src/tools/rustfmt/tests/target/width-heuristics.rs @@ -0,0 +1,24 @@ +// rustfmt-max_width: 120 + +// elems on multiple lines for max_width 100, but same line for max_width 120 +fn foo(e: Enum) { + match e { + Enum::Var { elem1, elem2, elem3 } => { + return; + } + } +} + +// elems not on same line for either max_width 100 or 120 +fn bar(e: Enum) { + match e { + Enum::Var { + elem1, + elem2, + elem3, + elem4, + } => { + return; + } + } +} diff --git a/src/tools/rustfmt/tests/target/wrap_comments_should_not_imply_format_doc_comments.rs b/src/tools/rustfmt/tests/target/wrap_comments_should_not_imply_format_doc_comments.rs new file mode 100644 index 000000000..d61d4d7c2 --- /dev/null +++ b/src/tools/rustfmt/tests/target/wrap_comments_should_not_imply_format_doc_comments.rs @@ -0,0 +1,16 @@ +// rustfmt-wrap_comments: true + +/// Foo +/// +/// # Example +/// ``` +/// # #![cfg_attr(not(dox), feature(cfg_target_feature, target_feature, stdsimd))] +/// # #![cfg_attr(not(dox), no_std)] +/// fn foo() { } +/// ``` +fn foo() {} + +/// A long commment for wrapping +/// This is a long long long long long long long long long long long long long +/// long long long long long long long sentence. +fn bar() {} diff --git a/src/tools/rustfmt/tests/writemode/source/fn-single-line.rs b/src/tools/rustfmt/tests/writemode/source/fn-single-line.rs new file mode 100644 index 000000000..ab1e13e17 --- /dev/null +++ b/src/tools/rustfmt/tests/writemode/source/fn-single-line.rs @@ -0,0 +1,80 @@ +// rustfmt-fn_single_line: true +// rustfmt-emit_mode: checkstyle +// Test single-line functions. + +fn foo_expr() { + 1 +} + +fn foo_stmt() { + foo(); +} + +fn foo_decl_local() { + let z = 5; + } + +fn foo_decl_item(x: &mut i32) { + x = 3; +} + + fn empty() { + +} + +fn foo_return() -> String { + "yay" +} + +fn foo_where() -> T where T: Sync { + let x = 2; +} + +fn fooblock() { + { + "inner-block" + } +} + +fn fooblock2(x: i32) { + let z = match x { + _ => 2, + }; +} + +fn comment() { + // this is a test comment + 1 +} + +fn comment2() { + // multi-line comment + let z = 2; + 1 +} + +fn only_comment() { + // Keep this here +} + +fn aaaaaaaaaaaaaaaaa_looooooooooooooooooooooong_name() { + let z = "aaaaaaawwwwwwwwwwwwwwwwwwwwwwwwwwww"; +} + +fn lots_of_space () { + 1 +} + +fn mac() -> Vec<i32> { vec![] } + +trait CoolTypes { + fn dummy(&self) { + } +} + +trait CoolerTypes { fn dummy(&self) { +} +} + +fn Foo<T>() where T: Bar { +} diff --git a/src/tools/rustfmt/tests/writemode/source/json.rs b/src/tools/rustfmt/tests/writemode/source/json.rs new file mode 100644 index 000000000..89dcf6941 --- /dev/null +++ b/src/tools/rustfmt/tests/writemode/source/json.rs @@ -0,0 +1,80 @@ +// rustfmt-fn_single_line: true +// rustfmt-emit_mode: json +// Test single-line functions. + +fn foo_expr() { + 1 +} + +fn foo_stmt() { + foo(); +} + +fn foo_decl_local() { + let z = 5; + } + +fn foo_decl_item(x: &mut i32) { + x = 3; +} + + fn empty() { + +} + +fn foo_return() -> String { + "yay" +} + +fn foo_where() -> T where T: Sync { + let x = 2; +} + +fn fooblock() { + { + "inner-block" + } +} + +fn fooblock2(x: i32) { + let z = match x { + _ => 2, + }; +} + +fn comment() { + // this is a test comment + 1 +} + +fn comment2() { + // multi-line comment + let z = 2; + 1 +} + +fn only_comment() { + // Keep this here +} + +fn aaaaaaaaaaaaaaaaa_looooooooooooooooooooooong_name() { + let z = "aaaaaaawwwwwwwwwwwwwwwwwwwwwwwwwwww"; +} + +fn lots_of_space () { + 1 +} + +fn mac() -> Vec<i32> { vec![] } + +trait CoolTypes { + fn dummy(&self) { + } +} + +trait CoolerTypes { fn dummy(&self) { +} +} + +fn Foo<T>() where T: Bar { +} diff --git a/src/tools/rustfmt/tests/writemode/source/modified.rs b/src/tools/rustfmt/tests/writemode/source/modified.rs new file mode 100644 index 000000000..948beb348 --- /dev/null +++ b/src/tools/rustfmt/tests/writemode/source/modified.rs @@ -0,0 +1,14 @@ +// rustfmt-write_mode: modified +// Test "modified" output + +fn +blah +() +{ } + + +#[cfg +( a , b +)] +fn +main() {} diff --git a/src/tools/rustfmt/tests/writemode/source/stdin.rs b/src/tools/rustfmt/tests/writemode/source/stdin.rs new file mode 100644 index 000000000..06f8a0c28 --- /dev/null +++ b/src/tools/rustfmt/tests/writemode/source/stdin.rs @@ -0,0 +1,6 @@ + +fn + some( ) +{ +} +fn main () {} diff --git a/src/tools/rustfmt/tests/writemode/target/checkstyle.xml b/src/tools/rustfmt/tests/writemode/target/checkstyle.xml new file mode 100644 index 000000000..05bc3a252 --- /dev/null +++ b/src/tools/rustfmt/tests/writemode/target/checkstyle.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<checkstyle version="4.3"><file name="tests/writemode/source/fn-single-line.rs"><error line="5" severity="warning" message="Should be `fn foo_expr() { 1 }`" /><error line="7" severity="warning" message="Should be `fn foo_stmt() { foo(); }`" /><error line="9" severity="warning" message="Should be `fn foo_decl_local() { let z = 5; }`" /><error line="11" severity="warning" message="Should be `fn foo_decl_item(x: &mut i32) { x = 3; }`" /><error line="13" severity="warning" message="Should be `fn empty() {}`" /><error line="15" severity="warning" message="Should be `fn foo_return() -> String { "yay" }`" /><error line="17" severity="warning" message="Should be `fn foo_where() -> T`" /><error line="18" severity="warning" message="Should be `where`" /><error line="19" severity="warning" message="Should be ` T: Sync,`" /><error line="20" severity="warning" message="Should be `{`" /><error line="55" severity="warning" message="Should be `fn lots_of_space() { 1 }`" /><error line="60" severity="warning" message="Should be ` fn dummy(&self) {}`" /><error line="63" severity="warning" message="Should be `trait CoolerTypes {`" /><error line="64" severity="warning" message="Should be ` fn dummy(&self) {}`" /><error line="67" severity="warning" message="Should be `fn Foo<T>()`" /><error line="68" severity="warning" message="Should be `where`" /><error line="69" severity="warning" message="Should be ` T: Bar,`" /><error line="70" severity="warning" message="Should be `{`" /></file></checkstyle> diff --git a/src/tools/rustfmt/tests/writemode/target/modified.txt b/src/tools/rustfmt/tests/writemode/target/modified.txt new file mode 100644 index 000000000..5c0539a66 --- /dev/null +++ b/src/tools/rustfmt/tests/writemode/target/modified.txt @@ -0,0 +1,5 @@ +4 4 1 +fn blah() {} +10 5 2 +#[cfg(a, b)] +fn main() {} diff --git a/src/tools/rustfmt/tests/writemode/target/output.json b/src/tools/rustfmt/tests/writemode/target/output.json new file mode 100644 index 000000000..d8b5467ee --- /dev/null +++ b/src/tools/rustfmt/tests/writemode/target/output.json @@ -0,0 +1 @@ +[{"name":"tests/writemode/source/json.rs","mismatches":[{"original_begin_line":5,"original_end_line":7,"expected_begin_line":5,"expected_end_line":5,"original":"fn foo_expr() {\n 1\n}\n","expected":"fn foo_expr() { 1 }\n"},{"original_begin_line":9,"original_end_line":11,"expected_begin_line":7,"expected_end_line":7,"original":"fn foo_stmt() {\n foo();\n}\n","expected":"fn foo_stmt() { foo(); }\n"},{"original_begin_line":13,"original_end_line":15,"expected_begin_line":9,"expected_end_line":9,"original":"fn foo_decl_local() {\n let z = 5;\n }\n","expected":"fn foo_decl_local() { let z = 5; }\n"},{"original_begin_line":17,"original_end_line":19,"expected_begin_line":11,"expected_end_line":11,"original":"fn foo_decl_item(x: &mut i32) {\n x = 3;\n}\n","expected":"fn foo_decl_item(x: &mut i32) { x = 3; }\n"},{"original_begin_line":21,"original_end_line":21,"expected_begin_line":13,"expected_end_line":13,"original":" fn empty() {\n","expected":"fn empty() {}\n"},{"original_begin_line":23,"original_end_line":23,"expected_begin_line":15,"expected_end_line":15,"original":"}\n","expected":"fn foo_return() -> String { \"yay\" }\n"},{"original_begin_line":25,"original_end_line":29,"expected_begin_line":17,"expected_end_line":20,"original":"fn foo_return() -> String {\n \"yay\"\n}\n\nfn foo_where() -> T where T: Sync {\n","expected":"fn foo_where() -> T\nwhere\n T: Sync,\n{\n"},{"original_begin_line":64,"original_end_line":66,"expected_begin_line":55,"expected_end_line":55,"original":"fn lots_of_space () {\n 1 \n}\n","expected":"fn lots_of_space() { 1 }\n"},{"original_begin_line":71,"original_end_line":72,"expected_begin_line":60,"expected_end_line":60,"original":" fn dummy(&self) {\n }\n","expected":" fn dummy(&self) {}\n"},{"original_begin_line":75,"original_end_line":75,"expected_begin_line":63,"expected_end_line":64,"original":"trait CoolerTypes { fn dummy(&self) { \n","expected":"trait CoolerTypes {\n fn dummy(&self) {}\n"},{"original_begin_line":77,"original_end_line":77,"expected_begin_line":66,"expected_end_line":66,"original":"}\n","expected":""},{"original_begin_line":79,"original_end_line":79,"expected_begin_line":67,"expected_end_line":70,"original":"fn Foo<T>() where T: Bar {\n","expected":"fn Foo<T>()\nwhere\n T: Bar,\n{\n"}]}] diff --git a/src/tools/rustfmt/tests/writemode/target/stdin.json b/src/tools/rustfmt/tests/writemode/target/stdin.json new file mode 100644 index 000000000..dbf2c4863 --- /dev/null +++ b/src/tools/rustfmt/tests/writemode/target/stdin.json @@ -0,0 +1 @@ +[{"name":"<stdin>","mismatches":[{"original_begin_line":1,"original_end_line":6,"expected_begin_line":1,"expected_end_line":2,"original":"\nfn\n some( )\n{\n}\nfn main () {}\n","expected":"fn some() {}\nfn main() {}\n"}]}] diff --git a/src/tools/rustfmt/tests/writemode/target/stdin.xml b/src/tools/rustfmt/tests/writemode/target/stdin.xml new file mode 100644 index 000000000..a7301bbc5 --- /dev/null +++ b/src/tools/rustfmt/tests/writemode/target/stdin.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?>
+<checkstyle version="4.3"><file name="<stdin>"><error line="1" severity="warning" message="Should be `fn some() {}`" /><error line="2" severity="warning" message="Should be `fn main() {}`" /></file></checkstyle>
|