Skip to content

Commit 567c266

Browse files
committed
Auto merge of #150132 - JonathanBrouwer:rollup-8ijhb7l, r=JonathanBrouwer
Rollup of 11 pull requests Successful merges: - #145933 (Expand `str_as_str` to more types) - #148849 (Set -Cpanic=abort in windows-msvc stack protector tests) - #149925 (`cfg_select!`: parse unused branches) - #150022 (Generate macro expansion for rust compiler crates docs) - #150024 (Support recursive delegation) - #150048 (std_detect: AArch64 Darwin: expose SME F16F16 and B16B16 features) - #150083 (tests/run-make-cargo/same-crate-name-and-macro-name: New regression test) - #150102 (Fixed ICE for EII with multiple defaults due to duplicate definition in nameres) - #150124 (unstable.rs: fix typos in comments (implementatble -> implementable)) - #150125 (Port `#[rustc_lint_opt_deny_field_access]` to attribute parser) - #150126 (Subtree sync for rustc_codegen_cranelift) Failed merges: - #150127 (Port `#[rustc_lint_untracked_query_information]` and `#[rustc_lint_diagnostics]` to using attribute parsers) r? `@ghost` `@rustbot` modify labels: rollup
2 parents ed0006a + ee56ef6 commit 567c266

File tree

64 files changed

+976
-222
lines changed

Some content is hidden

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

64 files changed

+976
-222
lines changed

compiler/rustc_ast_lowering/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ ast_lowering_coroutine_too_many_parameters =
5656
ast_lowering_default_field_in_tuple = default fields are not supported in tuple structs
5757
.label = default fields are only supported on structs
5858
59+
ast_lowering_delegation_cycle_in_signature_resolution = encountered a cycle during delegation signature resolution
60+
ast_lowering_delegation_unresolved_callee = failed to resolve delegation callee
5961
ast_lowering_does_not_support_modifiers =
6062
the `{$class_name}` register class does not support template modifiers
6163

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use hir::{BodyId, HirId};
4444
use rustc_abi::ExternAbi;
4545
use rustc_ast::*;
4646
use rustc_attr_parsing::{AttributeParser, ShouldEmit};
47+
use rustc_data_structures::fx::FxHashSet;
4748
use rustc_errors::ErrorGuaranteed;
4849
use rustc_hir::Target;
4950
use rustc_hir::attrs::{AttributeKind, InlineAttr};
@@ -55,6 +56,7 @@ use rustc_span::{DUMMY_SP, Ident, Span, Symbol};
5556
use {rustc_ast as ast, rustc_hir as hir};
5657

5758
use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode};
59+
use crate::errors::{CycleInDelegationSignatureResolution, UnresolvedDelegationCallee};
5860
use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt};
5961

6062
pub(crate) struct DelegationResults<'hir> {
@@ -119,10 +121,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
119121
&mut self,
120122
delegation: &Delegation,
121123
item_id: NodeId,
122-
is_in_trait_impl: bool,
123124
) -> DelegationResults<'hir> {
124125
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
125-
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
126+
127+
let sig_id = self.get_delegation_sig_id(
128+
self.resolver.delegation_sig_resolution_nodes[&self.local_def_id(item_id)],
129+
span,
130+
);
131+
126132
match sig_id {
127133
Ok(sig_id) => {
128134
self.add_attributes_if_needed(span, sig_id);
@@ -238,24 +244,48 @@ impl<'hir> LoweringContext<'_, 'hir> {
238244

239245
fn get_delegation_sig_id(
240246
&self,
241-
item_id: NodeId,
242-
path_id: NodeId,
247+
mut node_id: NodeId,
243248
span: Span,
244-
is_in_trait_impl: bool,
245249
) -> Result<DefId, ErrorGuaranteed> {
246-
let sig_id = if is_in_trait_impl { item_id } else { path_id };
247-
self.get_resolution_id(sig_id, span)
250+
let mut visited: FxHashSet<NodeId> = Default::default();
251+
252+
loop {
253+
visited.insert(node_id);
254+
255+
let Some(def_id) = self.get_resolution_id(node_id) else {
256+
return Err(self.tcx.dcx().span_delayed_bug(
257+
span,
258+
format!(
259+
"LoweringContext: couldn't resolve node {:?} in delegation item",
260+
node_id
261+
),
262+
));
263+
};
264+
265+
// If def_id is in local crate and it corresponds to another delegation
266+
// it means that we refer to another delegation as a callee, so in order to obtain
267+
// a signature DefId we obtain NodeId of the callee delegation and try to get signature from it.
268+
if let Some(local_id) = def_id.as_local()
269+
&& let Some(next_node_id) =
270+
self.resolver.delegation_sig_resolution_nodes.get(&local_id)
271+
{
272+
node_id = *next_node_id;
273+
if visited.contains(&node_id) {
274+
// We encountered a cycle in the resolution, or delegation callee refers to non-existent
275+
// entity, in this case emit an error.
276+
return Err(match visited.len() {
277+
1 => self.dcx().emit_err(UnresolvedDelegationCallee { span }),
278+
_ => self.dcx().emit_err(CycleInDelegationSignatureResolution { span }),
279+
});
280+
}
281+
} else {
282+
return Ok(def_id);
283+
}
284+
}
248285
}
249286

250-
fn get_resolution_id(&self, node_id: NodeId, span: Span) -> Result<DefId, ErrorGuaranteed> {
251-
let def_id =
252-
self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id());
253-
def_id.ok_or_else(|| {
254-
self.tcx.dcx().span_delayed_bug(
255-
span,
256-
format!("LoweringContext: couldn't resolve node {:?} in delegation item", node_id),
257-
)
258-
})
287+
fn get_resolution_id(&self, node_id: NodeId) -> Option<DefId> {
288+
self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id())
259289
}
260290

261291
fn lower_delegation_generics(&mut self, span: Span) -> &'hir hir::Generics<'hir> {
@@ -271,8 +301,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
271301
// Function parameter count, including C variadic `...` if present.
272302
fn param_count(&self, sig_id: DefId) -> (usize, bool /*c_variadic*/) {
273303
if let Some(local_sig_id) = sig_id.as_local() {
274-
// Map may be filled incorrectly due to recursive delegation.
275-
// Error will be emitted later during HIR ty lowering.
276304
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
277305
Some(sig) => (sig.param_count, sig.c_variadic),
278306
None => (0, false),
@@ -489,8 +517,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
489517
delegation.path.segments.iter().rev().skip(1).any(|segment| segment.args.is_some());
490518

491519
let call = if self
492-
.get_resolution_id(delegation.id, span)
493-
.and_then(|def_id| Ok(self.is_method(def_id, span)))
520+
.get_resolution_id(delegation.id)
521+
.map(|def_id| self.is_method(def_id, span))
494522
.unwrap_or_default()
495523
&& delegation.qself.is_none()
496524
&& !has_generic_args

compiler/rustc_ast_lowering/src/errors.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,3 +475,17 @@ pub(crate) struct UnionWithDefault {
475475
#[primary_span]
476476
pub span: Span,
477477
}
478+
479+
#[derive(Diagnostic)]
480+
#[diag(ast_lowering_delegation_unresolved_callee)]
481+
pub(crate) struct UnresolvedDelegationCallee {
482+
#[primary_span]
483+
pub span: Span,
484+
}
485+
486+
#[derive(Diagnostic)]
487+
#[diag(ast_lowering_delegation_cycle_in_signature_resolution)]
488+
pub(crate) struct CycleInDelegationSignatureResolution {
489+
#[primary_span]
490+
pub span: Span,
491+
}

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
541541
hir::ItemKind::Macro(ident, macro_def, macro_kinds)
542542
}
543543
ItemKind::Delegation(box delegation) => {
544-
let delegation_results = self.lower_delegation(delegation, id, false);
544+
let delegation_results = self.lower_delegation(delegation, id);
545545
hir::ItemKind::Fn {
546546
sig: delegation_results.sig,
547547
ident: delegation_results.ident,
@@ -1026,7 +1026,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10261026
(*ident, generics, kind, ty.is_some())
10271027
}
10281028
AssocItemKind::Delegation(box delegation) => {
1029-
let delegation_results = self.lower_delegation(delegation, i.id, false);
1029+
let delegation_results = self.lower_delegation(delegation, i.id);
10301030
let item_kind = hir::TraitItemKind::Fn(
10311031
delegation_results.sig,
10321032
hir::TraitFn::Provided(delegation_results.body_id),
@@ -1196,7 +1196,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11961196
)
11971197
}
11981198
AssocItemKind::Delegation(box delegation) => {
1199-
let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
1199+
let delegation_results = self.lower_delegation(delegation, i.id);
12001200
(
12011201
delegation.ident,
12021202
(

compiler/rustc_attr_parsing/src/attributes/cfg_select.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,33 @@ pub struct CfgSelectBranches {
2828
pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>,
2929
}
3030

31+
impl CfgSelectBranches {
32+
/// Removes the top-most branch for which `predicate` returns `true`,
33+
/// or the wildcard if none of the reachable branches satisfied the predicate.
34+
pub fn pop_first_match<F>(&mut self, predicate: F) -> Option<(TokenStream, Span)>
35+
where
36+
F: Fn(&CfgEntry) -> bool,
37+
{
38+
for (index, (cfg, _, _)) in self.reachable.iter().enumerate() {
39+
if predicate(cfg) {
40+
let matched = self.reachable.remove(index);
41+
return Some((matched.1, matched.2));
42+
}
43+
}
44+
45+
self.wildcard.take().map(|(_, tts, span)| (tts, span))
46+
}
47+
48+
/// Consume this value and iterate over all the `TokenStream`s that it stores.
49+
pub fn into_iter_tts(self) -> impl Iterator<Item = (TokenStream, Span)> {
50+
let it1 = self.reachable.into_iter().map(|(_, tts, span)| (tts, span));
51+
let it2 = self.wildcard.into_iter().map(|(_, tts, span)| (tts, span));
52+
let it3 = self.unreachable.into_iter().map(|(_, tts, span)| (tts, span));
53+
54+
it1.chain(it2).chain(it3)
55+
}
56+
}
57+
3158
pub fn parse_cfg_select(
3259
p: &mut Parser<'_>,
3360
sess: &Session,

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,35 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLegacyConstGenericsParser {
117117
}
118118
}
119119

120+
pub(crate) struct RustcLintOptDenyFieldAccessParser;
121+
122+
impl<S: Stage> SingleAttributeParser<S> for RustcLintOptDenyFieldAccessParser {
123+
const PATH: &[Symbol] = &[sym::rustc_lint_opt_deny_field_access];
124+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
125+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
126+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]);
127+
const TEMPLATE: AttributeTemplate = template!(Word);
128+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
129+
let Some(arg) = args.list().and_then(MetaItemListParser::single) else {
130+
cx.expected_single_argument(cx.attr_span);
131+
return None;
132+
};
133+
134+
let MetaItemOrLitParser::Lit(MetaItemLit { kind: LitKind::Str(lint_message, _), .. }) = arg
135+
else {
136+
cx.expected_string_literal(arg.span(), arg.lit());
137+
return None;
138+
};
139+
140+
Some(AttributeKind::RustcLintOptDenyFieldAccess { lint_message: *lint_message })
141+
}
142+
}
143+
120144
pub(crate) struct RustcLintOptTyParser;
121145

122146
impl<S: Stage> NoArgsAttributeParser<S> for RustcLintOptTyParser {
123147
const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty];
124-
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
148+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
125149
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
126150
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy;
127151
}
@@ -130,7 +154,7 @@ pub(crate) struct RustcLintQueryInstabilityParser;
130154

131155
impl<S: Stage> NoArgsAttributeParser<S> for RustcLintQueryInstabilityParser {
132156
const PATH: &[Symbol] = &[sym::rustc_lint_query_instability];
133-
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
157+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
134158
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
135159
Allow(Target::Fn),
136160
Allow(Target::Method(MethodKind::Inherent)),

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ use crate::attributes::prototype::CustomMirParser;
6161
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
6262
use crate::attributes::rustc_internal::{
6363
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser,
64-
RustcLegacyConstGenericsParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser,
65-
RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser,
66-
RustcObjectLifetimeDefaultParser, RustcScalableVectorParser,
64+
RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser,
65+
RustcLintQueryInstabilityParser, RustcMainParser, RustcNeverReturnsNullPointerParser,
66+
RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser,
6767
RustcSimdMonomorphizeLaneLimitParser,
6868
};
6969
use crate::attributes::semantics::MayDangleParser;
@@ -213,6 +213,7 @@ attribute_parsers!(
213213
Single<RustcLayoutScalarValidRangeEndParser>,
214214
Single<RustcLayoutScalarValidRangeStartParser>,
215215
Single<RustcLegacyConstGenericsParser>,
216+
Single<RustcLintOptDenyFieldAccessParser>,
216217
Single<RustcObjectLifetimeDefaultParser>,
217218
Single<RustcScalableVectorParser>,
218219
Single<RustcSimdMonomorphizeLaneLimitParser>,

compiler/rustc_builtin_macros/src/cfg_select.rs

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,65 @@
11
use rustc_ast::tokenstream::TokenStream;
2+
use rustc_ast::{Expr, ast};
23
use rustc_attr_parsing as attr;
34
use rustc_attr_parsing::{
45
CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, parse_cfg_select,
56
};
6-
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
7+
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacResult, MacroExpanderResult};
78
use rustc_span::{Ident, Span, sym};
9+
use smallvec::SmallVec;
810

911
use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable};
1012

11-
/// Selects the first arm whose predicate evaluates to true.
12-
fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> {
13-
for (cfg, tt, arm_span) in branches.reachable {
14-
if let EvalConfigResult::True = attr::eval_config_entry(&ecx.sess, &cfg) {
15-
return Some((tt, arm_span));
16-
}
13+
/// This intermediate structure is used to emit parse errors for the branches that are not chosen.
14+
/// The `MacResult` instance below parses all branches, emitting any errors it encounters, but only
15+
/// keeps the parse result for the selected branch.
16+
struct CfgSelectResult<'cx, 'sess> {
17+
ecx: &'cx mut ExtCtxt<'sess>,
18+
site_span: Span,
19+
selected_tts: TokenStream,
20+
selected_span: Span,
21+
other_branches: CfgSelectBranches,
22+
}
23+
24+
fn tts_to_mac_result<'cx, 'sess>(
25+
ecx: &'cx mut ExtCtxt<'sess>,
26+
site_span: Span,
27+
tts: TokenStream,
28+
span: Span,
29+
) -> Box<dyn MacResult + 'cx> {
30+
match ExpandResult::from_tts(ecx, tts, site_span, span, Ident::with_dummy_span(sym::cfg_select))
31+
{
32+
ExpandResult::Ready(x) => x,
33+
_ => unreachable!("from_tts always returns Ready"),
1734
}
35+
}
36+
37+
macro_rules! forward_to_parser_any_macro {
38+
($method_name:ident, $ret_ty:ty) => {
39+
fn $method_name(self: Box<Self>) -> Option<$ret_ty> {
40+
let CfgSelectResult { ecx, site_span, selected_tts, selected_span, .. } = *self;
41+
42+
for (tts, span) in self.other_branches.into_iter_tts() {
43+
let _ = tts_to_mac_result(ecx, site_span, tts, span).$method_name();
44+
}
45+
46+
tts_to_mac_result(ecx, site_span, selected_tts, selected_span).$method_name()
47+
}
48+
};
49+
}
50+
51+
impl<'cx, 'sess> MacResult for CfgSelectResult<'cx, 'sess> {
52+
forward_to_parser_any_macro!(make_expr, Box<Expr>);
53+
forward_to_parser_any_macro!(make_stmts, SmallVec<[ast::Stmt; 1]>);
54+
forward_to_parser_any_macro!(make_items, SmallVec<[Box<ast::Item>; 1]>);
55+
56+
forward_to_parser_any_macro!(make_impl_items, SmallVec<[Box<ast::AssocItem>; 1]>);
57+
forward_to_parser_any_macro!(make_trait_impl_items, SmallVec<[Box<ast::AssocItem>; 1]>);
58+
forward_to_parser_any_macro!(make_trait_items, SmallVec<[Box<ast::AssocItem>; 1]>);
59+
forward_to_parser_any_macro!(make_foreign_items, SmallVec<[Box<ast::ForeignItem>; 1]>);
1860

19-
branches.wildcard.map(|(_, tt, span)| (tt, span))
61+
forward_to_parser_any_macro!(make_ty, Box<ast::Ty>);
62+
forward_to_parser_any_macro!(make_pat, Box<ast::Pat>);
2063
}
2164

2265
pub(super) fn expand_cfg_select<'cx>(
@@ -31,7 +74,7 @@ pub(super) fn expand_cfg_select<'cx>(
3174
Some(ecx.ecfg.features),
3275
ecx.current_expansion.lint_node_id,
3376
) {
34-
Ok(branches) => {
77+
Ok(mut branches) => {
3578
if let Some((underscore, _, _)) = branches.wildcard {
3679
// Warn for every unreachable predicate. We store the fully parsed branch for rustfmt.
3780
for (predicate, _, _) in &branches.unreachable {
@@ -44,14 +87,17 @@ pub(super) fn expand_cfg_select<'cx>(
4487
}
4588
}
4689

47-
if let Some((tts, arm_span)) = select_arm(ecx, branches) {
48-
return ExpandResult::from_tts(
90+
if let Some((selected_tts, selected_span)) = branches.pop_first_match(|cfg| {
91+
matches!(attr::eval_config_entry(&ecx.sess, cfg), EvalConfigResult::True)
92+
}) {
93+
let mac = CfgSelectResult {
4994
ecx,
50-
tts,
51-
sp,
52-
arm_span,
53-
Ident::with_dummy_span(sym::cfg_select),
54-
);
95+
selected_tts,
96+
selected_span,
97+
other_branches: branches,
98+
site_span: sp,
99+
};
100+
return ExpandResult::Ready(Box::new(mac));
55101
} else {
56102
// Emit a compiler error when none of the predicates matched.
57103
let guar = ecx.dcx().emit_err(CfgSelectNoMatches { span: sp });

0 commit comments

Comments
 (0)