Skip to content

Commit a5ec4b6

Browse files
Implement indent check
1 parent 13c3873 commit a5ec4b6

3 files changed

Lines changed: 44 additions & 8 deletions

File tree

compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ impl DiagnosticDeriveVariantBuilder {
226226
)
227227
.emit();
228228
}
229-
self.message = Some(Message::Inline(message.span(), message.value()));
229+
self.message =
230+
Some(Message::Inline(attr.span(), message.span(), message.value()));
230231
} else {
231232
// Parse a slug
232233
let slug = input.parse::<Path>()?;

compiler/rustc_macros/src/diagnostics/message.rs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::diagnostics::error::span_err;
1111
#[derive(Clone)]
1212
pub(crate) enum Message {
1313
Slug(Path),
14-
Inline(Span, String),
14+
Inline(Span, Span, String),
1515
}
1616

1717
impl Message {
@@ -23,8 +23,8 @@ impl Message {
2323
Message::Slug(slug) => {
2424
quote! { crate::fluent_generated::#slug }
2525
}
26-
Message::Inline(message_span, message) => {
27-
verify_fluent_message(*message_span, &message, variant);
26+
Message::Inline(attr_span, message_span, message) => {
27+
verify_fluent_message(*attr_span, *message_span, &message, variant);
2828
quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) }
2929
}
3030
}
@@ -85,7 +85,18 @@ impl Message {
8585
}
8686
}
8787

88-
fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&VariantInfo<'_>>) {
88+
fn verify_fluent_message(
89+
attr_span: Span,
90+
msg_span: Span,
91+
message_str: &str,
92+
variant: Option<&VariantInfo<'_>>,
93+
) {
94+
verify_variables_used(msg_span, message_str, variant);
95+
verify_message_style(msg_span, message_str);
96+
verify_message_formatting(attr_span, msg_span, message_str);
97+
}
98+
99+
fn verify_variables_used(msg_span: Span, message_str: &str, variant: Option<&VariantInfo<'_>>) {
89100
// Parse the fluent message
90101
const GENERATED_MSG_ID: &str = "generated_msg";
91102
let resource =
@@ -114,8 +125,6 @@ fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&Var
114125
}
115126
}
116127
}
117-
118-
verify_message_style(msg_span, message_str);
119128
}
120129

121130
fn variable_references<'a>(msg: &fluent_syntax::ast::Message<&'a str>) -> Vec<&'a str> {
@@ -181,3 +190,29 @@ fn verify_message_style(msg_span: Span, message: &str) {
181190
return;
182191
}
183192
}
193+
194+
/// Verifies that the message is properly indented into the code
195+
fn verify_message_formatting(attr_span: Span, msg_span: Span, message: &str) {
196+
// Find the indent at the start of the message (`column()` is one-indexed)
197+
let start = attr_span.unwrap().column() - 1;
198+
199+
for line in message.lines().skip(1) {
200+
if line.is_empty() {
201+
continue;
202+
}
203+
let indent = line.chars().take_while(|c| *c == ' ').count();
204+
if indent < start {
205+
span_err(
206+
msg_span.unwrap(),
207+
format!("message is not properly indented. {indent} < {start}"),
208+
)
209+
.emit();
210+
return;
211+
}
212+
if indent % 4 != 0 {
213+
span_err(msg_span.unwrap(), "message is not indented with a multiple of 4 spaces")
214+
.emit();
215+
return;
216+
}
217+
}
218+
}

compiler/rustc_macros/src/diagnostics/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ impl SubdiagnosticVariant {
708708
}
709709
if !input.is_empty() { input.parse::<Token![,]>()?; }
710710
if is_first {
711-
slug = Some(Message::Inline(message.span(), message.value()));
711+
slug = Some(Message::Inline(attr.span(), message.span(), message.value()));
712712
is_first = false;
713713
} else {
714714
span_err(message.span().unwrap(), "a diagnostic message must be the first argument to the attribute").emit();

0 commit comments

Comments
 (0)