diff --git a/Cargo.lock b/Cargo.lock index c7c95a33bc86f..63c7d97bce43f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -184,9 +184,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "askama" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7125972258312e79827b60c9eb93938334100245081cf701a2dee981b17427" +checksum = "03341eae1125472b0672fbf35cc9aa7b74cd8e0c3d02f02c28a04678f12aaa7a" dependencies = [ "askama_macros", "itoa", @@ -197,9 +197,9 @@ dependencies = [ [[package]] name = "askama_derive" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba5e7259a1580c61571e3116ebaaa01e3c001b2132b17c4cc5c70780ca3e994" +checksum = "461bd78f3da90b5e44eee4272cfb1c4832aa3dcdb6c370aedd3eb253d2b9e3ca" dependencies = [ "askama_parser", "basic-toml", @@ -214,18 +214,18 @@ dependencies = [ [[package]] name = "askama_macros" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "236ce20b77cb13506eaf5024899f4af6e12e8825f390bd943c4c37fd8f322e46" +checksum = "ba49fb22ee3074574b8510abd9495d4f0bb9b8f87e8e45ee31e2cee508f7a8e5" dependencies = [ "askama_derive", ] [[package]] name = "askama_parser" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c63392767bb2df6aa65a6e1e3b80fd89bb7af6d58359b924c0695620f1512e" +checksum = "7e33eb7484958aaa1f27e9adb556f5d557331cd891bdbb33781bc1f9550b6f6e" dependencies = [ "rustc-hash 2.1.1", "serde", 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_const_eval/src/const_eval/dyn_trait.rs b/compiler/rustc_const_eval/src/const_eval/dyn_trait.rs new file mode 100644 index 0000000000000..0976a7283ef37 --- /dev/null +++ b/compiler/rustc_const_eval/src/const_eval/dyn_trait.rs @@ -0,0 +1,178 @@ +use rustc_middle::mir::interpret::{CtfeProvenance, InterpResult, Scalar, interp_ok}; +use rustc_middle::ty::{Region, Ty}; +use rustc_middle::{span_bug, ty}; +use rustc_span::def_id::DefId; +use rustc_span::sym; + +use crate::const_eval::CompileTimeMachine; +use crate::interpret::{Immediate, InterpCx, MPlaceTy, MemoryKind, Writeable}; +impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { + pub(crate) fn write_dyn_trait_type_info( + &mut self, + dyn_place: impl Writeable<'tcx, CtfeProvenance>, + data: &'tcx ty::List>>, + region: Region<'tcx>, + ) -> InterpResult<'tcx> { + let tcx = self.tcx.tcx; + + // Find the principal trait ref (for super trait collection), collect auto traits, + // and collect all projection predicates (used when computing TypeId for each supertrait). + let mut principal: Option>> = None; + let mut auto_traits_def_ids: Vec> = Vec::new(); + let mut projections: Vec>> = Vec::new(); + + for b in data.iter() { + match b.skip_binder() { + ty::ExistentialPredicate::Trait(tr) => principal = Some(b.rebind(tr)), + ty::ExistentialPredicate::AutoTrait(did) => auto_traits_def_ids.push(b.rebind(did)), + ty::ExistentialPredicate::Projection(p) => projections.push(b.rebind(p)), + } + } + + // This is to make principal dyn type include Trait and projection predicates, excluding auto traits. + let principal_ty: Option> = principal.map(|_tr| { + let preds = tcx + .mk_poly_existential_predicates_from_iter(data.iter().filter(|b| { + !matches!(b.skip_binder(), ty::ExistentialPredicate::AutoTrait(_)) + })); + Ty::new_dynamic(tcx, preds, region) + }); + + // DynTrait { predicates: &'static [Trait] } + for (field_idx, field) in + dyn_place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&dyn_place, field_idx)?; + match field.name { + sym::predicates => { + self.write_dyn_trait_predicates_slice( + &field_place, + principal_ty, + &auto_traits_def_ids, + region, + )?; + } + other => { + span_bug!(self.tcx.def_span(field.did), "unimplemented DynTrait field {other}") + } + } + } + + interp_ok(()) + } + + fn mk_dyn_principal_auto_trait_ty( + &self, + auto_trait_def_id: ty::Binder<'tcx, DefId>, + region: Region<'tcx>, + ) -> Ty<'tcx> { + let tcx = self.tcx.tcx; + + // Preserve the binder vars from the original auto-trait predicate. + let pred_inner = ty::ExistentialPredicate::AutoTrait(auto_trait_def_id.skip_binder()); + let pred = ty::Binder::bind_with_vars(pred_inner, auto_trait_def_id.bound_vars()); + + let preds = tcx.mk_poly_existential_predicates_from_iter([pred].into_iter()); + Ty::new_dynamic(tcx, preds, region) + } + + fn write_dyn_trait_predicates_slice( + &mut self, + slice_place: &impl Writeable<'tcx, CtfeProvenance>, + principal_ty: Option>, + auto_trait_def_ids: &[ty::Binder<'tcx, DefId>], + region: Region<'tcx>, + ) -> InterpResult<'tcx> { + let tcx = self.tcx.tcx; + + // total entries in DynTrait predicates + let total_len = principal_ty.map(|_| 1).unwrap_or(0) + auto_trait_def_ids.len(); + + // element type = DynTraitPredicate + let slice_ty = slice_place.layout().ty.builtin_deref(false).unwrap(); // [DynTraitPredicate] + let elem_ty = slice_ty.sequence_element_type(tcx); // DynTraitPredicate + + let arr_layout = self.layout_of(Ty::new_array(tcx, elem_ty, total_len as u64))?; + let arr_place = self.allocate(arr_layout, MemoryKind::Stack)?; + let mut elems = self.project_array_fields(&arr_place)?; + + // principal entry (if any) - NOT an auto trait + if let Some(principal_ty) = principal_ty { + let Some((_i, elem_place)) = elems.next(self)? else { + span_bug!(self.tcx.span, "DynTrait.predicates length computed wrong (principal)"); + }; + self.write_dyn_trait_predicate(elem_place, principal_ty, false)?; + } + + // auto trait entries - these ARE auto traits + for auto in auto_trait_def_ids { + let Some((_i, elem_place)) = elems.next(self)? else { + span_bug!(self.tcx.span, "DynTrait.predicates length computed wrong (auto)"); + }; + let auto_ty = self.mk_dyn_principal_auto_trait_ty(*auto, region); + self.write_dyn_trait_predicate(elem_place, auto_ty, true)?; + } + + let arr_place = arr_place.map_provenance(CtfeProvenance::as_immutable); + let imm = Immediate::new_slice(arr_place.ptr(), total_len as u64, self); + self.write_immediate(imm, slice_place) + } + + fn write_dyn_trait_predicate( + &mut self, + predicate_place: MPlaceTy<'tcx>, + trait_ty: Ty<'tcx>, + is_auto: bool, + ) -> InterpResult<'tcx> { + // DynTraitPredicate { trait_ty: Trait } + for (field_idx, field) in predicate_place + .layout + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .iter_enumerated() + { + let field_place = self.project_field(&predicate_place, field_idx)?; + match field.name { + sym::trait_ty => { + // Now write the Trait struct + self.write_trait(field_place, trait_ty, is_auto)?; + } + other => { + span_bug!( + self.tcx.def_span(field.did), + "unimplemented DynTraitPredicate field {other}" + ) + } + } + } + interp_ok(()) + } + fn write_trait( + &mut self, + trait_place: MPlaceTy<'tcx>, + trait_ty: Ty<'tcx>, + is_auto: bool, + ) -> InterpResult<'tcx> { + // Trait { ty: TypeId, is_auto: bool } + for (field_idx, field) in + trait_place.layout.ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&trait_place, field_idx)?; + match field.name { + sym::ty => { + self.write_type_id(trait_ty, &field_place)?; + } + sym::is_auto => { + self.write_scalar(Scalar::from_bool(is_auto), &field_place)?; + } + other => { + span_bug!(self.tcx.def_span(field.did), "unimplemented Trait field {other}") + } + } + } + interp_ok(()) + } +} diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index e70488b81c4ce..c17ff8621a50b 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -9,6 +9,7 @@ use tracing::instrument; use crate::interpret::InterpCx; mod dummy_machine; +mod dyn_trait; mod error; mod eval_queries; mod fn_queries; diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 3fcf6f94b5bf3..f8881f0968bb4 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -129,13 +129,18 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } + ty::Dynamic(predicates, region) => { + let (variant, variant_place) = downcast(sym::DynTrait)?; + let dyn_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_dyn_trait_type_info(dyn_place, *predicates, *region)?; + variant + } ty::Adt(_, _) | ty::Foreign(_) | ty::Pat(_, _) | ty::FnDef(..) | ty::FnPtr(..) | ty::UnsafeBinder(..) - | ty::Dynamic(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) 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/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c4391c3ec4fc4..1ebada3c285e7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -186,6 +186,7 @@ symbols! { AtomicU64, AtomicU128, AtomicUsize, + AutoTrait, BTreeEntry, BTreeMap, BTreeSet, @@ -231,6 +232,7 @@ symbols! { Display, DoubleEndedIterator, Duration, + DynTrait, Encodable, Encoder, Enumerate, @@ -1297,6 +1299,7 @@ symbols! { io_stdout, irrefutable_let_patterns, is, + is_auto, is_val_statically_known, isa_attribute, isize, @@ -1750,6 +1753,7 @@ symbols! { precise_capturing_in_traits, precise_pointer_size_matching, precision, + predicates, pref_align_of, prefetch_read_data, prefetch_read_instruction, @@ -2297,6 +2301,7 @@ symbols! { trace_macros, track_caller, trait_alias, + trait_ty, trait_upcasting, transmute, transmute_generic_consts, 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/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 30a70165b095f..8b30803c97c98 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -47,6 +47,8 @@ pub enum TypeKind { Array(Array), /// Slices. Slice(Slice), + /// Dynamic Traits. + DynTrait(DynTrait), /// Primitive boolean type. Bool(Bool), /// Primitive character type. @@ -105,6 +107,36 @@ pub struct Slice { pub element_ty: TypeId, } +/// Compile-time type information about dynamic traits. +/// FIXME(#146922): Add super traits and generics +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct DynTrait { + /// The predicates of a dynamic trait. + pub predicates: &'static [DynTraitPredicate], +} + +/// Compile-time type information about a dynamic trait predicate. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct DynTraitPredicate { + /// The type of the trait as a dynamic trait type. + pub trait_ty: Trait, +} + +/// Compile-time type information about a trait. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Trait { + /// The TypeId of the trait as a dynamic type + pub ty: TypeId, + /// Whether the trait is an auto trait + pub is_auto: bool, +} + /// Compile-time type information about `bool`. #[derive(Debug)] #[non_exhaustive] diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 0820e4f839930..87f2d5dd8289c 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -163,3 +163,132 @@ fn test_pointers() { _ => unreachable!(), } } + +#[test] +fn test_dynamic_traits() { + use std::collections::HashSet; + use std::mem::type_info::DynTraitPredicate; + trait A {} + + trait B { + type Foo; + } + + trait FooTrait<'a, 'b, const CONST_NUM: i32> {} + + trait ProjectorTrait<'a, 'b> {} + + fn preds_of() -> &'static [DynTraitPredicate] { + match const { Type::of::() }.kind { + TypeKind::DynTrait(d) => d.predicates, + _ => unreachable!(), + } + } + + fn pred<'a>(preds: &'a [DynTraitPredicate], want: TypeId) -> &'a DynTraitPredicate { + preds + .iter() + .find(|p| p.trait_ty.ty == want) + .unwrap_or_else(|| panic!("missing predicate for {want:?}")) + } + + fn assert_typeid_set_eq(actual: &[TypeId], expected: &[TypeId]) { + let actual_set: HashSet = actual.iter().copied().collect(); + let expected_set: HashSet = expected.iter().copied().collect(); + assert_eq!(actual.len(), actual_set.len(), "duplicates present: {actual:?}"); + assert_eq!( + actual_set, expected_set, + "unexpected ids.\nactual: {actual:?}\nexpected: {expected:?}" + ); + } + + fn assert_predicates_exact(preds: &[DynTraitPredicate], expected_pred_ids: &[TypeId]) { + let actual_pred_ids: Vec = preds.iter().map(|p| p.trait_ty.ty).collect(); + assert_typeid_set_eq(&actual_pred_ids, expected_pred_ids); + } + + // dyn Send + { + let preds = preds_of::(); + assert_predicates_exact(preds, &[TypeId::of::()]); + + let p = pred(preds, TypeId::of::()); + assert!(p.trait_ty.is_auto); + } + + // dyn A + { + let preds = preds_of::>(); + assert_predicates_exact(preds, &[TypeId::of::>()]); + + let p = pred(preds, TypeId::of::>()); + assert!(!p.trait_ty.is_auto); + } + + // dyn B<5, Foo = i32> + { + let preds = preds_of::>(); + assert_predicates_exact(preds, &[TypeId::of::>()]); + + let e = pred(preds, TypeId::of::>()); + assert!(!e.trait_ty.is_auto); + } + + // dyn for<'a> FooTrait<'a, 'a, 7> + { + let preds = preds_of:: FooTrait<'a, 'a, 7>>(); + assert_predicates_exact(preds, &[TypeId::of:: FooTrait<'a, 'a, 7>>()]); + + let foo = pred(preds, TypeId::of:: FooTrait<'a, 'a, 7>>()); + assert!(!foo.trait_ty.is_auto); + } + + // dyn FooTrait<'static, 'static, 7> + { + let preds = preds_of::>(); + assert_predicates_exact(preds, &[TypeId::of::>()]); + + let foo = pred(preds, TypeId::of::>()); + assert!(!foo.trait_ty.is_auto); + } + + // dyn for<'a, 'b> FooTrait<'a, 'b, 7> + { + let preds = preds_of:: FooTrait<'a, 'b, 7>>(); + assert_predicates_exact(preds, &[TypeId::of:: FooTrait<'a, 'b, 7>>()]); + + let foo = pred(preds, TypeId::of:: FooTrait<'a, 'b, 7>>()); + assert!(!foo.trait_ty.is_auto); + } + + // dyn for<'a, 'b> ProjectorTrait<'a, 'b> + { + let preds = preds_of:: ProjectorTrait<'a, 'b>>(); + assert_predicates_exact(preds, &[TypeId::of:: ProjectorTrait<'a, 'b>>()]); + + let proj = pred(preds, TypeId::of:: ProjectorTrait<'a, 'b>>()); + assert!(!proj.trait_ty.is_auto); + } + + // dyn for<'a> FooTrait<'a, 'a, 7> + Send + Sync + { + let preds = preds_of:: FooTrait<'a, 'a, 7> + Send + Sync>(); + assert_predicates_exact( + preds, + &[ + TypeId::of:: FooTrait<'a, 'a, 7>>(), + TypeId::of::(), + TypeId::of::(), + ], + ); + + let foo = pred(preds, TypeId::of:: FooTrait<'a, 'a, 7>>()); + assert!(!foo.trait_ty.is_auto); + + let send = pred(preds, TypeId::of::()); + assert!(send.trait_ty.is_auto); + + let sync = pred(preds, TypeId::of::()); + assert!(sync.trait_ty.is_auto); + } +} 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/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index f983c59f9bf8c..8bbd03ac3afa9 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -87,7 +87,7 @@ impl Step for Std { Mode::Std, SourceType::InTree, target, - Kind::Check, + builder.config.cmd.kind(), ); std_cargo(builder, target, &mut cargo, &self.crates); @@ -97,7 +97,7 @@ impl Step for Std { } let _guard = builder.msg( - Kind::Check, + builder.config.cmd.kind(), format_args!("library artifacts{}", crate_description(&self.crates)), Mode::Std, build_compiler, diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index 539edf60033a5..b394c6fbefffc 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] anyhow = "1" -askama = "0.15.1" +askama = "0.15.2" clap = { version = "4.5", features = ["derive"] } csv = "1" diff = "0.1" diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 3c5d01c7201bc..43006435fcdee 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" [dependencies] # tidy-alphabetical-start arrayvec = { version = "0.7", default-features = false } -askama = { version = "0.15.1", default-features = false, features = ["alloc", "config", "derive"] } +askama = { version = "0.15.2", default-features = false, features = ["alloc", "config", "derive"] } base64 = "0.21.7" indexmap = { version = "2", features = ["serde"] } itertools = "0.12" diff --git a/src/tools/generate-copyright/Cargo.toml b/src/tools/generate-copyright/Cargo.toml index 66b9f394409be..e1a5ca31a1db6 100644 --- a/src/tools/generate-copyright/Cargo.toml +++ b/src/tools/generate-copyright/Cargo.toml @@ -8,7 +8,7 @@ description = "Produces a manifest of all the copyrighted materials in the Rust [dependencies] anyhow = "1.0.65" -askama = "0.15.1" +askama = "0.15.2" cargo_metadata = "0.21" serde = { version = "1.0.147", features = ["derive"] } serde_json = "1.0.85" 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/mir-opt/simplify_match.rs b/tests/mir-opt/simplify_match.rs index b035b6339fae9..ca9dac40aa917 100644 --- a/tests/mir-opt/simplify_match.rs +++ b/tests/mir-opt/simplify_match.rs @@ -1,9 +1,15 @@ -// skip-filecheck +//! Test that GVN propagates the constant `false` and eliminates the match. // EMIT_MIR_FOR_EACH_PANIC_STRATEGY + #[inline(never)] fn noop() {} // EMIT_MIR simplify_match.main.GVN.diff +// CHECK-LABEL: fn main( +// CHECK: debug x => const false; +// CHECK-NOT: switchInt +// CHECK: bb0: { +// CHECK-NEXT: return; fn main() { match { let x = false; diff --git a/tests/run-make/crate-loading/multiple-dep-versions.stderr b/tests/run-make/crate-loading/multiple-dep-versions.stderr index f8f8bfaaff6f5..ef7fb70822665 100644 --- a/tests/run-make/crate-loading/multiple-dep-versions.stderr +++ b/tests/run-make/crate-loading/multiple-dep-versions.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied +error[E0277]: the trait bound `dep_2_reexport::Type: dependency::Trait` is not satisfied --> replaced | LL | do_something(Type); - | ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type` + | ------------ ^^^^ the trait `dependency::Trait` is not implemented for `dep_2_reexport::Type` | | | required by a bound introduced by this call | @@ -17,7 +17,7 @@ LL | pub trait Trait { LL | pub trait Trait { | --------------- this is the found trait = help: you can use `cargo tree` to explore your dependency tree -help: the trait `Trait` is implemented for `dependency::Type` +help: the trait `dependency::Trait` is implemented for `dependency::Type` --> replaced | LL | impl Trait for Type { @@ -64,11 +64,11 @@ LL | pub trait Trait { | --------------- this is the trait that was imported = help: you can use `cargo tree` to explore your dependency tree -error[E0277]: the trait bound `OtherType: Trait` is not satisfied +error[E0277]: the trait bound `OtherType: dependency::Trait` is not satisfied --> replaced | LL | do_something(OtherType); - | ------------ ^^^^^^^^^ the trait `Trait` is not implemented for `OtherType` + | ------------ ^^^^^^^^^ the trait `dependency::Trait` is not implemented for `OtherType` | | | required by a bound introduced by this call | @@ -83,7 +83,7 @@ LL | pub trait Trait { LL | pub trait Trait { | --------------- this is the found trait = help: you can use `cargo tree` to explore your dependency tree -help: the trait `Trait` is implemented for `dependency::Type` +help: the trait `dependency::Trait` is implemented for `dependency::Type` --> replaced | LL | impl Trait for Type { 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`. diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr index 234e251b2ad8d..08c850cd8e24e 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr @@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` | LL | struct A; | ^^^^^^^^ -note: required by a bound in `Trait` +note: required by a bound in `r#trait::Trait` --> $DIR/auxiliary/trait.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr index 3b0d66e75e86e..ebd7606815d07 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr @@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` | LL | struct A; | ^^^^^^^^ -note: required by a bound in `Trait` +note: required by a bound in `r#trait::Trait` --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr index 86c1140573e3c..c21d49e325e22 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr @@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` | LL | struct A; | ^^^^^^^^ -note: required by a bound in `Trait` +note: required by a bound in `r#trait::Trait` --> remapped/errors/auxiliary/trait-diag.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-doc-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-doc-in-deps.stderr index e1b93a1042f57..6ea6c16c5149e 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.only-doc-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-doc-in-deps.stderr @@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` | LL | struct A; | ^^^^^^^^ -note: required by a bound in `Trait` +note: required by a bound in `r#trait::Trait` --> $DIR/auxiliary/trait-doc.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr index 91c9cd90152bf..9a0676ca0ea94 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr @@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` | LL | struct A; | ^^^^^^^^ -note: required by a bound in `Trait` +note: required by a bound in `r#trait::Trait` --> $DIR/auxiliary/trait-macro.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr index 3b0d66e75e86e..ebd7606815d07 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr @@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` | LL | struct A; | ^^^^^^^^ -note: required by a bound in `Trait` +note: required by a bound in `r#trait::Trait` --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr index 00a647df61f9f..688db94a97535 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr @@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` | LL | struct A; | ^^^^^^^^ -note: required by a bound in `Trait` +note: required by a bound in `r#trait::Trait` --> remapped/errors/auxiliary/trait-diag.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-doc-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-doc-in-deps.stderr index e1b93a1042f57..6ea6c16c5149e 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.with-doc-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-doc-in-deps.stderr @@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` | LL | struct A; | ^^^^^^^^ -note: required by a bound in `Trait` +note: required by a bound in `r#trait::Trait` --> $DIR/auxiliary/trait-doc.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr index 91c9cd90152bf..9a0676ca0ea94 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr @@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` | LL | struct A; | ^^^^^^^^ -note: required by a bound in `Trait` +note: required by a bound in `r#trait::Trait` --> $DIR/auxiliary/trait-macro.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/privacy/private-inferred-type.rs b/tests/ui/privacy/private-inferred-type.rs index 8c07226fe0e4d..ed22ad44c4497 100644 --- a/tests/ui/privacy/private-inferred-type.rs +++ b/tests/ui/privacy/private-inferred-type.rs @@ -115,11 +115,11 @@ fn main() { m::m!(); - m::leak_anon1(); //~ ERROR trait `Trait` is private + m::leak_anon1(); //~ ERROR trait `m::Trait` is private m::leak_anon2(); //~ ERROR type `Priv` is private m::leak_anon3(); //~ ERROR type `Priv` is private - m::leak_dyn1(); //~ ERROR trait `Trait` is private + m::leak_dyn1(); //~ ERROR trait `m::Trait` is private m::leak_dyn2(); //~ ERROR type `Priv` is private m::leak_dyn3(); //~ ERROR type `Priv` is private diff --git a/tests/ui/privacy/private-inferred-type.stderr b/tests/ui/privacy/private-inferred-type.stderr index fc3f9ab62bfa9..0dfa799a4d95d 100644 --- a/tests/ui/privacy/private-inferred-type.stderr +++ b/tests/ui/privacy/private-inferred-type.stderr @@ -172,7 +172,7 @@ LL | m::m!(); | = note: this error originates in the macro `m::m` (in Nightly builds, run with -Z macro-backtrace for more info) -error: trait `Trait` is private +error: trait `m::Trait` is private --> $DIR/private-inferred-type.rs:118:5 | LL | m::leak_anon1(); @@ -190,7 +190,7 @@ error: type `Priv` is private LL | m::leak_anon3(); | ^^^^^^^^^^^^^^^ private type -error: trait `Trait` is private +error: trait `m::Trait` is private --> $DIR/private-inferred-type.rs:122:5 | LL | m::leak_dyn1(); diff --git a/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr b/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr index 4ce936582f43d..b459ad47e067a 100644 --- a/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr +++ b/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr @@ -22,7 +22,7 @@ LL | type P = [u8]; | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Trait::P` +note: required by a bound in `main::Trait::P` --> $DIR/suggest-maybe-sized-bound.rs:13:9 | LL | type P; diff --git a/tests/ui/traits/bound/on-structs-and-enums-xc.stderr b/tests/ui/traits/bound/on-structs-and-enums-xc.stderr index 5064b60bfd579..472ac187a9666 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-xc.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-xc.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `usize: Trait` is not satisfied +error[E0277]: the trait bound `usize: on_structs_and_enums_xc::Trait` is not satisfied --> $DIR/on-structs-and-enums-xc.rs:7:15 | LL | fn explode(x: Foo) {} - | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` + | ^^^^^^^^^^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `usize` | note: required by a bound in `Foo` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18 @@ -10,11 +10,11 @@ note: required by a bound in `Foo` LL | pub struct Foo { | ^^^^^ required by this bound in `Foo` -error[E0277]: the trait bound `f32: Trait` is not satisfied +error[E0277]: the trait bound `f32: on_structs_and_enums_xc::Trait` is not satisfied --> $DIR/on-structs-and-enums-xc.rs:10:14 | LL | fn kaboom(y: Bar) {} - | ^^^^^^^^ the trait `Trait` is not implemented for `f32` + | ^^^^^^^^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `f32` | note: required by a bound in `Bar` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16 diff --git a/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr index 1f46415e24369..5cf682a5045e8 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `{integer}: Trait` is not satisfied +error[E0277]: the trait bound `{integer}: on_structs_and_enums_xc::Trait` is not satisfied --> $DIR/on-structs-and-enums-xc1.rs:9:12 | LL | x: 3 - | ^ the trait `Trait` is not implemented for `{integer}` + | ^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `{integer}` | note: required by a bound in `Foo` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18 @@ -10,11 +10,11 @@ note: required by a bound in `Foo` LL | pub struct Foo { | ^^^^^ required by this bound in `Foo` -error[E0277]: the trait bound `f64: Trait` is not satisfied +error[E0277]: the trait bound `f64: on_structs_and_enums_xc::Trait` is not satisfied --> $DIR/on-structs-and-enums-xc1.rs:12:14 | LL | let bar: Bar = return; - | ^^^^^^^^ the trait `Trait` is not implemented for `f64` + | ^^^^^^^^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `f64` | note: required by a bound in `Bar` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16 diff --git a/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.rs b/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.rs index ec6bb7bbcc594..35465183001a1 100644 --- a/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.rs +++ b/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.rs @@ -5,8 +5,8 @@ // Issue #148892. //@ aux-crate:crate1=crate1.rs -struct MyStruct; //~ HELP the trait `Trait` is not implemented for `MyStruct` +struct MyStruct; //~ HELP the trait `crate1::Trait` is not implemented for `MyStruct` fn main() { - crate1::foo(MyStruct); //~ ERROR the trait bound `MyStruct: Trait` is not satisfied + crate1::foo(MyStruct); //~ ERROR the trait bound `MyStruct: crate1::Trait` is not satisfied } diff --git a/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.stderr b/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.stderr index 7fec237f54d43..5bcda9f2a95b8 100644 --- a/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.stderr +++ b/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `MyStruct: Trait` is not satisfied +error[E0277]: the trait bound `MyStruct: crate1::Trait` is not satisfied --> $DIR/wrong-multiple-different-versions-of-a-crate.rs:11:17 | LL | crate1::foo(MyStruct); @@ -6,7 +6,7 @@ LL | crate1::foo(MyStruct); | | | required by a bound introduced by this call | -help: the trait `Trait` is not implemented for `MyStruct` +help: the trait `crate1::Trait` is not implemented for `MyStruct` --> $DIR/wrong-multiple-different-versions-of-a-crate.rs:8:1 | LL | struct MyStruct; diff --git a/tests/ui/unresolved/unresolved-candidates.stderr b/tests/ui/unresolved/unresolved-candidates.stderr index 55b9d8ec6e8fc..7d8e894a55826 100644 --- a/tests/ui/unresolved/unresolved-candidates.stderr +++ b/tests/ui/unresolved/unresolved-candidates.stderr @@ -4,8 +4,10 @@ error[E0432]: unresolved import `Trait` LL | use Trait; | ^^^^^ no `Trait` in the root | -help: consider importing this trait instead +help: consider importing one of these items instead | +LL | use std::mem::type_info::Trait; + | +++++++++++++++++++++ LL | use a::Trait; | +++ diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr index afef024e1b9c1..60bb2117df24c 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy` +error[E0119]: conflicting implementations of trait `aux::Trait` for type `LocalTy` --> $DIR/unstable_impl_coherence.rs:14:1 | LL | impl aux::Trait for LocalTy {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `unstable_impl_coherence_aux`: - - impl Trait for T + - impl aux::Trait for T where feature(foo) is enabled; error: aborting due to 1 previous error diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr index afef024e1b9c1..60bb2117df24c 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy` +error[E0119]: conflicting implementations of trait `aux::Trait` for type `LocalTy` --> $DIR/unstable_impl_coherence.rs:14:1 | LL | impl aux::Trait for LocalTy {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `unstable_impl_coherence_aux`: - - impl Trait for T + - impl aux::Trait for T where feature(foo) is enabled; error: aborting due to 1 previous error diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs b/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs index 22100f85f715b..c36316dc5fa1b 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs @@ -12,6 +12,6 @@ use aux::Trait; struct LocalTy; impl aux::Trait for LocalTy {} -//~^ ERROR: conflicting implementations of trait `Trait` for type `LocalTy` +//~^ ERROR: conflicting implementations of trait `aux::Trait` for type `LocalTy` fn main(){} diff --git a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr index 840af730154d9..b2e4eb730d84e 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr +++ b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr @@ -4,9 +4,9 @@ error[E0283]: type annotations needed LL | vec![].foo(); | ^^^ cannot infer type for struct `Vec<_>` | - = note: multiple `impl`s satisfying `Vec<_>: Trait` found in the `unstable_impl_method_selection_aux` crate: - - impl Trait for Vec; - - impl Trait for Vec + = note: multiple `impl`s satisfying `Vec<_>: aux::Trait` found in the `unstable_impl_method_selection_aux` crate: + - impl aux::Trait for Vec; + - impl aux::Trait for Vec where feature(bar) is enabled; error: aborting due to 1 previous error diff --git a/tests/ui/use/issue-18986.stderr b/tests/ui/use/issue-18986.stderr index 350cb18f95272..084fa80c3b6d3 100644 --- a/tests/ui/use/issue-18986.stderr +++ b/tests/ui/use/issue-18986.stderr @@ -3,6 +3,11 @@ error[E0574]: expected struct, variant or union type, found trait `Trait` | LL | Trait { x: 42 } => () | ^^^^^ not a struct, variant or union type + | +help: consider importing this struct instead + | +LL + use std::mem::type_info::Trait; + | error: aborting due to 1 previous error