Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ea34650

Browse files
committedJun 21, 2025·
Auto merge of #142826 - jdonszelmann:rollup-1wxomvb, r=jdonszelmann
Rollup of 3 pull requests Successful merges: - #142539 (Port `#[may_dangle]` to the new attribute system) - #142690 (expand: Remove some unnecessary generic parameters) - #142698 (Improve diagnostics for `concat_bytes!` with C string literals) Failed merges: - #142600 (Port `#[rustc_pub_transparent]` to the new attribute system) - #142776 (All HIR attributes are outer) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6d0c9e2 + c693bc2 commit ea34650

File tree

12 files changed

+215
-88
lines changed

12 files changed

+215
-88
lines changed
 

‎compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,13 @@ pub enum AttributeKind {
233233

234234
/// Represents `#[rustc_macro_transparency]`.
235235
MacroTransparency(Transparency),
236+
237+
/// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html).
238+
MayDangle(Span),
239+
236240
/// Represents `#[optimize(size|speed)]`
237241
Optimize(OptimizeAttr, Span),
242+
238243
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
239244
Repr(ThinVec<(ReprAttr, Span)>),
240245

‎compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub(crate) mod deprecation;
3434
pub(crate) mod inline;
3535
pub(crate) mod lint_helpers;
3636
pub(crate) mod repr;
37+
pub(crate) mod semantics;
3738
pub(crate) mod stability;
3839
pub(crate) mod transparency;
3940
pub(crate) mod util;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use rustc_attr_data_structures::AttributeKind;
2+
use rustc_feature::{AttributeTemplate, template};
3+
use rustc_span::{Symbol, sym};
4+
5+
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
6+
use crate::context::{AcceptContext, Stage};
7+
use crate::parser::ArgParser;
8+
9+
pub(crate) struct MayDangleParser;
10+
impl<S: Stage> SingleAttributeParser<S> for MayDangleParser {
11+
const PATH: &[Symbol] = &[sym::may_dangle];
12+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
13+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
14+
const TEMPLATE: AttributeTemplate = template!(Word);
15+
16+
fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
17+
Some(AttributeKind::MayDangle(cx.attr_span))
18+
}
19+
}

‎compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::attributes::deprecation::DeprecationParser;
2121
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
2222
use crate::attributes::lint_helpers::AsPtrParser;
2323
use crate::attributes::repr::{AlignParser, ReprParser};
24+
use crate::attributes::semantics::MayDangleParser;
2425
use crate::attributes::stability::{
2526
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
2627
};
@@ -110,6 +111,7 @@ attribute_parsers!(
110111
Single<ConstStabilityIndirectParser>,
111112
Single<DeprecationParser>,
112113
Single<InlineParser>,
114+
Single<MayDangleParser>,
113115
Single<OptimizeParser>,
114116
Single<RustcForceInlineParser>,
115117
Single<TransparencyParser>,

‎compiler/rustc_builtin_macros/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ builtin_macros_concat_bytes_bad_repeat = repeat count is not a positive number
104104
builtin_macros_concat_bytes_invalid = cannot concatenate {$lit_kind} literals
105105
.byte_char = try using a byte character
106106
.byte_str = try using a byte string
107+
.c_str = try using a null-terminated byte string
108+
.c_str_note = concatenating C strings is ambiguous about including the '\0'
107109
.number_array = try wrapping the number in an array
108110
109111
builtin_macros_concat_bytes_missing_literal = expected a byte literal

‎compiler/rustc_builtin_macros/src/concat_bytes.rs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_ast::ptr::P;
22
use rustc_ast::tokenstream::TokenStream;
3-
use rustc_ast::{ExprKind, LitIntType, LitKind, UintTy, token};
3+
use rustc_ast::{ExprKind, LitIntType, LitKind, StrStyle, UintTy, token};
44
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
55
use rustc_session::errors::report_lit_error;
66
use rustc_span::{ErrorGuaranteed, Span};
@@ -21,15 +21,32 @@ fn invalid_type_err(
2121
let snippet = cx.sess.source_map().span_to_snippet(span).ok();
2222
let dcx = cx.dcx();
2323
match LitKind::from_token_lit(token_lit) {
24-
Ok(LitKind::CStr(_, _)) => {
24+
Ok(LitKind::CStr(_, style)) => {
2525
// Avoid ambiguity in handling of terminal `NUL` by refusing to
2626
// concatenate C string literals as bytes.
27-
dcx.emit_err(errors::ConcatCStrLit { span })
27+
let sugg = if let Some(mut as_bstr) = snippet
28+
&& style == StrStyle::Cooked
29+
&& as_bstr.starts_with('c')
30+
&& as_bstr.ends_with('"')
31+
{
32+
// Suggest`c"foo"` -> `b"foo\0"` if we can
33+
as_bstr.replace_range(0..1, "b");
34+
as_bstr.pop();
35+
as_bstr.push_str(r#"\0""#);
36+
Some(ConcatBytesInvalidSuggestion::CStrLit { span, as_bstr })
37+
} else {
38+
// No suggestion for a missing snippet, raw strings, or if for some reason we have
39+
// a span that doesn't match `c"foo"` (possible if a proc macro assigns a span
40+
// that doesn't actually point to a C string).
41+
None
42+
};
43+
// We can only provide a suggestion if we have a snip and it is not a raw string
44+
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "C string", sugg, cs_note: Some(()) })
2845
}
2946
Ok(LitKind::Char(_)) => {
3047
let sugg =
3148
snippet.map(|snippet| ConcatBytesInvalidSuggestion::CharLit { span, snippet });
32-
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg })
49+
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg, cs_note: None })
3350
}
3451
Ok(LitKind::Str(_, _)) => {
3552
// suggestion would be invalid if we are nested
@@ -38,18 +55,21 @@ fn invalid_type_err(
3855
} else {
3956
None
4057
};
41-
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg })
58+
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg, cs_note: None })
4259
}
4360
Ok(LitKind::Float(_, _)) => {
44-
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None })
45-
}
46-
Ok(LitKind::Bool(_)) => {
47-
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None })
61+
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None, cs_note: None })
4862
}
63+
Ok(LitKind::Bool(_)) => dcx.emit_err(ConcatBytesInvalid {
64+
span,
65+
lit_kind: "boolean",
66+
sugg: None,
67+
cs_note: None,
68+
}),
4969
Ok(LitKind::Int(_, _)) if !is_nested => {
5070
let sugg =
5171
snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span, snippet });
52-
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg })
72+
dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg, cs_note: None })
5373
}
5474
Ok(LitKind::Int(val, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::U8))) => {
5575
assert!(val.get() > u8::MAX.into()); // must be an error

‎compiler/rustc_builtin_macros/src/errors.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ pub(crate) struct ConcatBytesInvalid {
215215
pub(crate) lit_kind: &'static str,
216216
#[subdiagnostic]
217217
pub(crate) sugg: Option<ConcatBytesInvalidSuggestion>,
218+
#[note(builtin_macros_c_str_note)]
219+
pub(crate) cs_note: Option<()>,
218220
}
219221

220222
#[derive(Subdiagnostic)]
@@ -239,6 +241,13 @@ pub(crate) enum ConcatBytesInvalidSuggestion {
239241
span: Span,
240242
snippet: String,
241243
},
244+
#[note(builtin_macros_c_str_note)]
245+
#[suggestion(builtin_macros_c_str, code = "{as_bstr}", applicability = "machine-applicable")]
246+
CStrLit {
247+
#[primary_span]
248+
span: Span,
249+
as_bstr: String,
250+
},
242251
#[suggestion(
243252
builtin_macros_number_array,
244253
code = "[{snippet}]",

‎compiler/rustc_expand/src/expand.rs

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ macro_rules! ast_fragments {
8686
}
8787
}
8888

89-
fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> {
89+
fn make_from(self, result: Box<dyn MacResult + '_>) -> Option<AstFragment> {
9090
match self {
9191
AstFragmentKind::OptExpr =>
9292
result.make_expr().map(Some).map(AstFragment::OptExpr),
@@ -136,7 +136,7 @@ macro_rules! ast_fragments {
136136
T::fragment_to_output(self)
137137
}
138138

139-
pub(crate) fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) {
139+
pub(crate) fn mut_visit_with(&mut self, vis: &mut impl MutVisitor) {
140140
match self {
141141
AstFragment::OptExpr(opt_expr) => {
142142
if let Some(expr) = opt_expr.take() {
@@ -316,9 +316,9 @@ impl AstFragmentKind {
316316
}
317317
}
318318

319-
pub(crate) fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>(
319+
pub(crate) fn expect_from_annotatables(
320320
self,
321-
items: I,
321+
items: impl IntoIterator<Item = Annotatable>,
322322
) -> AstFragment {
323323
let mut items = items.into_iter();
324324
match self {
@@ -1218,10 +1218,10 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
12181218
fn descr() -> &'static str {
12191219
unreachable!()
12201220
}
1221-
fn walk_flat_map<V: MutVisitor>(self, _visitor: &mut V) -> Self::OutputTy {
1221+
fn walk_flat_map(self, _collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
12221222
unreachable!()
12231223
}
1224-
fn walk<V: MutVisitor>(&mut self, _visitor: &mut V) {
1224+
fn walk(&mut self, _collector: &mut InvocationCollector<'_, '_>) {
12251225
unreachable!()
12261226
}
12271227
fn is_mac_call(&self) -> bool {
@@ -1276,8 +1276,8 @@ impl InvocationCollectorNode for P<ast::Item> {
12761276
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
12771277
fragment.make_items()
12781278
}
1279-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1280-
walk_flat_map_item(visitor, self)
1279+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1280+
walk_flat_map_item(collector, self)
12811281
}
12821282
fn is_mac_call(&self) -> bool {
12831283
matches!(self.kind, ItemKind::MacCall(..))
@@ -1431,8 +1431,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag>
14311431
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
14321432
fragment.make_trait_items()
14331433
}
1434-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1435-
walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Trait)
1434+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1435+
walk_flat_map_assoc_item(collector, self.wrapped, AssocCtxt::Trait)
14361436
}
14371437
fn is_mac_call(&self) -> bool {
14381438
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@@ -1472,8 +1472,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
14721472
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
14731473
fragment.make_impl_items()
14741474
}
1475-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1476-
walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: false })
1475+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1476+
walk_flat_map_assoc_item(collector, self.wrapped, AssocCtxt::Impl { of_trait: false })
14771477
}
14781478
fn is_mac_call(&self) -> bool {
14791479
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@@ -1513,8 +1513,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitImplItem
15131513
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
15141514
fragment.make_trait_impl_items()
15151515
}
1516-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1517-
walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: true })
1516+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1517+
walk_flat_map_assoc_item(collector, self.wrapped, AssocCtxt::Impl { of_trait: true })
15181518
}
15191519
fn is_mac_call(&self) -> bool {
15201520
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@@ -1551,8 +1551,8 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
15511551
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
15521552
fragment.make_foreign_items()
15531553
}
1554-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1555-
walk_flat_map_foreign_item(visitor, self)
1554+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1555+
walk_flat_map_foreign_item(collector, self)
15561556
}
15571557
fn is_mac_call(&self) -> bool {
15581558
matches!(self.kind, ForeignItemKind::MacCall(..))
@@ -1573,8 +1573,8 @@ impl InvocationCollectorNode for ast::Variant {
15731573
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
15741574
fragment.make_variants()
15751575
}
1576-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1577-
walk_flat_map_variant(visitor, self)
1576+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1577+
walk_flat_map_variant(collector, self)
15781578
}
15791579
}
15801580

@@ -1586,8 +1586,8 @@ impl InvocationCollectorNode for ast::WherePredicate {
15861586
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
15871587
fragment.make_where_predicates()
15881588
}
1589-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1590-
walk_flat_map_where_predicate(visitor, self)
1589+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1590+
walk_flat_map_where_predicate(collector, self)
15911591
}
15921592
}
15931593

@@ -1599,8 +1599,8 @@ impl InvocationCollectorNode for ast::FieldDef {
15991599
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
16001600
fragment.make_field_defs()
16011601
}
1602-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1603-
walk_flat_map_field_def(visitor, self)
1602+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1603+
walk_flat_map_field_def(collector, self)
16041604
}
16051605
}
16061606

@@ -1612,8 +1612,8 @@ impl InvocationCollectorNode for ast::PatField {
16121612
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
16131613
fragment.make_pat_fields()
16141614
}
1615-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1616-
walk_flat_map_pat_field(visitor, self)
1615+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1616+
walk_flat_map_pat_field(collector, self)
16171617
}
16181618
}
16191619

@@ -1625,8 +1625,8 @@ impl InvocationCollectorNode for ast::ExprField {
16251625
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
16261626
fragment.make_expr_fields()
16271627
}
1628-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1629-
walk_flat_map_expr_field(visitor, self)
1628+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1629+
walk_flat_map_expr_field(collector, self)
16301630
}
16311631
}
16321632

@@ -1638,8 +1638,8 @@ impl InvocationCollectorNode for ast::Param {
16381638
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
16391639
fragment.make_params()
16401640
}
1641-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1642-
walk_flat_map_param(visitor, self)
1641+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1642+
walk_flat_map_param(collector, self)
16431643
}
16441644
}
16451645

@@ -1651,8 +1651,8 @@ impl InvocationCollectorNode for ast::GenericParam {
16511651
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
16521652
fragment.make_generic_params()
16531653
}
1654-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1655-
walk_flat_map_generic_param(visitor, self)
1654+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1655+
walk_flat_map_generic_param(collector, self)
16561656
}
16571657
}
16581658

@@ -1664,8 +1664,8 @@ impl InvocationCollectorNode for ast::Arm {
16641664
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
16651665
fragment.make_arms()
16661666
}
1667-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1668-
walk_flat_map_arm(visitor, self)
1667+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1668+
walk_flat_map_arm(collector, self)
16691669
}
16701670
}
16711671

@@ -1677,8 +1677,8 @@ impl InvocationCollectorNode for ast::Stmt {
16771677
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
16781678
fragment.make_stmts()
16791679
}
1680-
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1681-
walk_flat_map_stmt(visitor, self)
1680+
fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1681+
walk_flat_map_stmt(collector, self)
16821682
}
16831683
fn is_mac_call(&self) -> bool {
16841684
match &self.kind {
@@ -1751,8 +1751,8 @@ impl InvocationCollectorNode for ast::Crate {
17511751
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
17521752
fragment.make_crate()
17531753
}
1754-
fn walk<V: MutVisitor>(&mut self, visitor: &mut V) {
1755-
walk_crate(visitor, self)
1754+
fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
1755+
walk_crate(collector, self)
17561756
}
17571757
fn expand_cfg_false(
17581758
&mut self,
@@ -1777,8 +1777,8 @@ impl InvocationCollectorNode for ast::Ty {
17771777
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
17781778
fragment.make_ty()
17791779
}
1780-
fn walk<V: MutVisitor>(&mut self, visitor: &mut V) {
1781-
walk_ty(visitor, self)
1780+
fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
1781+
walk_ty(collector, self)
17821782
}
17831783
fn is_mac_call(&self) -> bool {
17841784
matches!(self.kind, ast::TyKind::MacCall(..))
@@ -1800,8 +1800,8 @@ impl InvocationCollectorNode for ast::Pat {
18001800
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
18011801
fragment.make_pat()
18021802
}
1803-
fn walk<V: MutVisitor>(&mut self, visitor: &mut V) {
1804-
walk_pat(visitor, self)
1803+
fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
1804+
walk_pat(collector, self)
18051805
}
18061806
fn is_mac_call(&self) -> bool {
18071807
matches!(self.kind, PatKind::MacCall(..))
@@ -1826,8 +1826,8 @@ impl InvocationCollectorNode for ast::Expr {
18261826
fn descr() -> &'static str {
18271827
"an expression"
18281828
}
1829-
fn walk<V: MutVisitor>(&mut self, visitor: &mut V) {
1830-
walk_expr(visitor, self)
1829+
fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
1830+
walk_expr(collector, self)
18311831
}
18321832
fn is_mac_call(&self) -> bool {
18331833
matches!(self.kind, ExprKind::MacCall(..))
@@ -1850,8 +1850,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> {
18501850
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
18511851
fragment.make_opt_expr()
18521852
}
1853-
fn walk_flat_map<V: MutVisitor>(mut self, visitor: &mut V) -> Self::OutputTy {
1854-
walk_expr(visitor, &mut self.wrapped);
1853+
fn walk_flat_map(mut self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1854+
walk_expr(collector, &mut self.wrapped);
18551855
Some(self.wrapped)
18561856
}
18571857
fn is_mac_call(&self) -> bool {
@@ -1885,8 +1885,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, MethodReceiverTag>
18851885
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
18861886
AstNodeWrapper::new(fragment.make_method_receiver_expr(), MethodReceiverTag)
18871887
}
1888-
fn walk<V: MutVisitor>(&mut self, visitor: &mut V) {
1889-
walk_expr(visitor, &mut self.wrapped)
1888+
fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
1889+
walk_expr(collector, &mut self.wrapped)
18901890
}
18911891
fn is_mac_call(&self) -> bool {
18921892
matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))

‎compiler/rustc_hir/src/hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,7 @@ impl AttributeExt for Attribute {
13021302
// FIXME: should not be needed anymore when all attrs are parsed
13031303
Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
13041304
Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
1305+
Attribute::Parsed(AttributeKind::MayDangle(span)) => *span,
13051306
a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
13061307
}
13071308
}

‎compiler/rustc_passes/src/check_attr.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
163163
Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
164164
self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
165165
}
166+
&Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
167+
self.check_may_dangle(hir_id, attr_span)
168+
}
166169
Attribute::Unparsed(_) => {
167170
match attr.path().as_slice() {
168171
[sym::diagnostic, sym::do_not_recommend, ..] => {
@@ -236,7 +239,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
236239
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
237240
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
238241
[sym::must_use, ..] => self.check_must_use(hir_id, attr, target),
239-
[sym::may_dangle, ..] => self.check_may_dangle(hir_id, attr),
240242
[sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target),
241243
[sym::rustc_allow_incoherent_impl, ..] => {
242244
self.check_allow_incoherent_impl(attr, span, target)
@@ -1619,7 +1621,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16191621
}
16201622

16211623
/// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
1622-
fn check_may_dangle(&self, hir_id: HirId, attr: &Attribute) {
1624+
fn check_may_dangle(&self, hir_id: HirId, attr_span: Span) {
16231625
if let hir::Node::GenericParam(param) = self.tcx.hir_node(hir_id)
16241626
&& matches!(
16251627
param.kind,
@@ -1636,7 +1638,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16361638
return;
16371639
}
16381640

1639-
self.dcx().emit_err(errors::InvalidMayDangle { attr_span: attr.span() });
1641+
self.dcx().emit_err(errors::InvalidMayDangle { attr_span });
16401642
}
16411643

16421644
/// Checks if `#[cold]` is applied to a non-function.

‎tests/ui/macros/concat-bytes-error.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,44 @@
1+
//@ edition: 2021
2+
// 2021 edition for C string literals
3+
14
#![feature(concat_bytes)]
25

36
fn main() {
7+
// Identifiers
48
concat_bytes!(pie); //~ ERROR expected a byte literal
59
concat_bytes!(pie, pie); //~ ERROR expected a byte literal
10+
11+
// String literals
612
concat_bytes!("tnrsi", "tnri"); //~ ERROR cannot concatenate string literals
13+
//~^ SUGGESTION b"tnrsi"
14+
concat_bytes!(r"tnrsi", r"tnri"); //~ ERROR cannot concatenate string literals
15+
//~^ SUGGESTION br"tnrsi"
16+
concat_bytes!(r#"tnrsi"#, r###"tnri"###); //~ ERROR cannot concatenate string literals
17+
//~^ SUGGESTION br#"tnrsi"#
18+
concat_bytes!(c"tnrsi", c"tnri"); //~ ERROR cannot concatenate C string literals
19+
//~^ SUGGESTION b"tnrsi\0"
20+
concat_bytes!(cr"tnrsi", cr"tnri"); //~ ERROR cannot concatenate C string literals
21+
concat_bytes!(cr#"tnrsi"#, cr###"tnri"###); //~ ERROR cannot concatenate C string literals
22+
23+
// Other literals
724
concat_bytes!(2.8); //~ ERROR cannot concatenate float literals
825
concat_bytes!(300); //~ ERROR cannot concatenate numeric literals
26+
//~^ SUGGESTION [300]
927
concat_bytes!('a'); //~ ERROR cannot concatenate character literals
28+
//~^ SUGGESTION b'a'
1029
concat_bytes!(true, false); //~ ERROR cannot concatenate boolean literals
1130
concat_bytes!(42, b"va", b'l'); //~ ERROR cannot concatenate numeric literals
31+
//~^ SUGGESTION [42]
1232
concat_bytes!(42, b"va", b'l', [1, 2]); //~ ERROR cannot concatenate numeric literals
33+
//~^ SUGGESTION [42]
34+
35+
// Nested items
1336
concat_bytes!([
1437
"hi", //~ ERROR cannot concatenate string literals
1538
]);
1639
concat_bytes!([
1740
'a', //~ ERROR cannot concatenate character literals
41+
//~^ SUGGESTION b'a'
1842
]);
1943
concat_bytes!([
2044
true, //~ ERROR cannot concatenate boolean literals
@@ -38,6 +62,7 @@ fn main() {
3862
[5, 6, 7], //~ ERROR cannot concatenate doubly nested array
3963
]);
4064
concat_bytes!(5u16); //~ ERROR cannot concatenate numeric literals
65+
//~^ SUGGESTION [5u16]
4166
concat_bytes!([5u16]); //~ ERROR numeric literal is not a `u8`
4267
concat_bytes!([3; ()]); //~ ERROR repeat count is not a positive number
4368
concat_bytes!([3; -2]); //~ ERROR repeat count is not a positive number
Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,148 @@
11
error: expected a byte literal
2-
--> $DIR/concat-bytes-error.rs:4:19
2+
--> $DIR/concat-bytes-error.rs:8:19
33
|
44
LL | concat_bytes!(pie);
55
| ^^^
66
|
77
= note: only byte literals (like `b"foo"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()`
88

99
error: expected a byte literal
10-
--> $DIR/concat-bytes-error.rs:5:19
10+
--> $DIR/concat-bytes-error.rs:9:19
1111
|
1212
LL | concat_bytes!(pie, pie);
1313
| ^^^ ^^^
1414
|
1515
= note: only byte literals (like `b"foo"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()`
1616

1717
error: cannot concatenate string literals
18-
--> $DIR/concat-bytes-error.rs:6:19
18+
--> $DIR/concat-bytes-error.rs:12:19
1919
|
2020
LL | concat_bytes!("tnrsi", "tnri");
2121
| ^^^^^^^ help: try using a byte string: `b"tnrsi"`
2222

23+
error: cannot concatenate string literals
24+
--> $DIR/concat-bytes-error.rs:14:19
25+
|
26+
LL | concat_bytes!(r"tnrsi", r"tnri");
27+
| ^^^^^^^^ help: try using a byte string: `br"tnrsi"`
28+
29+
error: cannot concatenate string literals
30+
--> $DIR/concat-bytes-error.rs:16:19
31+
|
32+
LL | concat_bytes!(r#"tnrsi"#, r###"tnri"###);
33+
| ^^^^^^^^^^ help: try using a byte string: `br#"tnrsi"#`
34+
35+
error: cannot concatenate C string literals
36+
--> $DIR/concat-bytes-error.rs:18:19
37+
|
38+
LL | concat_bytes!(c"tnrsi", c"tnri");
39+
| ^^^^^^^^ help: try using a null-terminated byte string: `b"tnrsi\0"`
40+
|
41+
note: concatenating C strings is ambiguous about including the '\0'
42+
--> $DIR/concat-bytes-error.rs:18:19
43+
|
44+
LL | concat_bytes!(c"tnrsi", c"tnri");
45+
| ^^^^^^^^
46+
= note: concatenating C strings is ambiguous about including the '\0'
47+
48+
error: cannot concatenate C string literals
49+
--> $DIR/concat-bytes-error.rs:20:19
50+
|
51+
LL | concat_bytes!(cr"tnrsi", cr"tnri");
52+
| ^^^^^^^^^
53+
|
54+
= note: concatenating C strings is ambiguous about including the '\0'
55+
56+
error: cannot concatenate C string literals
57+
--> $DIR/concat-bytes-error.rs:21:19
58+
|
59+
LL | concat_bytes!(cr#"tnrsi"#, cr###"tnri"###);
60+
| ^^^^^^^^^^^
61+
|
62+
= note: concatenating C strings is ambiguous about including the '\0'
63+
2364
error: cannot concatenate float literals
24-
--> $DIR/concat-bytes-error.rs:7:19
65+
--> $DIR/concat-bytes-error.rs:24:19
2566
|
2667
LL | concat_bytes!(2.8);
2768
| ^^^
2869

2970
error: cannot concatenate numeric literals
30-
--> $DIR/concat-bytes-error.rs:8:19
71+
--> $DIR/concat-bytes-error.rs:25:19
3172
|
3273
LL | concat_bytes!(300);
3374
| ^^^ help: try wrapping the number in an array: `[300]`
3475

3576
error: cannot concatenate character literals
36-
--> $DIR/concat-bytes-error.rs:9:19
77+
--> $DIR/concat-bytes-error.rs:27:19
3778
|
3879
LL | concat_bytes!('a');
3980
| ^^^ help: try using a byte character: `b'a'`
4081

4182
error: cannot concatenate boolean literals
42-
--> $DIR/concat-bytes-error.rs:10:19
83+
--> $DIR/concat-bytes-error.rs:29:19
4384
|
4485
LL | concat_bytes!(true, false);
4586
| ^^^^
4687

4788
error: cannot concatenate numeric literals
48-
--> $DIR/concat-bytes-error.rs:11:19
89+
--> $DIR/concat-bytes-error.rs:30:19
4990
|
5091
LL | concat_bytes!(42, b"va", b'l');
5192
| ^^ help: try wrapping the number in an array: `[42]`
5293

5394
error: cannot concatenate numeric literals
54-
--> $DIR/concat-bytes-error.rs:12:19
95+
--> $DIR/concat-bytes-error.rs:32:19
5596
|
5697
LL | concat_bytes!(42, b"va", b'l', [1, 2]);
5798
| ^^ help: try wrapping the number in an array: `[42]`
5899

59100
error: cannot concatenate string literals
60-
--> $DIR/concat-bytes-error.rs:14:9
101+
--> $DIR/concat-bytes-error.rs:37:9
61102
|
62103
LL | "hi",
63104
| ^^^^
64105

65106
error: cannot concatenate character literals
66-
--> $DIR/concat-bytes-error.rs:17:9
107+
--> $DIR/concat-bytes-error.rs:40:9
67108
|
68109
LL | 'a',
69110
| ^^^ help: try using a byte character: `b'a'`
70111

71112
error: cannot concatenate boolean literals
72-
--> $DIR/concat-bytes-error.rs:20:9
113+
--> $DIR/concat-bytes-error.rs:44:9
73114
|
74115
LL | true,
75116
| ^^^^
76117

77118
error: cannot concatenate boolean literals
78-
--> $DIR/concat-bytes-error.rs:23:9
119+
--> $DIR/concat-bytes-error.rs:47:9
79120
|
80121
LL | false,
81122
| ^^^^^
82123

83124
error: cannot concatenate float literals
84-
--> $DIR/concat-bytes-error.rs:26:9
125+
--> $DIR/concat-bytes-error.rs:50:9
85126
|
86127
LL | 2.6,
87128
| ^^^
88129

89130
error: numeric literal is out of bounds
90-
--> $DIR/concat-bytes-error.rs:29:9
131+
--> $DIR/concat-bytes-error.rs:53:9
91132
|
92133
LL | 265,
93134
| ^^^
94135

95136
error: expected a byte literal
96-
--> $DIR/concat-bytes-error.rs:32:9
137+
--> $DIR/concat-bytes-error.rs:56:9
97138
|
98139
LL | -33,
99140
| ^^^
100141
|
101142
= note: only byte literals (like `b"foo"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()`
102143

103144
error: cannot concatenate doubly nested array
104-
--> $DIR/concat-bytes-error.rs:35:9
145+
--> $DIR/concat-bytes-error.rs:59:9
105146
|
106147
LL | b"hi!",
107148
| ^^^^^^
@@ -110,72 +151,72 @@ LL | b"hi!",
110151
= help: try flattening the array
111152

112153
error: cannot concatenate doubly nested array
113-
--> $DIR/concat-bytes-error.rs:38:9
154+
--> $DIR/concat-bytes-error.rs:62:9
114155
|
115156
LL | [5, 6, 7],
116157
| ^^^^^^^^^
117158

118159
error: cannot concatenate numeric literals
119-
--> $DIR/concat-bytes-error.rs:40:19
160+
--> $DIR/concat-bytes-error.rs:64:19
120161
|
121162
LL | concat_bytes!(5u16);
122163
| ^^^^ help: try wrapping the number in an array: `[5u16]`
123164

124165
error: numeric literal is not a `u8`
125-
--> $DIR/concat-bytes-error.rs:41:20
166+
--> $DIR/concat-bytes-error.rs:66:20
126167
|
127168
LL | concat_bytes!([5u16]);
128169
| ^^^^
129170

130171
error: repeat count is not a positive number
131-
--> $DIR/concat-bytes-error.rs:42:23
172+
--> $DIR/concat-bytes-error.rs:67:23
132173
|
133174
LL | concat_bytes!([3; ()]);
134175
| ^^
135176

136177
error: repeat count is not a positive number
137-
--> $DIR/concat-bytes-error.rs:43:23
178+
--> $DIR/concat-bytes-error.rs:68:23
138179
|
139180
LL | concat_bytes!([3; -2]);
140181
| ^^
141182

142183
error: repeat count is not a positive number
143-
--> $DIR/concat-bytes-error.rs:44:25
184+
--> $DIR/concat-bytes-error.rs:69:25
144185
|
145186
LL | concat_bytes!([pie; -2]);
146187
| ^^
147188

148189
error: expected a byte literal
149-
--> $DIR/concat-bytes-error.rs:45:20
190+
--> $DIR/concat-bytes-error.rs:70:20
150191
|
151192
LL | concat_bytes!([pie; 2]);
152193
| ^^^
153194
|
154195
= note: only byte literals (like `b"foo"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()`
155196

156197
error: cannot concatenate float literals
157-
--> $DIR/concat-bytes-error.rs:46:20
198+
--> $DIR/concat-bytes-error.rs:71:20
158199
|
159200
LL | concat_bytes!([2.2; 0]);
160201
| ^^^
161202

162203
error: repeat count is not a positive number
163-
--> $DIR/concat-bytes-error.rs:47:25
204+
--> $DIR/concat-bytes-error.rs:72:25
164205
|
165206
LL | concat_bytes!([5.5; ()]);
166207
| ^^
167208

168209
error: cannot concatenate doubly nested array
169-
--> $DIR/concat-bytes-error.rs:48:20
210+
--> $DIR/concat-bytes-error.rs:73:20
170211
|
171212
LL | concat_bytes!([[1, 2, 3]; 3]);
172213
| ^^^^^^^^^
173214

174215
error: cannot concatenate doubly nested array
175-
--> $DIR/concat-bytes-error.rs:49:20
216+
--> $DIR/concat-bytes-error.rs:74:20
176217
|
177218
LL | concat_bytes!([[42; 2]; 3]);
178219
| ^^^^^^^
179220

180-
error: aborting due to 28 previous errors
221+
error: aborting due to 33 previous errors
181222

0 commit comments

Comments
 (0)
Please sign in to comment.