Skip to content

Commit 5c91664

Browse files
Implement indent check
1 parent c1091da commit 5c91664

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
@@ -10,7 +10,7 @@ use crate::diagnostics::error::span_err;
1010
#[derive(Clone)]
1111
pub(crate) enum Message {
1212
Slug(Path),
13-
Inline(Span, String),
13+
Inline(Span, Span, String),
1414
}
1515

1616
impl Message {
@@ -22,8 +22,8 @@ impl Message {
2222
Message::Slug(slug) => {
2323
quote! { crate::fluent_generated::#slug }
2424
}
25-
Message::Inline(message_span, message) => {
26-
verify_fluent_message(*message_span, &message, variant);
25+
Message::Inline(attr_span, message_span, message) => {
26+
verify_fluent_message(*attr_span, *message_span, &message, variant);
2727
quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) }
2828
}
2929
}
@@ -84,7 +84,18 @@ impl Message {
8484
}
8585
}
8686

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

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

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)