diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 365cd55bdc38b..6375927b01de4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1,4 +1,5 @@ use rustc_ast::{LitIntType, LitKind, MetaItemLit}; +use rustc_hir::attrs::RustcLayoutType; use rustc_session::errors; use super::prelude::*; @@ -329,3 +330,61 @@ impl NoArgsAttributeParser for RustcOffloadKernelParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOffloadKernel; } + +pub(crate) struct RustcLayoutParser; + +impl CombineAttributeParser for RustcLayoutParser { + const PATH: &[rustc_span::Symbol] = &[sym::rustc_layout]; + + type Item = RustcLayoutType; + + const CONVERT: ConvertFn = |items, _| AttributeKind::RustcLayout(items); + + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Struct), + Allow(Target::Enum), + Allow(Target::Union), + Allow(Target::TyAlias), + ]); + + const TEMPLATE: AttributeTemplate = + template!(List: &["abi", "align", "size", "homogenous_aggregate", "debug"]); + + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { + let ArgParser::List(items) = args else { + cx.expected_list(cx.attr_span, args); + return vec![]; + }; + + let mut result = Vec::new(); + for item in items.mixed() { + let Some(arg) = item.meta_item() else { + cx.unexpected_literal(item.span()); + continue; + }; + let Some(ident) = arg.ident() else { + cx.expected_identifier(arg.span()); + return vec![]; + }; + let ty = match ident.name { + sym::abi => RustcLayoutType::Abi, + sym::align => RustcLayoutType::Align, + sym::size => RustcLayoutType::Size, + sym::homogeneous_aggregate => RustcLayoutType::HomogenousAggregate, + sym::debug => RustcLayoutType::Debug, + _ => { + cx.expected_specific_argument( + ident.span, + &[sym::abi, sym::align, sym::size, sym::homogeneous_aggregate, sym::debug], + ); + continue; + } + }; + result.push(ty); + } + result + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 20bdfa45a013d..a4d08de515adb 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -75,7 +75,7 @@ use crate::attributes::rustc_dump::{ RustcDumpVtable, }; use crate::attributes::rustc_internal::{ - RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser, + RustcHasIncoherentInherentImplsParser, RustcLayoutParser, RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser, @@ -198,6 +198,7 @@ attribute_parsers!( Combine, Combine, Combine, + Combine, Combine, Combine, // tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index ef9ee4b6fb2d0..bc58f1d8faa5d 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -690,6 +690,15 @@ impl IntoDiagArg for CrateType { } } +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub enum RustcLayoutType { + Abi, + Align, + Size, + HomogenousAggregate, + Debug, +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -1048,6 +1057,9 @@ pub enum AttributeKind { /// Represents `#[rustc_has_incoherent_inherent_impls]` RustcHasIncoherentInherentImpls, + /// Represents `#[rustc_layout]` + RustcLayout(ThinVec), + /// Represents `#[rustc_layout_scalar_valid_range_end]`. RustcLayoutScalarValidRangeEnd(Box, Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 631b07ff1da29..4fd0f5698a8bd 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -111,6 +111,7 @@ impl AttributeKind { RustcDumpVtable(..) => No, RustcDynIncompatibleTrait(..) => No, RustcHasIncoherentInherentImpls => Yes, + RustcLayout(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 1ad9bbc3b4b30..0cac699e5b626 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -280,31 +280,21 @@ fn add_query_desc_cached_impl( let crate::query::Providers { #name: _, .. }; }; - // Find out if we should cache the query on disk - let cache = if let Some((args, expr)) = modifiers.cache.as_ref() { + // Generate a function to check whether we should cache the query to disk, for some key. + if let Some((args, expr)) = modifiers.cache.as_ref() { let tcx = args.as_ref().map(|t| quote! { #t }).unwrap_or_else(|| quote! { _ }); // expr is a `Block`, meaning that `{ #expr }` gets expanded // to `{ { stmts... } }`, which triggers the `unused_braces` lint. // we're taking `key` by reference, but some rustc types usually prefer being passed by value - quote! { + cached.extend(quote! { #[allow(unused_variables, unused_braces, rustc::pass_by_value)] #[inline] pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::query::queries::#name::Key<'tcx>) -> bool { #ra_hint #expr } - } - } else { - quote! { - // we're taking `key` by reference, but some rustc types usually prefer being passed by value - #[allow(rustc::pass_by_value)] - #[inline] - pub fn #name<'tcx>(_: TyCtxt<'tcx>, _: &crate::query::queries::#name::Key<'tcx>) -> bool { - #ra_hint - false - } - } - }; + }); + } let (tcx, desc) = &modifiers.desc; let tcx = tcx.as_ref().map_or_else(|| quote! { _ }, |t| quote! { #t }); @@ -322,10 +312,6 @@ fn add_query_desc_cached_impl( descs.extend(quote! { #desc }); - - cached.extend(quote! { - #cache - }); } pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 2bda014a19fe7..b21db6eeeea07 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -18,6 +18,18 @@ use crate::query::{ }; use crate::ty::TyCtxt; +pub type WillCacheOnDiskForKeyFn<'tcx, Key> = fn(tcx: TyCtxt<'tcx>, key: &Key) -> bool; + +pub type TryLoadFromDiskFn<'tcx, Key, Value> = fn( + tcx: TyCtxt<'tcx>, + key: &Key, + prev_index: SerializedDepNodeIndex, + index: DepNodeIndex, +) -> Option; + +pub type IsLoadableFromDiskFn<'tcx, Key> = + fn(tcx: TyCtxt<'tcx>, key: &Key, index: SerializedDepNodeIndex) -> bool; + /// Stores function pointers and other metadata for a particular query. /// /// Used indirectly by query plumbing in `rustc_query_system`, via a trait. @@ -31,18 +43,11 @@ pub struct QueryVTable<'tcx, C: QueryCache> { pub query_state: usize, // Offset of this query's cache field in the QueryCaches struct pub query_cache: usize, - pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool, + pub will_cache_on_disk_for_key_fn: Option>, pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value, pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value, - pub can_load_from_disk: bool, - pub try_load_from_disk: fn( - tcx: TyCtxt<'tcx>, - key: &C::Key, - prev_index: SerializedDepNodeIndex, - index: DepNodeIndex, - ) -> Option, - pub loadable_from_disk: - fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool, + pub try_load_from_disk_fn: Option>, + pub is_loadable_from_disk_fn: Option>, pub hash_result: HashResult, pub value_from_cycle_error: fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value, diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 395d940ddae62..f8ff46189c052 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -302,8 +302,6 @@ passes_layout_align = align: {$align} passes_layout_homogeneous_aggregate = homogeneous_aggregate: {$homogeneous_aggregate} -passes_layout_invalid_attribute = - `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases passes_layout_of = layout_of({$normalized_ty}) = {$ty_layout} passes_layout_size = diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 541870607b63d..800965f81d3db 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -299,6 +299,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDumpVtable(..) | AttributeKind::RustcDynIncompatibleTrait(..) | AttributeKind::RustcHasIncoherentInherentImpls + | AttributeKind::RustcLayout(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLintOptDenyFieldAccess { .. } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index bf9b615546d89..29688dd4d5377 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -519,13 +519,6 @@ pub(crate) struct LayoutOf<'tcx> { pub ty_layout: String, } -#[derive(Diagnostic)] -#[diag(passes_layout_invalid_attribute)] -pub(crate) struct LayoutInvalidAttribute { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(passes_abi_of)] pub(crate) struct AbiOf { diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 4054cfa56330e..354a98d6d0dc7 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -1,20 +1,18 @@ use rustc_abi::{HasDataLayout, TargetDataLayout}; -use rustc_hir::Attribute; +use rustc_hir::attrs::{AttributeKind, RustcLayoutType}; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_hir::find_attr; use rustc_middle::span_bug; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers}; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::Span; use rustc_span::source_map::Spanned; -use rustc_span::{Span, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::TyCtxtInferExt; use rustc_trait_selection::traits; -use crate::errors::{ - LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf, - LayoutSize, UnrecognizedArgument, -}; +use crate::errors::{LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutOf, LayoutSize}; pub fn test_layout(tcx: TyCtxt<'_>) { if !tcx.features().rustc_attrs() { @@ -22,14 +20,14 @@ pub fn test_layout(tcx: TyCtxt<'_>) { return; } for id in tcx.hir_crate_items(()).definitions() { - for attr in tcx.get_attrs(id, sym::rustc_layout) { - match tcx.def_kind(id) { - DefKind::TyAlias | DefKind::Enum | DefKind::Struct | DefKind::Union => { - dump_layout_of(tcx, id, attr); - } - _ => { - tcx.dcx().emit_err(LayoutInvalidAttribute { span: tcx.def_span(id) }); - } + let attrs = tcx.get_all_attrs(id); + if let Some(attrs) = find_attr!(attrs, AttributeKind::RustcLayout(attrs) => attrs) { + // Attribute parsing handles error reporting + if matches!( + tcx.def_kind(id), + DefKind::TyAlias | DefKind::Enum | DefKind::Struct | DefKind::Union + ) { + dump_layout_of(tcx, id, attrs); } } } @@ -66,7 +64,7 @@ pub fn ensure_wf<'tcx>( } } -fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { +fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attrs: &[RustcLayoutType]) { let typing_env = ty::TypingEnv::post_analysis(tcx, item_def_id); let ty = tcx.type_of(item_def_id).instantiate_identity(); let span = tcx.def_span(item_def_id.to_def_id()); @@ -75,32 +73,29 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { } match tcx.layout_of(typing_env.as_query_input(ty)) { Ok(ty_layout) => { - // Check out the `#[rustc_layout(..)]` attribute to tell what to dump. - // The `..` are the names of fields to dump. - let meta_items = attr.meta_item_list().unwrap_or_default(); - for meta_item in meta_items { - match meta_item.name() { + for attr in attrs { + match attr { // FIXME: this never was about ABI and now this dump arg is confusing - Some(sym::abi) => { + RustcLayoutType::Abi => { tcx.dcx().emit_err(LayoutAbi { span, abi: format!("{:?}", ty_layout.backend_repr), }); } - Some(sym::align) => { + RustcLayoutType::Align => { tcx.dcx().emit_err(LayoutAlign { span, align: format!("{:?}", ty_layout.align), }); } - Some(sym::size) => { + RustcLayoutType::Size => { tcx.dcx() .emit_err(LayoutSize { span, size: format!("{:?}", ty_layout.size) }); } - Some(sym::homogeneous_aggregate) => { + RustcLayoutType::HomogenousAggregate => { tcx.dcx().emit_err(LayoutHomogeneousAggregate { span, homogeneous_aggregate: format!( @@ -111,16 +106,12 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { }); } - Some(sym::debug) => { + RustcLayoutType::Debug => { let normalized_ty = tcx.normalize_erasing_regions(typing_env, ty); // FIXME: using the `Debug` impl here isn't ideal. let ty_layout = format!("{:#?}", *ty_layout); tcx.dcx().emit_err(LayoutOf { span, normalized_ty, ty_layout }); } - - _ => { - tcx.dcx().emit_err(UnrecognizedArgument { span: meta_item.span() }); - } } } } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 8fa4fb3090dbd..4e79d0842da22 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -81,8 +81,8 @@ where } #[inline(always)] - fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool { - (self.vtable.cache_on_disk)(tcx, key) + fn will_cache_on_disk_for_key(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool { + self.vtable.will_cache_on_disk_for_key_fn.map_or(false, |f| f(tcx, key)) } #[inline(always)] @@ -128,21 +128,18 @@ where prev_index: SerializedDepNodeIndex, index: DepNodeIndex, ) -> Option { - if self.vtable.can_load_from_disk { - (self.vtable.try_load_from_disk)(qcx.tcx, key, prev_index, index) - } else { - None - } + // `?` will return None immediately for queries that never cache to disk. + self.vtable.try_load_from_disk_fn?(qcx.tcx, key, prev_index, index) } #[inline] - fn loadable_from_disk( + fn is_loadable_from_disk( self, qcx: QueryCtxt<'tcx>, key: &Self::Key, index: SerializedDepNodeIndex, ) -> bool { - (self.vtable.loadable_from_disk)(qcx.tcx, key, index) + self.vtable.is_loadable_from_disk_fn.map_or(false, |f| f(qcx.tcx, key, index)) } fn value_from_cycle_error( diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index ef7a62351930d..2d4e10a0380c8 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -396,7 +396,7 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>( assert!(query.query_state(qcx).all_inactive()); let cache = query.query_cache(qcx); cache.iter(&mut |key, value, dep_node| { - if query.cache_on_disk(qcx.tcx, key) { + if query.will_cache_on_disk_for_key(qcx.tcx, key) { let dep_node = SerializedDepNodeIndex::new(dep_node.index()); // Record position of the cache entry. @@ -445,7 +445,7 @@ where let key = Q::Key::recover(tcx, &dep_node).unwrap_or_else(|| { panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash) }); - if query.cache_on_disk(tcx, &key) { + if query.will_cache_on_disk_for_key(tcx, &key) { let _ = query.execute_query(tcx, key); } } @@ -648,7 +648,11 @@ macro_rules! define_queries { cycle_error_handling: cycle_error_handling!([$($modifiers)*]), query_state: std::mem::offset_of!(QueryStates<'tcx>, $name), query_cache: std::mem::offset_of!(QueryCaches<'tcx>, $name), - cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key), + will_cache_on_disk_for_key_fn: should_ever_cache_on_disk!([$($modifiers)*] { + Some(::rustc_middle::query::cached::$name) + } { + None + }), execute_query: |tcx, key| erase::erase_val(tcx.$name(key)), compute: |tcx, key| { #[cfg(debug_assertions)] @@ -666,37 +670,34 @@ macro_rules! define_queries { ) ) }, - can_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] true false), - try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] { - |tcx, key, prev_index, index| { - if ::rustc_middle::query::cached::$name(tcx, key) { - let value = $crate::plumbing::try_load_from_disk::< - queries::$name::ProvidedValue<'tcx> - >( - tcx, - prev_index, - index, - ); - value.map(|value| queries::$name::provided_to_erased(tcx, value)) - } else { - None + try_load_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] { + Some(|tcx, key, prev_index, index| { + // Check the `cache_on_disk_if` condition for this key. + if !::rustc_middle::query::cached::$name(tcx, key) { + return None; } - } + + let value: queries::$name::ProvidedValue<'tcx> = + $crate::plumbing::try_load_from_disk(tcx, prev_index, index)?; + + // Arena-alloc the value if appropriate, and erase it. + Some(queries::$name::provided_to_erased(tcx, value)) + }) } { - |_tcx, _key, _prev_index, _index| None + None + }), + is_loadable_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] { + Some(|tcx, key, index| -> bool { + ::rustc_middle::query::cached::$name(tcx, key) && + $crate::plumbing::loadable_from_disk(tcx, index) + }) + } { + None }), value_from_cycle_error: |tcx, cycle, guar| { let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar); erase::erase_val(result) }, - loadable_from_disk: |_tcx, _key, _index| { - should_ever_cache_on_disk!([$($modifiers)*] { - ::rustc_middle::query::cached::$name(_tcx, _key) && - $crate::plumbing::loadable_from_disk(_tcx, _index) - } { - false - }) - }, hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]), format_value: |value| format!("{:?}", erase::restore_val::>(*value)), } diff --git a/compiler/rustc_query_system/src/query/dispatcher.rs b/compiler/rustc_query_system/src/query/dispatcher.rs index d7dd6dd6464a5..ac6c38dd7db55 100644 --- a/compiler/rustc_query_system/src/query/dispatcher.rs +++ b/compiler/rustc_query_system/src/query/dispatcher.rs @@ -46,7 +46,7 @@ pub trait QueryDispatcher<'tcx>: Copy { // Don't use this method to access query results, instead use the methods on TyCtxt fn query_cache<'a>(self, tcx: Self::Qcx) -> &'a Self::Cache; - fn cache_on_disk(self, tcx: DepContextOf<'tcx, Self>, key: &Self::Key) -> bool; + fn will_cache_on_disk_for_key(self, tcx: DepContextOf<'tcx, Self>, key: &Self::Key) -> bool; // Don't use this method to compute query results, instead use the methods on TyCtxt fn execute_query(self, tcx: DepContextOf<'tcx, Self>, k: Self::Key) -> Self::Value; @@ -61,7 +61,7 @@ pub trait QueryDispatcher<'tcx>: Copy { index: DepNodeIndex, ) -> Option; - fn loadable_from_disk( + fn is_loadable_from_disk( self, qcx: Self::Qcx, key: &Self::Key, diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index c4431ff870d0c..04902d0ab10c9 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -623,7 +623,7 @@ where // We always expect to find a cached result for things that // can be forced from `DepNode`. debug_assert!( - !query.cache_on_disk(*qcx.dep_context(), key) + !query.will_cache_on_disk_for_key(*qcx.dep_context(), key) || !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(), "missing on-disk cache entry for {dep_node:?}" ); @@ -631,7 +631,7 @@ where // Sanity check for the logic in `ensure`: if the node is green and the result loadable, // we should actually be able to load it. debug_assert!( - !query.loadable_from_disk(qcx, key, prev_dep_node_index), + !query.is_loadable_from_disk(qcx, key, prev_dep_node_index), "missing on-disk cache entry for loadable {dep_node:?}" ); @@ -798,7 +798,7 @@ where return (false, None); } - let loadable = query.loadable_from_disk(qcx, key, serialized_dep_node_index); + let loadable = query.is_loadable_from_disk(qcx, key, serialized_dep_node_index); (!loadable, Some(dep_node)) } diff --git a/tests/rustdoc-gui/globals.goml b/tests/rustdoc-gui/globals.goml index 89f57add81618..4f12175f6ab23 100644 --- a/tests/rustdoc-gui/globals.goml +++ b/tests/rustdoc-gui/globals.goml @@ -4,14 +4,14 @@ include: "utils.goml" // URL query -go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=sa'%3Bda'%3Bds" +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=sa" wait-for: "#search-tabs" assert-window-property-false: {"searchIndex": null} // Form input go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" call-function: ("perform-search", {"query": "Foo"}) -assert-window-property-false: {"searchIndex": null} +wait-for-window-property-false: {"searchIndex": null} // source sidebar go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index 90e3c58dad719..60415911d38e9 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -68,12 +68,12 @@ union P5 { zst: [u16; 0], byte: u8 } //~ ERROR: layout_of #[rustc_layout(debug)] type X = std::mem::MaybeUninit; //~ ERROR: layout_of -#[rustc_layout(debug)] -const C: () = (); //~ ERROR: can only be applied to +#[rustc_layout(debug)] //~ ERROR: cannot be used on constants +const C: () = (); impl S { - #[rustc_layout(debug)] - const C: () = (); //~ ERROR: can only be applied to + #[rustc_layout(debug)] //~ ERROR: cannot be used on associated consts + const C: () = (); } #[rustc_layout(debug)] diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 79ce21eb532b0..c92f876fa5a13 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -4,6 +4,22 @@ error: unions cannot have zero fields LL | union EmptyUnion {} | ^^^^^^^^^^^^^^^^^^^ +error: `#[rustc_layout]` attribute cannot be used on constants + --> $DIR/debug.rs:71:1 + | +LL | #[rustc_layout(debug)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_layout]` can be applied to data types and type aliases + +error: `#[rustc_layout]` attribute cannot be used on associated consts + --> $DIR/debug.rs:75:5 + | +LL | #[rustc_layout(debug)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_layout]` can be applied to data types and type aliases + error: layout_of(E) = Layout { size: Size(12 bytes), align: AbiAlign { @@ -577,12 +593,6 @@ error: layout_of(MaybeUninit) = Layout { LL | type X = std::mem::MaybeUninit; | ^^^^^^ -error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases - --> $DIR/debug.rs:72:1 - | -LL | const C: () = (); - | ^^^^^^^^^^^ - error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/debug.rs:80:19 | @@ -604,12 +614,6 @@ error: the type `T` does not have a fixed layout LL | type TooGeneric = T; | ^^^^^^^^^^^^^^^^^^ -error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases - --> $DIR/debug.rs:76:5 - | -LL | const C: () = (); - | ^^^^^^^^^^^ - error: aborting due to 20 previous errors For more information about this error, try `rustc --explain E0277`.