Skip to content

Commit 7941e11

Browse files
committed
Auto merge of #149940 - jhpratt:rollup-7b6iyje, r=jhpratt
Rollup of 11 pull requests Successful merges: - #145278 (Update `rustc_codegen_gcc` rotate operation document) - #148825 (Add SystemTime::{MIN, MAX}) - #148837 (Use `let...else` instead of `match foo { ... _ => return };` and `if let ... else return`) - #149177 (Add proper suggestion for associated function with unknown field) - #149843 (Inherit attributes in delegation) - #149860 (Fix: Prevent macro-expanded extern crates from shadowing extern arguments) - #149874 (Weak for Arc pointer is marked as DynSend/DynSync) - #149903 (Remove unused code in `cfg_old`) - #149911 (bootstrap: Don't pass an unused `--color` to compiletest) - #149916 (Add a sanity check in case of any duplicate nodes) - #149924 (`declare_lint_pass` for `INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents dc47a69 + f90ae7f commit 7941e11

File tree

95 files changed

+1047
-845
lines changed

Some content is hidden

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

95 files changed

+1047
-845
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,11 +1533,10 @@ impl Expr {
15331533
// then type of result is trait object.
15341534
// Otherwise we don't assume the result type.
15351535
ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1536-
if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1537-
TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1538-
} else {
1536+
let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) else {
15391537
return None;
1540-
}
1538+
};
1539+
TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
15411540
}
15421541

15431542
ExprKind::Underscore => TyKind::Infer,

compiler/rustc_ast/src/attr/mod.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -447,20 +447,17 @@ impl MetaItem {
447447
thin_vec![PathSegment::path_root(span)]
448448
};
449449
loop {
450-
if let Some(&TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
450+
let Some(&TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
451451
iter.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref()
452-
{
453-
segments.push(PathSegment::from_ident(Ident::new(name, span)));
454-
} else {
452+
else {
455453
return None;
456-
}
457-
if let Some(TokenTree::Token(Token { kind: token::PathSep, .. }, _)) =
458-
iter.peek()
459-
{
460-
iter.next();
461-
} else {
454+
};
455+
segments.push(PathSegment::from_ident(Ident::new(name, span)));
456+
let Some(TokenTree::Token(Token { kind: token::PathSep, .. }, _)) = iter.peek()
457+
else {
462458
break;
463-
}
459+
};
460+
iter.next();
464461
}
465462
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
466463
Path { span, segments, tokens: None }

compiler/rustc_ast/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
// tidy-alphabetical-start
88
#![cfg_attr(bootstrap, feature(array_windows))]
9+
#![deny(clippy::manual_let_else)]
910
#![doc(test(attr(deny(warnings), allow(internal_features))))]
1011
#![feature(associated_type_defaults)]
1112
#![feature(box_patterns)]

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 133 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ use hir::def::{DefKind, PartialRes, Res};
4343
use hir::{BodyId, HirId};
4444
use rustc_abi::ExternAbi;
4545
use rustc_ast::*;
46+
use rustc_attr_parsing::{AttributeParser, ShouldEmit};
4647
use rustc_errors::ErrorGuaranteed;
48+
use rustc_hir::Target;
4749
use rustc_hir::attrs::{AttributeKind, InlineAttr};
4850
use rustc_hir::def_id::DefId;
4951
use rustc_middle::span_bug;
50-
use rustc_middle::ty::{Asyncness, ResolverAstLowering};
52+
use rustc_middle::ty::{Asyncness, DelegationFnSigAttrs, ResolverAstLowering};
5153
use rustc_span::symbol::kw;
52-
use rustc_span::{Ident, Span, Symbol};
54+
use rustc_span::{DUMMY_SP, Ident, Span, Symbol};
5355
use {rustc_ast as ast, rustc_hir as hir};
5456

5557
use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode};
@@ -62,6 +64,41 @@ pub(crate) struct DelegationResults<'hir> {
6264
pub generics: &'hir hir::Generics<'hir>,
6365
}
6466

67+
struct AttributeAdditionInfo {
68+
pub equals: fn(&hir::Attribute) -> bool,
69+
pub kind: AttributeAdditionKind,
70+
}
71+
72+
enum AttributeAdditionKind {
73+
Default { factory: fn(Span) -> hir::Attribute },
74+
Inherit { flag: DelegationFnSigAttrs, factory: fn(Span, &hir::Attribute) -> hir::Attribute },
75+
}
76+
77+
const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
78+
79+
static ATTRIBUTES_ADDITIONS: &[AttributeAdditionInfo] = &[
80+
AttributeAdditionInfo {
81+
equals: |a| matches!(a, hir::Attribute::Parsed(AttributeKind::MustUse { .. })),
82+
kind: AttributeAdditionKind::Inherit {
83+
factory: |span, original_attribute| {
84+
let reason = match original_attribute {
85+
hir::Attribute::Parsed(AttributeKind::MustUse { reason, .. }) => *reason,
86+
_ => None,
87+
};
88+
89+
hir::Attribute::Parsed(AttributeKind::MustUse { span, reason })
90+
},
91+
flag: DelegationFnSigAttrs::MUST_USE,
92+
},
93+
},
94+
AttributeAdditionInfo {
95+
equals: |a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))),
96+
kind: AttributeAdditionKind::Default {
97+
factory: |span| hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span)),
98+
},
99+
},
100+
];
101+
65102
impl<'hir> LoweringContext<'_, 'hir> {
66103
fn is_method(&self, def_id: DefId, span: Span) -> bool {
67104
match self.tcx.def_kind(def_id) {
@@ -88,7 +125,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
88125
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
89126
match sig_id {
90127
Ok(sig_id) => {
91-
self.add_inline_attribute_if_needed(span);
128+
self.add_attributes_if_needed(span, sig_id);
92129

93130
let is_method = self.is_method(sig_id, span);
94131
let (param_count, c_variadic) = self.param_count(sig_id);
@@ -103,29 +140,100 @@ impl<'hir> LoweringContext<'_, 'hir> {
103140
}
104141
}
105142

106-
fn add_inline_attribute_if_needed(&mut self, span: Span) {
107-
const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
108-
let create_inline_attr_slice =
109-
|| [hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span))];
110-
111-
let new_attributes = match self.attrs.get(&PARENT_ID) {
112-
Some(attrs) => {
113-
// Check if reuse already specifies any inline attribute, if so, do nothing
114-
if attrs
115-
.iter()
116-
.any(|a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))))
143+
fn add_attributes_if_needed(&mut self, span: Span, sig_id: DefId) {
144+
let new_attributes = self.create_new_attributes(
145+
ATTRIBUTES_ADDITIONS,
146+
span,
147+
sig_id,
148+
self.attrs.get(&PARENT_ID),
149+
);
150+
151+
if new_attributes.is_empty() {
152+
return;
153+
}
154+
155+
let new_arena_allocated_attributes = match self.attrs.get(&PARENT_ID) {
156+
Some(existing_attrs) => self.arena.alloc_from_iter(
157+
existing_attrs.iter().map(|a| a.clone()).chain(new_attributes.into_iter()),
158+
),
159+
None => self.arena.alloc_from_iter(new_attributes.into_iter()),
160+
};
161+
162+
self.attrs.insert(PARENT_ID, new_arena_allocated_attributes);
163+
}
164+
165+
fn create_new_attributes(
166+
&self,
167+
candidate_additions: &[AttributeAdditionInfo],
168+
span: Span,
169+
sig_id: DefId,
170+
existing_attrs: Option<&&[hir::Attribute]>,
171+
) -> Vec<hir::Attribute> {
172+
let local_original_attributes = self.parse_local_original_attributes(sig_id);
173+
174+
candidate_additions
175+
.iter()
176+
.filter_map(|addition_info| {
177+
if let Some(existing_attrs) = existing_attrs
178+
&& existing_attrs
179+
.iter()
180+
.any(|existing_attr| (addition_info.equals)(existing_attr))
117181
{
118-
return;
182+
return None;
119183
}
120184

121-
self.arena.alloc_from_iter(
122-
attrs.into_iter().map(|a| a.clone()).chain(create_inline_attr_slice()),
123-
)
124-
}
125-
None => self.arena.alloc_from_iter(create_inline_attr_slice()),
126-
};
185+
match addition_info.kind {
186+
AttributeAdditionKind::Default { factory } => Some(factory(span)),
187+
AttributeAdditionKind::Inherit { flag, factory } => {
188+
let original_attribute = match sig_id.as_local() {
189+
Some(local_id) => self
190+
.resolver
191+
.delegation_fn_sigs
192+
.get(&local_id)
193+
.is_some_and(|sig| sig.attrs_flags.contains(flag))
194+
.then(|| {
195+
local_original_attributes
196+
.as_ref()
197+
.map(|attrs| {
198+
attrs
199+
.iter()
200+
.find(|base_attr| (addition_info.equals)(base_attr))
201+
})
202+
.flatten()
203+
})
204+
.flatten(),
205+
None => self
206+
.tcx
207+
.get_all_attrs(sig_id)
208+
.iter()
209+
.find(|base_attr| (addition_info.equals)(base_attr)),
210+
};
127211

128-
self.attrs.insert(PARENT_ID, new_attributes);
212+
original_attribute.map(|a| factory(span, a))
213+
}
214+
}
215+
})
216+
.collect::<Vec<_>>()
217+
}
218+
219+
fn parse_local_original_attributes(&self, sig_id: DefId) -> Option<Vec<hir::Attribute>> {
220+
if let Some(local_id) = sig_id.as_local()
221+
&& let Some(info) = self.resolver.delegation_fn_sigs.get(&local_id)
222+
&& !info.to_inherit_attrs.is_empty()
223+
{
224+
Some(AttributeParser::parse_limited_all(
225+
self.tcx.sess,
226+
info.to_inherit_attrs.as_slice(),
227+
None,
228+
Target::Fn,
229+
DUMMY_SP,
230+
DUMMY_NODE_ID,
231+
Some(self.tcx.features()),
232+
ShouldEmit::Nothing,
233+
))
234+
} else {
235+
None
236+
}
129237
}
130238

131239
fn get_delegation_sig_id(
@@ -220,7 +328,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
220328
// We are not forwarding the attributes, as the delegation fn sigs are collected on the ast,
221329
// and here we need the hir attributes.
222330
let default_safety =
223-
if sig.target_feature || self.tcx.def_kind(parent) == DefKind::ForeignMod {
331+
if sig.attrs_flags.contains(DelegationFnSigAttrs::TARGET_FEATURE)
332+
|| self.tcx.def_kind(parent) == DefKind::ForeignMod
333+
{
224334
hir::Safety::Unsafe
225335
} else {
226336
hir::Safety::Safe

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ attr_parsing_bundle_needs_static =
66
77
attr_parsing_cfg_attr_bad_delim = wrong `cfg_attr` delimiters
88
9-
attr_parsing_cfg_predicate_identifier =
10-
`cfg` predicate key must be an identifier
11-
129
attr_parsing_deprecated_item_suggestion =
1310
suggestions on deprecated items are unstable
1411
.help = add `#![feature(deprecated_suggestion)]` to the crate root
@@ -41,9 +38,6 @@ attr_parsing_empty_link_name =
4138
link name must not be empty
4239
.label = empty link name
4340
44-
attr_parsing_expected_one_cfg_pattern =
45-
expected 1 cfg-pattern
46-
4741
attr_parsing_expected_single_version_literal =
4842
expected single version literal
4943
@@ -241,12 +235,6 @@ attr_parsing_unstable_cfg_target_compact =
241235
attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable
242236
.help = If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]`
243237
244-
attr_parsing_unsupported_literal_cfg_boolean =
245-
literal in `cfg` predicate value must be a boolean
246-
attr_parsing_unsupported_literal_cfg_string =
247-
literal in `cfg` predicate value must be a string
248-
attr_parsing_unsupported_literal_generic =
249-
unsupported literal
250238
attr_parsing_unsupported_literal_suggestion =
251239
consider removing the prefix
252240

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use rustc_ast::token::Delimiter;
44
use rustc_ast::tokenstream::DelimSpan;
55
use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, ast, token};
66
use rustc_errors::{Applicability, PResult};
7-
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate, Features, template};
7+
use rustc_feature::{
8+
AttrSuggestionStyle, AttributeTemplate, Features, GatedCfg, find_gated_cfg, template,
9+
};
810
use rustc_hir::attrs::CfgEntry;
911
use rustc_hir::lints::AttributeLintKind;
1012
use rustc_hir::{AttrPath, RustcVersion};
@@ -23,7 +25,7 @@ use crate::session_diagnostics::{
2325
AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg,
2426
ParsedDescription,
2527
};
26-
use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics, try_gate_cfg};
28+
use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics};
2729

2830
pub const CFG_TEMPLATE: AttributeTemplate = template!(
2931
List: &["predicate"],
@@ -410,3 +412,19 @@ fn parse_cfg_attr_internal<'a>(
410412

411413
Ok((cfg_predicate, expanded_attrs))
412414
}
415+
416+
fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) {
417+
let gate = find_gated_cfg(|sym| sym == name);
418+
if let (Some(feats), Some(gated_cfg)) = (features, gate) {
419+
gate_cfg(gated_cfg, span, sess, feats);
420+
}
421+
}
422+
423+
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
424+
fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) {
425+
let (cfg, feature, has_feature) = gated_cfg;
426+
if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
427+
let explain = format!("`cfg({cfg})` is experimental and subject to change");
428+
feature_err(sess, *feature, cfg_span, explain).emit();
429+
}
430+
}

0 commit comments

Comments
 (0)