Skip to content
Closed
6 changes: 1 addition & 5 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,11 +656,7 @@ impl Pat {
// A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
// assuming `T0` to `Tn` are all syntactically valid as types.
PatKind::Tuple(pats) => {
let mut tys = ThinVec::with_capacity(pats.len());
// FIXME(#48994) - could just be collected into an Option<Vec>
for pat in pats {
tys.push(pat.to_ty()?);
}
let tys = pats.iter().map(|pat| pat.to_ty()).collect::<Option<ThinVec<_>>>()?;
TyKind::Tup(tys)
}
_ => return None,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,5 @@ pub(crate) struct FixedX18InvalidArch<'a> {
}

#[derive(Diagnostic)]
#[diag("`-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later.")]
#[diag("`-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later")]
pub(crate) struct SanitizerKcfiArityRequiresLLVM2100;
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub(crate) struct MissingQueryDepGraph {

#[derive(Diagnostic)]
#[diag(
"found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case)."
"found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case)"
)]
pub(crate) struct MalformedCguName {
#[primary_span]
Expand Down Expand Up @@ -562,12 +562,12 @@ pub(crate) struct SelfContainedLinkerMissing;

#[derive(Diagnostic)]
#[diag(
"please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option."
"please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option"
)]
pub(crate) struct CheckInstalledVisualStudio;

#[derive(Diagnostic)]
#[diag("VS Code is a different product, and is not sufficient.")]
#[diag("VS Code is a different product, and is not sufficient")]
pub(crate) struct InsufficientVSCodeProduct;

#[derive(Diagnostic)]
Expand Down Expand Up @@ -610,13 +610,13 @@ pub(crate) struct LinkerFileStem;

#[derive(Diagnostic)]
#[diag(
"link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms."
"link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms"
)]
pub(crate) struct StaticLibraryNativeArtifacts;

#[derive(Diagnostic)]
#[diag(
"native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms."
"native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms"
)]
pub(crate) struct StaticLibraryNativeArtifactsToFile<'a> {
pub path: &'a Path,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ pub(crate) struct UnallowedHeapAllocations {
pub span: Span,
pub kind: ConstContext,
#[note(
"The runtime heap is not yet available at compile-time, so no runtime heap allocations can be created."
"the runtime heap is not yet available at compile-time, so no runtime heap allocations can be created"
)]
pub teach: bool,
}
Expand Down Expand Up @@ -347,7 +347,7 @@ pub(crate) struct InteriorMutableBorrowEscaping {
#[diag("constant evaluation is taking a long time")]
#[note(
"this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
If your compilation actually takes a long time, you can safely allow the lint."
If your compilation actually takes a long time, you can safely allow the lint"
)]
pub struct LongRunning {
#[help("the constant being evaluated")]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_driver_impl/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub(crate) struct RlinkCorruptFile<'a> {
}

#[derive(Diagnostic)]
#[diag("the compiler unexpectedly panicked. this is a bug.")]
#[diag("the compiler unexpectedly panicked. This is a bug")]
pub(crate) struct Ice;

#[derive(Diagnostic)]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ declare_features! (
(unstable, async_for_loop, "1.77.0", Some(118898)),
/// Allows `async` trait bound modifier.
(unstable, async_trait_bounds, "1.85.0", Some(62290)),
/// Target features on avr.
(unstable, avr_target_feature, "CURRENT_RUSTC_VERSION", Some(146889)),
/// Allows using Intel AVX10 target features and intrinsics
(unstable, avx10_target_feature, "1.88.0", Some(138843)),
/// Target features on bpf.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ pub(crate) struct CastThinPointerToWidePointer<'tcx> {
pub expr_ty: Ty<'tcx>,
pub cast_ty: Ty<'tcx>,
#[note(
"Thin pointers are \"simple\" pointers: they are purely a reference to a
"thin pointers are \"simple\" pointers: they are purely a reference to a
memory address.

Wide pointers are pointers referencing \"Dynamically Sized Types\" (also
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_incremental/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ pub(crate) struct DeleteWorkProduct<'a> {

#[derive(Diagnostic)]
#[diag(
"corrupt incremental compilation artifact found at `{$path}`. This file will automatically be ignored and deleted. If you see this message repeatedly or can provoke it without manually manipulating the compiler's artifacts, please file an issue. The incremental compilation system relies on hardlinks and filesystem locks behaving correctly, and may not deal well with OS crashes, so whatever information you can provide about your filesystem or other state may be very relevant."
"corrupt incremental compilation artifact found at `{$path}`. This file will automatically be ignored and deleted. If you see this message repeatedly or can provoke it without manually manipulating the compiler's artifacts, please file an issue. The incremental compilation system relies on hardlinks and filesystem locks behaving correctly, and may not deal well with OS crashes, so whatever information you can provide about your filesystem or other state may be very relevant"
)]
pub(crate) struct CorruptFile<'a> {
pub path: &'a Path,
Expand Down
72 changes: 57 additions & 15 deletions compiler/rustc_macros/src/diagnostics/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ impl Message {
quote! { crate::fluent_generated::#slug }
}
Message::Inline(message_span, message) => {
if let Some(variant) = variant {
verify_fluent_message(*message_span, &message, variant);
}
verify_fluent_message(*message_span, &message, variant);
quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) }
}
}
Expand Down Expand Up @@ -86,30 +84,37 @@ impl Message {
}
}

fn verify_fluent_message(msg_span: Span, message: &str, variant: &VariantInfo<'_>) {
fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&VariantInfo<'_>>) {
// Parse the fluent message
const GENERATED_MSG_ID: &str = "generated_msg";
let resource = FluentResource::try_new(format!("{GENERATED_MSG_ID} = {message}\n")).unwrap();
let resource =
FluentResource::try_new(format!("{GENERATED_MSG_ID} = {message_str}\n")).unwrap();
assert_eq!(resource.entries().count(), 1);
let Some(fluent_syntax::ast::Entry::Message(message)) = resource.get_entry(0) else {
panic!("Did not parse into a message")
};

// Check if all variables are used
let fields: Vec<String> = variant
.bindings()
.iter()
.flat_map(|b| b.ast().ident.as_ref())
.map(|id| id.to_string())
.collect();
for variable in variable_references(&message) {
if !fields.iter().any(|f| f == variable) {
span_err(msg_span.unwrap(), format!("Variable `{variable}` not found in diagnostic "))
if let Some(variant) = variant {
let fields: Vec<String> = variant
.bindings()
.iter()
.flat_map(|b| b.ast().ident.as_ref())
.map(|id| id.to_string())
.collect();
for variable in variable_references(&message) {
if !fields.iter().any(|f| f == variable) {
span_err(
msg_span.unwrap(),
format!("Variable `{variable}` not found in diagnostic "),
)
.help(format!("Available fields: {:?}", fields.join(", ")))
.emit();
}
}
// assert!(, );
}

verify_message_style(msg_span, message_str);
}

fn variable_references<'a>(msg: &fluent_syntax::ast::Message<&'a str>) -> Vec<&'a str> {
Expand All @@ -136,3 +141,40 @@ fn variable_references<'a>(msg: &fluent_syntax::ast::Message<&'a str>) -> Vec<&'
}
refs
}

const ALLOWED_CAPITALIZED_WORDS: &[&str] = &[
// tidy-alphabetical-start
"ABI",
"ABIs",
"ADT",
"C-variadic",
"CGU-reuse",
"Cargo",
"Ferris",
"GCC",
"MIR",
"NaNs",
"OK",
"VS",
// tidy-alphabetical-end
];

/// See: https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-output-style-guide
fn verify_message_style(msg_span: Span, message: &str) {
// Verify that message starts with lowercase char
let Some(first_word) = message.split_whitespace().next() else {
span_err(msg_span.unwrap(), "message must not be empty").emit();
return;
};
let first_char = first_word.chars().next().expect("Word is not empty");
if first_char.is_uppercase() && !ALLOWED_CAPITALIZED_WORDS.contains(&first_word) {
span_err(msg_span.unwrap(), "message `{value}` starts with an uppercase letter. Fix it or add it to `ALLOWED_CAPITALIZED_WORDS`").emit();
return;
}

// Verify that message does not end in `.`
if message.ends_with(".") && !message.ends_with("...") {
span_err(msg_span.unwrap(), "message `{value}` ends with a period").emit();
return;
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ pub(crate) struct LowerRangeBoundMustBeLessThanOrEqualToUpper {
#[label("lower bound larger than upper bound")]
pub(crate) span: Span,
#[note(
"When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range."
"when matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range"
)]
pub(crate) teach: bool,
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ symbols! {
automatically_derived,
available_externally,
avr,
avr_target_feature,
avx,
avx10_target_feature,
avx512_target_feature,
Expand Down
41 changes: 33 additions & 8 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,28 @@ static M68K_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
// tidy-alphabetical-end
];

static AVR_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
// tidy-alphabetical-start
("addsubiw", Unstable(sym::avr_target_feature), &[]),
("break", Unstable(sym::avr_target_feature), &[]),
("eijmpcall", Unstable(sym::avr_target_feature), &[]),
("elpm", Unstable(sym::avr_target_feature), &[]),
("elpmx", Unstable(sym::avr_target_feature), &[]),
("ijmpcall", Unstable(sym::avr_target_feature), &[]),
("jmpcall", Unstable(sym::avr_target_feature), &[]),
("lowbytefirst", Unstable(sym::avr_target_feature), &[]),
("lpm", Unstable(sym::avr_target_feature), &[]),
("lpmx", Unstable(sym::avr_target_feature), &[]),
("movw", Unstable(sym::avr_target_feature), &[]),
("mul", Unstable(sym::avr_target_feature), &[]),
("rmw", Unstable(sym::avr_target_feature), &[]),
("spm", Unstable(sym::avr_target_feature), &[]),
("spmx", Unstable(sym::avr_target_feature), &[]),
("sram", Forbidden { reason: "devices that have no SRAM are unsupported" }, &[]),
("tinyencoding", Unstable(sym::avr_target_feature), &[]),
// tidy-alphabetical-end
];

/// When rustdoc is running, provide a list of all known features so that all their respective
/// primitives may be documented.
///
Expand All @@ -919,6 +941,7 @@ pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
.chain(IBMZ_FEATURES)
.chain(SPARC_FEATURES)
.chain(M68K_FEATURES)
.chain(AVR_FEATURES)
.cloned()
.map(|(f, s, _)| (f, s))
}
Expand Down Expand Up @@ -996,12 +1019,8 @@ impl Target {
Arch::S390x => IBMZ_FEATURES,
Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES,
Arch::M68k => M68K_FEATURES,
Arch::AmdGpu
| Arch::Avr
| Arch::Msp430
| Arch::SpirV
| Arch::Xtensa
| Arch::Other(_) => &[],
Arch::Avr => AVR_FEATURES,
Arch::AmdGpu | Arch::Msp430 | Arch::SpirV | Arch::Xtensa | Arch::Other(_) => &[],
}
}

Expand All @@ -1023,11 +1042,11 @@ impl Target {
MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI
}
Arch::AmdGpu => AMDGPU_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
Arch::Nvptx64 | Arch::Bpf | Arch::M68k => &[], // no vector ABI
Arch::Nvptx64 | Arch::Bpf | Arch::M68k | Arch::Avr => &[], // no vector ABI
Arch::CSky => CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
// FIXME: for some tier3 targets, we are overly cautious and always give warnings
// when passing args in vector registers.
Arch::Avr | Arch::Msp430 | Arch::SpirV | Arch::Xtensa | Arch::Other(_) => &[],
Arch::Msp430 | Arch::SpirV | Arch::Xtensa | Arch::Other(_) => &[],
}
}

Expand Down Expand Up @@ -1224,6 +1243,12 @@ impl Target {
// because the vector and float registers overlap.
FeatureConstraints { required: &[], incompatible: &["soft-float"] }
}
Arch::Avr => {
// SRAM is minimum requirement for C/C++ in both avr-gcc and Clang,
// and backends of them only support assembly for devices have no SRAM.
// See the discussion in https://github.com/rust-lang/rust/pull/146900 for more.
FeatureConstraints { required: &["sram"], incompatible: &[] }
}
_ => NOTHING,
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/doc/rustc/src/platform-support/avr-none.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ the possible variants:

https://github.com/llvm/llvm-project/blob/093d4db2f3c874d4683fb01194b00dbb20e5c713/clang/lib/Basic/Targets/AVR.cpp#L32

Note that devices that have no SRAM are not supported, same as when compiling C/C++ programs with avr-gcc or Clang.

## Testing

You can use [`simavr`](https://github.com/buserror/simavr) to emulate the
Expand Down
Loading
Loading