diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index ca4805a93e017..4ffc836f5559c 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -188,19 +188,6 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { load } } - - fn memset(&mut self, ptr: &'ll Value, fill_byte: &'ll Value, size: &'ll Value, align: Align) { - unsafe { - llvm::LLVMRustBuildMemSet( - self.llbuilder, - ptr, - align.bytes() as c_uint, - fill_byte, - size, - false, - ); - } - } } /// Empty string, to be used where LLVM expects an instruction name, indicating diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index f1735b9a0f586..402861eda8707 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -19,8 +19,6 @@ pub(crate) struct OffloadGlobals<'ll> { pub launcher_fn: &'ll llvm::Value, pub launcher_ty: &'ll llvm::Type, - pub bin_desc: &'ll llvm::Type, - pub kernel_args_ty: &'ll llvm::Type, pub offload_entry_ty: &'ll llvm::Type, @@ -31,8 +29,8 @@ pub(crate) struct OffloadGlobals<'ll> { pub ident_t_global: &'ll llvm::Value, - pub register_lib: &'ll llvm::Value, - pub unregister_lib: &'ll llvm::Value, + // FIXME(offload): Drop this, once we fully automated our offload compilation pipeline, since + // LLVM will initialize them for us if it sees gpu kernels being registered. pub init_rtls: &'ll llvm::Value, } @@ -44,15 +42,6 @@ impl<'ll> OffloadGlobals<'ll> { let (begin_mapper, _, end_mapper, mapper_fn_ty) = gen_tgt_data_mappers(cx); let ident_t_global = generate_at_one(cx); - let tptr = cx.type_ptr(); - let ti32 = cx.type_i32(); - let tgt_bin_desc_ty = vec![ti32, tptr, tptr, tptr]; - let bin_desc = cx.type_named_struct("struct.__tgt_bin_desc"); - cx.set_struct_body(bin_desc, &tgt_bin_desc_ty, false); - - let reg_lib_decl = cx.type_func(&[cx.type_ptr()], cx.type_void()); - let register_lib = declare_offload_fn(&cx, "__tgt_register_lib", reg_lib_decl); - let unregister_lib = declare_offload_fn(&cx, "__tgt_unregister_lib", reg_lib_decl); let init_ty = cx.type_func(&[], cx.type_void()); let init_rtls = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); @@ -63,20 +52,84 @@ impl<'ll> OffloadGlobals<'ll> { OffloadGlobals { launcher_fn, launcher_ty, - bin_desc, kernel_args_ty, offload_entry_ty, begin_mapper, end_mapper, mapper_fn_ty, ident_t_global, - register_lib, - unregister_lib, init_rtls, } } } +// We need to register offload before using it. We also should unregister it once we are done, for +// good measures. Previously we have done so before and after each individual offload intrinsic +// call, but that comes at a performance cost. The repeated (un)register calls might also confuse +// the LLVM ompOpt pass, which tries to move operations to a better location. The easiest solution, +// which we copy from clang, is to just have those two calls once, in the global ctor/dtor section +// of the final binary. +pub(crate) fn register_offload<'ll>(cx: &CodegenCx<'ll, '_>) { + // First we check quickly whether we already have done our setup, in which case we return early. + // Shouldn't be needed for correctness. + let register_lib_name = "__tgt_register_lib"; + if cx.get_function(register_lib_name).is_some() { + return; + } + + let reg_lib_decl = cx.type_func(&[cx.type_ptr()], cx.type_void()); + let register_lib = declare_offload_fn(&cx, register_lib_name, reg_lib_decl); + let unregister_lib = declare_offload_fn(&cx, "__tgt_unregister_lib", reg_lib_decl); + + let ptr_null = cx.const_null(cx.type_ptr()); + let const_struct = cx.const_struct(&[cx.get_const_i32(0), ptr_null, ptr_null, ptr_null], false); + let omp_descriptor = + add_global(cx, ".omp_offloading.descriptor", const_struct, InternalLinkage); + // @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries } + // @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 0, ptr null, ptr null, ptr null } + + let atexit = cx.type_func(&[cx.type_ptr()], cx.type_i32()); + let atexit_fn = declare_offload_fn(cx, "atexit", atexit); + + let desc_ty = cx.type_func(&[], cx.type_void()); + let reg_name = ".omp_offloading.descriptor_reg"; + let unreg_name = ".omp_offloading.descriptor_unreg"; + let desc_reg_fn = declare_offload_fn(cx, reg_name, desc_ty); + let desc_unreg_fn = declare_offload_fn(cx, unreg_name, desc_ty); + llvm::set_linkage(desc_reg_fn, InternalLinkage); + llvm::set_linkage(desc_unreg_fn, InternalLinkage); + llvm::set_section(desc_reg_fn, c".text.startup"); + llvm::set_section(desc_unreg_fn, c".text.startup"); + + // define internal void @.omp_offloading.descriptor_reg() section ".text.startup" { + // entry: + // call void @__tgt_register_lib(ptr @.omp_offloading.descriptor) + // %0 = call i32 @atexit(ptr @.omp_offloading.descriptor_unreg) + // ret void + // } + let bb = Builder::append_block(cx, desc_reg_fn, "entry"); + let mut a = Builder::build(cx, bb); + a.call(reg_lib_decl, None, None, register_lib, &[omp_descriptor], None, None); + a.call(atexit, None, None, atexit_fn, &[desc_unreg_fn], None, None); + a.ret_void(); + + // define internal void @.omp_offloading.descriptor_unreg() section ".text.startup" { + // entry: + // call void @__tgt_unregister_lib(ptr @.omp_offloading.descriptor) + // ret void + // } + let bb = Builder::append_block(cx, desc_unreg_fn, "entry"); + let mut a = Builder::build(cx, bb); + a.call(reg_lib_decl, None, None, unregister_lib, &[omp_descriptor], None, None); + a.ret_void(); + + // @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @.omp_offloading.descriptor_reg, ptr null }] + let args = vec![cx.get_const_i32(101), desc_reg_fn, ptr_null]; + let const_struct = cx.const_struct(&args, false); + let arr = cx.const_array(cx.val_ty(const_struct), &[const_struct]); + add_global(cx, "llvm.global_ctors", arr, AppendingLinkage); +} + pub(crate) struct OffloadKernelDims<'ll> { num_workgroups: &'ll Value, threads_per_block: &'ll Value, @@ -487,9 +540,6 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( let tgt_decl = offload_globals.launcher_fn; let tgt_target_kernel_ty = offload_globals.launcher_ty; - // %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } - let tgt_bin_desc = offload_globals.bin_desc; - let tgt_kernel_decl = offload_globals.kernel_args_ty; let begin_mapper_decl = offload_globals.begin_mapper; let end_mapper_decl = offload_globals.end_mapper; @@ -513,12 +563,9 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( } // Step 0) - // %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } - // %6 = alloca %struct.__tgt_bin_desc, align 8 unsafe { llvm::LLVMRustPositionBuilderPastAllocas(&builder.llbuilder, builder.llfn()); } - let tgt_bin_desc_alloca = builder.direct_alloca(tgt_bin_desc, Align::EIGHT, "EmptyDesc"); let ty = cx.type_array(cx.type_ptr(), num_args); // Baseptr are just the input pointer to the kernel, stored in a local alloca @@ -536,7 +583,6 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( unsafe { llvm::LLVMPositionBuilderAtEnd(&builder.llbuilder, bb); } - builder.memset(tgt_bin_desc_alloca, cx.get_const_i8(0), cx.get_const_i64(32), Align::EIGHT); // Now we allocate once per function param, a copy to be passed to one of our maps. let mut vals = vec![]; @@ -574,15 +620,9 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( geps.push(gep); } - let mapper_fn_ty = cx.type_func(&[cx.type_ptr()], cx.type_void()); - let register_lib_decl = offload_globals.register_lib; - let unregister_lib_decl = offload_globals.unregister_lib; let init_ty = cx.type_func(&[], cx.type_void()); let init_rtls_decl = offload_globals.init_rtls; - // FIXME(offload): Later we want to add them to the wrapper code, rather than our main function. - // call void @__tgt_register_lib(ptr noundef %6) - builder.call(mapper_fn_ty, None, None, register_lib_decl, &[tgt_bin_desc_alloca], None, None); // call void @__tgt_init_all_rtls() builder.call(init_ty, None, None, init_rtls_decl, &[], None, None); @@ -679,6 +719,4 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( num_args, s_ident_t, ); - - builder.call(mapper_fn_ty, None, None, unregister_lib_decl, &[tgt_bin_desc_alloca], None, None); } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index b0cf9925019d2..f2261ab79340f 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -124,6 +124,10 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { pub(crate) fn const_null(&self, t: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMConstNull(t) } } + + pub(crate) fn const_struct(&self, elts: &[&'ll Value], packed: bool) -> &'ll Value { + struct_in_context(self.llcx(), elts, packed) + } } impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 50e627cf6bdf2..e035f0809d685 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -30,7 +30,9 @@ use tracing::debug; use crate::abi::FnAbiLlvmExt; use crate::builder::Builder; use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call}; -use crate::builder::gpu_offload::{OffloadKernelDims, gen_call_handling, gen_define_handling}; +use crate::builder::gpu_offload::{ + OffloadKernelDims, gen_call_handling, gen_define_handling, register_offload, +}; use crate::context::CodegenCx; use crate::declare::declare_raw_fn; use crate::errors::{ @@ -1402,6 +1404,7 @@ fn codegen_offload<'ll, 'tcx>( return; } }; + register_offload(cx); let offload_data = gen_define_handling(&cx, &metadata, target_symbol, offload_globals); gen_call_handling(bx, &offload_data, &args, &types, &metadata, offload_globals, &offload_dims); } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 9d17c998a8f29..901a023c4f308 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -122,7 +122,7 @@ use crate::mir::mono::{ CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions, NormalizationErrorInMono, }; use crate::query::erase::{Erase, erase, restore}; -use crate::query::plumbing::{CyclePlaceholder, DynamicQuery}; +use crate::query::plumbing::CyclePlaceholder; use crate::traits::query::{ CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal, CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal, diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 9ee8d743e64a4..0e536352563f4 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -14,11 +14,14 @@ use crate::dep_graph; use crate::dep_graph::DepKind; use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; use crate::query::{ - DynamicQueries, ExternProviders, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates, + ExternProviders, PerQueryVTables, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates, }; use crate::ty::TyCtxt; -pub struct DynamicQuery<'tcx, C: QueryCache> { +/// Stores function pointers and other metadata for a particular query. +/// +/// Used indirectly by query plumbing in `rustc_query_system`, via a trait. +pub struct QueryVTable<'tcx, C: QueryCache> { pub name: &'static str, pub eval_always: bool, pub dep_kind: DepKind, @@ -62,7 +65,7 @@ pub struct QuerySystem<'tcx> { pub states: QueryStates<'tcx>, pub arenas: WorkerLocal>, pub caches: QueryCaches<'tcx>, - pub dynamic_queries: DynamicQueries<'tcx>, + pub query_vtables: PerQueryVTables<'tcx>, /// This provides access to the incremental compilation on-disk cache for query results. /// Do not access this directly. It is only meant to be used by @@ -418,9 +421,12 @@ macro_rules! define_callbacks { })* } - pub struct DynamicQueries<'tcx> { + /// Holds a `QueryVTable` for each query. + /// + /// ("Per" just makes this pluralized name more visually distinct.) + pub struct PerQueryVTables<'tcx> { $( - pub $name: DynamicQuery<'tcx, queries::$name::Storage<'tcx>>, + pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, queries::$name::Storage<'tcx>>, )* } diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 490af1257760d..3d8b97b2fde38 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -758,7 +758,7 @@ impl<'input> Parser<'input> { } /// Parses a word starting at the current position. A word is the same as a - /// Rust identifier, except that it can't start with `_` character. + /// Rust identifier or keyword, except that it can't be a bare `_` character. fn word(&mut self) -> &'input str { let index = self.input_vec_index; match self.peek() { diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index e8983bfa1ddba..b628224db5369 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -12,17 +12,16 @@ use rustc_middle::arena::Arena; use rustc_middle::dep_graph::{self, DepKind, DepKindVTable, DepNodeIndex}; use rustc_middle::query::erase::{Erase, erase, restore}; use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; -use rustc_middle::query::plumbing::{DynamicQuery, QuerySystem, QuerySystemFns}; +use rustc_middle::query::plumbing::{QuerySystem, QuerySystemFns, QueryVTable}; use rustc_middle::query::{ - AsLocalKey, DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, - queries, + AsLocalKey, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, queries, }; use rustc_middle::ty::TyCtxt; use rustc_query_system::Value; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - CycleError, CycleErrorHandling, HashResult, QueryCache, QueryConfig, QueryMap, QueryMode, + CycleError, CycleErrorHandling, HashResult, QueryCache, QueryDispatcher, QueryMap, QueryMode, QueryStackDeferred, QueryState, get_query_incr, get_query_non_incr, }; use rustc_span::{ErrorGuaranteed, Span}; @@ -37,30 +36,39 @@ pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all}; mod profiling_support; pub use self::profiling_support::alloc_self_profile_query_strings; -struct DynamicConfig< +/// Combines a [`QueryVTable`] with some additional compile-time booleans +/// to implement [`QueryDispatcher`], for use by code in [`rustc_query_system`]. +/// +/// Baking these boolean flags into the type gives a modest but measurable +/// improvement to compiler perf and compiler code size; see +/// . +struct SemiDynamicQueryDispatcher< 'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool, > { - dynamic: &'tcx DynamicQuery<'tcx, C>, + vtable: &'tcx QueryVTable<'tcx, C>, } +// Manually implement Copy/Clone, because deriving would put trait bounds on the cache type. impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy - for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> + for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> { } impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone - for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> + for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> { fn clone(&self) -> Self { *self } } +// This is `impl QueryDispatcher for SemiDynamicQueryDispatcher`. impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> - QueryConfig> for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> + QueryDispatcher> + for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> where for<'a> C::Key: HashStable>, { @@ -70,12 +78,12 @@ where #[inline(always)] fn name(self) -> &'static str { - self.dynamic.name + self.vtable.name } #[inline(always)] fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool { - (self.dynamic.cache_on_disk)(tcx, key) + (self.vtable.cache_on_disk)(tcx, key) } #[inline(always)] @@ -90,7 +98,7 @@ where // This is just manually doing the subfield referencing through pointer math. unsafe { &*(&qcx.tcx.query_system.states as *const QueryStates<'tcx>) - .byte_add(self.dynamic.query_state) + .byte_add(self.vtable.query_state) .cast::>>() } } @@ -104,19 +112,19 @@ where // This is just manually doing the subfield referencing through pointer math. unsafe { &*(&qcx.tcx.query_system.caches as *const QueryCaches<'tcx>) - .byte_add(self.dynamic.query_cache) + .byte_add(self.vtable.query_cache) .cast::() } } #[inline(always)] fn execute_query(self, tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { - (self.dynamic.execute_query)(tcx, key) + (self.vtable.execute_query)(tcx, key) } #[inline(always)] fn compute(self, qcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value { - (self.dynamic.compute)(qcx.tcx, key) + (self.vtable.compute)(qcx.tcx, key) } #[inline(always)] @@ -127,8 +135,8 @@ where prev_index: SerializedDepNodeIndex, index: DepNodeIndex, ) -> Option { - if self.dynamic.can_load_from_disk { - (self.dynamic.try_load_from_disk)(qcx.tcx, key, prev_index, index) + if self.vtable.can_load_from_disk { + (self.vtable.try_load_from_disk)(qcx.tcx, key, prev_index, index) } else { None } @@ -141,7 +149,7 @@ where key: &Self::Key, index: SerializedDepNodeIndex, ) -> bool { - (self.dynamic.loadable_from_disk)(qcx.tcx, key, index) + (self.vtable.loadable_from_disk)(qcx.tcx, key, index) } fn value_from_cycle_error( @@ -150,12 +158,12 @@ where cycle_error: &CycleError, guar: ErrorGuaranteed, ) -> Self::Value { - (self.dynamic.value_from_cycle_error)(tcx, cycle_error, guar) + (self.vtable.value_from_cycle_error)(tcx, cycle_error, guar) } #[inline(always)] fn format_value(self) -> fn(&Self::Value) -> String { - self.dynamic.format_value + self.vtable.format_value } #[inline(always)] @@ -165,7 +173,7 @@ where #[inline(always)] fn eval_always(self) -> bool { - self.dynamic.eval_always + self.vtable.eval_always } #[inline(always)] @@ -180,31 +188,42 @@ where #[inline(always)] fn dep_kind(self) -> DepKind { - self.dynamic.dep_kind + self.vtable.dep_kind } #[inline(always)] fn cycle_error_handling(self) -> CycleErrorHandling { - self.dynamic.cycle_error_handling + self.vtable.cycle_error_handling } #[inline(always)] fn hash_result(self) -> HashResult { - self.dynamic.hash_result + self.vtable.hash_result } } -/// This is implemented per query. It allows restoring query values from their erased state -/// and constructing a QueryConfig. -trait QueryConfigRestored<'tcx> { - type RestoredValue; - type Config: QueryConfig>; +/// Provides access to vtable-like operations for a query +/// (by creating a [`QueryDispatcher`]), +/// but also keeps track of the "unerased" value type of the query +/// (i.e. the actual result type in the query declaration). +/// +/// This trait allows some per-query code to be defined in generic functions +/// with a trait bound, instead of having to be defined inline within a macro +/// expansion. +/// +/// There is one macro-generated implementation of this trait for each query, +/// on the type `rustc_query_impl::query_impl::$name::QueryType`. +trait QueryDispatcherUnerased<'tcx> { + type UnerasedValue; + type Dispatcher: QueryDispatcher>; const NAME: &'static &'static str; - fn config(tcx: TyCtxt<'tcx>) -> Self::Config; - fn restore(value: >>::Value) - -> Self::RestoredValue; + fn query_dispatcher(tcx: TyCtxt<'tcx>) -> Self::Dispatcher; + + fn restore_val( + value: >>::Value, + ) -> Self::UnerasedValue; } pub fn query_system<'a>( @@ -217,7 +236,7 @@ pub fn query_system<'a>( states: Default::default(), arenas: Default::default(), caches: Default::default(), - dynamic_queries: dynamic_queries(), + query_vtables: make_query_vtables(), on_disk_cache, fns: QuerySystemFns { engine: engine(incremental), diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 0c3fcf25c6550..6ead03a527a7a 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -27,14 +27,14 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffect, + QueryCache, QueryContext, QueryDispatcher, QueryJobId, QueryMap, QuerySideEffect, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, force_query, }; use rustc_query_system::{QueryOverflow, QueryOverflowNote}; use rustc_serialize::{Decodable, Encodable}; use rustc_span::def_id::LOCAL_CRATE; -use crate::QueryConfigRestored; +use crate::QueryDispatcherUnerased; /// Implements [`QueryContext`] for use by [`rustc_query_system`], since that /// crate does not have direct access to [`TyCtxt`]. @@ -387,13 +387,13 @@ pub(crate) fn create_query_frame< } pub(crate) fn encode_query_results<'a, 'tcx, Q>( - query: Q::Config, + query: Q::Dispatcher, qcx: QueryCtxt<'tcx>, encoder: &mut CacheEncoder<'a, 'tcx>, query_result_index: &mut EncodedDepNodeIndex, ) where - Q: super::QueryConfigRestored<'tcx>, - Q::RestoredValue: Encodable>, + Q: QueryDispatcherUnerased<'tcx>, + Q::UnerasedValue: Encodable>, { let _timer = qcx.tcx.prof.generic_activity_with_arg("encode_query_results_for", query.name()); @@ -408,13 +408,13 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>( // Encode the type check tables with the `SerializedDepNodeIndex` // as tag. - encoder.encode_tagged(dep_node, &Q::restore(*value)); + encoder.encode_tagged(dep_node, &Q::restore_val(*value)); } }); } pub(crate) fn query_key_hash_verify<'tcx>( - query: impl QueryConfig>, + query: impl QueryDispatcher>, qcx: QueryCtxt<'tcx>, ) { let _timer = qcx.tcx.prof.generic_activity_with_arg("query_key_hash_verify_for", query.name()); @@ -442,7 +442,7 @@ pub(crate) fn query_key_hash_verify<'tcx>( fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) where - Q: QueryConfig>, + Q: QueryDispatcher>, { debug_assert!(tcx.dep_graph.is_green(&dep_node)); @@ -488,7 +488,7 @@ where fn force_from_dep_node<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool where - Q: QueryConfig>, + Q: QueryDispatcher>, { // We must avoid ever having to call `force_from_dep_node()` for a // `DepNode::codegen_unit`: @@ -521,9 +521,10 @@ pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q>( is_eval_always: bool, ) -> DepKindVTable<'tcx> where - Q: QueryConfigRestored<'tcx>, + Q: QueryDispatcherUnerased<'tcx>, { - let fingerprint_style = >>::Key::fingerprint_style(); + let fingerprint_style = + >>::Key::fingerprint_style(); if is_anon || !fingerprint_style.reconstructible() { return DepKindVTable { @@ -541,10 +542,10 @@ where is_eval_always, fingerprint_style, force_from_dep_node: Some(|tcx, dep_node, _| { - force_from_dep_node(Q::config(tcx), tcx, dep_node) + force_from_dep_node(Q::query_dispatcher(tcx), tcx, dep_node) }), try_load_from_on_disk_cache: Some(|tcx, dep_node| { - try_load_from_on_disk_cache(Q::config(tcx), tcx, dep_node) + try_load_from_on_disk_cache(Q::query_dispatcher(tcx), tcx, dep_node) }), name: Q::NAME, } @@ -613,7 +614,7 @@ macro_rules! define_queries { #[cfg(debug_assertions)] let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); get_query_incr( - QueryType::config(tcx), + QueryType::query_dispatcher(tcx), QueryCtxt::new(tcx), span, key, @@ -633,7 +634,7 @@ macro_rules! define_queries { __mode: QueryMode, ) -> Option>> { Some(get_query_non_incr( - QueryType::config(tcx), + QueryType::query_dispatcher(tcx), QueryCtxt::new(tcx), span, key, @@ -641,10 +642,10 @@ macro_rules! define_queries { } } - pub(crate) fn dynamic_query<'tcx>() - -> DynamicQuery<'tcx, queries::$name::Storage<'tcx>> + pub(crate) fn make_query_vtable<'tcx>() + -> QueryVTable<'tcx, queries::$name::Storage<'tcx>> { - DynamicQuery { + QueryVTable { name: stringify!($name), eval_always: is_eval_always!([$($modifiers)*]), dep_kind: dep_graph::dep_kinds::$name, @@ -710,9 +711,9 @@ macro_rules! define_queries { data: PhantomData<&'tcx ()> } - impl<'tcx> QueryConfigRestored<'tcx> for QueryType<'tcx> { - type RestoredValue = queries::$name::Value<'tcx>; - type Config = DynamicConfig< + impl<'tcx> QueryDispatcherUnerased<'tcx> for QueryType<'tcx> { + type UnerasedValue = queries::$name::Value<'tcx>; + type Dispatcher = SemiDynamicQueryDispatcher< 'tcx, queries::$name::Storage<'tcx>, { is_anon!([$($modifiers)*]) }, @@ -723,14 +724,14 @@ macro_rules! define_queries { const NAME: &'static &'static str = &stringify!($name); #[inline(always)] - fn config(tcx: TyCtxt<'tcx>) -> Self::Config { - DynamicConfig { - dynamic: &tcx.query_system.dynamic_queries.$name, + fn query_dispatcher(tcx: TyCtxt<'tcx>) -> Self::Dispatcher { + SemiDynamicQueryDispatcher { + vtable: &tcx.query_system.query_vtables.$name, } } #[inline(always)] - fn restore(value: >>::Value) -> Self::RestoredValue { + fn restore_val(value: >>::Value) -> Self::UnerasedValue { restore::>(value) } } @@ -782,7 +783,7 @@ macro_rules! define_queries { query_result_index: &mut EncodedDepNodeIndex ) { $crate::plumbing::encode_query_results::>( - query_impl::$name::QueryType::config(tcx), + query_impl::$name::QueryType::query_dispatcher(tcx), QueryCtxt::new(tcx), encoder, query_result_index, @@ -792,7 +793,7 @@ macro_rules! define_queries { pub(crate) fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) { $crate::plumbing::query_key_hash_verify( - query_impl::$name::QueryType::config(tcx), + query_impl::$name::QueryType::query_dispatcher(tcx), QueryCtxt::new(tcx), ) } @@ -810,10 +811,10 @@ macro_rules! define_queries { } } - pub fn dynamic_queries<'tcx>() -> DynamicQueries<'tcx> { - DynamicQueries { + pub fn make_query_vtables<'tcx>() -> ::rustc_middle::query::PerQueryVTables<'tcx> { + ::rustc_middle::query::PerQueryVTables { $( - $name: query_impl::$name::dynamic_query(), + $name: query_impl::$name::make_query_vtable(), )* } } diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/dispatcher.rs similarity index 85% rename from compiler/rustc_query_system/src/query/config.rs rename to compiler/rustc_query_system/src/query/dispatcher.rs index 66b04aa7b467b..bba1703dfbb6b 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/dispatcher.rs @@ -1,5 +1,3 @@ -//! Query configuration and description traits. - use std::fmt::Debug; use std::hash::Hash; @@ -14,7 +12,15 @@ use crate::query::{CycleError, CycleErrorHandling, DepNodeIndex, QueryContext, Q pub type HashResult = Option, &V) -> Fingerprint>; -pub trait QueryConfig: Copy { +/// Trait that can be used as a vtable for a single query, providing operations +/// and metadata for that query. +/// +/// Implemented by `rustc_query_impl::SemiDynamicQueryDispatcher`, which +/// mostly delegates to `rustc_middle::query::plumbing::QueryVTable`. +/// Those types are not visible from this `rustc_query_system` crate. +/// +/// "Dispatcher" should be understood as a near-synonym of "vtable". +pub trait QueryDispatcher: Copy { fn name(self) -> &'static str; // `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap, diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 3ff980fa9bc5c..701253d50fcca 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -13,7 +13,7 @@ use rustc_span::Span; use rustc_span::def_id::DefId; pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; -pub use self::config::{HashResult, QueryConfig}; +pub use self::dispatcher::{HashResult, QueryDispatcher}; pub use self::job::{ QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap, break_query_cycles, print_query_stack, report_cycle, @@ -22,7 +22,7 @@ pub use self::plumbing::*; use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; mod caches; -mod config; +mod dispatcher; mod job; mod plumbing; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 5be4ee1452082..9afad1546e9eb 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -18,7 +18,7 @@ use rustc_errors::{Diag, FatalError, StashKey}; use rustc_span::{DUMMY_SP, Span}; use tracing::instrument; -use super::{QueryConfig, QueryStackFrameExtra}; +use super::{QueryDispatcher, QueryStackFrameExtra}; use crate::dep_graph::{DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeParams}; use crate::ich::StableHashingContext; use crate::query::caches::QueryCache; @@ -126,7 +126,7 @@ where #[inline(never)] fn mk_cycle(query: Q, qcx: Qcx, cycle_error: CycleError) -> Q::Value where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { let error = report_cycle(qcx.dep_context().sess(), &cycle_error); @@ -140,7 +140,7 @@ fn handle_cycle_error( error: Diag<'_>, ) -> Q::Value where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { match query.cycle_error_handling() { @@ -279,7 +279,7 @@ fn cycle_error( span: Span, ) -> (Q::Value, Option) where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { // Ensure there was no errors collecting all active jobs. @@ -300,7 +300,7 @@ fn wait_for_query( current: Option, ) -> (Q::Value, Option) where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { // For parallel queries, we'll block and wait until the query running @@ -349,7 +349,7 @@ fn try_execute_query( dep_node: Option, ) -> (Q::Value, Option) where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { let state = query.query_state(qcx); @@ -421,7 +421,7 @@ fn execute_job( dep_node: Option, ) -> (Q::Value, Option) where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { // Use `JobOwner` so the query will be poisoned if executing it panics. @@ -491,7 +491,7 @@ fn execute_job_non_incr( job_id: QueryJobId, ) -> (Q::Value, DepNodeIndex) where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled()); @@ -530,7 +530,7 @@ fn execute_job_incr( job_id: QueryJobId, ) -> (Q::Value, DepNodeIndex) where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { if !query.anon() && !query.eval_always() { @@ -585,7 +585,7 @@ fn try_load_from_disk_and_cache_in_memory( dep_node: &DepNode, ) -> Option<(Q::Value, DepNodeIndex)> where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { // Note this function can be called concurrently from the same query @@ -771,7 +771,7 @@ fn ensure_must_run( check_cache: bool, ) -> (bool, Option) where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { if query.eval_always() { @@ -819,7 +819,7 @@ pub enum QueryMode { #[inline(always)] pub fn get_query_non_incr(query: Q, qcx: Qcx, span: Span, key: Q::Key) -> Q::Value where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled()); @@ -836,7 +836,7 @@ pub fn get_query_incr( mode: QueryMode, ) -> Option where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { debug_assert!(qcx.dep_context().dep_graph().is_fully_enabled()); @@ -862,7 +862,7 @@ where pub fn force_query(query: Q, qcx: Qcx, key: Q::Key, dep_node: DepNode) where - Q: QueryConfig, + Q: QueryDispatcher, Qcx: QueryContext, { // We may be concurrently trying both execute and force a query. diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 3d7c580be8c95..e3ff2ba51aba0 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -136,9 +136,10 @@ //! padding specified by fill/alignment will be used to take up the required //! space (see below). //! -//! The value for the width can also be provided as a [`usize`] in the list of -//! parameters by adding a postfix `$`, indicating that the second argument is -//! a [`usize`] specifying the width. +//! The width can also be provided dynamically by referencing another argument +//! with a `$` suffix. Use `{:N$}` to reference the Nth positional argument +//! (where N is an integer), or `{:name$}` to reference a named argument. The +//! referenced argument must be of type [`usize`]. //! //! Referring to an argument with the dollar syntax does not affect the "next //! argument" counter, so it's usually a good idea to refer to arguments by @@ -236,7 +237,8 @@ //! //! 2. An integer or name followed by dollar sign `.N$`: //! -//! use format *argument* `N` (which must be a `usize`) as the precision. +//! use the value of format *argument* `N` (which must be a `usize`) as the precision. +//! An integer refers to a positional argument, and a name refers to a named argument. //! //! 3. An asterisk `.*`: //! @@ -363,7 +365,10 @@ //! - `ws` is any character for which [`char::is_whitespace`] returns `true`, has no semantic //! meaning and is completely optional, //! - `integer` is a decimal integer that may contain leading zeroes and must fit into an `usize` and -//! - `identifier` is an `IDENTIFIER_OR_KEYWORD` (not an `IDENTIFIER`) as defined by the [Rust language reference](https://doc.rust-lang.org/reference/identifiers.html). +//! - `identifier` is an `IDENTIFIER_OR_KEYWORD` (not an `IDENTIFIER`) as +//! defined by the [Rust language +//! reference](https://doc.rust-lang.org/reference/identifiers.html), except +//! for a bare `_`. //! //! # Formatting traits //! diff --git a/package.json b/package.json index 1fe87b1816691..66596cab42682 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "browser-ui-test": "^0.23.2", + "browser-ui-test": "^0.23.3", "es-check": "^9.4.4", "eslint": "^8.57.1", "typescript": "^5.8.3" diff --git a/tests/codegen-llvm/gpu_offload/control_flow.rs b/tests/codegen-llvm/gpu_offload/control_flow.rs index 28ee9c85b0edc..1a3d3cd7a7789 100644 --- a/tests/codegen-llvm/gpu_offload/control_flow.rs +++ b/tests/codegen-llvm/gpu_offload/control_flow.rs @@ -12,8 +12,7 @@ // CHECK: define{{( dso_local)?}} void @main() // CHECK-NOT: define -// CHECK: %EmptyDesc = alloca %struct.__tgt_bin_desc, align 8 -// CHECK-NEXT: %.offload_baseptrs = alloca [1 x ptr], align 8 +// CHECK: %.offload_baseptrs = alloca [1 x ptr], align 8 // CHECK-NEXT: %.offload_ptrs = alloca [1 x ptr], align 8 // CHECK-NEXT: %.offload_sizes = alloca [1 x i64], align 8 // CHECK-NEXT: %kernel_args = alloca %struct.__tgt_kernel_arguments, align 8 diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index 27ff6f325aa0f..d0bc34ec66b20 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -2,9 +2,10 @@ //@ no-prefer-dynamic //@ needs-offload -// This test is verifying that we generate __tgt_target_data_*_mapper before and after a call to the -// kernel_1. Better documentation to what each global or variable means is available in the gpu -// offload code, or the LLVM offload documentation. +// This test is verifying that we generate __tgt_target_data_*_mapper before and after a call to +// __tgt_target_kernel, and initialize all needed variables. It also verifies some related globals. +// Better documentation to what each global or variable means is available in the gpu offload code, +// or the LLVM offload documentation. #![feature(rustc_attrs)] #![feature(core_intrinsics)] @@ -17,10 +18,8 @@ fn main() { core::hint::black_box(&x); } -#[unsafe(no_mangle)] -#[inline(never)] pub fn kernel_1(x: &mut [f32; 256]) { - core::intrinsics::offload(_kernel_1, [256, 1, 1], [32, 1, 1], (x,)) + core::intrinsics::offload(kernel_1, [256, 1, 1], [32, 1, 1], (x,)) } #[unsafe(no_mangle)] @@ -33,75 +32,75 @@ pub fn _kernel_1(x: &mut [f32; 256]) { // CHECK: %struct.ident_t = type { i32, i32, i32, i32, ptr } // CHECK: %struct.__tgt_offload_entry = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// CHECK: %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } // CHECK: %struct.__tgt_kernel_arguments = type { i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, i64, i64, [3 x i32], [3 x i32], i32 } -// CHECK: @anon.{{.*}}.0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 -// CHECK: @anon.{{.*}}.1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @anon.{{.*}}.0 }, align 8 +// CHECK: @anon.[[ID:.*]].0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 +// CHECK: @anon.{{.*}}.1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @anon.[[ID]].0 }, align 8 -// CHECK: @.offload_sizes._kernel_1 = private unnamed_addr constant [1 x i64] [i64 1024] -// CHECK: @.offload_maptypes._kernel_1 = private unnamed_addr constant [1 x i64] [i64 35] -// CHECK: @._kernel_1.region_id = internal constant i8 0 -// CHECK: @.offloading.entry_name._kernel_1 = internal unnamed_addr constant [10 x i8] c"_kernel_1\00", section ".llvm.rodata.offloading", align 1 -// CHECK: @.offloading.entry._kernel_1 = internal constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr @._kernel_1.region_id, ptr @.offloading.entry_name._kernel_1, i64 0, i64 0, ptr null }, section "llvm_offload_entries", align 8 +// CHECK-DAG: @.omp_offloading.descriptor = internal constant { i32, ptr, ptr, ptr } zeroinitializer +// CHECK-DAG: @llvm.global_ctors = appending constant [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @.omp_offloading.descriptor_reg, ptr null }] +// CHECK-DAG: @.offload_sizes.[[K:[^ ]*kernel_1]] = private unnamed_addr constant [1 x i64] [i64 1024] +// CHECK-DAG: @.offload_maptypes.[[K]] = private unnamed_addr constant [1 x i64] [i64 35] +// CHECK-DAG: @.[[K]].region_id = internal constant i8 0 +// CHECK-DAG: @.offloading.entry_name.[[K]] = internal unnamed_addr constant [{{[0-9]+}} x i8] c"[[K]]{{\\00}}", section ".llvm.rodata.offloading", align 1 +// CHECK-DAG: @.offloading.entry.[[K]] = internal constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr @.[[K]].region_id, ptr @.offloading.entry_name.[[K]], i64 0, i64 0, ptr null }, section "llvm_offload_entries", align 8 // CHECK: declare i32 @__tgt_target_kernel(ptr, i64, i32, i32, ptr, ptr) -// CHECK: declare void @__tgt_register_lib(ptr) local_unnamed_addr -// CHECK: declare void @__tgt_unregister_lib(ptr) local_unnamed_addr - -// CHECK: define{{( dso_local)?}} void @main() -// CHECK-NEXT: start: -// CHECK-NEXT: %0 = alloca [8 x i8], align 8 -// CHECK-NEXT: %x = alloca [1024 x i8], align 16 -// CHECK: call void @kernel_1(ptr noalias noundef nonnull align 4 dereferenceable(1024) %x) -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %0) -// CHECK-NEXT: store ptr %x, ptr %0, align 8 -// CHECK-NEXT: call void asm sideeffect "", "r,~{memory}"(ptr nonnull %0) -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %0) -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %x) -// CHECK-NEXT: ret void -// CHECK-NEXT: } -// CHECK: define{{( dso_local)?}} void @kernel_1(ptr noalias noundef align 4 dereferenceable(1024) %x) +// CHECK-LABEL: define{{( dso_local)?}} void @main() // CHECK-NEXT: start: -// CHECK-NEXT: %EmptyDesc = alloca %struct.__tgt_bin_desc, align 8 +// CHECK-NEXT: %0 = alloca [8 x i8], align 8 +// CHECK-NEXT: %x = alloca [1024 x i8], align 16 // CHECK-NEXT: %.offload_baseptrs = alloca [1 x ptr], align 8 // CHECK-NEXT: %.offload_ptrs = alloca [1 x ptr], align 8 // CHECK-NEXT: %.offload_sizes = alloca [1 x i64], align 8 // CHECK-NEXT: %kernel_args = alloca %struct.__tgt_kernel_arguments, align 8 -// CHECK-NEXT: %dummy = load volatile ptr, ptr @.offload_sizes._kernel_1, align 8 -// CHECK-NEXT: %dummy1 = load volatile ptr, ptr @.offloading.entry._kernel_1, align 8 -// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(32) %EmptyDesc, i8 0, i64 32, i1 false) -// CHECK-NEXT: call void @__tgt_register_lib(ptr nonnull %EmptyDesc) +// CHECK: %dummy = load volatile ptr, ptr @.offload_sizes.[[K]], align 8 +// CHECK-NEXT: %dummy1 = load volatile ptr, ptr @.offloading.entry.[[K]], align 8 // CHECK-NEXT: call void @__tgt_init_all_rtls() // CHECK-NEXT: store ptr %x, ptr %.offload_baseptrs, align 8 // CHECK-NEXT: store ptr %x, ptr %.offload_ptrs, align 8 // CHECK-NEXT: store i64 1024, ptr %.offload_sizes, align 8 -// CHECK-NEXT: call void @__tgt_target_data_begin_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes._kernel_1, ptr null, ptr null) +// CHECK-NEXT: call void @__tgt_target_data_begin_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.[[K]], ptr null, ptr null) // CHECK-NEXT: store i32 3, ptr %kernel_args, align 8 -// CHECK-NEXT: %0 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 4 -// CHECK-NEXT: store i32 1, ptr %0, align 4 -// CHECK-NEXT: %1 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 8 -// CHECK-NEXT: store ptr %.offload_baseptrs, ptr %1, align 8 -// CHECK-NEXT: %2 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 16 -// CHECK-NEXT: store ptr %.offload_ptrs, ptr %2, align 8 -// CHECK-NEXT: %3 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 24 -// CHECK-NEXT: store ptr %.offload_sizes, ptr %3, align 8 -// CHECK-NEXT: %4 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 32 -// CHECK-NEXT: store ptr @.offload_maptypes._kernel_1, ptr %4, align 8 -// CHECK-NEXT: %5 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 40 -// CHECK-NEXT: %6 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 72 -// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(32) %5, i8 0, i64 32, i1 false) -// CHECK-NEXT: store <4 x i32> , ptr %6, align 8 -// CHECK-NEXT: %.fca.1.gep5 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 88 -// CHECK-NEXT: store i32 1, ptr %.fca.1.gep5, align 8 -// CHECK-NEXT: %.fca.2.gep7 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 92 -// CHECK-NEXT: store i32 1, ptr %.fca.2.gep7, align 4 -// CHECK-NEXT: %7 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 96 -// CHECK-NEXT: store i32 0, ptr %7, align 8 -// CHECK-NEXT: %8 = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 256, i32 32, ptr nonnull @._kernel_1.region_id, ptr nonnull %kernel_args) -// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes._kernel_1, ptr null, ptr null) -// CHECK-NEXT: call void @__tgt_unregister_lib(ptr nonnull %EmptyDesc) +// CHECK-NEXT: [[P4:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 4 +// CHECK-NEXT: store i32 1, ptr [[P4]], align 4 +// CHECK-NEXT: [[P8:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 8 +// CHECK-NEXT: store ptr %.offload_baseptrs, ptr [[P8]], align 8 +// CHECK-NEXT: [[P16:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 16 +// CHECK-NEXT: store ptr %.offload_ptrs, ptr [[P16]], align 8 +// CHECK-NEXT: [[P24:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 24 +// CHECK-NEXT: store ptr %.offload_sizes, ptr [[P24]], align 8 +// CHECK-NEXT: [[P32:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 32 +// CHECK-NEXT: store ptr @.offload_maptypes.[[K]], ptr [[P32]], align 8 +// CHECK-NEXT: [[P40:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 40 +// CHECK-NEXT: [[P72:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 72 +// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(32) [[P40]], i8 0, i64 32, i1 false) +// CHECK-NEXT: store <4 x i32> , ptr [[P72]], align 8 +// CHECK-NEXT: [[P88:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 88 +// CHECK-NEXT: store i32 1, ptr [[P88]], align 8 +// CHECK-NEXT: [[P92:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 92 +// CHECK-NEXT: store i32 1, ptr [[P92]], align 4 +// CHECK-NEXT: [[P96:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 96 +// CHECK-NEXT: store i32 0, ptr [[P96]], align 8 +// CHECK-NEXT: {{%[^ ]+}} = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 256, i32 32, ptr nonnull @.[[K]].region_id, ptr nonnull %kernel_args) +// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.[[K]], ptr null, ptr null) +// CHECK: ret void +// CHECK-NEXT: } + +// CHECK: declare void @__tgt_register_lib(ptr) local_unnamed_addr +// CHECK: declare void @__tgt_unregister_lib(ptr) local_unnamed_addr + +// CHECK-LABEL: define internal void @.omp_offloading.descriptor_reg() section ".text.startup" { +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @__tgt_register_lib(ptr nonnull @.omp_offloading.descriptor) +// CHECK-NEXT: %0 = {{tail }}call i32 @atexit(ptr nonnull @.omp_offloading.descriptor_unreg) +// CHECK-NEXT: ret void +// CHECK-NEXT: } + +// CHECK-LABEL: define internal void @.omp_offloading.descriptor_unreg() section ".text.startup" { +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @__tgt_unregister_lib(ptr nonnull @.omp_offloading.descriptor) // CHECK-NEXT: ret void // CHECK-NEXT: } diff --git a/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs index 3d1e48a4c6382..91447e5fa166b 100644 --- a/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs +++ b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs @@ -14,3 +14,20 @@ pub mod bar { //~| ERROR: unresolved link pub fn sql_function_proc() {} } + +// From here, this is a regression test for . +pub use fuzz_test_helpers::*; + +/// A type referenced in the deprecation note. +pub struct Env; + +impl Env { + pub fn try_invoke(&self) {} +} + +mod fuzz_test_helpers { + #[deprecated(note = "use [Env::try_invoke] instead")] + //~^ ERROR: unresolved link + //~| ERROR: unresolved link + pub fn fuzz_catch_panic() {} +} diff --git a/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr index 25f10b24d9fb5..c708ca04ebec1 100644 --- a/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr +++ b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr @@ -16,6 +16,18 @@ note: the lint level is defined here LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: unresolved link to `Env::try_invoke` + --> $DIR/deprecated-note-from-reexported.rs:28:25 + | +LL | #[deprecated(note = "use [Env::try_invoke] instead")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + use [Env::try_invoke] instead + ^^^^^^^^^^^^^^^ + = note: no item named `Env` in scope + error: unresolved link to `define_sql_function` --> $DIR/deprecated-note-from-reexported.rs:12:25 | @@ -30,5 +42,18 @@ LL | #[deprecated(note = "Use [`define_sql_function`] instead")] = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 2 previous errors +error: unresolved link to `Env::try_invoke` + --> $DIR/deprecated-note-from-reexported.rs:28:25 + | +LL | #[deprecated(note = "use [Env::try_invoke] instead")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + use [Env::try_invoke] instead + ^^^^^^^^^^^^^^^ + = note: no item named `Env` in scope + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs index 37f78a7777c46..4f08c5327c153 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs @@ -18,6 +18,7 @@ extern crate rustc_fluent_macro; extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; +extern crate core; use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr index 316f23888bc1f..0b00e098f6d4a 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `NotIntoDiagArg: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive-doc-comment-field.rs:36:10 + --> $DIR/diagnostic-derive-doc-comment-field.rs:37:10 | LL | #[derive(Diagnostic)] | ---------- required by a bound introduced by this call @@ -8,7 +8,7 @@ LL | arg: NotIntoDiagArg, | ^^^^^^^^^^^^^^ unsatisfied trait bound | help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg` - --> $DIR/diagnostic-derive-doc-comment-field.rs:28:1 + --> $DIR/diagnostic-derive-doc-comment-field.rs:29:1 | LL | struct NotIntoDiagArg; | ^^^^^^^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ note: required by a bound in `Diag::<'a, G>::arg` = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `NotIntoDiagArg: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive-doc-comment-field.rs:46:10 + --> $DIR/diagnostic-derive-doc-comment-field.rs:47:10 | LL | #[derive(Subdiagnostic)] | ------------- required by a bound introduced by this call @@ -30,7 +30,7 @@ LL | arg: NotIntoDiagArg, | ^^^^^^^^^^^^^^ unsatisfied trait bound | help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg` - --> $DIR/diagnostic-derive-doc-comment-field.rs:28:1 + --> $DIR/diagnostic-derive-doc-comment-field.rs:29:1 | LL | struct NotIntoDiagArg; | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index fa2d037064d29..fcae379d982fc 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -29,6 +29,8 @@ use rustc_errors::{Applicability, DiagMessage, ErrCode, MultiSpan, SubdiagMessag extern crate rustc_session; +extern crate core; + rustc_fluent_macro::fluent_messages! { "./example.ftl" } // E0123 and E0456 are no longer used, so we define our own constants here just for this test. @@ -56,7 +58,7 @@ enum DiagnosticOnEnum { #[derive(Diagnostic)] #[diag(no_crate_example, code = E0123)] #[diag = "E0123"] -//~^ ERROR failed to resolve: you might be missing crate `core` +//~^ ERROR expected parentheses: #[diag(...)] struct WrongStructAttrStyle {} #[derive(Diagnostic)] @@ -801,7 +803,7 @@ struct SuggestionsNoItem { struct SuggestionsInvalidItem { #[suggestion(code(foo))] //~^ ERROR `code(...)` must contain only string literals - //~| ERROR failed to resolve: you might be missing crate `core` + //~| ERROR unexpected token, expected `)` sub: Span, } @@ -809,7 +811,7 @@ struct SuggestionsInvalidItem { #[diag(no_crate_example)] struct SuggestionsInvalidLiteral { #[suggestion(code = 3)] - //~^ ERROR failed to resolve: you might be missing crate `core` + //~^ ERROR expected string literal sub: Span, } diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 77c48aceca8ec..cf5c0c2e6491f 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -1,11 +1,11 @@ error: derive(Diagnostic): unsupported type attribute for diagnostic derive enum - --> $DIR/diagnostic-derive.rs:47:1 + --> $DIR/diagnostic-derive.rs:49:1 | LL | #[diag(no_crate_example, code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:50:5 + --> $DIR/diagnostic-derive.rs:52:5 | LL | Foo, | ^^^ @@ -13,21 +13,27 @@ LL | Foo, = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:52:5 + --> $DIR/diagnostic-derive.rs:54:5 | LL | Bar, | ^^^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` +error: expected parentheses: #[diag(...)] + --> $DIR/diagnostic-derive.rs:60:8 + | +LL | #[diag = "E0123"] + | ^ + error: derive(Diagnostic): `#[nonsense(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:63:1 + --> $DIR/diagnostic-derive.rs:65:1 | LL | #[nonsense(no_crate_example, code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:63:1 + --> $DIR/diagnostic-derive.rs:65:1 | LL | #[nonsense(no_crate_example, code = E0123)] | ^ @@ -35,7 +41,7 @@ LL | #[nonsense(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:70:1 + --> $DIR/diagnostic-derive.rs:72:1 | LL | #[diag(code = E0123)] | ^ @@ -43,13 +49,13 @@ LL | #[diag(code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug must be the first argument - --> $DIR/diagnostic-derive.rs:80:16 + --> $DIR/diagnostic-derive.rs:82:16 | LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:80:1 + --> $DIR/diagnostic-derive.rs:82:1 | LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] | ^ @@ -57,7 +63,7 @@ LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): unknown argument - --> $DIR/diagnostic-derive.rs:86:8 + --> $DIR/diagnostic-derive.rs:88:8 | LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] | ^^^^^^^^ @@ -65,7 +71,7 @@ LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] = note: only the `code` parameter is valid after the slug error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:86:1 + --> $DIR/diagnostic-derive.rs:88:1 | LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] | ^ @@ -73,7 +79,7 @@ LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): unknown argument - --> $DIR/diagnostic-derive.rs:92:8 + --> $DIR/diagnostic-derive.rs:94:8 | LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] | ^^^^^^^^ @@ -81,7 +87,7 @@ LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] = note: only the `code` parameter is valid after the slug error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:92:1 + --> $DIR/diagnostic-derive.rs:94:1 | LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] | ^ @@ -89,7 +95,7 @@ LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): unknown argument - --> $DIR/diagnostic-derive.rs:98:40 + --> $DIR/diagnostic-derive.rs:100:40 | LL | #[diag(no_crate_example, code = E0123, slug = "foo")] | ^^^^ @@ -97,55 +103,55 @@ LL | #[diag(no_crate_example, code = E0123, slug = "foo")] = note: only the `code` parameter is valid after the slug error: derive(Diagnostic): `#[suggestion = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:105:5 + --> $DIR/diagnostic-derive.rs:107:5 | LL | #[suggestion = "bar"] | ^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:112:8 + --> $DIR/diagnostic-derive.rs:114:8 | LL | #[diag(no_crate_example, code = E0456)] | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:111:8 + --> $DIR/diagnostic-derive.rs:113:8 | LL | #[diag(no_crate_example, code = E0123)] | ^^^^^^^^^^^^^^^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:112:26 + --> $DIR/diagnostic-derive.rs:114:26 | LL | #[diag(no_crate_example, code = E0456)] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:111:26 + --> $DIR/diagnostic-derive.rs:113:26 | LL | #[diag(no_crate_example, code = E0123)] | ^^^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:118:40 + --> $DIR/diagnostic-derive.rs:120:40 | LL | #[diag(no_crate_example, code = E0123, code = E0456)] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:118:26 + --> $DIR/diagnostic-derive.rs:120:26 | LL | #[diag(no_crate_example, code = E0123, code = E0456)] | ^^^^ error: derive(Diagnostic): diagnostic slug must be the first argument - --> $DIR/diagnostic-derive.rs:123:43 + --> $DIR/diagnostic-derive.rs:125:43 | LL | #[diag(no_crate_example, no_crate::example, code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:128:1 + --> $DIR/diagnostic-derive.rs:130:1 | LL | struct KindNotProvided {} | ^^^^^^ @@ -153,7 +159,7 @@ LL | struct KindNotProvided {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:131:1 + --> $DIR/diagnostic-derive.rs:133:1 | LL | #[diag(code = E0123)] | ^ @@ -161,31 +167,31 @@ LL | #[diag(code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:142:5 + --> $DIR/diagnostic-derive.rs:144:5 | LL | #[primary_span] | ^ error: derive(Diagnostic): `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:150:5 + --> $DIR/diagnostic-derive.rs:152:5 | LL | #[nonsense] | ^ error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:167:5 + --> $DIR/diagnostic-derive.rs:169:5 | LL | #[label(no_crate_label)] | ^ error: derive(Diagnostic): `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:175:46 + --> $DIR/diagnostic-derive.rs:177:46 | LL | #[suggestion(no_crate_suggestion, code = "{name}")] | ^^^^^^^^ error: invalid format string: expected `}` but string was terminated - --> $DIR/diagnostic-derive.rs:180:10 + --> $DIR/diagnostic-derive.rs:182:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ expected `}` in format string @@ -194,7 +200,7 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive.rs:190:10 + --> $DIR/diagnostic-derive.rs:192:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ unmatched `}` in format string @@ -203,19 +209,19 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:210:5 + --> $DIR/diagnostic-derive.rs:212:5 | LL | #[label(no_crate_label)] | ^ error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:229:5 + --> $DIR/diagnostic-derive.rs:231:5 | LL | #[suggestion(no_crate_suggestion)] | ^ error: derive(Diagnostic): invalid nested attribute - --> $DIR/diagnostic-derive.rs:237:18 + --> $DIR/diagnostic-derive.rs:239:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^ @@ -223,13 +229,13 @@ LL | #[suggestion(nonsense = "bar")] = help: only `no_span`, `style`, `code` and `applicability` are valid nested attributes error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:237:5 + --> $DIR/diagnostic-derive.rs:239:5 | LL | #[suggestion(nonsense = "bar")] | ^ error: derive(Diagnostic): invalid nested attribute - --> $DIR/diagnostic-derive.rs:246:18 + --> $DIR/diagnostic-derive.rs:248:18 | LL | #[suggestion(msg = "bar")] | ^^^ @@ -237,13 +243,13 @@ LL | #[suggestion(msg = "bar")] = help: only `no_span`, `style`, `code` and `applicability` are valid nested attributes error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:246:5 + --> $DIR/diagnostic-derive.rs:248:5 | LL | #[suggestion(msg = "bar")] | ^ error: derive(Diagnostic): wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:269:5 + --> $DIR/diagnostic-derive.rs:271:5 | LL | #[suggestion(no_crate_suggestion, code = "This is suggested code")] | ^ @@ -251,79 +257,79 @@ LL | #[suggestion(no_crate_suggestion, code = "This is suggested code")] = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:285:24 + --> $DIR/diagnostic-derive.rs:287:24 | LL | suggestion: (Span, Span, Applicability), | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:285:18 + --> $DIR/diagnostic-derive.rs:287:18 | LL | suggestion: (Span, Span, Applicability), | ^^^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:293:33 + --> $DIR/diagnostic-derive.rs:295:33 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:293:18 + --> $DIR/diagnostic-derive.rs:295:18 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ error: derive(Diagnostic): `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:300:5 + --> $DIR/diagnostic-derive.rs:302:5 | LL | #[label = "bar"] | ^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:451:5 + --> $DIR/diagnostic-derive.rs:453:5 | LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] | ^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:453:24 + --> $DIR/diagnostic-derive.rs:455:24 | LL | suggestion: (Span, Applicability), | ^^^^^^^^^^^^^ error: derive(Diagnostic): invalid applicability - --> $DIR/diagnostic-derive.rs:459:69 + --> $DIR/diagnostic-derive.rs:461:69 | LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")] | ^^^^^^^^ error: derive(Diagnostic): the `#[help(...)]` attribute can only be applied to fields of type `Span`, `MultiSpan`, `bool` or `()` - --> $DIR/diagnostic-derive.rs:526:5 + --> $DIR/diagnostic-derive.rs:528:5 | LL | #[help(no_crate_help)] | ^ error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/diagnostic-derive.rs:535:32 + --> $DIR/diagnostic-derive.rs:537:32 | LL | #[label(no_crate_label, foo)] | ^ error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/diagnostic-derive.rs:543:29 + --> $DIR/diagnostic-derive.rs:545:29 | LL | #[label(no_crate_label, foo = "...")] | ^^^ error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/diagnostic-derive.rs:551:29 + --> $DIR/diagnostic-derive.rs:553:29 | LL | #[label(no_crate_label, foo("..."))] | ^^^ error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:563:5 + --> $DIR/diagnostic-derive.rs:565:5 | LL | #[primary_span] | ^ @@ -331,13 +337,13 @@ LL | #[primary_span] = help: the `primary_span` field attribute is not valid for lint diagnostics error: derive(Diagnostic): `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:583:1 + --> $DIR/diagnostic-derive.rs:585:1 | LL | #[error(no_crate_example, code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:583:1 + --> $DIR/diagnostic-derive.rs:585:1 | LL | #[error(no_crate_example, code = E0123)] | ^ @@ -345,13 +351,13 @@ LL | #[error(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:590:1 + --> $DIR/diagnostic-derive.rs:592:1 | LL | #[warn_(no_crate_example, code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:590:1 + --> $DIR/diagnostic-derive.rs:592:1 | LL | #[warn_(no_crate_example, code = E0123)] | ^ @@ -359,13 +365,13 @@ LL | #[warn_(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:597:1 + --> $DIR/diagnostic-derive.rs:599:1 | LL | #[lint(no_crate_example, code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:597:1 + --> $DIR/diagnostic-derive.rs:599:1 | LL | #[lint(no_crate_example, code = E0123)] | ^ @@ -373,13 +379,13 @@ LL | #[lint(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:604:1 + --> $DIR/diagnostic-derive.rs:606:1 | LL | #[lint(no_crate_example, code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:604:1 + --> $DIR/diagnostic-derive.rs:606:1 | LL | #[lint(no_crate_example, code = E0123)] | ^ @@ -387,19 +393,19 @@ LL | #[lint(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:613:53 + --> $DIR/diagnostic-derive.rs:615:53 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:613:39 + --> $DIR/diagnostic-derive.rs:615:39 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive.rs:622:24 + --> $DIR/diagnostic-derive.rs:624:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -407,7 +413,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive.rs:630:17 + --> $DIR/diagnostic-derive.rs:632:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -415,13 +421,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:637:5 + --> $DIR/diagnostic-derive.rs:639:5 | LL | #[suggestion(no_crate_suggestion)] | ^ error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:644:1 + --> $DIR/diagnostic-derive.rs:646:1 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^ @@ -429,7 +435,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:647:1 + --> $DIR/diagnostic-derive.rs:649:1 | LL | #[multipart_suggestion()] | ^ @@ -437,7 +443,7 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:651:5 + --> $DIR/diagnostic-derive.rs:653:5 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^ @@ -445,7 +451,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:659:1 + --> $DIR/diagnostic-derive.rs:661:1 | LL | #[suggestion(no_crate_suggestion, code = "...")] | ^ @@ -453,7 +459,7 @@ LL | #[suggestion(no_crate_suggestion, code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: derive(Diagnostic): `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:668:1 + --> $DIR/diagnostic-derive.rs:670:1 | LL | #[label] | ^ @@ -461,61 +467,73 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:702:5 + --> $DIR/diagnostic-derive.rs:704:5 | LL | #[subdiagnostic(bad)] | ^ error: derive(Diagnostic): `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:710:5 + --> $DIR/diagnostic-derive.rs:712:5 | LL | #[subdiagnostic = "bad"] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:718:5 + --> $DIR/diagnostic-derive.rs:720:5 | LL | #[subdiagnostic(bad, bad)] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:726:5 + --> $DIR/diagnostic-derive.rs:728:5 | LL | #[subdiagnostic("bad")] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:734:5 + --> $DIR/diagnostic-derive.rs:736:5 | LL | #[subdiagnostic(eager)] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:742:5 + --> $DIR/diagnostic-derive.rs:744:5 | LL | #[subdiagnostic(eager)] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:763:5 + --> $DIR/diagnostic-derive.rs:765:5 | LL | #[subdiagnostic(eager)] | ^ error: derive(Diagnostic): expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:794:23 + --> $DIR/diagnostic-derive.rs:796:23 | LL | #[suggestion(code())] | ^ error: derive(Diagnostic): `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:802:23 + --> $DIR/diagnostic-derive.rs:804:23 | LL | #[suggestion(code(foo))] | ^^^ +error: unexpected token, expected `)` + --> $DIR/diagnostic-derive.rs:804:23 + | +LL | #[suggestion(code(foo))] + | ^^^ + +error: expected string literal + --> $DIR/diagnostic-derive.rs:813:25 + | +LL | #[suggestion(code = 3)] + | ^ + error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:826:5 + --> $DIR/diagnostic-derive.rs:828:5 | LL | #[suggestion(no_crate_suggestion, code = "")] | ^ @@ -524,38 +542,20 @@ LL | #[suggestion(no_crate_suggestion, code = "")] = help: to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]` = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/diagnostic-derive.rs:58:8 - | -LL | #[diag = "E0123"] - | ^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/diagnostic-derive.rs:802:23 - | -LL | #[suggestion(code(foo))] - | ^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/diagnostic-derive.rs:811:25 - | -LL | #[suggestion(code = 3)] - | ^ you might be missing crate `core` - error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:63:3 + --> $DIR/diagnostic-derive.rs:65:3 | LL | #[nonsense(no_crate_example, code = E0123)] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:150:7 + --> $DIR/diagnostic-derive.rs:152:7 | LL | #[nonsense] | ^^^^^^^^ error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive.rs:583:3 + --> $DIR/diagnostic-derive.rs:585:3 | LL | #[error(no_crate_example, code = E0123)] | ^^^^^ @@ -567,7 +567,7 @@ LL | struct ErrorAttribute {} | error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive.rs:590:3 + --> $DIR/diagnostic-derive.rs:592:3 | LL | #[warn_(no_crate_example, code = E0123)] | ^^^^^ @@ -579,7 +579,7 @@ LL + #[warn(no_crate_example, code = E0123)] | error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:597:3 + --> $DIR/diagnostic-derive.rs:599:3 | LL | #[lint(no_crate_example, code = E0123)] | ^^^^ @@ -591,7 +591,7 @@ LL + #[link(no_crate_example, code = E0123)] | error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:604:3 + --> $DIR/diagnostic-derive.rs:606:3 | LL | #[lint(no_crate_example, code = E0123)] | ^^^^ @@ -603,7 +603,7 @@ LL + #[link(no_crate_example, code = E0123)] | error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:644:3 + --> $DIR/diagnostic-derive.rs:646:3 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ @@ -615,7 +615,7 @@ LL | struct MultipartSuggestion { | error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:647:3 + --> $DIR/diagnostic-derive.rs:649:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ @@ -627,7 +627,7 @@ LL | struct MultipartSuggestion { | error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:651:7 + --> $DIR/diagnostic-derive.rs:653:7 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ @@ -635,13 +635,13 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = note: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated` - --> $DIR/diagnostic-derive.rs:75:8 + --> $DIR/diagnostic-derive.rs:77:8 | LL | #[diag(nonsense, code = E0123)] | ^^^^^^^^ not found in `crate::fluent_generated` error[E0425]: cannot find value `__code_34` in this scope - --> $DIR/diagnostic-derive.rs:808:10 + --> $DIR/diagnostic-derive.rs:810:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ not found in this scope @@ -649,7 +649,7 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `Hello: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive.rs:349:12 + --> $DIR/diagnostic-derive.rs:351:12 | LL | #[derive(Diagnostic)] | ---------- required by a bound introduced by this call @@ -658,7 +658,7 @@ LL | other: Hello, | ^^^^^ unsatisfied trait bound | help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `Hello` - --> $DIR/diagnostic-derive.rs:40:1 + --> $DIR/diagnostic-derive.rs:42:1 | LL | struct Hello {} | ^^^^^^^^^^^^ @@ -672,5 +672,5 @@ note: required by a bound in `Diag::<'a, G>::arg` error: aborting due to 85 previous errors -Some errors have detailed explanations: E0277, E0425, E0433. +Some errors have detailed explanations: E0277, E0425. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.rs new file mode 100644 index 0000000000000..f42fe16898428 --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.rs @@ -0,0 +1,37 @@ +//@ check-fail +// Tests error conditions for specifying subdiagnostics using #[derive(Subdiagnostic)]. +// This test is split off from the main `subdiagnostic-derive`, +// because this error is generated post-expansion. + +// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, +// changing the output of this test. Since Subdiagnostic is strictly internal to the compiler +// the test is just ignored on stable and beta: +//@ ignore-stage1 +//@ ignore-beta +//@ ignore-stable + +#![feature(rustc_private)] +#![crate_type = "lib"] + +extern crate rustc_errors; +extern crate rustc_fluent_macro; +extern crate rustc_macros; +extern crate rustc_session; +extern crate rustc_span; +extern crate core; + +use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; +use rustc_macros::Subdiagnostic; +use rustc_span::Span; + +rustc_fluent_macro::fluent_messages! { "./example.ftl" } + +#[derive(Subdiagnostic)] +#[label(slug)] +//~^ ERROR cannot find value `slug` in module `crate::fluent_generated` +//~^^ NOTE not found in `crate::fluent_generated` +struct L { + #[primary_span] + span: Span, + var: String, +} diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.stderr new file mode 100644 index 0000000000000..37566e39fcd67 --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `slug` in module `crate::fluent_generated` + --> $DIR/subdiagnostic-derive-2.rs:30:9 + | +LL | #[label(slug)] + | ^^^^ not found in `crate::fluent_generated` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index c837372a7a7a7..941668ad602e4 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -16,6 +16,7 @@ extern crate rustc_fluent_macro; extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; +extern crate core; use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; use rustc_macros::Subdiagnostic; @@ -94,8 +95,7 @@ struct G { #[derive(Subdiagnostic)] #[label("...")] -//~^ ERROR failed to resolve: you might be missing crate `core` -//~| NOTE you might be missing crate `core` +//~^ ERROR unexpected literal in nested attribute, expected ident struct H { #[primary_span] span: Span, @@ -122,16 +122,6 @@ struct K { var: String, } -#[derive(Subdiagnostic)] -#[label(slug)] -//~^ ERROR cannot find value `slug` in module `crate::fluent_generated` -//~^^ NOTE not found in `crate::fluent_generated` -struct L { - #[primary_span] - span: Span, - var: String, -} - #[derive(Subdiagnostic)] #[label()] //~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute @@ -310,8 +300,7 @@ struct AB { #[derive(Subdiagnostic)] union AC { - //~^ ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` + //~^ ERROR unexpected unsupported untagged union span: u32, b: u64, } @@ -581,8 +570,7 @@ struct BD { span2: Span, #[suggestion_part(foo = "bar")] //~^ ERROR `code` is the only valid nested attribute - //~| ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` + //~| ERROR expected `,` span4: Span, #[suggestion_part(code = "...")] //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` @@ -674,8 +662,7 @@ enum BL { struct BM { #[suggestion_part(code("foo"))] //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` + //~| ERROR unexpected token, expected `)` span: Span, r#type: String, } @@ -685,8 +672,7 @@ struct BM { struct BN { #[suggestion_part(code("foo", "bar"))] //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` + //~| ERROR unexpected token, expected `)` span: Span, r#type: String, } @@ -696,8 +682,7 @@ struct BN { struct BO { #[suggestion_part(code(3))] //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` + //~| ERROR unexpected token, expected `)` span: Span, r#type: String, } @@ -712,14 +697,10 @@ struct BP { } #[derive(Subdiagnostic)] -//~^ ERROR cannot find value `__code_29` in this scope -//~| NOTE in this expansion -//~| NOTE not found in this scope #[multipart_suggestion(no_crate_example)] struct BQ { #[suggestion_part(code = 3)] - //~^ ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` + //~^ ERROR expected string literal span: Span, r#type: String, } @@ -811,8 +792,7 @@ struct SuggestionStyleInvalid3 { #[derive(Subdiagnostic)] #[suggestion(no_crate_example, code = "", style("foo"))] //~^ ERROR expected `= "xxx"` -//~| ERROR failed to resolve: you might be missing crate `core` -//~| NOTE you might be missing crate `core` +//~| ERROR expected `,` struct SuggestionStyleInvalid4 { #[primary_span] sub: Span, diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index 0ae7ba4c4973d..c31da4421d255 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -1,39 +1,45 @@ error: derive(Diagnostic): label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:51:1 + --> $DIR/subdiagnostic-derive.rs:52:1 | LL | #[label(no_crate_example)] | ^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:58:1 + --> $DIR/subdiagnostic-derive.rs:59:1 | LL | #[label] | ^ error: derive(Diagnostic): `#[foo]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:67:1 + --> $DIR/subdiagnostic-derive.rs:68:1 | LL | #[foo] | ^ error: derive(Diagnostic): `#[label = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:77:1 + --> $DIR/subdiagnostic-derive.rs:78:1 | LL | #[label = "..."] | ^ error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:86:9 + --> $DIR/subdiagnostic-derive.rs:87:9 | LL | #[label(bug = "...")] | ^^^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:86:1 + --> $DIR/subdiagnostic-derive.rs:87:1 | LL | #[label(bug = "...")] | ^ +error: unexpected literal in nested attribute, expected ident + --> $DIR/subdiagnostic-derive.rs:97:9 + | +LL | #[label("...")] + | ^^^^^ + error: derive(Diagnostic): only `no_span` is a valid nested attribute --> $DIR/subdiagnostic-derive.rs:106:9 | @@ -59,85 +65,85 @@ LL | #[label(slug("..."))] | ^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:136:1 + --> $DIR/subdiagnostic-derive.rs:126:1 | LL | #[label()] | ^ error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:145:27 + --> $DIR/subdiagnostic-derive.rs:135:27 | LL | #[label(no_crate_example, code = "...")] | ^^^^ error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:154:27 + --> $DIR/subdiagnostic-derive.rs:144:27 | LL | #[label(no_crate_example, applicability = "machine-applicable")] | ^^^^^^^^^^^^^ error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:163:1 + --> $DIR/subdiagnostic-derive.rs:153:1 | LL | #[foo] | ^ error: derive(Diagnostic): `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:177:5 + --> $DIR/subdiagnostic-derive.rs:167:5 | LL | #[bar] | ^ error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:189:5 + --> $DIR/subdiagnostic-derive.rs:179:5 | LL | #[bar = "..."] | ^ error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:201:5 + --> $DIR/subdiagnostic-derive.rs:191:5 | LL | #[bar = 4] | ^ error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:213:5 + --> $DIR/subdiagnostic-derive.rs:203:5 | LL | #[bar("...")] | ^ error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:225:13 + --> $DIR/subdiagnostic-derive.rs:215:13 | LL | #[label(code = "...")] | ^^^^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:225:5 + --> $DIR/subdiagnostic-derive.rs:215:5 | LL | #[label(code = "...")] | ^ error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:254:5 + --> $DIR/subdiagnostic-derive.rs:244:5 | LL | #[primary_span] | ^ error: derive(Diagnostic): label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:251:1 + --> $DIR/subdiagnostic-derive.rs:241:1 | LL | #[label(no_crate_example)] | ^ error: derive(Diagnostic): `#[applicability]` is only valid on suggestions - --> $DIR/subdiagnostic-derive.rs:264:5 + --> $DIR/subdiagnostic-derive.rs:254:5 | LL | #[applicability] | ^ error: derive(Diagnostic): `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:274:5 + --> $DIR/subdiagnostic-derive.rs:264:5 | LL | #[bar] | ^ @@ -145,111 +151,121 @@ LL | #[bar] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:285:5 + --> $DIR/subdiagnostic-derive.rs:275:5 | LL | #[bar = "..."] | ^ error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:296:5 + --> $DIR/subdiagnostic-derive.rs:286:5 | LL | #[bar("...")] | ^ | = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes +error: unexpected unsupported untagged union + --> $DIR/subdiagnostic-derive.rs:302:1 + | +LL | / union AC { +LL | | +LL | | span: u32, +LL | | b: u64, +LL | | } + | |_^ + error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:328:44 + --> $DIR/subdiagnostic-derive.rs:317:44 | LL | #[label(no_crate_example, no_crate::example)] | ^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:341:5 + --> $DIR/subdiagnostic-derive.rs:330:5 | LL | #[primary_span] | ^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:338:5 + --> $DIR/subdiagnostic-derive.rs:327:5 | LL | #[primary_span] | ^ error: derive(Diagnostic): subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive.rs:347:8 + --> $DIR/subdiagnostic-derive.rs:336:8 | LL | struct AG { | ^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:384:46 + --> $DIR/subdiagnostic-derive.rs:373:46 | LL | #[suggestion(no_crate_example, code = "...", code = "...")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:384:32 + --> $DIR/subdiagnostic-derive.rs:373:32 | LL | #[suggestion(no_crate_example, code = "...", code = "...")] | ^^^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:402:5 + --> $DIR/subdiagnostic-derive.rs:391:5 | LL | #[applicability] | ^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:399:5 + --> $DIR/subdiagnostic-derive.rs:388:5 | LL | #[applicability] | ^ error: derive(Diagnostic): the `#[applicability]` attribute can only be applied to fields of type `Applicability` - --> $DIR/subdiagnostic-derive.rs:412:5 + --> $DIR/subdiagnostic-derive.rs:401:5 | LL | #[applicability] | ^ error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:425:1 + --> $DIR/subdiagnostic-derive.rs:414:1 | LL | #[suggestion(no_crate_example)] | ^ error: derive(Diagnostic): invalid applicability - --> $DIR/subdiagnostic-derive.rs:435:62 + --> $DIR/subdiagnostic-derive.rs:424:62 | LL | #[suggestion(no_crate_example, code = "...", applicability = "foo")] | ^^^^^ error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:453:1 + --> $DIR/subdiagnostic-derive.rs:442:1 | LL | #[suggestion(no_crate_example, code = "...")] | ^ error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:467:1 + --> $DIR/subdiagnostic-derive.rs:456:1 | LL | #[label] | ^ error: derive(Diagnostic): `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:487:39 + --> $DIR/subdiagnostic-derive.rs:476:39 | LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: derive(Diagnostic): `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:506:43 + --> $DIR/subdiagnostic-derive.rs:495:43 | LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: derive(Diagnostic): `#[suggestion_part]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:529:5 + --> $DIR/subdiagnostic-derive.rs:518:5 | LL | #[suggestion_part] | ^ @@ -257,7 +273,7 @@ LL | #[suggestion_part] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead error: derive(Diagnostic): `#[suggestion_part(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:532:5 + --> $DIR/subdiagnostic-derive.rs:521:5 | LL | #[suggestion_part(code = "...")] | ^ @@ -265,13 +281,13 @@ LL | #[suggestion_part(code = "...")] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:526:1 + --> $DIR/subdiagnostic-derive.rs:515:1 | LL | #[suggestion(no_crate_example, code = "...")] | ^ error: derive(Diagnostic): invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:541:42 + --> $DIR/subdiagnostic-derive.rs:530:42 | LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] | ^^^^ @@ -279,25 +295,25 @@ LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "mac = help: only `no_span`, `style` and `applicability` are valid nested attributes error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:541:1 + --> $DIR/subdiagnostic-derive.rs:530:1 | LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] | ^ error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:551:5 + --> $DIR/subdiagnostic-derive.rs:540:5 | LL | #[suggestion_part] | ^ error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:559:5 + --> $DIR/subdiagnostic-derive.rs:548:5 | LL | #[suggestion_part()] | ^ error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:568:5 + --> $DIR/subdiagnostic-derive.rs:557:5 | LL | #[primary_span] | ^ @@ -305,97 +321,127 @@ LL | #[primary_span] = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:565:1 + --> $DIR/subdiagnostic-derive.rs:554:1 | LL | #[multipart_suggestion(no_crate_example)] | ^ error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:576:5 + --> $DIR/subdiagnostic-derive.rs:565:5 | LL | #[suggestion_part] | ^ error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:579:5 + --> $DIR/subdiagnostic-derive.rs:568:5 | LL | #[suggestion_part()] | ^ error: derive(Diagnostic): `code` is the only valid nested attribute - --> $DIR/subdiagnostic-derive.rs:582:23 + --> $DIR/subdiagnostic-derive.rs:571:23 | LL | #[suggestion_part(foo = "bar")] | ^^^ error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:587:5 + --> $DIR/subdiagnostic-derive.rs:575:5 | LL | #[suggestion_part(code = "...")] | ^ error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:590:5 + --> $DIR/subdiagnostic-derive.rs:578:5 | LL | #[suggestion_part()] | ^ +error: expected `,` + --> $DIR/subdiagnostic-derive.rs:571:27 + | +LL | #[suggestion_part(foo = "bar")] + | ^ + error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:598:37 + --> $DIR/subdiagnostic-derive.rs:586:37 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:598:23 + --> $DIR/subdiagnostic-derive.rs:586:23 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ error: derive(Diagnostic): `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."` - --> $DIR/subdiagnostic-derive.rs:627:5 + --> $DIR/subdiagnostic-derive.rs:615:5 | LL | #[applicability] | ^ error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:675:34 + --> $DIR/subdiagnostic-derive.rs:663:34 | LL | #[suggestion_part(code("foo"))] | ^ +error: unexpected token, expected `)` + --> $DIR/subdiagnostic-derive.rs:663:28 + | +LL | #[suggestion_part(code("foo"))] + | ^^^^^ + error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:686:41 + --> $DIR/subdiagnostic-derive.rs:673:41 | LL | #[suggestion_part(code("foo", "bar"))] | ^ +error: unexpected token, expected `)` + --> $DIR/subdiagnostic-derive.rs:673:28 + | +LL | #[suggestion_part(code("foo", "bar"))] + | ^^^^^ + error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:697:30 + --> $DIR/subdiagnostic-derive.rs:683:30 | LL | #[suggestion_part(code(3))] | ^ +error: unexpected token, expected `)` + --> $DIR/subdiagnostic-derive.rs:683:28 + | +LL | #[suggestion_part(code(3))] + | ^ + error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:708:29 + --> $DIR/subdiagnostic-derive.rs:693:29 | LL | #[suggestion_part(code())] | ^ +error: expected string literal + --> $DIR/subdiagnostic-derive.rs:702:30 + | +LL | #[suggestion_part(code = 3)] + | ^ + error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:763:1 + --> $DIR/subdiagnostic-derive.rs:744:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] | ^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:763:1 + --> $DIR/subdiagnostic-derive.rs:744:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] | ^ error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:772:1 + --> $DIR/subdiagnostic-derive.rs:753:1 | LL | #[suggestion_hidden(no_crate_example, code = "")] | ^ @@ -403,7 +449,7 @@ LL | #[suggestion_hidden(no_crate_example, code = "")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:780:1 + --> $DIR/subdiagnostic-derive.rs:761:1 | LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] | ^ @@ -411,7 +457,7 @@ LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: derive(Diagnostic): invalid suggestion style - --> $DIR/subdiagnostic-derive.rs:788:51 + --> $DIR/subdiagnostic-derive.rs:769:51 | LL | #[suggestion(no_crate_example, code = "", style = "foo")] | ^^^^^ @@ -419,25 +465,31 @@ LL | #[suggestion(no_crate_example, code = "", style = "foo")] = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` error: derive(Diagnostic): expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:796:49 + --> $DIR/subdiagnostic-derive.rs:777:49 | LL | #[suggestion(no_crate_example, code = "", style = 42)] | ^ error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:804:48 + --> $DIR/subdiagnostic-derive.rs:785:48 | LL | #[suggestion(no_crate_example, code = "", style)] | ^ error: derive(Diagnostic): expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:812:48 + --> $DIR/subdiagnostic-derive.rs:793:48 + | +LL | #[suggestion(no_crate_example, code = "", style("foo"))] + | ^ + +error: expected `,` + --> $DIR/subdiagnostic-derive.rs:793:48 | LL | #[suggestion(no_crate_example, code = "", style("foo"))] | ^ error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:825:5 + --> $DIR/subdiagnostic-derive.rs:805:5 | LL | #[primary_span] | ^ @@ -446,128 +498,64 @@ LL | #[primary_span] = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:822:1 + --> $DIR/subdiagnostic-derive.rs:802:1 | LL | #[suggestion(no_crate_example, code = "")] | ^ -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:96:9 - | -LL | #[label("...")] - | ^^^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:312:1 - | -LL | union AC { - | ^^^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:582:27 - | -LL | #[suggestion_part(foo = "bar")] - | ^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:675:28 - | -LL | #[suggestion_part(code("foo"))] - | ^^^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:686:28 - | -LL | #[suggestion_part(code("foo", "bar"))] - | ^^^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:697:28 - | -LL | #[suggestion_part(code(3))] - | ^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:720:30 - | -LL | #[suggestion_part(code = 3)] - | ^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:812:48 - | -LL | #[suggestion(no_crate_example, code = "", style("foo"))] - | ^ you might be missing crate `core` - error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:67:3 + --> $DIR/subdiagnostic-derive.rs:68:3 | LL | #[foo] | ^^^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:163:3 + --> $DIR/subdiagnostic-derive.rs:153:3 | LL | #[foo] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:177:7 + --> $DIR/subdiagnostic-derive.rs:167:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:189:7 + --> $DIR/subdiagnostic-derive.rs:179:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:201:7 + --> $DIR/subdiagnostic-derive.rs:191:7 | LL | #[bar = 4] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:213:7 + --> $DIR/subdiagnostic-derive.rs:203:7 | LL | #[bar("...")] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:274:7 + --> $DIR/subdiagnostic-derive.rs:264:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:285:7 + --> $DIR/subdiagnostic-derive.rs:275:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:296:7 + --> $DIR/subdiagnostic-derive.rs:286:7 | LL | #[bar("...")] | ^^^ -error[E0425]: cannot find value `slug` in module `crate::fluent_generated` - --> $DIR/subdiagnostic-derive.rs:126:9 - | -LL | #[label(slug)] - | ^^^^ not found in `crate::fluent_generated` - -error[E0425]: cannot find value `__code_29` in this scope - --> $DIR/subdiagnostic-derive.rs:714:10 - | -LL | #[derive(Subdiagnostic)] - | ^^^^^^^^^^^^^ not found in this scope - | - = note: this error originates in the derive macro `Subdiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 86 previous errors +error: aborting due to 84 previous errors -Some errors have detailed explanations: E0425, E0433. -For more information about an error, try `rustc --explain E0425`.