Skip to content

Commit 0312a55

Browse files
committed
Auto merge of #154802 - matthiaskrgr:rollup-HWNmEyC, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #154376 (Remove more BuiltinLintDiag variants - part 4) - #154731 (llvm: Fix array ABI test to not check equality implementation) - #127534 (feat(core): impl Step for NonZero<u*>) - #154703 (Fix trailing comma in lifetime suggestion for empty angle brackets) - #154776 (Fix ICE in read_discriminant for enums with non-contiguous discriminants)
2 parents 981cf69 + 7f18b25 commit 0312a55

File tree

20 files changed

+540
-174
lines changed

20 files changed

+540
-174
lines changed

compiler/rustc_const_eval/src/interpret/discriminant.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,20 +121,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
121121
// discriminants are int-like.
122122
let discr_val = self.int_to_int_or_float(&tag_val, discr_layout).unwrap();
123123
let discr_bits = discr_val.to_scalar().to_bits(discr_layout.size)?;
124-
// Convert discriminant to variant index. Since we validated the tag against the
125-
// layout range above, this cannot fail.
124+
// Convert discriminant to variant index. The tag may pass the layout range
125+
// check above but still not match any actual variant discriminant (e.g.,
126+
// non-contiguous discriminants with a wrapping valid_range).
126127
let index = match *ty.kind() {
127128
ty::Adt(adt, _) => {
128-
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits).unwrap()
129+
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
129130
}
130131
ty::Coroutine(def_id, args) => {
131132
let args = args.as_coroutine();
132-
args.discriminants(def_id, *self.tcx)
133-
.find(|(_, var)| var.val == discr_bits)
134-
.unwrap()
133+
args.discriminants(def_id, *self.tcx).find(|(_, var)| var.val == discr_bits)
135134
}
136135
_ => span_bug!(self.cur_span(), "tagged layout for non-adt non-coroutine"),
137-
};
136+
}
137+
.ok_or_else(|| err_ub!(InvalidTag(Scalar::from_uint(tag_bits, tag_layout.size))))?;
138138
// Return the cast value, and the index.
139139
index.0
140140
}

compiler/rustc_errors/src/decorate_diag.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::any::Any;
2+
13
/// This module provides types and traits for buffering lints until later in compilation.
24
use rustc_ast::node_id::NodeId;
35
use rustc_data_structures::fx::FxIndexMap;
@@ -10,9 +12,11 @@ use crate::{Diag, DiagCtxtHandle, Diagnostic, Level};
1012
/// We can't implement `Diagnostic` for `BuiltinLintDiag`, because decorating some of its
1113
/// variants requires types we don't have yet. So, handle that case separately.
1214
pub enum DecorateDiagCompat {
15+
/// The third argument of the closure is a `Session`. However, due to the dependency tree,
16+
/// we don't have access to `rustc_session` here, so we downcast it when needed.
1317
Dynamic(
1418
Box<
15-
dyn for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()>
19+
dyn for<'a> FnOnce(DiagCtxtHandle<'a>, Level, &dyn Any) -> Diag<'a, ()>
1620
+ DynSync
1721
+ DynSend
1822
+ 'static,
@@ -30,7 +34,7 @@ impl std::fmt::Debug for DecorateDiagCompat {
3034
impl<D: for<'a> Diagnostic<'a, ()> + DynSync + DynSend + 'static> From<D> for DecorateDiagCompat {
3135
#[inline]
3236
fn from(d: D) -> Self {
33-
Self::Dynamic(Box::new(|dcx, level| d.into_diag(dcx, level)))
37+
Self::Dynamic(Box::new(|dcx, level, _| d.into_diag(dcx, level)))
3438
}
3539
}
3640

@@ -97,6 +101,26 @@ impl LintBuffer {
97101
node_id: NodeId,
98102
span: impl Into<MultiSpan>,
99103
callback: F,
104+
) {
105+
self.add_early_lint(BufferedEarlyLint {
106+
lint_id: LintId::of(lint),
107+
node_id,
108+
span: Some(span.into()),
109+
diagnostic: DecorateDiagCompat::Dynamic(Box::new(|dcx, level, _| callback(dcx, level))),
110+
});
111+
}
112+
113+
pub fn dyn_buffer_lint_any<
114+
F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level, &dyn Any) -> Diag<'a, ()>
115+
+ DynSend
116+
+ DynSync
117+
+ 'static,
118+
>(
119+
&mut self,
120+
lint: &'static Lint,
121+
node_id: NodeId,
122+
span: impl Into<MultiSpan>,
123+
callback: F,
100124
) {
101125
self.add_early_lint(BufferedEarlyLint {
102126
lint_id: LintId::of(lint),

compiler/rustc_errors/src/diagnostic.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use std::panic;
77
use std::path::PathBuf;
88
use std::thread::panicking;
99

10-
use rustc_data_structures::sync::{DynSend, DynSync};
1110
use rustc_error_messages::{DiagArgMap, DiagArgName, DiagArgValue, IntoDiagArg};
1211
use rustc_lint_defs::{Applicability, LintExpectationId};
1312
use rustc_macros::{Decodable, Encodable};
@@ -119,16 +118,6 @@ where
119118
}
120119
}
121120

122-
impl<'a> Diagnostic<'a, ()>
123-
for Box<
124-
dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level) -> Diag<'b, ()> + DynSync + DynSend + 'static,
125-
>
126-
{
127-
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
128-
self(dcx, level)
129-
}
130-
}
131-
132121
/// Type used to emit diagnostic through a closure instead of implementing the `Diagnostic` trait.
133122
pub struct DiagDecorator<F: FnOnce(&mut Diag<'_, ()>)>(pub F);
134123

compiler/rustc_lint/src/early.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use rustc_session::lint::LintPass;
1515
use rustc_span::{DUMMY_SP, Ident, Span};
1616
use tracing::debug;
1717

18-
use crate::DecorateBuiltinLint;
1918
use crate::context::{EarlyContext, LintContext, LintStore};
2019
use crate::passes::{EarlyLintPass, EarlyLintPassObject};
20+
use crate::{DecorateBuiltinLint, DiagAndSess};
2121

2222
pub(super) mod diagnostics;
2323

@@ -49,8 +49,12 @@ impl<'ecx, 'tcx, T: EarlyLintPass> EarlyContextAndPass<'ecx, 'tcx, T> {
4949
},
5050
);
5151
}
52-
DecorateDiagCompat::Dynamic(d) => {
53-
self.context.opt_span_lint(lint_id.lint, span, d);
52+
DecorateDiagCompat::Dynamic(callback) => {
53+
self.context.opt_span_lint(
54+
lint_id.lint,
55+
span,
56+
DiagAndSess { callback, sess: self.context.sess() },
57+
);
5458
}
5559
}
5660
}

compiler/rustc_lint/src/early/diagnostics.rs

Lines changed: 15 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use std::any::Any;
12
use std::borrow::Cow;
23

4+
use rustc_data_structures::sync::DynSend;
35
use rustc_errors::{
46
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, Level,
57
elided_lifetime_in_path_suggestion,
@@ -8,12 +10,24 @@ use rustc_hir::lints::{AttributeLintKind, FormatWarning};
810
use rustc_middle::ty::TyCtxt;
911
use rustc_session::Session;
1012
use rustc_session::lint::BuiltinLintDiag;
11-
use tracing::debug;
1213

1314
use crate::lints;
1415

1516
mod check_cfg;
1617

18+
pub struct DiagAndSess<'sess> {
19+
pub callback: Box<
20+
dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level, &dyn Any) -> Diag<'b, ()> + DynSend + 'static,
21+
>,
22+
pub sess: &'sess Session,
23+
}
24+
25+
impl<'a> Diagnostic<'a, ()> for DiagAndSess<'_> {
26+
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
27+
(self.callback)(dcx, level, self.sess)
28+
}
29+
}
30+
1731
/// This is a diagnostic struct that will decorate a `BuiltinLintDiag`
1832
/// Directly creating the lint structs is expensive, using this will only decorate the lint structs when needed.
1933
pub struct DecorateBuiltinLint<'sess, 'tcx> {
@@ -25,28 +39,6 @@ pub struct DecorateBuiltinLint<'sess, 'tcx> {
2539
impl<'a> Diagnostic<'a, ()> for DecorateBuiltinLint<'_, '_> {
2640
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
2741
match self.diagnostic {
28-
BuiltinLintDiag::AbsPathWithModule(mod_span) => {
29-
let (replacement, applicability) =
30-
match self.sess.source_map().span_to_snippet(mod_span) {
31-
Ok(ref s) => {
32-
// FIXME(Manishearth) ideally the emitting code
33-
// can tell us whether or not this is global
34-
let opt_colon =
35-
if s.trim_start().starts_with("::") { "" } else { "::" };
36-
37-
(format!("crate{opt_colon}{s}"), Applicability::MachineApplicable)
38-
}
39-
Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
40-
};
41-
lints::AbsPathWithModule {
42-
sugg: lints::AbsPathWithModuleSugg {
43-
span: mod_span,
44-
applicability,
45-
replacement,
46-
},
47-
}
48-
.into_diag(dcx, level)
49-
}
5042
BuiltinLintDiag::ElidedLifetimesInPaths(
5143
n,
5244
path_span,
@@ -87,36 +79,6 @@ impl<'a> Diagnostic<'a, ()> for DecorateBuiltinLint<'_, '_> {
8779
}
8880
.into_diag(dcx, level)
8981
}
90-
BuiltinLintDiag::SingleUseLifetime {
91-
param_span,
92-
use_span,
93-
elidable,
94-
deletion_span,
95-
ident,
96-
} => {
97-
debug!(?param_span, ?use_span, ?deletion_span);
98-
let suggestion = if let Some(deletion_span) = deletion_span {
99-
let (use_span, replace_lt) = if elidable {
100-
let use_span =
101-
self.sess.source_map().span_extend_while_whitespace(use_span);
102-
(use_span, String::new())
103-
} else {
104-
(use_span, "'_".to_owned())
105-
};
106-
debug!(?deletion_span, ?use_span);
107-
108-
// issue 107998 for the case such as a wrong function pointer type
109-
// `deletion_span` is empty and there is no need to report lifetime uses here
110-
let deletion_span =
111-
if deletion_span.is_empty() { None } else { Some(deletion_span) };
112-
Some(lints::SingleUseLifetimeSugg { deletion_span, use_span, replace_lt })
113-
} else {
114-
None
115-
};
116-
117-
lints::SingleUseLifetime { suggestion, param_span, use_span, ident }
118-
.into_diag(dcx, level)
119-
}
12082
BuiltinLintDiag::NamedArgumentUsedPositionally {
12183
position_sp_to_replace,
12284
position_sp_for_msg,

compiler/rustc_lint/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ use unused::*;
129129
#[rustfmt::skip]
130130
pub use builtin::{MissingDoc, SoftLints};
131131
pub use context::{EarlyContext, LateContext, LintContext, LintStore};
132-
pub use early::diagnostics::{DecorateAttrLint, DecorateBuiltinLint};
132+
pub use early::diagnostics::{DecorateAttrLint, DecorateBuiltinLint, DiagAndSess};
133133
pub use early::{EarlyCheckNode, check_ast_node};
134134
pub use late::{check_crate, late_lint_mod, unerased_lint_store};
135135
pub use levels::LintLevelsBuilder;

compiler/rustc_lint/src/lints.rs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,25 +3011,6 @@ pub(crate) struct IllFormedAttributeInput {
30113011
pub docs: &'static str,
30123012
}
30133013

3014-
#[derive(Diagnostic)]
3015-
#[diag(
3016-
"absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition"
3017-
)]
3018-
pub(crate) struct AbsPathWithModule {
3019-
#[subdiagnostic]
3020-
pub sugg: AbsPathWithModuleSugg,
3021-
}
3022-
3023-
#[derive(Subdiagnostic)]
3024-
#[suggestion("use `crate`", code = "{replacement}")]
3025-
pub(crate) struct AbsPathWithModuleSugg {
3026-
#[primary_span]
3027-
pub span: Span,
3028-
#[applicability]
3029-
pub applicability: Applicability,
3030-
pub replacement: String,
3031-
}
3032-
30333014
#[derive(Diagnostic)]
30343015
#[diag("hidden lifetime parameters in types are deprecated")]
30353016
pub(crate) struct ElidedLifetimesInPaths {
@@ -3081,30 +3062,6 @@ pub(crate) enum UnusedImportsSugg {
30813062
},
30823063
}
30833064

3084-
#[derive(Diagnostic)]
3085-
#[diag("lifetime parameter `{$ident}` only used once")]
3086-
pub(crate) struct SingleUseLifetime {
3087-
#[label("this lifetime...")]
3088-
pub param_span: Span,
3089-
#[label("...is used only here")]
3090-
pub use_span: Span,
3091-
#[subdiagnostic]
3092-
pub suggestion: Option<SingleUseLifetimeSugg>,
3093-
3094-
pub ident: Ident,
3095-
}
3096-
3097-
#[derive(Subdiagnostic)]
3098-
#[multipart_suggestion("elide the single-use lifetime", applicability = "machine-applicable")]
3099-
pub(crate) struct SingleUseLifetimeSugg {
3100-
#[suggestion_part(code = "")]
3101-
pub deletion_span: Option<Span>,
3102-
#[suggestion_part(code = "{replace_lt}")]
3103-
pub use_span: Span,
3104-
3105-
pub replace_lt: String,
3106-
}
3107-
31083065
#[derive(Diagnostic)]
31093066
#[diag("named argument `{$named_arg_name}` is not used by name")]
31103067
pub(crate) struct NamedArgumentUsedPositionally {

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,6 @@ pub enum DeprecatedSinceKind {
656656
// becomes hacky (and it gets allocated).
657657
#[derive(Debug)]
658658
pub enum BuiltinLintDiag {
659-
AbsPathWithModule(Span),
660659
ElidedLifetimesInPaths(usize, Span, bool, Span),
661660
UnusedImports {
662661
remove_whole_use: bool,
@@ -665,18 +664,6 @@ pub enum BuiltinLintDiag {
665664
test_module_span: Option<Span>,
666665
span_snippets: Vec<String>,
667666
},
668-
SingleUseLifetime {
669-
/// Span of the parameter which declares this lifetime.
670-
param_span: Span,
671-
/// Span of the code that should be removed when eliding this lifetime.
672-
/// This span should include leading or trailing comma.
673-
deletion_span: Option<Span>,
674-
/// Span of the single use, or None if the lifetime is never used.
675-
/// If true, the lifetime will be fully elided.
676-
use_span: Span,
677-
elidable: bool,
678-
ident: Ident,
679-
},
680667
NamedArgumentUsedPositionally {
681668
/// Span where the named argument is used by position and will be replaced with the named
682669
/// argument name

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1111
use rustc_data_structures::unord::{UnordMap, UnordSet};
1212
use rustc_errors::codes::*;
1313
use rustc_errors::{
14-
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, MultiSpan, SuggestionStyle,
14+
Applicability, Diag, DiagCtxtHandle, Diagnostic, ErrorGuaranteed, MultiSpan, SuggestionStyle,
1515
struct_span_code_err,
1616
};
1717
use rustc_feature::BUILTIN_ATTRIBUTES;
@@ -23,7 +23,6 @@ use rustc_hir::{PrimTy, Stability, StabilityLevel, find_attr};
2323
use rustc_middle::bug;
2424
use rustc_middle::ty::TyCtxt;
2525
use rustc_session::Session;
26-
use rustc_session::lint::BuiltinLintDiag;
2726
use rustc_session::lint::builtin::{
2827
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS, AMBIGUOUS_IMPORT_VISIBILITIES,
2928
AMBIGUOUS_PANIC_IMPORTS, MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
@@ -510,12 +509,35 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
510509
return;
511510
}
512511

513-
let diag = BuiltinLintDiag::AbsPathWithModule(root_span);
514-
self.lint_buffer.buffer_lint(
512+
self.lint_buffer.dyn_buffer_lint_any(
515513
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
516514
node_id,
517515
root_span,
518-
diag,
516+
move |dcx, level, sess| {
517+
let (replacement, applicability) = match sess
518+
.downcast_ref::<Session>()
519+
.expect("expected a `Session`")
520+
.source_map()
521+
.span_to_snippet(root_span)
522+
{
523+
Ok(ref s) => {
524+
// FIXME(Manishearth) ideally the emitting code
525+
// can tell us whether or not this is global
526+
let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
527+
528+
(format!("crate{opt_colon}{s}"), Applicability::MachineApplicable)
529+
}
530+
Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
531+
};
532+
errors::AbsPathWithModule {
533+
sugg: errors::AbsPathWithModuleSugg {
534+
span: root_span,
535+
applicability,
536+
replacement,
537+
},
538+
}
539+
.into_diag(dcx, level)
540+
},
519541
);
520542
}
521543

0 commit comments

Comments
 (0)