Skip to content

Commit 0d8969e

Browse files
committed
Auto merge of #152260 - JonathanBrouwer:rollup-ZTLa9e6, r=JonathanBrouwer
Rollup of 5 pull requests Successful merges: - #149960 (add `unreachable_cfg_select_predicates` lint) - #152126 (Convert to inline diagnostics in `rustc_mir_build`) - #152186 (Convert to inline diagnostics in `rustc_const_eval`) - #152234 (Dont strip const blocks in array lengths) - #152243 (Use relative paths for std links in rustc-docs)
2 parents efc9e1b + b38e122 commit 0d8969e

File tree

47 files changed

+1592
-1718
lines changed

Some content is hidden

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

47 files changed

+1592
-1718
lines changed

Cargo.lock

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3539,6 +3539,7 @@ dependencies = [
35393539
"rustc_abi",
35403540
"rustc_ast",
35413541
"rustc_ast_pretty",
3542+
"rustc_data_structures",
35423543
"rustc_errors",
35433544
"rustc_feature",
35443545
"rustc_hir",
@@ -3703,7 +3704,6 @@ dependencies = [
37033704
"rustc_ast",
37043705
"rustc_data_structures",
37053706
"rustc_errors",
3706-
"rustc_fluent_macro",
37073707
"rustc_hir",
37083708
"rustc_index",
37093709
"rustc_infer",
@@ -4281,7 +4281,6 @@ dependencies = [
42814281
"rustc_ast",
42824282
"rustc_data_structures",
42834283
"rustc_errors",
4284-
"rustc_fluent_macro",
42854284
"rustc_hir",
42864285
"rustc_index",
42874286
"rustc_infer",

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
827827
hir_id,
828828
def_id: self.local_def_id(v.id),
829829
data: self.lower_variant_data(hir_id, item_kind, &v.data),
830-
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const_to_anon_const(e)),
830+
disr_expr: v
831+
.disr_expr
832+
.as_ref()
833+
.map(|e| self.lower_anon_const_to_anon_const(e, e.value.span)),
831834
ident: self.lower_ident(v.ident),
832835
span: self.lower_span(v.span),
833836
}
@@ -917,7 +920,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
917920
None => Ident::new(sym::integer(index), self.lower_span(f.span)),
918921
},
919922
vis_span: self.lower_span(f.vis.span),
920-
default: f.default.as_ref().map(|v| self.lower_anon_const_to_anon_const(v)),
923+
default: f
924+
.default
925+
.as_ref()
926+
.map(|v| self.lower_anon_const_to_anon_const(v, v.value.span)),
921927
ty,
922928
safety: self.lower_safety(f.safety, hir::Safety::Safe),
923929
}

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 24 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2425,15 +2425,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24252425
);
24262426

24272427
let lowered_args = self.arena.alloc_from_iter(args.iter().map(|arg| {
2428-
let const_arg = if let ExprKind::ConstBlock(anon_const) = &arg.kind {
2429-
let def_id = self.local_def_id(anon_const.id);
2430-
let def_kind = self.tcx.def_kind(def_id);
2431-
assert_eq!(DefKind::AnonConst, def_kind);
2432-
self.lower_anon_const_to_const_arg(anon_const)
2433-
} else {
2434-
self.lower_expr_to_const_arg_direct(arg)
2435-
};
2436-
2428+
let const_arg = self.lower_expr_to_const_arg_direct(arg);
24372429
&*self.arena.alloc(const_arg)
24382430
}));
24392431

@@ -2445,16 +2437,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24452437
}
24462438
ExprKind::Tup(exprs) => {
24472439
let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| {
2448-
let expr = if let ExprKind::ConstBlock(anon_const) = &expr.kind {
2449-
let def_id = self.local_def_id(anon_const.id);
2450-
let def_kind = self.tcx.def_kind(def_id);
2451-
assert_eq!(DefKind::AnonConst, def_kind);
2452-
2453-
self.lower_anon_const_to_const_arg(anon_const)
2454-
} else {
2455-
self.lower_expr_to_const_arg_direct(&expr)
2456-
};
2457-
2440+
let expr = self.lower_expr_to_const_arg_direct(&expr);
24582441
&*self.arena.alloc(expr)
24592442
}));
24602443

@@ -2494,16 +2477,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24942477
// then go unused as the `Target::ExprField` is not actually
24952478
// corresponding to `Node::ExprField`.
24962479
self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField);
2497-
2498-
let expr = if let ExprKind::ConstBlock(anon_const) = &f.expr.kind {
2499-
let def_id = self.local_def_id(anon_const.id);
2500-
let def_kind = self.tcx.def_kind(def_id);
2501-
assert_eq!(DefKind::AnonConst, def_kind);
2502-
2503-
self.lower_anon_const_to_const_arg(anon_const)
2504-
} else {
2505-
self.lower_expr_to_const_arg_direct(&f.expr)
2506-
};
2480+
let expr = self.lower_expr_to_const_arg_direct(&f.expr);
25072481

25082482
&*self.arena.alloc(hir::ConstArgExprField {
25092483
hir_id,
@@ -2521,13 +2495,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25212495
}
25222496
ExprKind::Array(elements) => {
25232497
let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| {
2524-
let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind {
2525-
let def_id = self.local_def_id(anon_const.id);
2526-
assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
2527-
self.lower_anon_const_to_const_arg(anon_const)
2528-
} else {
2529-
self.lower_expr_to_const_arg_direct(element)
2530-
};
2498+
let const_arg = self.lower_expr_to_const_arg_direct(element);
25312499
&*self.arena.alloc(const_arg)
25322500
}));
25332501
let array_expr = self.arena.alloc(hir::ConstArgArrayExpr {
@@ -2557,6 +2525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25572525
| ExprKind::Call(..)
25582526
| ExprKind::Tup(..)
25592527
| ExprKind::Array(..)
2528+
| ExprKind::ConstBlock(..)
25602529
)
25612530
{
25622531
return self.lower_expr_to_const_arg_direct(expr);
@@ -2586,6 +2555,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25862555
span,
25872556
}
25882557
}
2558+
ExprKind::ConstBlock(anon_const) => {
2559+
let def_id = self.local_def_id(anon_const.id);
2560+
assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
2561+
self.lower_anon_const_to_const_arg(anon_const, span)
2562+
}
25892563
_ => overly_complex_const(self),
25902564
}
25912565
}
@@ -2596,11 +2570,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25962570
&mut self,
25972571
anon: &AnonConst,
25982572
) -> &'hir hir::ConstArg<'hir> {
2599-
self.arena.alloc(self.lower_anon_const_to_const_arg(anon))
2573+
self.arena.alloc(self.lower_anon_const_to_const_arg(anon, anon.value.span))
26002574
}
26012575

26022576
#[instrument(level = "debug", skip(self))]
2603-
fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2577+
fn lower_anon_const_to_const_arg(
2578+
&mut self,
2579+
anon: &AnonConst,
2580+
span: Span,
2581+
) -> hir::ConstArg<'hir> {
26042582
let tcx = self.tcx;
26052583

26062584
// We cannot change parsing depending on feature gates available,
@@ -2611,7 +2589,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
26112589
if tcx.features().min_generic_const_args() {
26122590
return match anon.mgca_disambiguation {
26132591
MgcaDisambiguation::AnonConst => {
2614-
let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2592+
let lowered_anon = self.lower_anon_const_to_anon_const(anon, span);
26152593
ConstArg {
26162594
hir_id: self.next_id(),
26172595
kind: hir::ConstArgKind::Anon(lowered_anon),
@@ -2657,7 +2635,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
26572635
};
26582636
}
26592637

2660-
let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2638+
let lowered_anon = self.lower_anon_const_to_anon_const(anon, anon.value.span);
26612639
ConstArg {
26622640
hir_id: self.next_id(),
26632641
kind: hir::ConstArgKind::Anon(lowered_anon),
@@ -2667,15 +2645,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
26672645

26682646
/// See [`hir::ConstArg`] for when to use this function vs
26692647
/// [`Self::lower_anon_const_to_const_arg`].
2670-
fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2648+
fn lower_anon_const_to_anon_const(
2649+
&mut self,
2650+
c: &AnonConst,
2651+
span: Span,
2652+
) -> &'hir hir::AnonConst {
26712653
self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
26722654
let def_id = this.local_def_id(c.id);
26732655
let hir_id = this.lower_node_id(c.id);
26742656
hir::AnonConst {
26752657
def_id,
26762658
hir_id,
26772659
body: this.lower_const_body(c.value.span, Some(&c.value)),
2678-
span: this.lower_span(c.value.span),
2660+
span: this.lower_span(span),
26792661
}
26802662
}))
26812663
}

compiler/rustc_attr_parsing/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2024"
88
rustc_abi = { path = "../rustc_abi" }
99
rustc_ast = { path = "../rustc_ast" }
1010
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
11+
rustc_data_structures = { path = "../rustc_data_structures" }
1112
rustc_errors = { path = "../rustc_errors" }
1213
rustc_feature = { path = "../rustc_feature" }
1314
rustc_hir = { path = "../rustc_hir" }

compiler/rustc_attr_parsing/src/attributes/cfg_select.rs

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
use rustc_ast::token::Token;
22
use rustc_ast::tokenstream::TokenStream;
33
use rustc_ast::{AttrStyle, NodeId, token};
4+
use rustc_data_structures::fx::FxHashMap;
45
use rustc_feature::{AttributeTemplate, Features};
56
use rustc_hir::attrs::CfgEntry;
67
use rustc_hir::{AttrPath, Target};
78
use rustc_parse::exp;
89
use rustc_parse::parser::{Parser, Recovery};
910
use rustc_session::Session;
10-
use rustc_span::{ErrorGuaranteed, Span, sym};
11+
use rustc_session::lint::BuiltinLintDiag;
12+
use rustc_session::lint::builtin::UNREACHABLE_CFG_SELECT_PREDICATES;
13+
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
1114

1215
use crate::parser::MetaItemOrLitParser;
1316
use crate::{AttributeParser, ParsedDescription, ShouldEmit, parse_cfg_entry};
1417

18+
#[derive(Clone)]
1519
pub enum CfgSelectPredicate {
1620
Cfg(CfgEntry),
1721
Wildcard(Token),
1822
}
1923

24+
impl CfgSelectPredicate {
25+
fn span(&self) -> Span {
26+
match self {
27+
CfgSelectPredicate::Cfg(cfg_entry) => cfg_entry.span(),
28+
CfgSelectPredicate::Wildcard(token) => token.span,
29+
}
30+
}
31+
}
32+
2033
#[derive(Default)]
2134
pub struct CfgSelectBranches {
2235
/// All the conditional branches.
@@ -115,5 +128,102 @@ pub fn parse_cfg_select(
115128
}
116129
}
117130

131+
if let Some(features) = features
132+
&& features.enabled(sym::cfg_select)
133+
{
134+
let it = branches
135+
.reachable
136+
.iter()
137+
.map(|(entry, _, _)| CfgSelectPredicate::Cfg(entry.clone()))
138+
.chain(branches.wildcard.as_ref().map(|(t, _, _)| CfgSelectPredicate::Wildcard(*t)))
139+
.chain(
140+
branches.unreachable.iter().map(|(entry, _, _)| CfgSelectPredicate::clone(entry)),
141+
);
142+
143+
lint_unreachable(p, it, lint_node_id);
144+
}
145+
118146
Ok(branches)
119147
}
148+
149+
fn lint_unreachable(
150+
p: &mut Parser<'_>,
151+
predicates: impl Iterator<Item = CfgSelectPredicate>,
152+
lint_node_id: NodeId,
153+
) {
154+
// Symbols that have a known value.
155+
let mut known = FxHashMap::<Symbol, bool>::default();
156+
let mut wildcard_span = None;
157+
let mut it = predicates;
158+
159+
let branch_is_unreachable = |predicate: CfgSelectPredicate, wildcard_span| {
160+
let span = predicate.span();
161+
p.psess.buffer_lint(
162+
UNREACHABLE_CFG_SELECT_PREDICATES,
163+
span,
164+
lint_node_id,
165+
BuiltinLintDiag::UnreachableCfg { span, wildcard_span },
166+
);
167+
};
168+
169+
for predicate in &mut it {
170+
let CfgSelectPredicate::Cfg(ref cfg_entry) = predicate else {
171+
wildcard_span = Some(predicate.span());
172+
break;
173+
};
174+
175+
match cfg_entry {
176+
CfgEntry::Bool(true, _) => {
177+
wildcard_span = Some(predicate.span());
178+
break;
179+
}
180+
CfgEntry::Bool(false, _) => continue,
181+
CfgEntry::NameValue { name, value, .. } => match value {
182+
None => {
183+
// `name` will be false in all subsequent branches.
184+
let current = known.insert(*name, false);
185+
186+
match current {
187+
None => continue,
188+
Some(false) => {
189+
branch_is_unreachable(predicate, None);
190+
break;
191+
}
192+
Some(true) => {
193+
// this branch will be taken, so all subsequent branches are unreachable.
194+
break;
195+
}
196+
}
197+
}
198+
Some(_) => { /* for now we don't bother solving these */ }
199+
},
200+
CfgEntry::Not(inner, _) => match &**inner {
201+
CfgEntry::NameValue { name, value: None, .. } => {
202+
// `name` will be true in all subsequent branches.
203+
let current = known.insert(*name, true);
204+
205+
match current {
206+
None => continue,
207+
Some(true) => {
208+
branch_is_unreachable(predicate, None);
209+
break;
210+
}
211+
Some(false) => {
212+
// this branch will be taken, so all subsequent branches are unreachable.
213+
break;
214+
}
215+
}
216+
}
217+
_ => { /* for now we don't bother solving these */ }
218+
},
219+
CfgEntry::All(_, _) | CfgEntry::Any(_, _) => {
220+
/* for now we don't bother solving these */
221+
}
222+
CfgEntry::Version(..) => { /* don't bother solving these */ }
223+
}
224+
}
225+
226+
for predicate in it {
227+
branch_is_unreachable(predicate, wildcard_span)
228+
}
229+
}

compiler/rustc_builtin_macros/src/cfg_select.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
use rustc_ast::tokenstream::TokenStream;
22
use rustc_ast::{Expr, ast};
33
use rustc_attr_parsing as attr;
4-
use rustc_attr_parsing::{
5-
CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, parse_cfg_select,
6-
};
4+
use rustc_attr_parsing::{CfgSelectBranches, EvalConfigResult, parse_cfg_select};
75
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacResult, MacroExpanderResult};
86
use rustc_span::{Ident, Span, sym};
97
use smallvec::SmallVec;
108

11-
use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable};
9+
use crate::errors::CfgSelectNoMatches;
1210

1311
/// This intermediate structure is used to emit parse errors for the branches that are not chosen.
1412
/// The `MacResult` instance below parses all branches, emitting any errors it encounters, but only
@@ -75,18 +73,6 @@ pub(super) fn expand_cfg_select<'cx>(
7573
ecx.current_expansion.lint_node_id,
7674
) {
7775
Ok(mut branches) => {
78-
if let Some((underscore, _, _)) = branches.wildcard {
79-
// Warn for every unreachable predicate. We store the fully parsed branch for rustfmt.
80-
for (predicate, _, _) in &branches.unreachable {
81-
let span = match predicate {
82-
CfgSelectPredicate::Wildcard(underscore) => underscore.span,
83-
CfgSelectPredicate::Cfg(cfg) => cfg.span(),
84-
};
85-
let err = CfgSelectUnreachable { span, wildcard_span: underscore.span };
86-
ecx.dcx().emit_warn(err);
87-
}
88-
}
89-
9076
if let Some((selected_tts, selected_span)) = branches.pop_first_match(|cfg| {
9177
matches!(attr::eval_config_entry(&ecx.sess, cfg), EvalConfigResult::True)
9278
}) {

compiler/rustc_builtin_macros/src/errors.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,17 +1086,6 @@ pub(crate) struct CfgSelectNoMatches {
10861086
pub span: Span,
10871087
}
10881088

1089-
#[derive(Diagnostic)]
1090-
#[diag("unreachable predicate")]
1091-
pub(crate) struct CfgSelectUnreachable {
1092-
#[primary_span]
1093-
#[label("this predicate is never reached")]
1094-
pub span: Span,
1095-
1096-
#[label("always matches")]
1097-
pub wildcard_span: Span,
1098-
}
1099-
11001089
#[derive(Diagnostic)]
11011090
#[diag("`#[eii_declaration(...)]` is only valid on macros")]
11021091
pub(crate) struct EiiExternTargetExpectedMacro {

0 commit comments

Comments
 (0)