diff options
20 files changed, 178 insertions, 86 deletions
diff --git a/.mailmap b/.mailmap index 9148b79e980..b8a9fc27eb7 100644 --- a/.mailmap +++ b/.mailmap @@ -415,6 +415,7 @@ Nick Platt <platt.nicholas@gmail.com> Niclas Schwarzlose <15schnic@gmail.com> Nicolas Abram <abramlujan@gmail.com> Nicole Mazzuca <npmazzuca@gmail.com> +Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> nils <48135649+Nilstrieb@users.noreply.github.com> Nif Ward <nif.ward@gmail.com> Nika Layzell <nika@thelayzells.com> <michael@thelayzells.com> NODA Kai <nodakai@gmail.com> diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 580451ba265..63e8a67db53 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1190,8 +1190,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // Set KCFI operand bundle let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; let kcfi_bundle = - if self.tcx.sess.is_sanitizer_kcfi_enabled() && fn_abi.is_some() && is_indirect_call { - let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap()); + if let Some(fn_abi) = fn_abi && self.tcx.sess.is_sanitizer_kcfi_enabled() && is_indirect_call { + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi); Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) } else { None diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d6fd057c5a4..4b1ff0e1df9 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2235,7 +2235,7 @@ impl EmitterWriter { } } else if is_multiline { buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber); - match &highlight_parts[..] { + match &highlight_parts { [SubstitutionHighlight { start: 0, end }] if *end == line_to_add.len() => { buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 1f9c993adff..d53e64830ff 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2399,10 +2399,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let suggestion = if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) }; let mut suggestions = vec![(sp, suggestion)]; - for add_lt_sugg in add_lt_suggs { - if let Some(add_lt_sugg) = add_lt_sugg { - suggestions.push(add_lt_sugg); - } + for add_lt_sugg in add_lt_suggs.into_iter().flatten() { + suggestions.push(add_lt_sugg); } err.multipart_suggestion_verbose( format!("{msg}..."), @@ -2426,11 +2424,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let mut sugg = vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))]; - for add_lt_sugg in add_lt_suggs.clone() { - if let Some(lt) = add_lt_sugg { - sugg.push(lt); - sugg.rotate_right(1); - } + for lt in add_lt_suggs.clone().into_iter().flatten() { + sugg.push(lt); + sugg.rotate_right(1); } // `MaybeIncorrect` due to issue #41966. err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect); diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index be66d0d4765..9edd7967e7a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -300,6 +300,7 @@ use rustc_arena::TypedArena; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::DefId; use rustc_hir::HirId; +use rustc_hir::Node; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_span::{Span, DUMMY_SP}; @@ -867,6 +868,8 @@ fn is_useful<'p, 'tcx>( &ctor, Constructor::Missing { nonexhaustive_enum_missing_real_variants: true } ) + // We don't want to lint patterns which are function arguments or locals + && !matches!(cx.tcx.hir().find_parent(hir_id), Some(Node::Param(_)|Node::Local(_))) { let patterns = { let mut split_wildcard = SplitWildcard::new(pcx); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index d34fa39352f..f41edff8513 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -651,8 +651,8 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance); let span = tcx.def_span(instance.def_id()); let mut path = PathBuf::new(); - let was_written = if written_to_path.is_some() { - path = written_to_path.unwrap(); + let was_written = if let Some(path2) = written_to_path { + path = path2; Some(()) } else { None diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index d727aba6de5..0bb42a3a71f 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -109,7 +109,7 @@ fn assert_default_hashing_controls<CTX: HashStableContext>(ctx: &CTX, msg: &str) // This is the case for instance when building a hash for name mangling. // Such configuration must not be used for metadata. HashingControls { hash_spans } - if hash_spans == !ctx.unstable_opts_incremental_ignore_spans() => {} + if hash_spans != ctx.unstable_opts_incremental_ignore_spans() => {} other => panic!("Attempted hashing of {msg} with non-default HashingControls: {other:?}"), } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index be0817472ea..fb75ec76729 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3888,8 +3888,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some(slice_ty) = candidate_impls .iter() .map(|trait_ref| trait_ref.trait_ref.self_ty()) - .filter(|t| is_slice(*t)) - .next() + .find(|t| is_slice(*t)) { let msg = &format!("convert the array to a `{}` slice instead", slice_ty); @@ -3936,7 +3935,7 @@ fn hint_missing_borrow<'tcx>( // This could be a variant constructor, for example. let Some(fn_decl) = found_node.fn_decl() else { return; }; - let args = fn_decl.inputs.iter().map(|ty| ty); + let args = fn_decl.inputs.iter(); fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec<hir::Mutability>) { let mut refs = vec![]; diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 64a6ce51b2e..44adcfa1a94 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -1,6 +1,13 @@ -use crate::cell::{Cell, OnceCell}; -use crate::fmt; use crate::ops::Deref; +use crate::{fmt, mem}; + +use super::UnsafeCell; + +enum State<T, F> { + Uninit(F), + Init(T), + Poisoned, +} /// A value which is initialized on the first access. /// @@ -31,8 +38,7 @@ use crate::ops::Deref; /// ``` #[unstable(feature = "lazy_cell", issue = "109736")] pub struct LazyCell<T, F = fn() -> T> { - cell: OnceCell<T>, - init: Cell<Option<F>>, + state: UnsafeCell<State<T, F>>, } impl<T, F: FnOnce() -> T> LazyCell<T, F> { @@ -53,8 +59,8 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> { /// ``` #[inline] #[unstable(feature = "lazy_cell", issue = "109736")] - pub const fn new(init: F) -> LazyCell<T, F> { - LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) } + pub const fn new(f: F) -> LazyCell<T, F> { + LazyCell { state: UnsafeCell::new(State::Uninit(f)) } } /// Forces the evaluation of this lazy value and returns a reference to @@ -77,10 +83,65 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> { #[inline] #[unstable(feature = "lazy_cell", issue = "109736")] pub fn force(this: &LazyCell<T, F>) -> &T { - this.cell.get_or_init(|| match this.init.take() { - Some(f) => f(), - None => panic!("`Lazy` instance has previously been poisoned"), - }) + // SAFETY: + // This invalidates any mutable references to the data. The resulting + // reference lives either until the end of the borrow of `this` (in the + // initialized case) or is invalidated in `really_init` (in the + // uninitialized case; `really_init` will create and return a fresh reference). + let state = unsafe { &*this.state.get() }; + match state { + State::Init(data) => data, + // SAFETY: The state is uninitialized. + State::Uninit(_) => unsafe { LazyCell::really_init(this) }, + State::Poisoned => panic!("LazyCell has previously been poisoned"), + } + } + + /// # Safety + /// May only be called when the state is `Uninit`. + #[cold] + unsafe fn really_init(this: &LazyCell<T, F>) -> &T { + // SAFETY: + // This function is only called when the state is uninitialized, + // so no references to `state` can exist except for the reference + // in `force`, which is invalidated here and not accessed again. + let state = unsafe { &mut *this.state.get() }; + // Temporarily mark the state as poisoned. This prevents reentrant + // accesses and correctly poisons the cell if the closure panicked. + let State::Uninit(f) = mem::replace(state, State::Poisoned) else { unreachable!() }; + + let data = f(); + + // SAFETY: + // If the closure accessed the cell through something like a reentrant + // mutex, but caught the panic resulting from the state being poisoned, + // the mutable borrow for `state` will be invalidated, so we need to + // go through the `UnsafeCell` pointer here. The state can only be + // poisoned at this point, so using `write` to skip the destructor + // of `State` should help the optimizer. + unsafe { this.state.get().write(State::Init(data)) }; + + // SAFETY: + // The previous references were invalidated by the `write` call above, + // so do a new shared borrow of the state instead. + let state = unsafe { &*this.state.get() }; + let State::Init(data) = state else { unreachable!() }; + data + } +} + +impl<T, F> LazyCell<T, F> { + #[inline] + fn get(&self) -> Option<&T> { + // SAFETY: + // This is sound for the same reason as in `force`: once the state is + // initialized, it will not be mutably accessed again, so this reference + // will stay valid for the duration of the borrow to `self`. + let state = unsafe { &*self.state.get() }; + match state { + State::Init(data) => Some(data), + _ => None, + } } } @@ -105,6 +166,11 @@ impl<T: Default> Default for LazyCell<T> { #[unstable(feature = "lazy_cell", issue = "109736")] impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish() + let mut d = f.debug_tuple("LazyCell"); + match self.get() { + Some(data) => d.field(data), + None => d.field(&format_args!("<uninit>")), + }; + d.finish() } } diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 080330fa41e..36cf7defd6d 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2120,8 +2120,8 @@ pub trait Iterator { /// /// # Current implementation /// - /// Current algorithms tries finding the first element for which the predicate evaluates - /// to false, and the last element for which it evaluates to true and repeatedly swaps them. + /// The current algorithm tries to find the first element for which the predicate evaluates + /// to false and the last element for which it evaluates to true, and repeatedly swaps them. /// /// Time complexity: *O*(*n*) /// diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 99a4e0b5106..a40d39c5e44 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -268,7 +268,7 @@ impl AsFd for OwnedFd { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { // Safety: `OwnedFd` and `BorrowedFd` have the same validity - // invariants, and the `BorrowdFd` is bounded by the lifetime + // invariants, and the `BorrowedFd` is bounded by the lifetime // of `&self`. unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } } diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 27236e191fd..965dfa5f398 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -12,17 +12,6 @@ dependencies = [ ] [[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -47,7 +36,6 @@ dependencies = [ name = "bootstrap" version = "0.0.0" dependencies = [ - "atty", "build_helper", "cc", "cmake", @@ -56,6 +44,7 @@ dependencies = [ "getopts", "hex", "ignore", + "is-terminal", "libc", "object", "once_cell", @@ -212,13 +201,13 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "errno" -version = "0.2.8" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys", ] [[package]] @@ -233,9 +222,9 @@ dependencies = [ [[package]] name = "fd-lock" -version = "3.0.8" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb21c69b9fea5e15dbc1049e4b77145dd0ba1c84019c488102de0dc4ea4b0a27" +checksum = "9799aefb4a2e4a01cc47610b1dd47c18ab13d991f27bbcaed9296f5a53d5cbad" dependencies = [ "cfg-if", "rustix", @@ -302,6 +291,12 @@ dependencies = [ ] [[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -327,15 +322,28 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.1" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87" +checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" dependencies = [ + "hermit-abi 0.3.1", "libc", "windows-sys", ] [[package]] +name = "is-terminal" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys", +] + +[[package]] name = "itoa" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -349,15 +357,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "linux-raw-sys" -version = "0.1.3" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "log" @@ -409,7 +417,7 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] @@ -540,9 +548,9 @@ checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "rustix" -version = "0.36.3" +version = "0.37.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e" +checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849" dependencies = [ "bitflags", "errno", @@ -753,17 +761,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows-targets", ] [[package]] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 5c659800bdb..2fbe7aa57aa 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -30,7 +30,7 @@ path = "bin/sccache-plus-cl.rs" test = false [dependencies] -atty = "0.2.14" +is-terminal = "0.4" build_helper = { path = "../tools/build_helper" } cmake = "0.1.38" filetime = "0.2" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 0eba18c3a63..b8b6b7b2d4e 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -808,6 +808,8 @@ define_config! { impl Config { pub fn default_opts() -> Config { + use is_terminal::IsTerminal; + let mut config = Config::default(); config.llvm_optimize = true; config.ninja_in_file = true; @@ -828,8 +830,8 @@ impl Config { config.dist_include_mingw_linker = true; config.dist_compression_profile = "fast".into(); - config.stdout_is_tty = atty::is(atty::Stream::Stdout); - config.stderr_is_tty = atty::is(atty::Stream::Stderr); + config.stdout_is_tty = std::io::stdout().is_terminal(); + config.stderr_is_tty = std::io::stderr().is_terminal(); // set by build.rs config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE")); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 2c514a0c826..ea8c7e9a67c 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -31,18 +31,13 @@ use crate::passes::{self, Condition}; use crate::scrape_examples::{AllCallLocations, ScrapeExamplesOptions}; use crate::theme; -#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] pub(crate) enum OutputFormat { Json, + #[default] Html, } -impl Default for OutputFormat { - fn default() -> OutputFormat { - OutputFormat::Html - } -} - impl OutputFormat { pub(crate) fn is_json(&self) -> bool { matches!(self, OutputFormat::Json) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index c099d0e4f3f..b61dd571458 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -177,8 +177,8 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> { } else { // We only want to "open" the tag ourselves if we have more than one pending and if the // current parent tag is not the same as our pending content. - let close_tag = if self.pending_elems.len() > 1 && current_class.is_some() { - Some(enter_span(self.out, current_class.unwrap(), &self.href_context)) + let close_tag = if self.pending_elems.len() > 1 && let Some(current_class) = current_class { + Some(enter_span(self.out, current_class, &self.href_context)) } else { None }; diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 94ad4753d7c..455b4e9aefe 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -113,11 +113,8 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf } else { ("", "") }; - let version = if it.is_crate() { - cx.cache().crate_version.as_ref().map(String::as_str).unwrap_or_default() - } else { - "" - }; + let version = + if it.is_crate() { cx.cache().crate_version.as_deref().unwrap_or_default() } else { "" }; let path: String = if !it.is_mod() { cx.current.iter().map(|s| s.as_str()).intersperse("::").collect() } else { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 4188aa1037f..1c6ab44a4c7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -810,7 +810,7 @@ fn trait_impls_for<'a>( /// /// These are common and we should just resolve to the trait in that case. fn is_derive_trait_collision<T>(ns: &PerNS<Result<Vec<(Res, T)>, ResolutionFailure<'_>>>) -> bool { - if let (&Ok(ref type_ns), &Ok(ref macro_ns)) = (&ns.type_ns, &ns.macro_ns) { + if let (Ok(type_ns), Ok(macro_ns)) = (&ns.type_ns, &ns.macro_ns) { type_ns.iter().any(|(res, _)| matches!(res, Res::Def(DefKind::Trait, _))) && macro_ns .iter() diff --git a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs index d8f07bb8f24..7ef1d635d9c 100644 --- a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs +++ b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs @@ -184,4 +184,20 @@ fn main() { // OK: both unstable and stable fields are matched with feature on #[warn(non_exhaustive_omitted_patterns)] let UnstableStruct { stable, stable2, unstable, .. } = UnstableStruct::default(); + + // Ok: local bindings are allowed + #[deny(non_exhaustive_omitted_patterns)] + let local = NonExhaustiveEnum::Unit; + + // Ok: missing patterns will be blocked by the pattern being refutable + #[deny(non_exhaustive_omitted_patterns)] + let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit; + //~^ refutable pattern in local binding + +} + +#[deny(non_exhaustive_omitted_patterns)] +// Ok: Pattern in a param is always wildcard +pub fn takes_non_exhaustive(_: NonExhaustiveEnum) { + let _closure = |_: NonExhaustiveEnum| {}; } diff --git a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr index 996bd4a1298..617c629a4fe 100644 --- a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr +++ b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr @@ -184,5 +184,20 @@ note: the lint level is defined here LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors; 6 warnings emitted +error[E0005]: refutable pattern in local binding + --> $DIR/omitted-patterns.rs:194:9 + | +LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `_` not covered + | + = 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/ch18-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 + | +LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit else { todo!() }; + | ++++++++++++++++ + +error: aborting due to 9 previous errors; 6 warnings emitted +For more information about this error, try `rustc --explain E0005`. |
