diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 4e605ef625199..0e8cdc266f899 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -99,7 +99,7 @@ fn resolve_block<'tcx>( for (i, statement) in blk.stmts.iter().enumerate() { match statement.kind { hir::StmtKind::Let(LetStmt { els: Some(els), .. }) => { - // Let-else has a special lexical structure for variables. + // let-else has a special lexical structure for variables. // First we take a checkpoint of the current scope context here. let mut prev_cx = visitor.cx; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 4e9ecb9006ab1..185cb4d522f2f 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2697,7 +2697,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,no_run + /// ```rust,compile_fail /// # #![allow(unused)] /// use std::ptr; /// unsafe { @@ -2716,7 +2716,7 @@ declare_lint! { /// /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html pub DEREF_NULLPTR, - Warn, + Deny, "detects when an null pointer is dereferenced" } @@ -2726,6 +2726,16 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) { /// test if expression is a null ptr fn is_null_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + let pointer_ty = cx.typeck_results().expr_ty(expr); + let ty::RawPtr(pointee, _) = pointer_ty.kind() else { + return false; + }; + if let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(*pointee)) { + if layout.layout.size() == rustc_abi::Size::ZERO { + return false; + } + } + match &expr.kind { hir::ExprKind::Cast(expr, ty) => { if let hir::TyKind::Ptr(_) = ty.kind { diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 4a741169443dd..f65b99d5f99f0 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -334,7 +334,7 @@ mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count *[other] variants that aren't } matched -mir_build_suggest_let_else = you might want to use `let else` to handle the {$count -> +mir_build_suggest_let_else = you might want to use `let...else` to handle the {$count -> [one] variant that isn't *[other] variants that aren't } matched diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 3fe8971f3d6c6..26393bf61a32e 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -867,7 +867,7 @@ impl<'a> Parser<'a> { if let_else || !if_let { err.span_suggestion_verbose( block_span.shrink_to_lo(), - format!("{alternatively}you might have meant to use `let else`"), + format!("{alternatively}you might have meant to use `let...else`"), "else ".to_string(), if let_else { Applicability::MachineApplicable diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index a26ae7d284443..08465ea541b80 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -197,6 +197,37 @@ themselves marked as unstable. To use any of these options, pass `-Z unstable-op the flag in question to Rustdoc on the command-line. To do this from Cargo, you can either use the `RUSTDOCFLAGS` environment variable or the `cargo rustdoc` command. +### `--merge`, `--parts-out-dir`, and `--include-parts-dir` + +These options control how rustdoc handles files that combine data from multiple crates. + +By default, they act like `--merge=shared` is set, and `--parts-out-dir` and `--include-parts-dir` +are turned off. The `--merge=shared` mode causes rustdoc to load the existing data in the out-dir, +combine the new crate data into it, and write the result. This is very easy to use in scripts that +manually invoke rustdoc, but it's also slow, because it performs O(crates) work on +every crate, meaning it performs O(crates2) work. + +```console +$ rustdoc crate1.rs --out-dir=doc +$ cat doc/search.index/crateNames/* +rd_("fcrate1") +$ rustdoc crate2.rs --out-dir=doc +$ cat doc/search.index/crateNames/* +rd_("fcrate1fcrate2") +``` + +To delay shared-data merging until the end of a build, so that you only have to perform O(crates) +work, use `--merge=none` on every crate except the last one, which will use `--merge=finalize`. + +```console +$ rustdoc +nightly crate1.rs --merge=none --parts-out-dir=crate1.d -Zunstable-options +$ cat doc/search.index/crateNames/* +cat: 'doc/search.index/crateNames/*': No such file or directory +$ rustdoc +nightly crate2.rs --merge=finalize --include-parts-dir=crate1.d -Zunstable-options +$ cat doc/search.index/crateNames/* +rd_("fcrate1fcrate2") +``` + ### `--document-hidden-items`: Show items that are `#[doc(hidden)]` diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index da19f506a3700..5d16dff24c69a 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -978,15 +978,16 @@ fn parse_extern_html_roots( Ok(externs) } -/// Path directly to crate-info file. +/// Path directly to crate-info directory. /// -/// For example, `/home/user/project/target/doc.parts//crate-info`. +/// For example, `/home/user/project/target/doc.parts`. +/// Each crate has its info stored in a file called `CRATENAME.json`. #[derive(Clone, Debug)] pub(crate) struct PathToParts(pub(crate) PathBuf); impl PathToParts { fn from_flag(path: String) -> Result { - let mut path = PathBuf::from(path); + let path = PathBuf::from(path); // check here is for diagnostics if path.exists() && !path.is_dir() { Err(format!( @@ -995,20 +996,22 @@ impl PathToParts { )) } else { // if it doesn't exist, we'll create it. worry about that in write_shared - path.push("crate-info"); Ok(PathToParts(path)) } } } -/// Reports error if --include-parts-dir / crate-info is not a file +/// Reports error if --include-parts-dir is not a directory fn parse_include_parts_dir(m: &getopts::Matches) -> Result, String> { let mut ret = Vec::new(); for p in m.opt_strs("include-parts-dir") { let p = PathToParts::from_flag(p)?; // this is just for diagnostic - if !p.0.is_file() { - return Err(format!("--include-parts-dir expected {} to be a file", p.0.display())); + if !p.0.is_dir() { + return Err(format!( + "--include-parts-dir expected {} to be a directory", + p.0.display() + )); } ret.push(p); } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 6045b9a77ecae..8b6776ffa4b8c 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -14,7 +14,7 @@ //! or contains "invocation-specific". use std::cell::RefCell; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::fs::File; use std::io::{self, Write as _}; use std::iter::once; @@ -84,9 +84,11 @@ pub(crate) fn write_shared( }; if let Some(parts_out_dir) = &opt.parts_out_dir { - create_parents(&parts_out_dir.0)?; + let mut parts_out_file = parts_out_dir.0.clone(); + parts_out_file.push(&format!("{crate_name}.json")); + create_parents(&parts_out_file)?; try_err!( - fs::write(&parts_out_dir.0, serde_json::to_string(&info).unwrap()), + fs::write(&parts_out_file, serde_json::to_string(&info).unwrap()), &parts_out_dir.0 ); } @@ -238,13 +240,25 @@ impl CrateInfo { pub(crate) fn read_many(parts_paths: &[PathToParts]) -> Result, Error> { parts_paths .iter() - .map(|parts_path| { - let path = &parts_path.0; - let parts = try_err!(fs::read(path), &path); - let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), &path); - Ok::<_, Error>(parts) + .fold(Ok(Vec::new()), |acc, parts_path| { + let mut acc = acc?; + let dir = &parts_path.0; + acc.append(&mut try_err!(std::fs::read_dir(dir), dir.as_path()) + .filter_map(|file| { + let to_crate_info = |file: Result| -> Result, Error> { + let file = try_err!(file, dir.as_path()); + if file.path().extension() != Some(OsStr::new("json")) { + return Ok(None); + } + let parts = try_err!(fs::read(file.path()), file.path()); + let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), file.path()); + Ok(Some(parts)) + }; + to_crate_info(file).transpose() + }) + .collect::, Error>>()?); + Ok(acc) }) - .collect::, Error>>() } } diff --git a/tests/run-make/rustdoc-merge-directory/dep1.rs b/tests/run-make/rustdoc-merge-directory/dep1.rs new file mode 100644 index 0000000000000..5a1238adec0eb --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory/dep1.rs @@ -0,0 +1,4 @@ +//@ hasraw crates.js 'dep1' +//@ hasraw search.index/name/*.js 'Dep1' +//@ has dep1/index.html +pub struct Dep1; diff --git a/tests/run-make/rustdoc-merge-directory/dep2.rs b/tests/run-make/rustdoc-merge-directory/dep2.rs new file mode 100644 index 0000000000000..238ff2e4f9b70 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory/dep2.rs @@ -0,0 +1,4 @@ +//@ hasraw crates.js 'dep1' +//@ hasraw search.index/name/*.js 'Dep1' +//@ has dep2/index.html +pub struct Dep2; diff --git a/tests/run-make/rustdoc-merge-directory/dep_missing.rs b/tests/run-make/rustdoc-merge-directory/dep_missing.rs new file mode 100644 index 0000000000000..74236aef47ea5 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory/dep_missing.rs @@ -0,0 +1,4 @@ +//@ !hasraw crates.js 'dep_missing' +//@ !hasraw search.index/name/*.js 'DepMissing' +//@ has dep_missing/index.html +pub struct DepMissing; diff --git a/tests/run-make/rustdoc-merge-directory/rmake.rs b/tests/run-make/rustdoc-merge-directory/rmake.rs new file mode 100644 index 0000000000000..e4695ddad0b48 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory/rmake.rs @@ -0,0 +1,46 @@ +// Running --merge=finalize without an input crate root should not trigger ICE. +// Issue: https://github.com/rust-lang/rust/issues/146646 + +//@ needs-target-std + +use run_make_support::{htmldocck, path, rustdoc}; + +fn main() { + let out_dir = path("out"); + let merged_dir = path("merged"); + let parts_out_dir = path("parts"); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + rustdoc() + .input("dep2.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep2.json").exists()); + + // dep_missing is different, because --parts-out-dir is not supplied + rustdoc().input("dep_missing.rs").out_dir(&out_dir).run(); + assert!(parts_out_dir.join("dep2.json").exists()); + + let output = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + htmldocck().arg(&out_dir).arg("dep1.rs").run(); + htmldocck().arg(&out_dir).arg("dep2.rs").run(); + htmldocck().arg(out_dir).arg("dep_missing.rs").run(); +} diff --git a/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs b/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs index d750a36f44534..4dad01f341fef 100644 --- a/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs +++ b/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs @@ -16,7 +16,7 @@ fn main() { .arg(format!("--parts-out-dir={}", parts_out_dir.display())) .arg("--merge=none") .run(); - assert!(parts_out_dir.join("crate-info").exists()); + assert!(parts_out_dir.join("sierra.json").exists()); let output = rustdoc() .arg("-Zunstable-options") diff --git a/tests/ui/empty/empty-never-array.stderr b/tests/ui/empty/empty-never-array.stderr index ee04ff162a4cb..cd8a80e3d49d7 100644 --- a/tests/ui/empty/empty-never-array.stderr +++ b/tests/ui/empty/empty-never-array.stderr @@ -14,7 +14,7 @@ LL | enum Helper { LL | T(T, [!; 0]), | - not covered = note: the matched value is of type `Helper` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Helper::U(u) = Helper::T(t, []) else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/error-codes/E0005.stderr b/tests/ui/error-codes/E0005.stderr index c643ee07a3739..004812cad9f18 100644 --- a/tests/ui/error-codes/E0005.stderr +++ b/tests/ui/error-codes/E0005.stderr @@ -7,7 +7,7 @@ LL | let Some(y) = x; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Option` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Some(y) = x else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr index b596da8463f21..614f382d67327 100644 --- a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr @@ -7,7 +7,7 @@ LL | let Ok(_x) = &foo(); = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `&Result` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Ok(_x) = &foo() else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr index 65903dbe12e57..9e13cf510e838 100644 --- a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr +++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr @@ -17,7 +17,7 @@ LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `[i32; 8]` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr index 17b65c1dae548..dec0fe1fe0d79 100644 --- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr +++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr @@ -17,7 +17,7 @@ LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `[i32; 8]` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/lint/lint-deref-nullptr.rs b/tests/ui/lint/lint-deref-nullptr.rs index f83d88309b9a7..ed0cc7fa3ee95 100644 --- a/tests/ui/lint/lint-deref-nullptr.rs +++ b/tests/ui/lint/lint-deref-nullptr.rs @@ -1,13 +1,14 @@ // test the deref_nullptr lint -#![deny(deref_nullptr)] - use std::ptr; struct Struct { field: u8, } +#[derive(Clone, Copy)] +struct Zst; + fn f() { unsafe { let a = 1; @@ -32,6 +33,11 @@ fn f() { // ^^ OKAY let offset = ptr::addr_of!((*ptr::null::()).field); //~^ ERROR dereferencing a null pointer + + // Make sure the lint permits derefs of null pointers to ZSTs + let ok: Zst = *ptr::null(); + let ok: Zst = *ptr::null_mut(); + let ok: Zst = *(0 as *const Zst); } } diff --git a/tests/ui/lint/lint-deref-nullptr.stderr b/tests/ui/lint/lint-deref-nullptr.stderr index 175431b2994bd..1216e455485a0 100644 --- a/tests/ui/lint/lint-deref-nullptr.stderr +++ b/tests/ui/lint/lint-deref-nullptr.stderr @@ -1,53 +1,49 @@ error: dereferencing a null pointer - --> $DIR/lint-deref-nullptr.rs:15:18 + --> $DIR/lint-deref-nullptr.rs:16:18 | LL | let ub = *(0 as *const i32); | ^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | -note: the lint level is defined here - --> $DIR/lint-deref-nullptr.rs:3:9 - | -LL | #![deny(deref_nullptr)] - | ^^^^^^^^^^^^^ + = note: `#[deny(deref_nullptr)]` on by default error: dereferencing a null pointer - --> $DIR/lint-deref-nullptr.rs:17:18 + --> $DIR/lint-deref-nullptr.rs:18:18 | LL | let ub = *ptr::null::(); | ^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed error: dereferencing a null pointer - --> $DIR/lint-deref-nullptr.rs:19:18 + --> $DIR/lint-deref-nullptr.rs:20:18 | LL | let ub = *ptr::null_mut::(); | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed error: dereferencing a null pointer - --> $DIR/lint-deref-nullptr.rs:21:18 + --> $DIR/lint-deref-nullptr.rs:22:18 | LL | let ub = *(ptr::null::() as *const i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed error: dereferencing a null pointer - --> $DIR/lint-deref-nullptr.rs:23:18 + --> $DIR/lint-deref-nullptr.rs:24:18 | LL | let ub = *(ptr::null::() as *mut i32 as *mut usize as *const u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed error: dereferencing a null pointer - --> $DIR/lint-deref-nullptr.rs:25:19 + --> $DIR/lint-deref-nullptr.rs:26:19 | LL | let ub = &*ptr::null::(); | ^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed error: dereferencing a null pointer - --> $DIR/lint-deref-nullptr.rs:27:19 + --> $DIR/lint-deref-nullptr.rs:28:19 | LL | let ub = &*ptr::null_mut::(); | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed error: dereferencing a null pointer - --> $DIR/lint-deref-nullptr.rs:33:36 + --> $DIR/lint-deref-nullptr.rs:34:36 | LL | let offset = ptr::addr_of!((*ptr::null::()).field); | ^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed diff --git a/tests/ui/lint/lint-forbid-internal-unsafe.rs b/tests/ui/lint/lint-forbid-internal-unsafe.rs index 3ee55ba96b137..ab3769b06cbe3 100644 --- a/tests/ui/lint/lint-forbid-internal-unsafe.rs +++ b/tests/ui/lint/lint-forbid-internal-unsafe.rs @@ -13,5 +13,5 @@ macro_rules! evil { fn main() { println!("{}", evil!(*(0 as *const u8))); - //~^ WARNING dereferencing a null pointer + //~^ ERROR dereferencing a null pointer } diff --git a/tests/ui/lint/lint-forbid-internal-unsafe.stderr b/tests/ui/lint/lint-forbid-internal-unsafe.stderr index 52d9c8471e56e..a58bd467f6757 100644 --- a/tests/ui/lint/lint-forbid-internal-unsafe.stderr +++ b/tests/ui/lint/lint-forbid-internal-unsafe.stderr @@ -10,13 +10,13 @@ note: the lint level is defined here LL | #![forbid(unsafe_code)] | ^^^^^^^^^^^ -warning: dereferencing a null pointer +error: dereferencing a null pointer --> $DIR/lint-forbid-internal-unsafe.rs:15:26 | LL | println!("{}", evil!(*(0 as *const u8))); | ^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | - = note: `#[warn(deref_nullptr)]` on by default + = note: `#[deny(deref_nullptr)]` on by default -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/issue-106552.stderr b/tests/ui/pattern/issue-106552.stderr index 6d9a989f182ea..06f33ecf10667 100644 --- a/tests/ui/pattern/issue-106552.stderr +++ b/tests/ui/pattern/issue-106552.stderr @@ -25,7 +25,7 @@ LL | let x @ 5 = 6; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` -help: you might want to use `let else` to handle the variants that aren't matched +help: you might want to use `let...else` to handle the variants that aren't matched | LL | let x @ 5 = 6 else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr index d241f417553fc..a234ad435c970 100644 --- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr @@ -152,7 +152,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result<&u32, &!>` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr index ea63d7ba1afd1..3fff1a3805c82 100644 --- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr @@ -106,7 +106,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result<&u32, &!>` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; | ++++++++++++++++ @@ -120,7 +120,7 @@ LL | let Ok(_x) = &res_u32_never; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `&Result` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Ok(_x) = &res_u32_never else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr index a1a44e7774428..28f9650557efc 100644 --- a/tests/ui/pattern/usefulness/empty-types.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr @@ -97,7 +97,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result<&u32, &!>` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; | ++++++++++++++++ @@ -111,7 +111,7 @@ LL | let Ok(_x) = &res_u32_never; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `&Result` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Ok(_x) = &res_u32_never else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/pattern/usefulness/issue-31561.stderr b/tests/ui/pattern/usefulness/issue-31561.stderr index 382b2337ffaba..389c1126b9848 100644 --- a/tests/ui/pattern/usefulness/issue-31561.stderr +++ b/tests/ui/pattern/usefulness/issue-31561.stderr @@ -17,7 +17,7 @@ LL | Bar, LL | Baz | --- not covered = note: the matched value is of type `Thing` -help: you might want to use `let else` to handle the variants that aren't matched +help: you might want to use `let...else` to handle the variants that aren't matched | LL | let Thing::Foo(y) = Thing::Foo(1) else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr index 48d7a636055dc..d31510d66e0c9 100644 --- a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr +++ b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr @@ -183,7 +183,7 @@ LL | enum Opt { LL | None, | ---- not covered = note: the matched value is of type `Opt` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Opt::Some(ref _x) = e else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr index 35d436a1413ed..cd78c0f0bb45c 100644 --- a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -7,7 +7,7 @@ LL | let Ok(x) = res; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result>` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Ok(x) = res else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr index c2c9ac15ab220..f8bf6f8cb28bc 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr @@ -138,7 +138,7 @@ LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `NonExhaustiveEnum` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/uninhabited/missing-if-let-or-let-else.rs b/tests/ui/uninhabited/missing-if-let-or-let-else.rs index 51fedb797562c..c8cc672a82aa4 100644 --- a/tests/ui/uninhabited/missing-if-let-or-let-else.rs +++ b/tests/ui/uninhabited/missing-if-let-or-let-else.rs @@ -6,14 +6,14 @@ fn a() { } fn b() { let Some(x) = foo() { //~ ERROR expected one of - //~^ HELP you might have meant to use `let else` + //~^ HELP you might have meant to use `let...else` return; } } fn c() { let Some(x) = foo() { //~ ERROR expected one of //~^ HELP you might have meant to use `if let` - //~| HELP alternatively, you might have meant to use `let else` + //~| HELP alternatively, you might have meant to use `let...else` // The parser check happens pre-macro-expansion, so we don't know for sure. println!("{x}"); } diff --git a/tests/ui/uninhabited/missing-if-let-or-let-else.stderr b/tests/ui/uninhabited/missing-if-let-or-let-else.stderr index 4b78a0fa16e8d..f13147dd7fc50 100644 --- a/tests/ui/uninhabited/missing-if-let-or-let-else.stderr +++ b/tests/ui/uninhabited/missing-if-let-or-let-else.stderr @@ -15,7 +15,7 @@ error: expected one of `.`, `;`, `?`, `else`, or an operator, found `{` LL | let Some(x) = foo() { | ^ expected one of `.`, `;`, `?`, `else`, or an operator | -help: you might have meant to use `let else` +help: you might have meant to use `let...else` | LL | let Some(x) = foo() else { | ++++ @@ -30,7 +30,7 @@ help: you might have meant to use `if let` | LL | if let Some(x) = foo() { | ++ -help: alternatively, you might have meant to use `let else` +help: alternatively, you might have meant to use `let...else` | LL | let Some(x) = foo() else { | ++++ diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr index 0e87f14aa14ae..a4270c29ff35b 100644 --- a/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr +++ b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr @@ -16,7 +16,7 @@ LL | A(foo::SecretlyEmpty), | - not covered = note: pattern `Foo::A(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future = note: the matched value is of type `Foo` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Foo::D(_y, _z) = x else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr index 0e87f14aa14ae..a4270c29ff35b 100644 --- a/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr +++ b/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr @@ -16,7 +16,7 @@ LL | A(foo::SecretlyEmpty), | - not covered = note: pattern `Foo::A(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future = note: the matched value is of type `Foo` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let Foo::D(_y, _z) = x else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.rs b/tests/ui/uninhabited/uninhabited-irrefutable.rs index 3f7414e596bf1..9f4731e6e71a2 100644 --- a/tests/ui/uninhabited/uninhabited-irrefutable.rs +++ b/tests/ui/uninhabited/uninhabited-irrefutable.rs @@ -34,5 +34,5 @@ fn main() { //~| NOTE for more information //~| NOTE pattern `Foo::A(_)` is currently uninhabited //~| NOTE the matched value is of type `Foo` - //~| HELP you might want to use `let else` + //~| HELP you might want to use `let...else` } diff --git a/tests/ui/unreachable-code/unreachable-bool-read-7246.rs b/tests/ui/unreachable-code/unreachable-bool-read-7246.rs index 8bbaa1025493f..212828679800b 100644 --- a/tests/ui/unreachable-code/unreachable-bool-read-7246.rs +++ b/tests/ui/unreachable-code/unreachable-bool-read-7246.rs @@ -5,7 +5,7 @@ use std::ptr; pub unsafe fn g() { return; if *ptr::null() {}; //~ ERROR unreachable - //~| WARNING dereferencing a null pointer + //~| ERROR dereferencing a null pointer } pub fn main() {} diff --git a/tests/ui/unreachable-code/unreachable-bool-read-7246.stderr b/tests/ui/unreachable-code/unreachable-bool-read-7246.stderr index 6072160cb5f13..6e4123760a791 100644 --- a/tests/ui/unreachable-code/unreachable-bool-read-7246.stderr +++ b/tests/ui/unreachable-code/unreachable-bool-read-7246.stderr @@ -12,13 +12,13 @@ note: the lint level is defined here LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ -warning: dereferencing a null pointer +error: dereferencing a null pointer --> $DIR/unreachable-bool-read-7246.rs:7:8 | LL | if *ptr::null() {}; | ^^^^^^^^^^^^ this code causes undefined behavior when executed | - = note: `#[warn(deref_nullptr)]` on by default + = note: `#[deny(deref_nullptr)]` on by default -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors