Skip to content

Commit 2efd070

Browse files
committed
Auto merge of #81774 - ehuss:beta-backports, r=ehuss
[beta] backports This backports: * CI: only copy python.exe to python3.exe if the latter does not exist #81762 * Make hitting the recursion limit in projection non-fatal #81055 * Remove incorrect `delay_span_bug` #81532 * introduce future-compatibility warning for forbidden lint groups #81556 * Update cargo #81755 * rustdoc: Fix visibility of trait and impl items #81288 * Work around missing -dev packages in solaris docker image. #81229 * Update LayoutError/LayoutErr stability attributes #81767 * Revert 78373 ("dont leak return value after panic in drop") #81257 * Rename `panic_fmt` lint to `non_fmt_panic` #81729
2 parents 1cd0303 + fc81b7c commit 2efd070

File tree

66 files changed

+11621
-11133
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+11621
-11133
lines changed

compiler/rustc_lint/src/context.rs

+15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use rustc_session::SessionLintStore;
3939
use rustc_span::lev_distance::find_best_match_for_name;
4040
use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
4141
use rustc_target::abi::LayoutOf;
42+
use tracing::debug;
4243

4344
use std::cell::Cell;
4445
use std::slice;
@@ -335,6 +336,20 @@ impl LintStore {
335336
}
336337
}
337338

339+
/// True if this symbol represents a lint group name.
340+
pub fn is_lint_group(&self, lint_name: Symbol) -> bool {
341+
debug!(
342+
"is_lint_group(lint_name={:?}, lint_groups={:?})",
343+
lint_name,
344+
self.lint_groups.keys().collect::<Vec<_>>()
345+
);
346+
let lint_name_str = &*lint_name.as_str();
347+
self.lint_groups.contains_key(&lint_name_str) || {
348+
let warnings_name_str = crate::WARNINGS.name_lower();
349+
lint_name_str == &*warnings_name_str
350+
}
351+
}
352+
338353
/// Checks the name of a lint for its existence, and whether it was
339354
/// renamed or removed. Generates a DiagnosticBuilder containing a
340355
/// warning for renamed and removed lints. This is over both lint

compiler/rustc_lint/src/levels.rs

+73-28
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::attr;
55
use rustc_ast::unwrap_or;
66
use rustc_ast_pretty::pprust;
77
use rustc_data_structures::fx::FxHashMap;
8-
use rustc_errors::{struct_span_err, Applicability};
8+
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
99
use rustc_hir as hir;
1010
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
1111
use rustc_hir::{intravisit, HirId};
@@ -17,11 +17,15 @@ use rustc_middle::lint::{
1717
};
1818
use rustc_middle::ty::query::Providers;
1919
use rustc_middle::ty::TyCtxt;
20-
use rustc_session::lint::{builtin, Level, Lint, LintId};
20+
use rustc_session::lint::{
21+
builtin::{self, FORBIDDEN_LINT_GROUPS},
22+
Level, Lint, LintId,
23+
};
2124
use rustc_session::parse::feature_err;
2225
use rustc_session::Session;
2326
use rustc_span::symbol::{sym, Symbol};
2427
use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP};
28+
use tracing::debug;
2529

2630
use std::cmp;
2731

@@ -51,6 +55,7 @@ pub struct LintLevelsBuilder<'s> {
5155
id_to_set: FxHashMap<HirId, u32>,
5256
cur: u32,
5357
warn_about_weird_lints: bool,
58+
store: &'s LintStore,
5459
}
5560

5661
pub struct BuilderPush {
@@ -59,13 +64,14 @@ pub struct BuilderPush {
5964
}
6065

6166
impl<'s> LintLevelsBuilder<'s> {
62-
pub fn new(sess: &'s Session, warn_about_weird_lints: bool, store: &LintStore) -> Self {
67+
pub fn new(sess: &'s Session, warn_about_weird_lints: bool, store: &'s LintStore) -> Self {
6368
let mut builder = LintLevelsBuilder {
6469
sess,
6570
sets: LintLevelSets::new(),
6671
cur: 0,
6772
id_to_set: Default::default(),
6873
warn_about_weird_lints,
74+
store,
6975
};
7076
builder.process_command_line(sess, store);
7177
assert_eq!(builder.sets.list.len(), 1);
@@ -120,36 +126,75 @@ impl<'s> LintLevelsBuilder<'s> {
120126
if let (Level::Forbid, old_src) =
121127
self.sets.get_lint_level(id.lint, self.cur, Some(&specs), &self.sess)
122128
{
123-
let mut diag_builder = struct_span_err!(
124-
self.sess,
125-
src.span(),
126-
E0453,
127-
"{}({}) incompatible with previous forbid",
128-
level.as_str(),
129-
src.name(),
129+
// Backwards compatibility check:
130+
//
131+
// We used to not consider `forbid(lint_group)`
132+
// as preventing `allow(lint)` for some lint `lint` in
133+
// `lint_group`. For now, issue a future-compatibility
134+
// warning for this case.
135+
let id_name = id.lint.name_lower();
136+
let fcw_warning = match old_src {
137+
LintLevelSource::Default => false,
138+
LintLevelSource::Node(symbol, _, _) => self.store.is_lint_group(symbol),
139+
LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol),
140+
};
141+
debug!(
142+
"fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}",
143+
fcw_warning, specs, old_src, id_name
130144
);
131-
diag_builder.span_label(src.span(), "overruled by previous forbid");
132-
match old_src {
133-
LintLevelSource::Default => {
134-
diag_builder.note(&format!(
135-
"`forbid` lint level is the default for {}",
136-
id.to_string()
137-
));
138-
}
139-
LintLevelSource::Node(_, forbid_source_span, reason) => {
140-
diag_builder.span_label(forbid_source_span, "`forbid` level set here");
141-
if let Some(rationale) = reason {
142-
diag_builder.note(&rationale.as_str());
145+
146+
let decorate_diag_builder = |mut diag_builder: DiagnosticBuilder<'_>| {
147+
diag_builder.span_label(src.span(), "overruled by previous forbid");
148+
match old_src {
149+
LintLevelSource::Default => {
150+
diag_builder.note(&format!(
151+
"`forbid` lint level is the default for {}",
152+
id.to_string()
153+
));
154+
}
155+
LintLevelSource::Node(_, forbid_source_span, reason) => {
156+
diag_builder.span_label(forbid_source_span, "`forbid` level set here");
157+
if let Some(rationale) = reason {
158+
diag_builder.note(&rationale.as_str());
159+
}
160+
}
161+
LintLevelSource::CommandLine(_, _) => {
162+
diag_builder.note("`forbid` lint level was set on command line");
143163
}
144164
}
145-
LintLevelSource::CommandLine(_, _) => {
146-
diag_builder.note("`forbid` lint level was set on command line");
147-
}
165+
diag_builder.emit();
166+
};
167+
if !fcw_warning {
168+
let diag_builder = struct_span_err!(
169+
self.sess,
170+
src.span(),
171+
E0453,
172+
"{}({}) incompatible with previous forbid",
173+
level.as_str(),
174+
src.name(),
175+
);
176+
decorate_diag_builder(diag_builder);
177+
} else {
178+
self.struct_lint(
179+
FORBIDDEN_LINT_GROUPS,
180+
Some(src.span().into()),
181+
|diag_builder| {
182+
let diag_builder = diag_builder.build(&format!(
183+
"{}({}) incompatible with previous forbid",
184+
level.as_str(),
185+
src.name(),
186+
));
187+
decorate_diag_builder(diag_builder);
188+
},
189+
);
148190
}
149-
diag_builder.emit();
150191

151-
// Retain the forbid lint level
152-
return;
192+
// Retain the forbid lint level, unless we are
193+
// issuing a FCW. In the FCW case, we want to
194+
// respect the new setting.
195+
if !fcw_warning {
196+
return;
197+
}
153198
}
154199
}
155200
specs.insert(id, (level, src));

compiler/rustc_lint/src/panic_fmt.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use rustc_parse_format::{ParseMode, Parser, Piece};
77
use rustc_span::{sym, InnerSpan};
88

99
declare_lint! {
10-
/// The `panic_fmt` lint detects `panic!("..")` with `{` or `}` in the string literal.
10+
/// The `non_fmt_panic` lint detects `panic!("..")` with `{` or `}` in the string literal
11+
/// when it is not used as a format string.
1112
///
1213
/// ### Example
1314
///
@@ -23,13 +24,13 @@ declare_lint! {
2324
/// with a single argument does not use `format_args!()`.
2425
/// A future edition of Rust will interpret this string as format string,
2526
/// which would break this.
26-
PANIC_FMT,
27+
NON_FMT_PANIC,
2728
Warn,
2829
"detect braces in single-argument panic!() invocations",
2930
report_in_external_macro
3031
}
3132

32-
declare_lint_pass!(PanicFmt => [PANIC_FMT]);
33+
declare_lint_pass!(PanicFmt => [NON_FMT_PANIC]);
3334

3435
impl<'tcx> LateLintPass<'tcx> for PanicFmt {
3536
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
@@ -92,7 +93,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
9293
[] => vec![fmt_span],
9394
v => v.iter().map(|span| fmt_span.from_inner(*span)).collect(),
9495
};
95-
cx.struct_span_lint(PANIC_FMT, arg_spans, |lint| {
96+
cx.struct_span_lint(NON_FMT_PANIC, arg_spans, |lint| {
9697
let mut l = lint.build(match n_arguments {
9798
1 => "panic message contains an unused formatting placeholder",
9899
_ => "panic message contains unused formatting placeholders",
@@ -129,7 +130,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
129130
Some(v) if v.len() == 1 => "panic message contains a brace",
130131
_ => "panic message contains braces",
131132
};
132-
cx.struct_span_lint(PANIC_FMT, brace_spans.unwrap_or(vec![expn.call_site]), |lint| {
133+
cx.struct_span_lint(NON_FMT_PANIC, brace_spans.unwrap_or(vec![expn.call_site]), |lint| {
133134
let mut l = lint.build(msg);
134135
l.note("this message is not used as a format string, but will be in a future Rust edition");
135136
if expn.call_site.contains(arg.span) {

compiler/rustc_lint_defs/src/builtin.rs

+37
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,42 @@ use crate::{declare_lint, declare_lint_pass, declare_tool_lint};
88
use rustc_span::edition::Edition;
99
use rustc_span::symbol::sym;
1010

11+
declare_lint! {
12+
/// The `forbidden_lint_groups` lint detects violations of
13+
/// `forbid` applied to a lint group. Due to a bug in the compiler,
14+
/// these used to be overlooked entirely. They now generate a warning.
15+
///
16+
/// ### Example
17+
///
18+
/// ```rust
19+
/// #![forbid(warnings)]
20+
/// #![deny(bad_style)]
21+
///
22+
/// fn main() {}
23+
/// ```
24+
///
25+
/// {{produces}}
26+
///
27+
/// ### Recommended fix
28+
///
29+
/// If your crate is using `#![forbid(warnings)]`,
30+
/// we recommend that you change to `#![deny(warnings)]`.
31+
///
32+
/// ### Explanation
33+
///
34+
/// Due to a compiler bug, applying `forbid` to lint groups
35+
/// previously had no effect. The bug is now fixed but instead of
36+
/// enforcing `forbid` we issue this future-compatibility warning
37+
/// to avoid breaking existing crates.
38+
pub FORBIDDEN_LINT_GROUPS,
39+
Warn,
40+
"applying forbid to lint-groups",
41+
@future_incompatible = FutureIncompatibleInfo {
42+
reference: "issue #81670 <https://github.com/rust-lang/rust/issues/81670>",
43+
edition: None,
44+
};
45+
}
46+
1147
declare_lint! {
1248
/// The `ill_formed_attribute_input` lint detects ill-formed attribute
1349
/// inputs that were previously accepted and used in practice.
@@ -2839,6 +2875,7 @@ declare_lint_pass! {
28392875
/// Does nothing as a lint pass, but registers some `Lint`s
28402876
/// that are used by other parts of the compiler.
28412877
HardwiredLints => [
2878+
FORBIDDEN_LINT_GROUPS,
28422879
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
28432880
ARITHMETIC_OVERFLOW,
28442881
UNCONDITIONAL_PANIC,

compiler/rustc_middle/src/lint.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ use rustc_data_structures::fx::FxHashMap;
55
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
66
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
77
use rustc_hir::HirId;
8-
use rustc_session::lint::{builtin, Level, Lint, LintId};
8+
use rustc_session::lint::{
9+
builtin::{self, FORBIDDEN_LINT_GROUPS},
10+
Level, Lint, LintId,
11+
};
912
use rustc_session::{DiagnosticMessageId, Session};
1013
use rustc_span::hygiene::MacroKind;
1114
use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
1215
use rustc_span::{symbol, Span, Symbol, DUMMY_SP};
1316

1417
/// How a lint level was set.
15-
#[derive(Clone, Copy, PartialEq, Eq, HashStable)]
18+
#[derive(Clone, Copy, PartialEq, Eq, HashStable, Debug)]
1619
pub enum LintLevelSource {
1720
/// Lint is at the default level as declared
1821
/// in rustc or a plugin.
@@ -87,7 +90,12 @@ impl LintLevelSets {
8790
// If we're about to issue a warning, check at the last minute for any
8891
// directives against the warnings "lint". If, for example, there's an
8992
// `allow(warnings)` in scope then we want to respect that instead.
90-
if level == Level::Warn {
93+
//
94+
// We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically
95+
// triggers in cases (like #80988) where you have `forbid(warnings)`,
96+
// and so if we turned that into an error, it'd defeat the purpose of the
97+
// future compatibility warning.
98+
if level == Level::Warn && LintId::of(lint) != LintId::of(FORBIDDEN_LINT_GROUPS) {
9199
let (warnings_level, warnings_src) =
92100
self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux);
93101
if let Some(configured_warning_level) = warnings_level {

compiler/rustc_mir_build/src/build/block.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::build::ForGuard::OutsideGuard;
33
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
44
use crate::thir::*;
55
use rustc_hir as hir;
6-
use rustc_middle::middle::region;
76
use rustc_middle::mir::*;
87
use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN;
98
use rustc_session::lint::Level;
@@ -13,7 +12,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1312
crate fn ast_block(
1413
&mut self,
1514
destination: Place<'tcx>,
16-
scope: Option<region::Scope>,
1715
block: BasicBlock,
1816
ast_block: &'tcx hir::Block<'tcx>,
1917
source_info: SourceInfo,
@@ -30,10 +28,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
3028
self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| {
3129
this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
3230
if targeted_by_break {
33-
this.in_breakable_scope(None, destination, scope, span, |this| {
31+
this.in_breakable_scope(None, destination, span, |this| {
3432
Some(this.ast_block_stmts(
3533
destination,
36-
scope,
3734
block,
3835
span,
3936
stmts,
@@ -42,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4239
))
4340
})
4441
} else {
45-
this.ast_block_stmts(destination, scope, block, span, stmts, expr, safety_mode)
42+
this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode)
4643
}
4744
})
4845
})
@@ -51,7 +48,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5148
fn ast_block_stmts(
5249
&mut self,
5350
destination: Place<'tcx>,
54-
scope: Option<region::Scope>,
5551
mut block: BasicBlock,
5652
span: Span,
5753
stmts: Vec<StmtRef<'tcx>>,
@@ -186,7 +182,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
186182
};
187183
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored, span });
188184

189-
unpack!(block = this.into(destination, scope, block, expr));
185+
unpack!(block = this.into(destination, block, expr));
190186
let popped = this.block_context.pop();
191187

192188
assert!(popped.map_or(false, |bf| bf.is_tail_expr()));

0 commit comments

Comments
 (0)