From 9b5574f028c75d794b51c96ff6471ddf756f329b Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 5 May 2023 21:26:42 +0100 Subject: [PATCH 1/9] Validate fluent variable references with `debug_assertions` --- compiler/rustc_fluent_macro/src/fluent.rs | 45 +++++++++++- .../src/diagnostics/diagnostic.rs | 68 +++++++++++++++++-- 2 files changed, 106 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index 9dffc9a764548..b1c83e0dedced 100644 --- a/compiler/rustc_fluent_macro/src/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -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( @@ -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), @@ -269,6 +271,17 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok ); }); } + #[cfg(debug_assertions)] + { + // 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),*]; + }) + } } } @@ -334,3 +347,29 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok } .into() } + +#[cfg(debug_assertions)] +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 +} diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 12a954258d1de..b9eba65f66a30 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -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; @@ -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); @@ -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); } @@ -73,7 +77,8 @@ impl<'a> DiagnosticDerive<'a> { }); let DiagnosticDeriveKind::Diagnostic { handler } = &builder.kind else { unreachable!() }; - structure.gen_impl(quote! { + #[allow(unused_mut)] + let mut imp = structure.gen_impl(quote! { gen impl<'__diagnostic_handler_sess, G> rustc_errors::IntoDiagnostic<'__diagnostic_handler_sess, G> for @Self @@ -89,7 +94,14 @@ impl<'a> DiagnosticDerive<'a> { #implementation } } - }) + }); + #[cfg(debug_assertions)] + { + for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { + imp.extend(test); + } + } + imp } } @@ -124,6 +136,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); @@ -148,6 +161,7 @@ impl<'a> LintDiagnosticDerive<'a> { DiagnosticDeriveError::ErrorHandled.to_compile_error() } Some(slug) => { + slugs.borrow_mut().push(slug.clone()); quote! { crate::fluent_generated::#slug.into() } @@ -156,7 +170,8 @@ impl<'a> LintDiagnosticDerive<'a> { }); let diag = &builder.diag; - structure.gen_impl(quote! { + #[allow(unused_mut)] + let mut imp = structure.gen_impl(quote! { gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self { #[track_caller] fn decorate_lint<'__b>( @@ -171,7 +186,14 @@ impl<'a> LintDiagnosticDerive<'a> { #msg } } - }) + }); + #[cfg(debug_assertions)] + { + for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { + imp.extend(test); + } + } + imp } } @@ -198,3 +220,41 @@ impl Mismatch { } } } + +/// Generates a `#[test]` that verifies that all referenced variables +/// exist on this structure. +#[cfg(debug_assertions)] +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)); + } + } + } +} From 220bb61b3317340d01d95aad4f4d30cca91943f2 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 6 May 2023 00:29:52 +0100 Subject: [PATCH 2/9] Fix diagnostics with errors --- compiler/rustc_fluent_macro/src/fluent.rs | 21 ++++++++----------- compiler/rustc_hir_analysis/messages.ftl | 2 +- .../src/diagnostics/diagnostic.rs | 19 ++++++----------- compiler/rustc_passes/src/errors.rs | 8 ------- .../auxiliary/default_body.rs | 4 ++++ .../default-body-stability-err.rs | 1 + .../default-body-stability-err.stderr | 14 +++++++++++-- .../default-body-stability-ok-impls.rs | 2 ++ 8 files changed, 35 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index b1c83e0dedced..56e23ac277520 100644 --- a/compiler/rustc_fluent_macro/src/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -271,17 +271,15 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok ); }); } - #[cfg(debug_assertions)] - { - // 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),*]; - }) - } + + // 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),*]; + }) } } @@ -348,7 +346,6 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok .into() } -#[cfg(debug_assertions)] fn variable_references<'a>(msg: &Message<&'a str>) -> Vec<&'a str> { let mut refs = vec![]; if let Some(Pattern { elements }) = &msg.value { diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 02d1dfcd1134c..5225fee4916ad 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -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 = diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index b9eba65f66a30..04b7c5feebe56 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -77,7 +77,7 @@ impl<'a> DiagnosticDerive<'a> { }); let DiagnosticDeriveKind::Diagnostic { handler } = &builder.kind else { unreachable!() }; - #[allow(unused_mut)] + let mut imp = structure.gen_impl(quote! { gen impl<'__diagnostic_handler_sess, G> rustc_errors::IntoDiagnostic<'__diagnostic_handler_sess, G> @@ -95,11 +95,8 @@ impl<'a> DiagnosticDerive<'a> { } } }); - #[cfg(debug_assertions)] - { - for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { - imp.extend(test); - } + for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { + imp.extend(test); } imp } @@ -170,7 +167,6 @@ impl<'a> LintDiagnosticDerive<'a> { }); let diag = &builder.diag; - #[allow(unused_mut)] let mut imp = structure.gen_impl(quote! { gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self { #[track_caller] @@ -187,12 +183,10 @@ impl<'a> LintDiagnosticDerive<'a> { } } }); - #[cfg(debug_assertions)] - { - for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { - imp.extend(test); - } + for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { + imp.extend(test); } + imp } } @@ -223,7 +217,6 @@ impl Mismatch { /// Generates a `#[test]` that verifies that all referenced variables /// exist on this structure. -#[cfg(debug_assertions)] 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()) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 99fc69d1bec7b..4d9254a0a45d2 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1153,14 +1153,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, diff --git a/tests/ui/stability-attribute/auxiliary/default_body.rs b/tests/ui/stability-attribute/auxiliary/default_body.rs index 3a177419d666d..2f315eb1bc8fc 100644 --- a/tests/ui/stability-attribute/auxiliary/default_body.rs +++ b/tests/ui/stability-attribute/auxiliary/default_body.rs @@ -11,6 +11,10 @@ pub trait JustTrait { #[rustc_default_body_unstable(feature = "fun_default_body", issue = "none")] #[stable(feature = "stable_feature", since = "1.0.0")] fn fun() {} + + #[rustc_default_body_unstable(feature = "fun_default_body", issue = "none", reason = "reason")] + #[stable(feature = "stable_feature", since = "1.0.0")] + fn fun2() {} } #[rustc_must_implement_one_of(eq, neq)] diff --git a/tests/ui/stability-attribute/default-body-stability-err.rs b/tests/ui/stability-attribute/default-body-stability-err.rs index ecb281bccf604..d1a3597687d7d 100644 --- a/tests/ui/stability-attribute/default-body-stability-err.rs +++ b/tests/ui/stability-attribute/default-body-stability-err.rs @@ -10,6 +10,7 @@ struct Type; impl JustTrait for Type {} //~^ ERROR not all trait items implemented, missing: `CONSTANT` [E0046] //~| ERROR not all trait items implemented, missing: `fun` [E0046] +//~| ERROR not all trait items implemented, missing: `fun2` [E0046] impl Equal for Type { //~^ ERROR not all trait items implemented, missing: `eq` [E0046] diff --git a/tests/ui/stability-attribute/default-body-stability-err.stderr b/tests/ui/stability-attribute/default-body-stability-err.stderr index ef666f30fc2a2..12ec9ea3adb41 100644 --- a/tests/ui/stability-attribute/default-body-stability-err.stderr +++ b/tests/ui/stability-attribute/default-body-stability-err.stderr @@ -18,8 +18,18 @@ LL | impl JustTrait for Type {} = note: use of unstable library feature 'fun_default_body' = help: add `#![feature(fun_default_body)]` to the crate attributes to enable +error[E0046]: not all trait items implemented, missing: `fun2` + --> $DIR/default-body-stability-err.rs:10:1 + | +LL | impl JustTrait for Type {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: default implementation of `fun2` is unstable + = note: use of unstable library feature 'fun_default_body': reason + = help: add `#![feature(fun_default_body)]` to the crate attributes to enable + error[E0046]: not all trait items implemented, missing: `eq` - --> $DIR/default-body-stability-err.rs:14:1 + --> $DIR/default-body-stability-err.rs:15:1 | LL | / impl Equal for Type { LL | | @@ -33,6 +43,6 @@ LL | | } = note: use of unstable library feature 'eq_default_body' = help: add `#![feature(eq_default_body)]` to the crate attributes to enable -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/stability-attribute/default-body-stability-ok-impls.rs b/tests/ui/stability-attribute/default-body-stability-ok-impls.rs index e1f5c017096ab..b29d45256bf39 100644 --- a/tests/ui/stability-attribute/default-body-stability-ok-impls.rs +++ b/tests/ui/stability-attribute/default-body-stability-ok-impls.rs @@ -12,6 +12,8 @@ impl JustTrait for Type { const CONSTANT: usize = 1; fn fun() {} + + fn fun2() {} } impl Equal for Type { From db235a07f79a34fe9e40bb122d6ae78f05bc2623 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 20 Jun 2023 20:00:39 +0000 Subject: [PATCH 3/9] Remove unnecessary call to select_from_obligation The only regression is one ambiguity in the new trait solver, having to do with two param-env candidates that may apply. I think this is fine, since the error message already kinda sucks. --- .../src/traits/error_reporting/mod.rs | 83 ++++++++----------- ...tion-param-candidates-are-ambiguous.stderr | 1 + 2 files changed, 35 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 398ec28a42638..75aee0670a258 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -5,7 +5,7 @@ pub mod suggestions; use super::{ FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow, - PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe, + PredicateObligation, SelectionError, TraitNotObjectSafe, }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -2269,55 +2269,40 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) }; - let obligation = obligation.with(self.tcx, trait_ref); - let mut selcx = SelectionContext::new(&self); - match selcx.select_from_obligation(&obligation) { - Ok(None) => { - let ambiguities = - ambiguity::recompute_applicable_impls(self.infcx, &obligation); - let has_non_region_infer = trait_ref - .skip_binder() - .substs - .types() - .any(|t| !t.is_ty_or_numeric_infer()); - // It doesn't make sense to talk about applicable impls if there are more - // than a handful of them. - if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer { - if self.tainted_by_errors().is_some() && subst.is_none() { - // If `subst.is_none()`, then this is probably two param-env - // candidates or impl candidates that are equal modulo lifetimes. - // Therefore, if we've already emitted an error, just skip this - // one, since it's not particularly actionable. - err.cancel(); - return; - } - self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate); - } else { - if self.tainted_by_errors().is_some() { - err.cancel(); - return; - } - err.note(format!("cannot satisfy `{}`", predicate)); - let impl_candidates = self.find_similar_impl_candidates( - predicate.to_opt_poly_trait_pred().unwrap(), - ); - if impl_candidates.len() < 10 { - self.report_similar_impl_candidates( - impl_candidates.as_slice(), - trait_ref, - obligation.cause.body_id, - &mut err, - false, - ); - } - } + let ambiguities = ambiguity::recompute_applicable_impls( + self.infcx, + &obligation.with(self.tcx, trait_ref), + ); + let has_non_region_infer = + trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_or_numeric_infer()); + // It doesn't make sense to talk about applicable impls if there are more + // than a handful of them. + if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer { + if self.tainted_by_errors().is_some() && subst.is_none() { + // If `subst.is_none()`, then this is probably two param-env + // candidates or impl candidates that are equal modulo lifetimes. + // Therefore, if we've already emitted an error, just skip this + // one, since it's not particularly actionable. + err.cancel(); + return; } - _ => { - if self.tainted_by_errors().is_some() { - err.cancel(); - return; - } - err.note(format!("cannot satisfy `{}`", predicate)); + self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate); + } else { + if self.tainted_by_errors().is_some() { + err.cancel(); + return; + } + err.note(format!("cannot satisfy `{}`", predicate)); + let impl_candidates = self + .find_similar_impl_candidates(predicate.to_opt_poly_trait_pred().unwrap()); + if impl_candidates.len() < 10 { + self.report_similar_impl_candidates( + impl_candidates.as_slice(), + trait_ref, + obligation.cause.body_id, + &mut err, + false, + ); } } diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr index fa5e780ee5e8b..83a0452b088d2 100644 --- a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr +++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr @@ -5,6 +5,7 @@ LL | needs_bar::(); | ^^^^^^^^^^^^^^ | = note: cannot satisfy `T: Bar` + = help: the trait `Bar` is implemented for `T` note: required by a bound in `needs_bar` --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17 | From 42571c4847692edc050288372a107e51ab4a9ce4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 20 Jun 2023 21:27:43 +0000 Subject: [PATCH 4/9] yeet ImplSource::TraitAlias too --- compiler/rustc_middle/src/traits/mod.rs | 19 ------------------- .../src/traits/structural_impls.rs | 12 ------------ .../src/traits/project.rs | 4 +--- .../src/traits/select/confirmation.rs | 14 ++++++-------- compiler/rustc_ty_utils/src/instance.rs | 4 +--- 5 files changed, 8 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index f03802049707c..f2bda4adf48e7 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -660,9 +660,6 @@ pub enum ImplSource<'tcx, N> { /// ImplSource for trait upcasting coercion TraitUpcasting(ImplSourceTraitUpcastingData), - - /// ImplSource for a trait alias. - TraitAlias(ImplSourceTraitAliasData<'tcx, N>), } impl<'tcx, N> ImplSource<'tcx, N> { @@ -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, } } @@ -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, } } @@ -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, } } @@ -713,11 +707,6 @@ impl<'tcx, N> ImplSource<'tcx, N> { 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, @@ -773,14 +762,6 @@ pub struct ImplSourceObjectData { pub nested: Vec, } -#[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, -} - #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] pub enum ObjectSafetyViolation { /// `Self: Sized` declared on the trait. diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index ac02d6ed62f2e..1a89560188a91 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -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), } } @@ -53,13 +51,3 @@ impl fmt::Debug for traits::ImplSourceObjectData { ) } } - -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 - ) - } -} diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index eb4cb88fb0b1e..bdffb9235e5b2 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1721,7 +1721,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( }; let eligible = match &impl_source { - super::ImplSource::TraitAlias(_) => true, super::ImplSource::UserDefined(impl_data) => { // We have to be careful when projecting out of an // impl because of specialization. If we are not in @@ -2013,8 +2012,7 @@ fn confirm_select_candidate<'cx, 'tcx>( } super::ImplSource::Object(_) | super::ImplSource::Param(..) - | super::ImplSource::TraitUpcasting(_) - | super::ImplSource::TraitAlias(..) => { + | super::ImplSource::TraitUpcasting(_) => { // we don't create Select candidates with this kind of resolution span_bug!( obligation.cause.span, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3c356978d5ca8..88941a7575534 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -27,10 +27,9 @@ use crate::traits::vtable::{ }; use crate::traits::{ BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource, - ImplSourceObjectData, ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, - ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause, - OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError, - TraitNotObjectSafe, TraitObligation, Unimplemented, + ImplSourceObjectData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, + Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, + SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, }; use super::BuiltinImplConditions; @@ -105,7 +104,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { TraitAliasCandidate => { let data = self.confirm_trait_alias_candidate(obligation); - ImplSource::TraitAlias(data) + ImplSource::Builtin(data) } BuiltinObjectCandidate => { @@ -721,10 +720,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_trait_alias_candidate( &mut self, obligation: &TraitObligation<'tcx>, - ) -> ImplSourceTraitAliasData<'tcx, PredicateObligation<'tcx>> { + ) -> Vec> { debug!(?obligation, "confirm_trait_alias_candidate"); - let alias_def_id = obligation.predicate.def_id(); let predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate); let trait_ref = predicate.trait_ref; let trait_def_id = trait_ref.def_id; @@ -741,7 +739,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?trait_def_id, ?trait_obligations, "trait alias obligations"); - ImplSourceTraitAliasData { alias_def_id, substs, nested: trait_obligations } + trait_obligations } fn confirm_generator_candidate( diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 45b1075b6023a..2d75862014d0b 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -293,9 +293,7 @@ fn resolve_associated_item<'tcx>( None } } - traits::ImplSource::Param(..) - | traits::ImplSource::TraitAlias(..) - | traits::ImplSource::TraitUpcasting(_) => None, + traits::ImplSource::Param(..) | traits::ImplSource::TraitUpcasting(_) => None, }) } From 7d0a5c31f5b3b4b1dc47ce51898be8895c9f4637 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 20 Jun 2023 21:48:05 +0000 Subject: [PATCH 5/9] yeet upcast_trait_def_id from ImplSourceObjectData --- compiler/rustc_middle/src/traits/mod.rs | 4 ---- compiler/rustc_middle/src/traits/structural_impls.rs | 4 ++-- .../rustc_trait_selection/src/traits/select/confirmation.rs | 6 +----- compiler/rustc_trait_selection/src/traits/util.rs | 2 +- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index f2bda4adf48e7..a333fbbb50671 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -703,7 +703,6 @@ 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(), }), @@ -750,9 +749,6 @@ pub struct ImplSourceTraitUpcastingData { #[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)] #[derive(TypeFoldable, TypeVisitable)] pub struct ImplSourceObjectData { - /// `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 diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index 1a89560188a91..a703e3c956228 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -46,8 +46,8 @@ impl fmt::Debug for traits::ImplSourceObjectData { 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 + "ImplSourceObjectData(vtable_base={}, nested={:?})", + self.vtable_base, self.nested ) } } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 88941a7575534..bf485ee7b53ae 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -651,11 +651,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { (unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)), ); - Ok(ImplSourceObjectData { - upcast_trait_def_id: upcast_trait_ref.def_id(), - vtable_base, - nested, - }) + Ok(ImplSourceObjectData { vtable_base, nested }) } fn confirm_fn_pointer_candidate( diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 906c357e8ca7e..4dc2f26a8ed17 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -248,7 +248,7 @@ pub fn get_vtable_index_of_object_method<'tcx, N>( ) -> Option { // Count number of methods preceding the one we are selecting and // add them to the total offset. - tcx.own_existential_vtable_entries(object.upcast_trait_def_id) + tcx.own_existential_vtable_entries(tcx.parent(method_def_id)) .iter() .copied() .position(|def_id| def_id == method_def_id) From 8969d974377b17861970d161a46a0fc80e3d34ad Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 23 Jun 2023 14:20:45 +0000 Subject: [PATCH 6/9] Add test for invalid variables --- .../session-diagnostic/example.ftl | 2 ++ .../session-diagnostic/invalid-variable.rs | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/ui-fulldeps/session-diagnostic/invalid-variable.rs diff --git a/tests/ui-fulldeps/session-diagnostic/example.ftl b/tests/ui-fulldeps/session-diagnostic/example.ftl index cb2d476d815d2..1d1ba8e1bd5cd 100644 --- a/tests/ui-fulldeps/session-diagnostic/example.ftl +++ b/tests/ui-fulldeps/session-diagnostic/example.ftl @@ -3,3 +3,5 @@ no_crate_example = this is an example message used in testing .help = with a help .suggestion = with a suggestion .label = with a label + +no_crate_bad_reference = {$r} does not exist diff --git a/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs b/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs new file mode 100644 index 0000000000000..57798dda3eb24 --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs @@ -0,0 +1,21 @@ +// run-fail +// compile-flags: --test +// test that messages referencing non-existent fields cause test failures + +#![feature(rustc_private)] +#![crate_type = "lib"] + +extern crate rustc_driver; +extern crate rustc_fluent_macro; +extern crate rustc_macros; +extern crate rustc_errors; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::Diagnostic; +use rustc_errors::{SubdiagnosticMessage, DiagnosticMessage}; +extern crate rustc_session; + +fluent_messages! { "./example.ftl" } + +#[derive(Diagnostic)] +#[diag(no_crate_bad_reference)] +struct BadRef; From b8e4c54ffb38885a9abd11ce2903af85cb62861f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 27 Jun 2023 14:33:04 +0200 Subject: [PATCH 7/9] Fix invalid HTML DIV tag used in HEAD --- src/librustdoc/html/templates/page.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 759c4fd601226..24f045f5ce3bf 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -24,7 +24,7 @@ {% endfor %} > {# #} {% endif %} -
{# #} -
{# #} {# #} {% if page.css_class.contains("crate") %} {# #} From acbfb8c3bdbcb29b23b11221ae2ec1386b061aa7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 27 Jun 2023 17:18:50 +0200 Subject: [PATCH 8/9] Replace `id` attribute with `name` for `` tag --- src/librustdoc/html/markdown.rs | 1 - src/librustdoc/html/static/js/source-script.js | 4 ++-- src/librustdoc/html/static/js/storage.js | 2 +- src/librustdoc/html/templates/page.html | 2 +- tests/run-make/rustdoc-themes/foo.rs | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 1c27320024a9f..fd00277e2137d 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1525,7 +1525,6 @@ fn init_id_map() -> FxHashMap, usize> { map.insert("toggle-all-docs".into(), 1); map.insert("all-types".into(), 1); map.insert("default-settings".into(), 1); - map.insert("rustdoc-vars".into(), 1); map.insert("sidebar-vars".into(), 1); map.insert("copy-path".into(), 1); map.insert("TOC".into(), 1); diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index d999f3b36fd82..6eb991360404a 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -3,13 +3,13 @@ // Local js definitions: /* global addClass, getCurrentValue, onEachLazy, removeClass, browserSupportsHistoryApi */ -/* global updateLocalStorage */ +/* global updateLocalStorage, getVar */ "use strict"; (function() { -const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value; +const rootPath = getVar("root-path"); const NAME_OFFSET = 0; const DIRS_OFFSET = 1; diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 93979a944183b..71961f6f2a9c3 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -108,7 +108,7 @@ function getCurrentValue(name) { // Get a value from the rustdoc-vars div, which is used to convey data from // Rust to the JS. If there is no such element, return null. const getVar = (function getVar(name) { - const el = document.getElementById("rustdoc-vars"); + const el = document.querySelector("head > meta[name='rustdoc-vars']"); return el ? el.attributes["data-" + name].value : null; }); diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 24f045f5ce3bf..d4ec9c34b6ffa 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -24,7 +24,7 @@ {% endfor %} > {# #} {% endif %} - Date: Tue, 27 Jun 2023 23:52:10 +0100 Subject: [PATCH 9/9] add boxy to t-types review --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 9248e8fc28a13..4bab8facc85b0 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -581,6 +581,7 @@ types = [ "@lcnr", "@oli-obk", "@spastorino", + "@BoxyUwU", ] borrowck = [ "@davidtwco",