Skip to content

Commit 71cd1bb

Browse files
committed
Port #[link_ordinal] to the new attribute parsing infrastructure.
1 parent 929b899 commit 71cd1bb

File tree

5 files changed

+40
-64
lines changed

5 files changed

+40
-64
lines changed

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ attr_parsing_ill_formed_attribute_input = {$num_suggestions ->
3232
*[other] valid forms for the attribute are {$suggestions}
3333
}
3434
35-
attr_parsing_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal`
36-
.note = an unsuffixed integer value, e.g., `1`, is expected
37-
3835
attr_parsing_incorrect_repr_format_align_one_arg =
3936
incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
4037

compiler/rustc_attr_parsing/src/attributes/link_attrs.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
21
use rustc_attr_data_structures::AttributeKind;
32
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
43
use rustc_feature::{AttributeTemplate, template};
54
use rustc_span::{Symbol, sym};
65

76
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
8-
use crate::context::{AcceptContext, Stage};
7+
use crate::context::{AcceptContext, Stage, parse_single_integer};
98
use crate::parser::ArgParser;
10-
use crate::session_diagnostics::{
11-
InvalidLinkOrdinalFormat, LinkOrdinalOutOfRange, NullOnLinkSection,
12-
};
9+
use crate::session_diagnostics::{LinkOrdinalOutOfRange, NullOnLinkSection};
1310

1411
pub(crate) struct LinkNameParser;
1512

@@ -70,22 +67,7 @@ impl<S: Stage> SingleAttributeParser<S> for LinkOrdinalParser {
7067
const TEMPLATE: AttributeTemplate = template!(List: "ordinal");
7168

7269
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
73-
let Some(arg_list) = args.list() else {
74-
cx.expected_list(cx.attr_span);
75-
return None;
76-
};
77-
78-
let Some(single_arg) = arg_list.single() else {
79-
cx.expected_single_argument(cx.attr_span);
80-
return None;
81-
};
82-
83-
let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
84-
single_arg.lit()
85-
else {
86-
cx.emit_err(InvalidLinkOrdinalFormat { span: cx.attr_span });
87-
return None;
88-
};
70+
let ordinal = parse_single_integer(cx, args)?;
8971

9072
// According to the table at
9173
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the
@@ -100,8 +82,8 @@ impl<S: Stage> SingleAttributeParser<S> for LinkOrdinalParser {
10082
// import library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I
10183
// don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL --
10284
// see earlier comment about LINK.EXE failing.)
103-
let Ok(ordinal) = ordinal.get().try_into() else {
104-
cx.emit_err(LinkOrdinalOutOfRange { span: cx.attr_span, ordinal: ordinal.get() });
85+
let Ok(ordinal) = ordinal.try_into() else {
86+
cx.emit_err(LinkOrdinalOutOfRange { span: cx.attr_span, ordinal });
10587
return None;
10688
};
10789

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
use rustc_ast::LitKind;
21
use rustc_attr_data_structures::AttributeKind;
32
use rustc_feature::{AttributeTemplate, template};
43
use rustc_span::{Symbol, sym};
54

65
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
7-
use crate::context::{AcceptContext, Stage};
6+
use crate::context::{AcceptContext, Stage, parse_single_integer};
87
use crate::parser::ArgParser;
98

109
pub(crate) struct RustcLayoutScalarValidRangeStart;
@@ -16,8 +15,8 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStart {
1615
const TEMPLATE: AttributeTemplate = template!(List: "start");
1716

1817
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
19-
parse_rustc_layout_scalar_valid_range(cx, args)
20-
.map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(n, cx.attr_span))
18+
parse_single_integer(cx, args)
19+
.map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(Box::new(n), cx.attr_span))
2120
}
2221
}
2322

@@ -30,34 +29,11 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEnd {
3029
const TEMPLATE: AttributeTemplate = template!(List: "end");
3130

3231
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
33-
parse_rustc_layout_scalar_valid_range(cx, args)
34-
.map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(n, cx.attr_span))
32+
parse_single_integer(cx, args)
33+
.map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(Box::new(n), cx.attr_span))
3534
}
3635
}
3736

38-
fn parse_rustc_layout_scalar_valid_range<S: Stage>(
39-
cx: &mut AcceptContext<'_, '_, S>,
40-
args: &ArgParser<'_>,
41-
) -> Option<Box<u128>> {
42-
let Some(list) = args.list() else {
43-
cx.expected_list(cx.attr_span);
44-
return None;
45-
};
46-
let Some(single) = list.single() else {
47-
cx.expected_single_argument(list.span);
48-
return None;
49-
};
50-
let Some(lit) = single.lit() else {
51-
cx.expected_integer_literal(single.span());
52-
return None;
53-
};
54-
let LitKind::Int(num, _ty) = lit.kind else {
55-
cx.expected_integer_literal(single.span());
56-
return None;
57-
};
58-
Some(Box::new(num.0))
59-
}
60-
6137
pub(crate) struct RustcObjectLifetimeDefaultParser;
6238

6339
impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::ops::{Deref, DerefMut};
55
use std::sync::LazyLock;
66

77
use private::Sealed;
8-
use rustc_ast::{self as ast, MetaItemLit, NodeId};
8+
use rustc_ast::{self as ast, LitKind, MetaItemLit, NodeId};
99
use rustc_attr_data_structures::AttributeKind;
1010
use rustc_attr_data_structures::lints::{AttributeLint, AttributeLintKind};
1111
use rustc_errors::{DiagCtxtHandle, Diagnostic};
@@ -742,3 +742,32 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
742742
}
743743
}
744744
}
745+
746+
/// Parse a single integer.
747+
///
748+
/// Used by attributes that take a single integer as argument, such as
749+
/// `#[link_ordinal]` and `#[rustc_layout_scalar_valid_range_start]`.
750+
/// `cx` is the context given to the attribute.
751+
/// `args` is the parser for the attribute arguments.
752+
pub(crate) fn parse_single_integer<S: Stage>(
753+
cx: &mut AcceptContext<'_, '_, S>,
754+
args: &ArgParser<'_>,
755+
) -> Option<u128> {
756+
let Some(list) = args.list() else {
757+
cx.expected_list(cx.attr_span);
758+
return None;
759+
};
760+
let Some(single) = list.single() else {
761+
cx.expected_single_argument(list.span);
762+
return None;
763+
};
764+
let Some(lit) = single.lit() else {
765+
cx.expected_integer_literal(single.span());
766+
return None;
767+
};
768+
let LitKind::Int(num, _ty) = lit.kind else {
769+
cx.expected_integer_literal(single.span());
770+
return None;
771+
};
772+
Some(num.0)
773+
}

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -514,14 +514,6 @@ pub(crate) struct NakedFunctionIncompatibleAttribute {
514514
pub attr: String,
515515
}
516516

517-
#[derive(Diagnostic)]
518-
#[diag(attr_parsing_illegal_link_ordinal_format)]
519-
#[note]
520-
pub(crate) struct InvalidLinkOrdinalFormat {
521-
#[primary_span]
522-
pub span: Span,
523-
}
524-
525517
#[derive(Diagnostic)]
526518
#[diag(attr_parsing_link_ordinal_out_of_range)]
527519
#[note]

0 commit comments

Comments
 (0)