diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index 9dffc9a764548..56e23ac277520 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,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),*]; + }) } } @@ -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 +} diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index cd6cf36baa44d..edc6bcacc6831 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 12a954258d1de..04b7c5feebe56 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! { + + 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,11 @@ impl<'a> DiagnosticDerive<'a> { #implementation } } - }) + }); + for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { + imp.extend(test); + } + imp } } @@ -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); @@ -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() } @@ -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>( @@ -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 } } @@ -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)); + } + } + } +} diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index f03802049707c..a333fbbb50671 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, } } @@ -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, @@ -761,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 @@ -773,14 +758,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..a703e3c956228 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), } } @@ -48,18 +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 - ) - } -} - -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 ) } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 7890c93d5ff0a..3fe7feb9dfa16 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -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, 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 f93d6b1ce88ed..c259260c1faf8 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}; @@ -2272,55 +2272,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/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index c84c75cecdfe3..60712ad05f154 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1720,7 +1720,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 @@ -2012,8 +2011,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 c94fddc124ff7..cc6521f3b50e7 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 => { @@ -652,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( @@ -721,10 +716,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 +735,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_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 72adf3106ab17..b6c64c0196aec 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) 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, }) } 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 759c4fd601226..d4ec9c34b6ffa 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") %} {# #} diff --git a/tests/run-make/rustdoc-themes/foo.rs b/tests/run-make/rustdoc-themes/foo.rs index 995544aeff998..8b1e75b0ae13b 100644 --- a/tests/run-make/rustdoc-themes/foo.rs +++ b/tests/run-make/rustdoc-themes/foo.rs @@ -1,4 +1,4 @@ // @has test.css // @has foo/struct.Foo.html -// @has - '//*[@id="rustdoc-vars"]/@data-themes' 'test' +// @has - '//*[@name="rustdoc-vars"]/@data-themes' 'test' pub struct Foo; 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; 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 { 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 | 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",