Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ pub(crate) struct UnstableInStableExposed {
pub is_function_call2: bool,
#[suggestion(
"if the {$is_function_call2 ->
[true] caller
*[false] function
} is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]`",
[true] caller
*[false] function
} is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]`",
code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n",
applicability = "has-placeholders"
)]
Expand Down Expand Up @@ -300,11 +300,11 @@ pub(crate) struct UnallowedHeapAllocations {
#[primary_span]
#[label(
r#"allocation not allowed in {$kind ->
[const] constant
[static] static
[const_fn] constant function
*[other] {""}
}s"#
[const] constant
[static] static
[const_fn] constant function
*[other] {""}
}s"#
)]
pub span: Span,
pub kind: ConstContext,
Expand Down Expand Up @@ -539,20 +539,20 @@ pub enum NonConstClosureNote {
},
#[note(
r#"function pointers need an RFC before allowed to be called in {$kind ->
[const] constant
[static] static
[const_fn] constant function
*[other] {""}
}s"#
[const] constant
[static] static
[const_fn] constant function
*[other] {""}
}s"#
)]
FnPtr,
#[note(
r#"closures need an RFC before allowed to be called in {$kind ->
[const] constant
[static] static
[const_fn] constant function
*[other] {""}
}s"#
[const] constant
[static] static
[const_fn] constant function
*[other] {""}
}s"#
)]
Closure,
}
Expand Down Expand Up @@ -608,11 +608,11 @@ pub struct LiveDrop<'tcx> {
#[primary_span]
#[label(
r#"the destructor for this type cannot be evaluated in {$kind ->
[const] constant
[static] static
[const_fn] constant function
*[other] {""}
}s"#
[const] constant
[static] static
[const_fn] constant function
*[other] {""}
}s"#
)]
pub span: Span,
pub kind: ConstContext,
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,11 @@ impl DiagnosticDeriveVariantBuilder {
)
.emit();
}
self.message =
Some(Message { message_span: message.span(), value: message.value() });
self.message = Some(Message {
attr_span: attr.span(),
message_span: message.span(),
value: message.value(),
});
}

// Parse arguments
Expand Down
39 changes: 35 additions & 4 deletions compiler/rustc_macros/src/diagnostics/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::diagnostics::error::span_err;

#[derive(Clone)]
pub(crate) struct Message {
pub attr_span: Span,
pub message_span: Span,
pub value: String,
}
Expand All @@ -19,12 +20,18 @@ impl Message {
/// For subdiagnostics, we cannot check this.
pub(crate) fn diag_message(&self, variant: Option<&VariantInfo<'_>>) -> TokenStream {
let message = &self.value;
verify_fluent_message(self.message_span, &message, variant);
self.verify(variant);
quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) }
}

fn verify(&self, variant: Option<&VariantInfo<'_>>) {
verify_variables_used(self.message_span, &self.value, variant);
verify_message_style(self.message_span, &self.value);
verify_message_formatting(self.attr_span, self.message_span, &self.value);
}
}

fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&VariantInfo<'_>>) {
fn verify_variables_used(msg_span: Span, message_str: &str, variant: Option<&VariantInfo<'_>>) {
// Parse the fluent message
const GENERATED_MSG_ID: &str = "generated_msg";
let resource =
Expand Down Expand Up @@ -53,8 +60,6 @@ fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&Var
}
}
}

verify_message_style(msg_span, message_str);
}

fn variable_references<'a>(msg: &fluent_syntax::ast::Message<&'a str>) -> Vec<&'a str> {
Expand Down Expand Up @@ -120,3 +125,29 @@ fn verify_message_style(msg_span: Span, message: &str) {
return;
}
}

/// Verifies that the message is properly indented into the code
fn verify_message_formatting(attr_span: Span, msg_span: Span, message: &str) {
// Find the indent at the start of the message (`column()` is one-indexed)
let start = attr_span.unwrap().column() - 1;

for line in message.lines().skip(1) {
if line.is_empty() {
continue;
}
let indent = line.chars().take_while(|c| *c == ' ').count();
if indent < start {
span_err(
msg_span.unwrap(),
format!("message is not properly indented. {indent} < {start}"),
)
.emit();
return;
}
if indent % 4 != 0 {
span_err(msg_span.unwrap(), "message is not indented with a multiple of 4 spaces")
.emit();
return;
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_macros/src/diagnostics/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ impl SubdiagnosticVariant {
}
if !input.is_empty() { input.parse::<Token![,]>()?; }
if is_first {
message = Some(Message { message_span: inline_message.span(), value: inline_message.value() });
message = Some(Message { attr_span: attr.span(), message_span: inline_message.span(), value: inline_message.value() });
is_first = false;
} else {
span_err(inline_message.span().unwrap(), "a diagnostic message must be the first argument to the attribute").emit();
Expand Down
34 changes: 17 additions & 17 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,12 @@ pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
pub(crate) missing_target_features: DiagArgValue,
pub(crate) missing_target_features_count: usize,
#[note("the {$build_target_features} target {$build_target_features_count ->
[1] feature
*[count] features
[1] feature
*[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it
*[count] them
} in `#[target_feature]`")]
[1] it
*[count] them
} in `#[target_feature]`")]
pub(crate) note: bool,
pub(crate) build_target_features: DiagArgValue,
pub(crate) build_target_features_count: usize,
Expand Down Expand Up @@ -532,12 +532,12 @@ pub(crate) struct CallToFunctionWithRequiresUnsafe {
pub(crate) missing_target_features: DiagArgValue,
pub(crate) missing_target_features_count: usize,
#[note("the {$build_target_features} target {$build_target_features_count ->
[1] feature
*[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it
*[count] them
} in `#[target_feature]`")]
[1] feature
*[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it
*[count] them
} in `#[target_feature]`")]
pub(crate) note: bool,
pub(crate) build_target_features: DiagArgValue,
pub(crate) build_target_features_count: usize,
Expand Down Expand Up @@ -1264,9 +1264,9 @@ pub(crate) struct InterpretedAsConstSugg {
pub(crate) enum SuggestLet {
#[multipart_suggestion(
"you might want to use `if let` to ignore the {$count ->
[one] variant that isn't
*[other] variants that aren't
} matched",
[one] variant that isn't
*[other] variants that aren't
} matched",
applicability = "has-placeholders"
)]
If {
Expand All @@ -1278,9 +1278,9 @@ pub(crate) enum SuggestLet {
},
#[suggestion(
"you might want to use `let...else` to handle the {$count ->
[one] variant that isn't
*[other] variants that aren't
} matched",
[one] variant that isn't
*[other] variants that aren't
} matched",
code = " else {{ todo!() }}",
applicability = "has-placeholders"
)]
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_monomorphize/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ pub(crate) struct AbiRequiredTargetFeature<'a> {
#[primary_span]
#[label(
"function {$is_call ->
[true] called
*[false] defined
} here"
[true] called
*[false] defined
} here"
)]
pub span: Span,
pub required_feature: &'a str,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,7 @@ pub(crate) enum MatchArmBodyWithoutBracesSugg {
#[multipart_suggestion(
"surround the {$num_statements ->
[one] statement
*[other] statements
*[other] statements
} with a body",
applicability = "machine-applicable"
)]
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1417,8 +1417,8 @@ pub(crate) struct DuplicateEiiImpls {
pub second_crate: Symbol,

#[note("in addition to these two, { $num_additional_crates ->
[one] another implementation was found in crate {$additional_crate_names}
*[other] more implementations were also found in the following crates: {$additional_crate_names}
[one] another implementation was found in crate {$additional_crate_names}
*[other] more implementations were also found in the following crates: {$additional_crate_names}
}")]
pub additional_crates: Option<()>,

Expand Down
Loading
Loading