Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9859bf2

Browse files
committedAug 14, 2024·
Auto merge of rust-lang#129076 - matthiaskrgr:rollup-rg8mi2x, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#128410 (Migrate `remap-path-prefix-dwarf` `run-make` test to rmake) - rust-lang#128759 (alloc: add ToString specialization for `&&str`) - rust-lang#128873 (Add windows-targets crate to std's sysroot) - rust-lang#129001 (chore(lib): Enhance documentation for core::fmt::Formatter's write_fm…) - rust-lang#129061 (Use `is_lang_item` more) - rust-lang#129062 (Remove a no-longer-true assert) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e9c965d + e01d614 commit 9859bf2

File tree

38 files changed

+543
-261
lines changed

38 files changed

+543
-261
lines changed
 

‎compiler/rustc_hir_typeck/src/check.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,11 @@ pub(super) fn check_fn<'a, 'tcx>(
160160
fcx.demand_suptype(span, ret_ty, actual_return_ty);
161161

162162
// Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
163-
if let Some(panic_impl_did) = tcx.lang_items().panic_impl()
164-
&& panic_impl_did == fn_def_id.to_def_id()
165-
{
166-
check_panic_info_fn(tcx, panic_impl_did.expect_local(), fn_sig);
163+
if tcx.is_lang_item(fn_def_id.to_def_id(), LangItem::PanicImpl) {
164+
check_panic_info_fn(tcx, fn_def_id, fn_sig);
167165
}
168166

169-
if let Some(lang_start_defid) = tcx.lang_items().start_fn()
170-
&& lang_start_defid == fn_def_id.to_def_id()
171-
{
167+
if tcx.is_lang_item(fn_def_id.to_def_id(), LangItem::Start) {
172168
check_lang_start_fn(tcx, fn_sig, fn_def_id);
173169
}
174170

‎compiler/rustc_lint/src/for_loops_over_fallibles.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use hir::{Expr, Pat};
2-
use rustc_hir as hir;
2+
use rustc_hir::{self as hir, LangItem};
33
use rustc_infer::infer::TyCtxtInferExt;
44
use rustc_infer::traits::ObligationCause;
55
use rustc_middle::ty;
@@ -126,7 +126,10 @@ fn extract_iterator_next_call<'tcx>(
126126
) -> Option<&'tcx Expr<'tcx>> {
127127
// This won't work for `Iterator::next(iter)`, is this an issue?
128128
if let hir::ExprKind::MethodCall(_, recv, _, _) = expr.kind
129-
&& cx.typeck_results().type_dependent_def_id(expr.hir_id) == cx.tcx.lang_items().next_fn()
129+
&& cx
130+
.typeck_results()
131+
.type_dependent_def_id(expr.hir_id)
132+
.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::IteratorNext))
130133
{
131134
Some(recv)
132135
} else {

‎compiler/rustc_lint/src/traits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
114114
let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else { return };
115115
for (bound, modifier) in &bounds[..] {
116116
let def_id = bound.trait_ref.trait_def_id();
117-
if cx.tcx.lang_items().drop_trait() == def_id
117+
if def_id.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::Drop))
118118
&& *modifier != hir::TraitBoundModifier::Maybe
119119
{
120120
let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return };

‎compiler/rustc_middle/src/ty/diagnostics.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ use std::ops::ControlFlow;
66

77
use rustc_data_structures::fx::FxHashMap;
88
use rustc_errors::{into_diag_arg_using_display, Applicability, Diag, DiagArgValue, IntoDiagArg};
9-
use rustc_hir as hir;
109
use rustc_hir::def::DefKind;
1110
use rustc_hir::def_id::DefId;
12-
use rustc_hir::{PredicateOrigin, WherePredicate};
11+
use rustc_hir::{self as hir, LangItem, PredicateOrigin, WherePredicate};
1312
use rustc_span::{BytePos, Span};
1413
use rustc_type_ir::TyKind::*;
1514

@@ -290,8 +289,9 @@ pub fn suggest_constraining_type_params<'a>(
290289
let Some(param) = param else { return false };
291290

292291
{
293-
let mut sized_constraints =
294-
constraints.extract_if(|(_, def_id)| *def_id == tcx.lang_items().sized_trait());
292+
let mut sized_constraints = constraints.extract_if(|(_, def_id)| {
293+
def_id.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Sized))
294+
});
295295
if let Some((_, def_id)) = sized_constraints.next() {
296296
applicability = Applicability::MaybeIncorrect;
297297

‎compiler/rustc_middle/src/ty/instance.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ impl<'tcx> Instance<'tcx> {
838838
return None;
839839
};
840840

841-
if tcx.lang_items().get(coroutine_callable_item) == Some(trait_item_id) {
841+
if tcx.is_lang_item(trait_item_id, coroutine_callable_item) {
842842
let ty::Coroutine(_, id_args) = *tcx.type_of(coroutine_def_id).skip_binder().kind()
843843
else {
844844
bug!()

‎compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
11451145
let term = if let Some(ty) = term.skip_binder().as_type()
11461146
&& let ty::Alias(ty::Projection, proj) = ty.kind()
11471147
&& let Some(assoc) = tcx.opt_associated_item(proj.def_id)
1148-
&& assoc.trait_container(tcx) == tcx.lang_items().coroutine_trait()
1148+
&& assoc
1149+
.trait_container(tcx)
1150+
.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Coroutine))
11491151
&& assoc.name == rustc_span::sym::Return
11501152
{
11511153
if let ty::Coroutine(_, args) = args.type_at(0).kind() {

‎compiler/rustc_middle/src/ty/sty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1916,7 +1916,7 @@ impl<'tcx> Ty<'tcx> {
19161916

19171917
pub fn is_c_void(self, tcx: TyCtxt<'_>) -> bool {
19181918
match self.kind() {
1919-
ty::Adt(adt, _) => tcx.lang_items().get(LangItem::CVoid) == Some(adt.did()),
1919+
ty::Adt(adt, _) => tcx.is_lang_item(adt.did(), LangItem::CVoid),
19201920
_ => false,
19211921
}
19221922
}

‎compiler/rustc_mir_build/src/thir/pattern/check_match.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -702,10 +702,12 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
702702
&& adt.is_enum()
703703
&& let Constructor::Variant(variant_index) = witness_1.ctor()
704704
{
705-
let variant = adt.variant(*variant_index);
706-
let inhabited = variant.inhabited_predicate(self.tcx, *adt).instantiate(self.tcx, args);
707-
assert!(inhabited.apply(self.tcx, cx.param_env, cx.module));
708-
!inhabited.apply_ignore_module(self.tcx, cx.param_env)
705+
let variant_inhabited = adt
706+
.variant(*variant_index)
707+
.inhabited_predicate(self.tcx, *adt)
708+
.instantiate(self.tcx, args);
709+
variant_inhabited.apply(self.tcx, cx.param_env, cx.module)
710+
&& !variant_inhabited.apply_ignore_module(self.tcx, cx.param_env)
709711
} else {
710712
false
711713
};

‎compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,9 @@ fn characteristic_def_id_of_mono_item<'tcx>(
648648

649649
if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
650650
if tcx.sess.opts.incremental.is_some()
651-
&& tcx.trait_id_of_impl(impl_def_id) == tcx.lang_items().drop_trait()
651+
&& tcx
652+
.trait_id_of_impl(impl_def_id)
653+
.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Drop))
652654
{
653655
// Put `Drop::drop` into the same cgu as `drop_in_place`
654656
// since `drop_in_place` is the only thing that can

‎compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_hir as hir;
44
use rustc_hir::def::DefKind;
55
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
66
use rustc_middle::ty::error::{ExpectedFound, TypeError};
7+
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
78
use rustc_middle::ty::print::{FmtPrinter, Printer};
89
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
910
use rustc_span::def_id::DefId;
@@ -313,11 +314,15 @@ impl<T> Trait<T> for X {
313314
(ty::Dynamic(t, _, ty::DynKind::Dyn), _)
314315
if let Some(def_id) = t.principal_def_id() =>
315316
{
316-
let mut impl_def_ids = vec![];
317+
let mut has_matching_impl = false;
317318
tcx.for_each_relevant_impl(def_id, values.found, |did| {
318-
impl_def_ids.push(did)
319+
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
320+
.types_may_unify(values.found, tcx.type_of(did).skip_binder())
321+
{
322+
has_matching_impl = true;
323+
}
319324
});
320-
if let [_] = &impl_def_ids[..] {
325+
if has_matching_impl {
321326
let trait_name = tcx.item_name(def_id);
322327
diag.help(format!(
323328
"`{}` implements `{trait_name}` so you could box the found value \
@@ -330,11 +335,15 @@ impl<T> Trait<T> for X {
330335
(_, ty::Dynamic(t, _, ty::DynKind::Dyn))
331336
if let Some(def_id) = t.principal_def_id() =>
332337
{
333-
let mut impl_def_ids = vec![];
338+
let mut has_matching_impl = false;
334339
tcx.for_each_relevant_impl(def_id, values.expected, |did| {
335-
impl_def_ids.push(did)
340+
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
341+
.types_may_unify(values.expected, tcx.type_of(did).skip_binder())
342+
{
343+
has_matching_impl = true;
344+
}
336345
});
337-
if let [_] = &impl_def_ids[..] {
346+
if has_matching_impl {
338347
let trait_name = tcx.item_name(def_id);
339348
diag.help(format!(
340349
"`{}` implements `{trait_name}` so you could change the expected \
@@ -346,11 +355,15 @@ impl<T> Trait<T> for X {
346355
(ty::Dynamic(t, _, ty::DynKind::DynStar), _)
347356
if let Some(def_id) = t.principal_def_id() =>
348357
{
349-
let mut impl_def_ids = vec![];
358+
let mut has_matching_impl = false;
350359
tcx.for_each_relevant_impl(def_id, values.found, |did| {
351-
impl_def_ids.push(did)
360+
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
361+
.types_may_unify(values.found, tcx.type_of(did).skip_binder())
362+
{
363+
has_matching_impl = true;
364+
}
352365
});
353-
if let [_] = &impl_def_ids[..] {
366+
if has_matching_impl {
354367
let trait_name = tcx.item_name(def_id);
355368
diag.help(format!(
356369
"`{}` implements `{trait_name}`, `#[feature(dyn_star)]` is likely \

‎compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
230230
post_message,
231231
);
232232

233-
let (err_msg, safe_transmute_explanation) = if Some(main_trait_ref.def_id())
234-
== self.tcx.lang_items().transmute_trait()
233+
let (err_msg, safe_transmute_explanation) = if self.tcx.is_lang_item(main_trait_ref.def_id(), LangItem::TransmuteTrait)
235234
{
236235
// Recompute the safe transmute reason and use that for the error reporting
237236
match self.get_safe_transmute_error_and_reason(

‎compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2831,7 +2831,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
28312831
// Do not suggest relaxing if there is an explicit `Sized` obligation.
28322832
&& !bounds.iter()
28332833
.filter_map(|bound| bound.trait_ref())
2834-
.any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait())
2834+
.any(|tr| tr.trait_def_id().is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Sized)))
28352835
{
28362836
let (span, separator) = if let [.., last] = bounds {
28372837
(last.span().shrink_to_hi(), " +")

‎compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_hir::LangItem;
12
use rustc_infer::traits::Obligation;
23
pub use rustc_middle::traits::query::type_op::ProvePredicate;
34
use rustc_middle::traits::query::NoSolution;
@@ -20,8 +21,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
2021
// such cases.
2122
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) =
2223
key.value.predicate.kind().skip_binder()
23-
&& let Some(sized_def_id) = tcx.lang_items().sized_trait()
24-
&& trait_ref.def_id() == sized_def_id
24+
&& tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized)
2525
&& trait_ref.self_ty().is_trivially_sized(tcx)
2626
{
2727
return Some(());

‎compiler/rustc_ty_utils/src/abi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ fn fn_abi_new_uncached<'tcx>(
621621
let rust_abi = matches!(sig.abi, RustIntrinsic | Rust | RustCall);
622622

623623
let is_drop_in_place =
624-
fn_def_id.is_some() && fn_def_id == cx.tcx.lang_items().drop_in_place_fn();
624+
fn_def_id.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::DropInPlace));
625625

626626
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, &'tcx FnAbiError<'tcx>> {
627627
let span = tracing::debug_span!("arg_of");

‎library/Cargo.lock

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ dependencies = [
339339
"std_detect",
340340
"unwind",
341341
"wasi",
342+
"windows-targets 0.0.0",
342343
]
343344

344345
[[package]]
@@ -421,9 +422,13 @@ version = "0.52.0"
421422
source = "registry+https://github.com/rust-lang/crates.io-index"
422423
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
423424
dependencies = [
424-
"windows-targets",
425+
"windows-targets 0.52.5",
425426
]
426427

428+
[[package]]
429+
name = "windows-targets"
430+
version = "0.0.0"
431+
427432
[[package]]
428433
name = "windows-targets"
429434
version = "0.52.5"

‎library/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ members = [
88
exclude = [
99
# stdarch has its own Cargo workspace
1010
"stdarch",
11+
"windows_targets"
1112
]
1213

1314
[profile.release.package.compiler_builtins]

‎library/alloc/src/string.rs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,14 +2643,54 @@ impl ToString for i8 {
26432643
}
26442644
}
26452645

2646-
#[doc(hidden)]
2646+
// Generic/generated code can sometimes have multiple, nested references
2647+
// for strings, including `&&&str`s that would never be written
2648+
// by hand. This macro generates twelve layers of nested `&`-impl
2649+
// for primitive strings.
26472650
#[cfg(not(no_global_oom_handling))]
2648-
#[stable(feature = "str_to_string_specialization", since = "1.9.0")]
2649-
impl ToString for str {
2650-
#[inline]
2651-
fn to_string(&self) -> String {
2652-
String::from(self)
2653-
}
2651+
macro_rules! to_string_str_wrap_in_ref {
2652+
{x $($x:ident)*} => {
2653+
&to_string_str_wrap_in_ref! { $($x)* }
2654+
};
2655+
{} => { str };
2656+
}
2657+
#[cfg(not(no_global_oom_handling))]
2658+
macro_rules! to_string_expr_wrap_in_deref {
2659+
{$self:expr ; x $($x:ident)*} => {
2660+
*(to_string_expr_wrap_in_deref! { $self ; $($x)* })
2661+
};
2662+
{$self:expr ;} => { $self };
2663+
}
2664+
#[cfg(not(no_global_oom_handling))]
2665+
macro_rules! to_string_str {
2666+
{$($($x:ident)*),+} => {
2667+
$(
2668+
#[doc(hidden)]
2669+
#[stable(feature = "str_to_string_specialization", since = "1.9.0")]
2670+
impl ToString for to_string_str_wrap_in_ref!($($x)*) {
2671+
#[inline]
2672+
fn to_string(&self) -> String {
2673+
String::from(to_string_expr_wrap_in_deref!(self ; $($x)*))
2674+
}
2675+
}
2676+
)+
2677+
};
2678+
}
2679+
2680+
#[cfg(not(no_global_oom_handling))]
2681+
to_string_str! {
2682+
x x x x x x x x x x x x,
2683+
x x x x x x x x x x x,
2684+
x x x x x x x x x x,
2685+
x x x x x x x x x,
2686+
x x x x x x x x,
2687+
x x x x x x x,
2688+
x x x x x x,
2689+
x x x x x,
2690+
x x x x,
2691+
x x x,
2692+
x x,
2693+
x,
26542694
}
26552695

26562696
#[doc(hidden)]

‎library/core/src/fmt/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,6 +1626,11 @@ impl<'a> Formatter<'a> {
16261626
self.buf.write_str(data)
16271627
}
16281628

1629+
/// Glue for usage of the [`write!`] macro with implementors of this trait.
1630+
///
1631+
/// This method should generally not be invoked manually, but rather through
1632+
/// the [`write!`] macro itself.
1633+
///
16291634
/// Writes some formatted information into this instance.
16301635
///
16311636
/// # Examples

‎library/std/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ object = { version = "0.36.0", default-features = false, optional = true, featur
5757
'archive',
5858
] }
5959

60+
[target.'cfg(windows)'.dependencies.windows-targets]
61+
path = "../windows_targets"
62+
6063
[dev-dependencies]
6164
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
6265
rand_xorshift = "0.3.0"
@@ -116,7 +119,7 @@ std_detect_env_override = ["std_detect/std_detect_env_override"]
116119

117120
# Enable using raw-dylib for Windows imports.
118121
# This will eventually be the default.
119-
windows_raw_dylib = []
122+
windows_raw_dylib = ["windows-targets/windows_raw_dylib"]
120123

121124
[package.metadata.fortanix-sgx]
122125
# Maximum possible number of threads when testing

‎library/std/src/sys/pal/windows/alloc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::alloc::{GlobalAlloc, Layout, System};
44
use crate::ffi::c_void;
55
use crate::ptr;
66
use crate::sync::atomic::{AtomicPtr, Ordering};
7-
use crate::sys::c::{self, windows_targets};
7+
use crate::sys::c;
88
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
99

1010
#[cfg(test)]

‎library/std/src/sys/pal/windows/c.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
use core::ffi::{c_uint, c_ulong, c_ushort, c_void, CStr};
99
use core::{mem, ptr};
1010

11-
pub(super) mod windows_targets;
12-
1311
mod windows_sys;
1412
pub use windows_sys::*;
1513

‎library/std/src/sys/pal/windows/c/windows_sys.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3317,4 +3317,3 @@ pub struct WSADATA {
33173317
#[cfg(target_arch = "arm")]
33183318
pub enum CONTEXT {}
33193319
// ignore-tidy-filelength
3320-
use super::windows_targets;

‎library/windows_targets/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "windows-targets"
3+
description = "A drop-in replacement for the real windows-targets crate for use in std only."
4+
version = "0.0.0"
5+
edition = "2021"
6+
7+
[features]
8+
# Enable using raw-dylib for Windows imports.
9+
# This will eventually be the default.
10+
windows_raw_dylib = []

‎library/std/src/sys/pal/windows/c/windows_targets.rs renamed to ‎library/windows_targets/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
//!
33
//! This is a simple wrapper around an `extern` block with a `#[link]` attribute.
44
//! It's very roughly equivalent to the windows-targets crate.
5+
#![no_std]
6+
#![no_core]
7+
#![feature(decl_macro)]
8+
#![feature(no_core)]
59

610
#[cfg(feature = "windows_raw_dylib")]
711
pub macro link {

‎src/tools/generate-windows-sys/src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ fn main() -> Result<(), Box<dyn Error>> {
3535
let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?;
3636
f.write_all(ARM32_SHIM.as_bytes())?;
3737
writeln!(&mut f, "// ignore-tidy-filelength")?;
38-
writeln!(&mut f, "use super::windows_targets;")?;
3938

4039
Ok(())
4140
}

‎src/tools/run-make-support/src/external_deps/llvm.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ pub fn llvm_bcanalyzer() -> LlvmBcanalyzer {
4848
LlvmBcanalyzer::new()
4949
}
5050

51+
/// Construct a new `llvm-dwarfdump` invocation. This assumes that `llvm-dwarfdump` is available
52+
/// at `$LLVM_BIN_DIR/llvm-dwarfdump`.
53+
pub fn llvm_dwarfdump() -> LlvmDwarfdump {
54+
LlvmDwarfdump::new()
55+
}
56+
5157
/// A `llvm-readobj` invocation builder.
5258
#[derive(Debug)]
5359
#[must_use]
@@ -97,13 +103,21 @@ pub struct LlvmBcanalyzer {
97103
cmd: Command,
98104
}
99105

106+
/// A `llvm-dwarfdump` invocation builder.
107+
#[derive(Debug)]
108+
#[must_use]
109+
pub struct LlvmDwarfdump {
110+
cmd: Command,
111+
}
112+
100113
crate::macros::impl_common_helpers!(LlvmReadobj);
101114
crate::macros::impl_common_helpers!(LlvmProfdata);
102115
crate::macros::impl_common_helpers!(LlvmFilecheck);
103116
crate::macros::impl_common_helpers!(LlvmObjdump);
104117
crate::macros::impl_common_helpers!(LlvmAr);
105118
crate::macros::impl_common_helpers!(LlvmNm);
106119
crate::macros::impl_common_helpers!(LlvmBcanalyzer);
120+
crate::macros::impl_common_helpers!(LlvmDwarfdump);
107121

108122
/// Generate the path to the bin directory of LLVM.
109123
#[must_use]
@@ -317,3 +331,19 @@ impl LlvmBcanalyzer {
317331
self
318332
}
319333
}
334+
335+
impl LlvmDwarfdump {
336+
/// Construct a new `llvm-dwarfdump` invocation. This assumes that `llvm-dwarfdump` is available
337+
/// at `$LLVM_BIN_DIR/llvm-dwarfdump`.
338+
pub fn new() -> Self {
339+
let llvm_dwarfdump = llvm_bin_dir().join("llvm-dwarfdump");
340+
let cmd = Command::new(llvm_dwarfdump);
341+
Self { cmd }
342+
}
343+
344+
/// Provide an input file.
345+
pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
346+
self.cmd.arg(path.as_ref());
347+
self
348+
}
349+
}

‎src/tools/run-make-support/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_nativ
4949
pub use clang::{clang, Clang};
5050
pub use htmldocck::htmldocck;
5151
pub use llvm::{
52-
llvm_ar, llvm_bcanalyzer, llvm_filecheck, llvm_nm, llvm_objdump, llvm_profdata, llvm_readobj,
53-
LlvmAr, LlvmBcanalyzer, LlvmFilecheck, LlvmNm, LlvmObjdump, LlvmProfdata, LlvmReadobj,
52+
llvm_ar, llvm_bcanalyzer, llvm_dwarfdump, llvm_filecheck, llvm_nm, llvm_objdump, llvm_profdata,
53+
llvm_readobj, LlvmAr, LlvmBcanalyzer, LlvmDwarfdump, LlvmFilecheck, LlvmNm, LlvmObjdump,
54+
LlvmProfdata, LlvmReadobj,
5455
};
5556
pub use python::python_command;
5657
pub use rustc::{aux_build, bare_rustc, rustc, Rustc};

‎src/tools/tidy/src/allowed_run_make_makefiles.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ run-make/macos-deployment-target/Makefile
1616
run-make/min-global-align/Makefile
1717
run-make/native-link-modifier-bundle/Makefile
1818
run-make/no-alloc-shim/Makefile
19-
run-make/remap-path-prefix-dwarf/Makefile
2019
run-make/reproducible-build/Makefile
2120
run-make/rlib-format-packed-bundled-libs/Makefile
2221
run-make/split-debuginfo/Makefile

‎src/tools/tidy/src/pal.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use crate::walk::{filter_dirs, walk};
3636

3737
// Paths that may contain platform-specific code.
3838
const EXCEPTION_PATHS: &[&str] = &[
39+
"library/windows_targets",
3940
"library/panic_abort",
4041
"library/panic_unwind",
4142
"library/unwind",
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//@ compile-flags: -C opt-level=3 -Z merge-functions=disabled
2+
#![crate_type = "lib"]
3+
4+
//! Make sure str::to_string is specialized not to use fmt machinery.
5+
6+
// CHECK-LABEL: define {{(dso_local )?}}void @one_ref
7+
#[no_mangle]
8+
pub fn one_ref(input: &str) -> String {
9+
// CHECK-NOT: {{(call|invoke).*}}fmt
10+
input.to_string()
11+
}
12+
13+
// CHECK-LABEL: define {{(dso_local )?}}void @two_ref
14+
#[no_mangle]
15+
pub fn two_ref(input: &&str) -> String {
16+
// CHECK-NOT: {{(call|invoke).*}}fmt
17+
input.to_string()
18+
}
19+
20+
// CHECK-LABEL: define {{(dso_local )?}}void @thirteen_ref
21+
#[no_mangle]
22+
pub fn thirteen_ref(input: &&&&&&&&&&&&&str) -> String {
23+
// CHECK-NOT: {{(call|invoke).*}}fmt
24+
input.to_string()
25+
}
26+
27+
// This is a known performance cliff because of the macro-generated
28+
// specialized impl. If this test suddenly starts failing,
29+
// consider removing the `to_string_str!` macro in `alloc/str/string.rs`.
30+
//
31+
// CHECK-LABEL: define {{(dso_local )?}}void @fourteen_ref
32+
#[no_mangle]
33+
pub fn fourteen_ref(input: &&&&&&&&&&&&&&str) -> String {
34+
// CHECK: {{(call|invoke).*}}fmt
35+
input.to_string()
36+
}

‎tests/run-make/remap-path-prefix-dwarf/Makefile

Lines changed: 0 additions & 112 deletions
This file was deleted.
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
// This test makes sure that --remap-path-prefix has the expected effects on paths in debuginfo.
2+
// We explicitly switch to a directory that *is* a prefix of the directory our
3+
// source code is contained in.
4+
// It tests several cases, each of them has a detailed description attached to it.
5+
// See https://github.com/rust-lang/rust/pull/96867
6+
7+
//@ ignore-windows
8+
// Reason: the remap path prefix is not printed in the dwarf dump.
9+
10+
use run_make_support::{cwd, is_darwin, llvm_dwarfdump, rust_lib_name, rustc};
11+
12+
fn main() {
13+
// The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path *is* within
14+
// the working directory of the compiler. We are remapping the path that contains `src`.
15+
check_dwarf(DwarfTest {
16+
lib_name: "abs_input_inside_working_dir",
17+
input_path: PathType::Absolute,
18+
scope: None,
19+
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
20+
dwarf_test: DwarfDump::ContainsSrcPath,
21+
});
22+
check_dwarf(DwarfTest {
23+
lib_name: "abs_input_inside_working_dir_scope",
24+
input_path: PathType::Absolute,
25+
scope: Some(ScopeType::Object),
26+
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
27+
dwarf_test: DwarfDump::ContainsSrcPath,
28+
});
29+
// The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path is *not*
30+
// within the working directory of the compiler. We are remapping both the path that contains
31+
// `src` and the working directory to the same thing. This setup corresponds to a workaround
32+
// that is needed when trying to remap everything to something that looks like a local
33+
// path. Relative paths are interpreted as relative to the compiler's working directory (e.g.
34+
// in debuginfo). If we also remap the working directory, the compiler strip it from other
35+
// paths so that the final outcome is the desired one again.
36+
check_dwarf(DwarfTest {
37+
lib_name: "abs_input_outside_working_dir",
38+
input_path: PathType::Absolute,
39+
scope: None,
40+
remap_path_prefix: PrefixType::Dual((
41+
format!("{}=REMAPPED", cwd().display()),
42+
"rmake_out=REMAPPED".to_owned(),
43+
)),
44+
dwarf_test: DwarfDump::ContainsSrcPath,
45+
});
46+
// The compiler is called with a *RELATIVE PATH* as input. We are remapping the working
47+
// directory of the compiler, which naturally is an implicit prefix of our relative input path.
48+
// Debuginfo will expand the relative path to an absolute path and we expect the working
49+
// directory to be remapped in that expansion.
50+
check_dwarf(DwarfTest {
51+
lib_name: "rel_input_remap_working_dir",
52+
input_path: PathType::Relative,
53+
scope: None,
54+
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
55+
dwarf_test: DwarfDump::ContainsSrcPath,
56+
});
57+
check_dwarf(DwarfTest {
58+
lib_name: "rel_input_remap_working_dir_scope",
59+
input_path: PathType::Relative,
60+
scope: Some(ScopeType::Object),
61+
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
62+
dwarf_test: DwarfDump::ContainsSrcPath,
63+
});
64+
check_dwarf(DwarfTest {
65+
lib_name: "rel_input_remap_working_dir_scope",
66+
input_path: PathType::Relative,
67+
scope: Some(ScopeType::Diagnostics),
68+
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
69+
dwarf_test: DwarfDump::AvoidSrcPath,
70+
});
71+
// The compiler is called with a *RELATIVE PATH* as input. We are remapping a *SUB-DIRECTORY*
72+
// of the compiler's working directory. This test makes sure that that directory is remapped
73+
// even though it won't actually show up in this form in the compiler's SourceMap and instead
74+
// is only constructed on demand during debuginfo generation.
75+
check_dwarf(DwarfTest {
76+
lib_name: "rel_input_remap_working_dir_child",
77+
input_path: PathType::Relative,
78+
scope: None,
79+
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().join("src").display())),
80+
dwarf_test: DwarfDump::ChildTest,
81+
});
82+
// The compiler is called with a *RELATIVE PATH* as input. We are remapping a
83+
// *PARENT DIRECTORY* of the compiler's working directory.
84+
check_dwarf(DwarfTest {
85+
lib_name: "rel_input_remap_working_dir_parent",
86+
input_path: PathType::Relative,
87+
scope: None,
88+
remap_path_prefix: PrefixType::Regular(format!(
89+
"{}=REMAPPED",
90+
cwd().parent().unwrap().display()
91+
)),
92+
dwarf_test: DwarfDump::ParentTest,
93+
});
94+
}
95+
96+
#[track_caller]
97+
fn check_dwarf(test: DwarfTest) {
98+
let mut rustc = rustc();
99+
match test.input_path {
100+
PathType::Absolute => rustc.input(cwd().join("src/quux.rs")),
101+
PathType::Relative => rustc.input("src/quux.rs"),
102+
};
103+
rustc.output(rust_lib_name(test.lib_name));
104+
rustc.arg("-Cdebuginfo=2");
105+
if let Some(scope) = test.scope {
106+
match scope {
107+
ScopeType::Object => rustc.arg("-Zremap-path-scope=object"),
108+
ScopeType::Diagnostics => rustc.arg("-Zremap-path-scope=diagnostics"),
109+
};
110+
if is_darwin() {
111+
rustc.arg("-Csplit-debuginfo=off");
112+
}
113+
}
114+
match test.remap_path_prefix {
115+
PrefixType::Regular(prefix) => {
116+
// We explicitly switch to a directory that *is* a prefix of the directory our
117+
// source code is contained in.
118+
rustc.arg("--remap-path-prefix");
119+
rustc.arg(prefix);
120+
}
121+
PrefixType::Dual((prefix1, prefix2)) => {
122+
// We explicitly switch to a directory that is *not* a prefix of the directory our
123+
// source code is contained in.
124+
rustc.arg("--remap-path-prefix");
125+
rustc.arg(prefix1);
126+
rustc.arg("--remap-path-prefix");
127+
rustc.arg(prefix2);
128+
}
129+
}
130+
rustc.run();
131+
match test.dwarf_test {
132+
DwarfDump::ContainsSrcPath => {
133+
llvm_dwarfdump()
134+
.input(rust_lib_name(test.lib_name))
135+
.run()
136+
// We expect the path to the main source file to be remapped.
137+
.assert_stdout_contains("REMAPPED/src/quux.rs")
138+
// No weird duplication of remapped components (see #78479)
139+
.assert_stdout_not_contains("REMAPPED/REMAPPED");
140+
}
141+
DwarfDump::AvoidSrcPath => {
142+
llvm_dwarfdump()
143+
.input(rust_lib_name(test.lib_name))
144+
.run()
145+
.assert_stdout_not_contains("REMAPPED/src/quux.rs")
146+
.assert_stdout_not_contains("REMAPPED/REMAPPED");
147+
}
148+
DwarfDump::ChildTest => {
149+
llvm_dwarfdump()
150+
.input(rust_lib_name(test.lib_name))
151+
.run()
152+
// We expect `src/quux.rs` to have been remapped to `REMAPPED/quux.rs`.
153+
.assert_stdout_contains("REMAPPED/quux.rs")
154+
// We don't want to find the path that we just remapped anywhere in the DWARF
155+
.assert_stdout_not_contains(cwd().join("src").to_str().unwrap())
156+
// No weird duplication of remapped components (see #78479)
157+
.assert_stdout_not_contains("REMAPPED/REMAPPED");
158+
}
159+
DwarfDump::ParentTest => {
160+
llvm_dwarfdump()
161+
.input(rust_lib_name(test.lib_name))
162+
.run()
163+
// We expect `src/quux.rs` to have been remapped to
164+
// `REMAPPED/remap-path-prefix-dwarf/src/quux.rs`.
165+
.assert_stdout_contains("REMAPPED/rmake_out/src/quux.rs")
166+
// We don't want to find the path that we just remapped anywhere in the DWARF
167+
.assert_stdout_not_contains(cwd().parent().unwrap().to_str().unwrap())
168+
// No weird duplication of remapped components (see #78479)
169+
.assert_stdout_not_contains("REMAPPED/REMAPPED");
170+
}
171+
};
172+
}
173+
174+
struct DwarfTest {
175+
lib_name: &'static str,
176+
input_path: PathType,
177+
scope: Option<ScopeType>,
178+
remap_path_prefix: PrefixType,
179+
dwarf_test: DwarfDump,
180+
}
181+
182+
enum PathType {
183+
Absolute,
184+
Relative,
185+
}
186+
187+
enum ScopeType {
188+
Object,
189+
Diagnostics,
190+
}
191+
192+
enum DwarfDump {
193+
ContainsSrcPath,
194+
AvoidSrcPath,
195+
ChildTest,
196+
ParentTest,
197+
}
198+
199+
enum PrefixType {
200+
Regular(String),
201+
Dual((String, String)),
202+
}

‎tests/ui/cast/ptr-to-trait-obj-different-args.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ LL | let y: *const dyn Trait<Y> = x as _;
1414
|
1515
= note: expected trait object `dyn Trait<X>`
1616
found trait object `dyn Trait<Y>`
17+
= help: `dyn Trait<Y>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
1718

1819
error[E0308]: mismatched types
1920
--> $DIR/ptr-to-trait-obj-different-args.rs:27:34
@@ -25,6 +26,7 @@ LL | let _: *const dyn Trait<T> = x as _;
2526
|
2627
= note: expected trait object `dyn Trait<X>`
2728
found trait object `dyn Trait<T>`
29+
= help: `dyn Trait<T>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
2830

2931
error[E0308]: mismatched types
3032
--> $DIR/ptr-to-trait-obj-different-args.rs:28:34
@@ -37,6 +39,7 @@ LL | let _: *const dyn Trait<X> = t as _;
3739
|
3840
= note: expected trait object `dyn Trait<T>`
3941
found trait object `dyn Trait<X>`
42+
= help: `dyn Trait<X>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
4043

4144
error[E0308]: mismatched types
4245
--> $DIR/ptr-to-trait-obj-different-args.rs:36:5

‎tests/ui/coercion/coerce-expect-unsized-ascribed.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ LL | let _ = type_ascribe!(Box::new( if true { false } else { true }), Box<d
4242
|
4343
= note: expected struct `Box<dyn Debug>`
4444
found struct `Box<bool>`
45+
= help: `bool` implements `Debug` so you could box the found value and coerce it to the trait object `Box<dyn Debug>`, you will have to change the expected type as well
4546

4647
error[E0308]: mismatched types
4748
--> $DIR/coerce-expect-unsized-ascribed.rs:16:27
@@ -51,6 +52,7 @@ LL | let _ = type_ascribe!(Box::new( match true { true => 'a', false => 'b'
5152
|
5253
= note: expected struct `Box<dyn Debug>`
5354
found struct `Box<char>`
55+
= help: `char` implements `Debug` so you could box the found value and coerce it to the trait object `Box<dyn Debug>`, you will have to change the expected type as well
5456

5557
error[E0308]: mismatched types
5658
--> $DIR/coerce-expect-unsized-ascribed.rs:18:27
@@ -96,6 +98,7 @@ LL | let _ = type_ascribe!(&if true { false } else { true }, &dyn Debug);
9698
|
9799
= note: expected reference `&dyn Debug`
98100
found reference `&bool`
101+
= help: `bool` implements `Debug` so you could box the found value and coerce it to the trait object `Box<dyn Debug>`, you will have to change the expected type as well
99102

100103
error[E0308]: mismatched types
101104
--> $DIR/coerce-expect-unsized-ascribed.rs:24:27
@@ -105,6 +108,7 @@ LL | let _ = type_ascribe!(&match true { true => 'a', false => 'b' }, &dyn D
105108
|
106109
= note: expected reference `&dyn Debug`
107110
found reference `&char`
111+
= help: `char` implements `Debug` so you could box the found value and coerce it to the trait object `Box<dyn Debug>`, you will have to change the expected type as well
108112

109113
error[E0308]: mismatched types
110114
--> $DIR/coerce-expect-unsized-ascribed.rs:26:27

‎tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -254,39 +254,39 @@ LL | _ => {}
254254
= note: this pattern matches no values because `!` is uninhabited
255255

256256
error: unreachable pattern
257-
--> $DIR/empty-types.rs:279:9
257+
--> $DIR/empty-types.rs:281:9
258258
|
259259
LL | _ => {}
260260
| ^
261261
|
262262
= note: this pattern matches no values because `!` is uninhabited
263263

264264
error: unreachable pattern
265-
--> $DIR/empty-types.rs:282:9
265+
--> $DIR/empty-types.rs:284:9
266266
|
267267
LL | (_, _) => {}
268268
| ^^^^^^
269269
|
270270
= note: this pattern matches no values because `(!, !)` is uninhabited
271271

272272
error: unreachable pattern
273-
--> $DIR/empty-types.rs:285:9
273+
--> $DIR/empty-types.rs:287:9
274274
|
275275
LL | Ok(_) => {}
276276
| ^^^^^
277277
|
278278
= note: this pattern matches no values because `Result<!, !>` is uninhabited
279279

280280
error: unreachable pattern
281-
--> $DIR/empty-types.rs:286:9
281+
--> $DIR/empty-types.rs:288:9
282282
|
283283
LL | Err(_) => {}
284284
| ^^^^^^
285285
|
286286
= note: this pattern matches no values because `Result<!, !>` is uninhabited
287287

288288
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
289-
--> $DIR/empty-types.rs:318:11
289+
--> $DIR/empty-types.rs:327:11
290290
|
291291
LL | match slice_never {}
292292
| ^^^^^^^^^^^
@@ -300,7 +300,7 @@ LL + }
300300
|
301301

302302
error[E0004]: non-exhaustive patterns: `&[]` not covered
303-
--> $DIR/empty-types.rs:329:11
303+
--> $DIR/empty-types.rs:338:11
304304
|
305305
LL | match slice_never {
306306
| ^^^^^^^^^^^ pattern `&[]` not covered
@@ -313,7 +313,7 @@ LL + &[] => todo!()
313313
|
314314

315315
error[E0004]: non-exhaustive patterns: `&[]` not covered
316-
--> $DIR/empty-types.rs:343:11
316+
--> $DIR/empty-types.rs:352:11
317317
|
318318
LL | match slice_never {
319319
| ^^^^^^^^^^^ pattern `&[]` not covered
@@ -327,7 +327,7 @@ LL + &[] => todo!()
327327
|
328328

329329
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
330-
--> $DIR/empty-types.rs:350:11
330+
--> $DIR/empty-types.rs:359:11
331331
|
332332
LL | match *slice_never {}
333333
| ^^^^^^^^^^^^
@@ -341,31 +341,31 @@ LL + }
341341
|
342342

343343
error: unreachable pattern
344-
--> $DIR/empty-types.rs:359:9
344+
--> $DIR/empty-types.rs:368:9
345345
|
346346
LL | _ => {}
347347
| ^
348348
|
349349
= note: this pattern matches no values because `[!; 3]` is uninhabited
350350

351351
error: unreachable pattern
352-
--> $DIR/empty-types.rs:362:9
352+
--> $DIR/empty-types.rs:371:9
353353
|
354354
LL | [_, _, _] => {}
355355
| ^^^^^^^^^
356356
|
357357
= note: this pattern matches no values because `[!; 3]` is uninhabited
358358

359359
error: unreachable pattern
360-
--> $DIR/empty-types.rs:365:9
360+
--> $DIR/empty-types.rs:374:9
361361
|
362362
LL | [_, ..] => {}
363363
| ^^^^^^^
364364
|
365365
= note: this pattern matches no values because `[!; 3]` is uninhabited
366366

367367
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
368-
--> $DIR/empty-types.rs:379:11
368+
--> $DIR/empty-types.rs:388:11
369369
|
370370
LL | match array_0_never {}
371371
| ^^^^^^^^^^^^^
@@ -379,15 +379,15 @@ LL + }
379379
|
380380

381381
error: unreachable pattern
382-
--> $DIR/empty-types.rs:386:9
382+
--> $DIR/empty-types.rs:395:9
383383
|
384384
LL | [] => {}
385385
| -- matches all the values already
386386
LL | _ => {}
387387
| ^ unreachable pattern
388388

389389
error[E0004]: non-exhaustive patterns: `[]` not covered
390-
--> $DIR/empty-types.rs:388:11
390+
--> $DIR/empty-types.rs:397:11
391391
|
392392
LL | match array_0_never {
393393
| ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -401,23 +401,23 @@ LL + [] => todo!()
401401
|
402402

403403
error: unreachable pattern
404-
--> $DIR/empty-types.rs:407:9
404+
--> $DIR/empty-types.rs:416:9
405405
|
406406
LL | Some(_) => {}
407407
| ^^^^^^^
408408
|
409409
= note: this pattern matches no values because `!` is uninhabited
410410

411411
error: unreachable pattern
412-
--> $DIR/empty-types.rs:412:9
412+
--> $DIR/empty-types.rs:421:9
413413
|
414414
LL | Some(_a) => {}
415415
| ^^^^^^^^
416416
|
417417
= note: this pattern matches no values because `!` is uninhabited
418418

419419
error: unreachable pattern
420-
--> $DIR/empty-types.rs:417:9
420+
--> $DIR/empty-types.rs:426:9
421421
|
422422
LL | None => {}
423423
| ---- matches all the values already
@@ -426,7 +426,7 @@ LL | _ => {}
426426
| ^ unreachable pattern
427427

428428
error: unreachable pattern
429-
--> $DIR/empty-types.rs:422:9
429+
--> $DIR/empty-types.rs:431:9
430430
|
431431
LL | None => {}
432432
| ---- matches all the values already
@@ -435,31 +435,31 @@ LL | _a => {}
435435
| ^^ unreachable pattern
436436

437437
error: unreachable pattern
438-
--> $DIR/empty-types.rs:594:9
438+
--> $DIR/empty-types.rs:603:9
439439
|
440440
LL | _ => {}
441441
| ^
442442
|
443443
= note: this pattern matches no values because `!` is uninhabited
444444

445445
error: unreachable pattern
446-
--> $DIR/empty-types.rs:597:9
446+
--> $DIR/empty-types.rs:606:9
447447
|
448448
LL | _x => {}
449449
| ^^
450450
|
451451
= note: this pattern matches no values because `!` is uninhabited
452452

453453
error: unreachable pattern
454-
--> $DIR/empty-types.rs:600:9
454+
--> $DIR/empty-types.rs:609:9
455455
|
456456
LL | _ if false => {}
457457
| ^
458458
|
459459
= note: this pattern matches no values because `!` is uninhabited
460460

461461
error: unreachable pattern
462-
--> $DIR/empty-types.rs:603:9
462+
--> $DIR/empty-types.rs:612:9
463463
|
464464
LL | _x if false => {}
465465
| ^^

‎tests/ui/pattern/usefulness/empty-types.never_pats.stderr

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -296,39 +296,53 @@ LL | _ => {}
296296
= note: this pattern matches no values because `!` is uninhabited
297297

298298
error: unreachable pattern
299-
--> $DIR/empty-types.rs:279:9
299+
--> $DIR/empty-types.rs:281:9
300300
|
301301
LL | _ => {}
302302
| ^
303303
|
304304
= note: this pattern matches no values because `!` is uninhabited
305305

306306
error: unreachable pattern
307-
--> $DIR/empty-types.rs:282:9
307+
--> $DIR/empty-types.rs:284:9
308308
|
309309
LL | (_, _) => {}
310310
| ^^^^^^
311311
|
312312
= note: this pattern matches no values because `(!, !)` is uninhabited
313313

314314
error: unreachable pattern
315-
--> $DIR/empty-types.rs:285:9
315+
--> $DIR/empty-types.rs:287:9
316316
|
317317
LL | Ok(_) => {}
318318
| ^^^^^
319319
|
320320
= note: this pattern matches no values because `Result<!, !>` is uninhabited
321321

322322
error: unreachable pattern
323-
--> $DIR/empty-types.rs:286:9
323+
--> $DIR/empty-types.rs:288:9
324324
|
325325
LL | Err(_) => {}
326326
| ^^^^^^
327327
|
328328
= note: this pattern matches no values because `Result<!, !>` is uninhabited
329329

330+
error[E0005]: refutable pattern in local binding
331+
--> $DIR/empty-types.rs:297:13
332+
|
333+
LL | let Ok(_) = *ptr_result_never_err;
334+
| ^^^^^ pattern `Err(!)` not covered
335+
|
336+
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
337+
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
338+
= note: the matched value is of type `Result<u8, !>`
339+
help: you might want to use `if let` to ignore the variant that isn't matched
340+
|
341+
LL | if let Ok(_) = *ptr_result_never_err { todo!() };
342+
| ++ +++++++++++
343+
330344
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
331-
--> $DIR/empty-types.rs:307:11
345+
--> $DIR/empty-types.rs:316:11
332346
|
333347
LL | match *x {}
334348
| ^^
@@ -342,7 +356,7 @@ LL ~ }
342356
|
343357

344358
error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
345-
--> $DIR/empty-types.rs:309:11
359+
--> $DIR/empty-types.rs:318:11
346360
|
347361
LL | match *x {}
348362
| ^^
@@ -356,7 +370,7 @@ LL ~ }
356370
|
357371

358372
error[E0004]: non-exhaustive patterns: `Ok(!)` and `Err(!)` not covered
359-
--> $DIR/empty-types.rs:311:11
373+
--> $DIR/empty-types.rs:320:11
360374
|
361375
LL | match *x {}
362376
| ^^ patterns `Ok(!)` and `Err(!)` not covered
@@ -378,7 +392,7 @@ LL ~ }
378392
|
379393

380394
error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
381-
--> $DIR/empty-types.rs:313:11
395+
--> $DIR/empty-types.rs:322:11
382396
|
383397
LL | match *x {}
384398
| ^^
@@ -392,7 +406,7 @@ LL ~ }
392406
|
393407

394408
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
395-
--> $DIR/empty-types.rs:318:11
409+
--> $DIR/empty-types.rs:327:11
396410
|
397411
LL | match slice_never {}
398412
| ^^^^^^^^^^^
@@ -406,7 +420,7 @@ LL + }
406420
|
407421

408422
error[E0004]: non-exhaustive patterns: `&[!, ..]` not covered
409-
--> $DIR/empty-types.rs:320:11
423+
--> $DIR/empty-types.rs:329:11
410424
|
411425
LL | match slice_never {
412426
| ^^^^^^^^^^^ pattern `&[!, ..]` not covered
@@ -420,7 +434,7 @@ LL + &[!, ..]
420434
|
421435

422436
error[E0004]: non-exhaustive patterns: `&[]`, `&[!]` and `&[!, !]` not covered
423-
--> $DIR/empty-types.rs:329:11
437+
--> $DIR/empty-types.rs:338:11
424438
|
425439
LL | match slice_never {
426440
| ^^^^^^^^^^^ patterns `&[]`, `&[!]` and `&[!, !]` not covered
@@ -433,7 +447,7 @@ LL + &[] | &[!] | &[!, !] => todo!()
433447
|
434448

435449
error[E0004]: non-exhaustive patterns: `&[]` and `&[!, ..]` not covered
436-
--> $DIR/empty-types.rs:343:11
450+
--> $DIR/empty-types.rs:352:11
437451
|
438452
LL | match slice_never {
439453
| ^^^^^^^^^^^ patterns `&[]` and `&[!, ..]` not covered
@@ -447,7 +461,7 @@ LL + &[] | &[!, ..] => todo!()
447461
|
448462

449463
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
450-
--> $DIR/empty-types.rs:350:11
464+
--> $DIR/empty-types.rs:359:11
451465
|
452466
LL | match *slice_never {}
453467
| ^^^^^^^^^^^^
@@ -461,31 +475,31 @@ LL + }
461475
|
462476

463477
error: unreachable pattern
464-
--> $DIR/empty-types.rs:359:9
478+
--> $DIR/empty-types.rs:368:9
465479
|
466480
LL | _ => {}
467481
| ^
468482
|
469483
= note: this pattern matches no values because `[!; 3]` is uninhabited
470484

471485
error: unreachable pattern
472-
--> $DIR/empty-types.rs:362:9
486+
--> $DIR/empty-types.rs:371:9
473487
|
474488
LL | [_, _, _] => {}
475489
| ^^^^^^^^^
476490
|
477491
= note: this pattern matches no values because `[!; 3]` is uninhabited
478492

479493
error: unreachable pattern
480-
--> $DIR/empty-types.rs:365:9
494+
--> $DIR/empty-types.rs:374:9
481495
|
482496
LL | [_, ..] => {}
483497
| ^^^^^^^
484498
|
485499
= note: this pattern matches no values because `[!; 3]` is uninhabited
486500

487501
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
488-
--> $DIR/empty-types.rs:379:11
502+
--> $DIR/empty-types.rs:388:11
489503
|
490504
LL | match array_0_never {}
491505
| ^^^^^^^^^^^^^
@@ -499,15 +513,15 @@ LL + }
499513
|
500514

501515
error: unreachable pattern
502-
--> $DIR/empty-types.rs:386:9
516+
--> $DIR/empty-types.rs:395:9
503517
|
504518
LL | [] => {}
505519
| -- matches all the values already
506520
LL | _ => {}
507521
| ^ unreachable pattern
508522

509523
error[E0004]: non-exhaustive patterns: `[]` not covered
510-
--> $DIR/empty-types.rs:388:11
524+
--> $DIR/empty-types.rs:397:11
511525
|
512526
LL | match array_0_never {
513527
| ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -521,23 +535,23 @@ LL + [] => todo!()
521535
|
522536

523537
error: unreachable pattern
524-
--> $DIR/empty-types.rs:407:9
538+
--> $DIR/empty-types.rs:416:9
525539
|
526540
LL | Some(_) => {}
527541
| ^^^^^^^
528542
|
529543
= note: this pattern matches no values because `!` is uninhabited
530544

531545
error: unreachable pattern
532-
--> $DIR/empty-types.rs:412:9
546+
--> $DIR/empty-types.rs:421:9
533547
|
534548
LL | Some(_a) => {}
535549
| ^^^^^^^^
536550
|
537551
= note: this pattern matches no values because `!` is uninhabited
538552

539553
error: unreachable pattern
540-
--> $DIR/empty-types.rs:417:9
554+
--> $DIR/empty-types.rs:426:9
541555
|
542556
LL | None => {}
543557
| ---- matches all the values already
@@ -546,7 +560,7 @@ LL | _ => {}
546560
| ^ unreachable pattern
547561

548562
error: unreachable pattern
549-
--> $DIR/empty-types.rs:422:9
563+
--> $DIR/empty-types.rs:431:9
550564
|
551565
LL | None => {}
552566
| ---- matches all the values already
@@ -555,7 +569,7 @@ LL | _a => {}
555569
| ^^ unreachable pattern
556570

557571
error[E0004]: non-exhaustive patterns: `&Some(!)` not covered
558-
--> $DIR/empty-types.rs:442:11
572+
--> $DIR/empty-types.rs:451:11
559573
|
560574
LL | match ref_opt_never {
561575
| ^^^^^^^^^^^^^ pattern `&Some(!)` not covered
@@ -574,7 +588,7 @@ LL + &Some(!)
574588
|
575589

576590
error[E0004]: non-exhaustive patterns: `Some(!)` not covered
577-
--> $DIR/empty-types.rs:483:11
591+
--> $DIR/empty-types.rs:492:11
578592
|
579593
LL | match *ref_opt_never {
580594
| ^^^^^^^^^^^^^^ pattern `Some(!)` not covered
@@ -593,7 +607,7 @@ LL + Some(!)
593607
|
594608

595609
error[E0004]: non-exhaustive patterns: `Err(!)` not covered
596-
--> $DIR/empty-types.rs:531:11
610+
--> $DIR/empty-types.rs:540:11
597611
|
598612
LL | match *ref_res_never {
599613
| ^^^^^^^^^^^^^^ pattern `Err(!)` not covered
@@ -612,7 +626,7 @@ LL + Err(!)
612626
|
613627

614628
error[E0004]: non-exhaustive patterns: `Err(!)` not covered
615-
--> $DIR/empty-types.rs:542:11
629+
--> $DIR/empty-types.rs:551:11
616630
|
617631
LL | match *ref_res_never {
618632
| ^^^^^^^^^^^^^^ pattern `Err(!)` not covered
@@ -631,7 +645,7 @@ LL + Err(!)
631645
|
632646

633647
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
634-
--> $DIR/empty-types.rs:561:11
648+
--> $DIR/empty-types.rs:570:11
635649
|
636650
LL | match *ref_tuple_half_never {}
637651
| ^^^^^^^^^^^^^^^^^^^^^
@@ -645,39 +659,39 @@ LL + }
645659
|
646660

647661
error: unreachable pattern
648-
--> $DIR/empty-types.rs:594:9
662+
--> $DIR/empty-types.rs:603:9
649663
|
650664
LL | _ => {}
651665
| ^
652666
|
653667
= note: this pattern matches no values because `!` is uninhabited
654668

655669
error: unreachable pattern
656-
--> $DIR/empty-types.rs:597:9
670+
--> $DIR/empty-types.rs:606:9
657671
|
658672
LL | _x => {}
659673
| ^^
660674
|
661675
= note: this pattern matches no values because `!` is uninhabited
662676

663677
error: unreachable pattern
664-
--> $DIR/empty-types.rs:600:9
678+
--> $DIR/empty-types.rs:609:9
665679
|
666680
LL | _ if false => {}
667681
| ^
668682
|
669683
= note: this pattern matches no values because `!` is uninhabited
670684

671685
error: unreachable pattern
672-
--> $DIR/empty-types.rs:603:9
686+
--> $DIR/empty-types.rs:612:9
673687
|
674688
LL | _x if false => {}
675689
| ^^
676690
|
677691
= note: this pattern matches no values because `!` is uninhabited
678692

679693
error[E0004]: non-exhaustive patterns: `&!` not covered
680-
--> $DIR/empty-types.rs:628:11
694+
--> $DIR/empty-types.rs:637:11
681695
|
682696
LL | match ref_never {
683697
| ^^^^^^^^^ pattern `&!` not covered
@@ -693,7 +707,7 @@ LL + &!
693707
|
694708

695709
error[E0004]: non-exhaustive patterns: `Ok(!)` not covered
696-
--> $DIR/empty-types.rs:644:11
710+
--> $DIR/empty-types.rs:653:11
697711
|
698712
LL | match *ref_result_never {
699713
| ^^^^^^^^^^^^^^^^^ pattern `Ok(!)` not covered
@@ -712,7 +726,7 @@ LL + Ok(!)
712726
|
713727

714728
error[E0004]: non-exhaustive patterns: `Some(!)` not covered
715-
--> $DIR/empty-types.rs:664:11
729+
--> $DIR/empty-types.rs:673:11
716730
|
717731
LL | match *x {
718732
| ^^ pattern `Some(!)` not covered
@@ -730,7 +744,7 @@ LL ~ None => {},
730744
LL + Some(!)
731745
|
732746

733-
error: aborting due to 64 previous errors; 1 warning emitted
747+
error: aborting due to 65 previous errors; 1 warning emitted
734748

735749
Some errors have detailed explanations: E0004, E0005.
736750
For more information about an error, try `rustc --explain E0004`.

‎tests/ui/pattern/usefulness/empty-types.normal.stderr

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -287,39 +287,53 @@ LL | _ => {}
287287
= note: this pattern matches no values because `!` is uninhabited
288288

289289
error: unreachable pattern
290-
--> $DIR/empty-types.rs:279:9
290+
--> $DIR/empty-types.rs:281:9
291291
|
292292
LL | _ => {}
293293
| ^
294294
|
295295
= note: this pattern matches no values because `!` is uninhabited
296296

297297
error: unreachable pattern
298-
--> $DIR/empty-types.rs:282:9
298+
--> $DIR/empty-types.rs:284:9
299299
|
300300
LL | (_, _) => {}
301301
| ^^^^^^
302302
|
303303
= note: this pattern matches no values because `(!, !)` is uninhabited
304304

305305
error: unreachable pattern
306-
--> $DIR/empty-types.rs:285:9
306+
--> $DIR/empty-types.rs:287:9
307307
|
308308
LL | Ok(_) => {}
309309
| ^^^^^
310310
|
311311
= note: this pattern matches no values because `Result<!, !>` is uninhabited
312312

313313
error: unreachable pattern
314-
--> $DIR/empty-types.rs:286:9
314+
--> $DIR/empty-types.rs:288:9
315315
|
316316
LL | Err(_) => {}
317317
| ^^^^^^
318318
|
319319
= note: this pattern matches no values because `Result<!, !>` is uninhabited
320320

321+
error[E0005]: refutable pattern in local binding
322+
--> $DIR/empty-types.rs:297:13
323+
|
324+
LL | let Ok(_) = *ptr_result_never_err;
325+
| ^^^^^ pattern `Err(_)` not covered
326+
|
327+
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
328+
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
329+
= note: the matched value is of type `Result<u8, !>`
330+
help: you might want to use `if let` to ignore the variant that isn't matched
331+
|
332+
LL | if let Ok(_) = *ptr_result_never_err { todo!() };
333+
| ++ +++++++++++
334+
321335
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
322-
--> $DIR/empty-types.rs:307:11
336+
--> $DIR/empty-types.rs:316:11
323337
|
324338
LL | match *x {}
325339
| ^^
@@ -333,7 +347,7 @@ LL ~ }
333347
|
334348

335349
error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
336-
--> $DIR/empty-types.rs:309:11
350+
--> $DIR/empty-types.rs:318:11
337351
|
338352
LL | match *x {}
339353
| ^^
@@ -347,7 +361,7 @@ LL ~ }
347361
|
348362

349363
error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
350-
--> $DIR/empty-types.rs:311:11
364+
--> $DIR/empty-types.rs:320:11
351365
|
352366
LL | match *x {}
353367
| ^^ patterns `Ok(_)` and `Err(_)` not covered
@@ -369,7 +383,7 @@ LL ~ }
369383
|
370384

371385
error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
372-
--> $DIR/empty-types.rs:313:11
386+
--> $DIR/empty-types.rs:322:11
373387
|
374388
LL | match *x {}
375389
| ^^
@@ -383,7 +397,7 @@ LL ~ }
383397
|
384398

385399
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
386-
--> $DIR/empty-types.rs:318:11
400+
--> $DIR/empty-types.rs:327:11
387401
|
388402
LL | match slice_never {}
389403
| ^^^^^^^^^^^
@@ -397,7 +411,7 @@ LL + }
397411
|
398412

399413
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
400-
--> $DIR/empty-types.rs:320:11
414+
--> $DIR/empty-types.rs:329:11
401415
|
402416
LL | match slice_never {
403417
| ^^^^^^^^^^^ pattern `&[_, ..]` not covered
@@ -411,7 +425,7 @@ LL + &[_, ..] => todo!()
411425
|
412426

413427
error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered
414-
--> $DIR/empty-types.rs:329:11
428+
--> $DIR/empty-types.rs:338:11
415429
|
416430
LL | match slice_never {
417431
| ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered
@@ -424,7 +438,7 @@ LL + &[] | &[_] | &[_, _] => todo!()
424438
|
425439

426440
error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered
427-
--> $DIR/empty-types.rs:343:11
441+
--> $DIR/empty-types.rs:352:11
428442
|
429443
LL | match slice_never {
430444
| ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered
@@ -438,7 +452,7 @@ LL + &[] | &[_, ..] => todo!()
438452
|
439453

440454
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
441-
--> $DIR/empty-types.rs:350:11
455+
--> $DIR/empty-types.rs:359:11
442456
|
443457
LL | match *slice_never {}
444458
| ^^^^^^^^^^^^
@@ -452,31 +466,31 @@ LL + }
452466
|
453467

454468
error: unreachable pattern
455-
--> $DIR/empty-types.rs:359:9
469+
--> $DIR/empty-types.rs:368:9
456470
|
457471
LL | _ => {}
458472
| ^
459473
|
460474
= note: this pattern matches no values because `[!; 3]` is uninhabited
461475

462476
error: unreachable pattern
463-
--> $DIR/empty-types.rs:362:9
477+
--> $DIR/empty-types.rs:371:9
464478
|
465479
LL | [_, _, _] => {}
466480
| ^^^^^^^^^
467481
|
468482
= note: this pattern matches no values because `[!; 3]` is uninhabited
469483

470484
error: unreachable pattern
471-
--> $DIR/empty-types.rs:365:9
485+
--> $DIR/empty-types.rs:374:9
472486
|
473487
LL | [_, ..] => {}
474488
| ^^^^^^^
475489
|
476490
= note: this pattern matches no values because `[!; 3]` is uninhabited
477491

478492
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
479-
--> $DIR/empty-types.rs:379:11
493+
--> $DIR/empty-types.rs:388:11
480494
|
481495
LL | match array_0_never {}
482496
| ^^^^^^^^^^^^^
@@ -490,15 +504,15 @@ LL + }
490504
|
491505

492506
error: unreachable pattern
493-
--> $DIR/empty-types.rs:386:9
507+
--> $DIR/empty-types.rs:395:9
494508
|
495509
LL | [] => {}
496510
| -- matches all the values already
497511
LL | _ => {}
498512
| ^ unreachable pattern
499513

500514
error[E0004]: non-exhaustive patterns: `[]` not covered
501-
--> $DIR/empty-types.rs:388:11
515+
--> $DIR/empty-types.rs:397:11
502516
|
503517
LL | match array_0_never {
504518
| ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -512,23 +526,23 @@ LL + [] => todo!()
512526
|
513527

514528
error: unreachable pattern
515-
--> $DIR/empty-types.rs:407:9
529+
--> $DIR/empty-types.rs:416:9
516530
|
517531
LL | Some(_) => {}
518532
| ^^^^^^^
519533
|
520534
= note: this pattern matches no values because `!` is uninhabited
521535

522536
error: unreachable pattern
523-
--> $DIR/empty-types.rs:412:9
537+
--> $DIR/empty-types.rs:421:9
524538
|
525539
LL | Some(_a) => {}
526540
| ^^^^^^^^
527541
|
528542
= note: this pattern matches no values because `!` is uninhabited
529543

530544
error: unreachable pattern
531-
--> $DIR/empty-types.rs:417:9
545+
--> $DIR/empty-types.rs:426:9
532546
|
533547
LL | None => {}
534548
| ---- matches all the values already
@@ -537,7 +551,7 @@ LL | _ => {}
537551
| ^ unreachable pattern
538552

539553
error: unreachable pattern
540-
--> $DIR/empty-types.rs:422:9
554+
--> $DIR/empty-types.rs:431:9
541555
|
542556
LL | None => {}
543557
| ---- matches all the values already
@@ -546,7 +560,7 @@ LL | _a => {}
546560
| ^^ unreachable pattern
547561

548562
error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
549-
--> $DIR/empty-types.rs:442:11
563+
--> $DIR/empty-types.rs:451:11
550564
|
551565
LL | match ref_opt_never {
552566
| ^^^^^^^^^^^^^ pattern `&Some(_)` not covered
@@ -565,7 +579,7 @@ LL + &Some(_) => todo!()
565579
|
566580

567581
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
568-
--> $DIR/empty-types.rs:483:11
582+
--> $DIR/empty-types.rs:492:11
569583
|
570584
LL | match *ref_opt_never {
571585
| ^^^^^^^^^^^^^^ pattern `Some(_)` not covered
@@ -584,7 +598,7 @@ LL + Some(_) => todo!()
584598
|
585599

586600
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
587-
--> $DIR/empty-types.rs:531:11
601+
--> $DIR/empty-types.rs:540:11
588602
|
589603
LL | match *ref_res_never {
590604
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@@ -603,7 +617,7 @@ LL + Err(_) => todo!()
603617
|
604618

605619
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
606-
--> $DIR/empty-types.rs:542:11
620+
--> $DIR/empty-types.rs:551:11
607621
|
608622
LL | match *ref_res_never {
609623
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@@ -622,7 +636,7 @@ LL + Err(_) => todo!()
622636
|
623637

624638
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
625-
--> $DIR/empty-types.rs:561:11
639+
--> $DIR/empty-types.rs:570:11
626640
|
627641
LL | match *ref_tuple_half_never {}
628642
| ^^^^^^^^^^^^^^^^^^^^^
@@ -636,39 +650,39 @@ LL + }
636650
|
637651

638652
error: unreachable pattern
639-
--> $DIR/empty-types.rs:594:9
653+
--> $DIR/empty-types.rs:603:9
640654
|
641655
LL | _ => {}
642656
| ^
643657
|
644658
= note: this pattern matches no values because `!` is uninhabited
645659

646660
error: unreachable pattern
647-
--> $DIR/empty-types.rs:597:9
661+
--> $DIR/empty-types.rs:606:9
648662
|
649663
LL | _x => {}
650664
| ^^
651665
|
652666
= note: this pattern matches no values because `!` is uninhabited
653667

654668
error: unreachable pattern
655-
--> $DIR/empty-types.rs:600:9
669+
--> $DIR/empty-types.rs:609:9
656670
|
657671
LL | _ if false => {}
658672
| ^
659673
|
660674
= note: this pattern matches no values because `!` is uninhabited
661675

662676
error: unreachable pattern
663-
--> $DIR/empty-types.rs:603:9
677+
--> $DIR/empty-types.rs:612:9
664678
|
665679
LL | _x if false => {}
666680
| ^^
667681
|
668682
= note: this pattern matches no values because `!` is uninhabited
669683

670684
error[E0004]: non-exhaustive patterns: `&_` not covered
671-
--> $DIR/empty-types.rs:628:11
685+
--> $DIR/empty-types.rs:637:11
672686
|
673687
LL | match ref_never {
674688
| ^^^^^^^^^ pattern `&_` not covered
@@ -684,7 +698,7 @@ LL + &_ => todo!()
684698
|
685699

686700
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
687-
--> $DIR/empty-types.rs:644:11
701+
--> $DIR/empty-types.rs:653:11
688702
|
689703
LL | match *ref_result_never {
690704
| ^^^^^^^^^^^^^^^^^ pattern `Ok(_)` not covered
@@ -703,7 +717,7 @@ LL + Ok(_) => todo!()
703717
|
704718

705719
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
706-
--> $DIR/empty-types.rs:664:11
720+
--> $DIR/empty-types.rs:673:11
707721
|
708722
LL | match *x {
709723
| ^^ pattern `Some(_)` not covered
@@ -721,7 +735,7 @@ LL ~ None => {},
721735
LL + Some(_) => todo!()
722736
|
723737

724-
error: aborting due to 64 previous errors
738+
error: aborting due to 65 previous errors
725739

726740
Some errors have detailed explanations: E0004, E0005.
727741
For more information about an error, try `rustc --explain E0004`.

‎tests/ui/pattern/usefulness/empty-types.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#[derive(Copy, Clone)]
1818
enum Void {}
1919

20-
/// A bunch of never situations that can't be normally constructed.
20+
/// A bunch of never situations that can't be normally constructed so we take them as argument.
2121
#[derive(Copy, Clone)]
2222
struct NeverBundle {
2323
never: !,
@@ -272,6 +272,8 @@ fn nested_validity_tracking(bundle: NeverBundle) {
272272
let ref_never: &! = &never;
273273
let tuple_never: (!, !) = bundle.tuple_never;
274274
let result_never: Result<!, !> = bundle.result_never;
275+
let result_never_err: Result<u8, !> = Ok(0);
276+
let ptr_result_never_err: *const Result<u8, !> = &result_never_err as *const _;
275277
let union_never = Uninit::<!>::new();
276278

277279
// These should be considered known_valid and warn unreachable.
@@ -287,6 +289,13 @@ fn nested_validity_tracking(bundle: NeverBundle) {
287289
}
288290

289291
// These should be considered !known_valid and not warn unreachable.
292+
unsafe {
293+
match *ptr_result_never_err {
294+
Ok(_) => {}
295+
Err(_) => {}
296+
}
297+
let Ok(_) = *ptr_result_never_err; //[normal,never_pats]~ ERROR refutable pattern
298+
}
290299
match ref_never {
291300
&_ => {}
292301
}

0 commit comments

Comments
 (0)
This repository has been archived.