Skip to content

Rollup of 4 pull requests #113114

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
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
42 changes: 39 additions & 3 deletions compiler/rustc_fluent_macro/src/fluent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
let mut previous_defns = HashMap::new();
let mut message_refs = Vec::new();
for entry in resource.entries() {
if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) = entry {
if let Entry::Message(msg) = entry {
let Message { id: Identifier { name }, attributes, value, .. } = msg;
let _ = previous_defns.entry(name.to_string()).or_insert(resource_span);
if name.contains('-') {
Diagnostic::spanned(
Expand Down Expand Up @@ -229,9 +230,10 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
continue;
}

let msg = format!("Constant referring to Fluent message `{name}` from `{crate_name}`");
let docstr =
format!("Constant referring to Fluent message `{name}` from `{crate_name}`");
constants.extend(quote! {
#[doc = #msg]
#[doc = #docstr]
pub const #snake_name: crate::DiagnosticMessage =
crate::DiagnosticMessage::FluentIdentifier(
std::borrow::Cow::Borrowed(#name),
Expand Down Expand Up @@ -269,6 +271,15 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
);
});
}

// Record variables referenced by these messages so we can produce
// tests in the derive diagnostics to validate them.
let ident = quote::format_ident!("{snake_name}_refs");
let vrefs = variable_references(msg);
constants.extend(quote! {
#[cfg(test)]
pub const #ident: &[&str] = &[#(#vrefs),*];
})
}
}

Expand Down Expand Up @@ -334,3 +345,28 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
}
.into()
}

fn variable_references<'a>(msg: &Message<&'a str>) -> Vec<&'a str> {
let mut refs = vec![];
if let Some(Pattern { elements }) = &msg.value {
for elt in elements {
if let PatternElement::Placeable {
expression: Expression::Inline(InlineExpression::VariableReference { id }),
} = elt
{
refs.push(id.name);
}
}
}
for attr in &msg.attributes {
for elt in &attr.value.elements {
if let PatternElement::Placeable {
expression: Expression::Inline(InlineExpression::VariableReference { id }),
} = elt
{
refs.push(id.name);
}
}
}
refs
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ hir_analysis_missing_trait_item_suggestion = implement the missing item: `{$snip

hir_analysis_missing_trait_item_unstable = not all trait items implemented, missing: `{$missing_item_name}`
.note = default implementation of `{$missing_item_name}` is unstable
.some_note = use of unstable library feature '{$feature}': {$r}
.some_note = use of unstable library feature '{$feature}': {$reason}
.none_note = use of unstable library feature '{$feature}'

hir_analysis_missing_type_params =
Expand Down
61 changes: 57 additions & 4 deletions compiler/rustc_macros/src/diagnostics/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#![deny(unused_must_use)]

use std::cell::RefCell;

use crate::diagnostics::diagnostic_builder::{DiagnosticDeriveBuilder, DiagnosticDeriveKind};
use crate::diagnostics::error::{span_err, DiagnosticDeriveError};
use crate::diagnostics::utils::SetOnce;
Expand Down Expand Up @@ -28,6 +30,7 @@ impl<'a> DiagnosticDerive<'a> {
pub(crate) fn into_tokens(self) -> TokenStream {
let DiagnosticDerive { mut structure, mut builder } = self;

let slugs = RefCell::new(Vec::new());
let implementation = builder.each_variant(&mut structure, |mut builder, variant| {
let preamble = builder.preamble(variant);
let body = builder.body(variant);
Expand Down Expand Up @@ -56,6 +59,7 @@ impl<'a> DiagnosticDerive<'a> {
return DiagnosticDeriveError::ErrorHandled.to_compile_error();
}
Some(slug) => {
slugs.borrow_mut().push(slug.clone());
quote! {
let mut #diag = #handler.struct_diagnostic(crate::fluent_generated::#slug);
}
Expand All @@ -73,7 +77,8 @@ impl<'a> DiagnosticDerive<'a> {
});

let DiagnosticDeriveKind::Diagnostic { handler } = &builder.kind else { unreachable!() };
structure.gen_impl(quote! {

let mut imp = structure.gen_impl(quote! {
gen impl<'__diagnostic_handler_sess, G>
rustc_errors::IntoDiagnostic<'__diagnostic_handler_sess, G>
for @Self
Expand All @@ -89,7 +94,11 @@ impl<'a> DiagnosticDerive<'a> {
#implementation
}
}
})
});
for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) {
imp.extend(test);
}
imp
}
}

Expand Down Expand Up @@ -124,6 +133,7 @@ impl<'a> LintDiagnosticDerive<'a> {
}
});

let slugs = RefCell::new(Vec::new());
let msg = builder.each_variant(&mut structure, |mut builder, variant| {
// Collect the slug by generating the preamble.
let _ = builder.preamble(variant);
Expand All @@ -148,6 +158,7 @@ impl<'a> LintDiagnosticDerive<'a> {
DiagnosticDeriveError::ErrorHandled.to_compile_error()
}
Some(slug) => {
slugs.borrow_mut().push(slug.clone());
quote! {
crate::fluent_generated::#slug.into()
}
Expand All @@ -156,7 +167,7 @@ impl<'a> LintDiagnosticDerive<'a> {
});

let diag = &builder.diag;
structure.gen_impl(quote! {
let mut imp = structure.gen_impl(quote! {
gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self {
#[track_caller]
fn decorate_lint<'__b>(
Expand All @@ -171,7 +182,12 @@ impl<'a> LintDiagnosticDerive<'a> {
#msg
}
}
})
});
for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) {
imp.extend(test);
}

imp
}
}

Expand All @@ -198,3 +214,40 @@ impl Mismatch {
}
}
}

/// Generates a `#[test]` that verifies that all referenced variables
/// exist on this structure.
fn generate_test(slug: &syn::Path, structure: &Structure<'_>) -> TokenStream {
// FIXME: We can't identify variables in a subdiagnostic
for field in structure.variants().iter().flat_map(|v| v.ast().fields.iter()) {
for attr_name in field.attrs.iter().filter_map(|at| at.path().get_ident()) {
if attr_name == "subdiagnostic" {
return quote!();
}
}
}
use std::sync::atomic::{AtomicUsize, Ordering};
// We need to make sure that the same diagnostic slug can be used multiple times without causing an
// error, so just have a global counter here.
static COUNTER: AtomicUsize = AtomicUsize::new(0);
let slug = slug.get_ident().unwrap();
let ident = quote::format_ident!("verify_{slug}_{}", COUNTER.fetch_add(1, Ordering::Relaxed));
let ref_slug = quote::format_ident!("{slug}_refs");
let struct_name = &structure.ast().ident;
let variables: Vec<_> = structure
.variants()
.iter()
.flat_map(|v| v.ast().fields.iter().filter_map(|f| f.ident.as_ref().map(|i| i.to_string())))
.collect();
// tidy errors on `#[test]` outside of test files, so we use `#[test ]` to work around this
quote! {
#[cfg(test)]
#[test ]
fn #ident() {
let variables = [#(#variables),*];
for vref in crate::fluent_generated::#ref_slug {
assert!(variables.contains(vref), "{}: variable `{vref}` not found ({})", stringify!(#struct_name), stringify!(#slug));
}
}
}
}
23 changes: 0 additions & 23 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -660,9 +660,6 @@ pub enum ImplSource<'tcx, N> {

/// ImplSource for trait upcasting coercion
TraitUpcasting(ImplSourceTraitUpcastingData<N>),

/// ImplSource for a trait alias.
TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
}

impl<'tcx, N> ImplSource<'tcx, N> {
Expand All @@ -671,7 +668,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::UserDefined(i) => i.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
ImplSource::Object(d) => d.nested,
ImplSource::TraitAlias(d) => d.nested,
ImplSource::TraitUpcasting(d) => d.nested,
}
}
Expand All @@ -681,7 +677,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::UserDefined(i) => &i.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n,
ImplSource::Object(d) => &d.nested,
ImplSource::TraitAlias(d) => &d.nested,
ImplSource::TraitUpcasting(d) => &d.nested,
}
}
Expand All @@ -691,7 +686,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::UserDefined(i) => &mut i.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
ImplSource::Object(d) => &mut d.nested,
ImplSource::TraitAlias(d) => &mut d.nested,
ImplSource::TraitUpcasting(d) => &mut d.nested,
}
}
Expand All @@ -709,15 +703,9 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()),
ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
upcast_trait_def_id: o.upcast_trait_def_id,
vtable_base: o.vtable_base,
nested: o.nested.into_iter().map(f).collect(),
}),
ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
alias_def_id: d.alias_def_id,
substs: d.substs,
nested: d.nested.into_iter().map(f).collect(),
}),
ImplSource::TraitUpcasting(d) => {
ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData {
vtable_vptr_slot: d.vtable_vptr_slot,
Expand Down Expand Up @@ -761,9 +749,6 @@ pub struct ImplSourceTraitUpcastingData<N> {
#[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceObjectData<N> {
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
pub upcast_trait_def_id: DefId,

/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits, pointers to supertrait vtable will
/// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
Expand All @@ -773,14 +758,6 @@ pub struct ImplSourceObjectData<N> {
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceTraitAliasData<'tcx, N> {
pub alias_def_id: DefId,
pub substs: SubstsRef<'tcx>,
pub nested: Vec<N>,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
pub enum ObjectSafetyViolation {
/// `Self: Sized` declared on the trait.
Expand Down
16 changes: 2 additions & 14 deletions compiler/rustc_middle/src/traits/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
write!(f, "ImplSourceParamData({:?}, {:?})", n, ct)
}

super::ImplSource::TraitAlias(ref d) => write!(f, "{:?}", d),

super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
}
}
Expand Down Expand Up @@ -48,18 +46,8 @@ impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"ImplSourceObjectData(upcast={:?}, vtable_base={}, nested={:?})",
self.upcast_trait_def_id, self.vtable_base, self.nested
)
}
}

impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx, N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"ImplSourceTraitAliasData(alias_def_id={:?}, substs={:?}, nested={:?})",
self.alias_def_id, self.substs, self.nested
"ImplSourceObjectData(vtable_base={}, nested={:?})",
self.vtable_base, self.nested
)
}
}
8 changes: 0 additions & 8 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1150,14 +1150,6 @@ pub struct UnixSigpipeValues {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_no_main_function, code = "E0601")]
pub struct NoMainFunction {
#[primary_span]
pub span: Span,
pub crate_name: String,
}

pub struct NoMainErr {
pub sp: Span,
pub crate_name: Symbol,
Expand Down
Loading