diff options
| author | Ben Kimock <kimockb@gmail.com> | 2025-02-01 05:39:41 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-01 05:39:41 +0000 |
| commit | b82463fcbfd2ed60a77003261445df0f430a3e50 (patch) | |
| tree | 532e602a81dd19c551f37b0cdc93e5b811c4b13b | |
| parent | 829bfc3f5ee4c4826b2571da419722e3242aa155 (diff) | |
| parent | c925c826bf4eb093f1b6bcded7a4b99a9d489851 (diff) | |
| download | rust-b82463fcbfd2ed60a77003261445df0f430a3e50.tar.gz rust-b82463fcbfd2ed60a77003261445df0f430a3e50.zip | |
Merge pull request #4169 from rust-lang/rustup-2025-02-01
Automatic Rustup
383 files changed, 3637 insertions, 2213 deletions
diff --git a/Cargo.lock b/Cargo.lock index 04bb96be369..75c6ab37bd1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4234,6 +4234,7 @@ name = "rustc_monomorphize" version = "0.0.0" dependencies = [ "rustc_abi", + "rustc_ast", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", @@ -4243,6 +4244,7 @@ dependencies = [ "rustc_middle", "rustc_session", "rustc_span", + "rustc_symbol_mangling", "rustc_target", "serde", "serde_json", diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs index 7ef8bc17973..ecc522ec39d 100644 --- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs +++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs @@ -79,6 +79,7 @@ pub struct AutoDiffItem { pub target: String, pub attrs: AutoDiffAttrs, } + #[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] pub struct AutoDiffAttrs { /// Conceptually either forward or reverse mode AD, as described in various autodiff papers and @@ -231,7 +232,7 @@ impl AutoDiffAttrs { self.ret_activity == DiffActivity::ActiveOnly } - pub fn error() -> Self { + pub const fn error() -> Self { AutoDiffAttrs { mode: DiffMode::Error, ret_activity: DiffActivity::None, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 07dcbba019a..0118b72962d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3777,7 +3777,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let tcx = self.infcx.tcx; if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) = &self.body[loan.reserve_location.block].terminator - && let Some((method_did, method_args)) = rustc_middle::util::find_self_call( + && let Some((method_did, method_args)) = mir::find_self_call( tcx, self.body, loan.assigned_place.local, diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index bd6f77156ca..5fe8eef3460 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -17,7 +17,7 @@ use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ AggregateKind, CallSource, ConstOperand, ConstraintCategory, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, - StatementKind, Terminator, TerminatorKind, + StatementKind, Terminator, TerminatorKind, find_self_call, }; use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -1016,12 +1016,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { kind: TerminatorKind::Call { fn_span, call_source, .. }, .. }) = &self.body[location.block].terminator { - let Some((method_did, method_args)) = rustc_middle::util::find_self_call( - self.infcx.tcx, - self.body, - target_temp, - location.block, - ) else { + let Some((method_did, method_args)) = + find_self_call(self.infcx.tcx, self.body, target_temp, location.block) + else { return normal_ret; }; diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 34066eb83fc..c7c9c6236d1 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -417,6 +417,16 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { Some(source_info.span), ); } + AssertKind::NullPointerDereference => { + let location = fx.get_caller_location(source_info).load_scalar(fx); + + codegen_panic_inner( + fx, + rustc_hir::LangItem::PanicNullPointerDereference, + &[location], + Some(source_info.span), + ) + } _ => { let location = fx.get_caller_location(source_info).load_scalar(fx); diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 3e7b81a96b6..425b2adf32a 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -6,7 +6,7 @@ use cranelift_module::*; use rustc_data_structures::fx::FxHashSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{AllocId, GlobalAlloc, Scalar, read_target_uint}; -use rustc_middle::ty::{Binder, ExistentialTraitRef, ScalarInt}; +use rustc_middle::ty::{ExistentialTraitRef, ScalarInt}; use crate::prelude::*; @@ -167,7 +167,9 @@ pub(crate) fn codegen_const_value<'tcx>( &mut fx.constants_cx, fx.module, ty, - dyn_ty.principal(), + dyn_ty.principal().map(|principal| { + fx.tcx.instantiate_bound_regions_with_erased(principal) + }), ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); @@ -243,7 +245,7 @@ pub(crate) fn data_id_for_vtable<'tcx>( cx: &mut ConstantCx, module: &mut dyn Module, ty: Ty<'tcx>, - trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>, + trait_ref: Option<ExistentialTraitRef<'tcx>>, ) -> DataId { let alloc_id = tcx.vtable_allocation((ty, trait_ref)); data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) @@ -460,9 +462,15 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant GlobalAlloc::Memory(target_alloc) => { data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability) } - GlobalAlloc::VTable(ty, dyn_ty) => { - data_id_for_vtable(tcx, cx, module, ty, dyn_ty.principal()) - } + GlobalAlloc::VTable(ty, dyn_ty) => data_id_for_vtable( + tcx, + cx, + module, + ty, + dyn_ty + .principal() + .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)), + ), GlobalAlloc::Static(def_id) => { if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index 2843e5bbdfb..f8bbb214920 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -61,7 +61,12 @@ pub(crate) fn unsized_info<'tcx>( old_info } } - (_, ty::Dynamic(data, ..)) => crate::vtable::get_vtable(fx, source, data.principal()), + (_, ty::Dynamic(data, ..)) => crate::vtable::get_vtable( + fx, + source, + data.principal() + .map(|principal| fx.tcx.instantiate_bound_regions_with_erased(principal)), + ), _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target), } } diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs index 82b6178be9d..a460023b59c 100644 --- a/compiler/rustc_codegen_cranelift/src/vtable.rs +++ b/compiler/rustc_codegen_cranelift/src/vtable.rs @@ -90,7 +90,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( pub(crate) fn get_vtable<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>, - trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, + trait_ref: Option<ty::ExistentialTraitRef<'tcx>>, ) -> Value { let data_id = data_id_for_vtable(fx.tcx, &mut fx.constants_cx, fx.module, ty, trait_ref); let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index bd5d6ba387c..20a3482aaa2 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -234,7 +234,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { GlobalAlloc::VTable(ty, dyn_ty) => { let alloc = self .tcx - .global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal()))) + .global_alloc(self.tcx.vtable_allocation(( + ty, + dyn_ty.principal().map(|principal| { + self.tcx.instantiate_bound_regions_with_erased(principal) + }), + ))) .unwrap_memory(); let init = const_alloc_to_gcc(self, alloc); self.static_addr_of(init, alloc.inner().align, None) diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 30732c74eb3..570ef938dc4 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::layout::{ FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers, }; -use rustc_middle::ty::{self, Instance, PolyExistentialTraitRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt}; use rustc_session::Session; use rustc_span::source_map::respan; use rustc_span::{DUMMY_SP, Span}; @@ -90,7 +90,7 @@ pub struct CodegenCx<'gcc, 'tcx> { pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>, /// Cache generated vtables pub vtables: - RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>>, + RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>, // TODO(antoyo): improve the SSA API to not require those. /// Mapping from function pointer type to indexes of on stack parameters. @@ -401,7 +401,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> { impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn vtables( &self, - ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>> { + ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>), RValue<'gcc>>> { &self.vtables } diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index 4b84b1dbfd3..86d3de225f7 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -7,7 +7,7 @@ use rustc_data_structures::sync::Lrc; use rustc_index::bit_set::DenseBitSet; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{self, Body, SourceScope}; -use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty}; +use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty}; use rustc_session::config::DebugInfo; use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol}; use rustc_target::abi::Size; @@ -214,7 +214,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn create_vtable_debuginfo( &self, _ty: Ty<'tcx>, - _trait_ref: Option<PolyExistentialTraitRef<'tcx>>, + _trait_ref: Option<ExistentialTraitRef<'tcx>>, _vtable: Self::Value, ) { // TODO(antoyo) diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs index bfe73c38435..58a26801b67 100644 --- a/compiler/rustc_codegen_gcc/tests/run/int.rs +++ b/compiler/rustc_codegen_gcc/tests/run/int.rs @@ -3,8 +3,6 @@ // Run-time: // status: 0 -#![feature(const_black_box)] - /* * Code */ diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index 6b17b5f6989..9e8e4e1c567 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -62,8 +62,8 @@ fn generate_enzyme_call<'ll>( // add outer_fn name to ad_name to make it unique, in case users apply autodiff to multiple // functions. Unwrap will only panic, if LLVM gave us an invalid string. let name = llvm::get_value_name(outer_fn); - let outer_fn_name = std::ffi::CStr::from_bytes_with_nul(name).unwrap().to_str().unwrap(); - ad_name.push_str(outer_fn_name.to_string().as_str()); + let outer_fn_name = std::str::from_utf8(name).unwrap(); + ad_name.push_str(outer_fn_name); // Let us assume the user wrote the following function square: // @@ -255,14 +255,14 @@ fn generate_enzyme_call<'ll>( // have no debug info to copy, which would then be ok. trace!("no dbg info"); } + // Now that we copied the metadata, get rid of dummy code. - llvm::LLVMRustEraseInstBefore(entry, last_inst); - llvm::LLVMRustEraseInstFromParent(last_inst); + llvm::LLVMRustEraseInstUntilInclusive(entry, last_inst); - if cx.val_ty(outer_fn) != cx.type_void() { - builder.ret(call); - } else { + if cx.val_ty(call) == cx.type_void() { builder.ret_void(); + } else { + builder.ret(call); } // Let's crash in case that we messed something up above and generated invalid IR. diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index f8b30cb507a..8c94a46ebf3 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -314,7 +314,12 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { GlobalAlloc::VTable(ty, dyn_ty) => { let alloc = self .tcx - .global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal()))) + .global_alloc(self.tcx.vtable_allocation(( + ty, + dyn_ty.principal().map(|principal| { + self.tcx.instantiate_bound_regions_with_erased(principal) + }), + ))) .unwrap_memory(); let init = const_alloc_to_llvm(self, alloc, /*static*/ false); let value = self.static_addr_of_impl(init, alloc.inner().align, None); diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 79381f35a3c..ba4fd75fb94 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -77,8 +77,7 @@ pub(crate) struct CodegenCx<'ll, 'tcx> { /// Cache instances of monomorphic and polymorphic items pub instances: RefCell<FxHashMap<Instance<'tcx>, &'ll Value>>, /// Cache generated vtables - pub vtables: - RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>, + pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>>, /// Cache of constant strings, pub const_str_cache: RefCell<FxHashMap<String, &'ll Value>>, @@ -663,15 +662,14 @@ impl<'ll> SimpleCx<'ll> { impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn vtables( &self, - ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>> - { + ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>> { &self.vtables } fn apply_vcall_visibility_metadata( &self, ty: Ty<'tcx>, - poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, + poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>, vtable: &'ll Value, ) { apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable); diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index fd22421c7fc..9a2473d6cf2 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -298,7 +298,7 @@ struct UsageSets<'tcx> { /// Prepare sets of definitions that are relevant to deciding whether something /// is an "unused function" for coverage purposes. fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> { - let MonoItemPartitions { all_mono_items, codegen_units } = + let MonoItemPartitions { all_mono_items, codegen_units, .. } = tcx.collect_and_partition_mono_items(()); // Obtain a MIR body for each function participating in codegen, via an diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 6eae16d8be6..3a0c7f007bd 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -13,7 +13,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{ - self, AdtKind, CoroutineArgsExt, Instance, PolyExistentialTraitRef, Ty, TyCtxt, Visibility, + self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility, }; use rustc_session::config::{self, DebugInfo, Lto}; use rustc_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Symbol, hygiene}; @@ -1399,7 +1399,7 @@ pub(crate) fn build_global_var_di_node<'ll>( fn build_vtable_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, - poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, + poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>, ) -> &'ll DIType { let tcx = cx.tcx; @@ -1510,7 +1510,7 @@ fn find_vtable_behind_cast<'ll>(vtable: &'ll Value) -> &'ll Value { pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, - trait_ref: Option<PolyExistentialTraitRef<'tcx>>, + trait_ref: Option<ExistentialTraitRef<'tcx>>, vtable: &'ll Value, ) { // FIXME(flip1995): The virtual function elimination optimization only works with full LTO in @@ -1531,7 +1531,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( let vtable = find_vtable_behind_cast(vtable); let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty); let trait_ref_self = cx.tcx.erase_regions(trait_ref_self); - let trait_def_id = trait_ref_self.def_id(); + let trait_def_id = trait_ref_self.def_id; let trait_vis = cx.tcx.visibility(trait_def_id); let cgus = cx.sess().codegen_units().as_usize(); @@ -1590,7 +1590,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( pub(crate) fn create_vtable_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, - poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, + poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>, vtable: &'ll Value, ) { if cx.dbg_cx.is_none() { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index a37e719d43f..af1d503ad6a 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; use rustc_middle::bug; -use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt}; use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; use crate::common::{AsCCharPtr, CodegenCx}; @@ -44,7 +44,7 @@ pub(super) enum UniqueTypeId<'tcx> { /// The ID for the additional wrapper struct type describing an enum variant in CPP-like mode. VariantStructTypeCppLikeWrapper(Ty<'tcx>, VariantIdx, private::HiddenZst), /// The ID of the artificial type we create for VTables. - VTableTy(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>, private::HiddenZst), + VTableTy(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>, private::HiddenZst), } impl<'tcx> UniqueTypeId<'tcx> { @@ -88,7 +88,7 @@ impl<'tcx> UniqueTypeId<'tcx> { pub(crate) fn for_vtable_ty( tcx: TyCtxt<'tcx>, self_type: Ty<'tcx>, - implemented_trait: Option<PolyExistentialTraitRef<'tcx>>, + implemented_trait: Option<ExistentialTraitRef<'tcx>>, ) -> Self { assert_eq!( self_type, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 5089560784a..b1ce52667bd 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -588,7 +588,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn create_vtable_debuginfo( &self, ty: Ty<'tcx>, - trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, + trait_ref: Option<ty::ExistentialTraitRef<'tcx>>, vtable: Self::Value, ) { metadata::create_vtable_di_node(self, ty, trait_ref, vtable) diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 729d6f62e24..ae813fe5ebf 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -7,11 +7,13 @@ use crate::llvm::Bool; extern "C" { // Enzyme pub fn LLVMRustHasMetadata(I: &Value, KindID: c_uint) -> bool; - pub fn LLVMRustEraseInstBefore(BB: &BasicBlock, I: &Value); + pub fn LLVMRustEraseInstUntilInclusive(BB: &BasicBlock, I: &Value); pub fn LLVMRustGetLastInstruction<'a>(BB: &BasicBlock) -> Option<&'a Value>; pub fn LLVMRustDIGetInstMetadata(I: &Value) -> Option<&Metadata>; pub fn LLVMRustEraseInstFromParent(V: &Value); pub fn LLVMRustGetTerminator<'a>(B: &BasicBlock) -> &'a Value; + pub fn LLVMDumpModule(M: &Module); + pub fn LLVMDumpValue(V: &Value); pub fn LLVMRustVerifyFunction(V: &Value, action: LLVMRustVerifierFailureAction) -> Bool; pub fn LLVMGetFunctionCallConv(F: &Value) -> c_uint; diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 186b8171dd8..22e262546c3 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -16,6 +16,8 @@ codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$erro codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering +codegen_ssa_autodiff_without_lto = using the autodiff feature requires using fat-lto + codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty codegen_ssa_cgu_not_recorded = diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index b40bb4ed5d2..914f2c21fa7 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -7,6 +7,7 @@ use std::sync::mpsc::{Receiver, Sender, channel}; use std::{fs, io, mem, str, thread}; use rustc_ast::attr; +use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::jobserver::{self, Acquired}; use rustc_data_structures::memmap::Mmap; @@ -40,7 +41,7 @@ use tracing::debug; use super::link::{self, ensure_removed}; use super::lto::{self, SerializedModule}; use super::symbol_export::symbol_name_for_instance_in_crate; -use crate::errors::ErrorCreatingRemarkDir; +use crate::errors::{AutodiffWithoutLto, ErrorCreatingRemarkDir}; use crate::traits::*; use crate::{ CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, @@ -118,6 +119,7 @@ pub struct ModuleConfig { pub merge_functions: bool, pub emit_lifetime_markers: bool, pub llvm_plugins: Vec<String>, + pub autodiff: Vec<config::AutoDiff>, } impl ModuleConfig { @@ -266,6 +268,7 @@ impl ModuleConfig { emit_lifetime_markers: sess.emit_lifetime_markers(), llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]), + autodiff: if_regular!(sess.opts.unstable_opts.autodiff.clone(), vec![]), } } @@ -389,6 +392,7 @@ impl<B: WriteBackendMethods> CodegenContext<B> { fn generate_lto_work<B: ExtraBackendMethods>( cgcx: &CodegenContext<B>, + autodiff: Vec<AutoDiffItem>, needs_fat_lto: Vec<FatLtoInput<B>>, needs_thin_lto: Vec<(String, B::ThinBuffer)>, import_only_modules: Vec<(SerializedModule<B::ModuleBuffer>, WorkProduct)>, @@ -397,11 +401,19 @@ fn generate_lto_work<B: ExtraBackendMethods>( if !needs_fat_lto.is_empty() { assert!(needs_thin_lto.is_empty()); - let module = + let mut module = B::run_fat_lto(cgcx, needs_fat_lto, import_only_modules).unwrap_or_else(|e| e.raise()); + if cgcx.lto == Lto::Fat { + let config = cgcx.config(ModuleKind::Regular); + module = unsafe { module.autodiff(cgcx, autodiff, config).unwrap() }; + } // We are adding a single work item, so the cost doesn't matter. vec![(WorkItem::LTO(module), 0)] } else { + if !autodiff.is_empty() { + let dcx = cgcx.create_dcx(); + dcx.handle().emit_fatal(AutodiffWithoutLto {}); + } assert!(needs_fat_lto.is_empty()); let (lto_modules, copy_jobs) = B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules) .unwrap_or_else(|e| e.raise()); @@ -1021,6 +1033,9 @@ pub(crate) enum Message<B: WriteBackendMethods> { /// Sent from a backend worker thread. WorkItem { result: Result<WorkItemResult<B>, Option<WorkerFatalError>>, worker_id: usize }, + /// A vector containing all the AutoDiff tasks that we have to pass to Enzyme. + AddAutoDiffItems(Vec<AutoDiffItem>), + /// The frontend has finished generating something (backend IR or a /// post-LTO artifact) for a codegen unit, and it should be passed to the /// backend. Sent from the main thread. @@ -1348,6 +1363,7 @@ fn start_executing_work<B: ExtraBackendMethods>( // This is where we collect codegen units that have gone all the way // through codegen and LLVM. + let mut autodiff_items = Vec::new(); let mut compiled_modules = vec![]; let mut compiled_allocator_module = None; let mut needs_link = Vec::new(); @@ -1459,9 +1475,13 @@ fn start_executing_work<B: ExtraBackendMethods>( let needs_thin_lto = mem::take(&mut needs_thin_lto); let import_only_modules = mem::take(&mut lto_import_only_modules); - for (work, cost) in - generate_lto_work(&cgcx, needs_fat_lto, needs_thin_lto, import_only_modules) - { + for (work, cost) in generate_lto_work( + &cgcx, + autodiff_items.clone(), + needs_fat_lto, + needs_thin_lto, + import_only_modules, + ) { let insertion_index = work_items .binary_search_by_key(&cost, |&(_, cost)| cost) .unwrap_or_else(|e| e); @@ -1596,6 +1616,10 @@ fn start_executing_work<B: ExtraBackendMethods>( main_thread_state = MainThreadState::Idle; } + Message::AddAutoDiffItems(mut items) => { + autodiff_items.append(&mut items); + } + Message::CodegenComplete => { if codegen_state != Aborted { codegen_state = Completed; @@ -2070,6 +2094,10 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> { drop(self.coordinator.sender.send(Box::new(Message::CodegenComplete::<B>))); } + pub(crate) fn submit_autodiff_items(&self, items: Vec<AutoDiffItem>) { + drop(self.coordinator.sender.send(Box::new(Message::<B>::AddAutoDiffItems(items)))); + } + pub(crate) fn check_for_errors(&self, sess: &Session) { self.shared_emitter_main.check(sess, false); } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 83a9e6e2309..6e0333cf3ce 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -18,14 +18,13 @@ use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, Debugger use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_middle::middle::{exported_symbols, lang_items}; use rustc_middle::mir::BinOp; -use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem}; +use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem, MonoItemPartitions}; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::Session; use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType}; use rustc_span::{DUMMY_SP, Symbol, sym}; -use rustc_trait_selection::infer::at::ToTrace; use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::{debug, info}; @@ -129,14 +128,9 @@ pub fn validate_trivial_unsize<'tcx>( BoundRegionConversionTime::HigherRankedType, hr_source_principal, ); - let Ok(()) = ocx.eq_trace( + let Ok(()) = ocx.eq( &ObligationCause::dummy(), param_env, - ToTrace::to_trace( - &ObligationCause::dummy(), - hr_target_principal, - hr_source_principal, - ), target_principal, source_principal, ) else { @@ -211,7 +205,12 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( old_info } } - (_, ty::Dynamic(data, _, _)) => meth::get_vtable(cx, source, data.principal()), + (_, ty::Dynamic(data, _, _)) => meth::get_vtable( + cx, + source, + data.principal() + .map(|principal| bx.tcx().instantiate_bound_regions_with_erased(principal)), + ), _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target), } } @@ -624,7 +623,9 @@ pub fn codegen_crate<B: ExtraBackendMethods>( // Run the monomorphization collector and partition the collected items into // codegen units. - let codegen_units = tcx.collect_and_partition_mono_items(()).codegen_units; + let MonoItemPartitions { codegen_units, autodiff_items, .. } = + tcx.collect_and_partition_mono_items(()); + let autodiff_fncs = autodiff_items.to_vec(); // Force all codegen_unit queries so they are already either red or green // when compile_codegen_unit accesses them. We are not able to re-execute @@ -695,6 +696,10 @@ pub fn codegen_crate<B: ExtraBackendMethods>( ); } + if !autodiff_fncs.is_empty() { + ongoing_codegen.submit_autodiff_items(autodiff_fncs); + } + // For better throughput during parallel processing by LLVM, we used to sort // CGUs largest to smallest. This would lead to better thread utilization // by, for example, preventing a large CGU from being processed last and diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index a0bc2d4ea48..4166387dad0 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,5 +1,10 @@ +use std::str::FromStr; + use rustc_ast::attr::list_contains_name; -use rustc_ast::{MetaItemInner, attr}; +use rustc_ast::expand::autodiff_attrs::{ + AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, +}; +use rustc_ast::{MetaItem, MetaItemInner, attr}; use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::codes::*; @@ -13,6 +18,7 @@ use rustc_middle::middle::codegen_fn_attrs::{ }; use rustc_middle::mir::mono::Linkage; use rustc_middle::query::Providers; +use rustc_middle::span_bug; use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::parse::feature_err; use rustc_session::{Session, lint}; @@ -65,6 +71,13 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; } + // If our rustc version supports autodiff/enzyme, then we call our handler + // to check for any `#[rustc_autodiff(...)]` attributes. + if cfg!(llvm_enzyme) { + let ad = autodiff_attrs(tcx, did.into()); + codegen_fn_attrs.autodiff_item = ad; + } + // When `no_builtins` is applied at the crate level, we should add the // `no-builtins` attribute to each function to ensure it takes effect in LTO. let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); @@ -856,6 +869,109 @@ impl<'a> MixedExportNameAndNoMangleState<'a> { } } +/// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)] +/// macros. There are two forms. The pure one without args to mark primal functions (the functions +/// being differentiated). The other form is #[rustc_autodiff(Mode, ActivityList)] on top of the +/// placeholder functions. We wrote the rustc_autodiff attributes ourself, so this should never +/// panic, unless we introduced a bug when parsing the autodiff macro. +fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> { + let attrs = tcx.get_attrs(id, sym::rustc_autodiff); + + let attrs = + attrs.filter(|attr| attr.name_or_empty() == sym::rustc_autodiff).collect::<Vec<_>>(); + + // check for exactly one autodiff attribute on placeholder functions. + // There should only be one, since we generate a new placeholder per ad macro. + // FIXME(ZuseZ4): re-enable this check. Currently we add multiple, which doesn't cause harm but + // looks strange e.g. under cargo-expand. + let attr = match &attrs[..] { + [] => return None, + [attr] => attr, + // These two attributes are the same and unfortunately duplicated due to a previous bug. + [attr, _attr2] => attr, + _ => { + //FIXME(ZuseZ4): Once we fixed our parser, we should also prohibit the two-attribute + //branch above. + span_bug!(attrs[1].span, "cg_ssa: rustc_autodiff should only exist once per source"); + } + }; + + let list = attr.meta_item_list().unwrap_or_default(); + + // empty autodiff attribute macros (i.e. `#[autodiff]`) are used to mark source functions + if list.is_empty() { + return Some(AutoDiffAttrs::source()); + } + + let [mode, input_activities @ .., ret_activity] = &list[..] else { + span_bug!(attr.span, "rustc_autodiff attribute must contain mode and activities"); + }; + let mode = if let MetaItemInner::MetaItem(MetaItem { path: ref p1, .. }) = mode { + p1.segments.first().unwrap().ident + } else { + span_bug!(attr.span, "rustc_autodiff attribute must contain mode"); + }; + + // parse mode + let mode = match mode.as_str() { + "Forward" => DiffMode::Forward, + "Reverse" => DiffMode::Reverse, + "ForwardFirst" => DiffMode::ForwardFirst, + "ReverseFirst" => DiffMode::ReverseFirst, + _ => { + span_bug!(mode.span, "rustc_autodiff attribute contains invalid mode"); + } + }; + + // First read the ret symbol from the attribute + let ret_symbol = if let MetaItemInner::MetaItem(MetaItem { path: ref p1, .. }) = ret_activity { + p1.segments.first().unwrap().ident + } else { + span_bug!(attr.span, "rustc_autodiff attribute must contain the return activity"); + }; + + // Then parse it into an actual DiffActivity + let Ok(ret_activity) = DiffActivity::from_str(ret_symbol.as_str()) else { + span_bug!(ret_symbol.span, "invalid return activity"); + }; + + // Now parse all the intermediate (input) activities + let mut arg_activities: Vec<DiffActivity> = vec![]; + for arg in input_activities { + let arg_symbol = if let MetaItemInner::MetaItem(MetaItem { path: ref p2, .. }) = arg { + match p2.segments.first() { + Some(x) => x.ident, + None => { + span_bug!( + arg.span(), + "rustc_autodiff attribute must contain the input activity" + ); + } + } + } else { + span_bug!(arg.span(), "rustc_autodiff attribute must contain the input activity"); + }; + + match DiffActivity::from_str(arg_symbol.as_str()) { + Ok(arg_activity) => arg_activities.push(arg_activity), + Err(_) => { + span_bug!(arg_symbol.span, "invalid input activity"); + } + } + } + + for &input in &arg_activities { + if !valid_input_activity(mode, input) { + span_bug!(attr.span, "Invalid input activity {} for {} mode", input, mode); + } + } + if !valid_ret_activity(mode, ret_activity) { + span_bug!(attr.span, "Invalid return activity {} for {} mode", ret_activity, mode); + } + + Some(AutoDiffAttrs { mode, ret_activity, input_activity: arg_activities }) +} + pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers }; } diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index d766ae37e5b..05175371591 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -507,7 +507,7 @@ pub enum VTableNameKind { pub fn compute_debuginfo_vtable_name<'tcx>( tcx: TyCtxt<'tcx>, t: Ty<'tcx>, - trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, + trait_ref: Option<ty::ExistentialTraitRef<'tcx>>, kind: VTableNameKind, ) -> String { let cpp_like_debuginfo = cpp_like_debuginfo(tcx); @@ -530,8 +530,8 @@ pub fn compute_debuginfo_vtable_name<'tcx>( } if let Some(trait_ref) = trait_ref { - let trait_ref = tcx - .normalize_erasing_late_bound_regions(ty::TypingEnv::fully_monomorphized(), trait_ref); + let trait_ref = + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref); push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name); visited.clear(); push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index f3afb37a9ef..3ddbe4aeeec 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -40,6 +40,10 @@ pub(crate) struct CguNotRecorded<'a> { } #[derive(Diagnostic)] +#[diag(codegen_ssa_autodiff_without_lto)] +pub struct AutodiffWithoutLto; + +#[derive(Diagnostic)] #[diag(codegen_ssa_unknown_reuse_kind)] pub(crate) struct UnknownReuseKind { #[primary_span] diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 64cd4c38937..399c592432a 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -1,5 +1,5 @@ use rustc_middle::bug; -use rustc_middle::ty::{self, GenericArgKind, Ty}; +use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt}; use rustc_session::config::Lto; use rustc_symbol_mangling::typeid_for_trait_ref; use rustc_target::callconv::FnAbi; @@ -72,12 +72,19 @@ impl<'a, 'tcx> VirtualIndex { /// This takes a valid `self` receiver type and extracts the principal trait /// ref of the type. Return `None` if there is no principal trait. -fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> { +fn dyn_trait_in_self<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, +) -> Option<ty::ExistentialTraitRef<'tcx>> { for arg in ty.peel_refs().walk() { if let GenericArgKind::Type(ty) = arg.unpack() && let ty::Dynamic(data, _, _) = ty.kind() { - return data.principal(); + // FIXME(arbitrary_self_types): This is likely broken for receivers which + // have a "non-self" trait objects as a generic argument. + return data + .principal() + .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)); } } @@ -96,7 +103,7 @@ fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> { pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( cx: &Cx, ty: Ty<'tcx>, - trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, + trait_ref: Option<ty::ExistentialTraitRef<'tcx>>, ) -> Cx::Value { let tcx = cx.tcx(); @@ -131,7 +138,7 @@ pub(crate) fn load_vtable<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( if bx.cx().sess().opts.unstable_opts.virtual_function_elimination && bx.cx().sess().lto() == Lto::Fat { - if let Some(trait_ref) = dyn_trait_in_self(ty) { + if let Some(trait_ref) = dyn_trait_in_self(bx.tcx(), ty) { let typeid = bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref)).unwrap(); let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); return func; diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index b0a1dedd646..4be363ca9a2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -713,6 +713,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // and `#[track_caller]` adds an implicit third argument. (LangItem::PanicMisalignedPointerDereference, vec![required, found, location]) } + AssertKind::NullPointerDereference => { + // It's `fn panic_null_pointer_dereference()`, + // `#[track_caller]` adds an implicit argument. + (LangItem::PanicNullPointerDereference, vec![location]) + } _ => { // It's `pub fn panic_...()` and `#[track_caller]` adds an implicit argument. (msg.panic_function(), vec![location]) diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs index fe135e911fb..30d77c206a5 100644 --- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs @@ -2,7 +2,7 @@ use std::ops::Range; use rustc_abi::Size; use rustc_middle::mir; -use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty}; +use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty}; use rustc_span::{SourceFile, Span, Symbol}; use rustc_target::callconv::FnAbi; @@ -13,7 +13,7 @@ pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes { fn create_vtable_debuginfo( &self, ty: Ty<'tcx>, - trait_ref: Option<PolyExistentialTraitRef<'tcx>>, + trait_ref: Option<ExistentialTraitRef<'tcx>>, vtable: Self::Value, ); diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index 5b33fd7ab10..4004947b464 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -10,11 +10,11 @@ use super::BackendTypes; pub trait MiscCodegenMethods<'tcx>: BackendTypes { fn vtables( &self, - ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>; + ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), Self::Value>>; fn apply_vcall_visibility_metadata( &self, _ty: Ty<'tcx>, - _poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, + _poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>, _vtable: Self::Value, ) { } diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 16ead1b9785..4834fd3d34c 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -634,7 +634,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::RawPtr(RawPtrKind::FakeForPtrMetadata, place) => { // These are only inserted for slice length, so the place must already be indirect. // This implies we do not have to worry about whether the borrow escapes. - assert!(place.is_indirect(), "fake borrows are always indirect"); + if !place.is_indirect() { + self.tcx.dcx().span_delayed_bug( + self.body.source_info(location).span, + "fake borrows are always indirect", + ); + } } Rvalue::Cast( diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 6a339d69542..82e0a6e6666 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -508,6 +508,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { found: eval_to_int(found)?, } } + NullPointerDereference => NullPointerDereference, }; Err(ConstEvalErrKind::AssertFailure(err)).into() } diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index e6a34193c9d..e2e6e16d8a7 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -5,6 +5,7 @@ use std::borrow::Cow; use either::{Left, Right}; use rustc_abi::{self as abi, ExternAbi, FieldIdx, Integer, VariantIdx}; +use rustc_hir::def_id::DefId; use rustc_middle::ty::layout::{FnAbiOf, IntegerExt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef}; use rustc_middle::{bug, mir, span_bug}; @@ -693,25 +694,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { trace!("Virtual call dispatches to {fn_inst:#?}"); // We can also do the lookup based on `def_id` and `dyn_ty`, and check that that // produces the same result. - if cfg!(debug_assertions) { - let tcx = *self.tcx; - - let trait_def_id = tcx.trait_of_item(def_id).unwrap(); - let virtual_trait_ref = - ty::TraitRef::from_method(tcx, trait_def_id, instance.args); - let existential_trait_ref = - ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref); - let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty); - - let concrete_method = Instance::expect_resolve_for_vtable( - tcx, - self.typing_env, - def_id, - instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args), - self.cur_span(), - ); - assert_eq!(fn_inst, concrete_method); - } + self.assert_virtual_instance_matches_concrete(dyn_ty, def_id, instance, fn_inst); // Adjust receiver argument. Layout can be any (thin) ptr. let receiver_ty = Ty::new_mut_ptr(self.tcx.tcx, dyn_ty); @@ -744,6 +727,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } + fn assert_virtual_instance_matches_concrete( + &self, + dyn_ty: Ty<'tcx>, + def_id: DefId, + virtual_instance: ty::Instance<'tcx>, + concrete_instance: ty::Instance<'tcx>, + ) { + let tcx = *self.tcx; + + let trait_def_id = tcx.trait_of_item(def_id).unwrap(); + let virtual_trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, virtual_instance.args); + let existential_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref); + let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty); + + let concrete_method = Instance::expect_resolve_for_vtable( + tcx, + self.typing_env, + def_id, + virtual_instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args), + self.cur_span(), + ); + assert_eq!(concrete_instance, concrete_method); + } + /// Initiate a tail call to this function -- popping the current stack frame, pushing the new /// stack frame and initializing the arguments. pub(super) fn init_fn_tail_call( diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index ef3e96784ce..e110c155da0 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -414,36 +414,33 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Sanity-check that `supertrait_vtable_slot` in this type's vtable indeed produces // our destination trait. - if cfg!(debug_assertions) { - let vptr_entry_idx = - self.tcx.supertrait_vtable_slot((src_pointee_ty, dest_pointee_ty)); - let vtable_entries = self.vtable_entries(data_a.principal(), ty); - if let Some(entry_idx) = vptr_entry_idx { - let Some(&ty::VtblEntry::TraitVPtr(upcast_trait_ref)) = - vtable_entries.get(entry_idx) - else { - span_bug!( - self.cur_span(), - "invalid vtable entry index in {} -> {} upcast", - src_pointee_ty, - dest_pointee_ty - ); - }; - let erased_trait_ref = upcast_trait_ref - .map_bound(|r| ty::ExistentialTraitRef::erase_self_ty(*self.tcx, r)); - assert!( - data_b - .principal() - .is_some_and(|b| self.eq_in_param_env(erased_trait_ref, b)) + let vptr_entry_idx = + self.tcx.supertrait_vtable_slot((src_pointee_ty, dest_pointee_ty)); + let vtable_entries = self.vtable_entries(data_a.principal(), ty); + if let Some(entry_idx) = vptr_entry_idx { + let Some(&ty::VtblEntry::TraitVPtr(upcast_trait_ref)) = + vtable_entries.get(entry_idx) + else { + span_bug!( + self.cur_span(), + "invalid vtable entry index in {} -> {} upcast", + src_pointee_ty, + dest_pointee_ty ); - } else { - // In this case codegen would keep using the old vtable. We don't want to do - // that as it has the wrong trait. The reason codegen can do this is that - // one vtable is a prefix of the other, so we double-check that. - let vtable_entries_b = self.vtable_entries(data_b.principal(), ty); - assert!(&vtable_entries[..vtable_entries_b.len()] == vtable_entries_b); }; - } + let erased_trait_ref = + ty::ExistentialTraitRef::erase_self_ty(*self.tcx, upcast_trait_ref); + assert!(data_b.principal().is_some_and(|b| self.eq_in_param_env( + erased_trait_ref, + self.tcx.instantiate_bound_regions_with_erased(b) + ))); + } else { + // In this case codegen would keep using the old vtable. We don't want to do + // that as it has the wrong trait. The reason codegen can do this is that + // one vtable is a prefix of the other, so we double-check that. + let vtable_entries_b = self.vtable_entries(data_b.principal(), ty); + assert!(&vtable_entries[..vtable_entries_b.len()] == vtable_entries_b); + }; // Get the destination trait vtable and return that. let new_vptr = self.get_vtable_ptr(ty, data_b)?; diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index af8d618b6b5..4cfaacebfcd 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -54,7 +54,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) -> &'tcx [VtblEntry<'tcx>] { if let Some(trait_) = trait_ { let trait_ref = trait_.with_self_ty(*self.tcx, dyn_ty); - let trait_ref = self.tcx.erase_regions(trait_ref); + let trait_ref = + self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref)); self.tcx.vtable_entries(trait_ref) } else { TyCtxt::COMMON_VTABLE_ENTRIES diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 65d586124b3..6ef73debadd 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -76,6 +76,7 @@ pub mod sync; pub mod tagged_ptr; pub mod temp_dir; pub mod thinvec; +pub mod thousands; pub mod transitive_relation; pub mod unhash; pub mod unord; diff --git a/compiler/rustc_data_structures/src/thousands/mod.rs b/compiler/rustc_data_structures/src/thousands/mod.rs new file mode 100644 index 00000000000..e7ab7ec2932 --- /dev/null +++ b/compiler/rustc_data_structures/src/thousands/mod.rs @@ -0,0 +1,16 @@ +//! This is an extremely bare-bones alternative to the `thousands` crate on +//! crates.io, for printing large numbers in a readable fashion. + +#[cfg(test)] +mod tests; + +// Converts the number to a string, with underscores as the thousands separator. +pub fn format_with_underscores(n: usize) -> String { + let mut s = n.to_string(); + let mut i = s.len(); + while i > 3 { + i -= 3; + s.insert(i, '_'); + } + s +} diff --git a/compiler/rustc_data_structures/src/thousands/tests.rs b/compiler/rustc_data_structures/src/thousands/tests.rs new file mode 100644 index 00000000000..906605d9a93 --- /dev/null +++ b/compiler/rustc_data_structures/src/thousands/tests.rs @@ -0,0 +1,14 @@ +use super::*; + +#[test] +fn test_format_with_underscores() { + assert_eq!("0", format_with_underscores(0)); + assert_eq!("1", format_with_underscores(1)); + assert_eq!("99", format_with_underscores(99)); + assert_eq!("345", format_with_underscores(345)); + assert_eq!("1_000", format_with_underscores(1_000)); + assert_eq!("12_001", format_with_underscores(12_001)); + assert_eq!("999_999", format_with_underscores(999_999)); + assert_eq!("1_000_000", format_with_underscores(1_000_000)); + assert_eq!("12_345_678", format_with_underscores(12_345_678)); +} diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 93f3d2ab911..699742aa0ea 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -7,6 +7,7 @@ use rustc_ast_pretty::pprust as pprust_ast; use rustc_middle::bug; use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty}; use rustc_middle::ty::{self, TyCtxt}; +use rustc_mir_build::thir::print::{thir_flat, thir_tree}; use rustc_session::Session; use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode}; use rustc_smir::rustc_internal::pretty::write_smir_pretty; @@ -313,7 +314,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { tcx.dcx().abort_if_errors(); debug!("pretty printing THIR tree"); for did in tcx.hir().body_owners() { - let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_tree(did)); + let _ = writeln!(out, "{:?}:\n{}\n", did, thir_tree(tcx, did)); } out } @@ -324,7 +325,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { tcx.dcx().abort_if_errors(); debug!("pretty printing THIR flat"); for did in tcx.hir().body_owners() { - let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_flat(did)); + let _ = writeln!(out, "{:?}:\n{}\n", did, thir_flat(tcx, did)); } out } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 17433eed9e7..684fc5e37e0 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1136,7 +1136,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), rustc_attr!( TEST, rustc_dump_vtable, Normal, template!(Word), - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/), diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 02bc069fc5f..d9759580e8f 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -316,6 +316,7 @@ language_item_table! { PanicAsyncFnResumedPanic, sym::panic_const_async_fn_resumed_panic, panic_const_async_fn_resumed_panic, Target::Fn, GenericRequirement::None; PanicAsyncGenFnResumedPanic, sym::panic_const_async_gen_fn_resumed_panic, panic_const_async_gen_fn_resumed_panic, Target::Fn, GenericRequirement::None; PanicGenFnNonePanic, sym::panic_const_gen_fn_none_panic, panic_const_gen_fn_none_panic, Target::Fn, GenericRequirement::None; + PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, Target::Fn, GenericRequirement::None; /// libstd panic entry point. Necessary for const eval to be able to catch it BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None; diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 7332888c5f9..3bff5fe02c0 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -424,12 +424,12 @@ fn compare_method_predicate_entailment<'tcx>( Ok(()) } -struct RemapLateParam<'a, 'tcx> { +struct RemapLateParam<'tcx> { tcx: TyCtxt<'tcx>, - mapping: &'a FxIndexMap<ty::LateParamRegionKind, ty::LateParamRegionKind>, + mapping: FxIndexMap<ty::LateParamRegionKind, ty::LateParamRegionKind>, } -impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'_, 'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'tcx> { fn cx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -653,6 +653,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( }))), terr, false, + None, ); return Err(diag.emit()); } @@ -1070,6 +1071,7 @@ fn report_trait_method_mismatch<'tcx>( }))), terr, false, + None, ); diag.emit() @@ -1862,6 +1864,7 @@ fn compare_const_predicate_entailment<'tcx>( }))), terr, false, + None, ); return Err(diag.emit()); }; diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 494e9560c81..0e9e9b48ab3 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -299,8 +299,7 @@ fn report_mismatched_rpitit_signature<'tcx>( }) .collect(); - let mut return_ty = - trait_m_sig.output().fold_with(&mut super::RemapLateParam { tcx, mapping: &mapping }); + let mut return_ty = trait_m_sig.output().fold_with(&mut super::RemapLateParam { tcx, mapping }); if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() { let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else { diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 0876bb82848..d7dfe482da4 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -1,7 +1,3 @@ -// FIXME(@lcnr): Move this module out of `rustc_hir_analysis`. -// -// We don't do any drop checking during hir typeck. - use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{ErrorGuaranteed, struct_span_code_err}; @@ -32,7 +28,10 @@ use crate::hir::def_id::{DefId, LocalDefId}; /// struct/enum definition for the nominal type itself (i.e. /// cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`). /// -pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorGuaranteed> { +pub(crate) fn check_drop_impl( + tcx: TyCtxt<'_>, + drop_impl_did: DefId, +) -> Result<(), ErrorGuaranteed> { match tcx.impl_polarity(drop_impl_did) { ty::ImplPolarity::Positive => {} ty::ImplPolarity::Negative => { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 8aa95d1c1d5..cf3d4897304 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -199,7 +199,8 @@ pub fn check_intrinsic_type( let split: Vec<&str> = name_str.split('_').collect(); assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format"); - //We only care about the operation here + // Each atomic op has variants with different suffixes (`_seq_cst`, `_acquire`, etc.). Use + // string ops to strip the suffixes, because the variants all get the same treatment here. let (n_tps, inputs, output) = match split[1] { "cxchg" | "cxchgweak" => ( 1, diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 814c784710a..96b33bdd250 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -455,18 +455,14 @@ fn fn_sig_suggestion<'tcx>( let mut output = sig.output(); let asyncness = if tcx.asyncness(assoc.def_id).is_async() { - output = if let ty::Alias(_, alias_ty) = *output.kind() { - tcx.explicit_item_self_bounds(alias_ty.def_id) + output = if let ty::Alias(_, alias_ty) = *output.kind() + && let Some(output) = tcx + .explicit_item_self_bounds(alias_ty.def_id) .iter_instantiated_copied(tcx, alias_ty.args) .find_map(|(bound, _)| { bound.as_projection_clause()?.no_bound_vars()?.term.as_type() - }) - .unwrap_or_else(|| { - span_bug!( - ident.span, - "expected async fn to have `impl Future` output, but it returns {output}" - ) - }) + }) { + output } else { span_bug!( ident.span, @@ -649,6 +645,7 @@ pub fn check_function_signature<'tcx>( }))), err, false, + None, ); return Err(diag.emit()); } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 83bb8c0dfaf..c9837ca3716 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2267,14 +2267,12 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> { let items = tcx.hir_module_items(module); - let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)); - res = - res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))); - res = - res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))); - res = res - .and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))); - res = res.and(items.par_opaques(|item| tcx.ensure().check_well_formed(item))); + let res = items + .par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)) + .and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))) + .and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))) + .and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))) + .and(items.par_opaques(|item| tcx.ensure().check_well_formed(item))); if module == LocalModDefId::CRATE_DEF_ID { super::entry::check_for_entry_fn(tcx); } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 6bbd76633da..30f51fe1724 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -404,17 +404,12 @@ pub(crate) fn coerce_unsized_info<'tcx>( check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ref(tcx, r_b, ty)) } - (&ty::Ref(_, ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => check_mutbl( - ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a }, - ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b }, - &|ty| Ty::new_imm_ptr(tcx, ty), - ), - - (&ty::RawPtr(ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => check_mutbl( - ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a }, - ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b }, - &|ty| Ty::new_imm_ptr(tcx, ty), - ), + (&ty::Ref(_, ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) + | (&ty::RawPtr(ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => { + let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a }; + let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b }; + check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ptr(tcx, ty)) + } (&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 4e5f0a3186a..b9ef166fc3f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -158,12 +158,12 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> let trait_ref = trait_header.trait_ref.instantiate_identity(); let trait_def = tcx.trait_def(trait_ref.def_id); - res = res.and(check_impl(tcx, impl_def_id, trait_ref, trait_def)); - res = res.and(check_object_overlap(tcx, impl_def_id, trait_ref)); - - res = res.and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def)); - res = res.and(tcx.ensure().orphan_check_impl(impl_def_id)); - res = res.and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header)); + res = res + .and(check_impl(tcx, impl_def_id, trait_ref, trait_def)) + .and(check_object_overlap(tcx, impl_def_id, trait_ref)) + .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def)) + .and(tcx.ensure().orphan_check_impl(impl_def_id)) + .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header)); } res @@ -199,10 +199,9 @@ fn check_object_overlap<'tcx>( for component_def_id in component_def_ids { if !tcx.is_dyn_compatible(component_def_id) { - // FIXME(dyn_compat_renaming): Rename test and update comment. // Without the 'dyn_compatible_for_dispatch' feature this is an error // which will be reported by wfcheck. Ignore it here. - // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`. + // This is tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`. // With the feature enabled, the trait is not implemented automatically, // so this is valid. } else { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index cad7b2a1e57..226370fccad 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -57,7 +57,7 @@ mod type_of; /////////////////////////////////////////////////////////////////////////// -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { resolve_bound_vars::provide(providers); *providers = Providers { type_of: type_of::type_of, @@ -122,7 +122,7 @@ pub fn provide(providers: &mut Providers) { /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy /// `probe_ty_param_bounds` requests, drawing the information from /// the HIR (`hir::Generics`), recursively. -pub struct ItemCtxt<'tcx> { +pub(crate) struct ItemCtxt<'tcx> { tcx: TyCtxt<'tcx>, item_def_id: LocalDefId, tainted_by_errors: Cell<Option<ErrorGuaranteed>>, @@ -148,7 +148,7 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector { } } -pub struct CollectItemTypesVisitor<'tcx> { +pub(crate) struct CollectItemTypesVisitor<'tcx> { pub tcx: TyCtxt<'tcx>, } @@ -364,19 +364,19 @@ fn bad_placeholder<'cx, 'tcx>( } impl<'tcx> ItemCtxt<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> { + pub(crate) fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> { ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) } } - pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { + pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { self.lowerer().lower_ty(hir_ty) } - pub fn hir_id(&self) -> hir::HirId { + pub(crate) fn hir_id(&self) -> hir::HirId { self.tcx.local_def_id_to_hir_id(self.item_def_id) } - pub fn node(&self) -> hir::Node<'tcx> { + pub(crate) fn node(&self) -> hir::Node<'tcx> { self.tcx.hir_node(self.hir_id()) } diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index f1022d95753..4a508fc0cf6 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -1,7 +1,8 @@ +use rustc_hir as hir; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::intravisit; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::sym; pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { @@ -87,3 +88,82 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) { } } } + +pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { + for id in tcx.hir().items() { + let def_id = id.owner_id.def_id; + + let Some(attr) = tcx.get_attr(def_id, sym::rustc_dump_vtable) else { + continue; + }; + + let vtable_entries = match tcx.hir().item(id).kind { + hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => { + let trait_ref = tcx.impl_trait_ref(def_id).unwrap().instantiate_identity(); + if trait_ref.has_non_region_param() { + tcx.dcx().span_err( + attr.span, + "`rustc_dump_vtable` must be applied to non-generic impl", + ); + continue; + } + if !tcx.is_dyn_compatible(trait_ref.def_id) { + tcx.dcx().span_err( + attr.span, + "`rustc_dump_vtable` must be applied to dyn-compatible trait", + ); + continue; + } + let Ok(trait_ref) = tcx + .try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref) + else { + tcx.dcx().span_err( + attr.span, + "`rustc_dump_vtable` applied to impl header that cannot be normalized", + ); + continue; + }; + tcx.vtable_entries(trait_ref) + } + hir::ItemKind::TyAlias(_, _) => { + let ty = tcx.type_of(def_id).instantiate_identity(); + if ty.has_non_region_param() { + tcx.dcx().span_err( + attr.span, + "`rustc_dump_vtable` must be applied to non-generic type", + ); + continue; + } + let Ok(ty) = + tcx.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) + else { + tcx.dcx().span_err( + attr.span, + "`rustc_dump_vtable` applied to type alias that cannot be normalized", + ); + continue; + }; + let ty::Dynamic(data, _, _) = *ty.kind() else { + tcx.dcx().span_err(attr.span, "`rustc_dump_vtable` to type alias of dyn type"); + continue; + }; + if let Some(principal) = data.principal() { + tcx.vtable_entries( + tcx.instantiate_bound_regions_with_erased(principal).with_self_ty(tcx, ty), + ) + } else { + TyCtxt::COMMON_VTABLE_ENTRIES + } + } + _ => { + tcx.dcx().span_err( + attr.span, + "`rustc_dump_vtable` only applies to impl, or type alias of dyn type", + ); + continue; + } + }; + + tcx.dcx().span_err(tcx.def_span(def_id), format!("vtable entries: {vtable_entries:#?}")); + } +} diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 72baf5c4b58..d67b9d33596 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -12,13 +12,11 @@ use std::ops::ControlFlow; use rustc_ast::visit::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_data_structures::sorted_map::SortedMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt}; use rustc_hir::{ - self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, ItemLocalMap, - LifetimeName, Node, + self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeName, Node, }; use rustc_macros::extension; use rustc_middle::hir::nested_filter; @@ -26,7 +24,7 @@ use rustc_middle::middle::resolve_bound_vars::*; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_middle::{bug, span_bug}; -use rustc_span::def_id::{DefId, LocalDefId, LocalDefIdMap}; +use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::{Ident, Span, sym}; use tracing::{debug, debug_span, instrument}; @@ -62,33 +60,9 @@ impl ResolvedArg { } } -/// Maps the id of each bound variable reference to the variable decl -/// that it corresponds to. -/// -/// FIXME. This struct gets converted to a `ResolveBoundVars` for -/// actual use. It has the same data, but indexed by `LocalDefId`. This -/// is silly. -#[derive(Debug, Default)] -struct NamedVarMap { - // maps from every use of a named (not anonymous) bound var to a - // `ResolvedArg` describing how that variable is bound - defs: ItemLocalMap<ResolvedArg>, - - // Maps relevant hir items to the bound vars on them. These include: - // - function defs - // - function pointers - // - closures - // - trait refs - // - bound types (like `T` in `for<'a> T<'a>: Foo`) - late_bound_vars: ItemLocalMap<Vec<ty::BoundVariableKind>>, - - // List captured variables for each opaque type. - opaque_captured_lifetimes: LocalDefIdMap<Vec<(ResolvedArg, LocalDefId)>>, -} - struct BoundVarContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, - map: &'a mut NamedVarMap, + rbv: &'a mut ResolveBoundVars, scope: ScopeRef<'a>, } @@ -267,19 +241,12 @@ pub(crate) fn provide(providers: &mut Providers) { /// Computes the `ResolveBoundVars` map that contains data for an entire `Item`. /// You should not read the result of this query directly, but rather use -/// `named_variable_map`, `is_late_bound_map`, etc. +/// `named_variable_map`, `late_bound_vars_map`, etc. #[instrument(level = "debug", skip(tcx))] fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars { - let mut named_variable_map = NamedVarMap { - defs: Default::default(), - late_bound_vars: Default::default(), - opaque_captured_lifetimes: Default::default(), - }; - let mut visitor = BoundVarContext { - tcx, - map: &mut named_variable_map, - scope: &Scope::Root { opt_parent_item: None }, - }; + let mut rbv = ResolveBoundVars::default(); + let mut visitor = + BoundVarContext { tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None } }; match tcx.hir_owner_node(local_def_id) { hir::OwnerNode::Item(item) => visitor.visit_item(item), hir::OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item), @@ -299,19 +266,10 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou hir::OwnerNode::Synthetic => unreachable!(), } - let defs = named_variable_map.defs.into_sorted_stable_ord(); - let late_bound_vars = named_variable_map.late_bound_vars.into_sorted_stable_ord(); - let opaque_captured_lifetimes = named_variable_map.opaque_captured_lifetimes; - let rl = ResolveBoundVars { - defs: SortedMap::from_presorted_elements(defs), - late_bound_vars: SortedMap::from_presorted_elements(late_bound_vars), - opaque_captured_lifetimes, - }; - - debug!(?rl.defs); - debug!(?rl.late_bound_vars); - debug!(?rl.opaque_captured_lifetimes); - rl + debug!(?rbv.defs); + debug!(?rbv.late_bound_vars); + debug!(?rbv.opaque_captured_lifetimes); + rbv } fn late_arg_as_bound_arg<'tcx>( @@ -404,7 +362,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { Scope::Binder { hir_id, .. } => { // Nested poly trait refs have the binders concatenated let mut full_binders = - self.map.late_bound_vars.entry(hir_id.local_id).or_default().clone(); + self.rbv.late_bound_vars.get_mut_or_insert_default(hir_id.local_id).clone(); full_binders.extend(supertrait_bound_vars); break (full_binders, BinderScopeType::Concatenating); } @@ -646,7 +604,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { let captures = captures.into_inner().into_iter().collect(); debug!(?captures); - self.map.opaque_captured_lifetimes.insert(opaque.def_id, captures); + self.rbv.opaque_captured_lifetimes.insert(opaque.def_id, captures); } #[instrument(level = "debug", skip(self))] @@ -848,7 +806,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { hir::TyKind::Ref(lifetime_ref, ref mt) => { self.visit_lifetime(lifetime_ref); let scope = Scope::ObjectLifetimeDefault { - lifetime: self.map.defs.get(&lifetime_ref.hir_id.local_id).cloned(), + lifetime: self.rbv.defs.get(&lifetime_ref.hir_id.local_id).cloned(), s: self.scope, }; self.with(scope, |this| this.visit_ty_unambig(mt.ty)); @@ -966,7 +924,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { let bound_vars: Vec<_> = self.tcx.fn_sig(sig_id).skip_binder().bound_vars().iter().collect(); let hir_id = self.tcx.local_def_id_to_hir_id(def_id); - self.map.late_bound_vars.insert(hir_id.local_id, bound_vars); + self.rbv.late_bound_vars.insert(hir_id.local_id, bound_vars); } self.visit_fn_like_elision(fd.inputs, output, matches!(fk, intravisit::FnKind::Closure)); intravisit::walk_fn_kind(self, fk); @@ -1140,8 +1098,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { where F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>), { - let BoundVarContext { tcx, map, .. } = self; - let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope }; + let BoundVarContext { tcx, rbv, .. } = self; + let mut this = BoundVarContext { tcx: *tcx, rbv, scope: &wrap_scope }; let span = debug_span!("scope", scope = ?this.scope.debug_truncated()); { let _enter = span.enter(); @@ -1150,10 +1108,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec<ty::BoundVariableKind>) { - if let Some(old) = self.map.late_bound_vars.insert(hir_id.local_id, binder) { + if let Some(old) = self.rbv.late_bound_vars.insert(hir_id.local_id, binder) { bug!( "overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}", - self.map.late_bound_vars[&hir_id.local_id] + self.rbv.late_bound_vars[&hir_id.local_id] ) } } @@ -1597,9 +1555,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { kind.descr(param_def_id.to_def_id()) ), }; - self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar)); + self.rbv.defs.insert(hir_id.local_id, ResolvedArg::Error(guar)); } else { - self.map.defs.insert(hir_id.local_id, def); + self.rbv.defs.insert(hir_id.local_id, def); } return; } @@ -1632,7 +1590,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { bug!("unexpected def-kind: {}", kind.descr(param_def_id.to_def_id())) } }); - self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar)); + self.rbv.defs.insert(hir_id.local_id, ResolvedArg::Error(guar)); return; } Scope::Root { .. } => break, @@ -1725,7 +1683,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } }; - let map = &self.map; + let rbv = &self.rbv; let generics = self.tcx.generics_of(def_id); // `type_def_id` points to an item, so there is nothing to inherit generics from. @@ -1744,7 +1702,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // This index can be used with `generic_args` since `parent_count == 0`. let index = generics.param_def_id_to_index[¶m_def_id] as usize; generic_args.args.get(index).and_then(|arg| match arg { - GenericArg::Lifetime(lt) => map.defs.get(<.hir_id.local_id).copied(), + GenericArg::Lifetime(lt) => rbv.defs.get(<.hir_id.local_id).copied(), _ => None, }) } @@ -2042,7 +2000,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: ResolvedArg) { debug!(span = ?lifetime_ref.ident.span); - self.map.defs.insert(lifetime_ref.hir_id.local_id, def); + self.rbv.defs.insert(lifetime_ref.hir_id.local_id, def); } // When we have a return type notation type in a where clause, like @@ -2197,7 +2155,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // See where these vars are used in `HirTyLowerer::lower_ty_maybe_return_type_notation`. // And this is exercised in: // `tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs`. - let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id.local_id).unwrap(); + let existing_bound_vars = self.rbv.late_bound_vars.get_mut(&hir_id.local_id).unwrap(); let existing_bound_vars_saved = existing_bound_vars.clone(); existing_bound_vars.extend(bound_vars); self.record_late_bound_vars(item_segment.hir_id, existing_bound_vars_saved); diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index e65420ea8bf..ed45833b614 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -100,213 +100,156 @@ enum InheritanceKind { Own, } -struct GenericsBuilder<'tcx> { +fn build_generics<'tcx>( tcx: TyCtxt<'tcx>, sig_id: DefId, parent: Option<DefId>, inh_kind: InheritanceKind, -} - -impl<'tcx> GenericsBuilder<'tcx> { - fn new(tcx: TyCtxt<'tcx>, sig_id: DefId) -> GenericsBuilder<'tcx> { - GenericsBuilder { tcx, sig_id, parent: None, inh_kind: InheritanceKind::WithParent(false) } - } - - fn with_parent(mut self, parent: DefId) -> Self { - self.parent = Some(parent); - self - } - - fn with_inheritance_kind(mut self, inh_kind: InheritanceKind) -> Self { - self.inh_kind = inh_kind; - self - } - - fn build(self) -> ty::Generics { - let mut own_params = vec![]; +) -> ty::Generics { + let mut own_params = vec![]; - let sig_generics = self.tcx.generics_of(self.sig_id); - if let InheritanceKind::WithParent(has_self) = self.inh_kind - && let Some(parent_def_id) = sig_generics.parent - { - let sig_parent_generics = self.tcx.generics_of(parent_def_id); - own_params.append(&mut sig_parent_generics.own_params.clone()); - if !has_self { - own_params.remove(0); - } + let sig_generics = tcx.generics_of(sig_id); + if let InheritanceKind::WithParent(has_self) = inh_kind + && let Some(parent_def_id) = sig_generics.parent + { + let sig_parent_generics = tcx.generics_of(parent_def_id); + own_params.append(&mut sig_parent_generics.own_params.clone()); + if !has_self { + own_params.remove(0); } - own_params.append(&mut sig_generics.own_params.clone()); + } + own_params.append(&mut sig_generics.own_params.clone()); + + // Lifetime parameters must be declared before type and const parameters. + // Therefore, When delegating from a free function to a associated function, + // generic parameters need to be reordered: + // + // trait Trait<'a, A> { + // fn foo<'b, B>(...) {...} + // } + // + // reuse Trait::foo; + // desugaring: + // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) { + // Trait::foo(...) + // } + own_params.sort_by_key(|key| key.kind.is_ty_or_const()); + + let param_def_id_to_index = + own_params.iter().map(|param| (param.def_id, param.index)).collect(); + + let (parent_count, has_self) = if let Some(def_id) = parent { + let parent_generics = tcx.generics_of(def_id); + let parent_kind = tcx.def_kind(def_id); + (parent_generics.count(), parent_kind == DefKind::Trait) + } else { + (0, false) + }; - // Lifetime parameters must be declared before type and const parameters. - // Therefore, When delegating from a free function to a associated function, - // generic parameters need to be reordered: + for (idx, param) in own_params.iter_mut().enumerate() { + param.index = (idx + parent_count) as u32; + // FIXME(fn_delegation): Default parameters are not inherited, because they are + // not permitted in functions. Therefore, there are 2 options here: // - // trait Trait<'a, A> { - // fn foo<'b, B>(...) {...} - // } + // - We can create non-default generic parameters. + // - We can substitute default parameters into the signature. // - // reuse Trait::foo; - // desugaring: - // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) { - // Trait::foo(...) - // } - own_params.sort_by_key(|key| key.kind.is_ty_or_const()); - - let param_def_id_to_index = - own_params.iter().map(|param| (param.def_id, param.index)).collect(); - - let (parent_count, has_self) = if let Some(def_id) = self.parent { - let parent_generics = self.tcx.generics_of(def_id); - let parent_kind = self.tcx.def_kind(def_id); - (parent_generics.count(), parent_kind == DefKind::Trait) - } else { - (0, false) - }; - - for (idx, param) in own_params.iter_mut().enumerate() { - param.index = (idx + parent_count) as u32; - // FIXME(fn_delegation): Default parameters are not inherited, because they are - // not permitted in functions. Therefore, there are 2 options here: - // - // - We can create non-default generic parameters. - // - We can substitute default parameters into the signature. - // - // At the moment, first option has been selected as the most general. - if let ty::GenericParamDefKind::Type { has_default, .. } - | ty::GenericParamDefKind::Const { has_default, .. } = &mut param.kind - { - *has_default = false; - } + // At the moment, first option has been selected as the most general. + if let ty::GenericParamDefKind::Type { has_default, .. } + | ty::GenericParamDefKind::Const { has_default, .. } = &mut param.kind + { + *has_default = false; } + } - ty::Generics { - parent: self.parent, - parent_count, - own_params, - param_def_id_to_index, - has_self, - has_late_bound_regions: sig_generics.has_late_bound_regions, - } + ty::Generics { + parent, + parent_count, + own_params, + param_def_id_to_index, + has_self, + has_late_bound_regions: sig_generics.has_late_bound_regions, } } -struct PredicatesBuilder<'tcx> { +fn build_predicates<'tcx>( tcx: TyCtxt<'tcx>, sig_id: DefId, parent: Option<DefId>, inh_kind: InheritanceKind, args: ty::GenericArgsRef<'tcx>, -} - -impl<'tcx> PredicatesBuilder<'tcx> { - fn new( +) -> ty::GenericPredicates<'tcx> { + struct PredicatesCollector<'tcx> { tcx: TyCtxt<'tcx>, + preds: Vec<(ty::Clause<'tcx>, Span)>, args: ty::GenericArgsRef<'tcx>, - sig_id: DefId, - ) -> PredicatesBuilder<'tcx> { - PredicatesBuilder { - tcx, - sig_id, - parent: None, - inh_kind: InheritanceKind::WithParent(false), - args, - } - } - - fn with_parent(mut self, parent: DefId) -> Self { - self.parent = Some(parent); - self } - fn with_inheritance_kind(mut self, inh_kind: InheritanceKind) -> Self { - self.inh_kind = inh_kind; - self - } - - fn build(self) -> ty::GenericPredicates<'tcx> { - struct PredicatesCollector<'tcx> { - tcx: TyCtxt<'tcx>, - preds: Vec<(ty::Clause<'tcx>, Span)>, - args: ty::GenericArgsRef<'tcx>, + impl<'tcx> PredicatesCollector<'tcx> { + fn new(tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> PredicatesCollector<'tcx> { + PredicatesCollector { tcx, preds: vec![], args } } - impl<'tcx> PredicatesCollector<'tcx> { - fn new(tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> PredicatesCollector<'tcx> { - PredicatesCollector { tcx, preds: vec![], args } - } - - fn with_own_preds( - mut self, - f: impl Fn(DefId) -> ty::GenericPredicates<'tcx>, - def_id: DefId, - ) -> Self { - let preds = f(def_id).instantiate_own(self.tcx, self.args); - self.preds.extend(preds); - self - } + fn with_own_preds( + mut self, + f: impl Fn(DefId) -> ty::GenericPredicates<'tcx>, + def_id: DefId, + ) -> Self { + let preds = f(def_id).instantiate_own(self.tcx, self.args); + self.preds.extend(preds); + self + } - fn with_preds( - mut self, - f: impl Fn(DefId) -> ty::GenericPredicates<'tcx> + Copy, - def_id: DefId, - ) -> Self { - let preds = f(def_id); - if let Some(parent_def_id) = preds.parent { - self = self.with_own_preds(f, parent_def_id); - } - self.with_own_preds(f, def_id) + fn with_preds( + mut self, + f: impl Fn(DefId) -> ty::GenericPredicates<'tcx> + Copy, + def_id: DefId, + ) -> Self { + let preds = f(def_id); + if let Some(parent_def_id) = preds.parent { + self = self.with_own_preds(f, parent_def_id); } + self.with_own_preds(f, def_id) } - let collector = PredicatesCollector::new(self.tcx, self.args); - - // `explicit_predicates_of` is used here to avoid copying `Self: Trait` predicate. - // Note: `predicates_of` query can also add inferred outlives predicates, but that - // is not the case here as `sig_id` is either a trait or a function. - let preds = match self.inh_kind { - InheritanceKind::WithParent(false) => { - collector.with_preds(|def_id| self.tcx.explicit_predicates_of(def_id), self.sig_id) - } - InheritanceKind::WithParent(true) => { - collector.with_preds(|def_id| self.tcx.predicates_of(def_id), self.sig_id) - } - InheritanceKind::Own => { - collector.with_own_preds(|def_id| self.tcx.predicates_of(def_id), self.sig_id) - } + } + let collector = PredicatesCollector::new(tcx, args); + + // `explicit_predicates_of` is used here to avoid copying `Self: Trait` predicate. + // Note: `predicates_of` query can also add inferred outlives predicates, but that + // is not the case here as `sig_id` is either a trait or a function. + let preds = match inh_kind { + InheritanceKind::WithParent(false) => { + collector.with_preds(|def_id| tcx.explicit_predicates_of(def_id), sig_id) } - .preds; - - ty::GenericPredicates { - parent: self.parent, - predicates: self.tcx.arena.alloc_from_iter(preds), + InheritanceKind::WithParent(true) => { + collector.with_preds(|def_id| tcx.predicates_of(def_id), sig_id) + } + InheritanceKind::Own => { + collector.with_own_preds(|def_id| tcx.predicates_of(def_id), sig_id) } } + .preds; + + ty::GenericPredicates { parent, predicates: tcx.arena.alloc_from_iter(preds) } } -struct GenericArgsBuilder<'tcx> { +fn build_generic_args<'tcx>( tcx: TyCtxt<'tcx>, - remap_table: RemapTable, sig_id: DefId, def_id: LocalDefId, -} + args: ty::GenericArgsRef<'tcx>, +) -> ty::GenericArgsRef<'tcx> { + let caller_generics = tcx.generics_of(def_id); + let callee_generics = tcx.generics_of(sig_id); -impl<'tcx> GenericArgsBuilder<'tcx> { - fn new(tcx: TyCtxt<'tcx>, sig_id: DefId, def_id: LocalDefId) -> GenericArgsBuilder<'tcx> { - GenericArgsBuilder { tcx, remap_table: FxHashMap::default(), sig_id, def_id } + let mut remap_table = FxHashMap::default(); + for caller_param in &caller_generics.own_params { + let callee_index = callee_generics.param_def_id_to_index(tcx, caller_param.def_id).unwrap(); + remap_table.insert(callee_index, caller_param.index); } - fn build_from_args(mut self, args: ty::GenericArgsRef<'tcx>) -> ty::GenericArgsRef<'tcx> { - let caller_generics = self.tcx.generics_of(self.def_id); - let callee_generics = self.tcx.generics_of(self.sig_id); - - for caller_param in &caller_generics.own_params { - let callee_index = - callee_generics.param_def_id_to_index(self.tcx, caller_param.def_id).unwrap(); - self.remap_table.insert(callee_index, caller_param.index); - } - - let mut folder = ParamIndexRemapper { tcx: self.tcx, remap_table: self.remap_table }; - args.fold_with(&mut folder) - } + let mut folder = ParamIndexRemapper { tcx, remap_table }; + args.fold_with(&mut folder) } fn create_generic_args<'tcx>( @@ -314,8 +257,6 @@ fn create_generic_args<'tcx>( def_id: LocalDefId, sig_id: DefId, ) -> ty::GenericArgsRef<'tcx> { - let builder = GenericArgsBuilder::new(tcx, sig_id, def_id); - let caller_kind = fn_kind(tcx, def_id.into()); let callee_kind = fn_kind(tcx, sig_id); match (caller_kind, callee_kind) { @@ -325,7 +266,7 @@ fn create_generic_args<'tcx>( | (FnKind::AssocTrait, FnKind::Free) | (FnKind::AssocTrait, FnKind::AssocTrait) => { let args = ty::GenericArgs::identity_for_item(tcx, sig_id); - builder.build_from_args(args) + build_generic_args(tcx, sig_id, def_id, args) } (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { @@ -335,8 +276,9 @@ fn create_generic_args<'tcx>( tcx.impl_trait_header(parent).unwrap().trait_ref.instantiate_identity().args; let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id); - let method_args = tcx.mk_args_from_iter(trait_args.iter().skip(callee_generics.parent_count)); - let method_args = builder.build_from_args(method_args); + let method_args = + tcx.mk_args_from_iter(trait_args.iter().skip(callee_generics.parent_count)); + let method_args = build_generic_args(tcx, sig_id, def_id, method_args); tcx.mk_args_from_iter(parent_args.iter().chain(method_args)) } @@ -347,16 +289,16 @@ fn create_generic_args<'tcx>( let generic_self_ty = ty::GenericArg::from(self_ty); let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id); - let trait_args = builder.build_from_args(trait_args); + let trait_args = build_generic_args(tcx, sig_id, def_id, trait_args); let args = std::iter::once(generic_self_ty).chain(trait_args.iter().skip(1)); tcx.mk_args_from_iter(args) } // For trait impl's `sig_id` is always equal to the corresponding trait method. + // For inherent methods delegation is not yet supported. (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) - // Delegation to inherent methods is not yet supported. | (_, FnKind::AssocInherentImpl) => unreachable!(), } } @@ -377,39 +319,31 @@ pub(crate) fn inherit_generics_for_delegation_item<'tcx>( def_id: LocalDefId, sig_id: DefId, ) -> ty::Generics { - let builder = GenericsBuilder::new(tcx, sig_id); - let caller_kind = fn_kind(tcx, def_id.into()); let callee_kind = fn_kind(tcx, sig_id); match (caller_kind, callee_kind) { - (FnKind::Free, FnKind::Free) - | (FnKind::Free, FnKind::AssocTrait) => builder.with_inheritance_kind(InheritanceKind::WithParent(true)).build(), + (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => { + build_generics(tcx, sig_id, None, InheritanceKind::WithParent(true)) + } (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { - builder - .with_parent(tcx.parent(def_id.into())) - .with_inheritance_kind(InheritanceKind::Own) - .build() + build_generics(tcx, sig_id, Some(tcx.parent(def_id.into())), InheritanceKind::Own) } (FnKind::AssocInherentImpl, FnKind::AssocTrait) - | (FnKind::AssocTrait, FnKind::AssocTrait) => { - builder - .with_parent(tcx.parent(def_id.into())) - .build() - } - - (FnKind::AssocInherentImpl, FnKind::Free) - | (FnKind::AssocTrait, FnKind::Free) => { - builder - .with_parent(tcx.parent(def_id.into())) - .build() - } + | (FnKind::AssocTrait, FnKind::AssocTrait) + | (FnKind::AssocInherentImpl, FnKind::Free) + | (FnKind::AssocTrait, FnKind::Free) => build_generics( + tcx, + sig_id, + Some(tcx.parent(def_id.into())), + InheritanceKind::WithParent(false), + ), // For trait impl's `sig_id` is always equal to the corresponding trait method. + // For inherent methods delegation is not yet supported. (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) - // Delegation to inherent methods is not yet supported. | (_, FnKind::AssocInherentImpl) => unreachable!(), } } @@ -420,36 +354,36 @@ pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( sig_id: DefId, ) -> ty::GenericPredicates<'tcx> { let args = create_generic_args(tcx, def_id, sig_id); - let builder = PredicatesBuilder::new(tcx, args, sig_id); - let caller_kind = fn_kind(tcx, def_id.into()); let callee_kind = fn_kind(tcx, sig_id); match (caller_kind, callee_kind) { - (FnKind::Free, FnKind::Free) - | (FnKind::Free, FnKind::AssocTrait) => { - builder.with_inheritance_kind(InheritanceKind::WithParent(true)).build() + (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => { + build_predicates(tcx, sig_id, None, InheritanceKind::WithParent(true), args) } - (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { - builder - .with_parent(tcx.parent(def_id.into())) - .with_inheritance_kind(InheritanceKind::Own) - .build() - } + (FnKind::AssocTraitImpl, FnKind::AssocTrait) => build_predicates( + tcx, + sig_id, + Some(tcx.parent(def_id.into())), + InheritanceKind::Own, + args, + ), (FnKind::AssocInherentImpl, FnKind::AssocTrait) | (FnKind::AssocTrait, FnKind::AssocTrait) | (FnKind::AssocInherentImpl, FnKind::Free) - | (FnKind::AssocTrait, FnKind::Free) => { - builder - .with_parent(tcx.parent(def_id.into())) - .build() - } + | (FnKind::AssocTrait, FnKind::Free) => build_predicates( + tcx, + sig_id, + Some(tcx.parent(def_id.into())), + InheritanceKind::WithParent(false), + args, + ), // For trait impl's `sig_id` is always equal to the corresponding trait method. + // For inherent methods delegation is not yet supported. (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) - // Delegation to inherent methods is not yet supported. | (_, FnKind::AssocInherentImpl) => unreachable!(), } } diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 67407349729..b2501d647a5 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -495,6 +495,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { .iter() .any(|constraint| constraint.ident.name == item.name) }) + .filter(|item| !item.is_impl_trait_in_trait()) .map(|item| self.tcx.item_ident(item.def_id).to_string()) .collect() } else { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index fe3dcb35639..43137397870 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -273,7 +273,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( // We lower to an infer even when the feature gate is not enabled // as it is useful for diagnostics to be able to see a `ConstKind::Infer` - args.push(ctx.provided_kind(&args, param, arg)); + args.push(ctx.provided_kind(param, arg)); args_iter.next(); params.next(); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 61d5869c19f..b4cab3330af 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -296,7 +296,6 @@ pub trait GenericArgsLowerer<'a, 'tcx> { fn provided_kind( &mut self, - preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx>; @@ -480,7 +479,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn provided_kind( &mut self, - _preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 32694d5f4bc..af1107b499f 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -34,7 +34,7 @@ //! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ } //! ``` //! -//! We get that the generic pamameters for `impl2` are `[T, std::vec::IntoIter<T>]`. +//! We get that the generic parameters for `impl2` are `[T, std::vec::IntoIter<T>]`. //! `T` is constrained to be `<I as Iterator>::Item`, so we check only //! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The //! predicates of `impl1` are only `T: Sized`, which is also a predicate of @@ -119,7 +119,6 @@ fn check_always_applicable( impl2_node: Node, ) -> Result<(), ErrorGuaranteed> { let span = tcx.def_span(impl1_def_id); - let mut res = check_has_items(tcx, impl1_def_id, impl2_node, span); let (impl1_args, impl2_args) = get_impl_args(tcx, impl1_def_id, impl2_node)?; let impl2_def_id = impl2_node.def_id(); @@ -131,11 +130,10 @@ fn check_always_applicable( unconstrained_parent_impl_args(tcx, impl2_def_id, impl2_args) }; - res = res.and(check_static_lifetimes(tcx, &parent_args, span)); - res = res.and(check_duplicate_params(tcx, impl1_args, parent_args, span)); - res = res.and(check_predicates(tcx, impl1_def_id, impl1_args, impl2_node, impl2_args, span)); - - res + check_has_items(tcx, impl1_def_id, impl2_node, span) + .and(check_static_lifetimes(tcx, &parent_args, span)) + .and(check_duplicate_params(tcx, impl1_args, parent_args, span)) + .and(check_predicates(tcx, impl1_def_id, impl1_args, impl2_node, impl2_args, span)) } fn check_has_items( diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index bc7d4365eee..ae054a9eaeb 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -83,12 +83,11 @@ pub mod autoderef; mod bounds; mod check_unused; mod coherence; -mod delegation; -pub mod hir_ty_lowering; -// FIXME: This module shouldn't be public. -pub mod collect; +mod collect; mod constrained_generic_params; +mod delegation; mod errors; +pub mod hir_ty_lowering; pub mod hir_wf_check; mod impl_wf_check; mod outlives; @@ -104,7 +103,8 @@ use rustc_middle::ty::{self, Const, Ty, TyCtxt}; use rustc_span::Span; use rustc_trait_selection::traits; -use self::hir_ty_lowering::{FeedConstTy, HirTyLowerer}; +pub use crate::collect::suggest_impl_trait; +use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer}; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } @@ -152,11 +152,14 @@ pub fn check_crate(tcx: TyCtxt<'_>) { }); if tcx.features().rustc_attrs() { - tcx.sess.time("outlives_dumping", || outlives::dump::inferred_outlives(tcx)); - tcx.sess.time("variance_dumping", || variance::dump::variances(tcx)); - collect::dump::opaque_hidden_types(tcx); - collect::dump::predicates_and_item_bounds(tcx); - collect::dump::def_parents(tcx); + tcx.sess.time("dumping_rustc_attr_data", || { + outlives::dump::inferred_outlives(tcx); + variance::dump::variances(tcx); + collect::dump::opaque_hidden_types(tcx); + collect::dump::predicates_and_item_bounds(tcx); + collect::dump::def_parents(tcx); + collect::dump::vtables(tcx); + }); } // Make sure we evaluate all static and (non-associated) const items, even if unused. diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index c2377b4781c..036163b9f14 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -24,7 +24,7 @@ pub(super) fn infer_predicates( // If new predicates were added then we need to re-calculate // all crates since there could be new implied predicates. - 'outer: loop { + loop { let mut predicates_added = false; // Visit all the crates and infer predicates @@ -90,7 +90,7 @@ pub(super) fn infer_predicates( } if !predicates_added { - break 'outer; + break; } } diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 02cfb57b836..a7760326bb4 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -27,9 +27,6 @@ mod solve; pub(crate) mod dump; -/// Code for transforming variances. -mod xform; - pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { variances_of, crate_variances, ..*providers }; } diff --git a/compiler/rustc_hir_analysis/src/variance/solve.rs b/compiler/rustc_hir_analysis/src/variance/solve.rs index d0bdca86779..4106c1a5b63 100644 --- a/compiler/rustc_hir_analysis/src/variance/solve.rs +++ b/compiler/rustc_hir_analysis/src/variance/solve.rs @@ -12,8 +12,26 @@ use tracing::debug; use super::constraints::*; use super::terms::VarianceTerm::*; use super::terms::*; -use super::xform::*; +fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance { + // Greatest lower bound of the variance lattice as defined in The Paper: + // + // * + // - + + // o + match (v1, v2) { + (ty::Invariant, _) | (_, ty::Invariant) => ty::Invariant, + + (ty::Covariant, ty::Contravariant) => ty::Invariant, + (ty::Contravariant, ty::Covariant) => ty::Invariant, + + (ty::Covariant, ty::Covariant) => ty::Covariant, + + (ty::Contravariant, ty::Contravariant) => ty::Contravariant, + + (x, ty::Bivariant) | (ty::Bivariant, x) => x, + } +} struct SolveContext<'a, 'tcx> { terms_cx: TermsContext<'a, 'tcx>, constraints: Vec<Constraint<'a>>, diff --git a/compiler/rustc_hir_analysis/src/variance/xform.rs b/compiler/rustc_hir_analysis/src/variance/xform.rs deleted file mode 100644 index 2e9964788e6..00000000000 --- a/compiler/rustc_hir_analysis/src/variance/xform.rs +++ /dev/null @@ -1,22 +0,0 @@ -use rustc_middle::ty; - -pub(crate) fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance { - // Greatest lower bound of the variance lattice as - // defined in The Paper: - // - // * - // - + - // o - match (v1, v2) { - (ty::Invariant, _) | (_, ty::Invariant) => ty::Invariant, - - (ty::Covariant, ty::Contravariant) => ty::Invariant, - (ty::Contravariant, ty::Covariant) => ty::Invariant, - - (ty::Covariant, ty::Covariant) => ty::Covariant, - - (ty::Contravariant, ty::Contravariant) => ty::Contravariant, - - (x, ty::Bivariant) | (ty::Bivariant, x) => x, - } -} diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 8e647ad3c6a..e84ae65f903 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1261,7 +1261,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn provided_kind( &mut self, - _preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 8e78fb3e219..fb5fc109ce4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1147,6 +1147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(self.param_env.and(trace.values)), e, true, + None, ); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index d432199f037..b77e6de52ff 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -31,12 +31,12 @@ use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt}; /// functions, closures, and `const`s, including performing type inference /// with [`InferCtxt`]. /// -/// This is in contrast to [`ItemCtxt`], which is used to type-check item *signatures* -/// and thus does not perform type inference. +/// This is in contrast to `rustc_hir_analysis::collect::ItemCtxt`, which is +/// used to type-check item *signatures* and thus does not perform type +/// inference. /// -/// See [`ItemCtxt`]'s docs for more. +/// See `ItemCtxt`'s docs for more. /// -/// [`ItemCtxt`]: rustc_hir_analysis::collect::ItemCtxt /// [`InferCtxt`]: infer::InferCtxt pub(crate) struct FnCtxt<'a, 'tcx> { pub(super) body_id: LocalDefId, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index aea2e0fd3a3..60f9265bfcc 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -12,8 +12,8 @@ use rustc_hir::{ GenericBound, HirId, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind, TyKind, WherePredicateKind, expr_needs_parens, }; -use rustc_hir_analysis::collect::suggest_impl_trait; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; +use rustc_hir_analysis::suggest_impl_trait; use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; use rustc_middle::span_bug; diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 880ee83c80a..5c1c38aeb95 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -413,7 +413,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn provided_kind( &mut self, - _preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 12e2bbc968f..ad15b764bcc 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -402,6 +402,18 @@ impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> { } } +impl<'tcx> ToTrace<'tcx> for ty::ExistentialTraitRef<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { + TypeTrace { + cause: cause.clone(), + values: ValuePairs::ExistentialTraitRef(ExpectedFound::new( + ty::Binder::dummy(a), + ty::Binder::dummy(b), + )), + } + } +} + impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { @@ -410,3 +422,15 @@ impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> { } } } + +impl<'tcx> ToTrace<'tcx> for ty::ExistentialProjection<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { + TypeTrace { + cause: cause.clone(), + values: ValuePairs::ExistentialProjection(ExpectedFound::new( + ty::Binder::dummy(a), + ty::Binder::dummy(b), + )), + } + } +} diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 241bc35857a..0b91c023cfc 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -26,7 +26,6 @@ use rustc_parse::{ }; use rustc_passes::{abi_test, input_stats, layout_test}; use rustc_resolve::Resolver; -use rustc_session::code_stats::VTableSizeInfo; use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; use rustc_session::cstore::Untracked; use rustc_session::output::{collect_crate_types, filename_for_input, find_crate_name}; @@ -989,90 +988,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { // we will fail to emit overlap diagnostics. Thus we invoke it here unconditionally. let _ = tcx.all_diagnostic_items(()); }); - - if sess.opts.unstable_opts.print_vtable_sizes { - let traits = tcx.traits(LOCAL_CRATE); - - for &tr in traits { - if !tcx.is_dyn_compatible(tr) { - continue; - } - - let name = ty::print::with_no_trimmed_paths!(tcx.def_path_str(tr)); - - let mut first_dsa = true; - - // Number of vtable entries, if we didn't have upcasting - let mut entries_ignoring_upcasting = 0; - // Number of vtable entries needed solely for upcasting - let mut entries_for_upcasting = 0; - - let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, tr)); - - // A slightly edited version of the code in - // `rustc_trait_selection::traits::vtable::vtable_entries`, that works without self - // type and just counts number of entries. - // - // Note that this is technically wrong, for traits which have associated types in - // supertraits: - // - // trait A: AsRef<Self::T> + AsRef<()> { type T; } - // - // Without self type we can't normalize `Self::T`, so we can't know if `AsRef<Self::T>` - // and `AsRef<()>` are the same trait, thus we assume that those are different, and - // potentially over-estimate how many vtable entries there are. - // - // Similarly this is wrong for traits that have methods with possibly-impossible bounds. - // For example: - // - // trait B<T> { fn f(&self) where T: Copy; } - // - // Here `dyn B<u8>` will have 4 entries, while `dyn B<String>` will only have 3. - // However, since we don't know `T`, we can't know if `T: Copy` holds or not, - // thus we lean on the bigger side and say it has 4 entries. - traits::vtable::prepare_vtable_segments(tcx, trait_ref, |segment| { - match segment { - traits::vtable::VtblSegment::MetadataDSA => { - // If this is the first dsa, it would be included either way, - // otherwise it's needed for upcasting - if std::mem::take(&mut first_dsa) { - entries_ignoring_upcasting += 3; - } else { - entries_for_upcasting += 3; - } - } - - traits::vtable::VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { - // Lookup the shape of vtable for the trait. - let own_existential_entries = - tcx.own_existential_vtable_entries(trait_ref.def_id()); - - // The original code here ignores the method if its predicates are - // impossible. We can't really do that as, for example, all not trivial - // bounds on generic parameters are impossible (since we don't know the - // parameters...), see the comment above. - entries_ignoring_upcasting += own_existential_entries.len(); - - if emit_vptr { - entries_for_upcasting += 1; - } - } - } - - std::ops::ControlFlow::Continue::<std::convert::Infallible>(()) - }); - - sess.code_stats.record_vtable_size(tr, &name, VTableSizeInfo { - trait_name: name.clone(), - entries: entries_ignoring_upcasting + entries_for_upcasting, - entries_ignoring_upcasting, - entries_for_upcasting, - upcasting_cost_percent: entries_for_upcasting as f64 - / entries_ignoring_upcasting as f64 - * 100., - }) - } - } } /// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used @@ -1153,12 +1068,6 @@ pub(crate) fn start_codegen<'tcx>( tcx.sess.code_stats.print_type_sizes(); } - if tcx.sess.opts.unstable_opts.print_vtable_sizes { - let crate_name = tcx.crate_name(LOCAL_CRATE); - - tcx.sess.code_stats.print_vtable_sizes(crate_name); - } - codegen } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 9495030f124..fb69dd54811 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -8,12 +8,12 @@ use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, registry}; use rustc_session::config::{ - BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, - DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, - FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, - LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig, - OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, - PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, + AutoDiff, BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel, + CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, + Externs, FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, + InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, + NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, + Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options, rustc_optgroups, }; @@ -760,6 +760,7 @@ fn test_unstable_options_tracking_hash() { tracked!(allow_features, Some(vec![String::from("lang_items")])); tracked!(always_encode_mir, true); tracked!(assume_incomplete_release, true); + tracked!(autodiff, vec![AutoDiff::Print]); tracked!(binary_dep_depinfo, true); tracked!(box_noalias, false); tracked!( diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index 9fde35f82d8..35db8632625 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -37,7 +37,7 @@ declare_lint_pass!(MultipleSupertraitUpcastable => [MULTIPLE_SUPERTRAIT_UPCASTAB impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { let def_id = item.owner_id.to_def_id(); - // NOTE(nbdd0121): use `object_safety_violations` instead of `is_dyn_compatible` because + // NOTE(nbdd0121): use `dyn_compatibility_violations` instead of `is_dyn_compatible` because // the latter will report `where_clause_object_safety` lint. if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind && cx.tcx.is_dyn_compatible(def_id) diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 35186778671..7ff316ba83a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -319,7 +319,11 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) { case LLVMRustAttributeKind::NoAlias: return Attribute::NoAlias; case LLVMRustAttributeKind::NoCapture: +#if LLVM_VERSION_GE(21, 0) + report_fatal_error("NoCapture doesn't exist in LLVM 21"); +#else return Attribute::NoCapture; +#endif case LLVMRustAttributeKind::NoCfCheck: return Attribute::NoCfCheck; case LLVMRustAttributeKind::NoInline: @@ -431,6 +435,12 @@ extern "C" void LLVMRustEraseInstFromParent(LLVMValueRef Instr) { extern "C" LLVMAttributeRef LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttributeKind RustAttr) { +#if LLVM_VERSION_GE(21, 0) + // LLVM 21 replaced the NoCapture attribute with Captures(none). + if (RustAttr == LLVMRustAttributeKind::NoCapture) { + return wrap(Attribute::getWithCaptureInfo(*unwrap(C), CaptureInfo::none())); + } +#endif return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr))); } @@ -667,8 +677,6 @@ extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints, unwrap<FunctionType>(Ty), StringRef(Constraints, ConstraintsLen))); } -typedef DIBuilder *LLVMRustDIBuilderRef; - template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) { return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr); } @@ -677,12 +685,6 @@ template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) { #define DIArray DINodeArray #define unwrapDI unwrapDIPtr -// FIXME(Zalathar): This is a temporary typedef to avoid churning dozens of -// bindings that are going to be deleted and replaced with their LLVM-C -// equivalents, as part of #134009. After that happens, the remaining bindings -// can be adjusted to use `LLVMDIFlags` instead of relying on this typedef. -typedef LLVMDIFlags LLVMRustDIFlags; - // Statically assert that `LLVMDIFlags` (C) and `DIFlags` (C++) have the same // layout, at least for the flags we know about. This isn't guaranteed, but is // likely to remain true, and as long as it is true it makes conversions easy. @@ -955,7 +957,8 @@ extern "C" LLVMValueRef LLVMRustGetLastInstruction(LLVMBasicBlockRef BB) { return nullptr; } -extern "C" void LLVMRustEraseInstBefore(LLVMBasicBlockRef bb, LLVMValueRef I) { +extern "C" void LLVMRustEraseInstUntilInclusive(LLVMBasicBlockRef bb, + LLVMValueRef I) { auto &BB = *unwrap(bb); auto &Inst = *unwrap<Instruction>(I); auto It = BB.begin(); @@ -963,8 +966,6 @@ extern "C" void LLVMRustEraseInstBefore(LLVMBasicBlockRef bb, LLVMValueRef I) { ++It; // Make sure we found the Instruction. assert(It != BB.end()); - // We don't want to erase the instruction itself. - It--; // Delete in rev order to ensure no dangling references. while (It != BB.begin()) { auto Prev = std::prev(It); @@ -994,34 +995,34 @@ extern "C" void LLVMRustGlobalAddMetadata(LLVMValueRef Global, unsigned Kind, unwrap<GlobalObject>(Global)->addMetadata(Kind, *unwrap<MDNode>(MD)); } -extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) { - return new DIBuilder(*unwrap(M)); +extern "C" LLVMDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) { + return wrap(new DIBuilder(*unwrap(M))); } -extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) { - delete Builder; +extern "C" void LLVMRustDIBuilderDispose(LLVMDIBuilderRef Builder) { + delete unwrap(Builder); } -extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) { - Builder->finalize(); +extern "C" void LLVMRustDIBuilderFinalize(LLVMDIBuilderRef Builder) { + unwrap(Builder)->finalize(); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit( - LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef, + LLVMDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen, bool isOptimized, const char *Flags, unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen, LLVMRustDebugEmissionKind Kind, uint64_t DWOId, bool SplitDebugInlining, LLVMRustDebugNameTableKind TableKind) { auto *File = unwrapDI<DIFile>(FileRef); - return wrap(Builder->createCompileUnit( + return wrap(unwrap(Builder)->createCompileUnit( Lang, File, StringRef(Producer, ProducerLen), isOptimized, Flags, RuntimeVer, StringRef(SplitName, SplitNameLen), fromRust(Kind), DWOId, SplitDebugInlining, false, fromRust(TableKind))); } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename, +LLVMRustDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename, size_t FilenameLen, const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind, const char *Checksum, size_t ChecksumLen, @@ -1034,29 +1035,29 @@ LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename, std::optional<StringRef> oSource{}; if (Source) oSource = StringRef(Source, SourceLen); - return wrap(Builder->createFile(StringRef(Filename, FilenameLen), - StringRef(Directory, DirectoryLen), CSInfo, - oSource)); + return wrap(unwrap(Builder)->createFile(StringRef(Filename, FilenameLen), + StringRef(Directory, DirectoryLen), + CSInfo, oSource)); } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder, +LLVMRustDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder, LLVMMetadataRef ParameterTypes) { - return wrap(Builder->createSubroutineType( + return wrap(unwrap(Builder)->createSubroutineType( DITypeRefArray(unwrap<MDTuple>(ParameterTypes)))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, - unsigned ScopeLine, LLVMRustDIFlags Flags, LLVMRustDISPFlags SPFlags, + unsigned ScopeLine, LLVMDIFlags Flags, LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam, LLVMMetadataRef Decl) { DITemplateParameterArray TParams = DITemplateParameterArray(unwrap<MDTuple>(TParam)); DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags); DINode::DIFlags llvmFlags = fromRust(Flags); - DISubprogram *Sub = Builder->createFunction( + DISubprogram *Sub = unwrap(Builder)->createFunction( unwrapDI<DIScope>(Scope), StringRef(Name, NameLen), StringRef(LinkageName, LinkageNameLen), unwrapDI<DIFile>(File), LineNo, unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags, llvmSPFlags, @@ -1067,15 +1068,15 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, - LLVMRustDIFlags Flags, LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) { + LLVMDIFlags Flags, LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) { DITemplateParameterArray TParams = DITemplateParameterArray(unwrap<MDTuple>(TParam)); DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags); DINode::DIFlags llvmFlags = fromRust(Flags); - DISubprogram *Sub = Builder->createMethod( + DISubprogram *Sub = unwrap(Builder)->createMethod( unwrapDI<DIScope>(Scope), StringRef(Name, NameLen), StringRef(LinkageName, LinkageNameLen), unwrapDI<DIFile>(File), LineNo, unwrapDI<DISubroutineType>(Ty), 0, 0, @@ -1085,39 +1086,39 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod( } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name, +LLVMRustDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name, size_t NameLen, uint64_t SizeInBits, unsigned Encoding) { - return wrap( - Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding)); + return wrap(unwrap(Builder)->createBasicType(StringRef(Name, NameLen), + SizeInBits, Encoding)); } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateTypedef(LLVMRustDIBuilderRef Builder, - LLVMMetadataRef Type, const char *Name, - size_t NameLen, LLVMMetadataRef File, - unsigned LineNo, LLVMMetadataRef Scope) { - return wrap(Builder->createTypedef( +LLVMRustDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type, + const char *Name, size_t NameLen, + LLVMMetadataRef File, unsigned LineNo, + LLVMMetadataRef Scope) { + return wrap(unwrap(Builder)->createTypedef( unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File), LineNo, unwrapDIPtr<DIScope>(Scope))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace, - const char *Name, size_t NameLen) { - return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy), - SizeInBits, AlignInBits, AddressSpace, - StringRef(Name, NameLen))); + LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy, uint64_t SizeInBits, + uint32_t AlignInBits, unsigned AddressSpace, const char *Name, + size_t NameLen) { + return wrap(unwrap(Builder)->createPointerType( + unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, AddressSpace, + StringRef(Name, NameLen))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, - uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags, + uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements, unsigned RunTimeLang, LLVMMetadataRef VTableHolder, const char *UniqueId, size_t UniqueIdLen) { - return wrap(Builder->createStructType( + return wrap(unwrap(Builder)->createStructType( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom), @@ -1126,12 +1127,12 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType( } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, - uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags, + uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef Discriminator, LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) { - return wrap(Builder->createVariantPart( + return wrap(unwrap(Builder)->createVariantPart( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator), @@ -1140,36 +1141,36 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart( } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags, + uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags, LLVMMetadataRef Ty) { - return wrap(Builder->createMemberType( + return wrap(unwrap(Builder)->createMemberType( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File), LineNo, SizeInBits, AlignInBits, OffsetInBits, fromRust(Flags), unwrapDI<DIType>(Ty))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant, - LLVMRustDIFlags Flags, LLVMMetadataRef Ty) { + LLVMDIFlags Flags, LLVMMetadataRef Ty) { llvm::ConstantInt *D = nullptr; if (Discriminant) { D = unwrap<llvm::ConstantInt>(Discriminant); } - return wrap(Builder->createVariantMemberType( + return wrap(unwrap(Builder)->createVariantMemberType( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File), LineNo, SizeInBits, AlignInBits, OffsetInBits, D, fromRust(Flags), unwrapDI<DIType>(Ty))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, - LLVMRustDIFlags Flags, LLVMValueRef val, uint32_t AlignInBits) { - return wrap(Builder->createStaticMemberType( + LLVMDIFlags Flags, LLVMValueRef val, uint32_t AlignInBits) { + return wrap(unwrap(Builder)->createStaticMemberType( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), fromRust(Flags), unwrap<llvm::ConstantInt>(val), llvm::dwarf::DW_TAG_member, AlignInBits)); @@ -1183,21 +1184,21 @@ LLVMRustDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag, } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateLexicalBlock(LLVMRustDIBuilderRef Builder, +LLVMRustDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line, unsigned Col) { - return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope), - unwrapDI<DIFile>(File), Line, Col)); + return wrap(unwrap(Builder)->createLexicalBlock( + unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Line, Col)); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlockFile( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File) { - return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope), - unwrapDI<DIFile>(File))); + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File) { + return wrap(unwrap(Builder)->createLexicalBlockFile( + unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V, LLVMMetadataRef Decl = nullptr, @@ -1206,16 +1207,16 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( llvm::DIExpression *InitExpr = nullptr; if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) { - InitExpr = Builder->createConstantValueExpression( + InitExpr = unwrap(Builder)->createConstantValueExpression( IntVal->getValue().getSExtValue()); } else if (llvm::ConstantFP *FPVal = llvm::dyn_cast<llvm::ConstantFP>(InitVal)) { - InitExpr = Builder->createConstantValueExpression( + InitExpr = unwrap(Builder)->createConstantValueExpression( FPVal->getValueAPF().bitcastToAPInt().getZExtValue()); } llvm::DIGlobalVariableExpression *VarExpr = - Builder->createGlobalVariableExpression( + unwrap(Builder)->createGlobalVariableExpression( unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen), StringRef(LinkageName, LinkageNameLen), unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit, @@ -1228,17 +1229,17 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable( - LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope, + LLVMDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, - LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags, - unsigned ArgNo, uint32_t AlignInBits) { + LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMDIFlags Flags, unsigned ArgNo, + uint32_t AlignInBits) { if (Tag == 0x100) { // DW_TAG_auto_variable - return wrap(Builder->createAutoVariable( + return wrap(unwrap(Builder)->createAutoVariable( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits)); } else { - return wrap(Builder->createParameterVariable( + return wrap(unwrap(Builder)->createParameterVariable( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo, unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags))); @@ -1246,53 +1247,56 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable( } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size, +LLVMRustDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size, uint32_t AlignInBits, LLVMMetadataRef Ty, LLVMMetadataRef Subscripts) { - return wrap( - Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty), - DINodeArray(unwrapDI<MDTuple>(Subscripts)))); + return wrap(unwrap(Builder)->createArrayType( + Size, AlignInBits, unwrapDI<DIType>(Ty), + DINodeArray(unwrapDI<MDTuple>(Subscripts)))); } extern "C" LLVMMetadataRef -LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo, +LLVMRustDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Builder, int64_t Lo, int64_t Count) { - return wrap(Builder->getOrCreateSubrange(Lo, Count)); + return wrap(unwrap(Builder)->getOrCreateSubrange(Lo, Count)); } extern "C" LLVMMetadataRef -LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder, +LLVMRustDIBuilderGetOrCreateArray(LLVMDIBuilderRef Builder, LLVMMetadataRef *Ptr, unsigned Count) { Metadata **DataValue = unwrap(Ptr); - return wrap( - Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get()); + return wrap(unwrap(Builder) + ->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)) + .get()); } -extern "C" void LLVMRustDIBuilderInsertDeclareAtEnd( - LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo, - uint64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL, - LLVMBasicBlockRef InsertAtEnd) { - Builder->insertDeclare(unwrap(V), unwrap<DILocalVariable>(VarInfo), - Builder->createExpression( - llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)), - DebugLoc(cast<MDNode>(unwrap(DL))), - unwrap(InsertAtEnd)); +extern "C" void +LLVMRustDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Builder, LLVMValueRef V, + LLVMMetadataRef VarInfo, uint64_t *AddrOps, + unsigned AddrOpsCount, LLVMMetadataRef DL, + LLVMBasicBlockRef InsertAtEnd) { + unwrap(Builder)->insertDeclare( + unwrap(V), unwrap<DILocalVariable>(VarInfo), + unwrap(Builder)->createExpression( + llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)), + DebugLoc(cast<MDNode>(unwrap(DL))), unwrap(InsertAtEnd)); } -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator( - LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen, - const uint64_t Value[2], unsigned SizeInBits, bool IsUnsigned) { - return wrap(Builder->createEnumerator( +extern "C" LLVMMetadataRef +LLVMRustDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder, const char *Name, + size_t NameLen, const uint64_t Value[2], + unsigned SizeInBits, bool IsUnsigned) { + return wrap(unwrap(Builder)->createEnumerator( StringRef(Name, NameLen), APSInt(APInt(SizeInBits, ArrayRef<uint64_t>(Value, 2)), IsUnsigned))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef Elements, LLVMMetadataRef ClassTy, bool IsScoped) { - return wrap(Builder->createEnumerationType( + return wrap(unwrap(Builder)->createEnumerationType( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)), unwrapDI<DIType>(ClassTy), @@ -1300,12 +1304,12 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, - uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags, + uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef Elements, unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) { - return wrap(Builder->createUnionType( + return wrap(unwrap(Builder)->createUnionType( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits, fromRust(Flags), DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang, @@ -1313,28 +1317,28 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType( } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef Ty) { bool IsDefault = false; // FIXME: should we ever set this true? - return wrap(Builder->createTemplateTypeParameter( + return wrap(unwrap(Builder)->createTemplateTypeParameter( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault)); } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder, +LLVMRustDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, bool ExportSymbols) { - return wrap(Builder->createNameSpace( + return wrap(unwrap(Builder)->createNameSpace( unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols)); } extern "C" void LLVMRustDICompositeTypeReplaceArrays( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef CompositeTy, + LLVMDIBuilderRef Builder, LLVMMetadataRef CompositeTy, LLVMMetadataRef Elements, LLVMMetadataRef Params) { DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy); - Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)), - DINodeArray(unwrap<MDTuple>(Params))); + unwrap(Builder)->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)), + DINodeArray(unwrap<MDTuple>(Params))); } extern "C" LLVMMetadataRef diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 904409dd777..43372154b2c 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -9,6 +9,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; use rustc_data_structures::sync::{Lrc, join, par_for_each_in}; use rustc_data_structures::temp_dir::MaybeTempDir; +use rustc_data_structures::thousands::format_with_underscores; use rustc_feature::Features; use rustc_hir as hir; use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE, LocalDefId, LocalDefIdSet}; @@ -22,7 +23,6 @@ use rustc_middle::traits::specialization_graph; use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::fast_reject::{self, TreatParams}; use rustc_middle::ty::{AssocItemContainer, SymbolName}; -use rustc_middle::util::common::to_readable_str; use rustc_middle::{bug, span_bug}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque}; use rustc_session::config::{CrateType, OptLevel}; @@ -782,7 +782,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { "{} {:<23}{:>10} ({:4.1}%)", prefix, label, - to_readable_str(size), + format_with_underscores(size), perc(size) ); } @@ -791,7 +791,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { "{} {:<23}{:>10} (of which {:.1}% are zero bytes)", prefix, "Total", - to_readable_str(total_bytes), + format_with_underscores(total_bytes), perc(zero_bytes) ); eprintln!("{prefix}"); diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index 8dc529b4d7a..ded1c580572 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -17,6 +17,9 @@ middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further itera middle_assert_misaligned_ptr_deref = misaligned pointer dereference: address must be a multiple of {$required} but is {$found} +middle_assert_null_ptr_deref = + null pointer dereference occurred + middle_assert_op_overflow = attempt to compute `{$left} {$op} {$right}`, which would overflow @@ -32,6 +35,8 @@ middle_assert_shl_overflow = middle_assert_shr_overflow = attempt to shift right by `{$val}`, which would overflow +middle_autodiff_unsafe_inner_const_ref = reading from a `Duplicated` const {$ty} is unsafe + middle_bounds_check = index out of bounds: the length is {$len} but the index is {$index} @@ -107,6 +112,8 @@ middle_type_length_limit = reached the type-length limit while instantiating `{$ middle_unknown_layout = the type `{$ty}` has an unknown layout +middle_unsupported_union = we don't support unions yet: '{$ty_name}' + middle_values_too_big = values of the type `{$ty}` are too big for the target architecture diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 750531b638e..eaccd8c360e 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -87,6 +87,7 @@ macro_rules! arena_types { [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<'tcx>, [decode] attribute: rustc_hir::Attribute, [] name_set: rustc_data_structures::unord::UnordSet<rustc_span::Symbol>, + [] autodiff_item: rustc_ast::expand::autodiff_attrs::AutoDiffItem, [] ordered_name_set: rustc_data_structures::fx::FxIndexSet<rustc_span::Symbol>, [] pats: rustc_middle::ty::PatternKind<'tcx>, diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index b0187a1848c..b30d3a950c6 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -37,6 +37,20 @@ pub struct OpaqueHiddenTypeMismatch<'tcx> { pub sub: TypeMismatchReason, } +#[derive(Diagnostic)] +#[diag(middle_unsupported_union)] +pub struct UnsupportedUnion { + pub ty_name: String, +} + +#[derive(Diagnostic)] +#[diag(middle_autodiff_unsafe_inner_const_ref)] +pub struct AutodiffUnsafeInnerConstRef { + #[primary_span] + pub span: Span, + pub ty: String, +} + #[derive(Subdiagnostic)] pub enum TypeMismatchReason { #[label(middle_conflict_types)] diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index 92fa64b0987..2be242364c1 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -1,7 +1,7 @@ -//! "Hooks" provide a way for `tcx` functionality to be provided by some downstream crate without -//! everything in rustc having to depend on that crate. This is somewhat similar to queries, but -//! queries come with a lot of machinery for caching and incremental compilation, whereas hooks are -//! just plain function pointers without any of the query magic. +//! "Hooks" let you write `tcx` methods in downstream crates and call them in this crate, reducing +//! the amount of code that needs to be in this crate (which is already very big). This is somewhat +//! similar to queries, but queries come with a lot of machinery for caching and incremental +//! compilation, whereas hooks are just plain function pointers without any of the query magic. use rustc_hir::def_id::{DefId, DefPathHash}; use rustc_session::StableCrateId; @@ -75,12 +75,6 @@ declare_hooks! { /// (Eligible functions might nevertheless be skipped for other reasons.) hook is_eligible_for_coverage(key: LocalDefId) -> bool; - /// Create the MIR for a given `DefId` - this includes - /// unreachable code. - /// You do not want to call this yourself, instead use the cached version - /// via `mir_built` - hook build_mir(key: LocalDefId) -> mir::Body<'tcx>; - /// Imports all `SourceFile`s from the given crate into the current session. /// This normally happens automatically when we decode a `Span` from /// that crate's metadata - however, the incr comp cache needs @@ -99,14 +93,11 @@ declare_hooks! { /// Will fetch a DefId from a DefPathHash for a foreign crate. hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId; - /// Create a THIR tree for debugging. - hook thir_tree(key: LocalDefId) -> String; - - /// Create a list-like THIR representation for debugging. - hook thir_flat(key: LocalDefId) -> String; - /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we /// can just link to the upstream crate and therefore don't need a mono item. + /// + /// Note: this hook isn't called within `rustc_middle` but #127779 suggests it's a hook instead + /// of a normal function because external tools might want to override it. hook should_codegen_locally(instance: crate::ty::Instance<'tcx>) -> bool; hook alloc_self_profile_query_strings() -> (); diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 39816c17b98..b3064d8fe25 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -4,8 +4,8 @@ /// /// If you have a span available, you should use [`span_bug`] instead. /// -/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxtHandle::span_delayed_bug`] -/// may be useful. +/// If the bug should only be emitted when compilation didn't fail, +/// [`DiagCtxtHandle::span_delayed_bug`] may be useful. /// /// [`DiagCtxtHandle::span_delayed_bug`]: rustc_errors::DiagCtxtHandle::span_delayed_bug /// [`span_bug`]: crate::span_bug @@ -14,14 +14,8 @@ macro_rules! bug { () => ( $crate::bug!("impossible case reached") ); - ($msg:expr) => ( - $crate::util::bug::bug_fmt(::std::format_args!($msg)) - ); - ($msg:expr,) => ( - $crate::bug!($msg) - ); - ($fmt:expr, $($arg:tt)+) => ( - $crate::util::bug::bug_fmt(::std::format_args!($fmt, $($arg)+)) + ($($arg:tt)+) => ( + $crate::util::bug::bug_fmt(::std::format_args!($($arg)+)) ); } @@ -30,20 +24,14 @@ macro_rules! bug { /// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger /// ICEs. /// -/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxtHandle::span_delayed_bug`] -/// may be useful. +/// If the bug should only be emitted when compilation didn't fail, +/// [`DiagCtxtHandle::span_delayed_bug`] may be useful. /// /// [`DiagCtxtHandle::span_delayed_bug`]: rustc_errors::DiagCtxtHandle::span_delayed_bug #[macro_export] macro_rules! span_bug { - ($span:expr, $msg:expr) => ( - $crate::util::bug::span_bug_fmt($span, ::std::format_args!($msg)) - ); - ($span:expr, $msg:expr,) => ( - $crate::span_bug!($span, $msg) - ); - ($span:expr, $fmt:expr, $($arg:tt)+) => ( - $crate::util::bug::span_bug_fmt($span, ::std::format_args!($fmt, $($arg)+)) + ($span:expr, $($arg:tt)+) => ( + $crate::util::bug::span_bug_fmt($span, ::std::format_args!($($arg)+)) ); } @@ -53,7 +41,6 @@ macro_rules! span_bug { // When possible, use one of these (relatively) convenient macros to write // the impls for you. -#[macro_export] macro_rules! TrivialLiftImpls { ($($ty:ty),+ $(,)?) => { $( @@ -69,7 +56,6 @@ macro_rules! TrivialLiftImpls { /// Used for types that are `Copy` and which **do not care about arena /// allocated data** (i.e., don't need to be folded). -#[macro_export] macro_rules! TrivialTypeTraversalImpls { ($($ty:ty),+ $(,)?) => { $( @@ -104,7 +90,6 @@ macro_rules! TrivialTypeTraversalImpls { }; } -#[macro_export] macro_rules! TrivialTypeTraversalAndLiftImpls { ($($t:tt)*) => { TrivialTypeTraversalImpls! { $($t)* } diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index cc980f6e62a..1784665bcae 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -1,4 +1,5 @@ use rustc_abi::Align; +use rustc_ast::expand::autodiff_attrs::AutoDiffAttrs; use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::Symbol; @@ -52,6 +53,8 @@ pub struct CodegenFnAttrs { /// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around /// the function entry. pub patchable_function_entry: Option<PatchableFunctionEntry>, + /// For the `#[autodiff]` macros. + pub autodiff_item: Option<AutoDiffAttrs>, } #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] @@ -160,6 +163,7 @@ impl CodegenFnAttrs { instruction_set: None, alignment: None, patchable_function_entry: None, + autodiff_item: None, } } diff --git a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs index 111ac990bc7..51a079e8bc1 100644 --- a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs +++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs @@ -45,15 +45,22 @@ pub enum ObjectLifetimeDefault { Param(DefId), } -/// Maps the id of each lifetime reference to the lifetime decl +/// Maps the id of each bound variable reference to the variable decl /// that it corresponds to. -#[derive(HashStable, Debug)] +#[derive(Debug, Default, HashStable)] pub struct ResolveBoundVars { - /// Maps from every use of a named (not anonymous) lifetime to a - /// `Region` describing how that region is bound + // Maps from every use of a named (not anonymous) bound var to a + // `ResolvedArg` describing how that variable is bound. pub defs: SortedMap<ItemLocalId, ResolvedArg>, + // Maps relevant hir items to the bound vars on them. These include: + // - function defs + // - function pointers + // - closures + // - trait refs + // - bound types (like `T` in `for<'a> T<'a>: Foo`) pub late_bound_vars: SortedMap<ItemLocalId, Vec<ty::BoundVariableKind>>, + // List captured variables for each opaque type. pub opaque_captured_lifetimes: LocalDefIdMap<Vec<(ResolvedArg, LocalDefId)>>, } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 0f3fca434ee..cfb78e5dddf 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -27,7 +27,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisit use rustc_serialize::{Decodable, Encodable}; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span, Symbol}; -use tracing::trace; +use tracing::{debug, trace}; pub use self::query::*; use self::visit::TyContext; @@ -1796,6 +1796,47 @@ impl DefLocation { } } +/// Checks if the specified `local` is used as the `self` parameter of a method call +/// in the provided `BasicBlock`. If it is, then the `DefId` of the called method is +/// returned. +pub fn find_self_call<'tcx>( + tcx: TyCtxt<'tcx>, + body: &Body<'tcx>, + local: Local, + block: BasicBlock, +) -> Option<(DefId, GenericArgsRef<'tcx>)> { + debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator); + if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) = + &body[block].terminator + && let Operand::Constant(box ConstOperand { const_, .. }) = func + && let ty::FnDef(def_id, fn_args) = *const_.ty().kind() + && let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) = + tcx.opt_associated_item(def_id) + && let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] = + **args + { + if self_place.as_local() == Some(local) { + return Some((def_id, fn_args)); + } + + // Handle the case where `self_place` gets reborrowed. + // This happens when the receiver is `&T`. + for stmt in &body[block].statements { + if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind + && let Some(reborrow_local) = place.as_local() + && self_place.as_local() == Some(reborrow_local) + && let Rvalue::Ref(_, _, deref_place) = rvalue + && let PlaceRef { local: deref_local, projection: [ProjectionElem::Deref] } = + deref_place.as_ref() + && deref_local == local + { + return Some((def_id, fn_args)); + } + } + } + None +} + // Some nodes are used a lot. Make sure they don't unintentionally get bigger. #[cfg(target_pointer_width = "64")] mod size_asserts { diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 6fa3fa2432d..e49fc376a13 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -1,6 +1,7 @@ use std::fmt; use std::hash::Hash; +use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_attr_parsing::InlineAttr; use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fingerprint::Fingerprint; @@ -246,6 +247,7 @@ impl ToStableHashKey<StableHashingContext<'_>> for MonoItem<'_> { pub struct MonoItemPartitions<'tcx> { pub codegen_units: &'tcx [CodegenUnit<'tcx>], pub all_mono_items: &'tcx DefIdSet, + pub autodiff_items: &'tcx [AutoDiffItem], } #[derive(Debug, HashStable)] diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 5868b64f6b5..90a2f175bc9 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1076,6 +1076,7 @@ pub enum AssertKind<O> { ResumedAfterReturn(CoroutineKind), ResumedAfterPanic(CoroutineKind), MisalignedPointerDereference { required: O, found: O }, + NullPointerDereference, } #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index c04a8251fbc..2fe116212eb 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -206,6 +206,7 @@ impl<O> AssertKind<O> { ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { LangItem::PanicGenFnNonePanic } + NullPointerDereference => LangItem::PanicNullPointerDereference, BoundsCheck { .. } | MisalignedPointerDereference { .. } => { bug!("Unexpected AssertKind") @@ -271,6 +272,7 @@ impl<O> AssertKind<O> { "\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\", {required:?}, {found:?}" ) } + NullPointerDereference => write!(f, "\"null pointer dereference occured\""), ResumedAfterReturn(CoroutineKind::Coroutine(_)) => { write!(f, "\"coroutine resumed after completion\"") } @@ -341,7 +343,7 @@ impl<O> AssertKind<O> { ResumedAfterPanic(CoroutineKind::Coroutine(_)) => { middle_assert_coroutine_resume_after_panic } - + NullPointerDereference => middle_assert_null_ptr_deref, MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref, } } @@ -374,7 +376,7 @@ impl<O> AssertKind<O> { add!("left", format!("{left:#?}")); add!("right", format!("{right:#?}")); } - ResumedAfterReturn(_) | ResumedAfterPanic(_) => {} + ResumedAfterReturn(_) | ResumedAfterPanic(_) | NullPointerDereference => {} MisalignedPointerDereference { required, found } => { add!("required", format!("{required:#?}")); add!("found", format!("{found:#?}")); diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 95de08ce9c8..6319a7e65b9 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -636,7 +636,7 @@ macro_rules! make_mir_visitor { OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => { self.visit_operand(op, location); } - ResumedAfterReturn(_) | ResumedAfterPanic(_) => { + ResumedAfterReturn(_) | ResumedAfterPanic(_) | NullPointerDereference => { // Nothing to visit } MisalignedPointerDereference { required, found } => { diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index f7090fa69e2..949d8303385 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -95,7 +95,7 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> { } } -impl<'tcx> Key for (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>) { +impl<'tcx> Key for (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>) { type Cache<V> = DefaultCache<Self, V>; fn default_span(&self, _: TyCtxt<'_>) -> Span { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 560e3bf3ade..41e9858030c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1437,9 +1437,9 @@ rustc_queries! { desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key) } } - query vtable_entries(key: ty::PolyTraitRef<'tcx>) + query vtable_entries(key: ty::TraitRef<'tcx>) -> &'tcx [ty::VtblEntry<'tcx>] { - desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id()) } + desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id) } } query first_method_vtable_slot(key: ty::TraitRef<'tcx>) -> usize { @@ -1451,7 +1451,7 @@ rustc_queries! { key.1, key.0 } } - query vtable_allocation(key: (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId { + query vtable_allocation(key: (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId { desc { |tcx| "vtable const allocation for <{} as {}>", key.0, key.1.map(|trait_ref| format!("{trait_ref}")).unwrap_or("_".to_owned()) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 8a9110f842a..28a6eba75aa 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -428,7 +428,7 @@ pub enum IsConstable { Ctor, } -crate::TrivialTypeTraversalAndLiftImpls! { +TrivialTypeTraversalAndLiftImpls! { IsConstable, } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index b212992bd2d..3ced64b5b80 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -858,7 +858,12 @@ where } let mk_dyn_vtable = |principal: Option<ty::PolyExistentialTraitRef<'tcx>>| { - let min_count = ty::vtable_min_entries(tcx, principal); + let min_count = ty::vtable_min_entries( + tcx, + principal.map(|principal| { + tcx.instantiate_bound_regions_with_erased(principal) + }), + ); Ty::new_imm_ref( tcx, tcx.lifetimes.re_static, diff --git a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs index cbc02097d82..568e504b940 100644 --- a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs +++ b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs @@ -4,7 +4,7 @@ use crate::ty::{self, ExistentialPredicateStableCmpExt, TyCtxt}; impl<'tcx> TyCtxt<'tcx> { /// Given a `def_id` of a trait or impl method, compute whether that method needs to - /// have an RPITIT shim applied to it for it to be object safe. If so, return the + /// have an RPITIT shim applied to it for it to be dyn compatible. If so, return the /// `def_id` of the RPITIT, and also the args of trait method that returns the RPITIT. /// /// NOTE that these args are not, in general, the same as than the RPITIT's args. They diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index 455bd16ff8c..6c9e0e7c0eb 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -7,7 +7,7 @@ use rustc_type_ir::elaborate; use crate::mir::interpret::{ AllocId, AllocInit, Allocation, CTFE_ALLOC_SALT, Pointer, Scalar, alloc_range, }; -use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt}; +use crate::ty::{self, Instance, TraitRef, Ty, TyCtxt}; #[derive(Clone, Copy, PartialEq, HashStable)] pub enum VtblEntry<'tcx> { @@ -22,7 +22,7 @@ pub enum VtblEntry<'tcx> { /// dispatchable associated function Method(Instance<'tcx>), /// pointer to a separate supertrait vtable, can be used by trait upcasting coercion - TraitVPtr(PolyTraitRef<'tcx>), + TraitVPtr(TraitRef<'tcx>), } impl<'tcx> fmt::Debug for VtblEntry<'tcx> { @@ -59,7 +59,7 @@ pub const COMMON_VTABLE_ENTRIES_ALIGN: usize = 2; // function is an accurate approximation. We verify this when actually computing the vtable below. pub(crate) fn vtable_min_entries<'tcx>( tcx: TyCtxt<'tcx>, - trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, + trait_ref: Option<ty::ExistentialTraitRef<'tcx>>, ) -> usize { let mut count = TyCtxt::COMMON_VTABLE_ENTRIES.len(); let Some(trait_ref) = trait_ref else { @@ -67,7 +67,7 @@ pub(crate) fn vtable_min_entries<'tcx>( }; // This includes self in supertraits. - for def_id in elaborate::supertrait_def_ids(tcx, trait_ref.def_id()) { + for def_id in elaborate::supertrait_def_ids(tcx, trait_ref.def_id) { count += tcx.own_existential_vtable_entries(def_id).len(); } @@ -83,7 +83,7 @@ pub(crate) fn vtable_min_entries<'tcx>( /// initial contents.) pub(super) fn vtable_allocation_provider<'tcx>( tcx: TyCtxt<'tcx>, - key: (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), + key: (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), ) -> AllocId { let (ty, poly_trait_ref) = key; @@ -118,7 +118,7 @@ pub(super) fn vtable_allocation_provider<'tcx>( for (idx, entry) in vtable_entries.iter().enumerate() { let idx: u64 = u64::try_from(idx).unwrap(); - let scalar = match entry { + let scalar = match *entry { VtblEntry::MetadataDropInPlace => { if ty.needs_drop(tcx, ty::TypingEnv::fully_monomorphized()) { let instance = ty::Instance::resolve_drop_in_place(tcx, ty); @@ -134,13 +134,12 @@ pub(super) fn vtable_allocation_provider<'tcx>( VtblEntry::Vacant => continue, VtblEntry::Method(instance) => { // Prepare the fn ptr we write into the vtable. - let fn_alloc_id = tcx.reserve_and_set_fn_alloc(*instance, CTFE_ALLOC_SALT); + let fn_alloc_id = tcx.reserve_and_set_fn_alloc(instance, CTFE_ALLOC_SALT); let fn_ptr = Pointer::from(fn_alloc_id); Scalar::from_pointer(fn_ptr, &tcx) } VtblEntry::TraitVPtr(trait_ref) => { - let super_trait_ref = trait_ref - .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + let super_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref); let supertrait_alloc_id = tcx.vtable_allocation((ty, Some(super_trait_ref))); let vptr = Pointer::from(supertrait_alloc_id); Scalar::from_pointer(vptr, &tcx) diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index b99336c2c85..7dda68b8393 100644 --- a/compiler/rustc_middle/src/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs @@ -1,4 +1,4 @@ -// These functions are used by macro expansion for bug! and span_bug! +// These functions are used by macro expansion for `bug!` and `span_bug!`. use std::fmt; use std::panic::{Location, panic_any}; @@ -8,15 +8,15 @@ use rustc_span::Span; use crate::ty::{TyCtxt, tls}; +// This wrapper makes for more compact code at callsites than calling `opt_span_buf_fmt` directly. #[cold] #[inline(never)] #[track_caller] pub fn bug_fmt(args: fmt::Arguments<'_>) -> ! { - // this wrapper mostly exists so I don't have to write a fully - // qualified path of None::<Span> inside the bug!() macro definition opt_span_bug_fmt(None::<Span>, args, Location::caller()); } +// This wrapper makes for more compact code at callsites than calling `opt_span_buf_fmt` directly. #[cold] #[inline(never)] #[track_caller] diff --git a/compiler/rustc_middle/src/util/common.rs b/compiler/rustc_middle/src/util/common.rs deleted file mode 100644 index 223b2b3bfe4..00000000000 --- a/compiler/rustc_middle/src/util/common.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[cfg(test)] -mod tests; - -pub fn to_readable_str(mut val: usize) -> String { - let mut groups = vec![]; - loop { - let group = val % 1000; - - val /= 1000; - - if val == 0 { - groups.push(group.to_string()); - break; - } else { - groups.push(format!("{group:03}")); - } - } - - groups.reverse(); - - groups.join("_") -} diff --git a/compiler/rustc_middle/src/util/common/tests.rs b/compiler/rustc_middle/src/util/common/tests.rs deleted file mode 100644 index 9a9fb203c62..00000000000 --- a/compiler/rustc_middle/src/util/common/tests.rs +++ /dev/null @@ -1,14 +0,0 @@ -use super::*; - -#[test] -fn test_to_readable_str() { - assert_eq!("0", to_readable_str(0)); - assert_eq!("1", to_readable_str(1)); - assert_eq!("99", to_readable_str(99)); - assert_eq!("999", to_readable_str(999)); - assert_eq!("1_000", to_readable_str(1_000)); - assert_eq!("1_001", to_readable_str(1_001)); - assert_eq!("999_999", to_readable_str(999_999)); - assert_eq!("1_000_000", to_readable_str(1_000_000)); - assert_eq!("1_234_567", to_readable_str(1_234_567)); -} diff --git a/compiler/rustc_middle/src/util/find_self_call.rs b/compiler/rustc_middle/src/util/find_self_call.rs deleted file mode 100644 index 0fdd3520738..00000000000 --- a/compiler/rustc_middle/src/util/find_self_call.rs +++ /dev/null @@ -1,47 +0,0 @@ -use rustc_span::def_id::DefId; -use rustc_span::source_map::Spanned; -use tracing::debug; - -use crate::mir::*; -use crate::ty::{self, GenericArgsRef, TyCtxt}; - -/// Checks if the specified `local` is used as the `self` parameter of a method call -/// in the provided `BasicBlock`. If it is, then the `DefId` of the called method is -/// returned. -pub fn find_self_call<'tcx>( - tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, - local: Local, - block: BasicBlock, -) -> Option<(DefId, GenericArgsRef<'tcx>)> { - debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator); - if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) = - &body[block].terminator - && let Operand::Constant(box ConstOperand { const_, .. }) = func - && let ty::FnDef(def_id, fn_args) = *const_.ty().kind() - && let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) = - tcx.opt_associated_item(def_id) - && let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] = - **args - { - if self_place.as_local() == Some(local) { - return Some((def_id, fn_args)); - } - - // Handle the case where `self_place` gets reborrowed. - // This happens when the receiver is `&T`. - for stmt in &body[block].statements { - if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind - && let Some(reborrow_local) = place.as_local() - && self_place.as_local() == Some(reborrow_local) - && let Rvalue::Ref(_, _, deref_place) = rvalue - && let PlaceRef { local: deref_local, projection: [ProjectionElem::Deref] } = - deref_place.as_ref() - && deref_local == local - { - return Some((def_id, fn_args)); - } - } - } - None -} diff --git a/compiler/rustc_middle/src/util/mod.rs b/compiler/rustc_middle/src/util/mod.rs index 097a868191c..8c875007b7f 100644 --- a/compiler/rustc_middle/src/util/mod.rs +++ b/compiler/rustc_middle/src/util/mod.rs @@ -1,8 +1,4 @@ pub mod bug; -pub mod common; -pub mod find_self_call; - -pub use find_self_call::find_self_call; #[derive(Default, Copy, Clone)] pub struct Providers { diff --git a/compiler/rustc_mir_build/src/builder/custom/mod.rs b/compiler/rustc_mir_build/src/builder/custom/mod.rs index ca2e1dd7a1a..bfc16816e2e 100644 --- a/compiler/rustc_mir_build/src/builder/custom/mod.rs +++ b/compiler/rustc_mir_build/src/builder/custom/mod.rs @@ -6,7 +6,7 @@ //! present, and if so we branch off into this module, which implements the attribute by //! implementing a custom lowering from THIR to MIR. //! -//! The result of this lowering is returned "normally" from the `build_mir` hook, with the only +//! The result of this lowering is returned "normally" from `build_mir`, with the only //! notable difference being that the `injected` field in the body is set. Various components of the //! MIR pipeline, like borrowck and the pass manager will then consult this field (via //! `body.should_skip()`) to skip the parts of the MIR pipeline that precede the MIR phase the user diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 9fa431f7d5f..93fb9873e80 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -20,7 +20,6 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::middle::region; use rustc_middle::mir::*; -use rustc_middle::query::TyCtxtAt; use rustc_middle::thir::{self, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt, TypeVisitableExt, TypingMode}; use rustc_middle::{bug, span_bug}; @@ -45,9 +44,9 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( .collect() } -/// Construct the MIR for a given `DefId`. -pub(crate) fn build_mir<'tcx>(tcx: TyCtxtAt<'tcx>, def: LocalDefId) -> Body<'tcx> { - let tcx = tcx.tcx; +/// Create the MIR for a given `DefId`, including unreachable code. Do not call +/// this directly; instead use the cached version via `mir_built`. +pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> { tcx.ensure_with_value().thir_abstract_const(def); if let Err(e) = tcx.check_match(def) { return construct_error(tcx, def, e); diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 8e786733ee0..fa5db32d913 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -14,11 +14,11 @@ // The `builder` module used to be named `build`, but that was causing GitHub's // "Go to file" feature to silently ignore all files in the module, probably // because it assumes that "build" is a build-output directory. See #134365. -mod builder; +pub mod builder; mod check_tail_calls; mod check_unsafety; mod errors; -mod thir; +pub mod thir; use rustc_middle::util::Providers; @@ -27,12 +27,9 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" } pub fn provide(providers: &mut Providers) { providers.check_match = thir::pattern::check_match; providers.lit_to_const = thir::constant::lit_to_const; - providers.hooks.build_mir = builder::build_mir; providers.closure_saved_names_of_captured_variables = builder::closure_saved_names_of_captured_variables; providers.check_unsafety = check_unsafety::check_unsafety; providers.check_tail_calls = check_tail_calls::check_tail_calls; providers.thir_body = thir::cx::thir_body; - providers.hooks.thir_tree = thir::print::thir_tree; - providers.hooks.thir_flat = thir::print::thir_flat; } diff --git a/compiler/rustc_mir_build/src/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs index ca26cc13b5e..c7c88801d4d 100644 --- a/compiler/rustc_mir_build/src/thir/mod.rs +++ b/compiler/rustc_mir_build/src/thir/mod.rs @@ -7,5 +7,5 @@ pub(crate) mod constant; pub(crate) mod cx; pub(crate) mod pattern; -pub(crate) mod print; +pub mod print; mod util; diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 2bcdb67c58a..228a64c2c70 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -1,12 +1,13 @@ use std::fmt::{self, Write}; -use rustc_middle::query::TyCtxtAt; use rustc_middle::thir::*; use rustc_middle::ty; +use rustc_middle::ty::TyCtxt; use rustc_span::def_id::LocalDefId; -pub(crate) fn thir_tree(tcx: TyCtxtAt<'_>, owner_def: LocalDefId) -> String { - match super::cx::thir_body(*tcx, owner_def) { +/// Create a THIR tree for debugging. +pub fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { + match super::cx::thir_body(tcx, owner_def) { Ok((thir, _)) => { let thir = thir.steal(); let mut printer = ThirPrinter::new(&thir); @@ -17,8 +18,9 @@ pub(crate) fn thir_tree(tcx: TyCtxtAt<'_>, owner_def: LocalDefId) -> String { } } -pub(crate) fn thir_flat(tcx: TyCtxtAt<'_>, owner_def: LocalDefId) -> String { - match super::cx::thir_body(*tcx, owner_def) { +/// Create a list-like THIR representation for debugging. +pub fn thir_flat(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { + match super::cx::thir_body(tcx, owner_def) { Ok((thir, _)) => format!("{:#?}", thir.steal()), Err(_) => "error".into(), } diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index d7e22c12394..ca5564e447a 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -1,11 +1,10 @@ -use rustc_hir::lang_items::LangItem; use rustc_index::IndexVec; use rustc_middle::mir::interpret::Scalar; -use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{Ty, TyCtxt}; use rustc_session::Session; -use tracing::{debug, trace}; + +use crate::check_pointers::{BorrowCheckMode, PointerCheck, check_pointers}; pub(super) struct CheckAlignment; @@ -19,46 +18,19 @@ impl<'tcx> crate::MirPass<'tcx> for CheckAlignment { } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - // This pass emits new panics. If for whatever reason we do not have a panic - // implementation, running this pass may cause otherwise-valid code to not compile. - if tcx.lang_items().get(LangItem::PanicImpl).is_none() { - return; - } - - let typing_env = body.typing_env(tcx); - let basic_blocks = body.basic_blocks.as_mut(); - let local_decls = &mut body.local_decls; - - // This pass inserts new blocks. Each insertion changes the Location for all - // statements/blocks after. Iterating or visiting the MIR in order would require updating - // our current location after every insertion. By iterating backwards, we dodge this issue: - // The only Locations that an insertion changes have already been handled. - for block in (0..basic_blocks.len()).rev() { - let block = block.into(); - for statement_index in (0..basic_blocks[block].statements.len()).rev() { - let location = Location { block, statement_index }; - let statement = &basic_blocks[block].statements[statement_index]; - let source_info = statement.source_info; - - let mut finder = - PointerFinder { tcx, local_decls, typing_env, pointers: Vec::new() }; - finder.visit_statement(statement, location); - - for (local, ty) in finder.pointers { - debug!("Inserting alignment check for {:?}", ty); - let new_block = split_block(basic_blocks, location); - insert_alignment_check( - tcx, - local_decls, - &mut basic_blocks[block], - local, - ty, - source_info, - new_block, - ); - } - } - } + // Skip trivially aligned place types. + let excluded_pointees = [tcx.types.bool, tcx.types.i8, tcx.types.u8]; + + // We have to exclude borrows here: in `&x.field`, the exact + // requirement is that the final reference must be aligned, but + // `check_pointers` would check that `x` is aligned, which would be wrong. + check_pointers( + tcx, + body, + &excluded_pointees, + insert_alignment_check, + BorrowCheckMode::ExcludeBorrows, + ); } fn is_required(&self) -> bool { @@ -66,119 +38,33 @@ impl<'tcx> crate::MirPass<'tcx> for CheckAlignment { } } -struct PointerFinder<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - local_decls: &'a mut LocalDecls<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - pointers: Vec<(Place<'tcx>, Ty<'tcx>)>, -} - -impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> { - fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { - // We want to only check reads and writes to Places, so we specifically exclude - // Borrow and RawBorrow. - match context { - PlaceContext::MutatingUse( - MutatingUseContext::Store - | MutatingUseContext::AsmOutput - | MutatingUseContext::Call - | MutatingUseContext::Yield - | MutatingUseContext::Drop, - ) => {} - PlaceContext::NonMutatingUse( - NonMutatingUseContext::Copy | NonMutatingUseContext::Move, - ) => {} - _ => { - return; - } - } - - if !place.is_indirect() { - return; - } - - // Since Deref projections must come first and only once, the pointer for an indirect place - // is the Local that the Place is based on. - let pointer = Place::from(place.local); - let pointer_ty = self.local_decls[place.local].ty; - - // We only want to check places based on unsafe pointers - if !pointer_ty.is_unsafe_ptr() { - trace!("Indirect, but not based on an unsafe ptr, not checking {:?}", place); - return; - } - - let pointee_ty = - pointer_ty.builtin_deref(true).expect("no builtin_deref for an unsafe pointer"); - // Ideally we'd support this in the future, but for now we are limited to sized types. - if !pointee_ty.is_sized(self.tcx, self.typing_env) { - debug!("Unsafe pointer, but pointee is not known to be sized: {:?}", pointer_ty); - return; - } - - // Try to detect types we are sure have an alignment of 1 and skip the check - // We don't need to look for str and slices, we already rejected unsized types above - let element_ty = match pointee_ty.kind() { - ty::Array(ty, _) => *ty, - _ => pointee_ty, - }; - if [self.tcx.types.bool, self.tcx.types.i8, self.tcx.types.u8].contains(&element_ty) { - debug!("Trivially aligned place type: {:?}", pointee_ty); - return; - } - - // Ensure that this place is based on an aligned pointer. - self.pointers.push((pointer, pointee_ty)); - - self.super_place(place, context, location); - } -} - -fn split_block( - basic_blocks: &mut IndexVec<BasicBlock, BasicBlockData<'_>>, - location: Location, -) -> BasicBlock { - let block_data = &mut basic_blocks[location.block]; - - // Drain every statement after this one and move the current terminator to a new basic block - let new_block = BasicBlockData { - statements: block_data.statements.split_off(location.statement_index), - terminator: block_data.terminator.take(), - is_cleanup: block_data.is_cleanup, - }; - - basic_blocks.push(new_block) -} - +/// Inserts the actual alignment check's logic. Returns a +/// [AssertKind::MisalignedPointerDereference] on failure. fn insert_alignment_check<'tcx>( tcx: TyCtxt<'tcx>, - local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>, - block_data: &mut BasicBlockData<'tcx>, pointer: Place<'tcx>, pointee_ty: Ty<'tcx>, + local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>, + stmts: &mut Vec<Statement<'tcx>>, source_info: SourceInfo, - new_block: BasicBlock, -) { - // Cast the pointer to a *const () +) -> PointerCheck<'tcx> { + // Cast the pointer to a *const (). let const_raw_ptr = Ty::new_imm_ptr(tcx, tcx.types.unit); let rvalue = Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(pointer), const_raw_ptr); let thin_ptr = local_decls.push(LocalDecl::with_source_info(const_raw_ptr, source_info)).into(); - block_data - .statements + stmts .push(Statement { source_info, kind: StatementKind::Assign(Box::new((thin_ptr, rvalue))) }); - // Transmute the pointer to a usize (equivalent to `ptr.addr()`) + // Transmute the pointer to a usize (equivalent to `ptr.addr()`). let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Copy(thin_ptr), tcx.types.usize); let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); - block_data - .statements - .push(Statement { source_info, kind: StatementKind::Assign(Box::new((addr, rvalue))) }); + stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new((addr, rvalue))) }); // Get the alignment of the pointee let alignment = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); let rvalue = Rvalue::NullaryOp(NullOp::AlignOf, pointee_ty); - block_data.statements.push(Statement { + stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new((alignment, rvalue))), }); @@ -191,7 +77,7 @@ fn insert_alignment_check<'tcx>( user_ty: None, const_: Const::Val(ConstValue::Scalar(Scalar::from_target_usize(1, &tcx)), tcx.types.usize), })); - block_data.statements.push(Statement { + stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new(( alignment_mask, @@ -202,7 +88,7 @@ fn insert_alignment_check<'tcx>( // BitAnd the alignment mask with the pointer let alignment_bits = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); - block_data.statements.push(Statement { + stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new(( alignment_bits, @@ -220,7 +106,7 @@ fn insert_alignment_check<'tcx>( user_ty: None, const_: Const::Val(ConstValue::Scalar(Scalar::from_target_usize(0, &tcx)), tcx.types.usize), })); - block_data.statements.push(Statement { + stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new(( is_ok, @@ -228,21 +114,13 @@ fn insert_alignment_check<'tcx>( ))), }); - // Set this block's terminator to our assert, continuing to new_block if we pass - block_data.terminator = Some(Terminator { - source_info, - kind: TerminatorKind::Assert { - cond: Operand::Copy(is_ok), - expected: true, - target: new_block, - msg: Box::new(AssertKind::MisalignedPointerDereference { - required: Operand::Copy(alignment), - found: Operand::Copy(addr), - }), - // This calls panic_misaligned_pointer_dereference, which is #[rustc_nounwind]. - // We never want to insert an unwind into unsafe code, because unwinding could - // make a failing UB check turn into much worse UB when we start unwinding. - unwind: UnwindAction::Unreachable, - }, - }); + // Emit a check that asserts on the alignment and otherwise triggers a + // AssertKind::MisalignedPointerDereference. + PointerCheck { + cond: Operand::Copy(is_ok), + assert_kind: Box::new(AssertKind::MisalignedPointerDereference { + required: Operand::Copy(alignment), + found: Operand::Copy(addr), + }), + } } diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index 7968b666dff..3affe4abbfa 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -133,7 +133,7 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { // the `self` parameter of a method call (as the terminator of our current // BasicBlock). If so, we emit a more specific lint. let method_did = self.target_local.and_then(|target_local| { - rustc_middle::util::find_self_call(self.tcx, self.body, target_local, loc.block) + find_self_call(self.tcx, self.body, target_local, loc.block) }); let lint_loc = if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc }; diff --git a/compiler/rustc_mir_transform/src/check_null.rs b/compiler/rustc_mir_transform/src/check_null.rs new file mode 100644 index 00000000000..0b6c0ceaac1 --- /dev/null +++ b/compiler/rustc_mir_transform/src/check_null.rs @@ -0,0 +1,110 @@ +use rustc_index::IndexVec; +use rustc_middle::mir::interpret::Scalar; +use rustc_middle::mir::*; +use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_session::Session; + +use crate::check_pointers::{BorrowCheckMode, PointerCheck, check_pointers}; + +pub(super) struct CheckNull; + +impl<'tcx> crate::MirPass<'tcx> for CheckNull { + fn is_enabled(&self, sess: &Session) -> bool { + sess.ub_checks() + } + + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + check_pointers(tcx, body, &[], insert_null_check, BorrowCheckMode::IncludeBorrows); + } + + fn is_required(&self) -> bool { + true + } +} + +fn insert_null_check<'tcx>( + tcx: TyCtxt<'tcx>, + pointer: Place<'tcx>, + pointee_ty: Ty<'tcx>, + local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>, + stmts: &mut Vec<Statement<'tcx>>, + source_info: SourceInfo, +) -> PointerCheck<'tcx> { + // Cast the pointer to a *const (). + let const_raw_ptr = Ty::new_imm_ptr(tcx, tcx.types.unit); + let rvalue = Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(pointer), const_raw_ptr); + let thin_ptr = local_decls.push(LocalDecl::with_source_info(const_raw_ptr, source_info)).into(); + stmts + .push(Statement { source_info, kind: StatementKind::Assign(Box::new((thin_ptr, rvalue))) }); + + // Transmute the pointer to a usize (equivalent to `ptr.addr()`). + let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Copy(thin_ptr), tcx.types.usize); + let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); + stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new((addr, rvalue))) }); + + // Get size of the pointee (zero-sized reads and writes are allowed). + let rvalue = Rvalue::NullaryOp(NullOp::SizeOf, pointee_ty); + let sizeof_pointee = + local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); + stmts.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new((sizeof_pointee, rvalue))), + }); + + // Check that the pointee is not a ZST. + let zero = Operand::Constant(Box::new(ConstOperand { + span: source_info.span, + user_ty: None, + const_: Const::Val(ConstValue::Scalar(Scalar::from_target_usize(0, &tcx)), tcx.types.usize), + })); + let is_pointee_no_zst = + local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); + stmts.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + is_pointee_no_zst, + Rvalue::BinaryOp(BinOp::Ne, Box::new((Operand::Copy(sizeof_pointee), zero.clone()))), + ))), + }); + + // Check whether the pointer is null. + let is_null = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); + stmts.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + is_null, + Rvalue::BinaryOp(BinOp::Eq, Box::new((Operand::Copy(addr), zero))), + ))), + }); + + // We want to throw an exception if the pointer is null and doesn't point to a ZST. + let should_throw_exception = + local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); + stmts.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + should_throw_exception, + Rvalue::BinaryOp( + BinOp::BitAnd, + Box::new((Operand::Copy(is_null), Operand::Copy(is_pointee_no_zst))), + ), + ))), + }); + + // The final condition whether this pointer usage is ok or not. + let is_ok = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); + stmts.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + is_ok, + Rvalue::UnaryOp(UnOp::Not, Operand::Copy(should_throw_exception)), + ))), + }); + + // Emit a PointerCheck that asserts on the condition and otherwise triggers + // a AssertKind::NullPointerDereference. + PointerCheck { + cond: Operand::Copy(is_ok), + assert_kind: Box::new(AssertKind::NullPointerDereference), + } +} diff --git a/compiler/rustc_mir_transform/src/check_pointers.rs b/compiler/rustc_mir_transform/src/check_pointers.rs new file mode 100644 index 00000000000..72460542f87 --- /dev/null +++ b/compiler/rustc_mir_transform/src/check_pointers.rs @@ -0,0 +1,234 @@ +use rustc_hir::lang_items::LangItem; +use rustc_index::IndexVec; +use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; +use rustc_middle::mir::*; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use tracing::{debug, trace}; + +/// Details of a pointer check, the condition on which we decide whether to +/// fail the assert and an [AssertKind] that defines the behavior on failure. +pub(crate) struct PointerCheck<'tcx> { + pub(crate) cond: Operand<'tcx>, + pub(crate) assert_kind: Box<AssertKind<Operand<'tcx>>>, +} + +/// Indicates whether we insert the checks for borrow places of a raw pointer. +/// Concretely places with [MutatingUseContext::Borrow] or +/// [NonMutatingUseContext::SharedBorrow]. +#[derive(Copy, Clone)] +pub(crate) enum BorrowCheckMode { + IncludeBorrows, + ExcludeBorrows, +} + +/// Utility for adding a check for read/write on every sized, raw pointer. +/// +/// Visits every read/write access to a [Sized], raw pointer and inserts a +/// new basic block directly before the pointer access. (Read/write accesses +/// are determined by the `PlaceContext` of the MIR visitor.) Then calls +/// `on_finding` to insert the actual logic for a pointer check (e.g. check for +/// alignment). A check can choose to be inserted for (mutable) borrows of +/// raw pointers via the `borrow_check_mode` parameter. +/// +/// This utility takes care of the right order of blocks, the only thing a +/// caller must do in `on_finding` is: +/// - Append [Statement]s to `stmts`. +/// - Append [LocalDecl]s to `local_decls`. +/// - Return a [PointerCheck] that contains the condition and an [AssertKind]. +/// The AssertKind must be a panic with `#[rustc_nounwind]`. The condition +/// should always return the boolean `is_ok`, so evaluate to true in case of +/// success and fail the check otherwise. +/// This utility will insert a terminator block that asserts on the condition +/// and panics on failure. +pub(crate) fn check_pointers<'a, 'tcx, F>( + tcx: TyCtxt<'tcx>, + body: &mut Body<'tcx>, + excluded_pointees: &'a [Ty<'tcx>], + on_finding: F, + borrow_check_mode: BorrowCheckMode, +) where + F: Fn( + /* tcx: */ TyCtxt<'tcx>, + /* pointer: */ Place<'tcx>, + /* pointee_ty: */ Ty<'tcx>, + /* local_decls: */ &mut IndexVec<Local, LocalDecl<'tcx>>, + /* stmts: */ &mut Vec<Statement<'tcx>>, + /* source_info: */ SourceInfo, + ) -> PointerCheck<'tcx>, +{ + // This pass emits new panics. If for whatever reason we do not have a panic + // implementation, running this pass may cause otherwise-valid code to not compile. + if tcx.lang_items().get(LangItem::PanicImpl).is_none() { + return; + } + + let typing_env = body.typing_env(tcx); + let basic_blocks = body.basic_blocks.as_mut(); + let local_decls = &mut body.local_decls; + + // This operation inserts new blocks. Each insertion changes the Location for all + // statements/blocks after. Iterating or visiting the MIR in order would require updating + // our current location after every insertion. By iterating backwards, we dodge this issue: + // The only Locations that an insertion changes have already been handled. + for block in (0..basic_blocks.len()).rev() { + let block = block.into(); + for statement_index in (0..basic_blocks[block].statements.len()).rev() { + let location = Location { block, statement_index }; + let statement = &basic_blocks[block].statements[statement_index]; + let source_info = statement.source_info; + + let mut finder = PointerFinder::new( + tcx, + local_decls, + typing_env, + excluded_pointees, + borrow_check_mode, + ); + finder.visit_statement(statement, location); + + for (local, ty) in finder.into_found_pointers() { + debug!("Inserting check for {:?}", ty); + let new_block = split_block(basic_blocks, location); + + // Invoke `on_finding` which appends to `local_decls` and the + // blocks statements. It returns information about the assert + // we're performing in the Terminator. + let block_data = &mut basic_blocks[block]; + let pointer_check = on_finding( + tcx, + local, + ty, + local_decls, + &mut block_data.statements, + source_info, + ); + block_data.terminator = Some(Terminator { + source_info, + kind: TerminatorKind::Assert { + cond: pointer_check.cond, + expected: true, + target: new_block, + msg: pointer_check.assert_kind, + // This calls a panic function associated with the pointer check, which + // is #[rustc_nounwind]. We never want to insert an unwind into unsafe + // code, because unwinding could make a failing UB check turn into much + // worse UB when we start unwinding. + unwind: UnwindAction::Unreachable, + }, + }); + } + } + } +} + +struct PointerFinder<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + local_decls: &'a mut LocalDecls<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + pointers: Vec<(Place<'tcx>, Ty<'tcx>)>, + excluded_pointees: &'a [Ty<'tcx>], + borrow_check_mode: BorrowCheckMode, +} + +impl<'a, 'tcx> PointerFinder<'a, 'tcx> { + fn new( + tcx: TyCtxt<'tcx>, + local_decls: &'a mut LocalDecls<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + excluded_pointees: &'a [Ty<'tcx>], + borrow_check_mode: BorrowCheckMode, + ) -> Self { + PointerFinder { + tcx, + local_decls, + typing_env, + excluded_pointees, + pointers: Vec::new(), + borrow_check_mode, + } + } + + fn into_found_pointers(self) -> Vec<(Place<'tcx>, Ty<'tcx>)> { + self.pointers + } + + /// Whether or not we should visit a [Place] with [PlaceContext]. + /// + /// We generally only visit Reads/Writes to a place and only Borrows if + /// requested. + fn should_visit_place(&self, context: PlaceContext) -> bool { + match context { + PlaceContext::MutatingUse( + MutatingUseContext::Store + | MutatingUseContext::Call + | MutatingUseContext::Yield + | MutatingUseContext::Drop, + ) => true, + PlaceContext::NonMutatingUse( + NonMutatingUseContext::Copy | NonMutatingUseContext::Move, + ) => true, + PlaceContext::MutatingUse(MutatingUseContext::Borrow) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) => { + matches!(self.borrow_check_mode, BorrowCheckMode::IncludeBorrows) + } + _ => false, + } + } +} + +impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> { + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { + if !self.should_visit_place(context) || !place.is_indirect() { + return; + } + + // Since Deref projections must come first and only once, the pointer for an indirect place + // is the Local that the Place is based on. + let pointer = Place::from(place.local); + let pointer_ty = self.local_decls[place.local].ty; + + // We only want to check places based on raw pointers + if !pointer_ty.is_unsafe_ptr() { + trace!("Indirect, but not based on an raw ptr, not checking {:?}", place); + return; + } + + let pointee_ty = + pointer_ty.builtin_deref(true).expect("no builtin_deref for an raw pointer"); + // Ideally we'd support this in the future, but for now we are limited to sized types. + if !pointee_ty.is_sized(self.tcx, self.typing_env) { + trace!("Raw pointer, but pointee is not known to be sized: {:?}", pointer_ty); + return; + } + + // We don't need to look for slices, we already rejected unsized types above. + let element_ty = match pointee_ty.kind() { + ty::Array(ty, _) => *ty, + _ => pointee_ty, + }; + if self.excluded_pointees.contains(&element_ty) { + trace!("Skipping pointer for type: {:?}", pointee_ty); + return; + } + + self.pointers.push((pointer, pointee_ty)); + + self.super_place(place, context, location); + } +} + +fn split_block( + basic_blocks: &mut IndexVec<BasicBlock, BasicBlockData<'_>>, + location: Location, +) -> BasicBlock { + let block_data = &mut basic_blocks[location.block]; + + // Drain every statement after this one and move the current terminator to a new basic block. + let new_block = BasicBlockData { + statements: block_data.statements.split_off(location.statement_index), + terminator: block_data.terminator.take(), + is_cleanup: block_data.is_cleanup, + }; + + basic_blocks.push(new_block) +} diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 2dc55e3614e..4af9a111bdf 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -33,6 +33,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_middle::util::Providers; use rustc_middle::{bug, query, span_bug}; +use rustc_mir_build::builder::build_mir; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, sym}; use tracing::debug; @@ -44,6 +45,7 @@ use std::sync::LazyLock; use pass_manager::{self as pm, Lint, MirLint, MirPass, WithMinOptLevel}; +mod check_pointers; mod cost_checker; mod cross_crate_inline; mod deduce_param_attrs; @@ -118,6 +120,7 @@ declare_passes! { mod check_call_recursion : CheckCallRecursion, CheckDropRecursion; mod check_alignment : CheckAlignment; mod check_const_item_mutation : CheckConstItemMutation; + mod check_null : CheckNull; mod check_packed_ref : CheckPackedRef; mod check_undefined_transmutes : CheckUndefinedTransmutes; // This pass is public to allow external drivers to perform MIR cleanup @@ -368,7 +371,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { } fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> { - let mut body = tcx.build_mir(def); + let mut body = build_mir(tcx, def); pass_manager::dump_mir_for_phase_change(tcx, &body); @@ -642,6 +645,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &[ // Add some UB checks before any UB gets optimized away. &check_alignment::CheckAlignment, + &check_null::CheckNull, // Before inlining: trim down MIR with passes to reduce inlining work. // Has to be done before inlining, otherwise actual call will be almost always inlined. diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 9bdaeb015cd..5462105e5e8 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } +rustc_ast = { path = "../rustc_ast" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } @@ -15,6 +16,7 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } +rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_target = { path = "../rustc_target" } serde = "1" serde_json = "1" diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index d53848f7461..246faed50e3 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -257,7 +257,7 @@ struct SharedState<'tcx> { pub(crate) struct UsageMap<'tcx> { // Maps every mono item to the mono items used by it. - used_map: UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>, + pub used_map: UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>, // Maps every mono item to the mono items that use it. user_map: UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>, @@ -814,6 +814,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { mir::AssertKind::MisalignedPointerDereference { .. } => { push_mono_lang_item(self, LangItem::PanicMisalignedPointerDereference); } + mir::AssertKind::NullPointerDereference => { + push_mono_lang_item(self, LangItem::PanicNullPointerDereference); + } _ => { push_mono_lang_item(self, msg.panic_function()); } @@ -1138,11 +1141,12 @@ fn create_mono_items_for_vtable_methods<'tcx>( bug!("create_mono_items_for_vtable_methods: {trait_ty:?} not a trait type"); }; if let Some(principal) = trait_ty.principal() { - let poly_trait_ref = principal.with_self_ty(tcx, impl_ty); - assert!(!poly_trait_ref.has_escaping_bound_vars()); + let trait_ref = + tcx.instantiate_bound_regions_with_erased(principal.with_self_ty(tcx, impl_ty)); + assert!(!trait_ref.has_escaping_bound_vars()); // Walk all methods of the trait, including those of its supertraits - let entries = tcx.vtable_entries(poly_trait_ref); + let entries = tcx.vtable_entries(trait_ref); debug!(?entries); let methods = entries .iter() @@ -1197,7 +1201,12 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt } } GlobalAlloc::VTable(ty, dyn_ty) => { - let alloc_id = tcx.vtable_allocation((ty, dyn_ty.principal())); + let alloc_id = tcx.vtable_allocation(( + ty, + dyn_ty + .principal() + .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)), + )); collect_alloc(tcx, alloc_id, output) } } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index e08c348a64d..c985ea04278 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -92,6 +92,8 @@ //! source-level module, functions from the same module will be available for //! inlining, even when they are not marked `#[inline]`. +mod autodiff; + use std::cmp; use std::collections::hash_map::Entry; use std::fs::{self, File}; @@ -251,7 +253,17 @@ where can_export_generics, always_export_generics, ); - if visibility == Visibility::Hidden && can_be_internalized { + + // We can't differentiate something that got inlined. + let autodiff_active = cfg!(llvm_enzyme) + && cx + .tcx + .codegen_fn_attrs(mono_item.def_id()) + .autodiff_item + .as_ref() + .is_some_and(|ad| ad.is_active()); + + if !autodiff_active && visibility == Visibility::Hidden && can_be_internalized { internalization_candidates.insert(mono_item); } let size_estimate = mono_item.size_estimate(cx.tcx); @@ -1176,6 +1188,18 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio }) .collect(); + let autodiff_mono_items: Vec<_> = items + .iter() + .filter_map(|item| match *item { + MonoItem::Fn(ref instance) => Some((item, instance)), + _ => None, + }) + .collect(); + + let autodiff_items = + autodiff::find_autodiff_source_functions(tcx, &usage_map, autodiff_mono_items); + let autodiff_items = tcx.arena.alloc_from_iter(autodiff_items); + // Output monomorphization stats per def_id if let SwitchWithOptPath::Enabled(ref path) = tcx.sess.opts.unstable_opts.dump_mono_stats { if let Err(err) = @@ -1236,7 +1260,11 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio } } - MonoItemPartitions { all_mono_items: tcx.arena.alloc(mono_items), codegen_units } + MonoItemPartitions { + all_mono_items: tcx.arena.alloc(mono_items), + codegen_units, + autodiff_items, + } } /// Outputs stats about instantiation counts and estimated size, per `MonoItem`'s diff --git a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs new file mode 100644 index 00000000000..bce31bf0748 --- /dev/null +++ b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs @@ -0,0 +1,121 @@ +use rustc_ast::expand::autodiff_attrs::{AutoDiffItem, DiffActivity}; +use rustc_hir::def_id::LOCAL_CRATE; +use rustc_middle::bug; +use rustc_middle::mir::mono::MonoItem; +use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; +use rustc_symbol_mangling::symbol_name_for_instance_in_crate; +use tracing::{debug, trace}; + +use crate::partitioning::UsageMap; + +fn adjust_activity_to_abi<'tcx>(tcx: TyCtxt<'tcx>, fn_ty: Ty<'tcx>, da: &mut Vec<DiffActivity>) { + if !matches!(fn_ty.kind(), ty::FnDef(..)) { + bug!("expected fn def for autodiff, got {:?}", fn_ty); + } + let fnc_binder: ty::Binder<'_, ty::FnSig<'_>> = fn_ty.fn_sig(tcx); + + // If rustc compiles the unmodified primal, we know that this copy of the function + // also has correct lifetimes. We know that Enzyme won't free the shadow too early + // (or actually at all), so let's strip lifetimes when computing the layout. + let x = tcx.instantiate_bound_regions_with_erased(fnc_binder); + let mut new_activities = vec![]; + let mut new_positions = vec![]; + for (i, ty) in x.inputs().iter().enumerate() { + if let Some(inner_ty) = ty.builtin_deref(true) { + if ty.is_fn_ptr() { + // FIXME(ZuseZ4): add a nicer error, or just figure out how to support them, + // since Enzyme itself can handle them. + tcx.dcx().err("function pointers are currently not supported in autodiff"); + } + if inner_ty.is_slice() { + // We know that the length will be passed as extra arg. + if !da.is_empty() { + // We are looking at a slice. The length of that slice will become an + // extra integer on llvm level. Integers are always const. + // However, if the slice get's duplicated, we want to know to later check the + // size. So we mark the new size argument as FakeActivitySize. + let activity = match da[i] { + DiffActivity::DualOnly + | DiffActivity::Dual + | DiffActivity::DuplicatedOnly + | DiffActivity::Duplicated => DiffActivity::FakeActivitySize, + DiffActivity::Const => DiffActivity::Const, + _ => bug!("unexpected activity for ptr/ref"), + }; + new_activities.push(activity); + new_positions.push(i + 1); + } + continue; + } + } + } + // now add the extra activities coming from slices + // Reverse order to not invalidate the indices + for _ in 0..new_activities.len() { + let pos = new_positions.pop().unwrap(); + let activity = new_activities.pop().unwrap(); + da.insert(pos, activity); + } +} + +pub(crate) fn find_autodiff_source_functions<'tcx>( + tcx: TyCtxt<'tcx>, + usage_map: &UsageMap<'tcx>, + autodiff_mono_items: Vec<(&MonoItem<'tcx>, &Instance<'tcx>)>, +) -> Vec<AutoDiffItem> { + let mut autodiff_items: Vec<AutoDiffItem> = vec![]; + for (item, instance) in autodiff_mono_items { + let target_id = instance.def_id(); + let cg_fn_attr = tcx.codegen_fn_attrs(target_id).autodiff_item.clone(); + let Some(target_attrs) = cg_fn_attr else { + continue; + }; + let mut input_activities: Vec<DiffActivity> = target_attrs.input_activity.clone(); + if target_attrs.is_source() { + trace!("source found: {:?}", target_id); + } + if !target_attrs.apply_autodiff() { + continue; + } + + let target_symbol = symbol_name_for_instance_in_crate(tcx, instance.clone(), LOCAL_CRATE); + + let source = + usage_map.used_map.get(&item).unwrap().into_iter().find_map(|item| match *item { + MonoItem::Fn(ref instance_s) => { + let source_id = instance_s.def_id(); + if let Some(ad) = &tcx.codegen_fn_attrs(source_id).autodiff_item + && ad.is_active() + { + return Some(instance_s); + } + None + } + _ => None, + }); + let inst = match source { + Some(source) => source, + None => continue, + }; + + debug!("source_id: {:?}", inst.def_id()); + let fn_ty = inst.ty(tcx, ty::TypingEnv::fully_monomorphized()); + assert!(fn_ty.is_fn()); + adjust_activity_to_abi(tcx, fn_ty, &mut input_activities); + let symb = symbol_name_for_instance_in_crate(tcx, inst.clone(), LOCAL_CRATE); + + let mut new_target_attrs = target_attrs.clone(); + new_target_attrs.input_activity = input_activities; + let itm = new_target_attrs.into_item(symb, target_symbol); + autodiff_items.push(itm); + } + + if !autodiff_items.is_empty() { + trace!("AUTODIFF ITEMS EXIST"); + for item in &mut *autodiff_items { + trace!("{}", &item); + } + } + + autodiff_items +} diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e19819a22b4..837da6e7724 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2471,6 +2471,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }))), terr, false, + None, ); diag.emit(); self.abort.set(true); diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 75b62a40ff9..6d9c70177a4 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -5,10 +5,10 @@ use rustc_ast::visit::BoundKind; use rustc_ast::{self as ast, NodeId, visit as ast_visit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::thousands::format_with_underscores; use rustc_hir::{self as hir, AmbigArg, HirId, intravisit as hir_visit}; use rustc_middle::hir::map::Map; use rustc_middle::ty::TyCtxt; -use rustc_middle::util::common::to_readable_str; use rustc_span::Span; use rustc_span::def_id::LocalDefId; @@ -144,10 +144,10 @@ impl<'k> StatCollector<'k> { "{} {:<18}{:>10} ({:4.1}%){:>14}{:>14}", prefix, label, - to_readable_str(size), + format_with_underscores(size), percent(size, total_size), - to_readable_str(node.stats.count), - to_readable_str(node.stats.size) + format_with_underscores(node.stats.count), + format_with_underscores(node.stats.size) ); if !node.subnodes.is_empty() { // We will soon sort, so the initial order does not matter. @@ -163,9 +163,9 @@ impl<'k> StatCollector<'k> { "{} - {:<18}{:>10} ({:4.1}%){:>14}", prefix, label, - to_readable_str(size), + format_with_underscores(size), percent(size, total_size), - to_readable_str(subnode.count), + format_with_underscores(subnode.count), ); } } @@ -175,8 +175,8 @@ impl<'k> StatCollector<'k> { "{} {:<18}{:>10} {:>14}", prefix, "Total", - to_readable_str(total_size), - to_readable_str(total_count), + format_with_underscores(total_size), + format_with_underscores(total_count), ); eprintln!("{prefix}"); } diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs index f3c21992784..b4597ae2515 100644 --- a/compiler/rustc_session/src/code_stats.rs +++ b/compiler/rustc_session/src/code_stats.rs @@ -1,10 +1,9 @@ use std::cmp; use rustc_abi::{Align, Size}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lock; use rustc_span::Symbol; -use rustc_span::def_id::DefId; #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct VariantInfo { @@ -71,29 +70,9 @@ pub struct TypeSizeInfo { pub variants: Vec<VariantInfo>, } -pub struct VTableSizeInfo { - pub trait_name: String, - - /// Number of entries in a vtable with the current algorithm - /// (i.e. with upcasting). - pub entries: usize, - - /// Number of entries in a vtable, as-if we did not have trait upcasting. - pub entries_ignoring_upcasting: usize, - - /// Number of entries in a vtable needed solely for upcasting - /// (i.e. `entries - entries_ignoring_upcasting`). - pub entries_for_upcasting: usize, - - /// Cost of having upcasting in % relative to the number of entries without - /// upcasting (i.e. `entries_for_upcasting / entries_ignoring_upcasting * 100%`). - pub upcasting_cost_percent: f64, -} - #[derive(Default)] pub struct CodeStats { type_sizes: Lock<FxHashSet<TypeSizeInfo>>, - vtable_sizes: Lock<FxHashMap<DefId, VTableSizeInfo>>, } impl CodeStats { @@ -127,14 +106,6 @@ impl CodeStats { self.type_sizes.borrow_mut().insert(info); } - pub fn record_vtable_size(&self, trait_did: DefId, trait_name: &str, info: VTableSizeInfo) { - let prev = self.vtable_sizes.lock().insert(trait_did, info); - assert!( - prev.is_none(), - "size of vtable for `{trait_name}` ({trait_did:?}) is already recorded" - ); - } - pub fn print_type_sizes(&self) { let type_sizes = self.type_sizes.borrow(); // We will soon sort, so the initial order does not matter. @@ -238,33 +209,4 @@ impl CodeStats { } } } - - pub fn print_vtable_sizes(&self, crate_name: Symbol) { - // We will soon sort, so the initial order does not matter. - #[allow(rustc::potential_query_instability)] - let mut infos = - std::mem::take(&mut *self.vtable_sizes.lock()).into_values().collect::<Vec<_>>(); - - // Primary sort: cost % in reverse order (from largest to smallest) - // Secondary sort: trait_name - infos.sort_by(|a, b| { - a.upcasting_cost_percent - .total_cmp(&b.upcasting_cost_percent) - .reverse() - .then_with(|| a.trait_name.cmp(&b.trait_name)) - }); - - for VTableSizeInfo { - trait_name, - entries, - entries_ignoring_upcasting, - entries_for_upcasting, - upcasting_cost_percent, - } in infos - { - println!( - r#"print-vtable-sizes {{ "crate_name": "{crate_name}", "trait_name": "{trait_name}", "entries": "{entries}", "entries_ignoring_upcasting": "{entries_ignoring_upcasting}", "entries_for_upcasting": "{entries_for_upcasting}", "upcasting_cost_percent": "{upcasting_cost_percent}" }}"# - ); - } - } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 97bd2670aa6..c8a811985d5 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -189,6 +189,39 @@ pub enum CoverageLevel { Mcdc, } +/// The different settings that the `-Z autodiff` flag can have. +#[derive(Clone, Copy, PartialEq, Hash, Debug)] +pub enum AutoDiff { + /// Print TypeAnalysis information + PrintTA, + /// Print ActivityAnalysis Information + PrintAA, + /// Print Performance Warnings from Enzyme + PrintPerf, + /// Combines the three print flags above. + Print, + /// Print the whole module, before running opts. + PrintModBefore, + /// Print the whole module just before we pass it to Enzyme. + /// For Debug purpose, prefer the OPT flag below + PrintModAfterOpts, + /// Print the module after Enzyme differentiated everything. + PrintModAfterEnzyme, + + /// Enzyme's loose type debug helper (can cause incorrect gradients) + LooseTypes, + + /// More flags + NoModOptAfter, + /// Tell Enzyme to run LLVM Opts on each function it generated. By default off, + /// since we already optimize the whole module after Enzyme is done. + EnableFncOpt, + NoVecUnroll, + RuntimeActivity, + /// Runs Enzyme specific Inlining + Inline, +} + /// Settings for `-Z instrument-xray` flag. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub struct InstrumentXRay { @@ -2902,7 +2935,7 @@ pub(crate) mod dep_tracking { }; use super::{ - BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions, + AutoDiff, BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, OomStrategy, OptLevel, OutFileName, @@ -2950,6 +2983,7 @@ pub(crate) mod dep_tracking { } impl_dep_tracking_hash_via_hash!( + AutoDiff, bool, usize, NonZero<usize>, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c7af40a8ad4..cc86c85f3f0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -398,6 +398,7 @@ mod desc { pub(crate) const parse_list: &str = "a space-separated list of strings"; pub(crate) const parse_list_with_polarity: &str = "a comma-separated list of strings, with elements beginning with + or -"; + pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Print`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfterOpts`, `PrintModAfterEnzyme`, `LooseTypes`, `NoModOptAfter`, `EnableFncOpt`, `NoVecUnroll`, `Inline`"; pub(crate) const parse_comma_list: &str = "a comma-separated list of strings"; pub(crate) const parse_opt_comma_list: &str = parse_comma_list; pub(crate) const parse_number: &str = "a number"; @@ -1029,6 +1030,38 @@ pub mod parse { } } + pub(crate) fn parse_autodiff(slot: &mut Vec<AutoDiff>, v: Option<&str>) -> bool { + let Some(v) = v else { + *slot = vec![]; + return true; + }; + let mut v: Vec<&str> = v.split(",").collect(); + v.sort_unstable(); + for &val in v.iter() { + let variant = match val { + "PrintTA" => AutoDiff::PrintTA, + "PrintAA" => AutoDiff::PrintAA, + "PrintPerf" => AutoDiff::PrintPerf, + "Print" => AutoDiff::Print, + "PrintModBefore" => AutoDiff::PrintModBefore, + "PrintModAfterOpts" => AutoDiff::PrintModAfterOpts, + "PrintModAfterEnzyme" => AutoDiff::PrintModAfterEnzyme, + "LooseTypes" => AutoDiff::LooseTypes, + "NoModOptAfter" => AutoDiff::NoModOptAfter, + "EnableFncOpt" => AutoDiff::EnableFncOpt, + "NoVecUnroll" => AutoDiff::NoVecUnroll, + "Inline" => AutoDiff::Inline, + _ => { + // FIXME(ZuseZ4): print an error saying which value is not recognized + return false; + } + }; + slot.push(variant); + } + + true + } + pub(crate) fn parse_instrument_coverage( slot: &mut InstrumentCoverage, v: Option<&str>, @@ -1736,6 +1769,22 @@ options! { either `loaded` or `not-loaded`."), assume_incomplete_release: bool = (false, parse_bool, [TRACKED], "make cfg(version) treat the current version as incomplete (default: no)"), + autodiff: Vec<crate::config::AutoDiff> = (Vec::new(), parse_autodiff, [TRACKED], + "a list of optional autodiff flags to enable + Optional extra settings: + `=PrintTA` + `=PrintAA` + `=PrintPerf` + `=Print` + `=PrintModBefore` + `=PrintModAfterOpts` + `=PrintModAfterEnzyme` + `=LooseTypes` + `=NoModOptAfter` + `=EnableFncOpt` + `=NoVecUnroll` + `=Inline` + Multiple options can be combined with commas."), #[rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field")] binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], "include artifacts (sysroot, crate dependencies) used during compilation in dep-info \ @@ -2034,8 +2083,6 @@ options! { Note that this overwrites the effect `-Clink-dead-code` has on collection!"), print_type_sizes: bool = (false, parse_bool, [UNTRACKED], "print layout information for each type encountered (default: no)"), - print_vtable_sizes: bool = (false, parse_bool, [UNTRACKED], - "print size comparison between old and new vtable layouts (default: no)"), proc_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], "show backtraces for panics during proc-macro execution (default: no)"), proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread, diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 8d4e55dc036..cdc56782a26 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -747,7 +747,9 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let alloc_id = tables.tcx.vtable_allocation(( ty.internal(&mut *tables, tcx), - trait_ref.internal(&mut *tables, tcx), + trait_ref + .internal(&mut *tables, tcx) + .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)), )); Some(alloc_id.stable(&mut *tables)) } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index aee98d7d410..150ec02b7db 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -496,6 +496,9 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { found: found.stable(tables), } } + AssertKind::NullPointerDereference => { + stable_mir::mir::AssertMessage::NullPointerDereference + } } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6f1d3a74a81..7f7b460cf57 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -502,7 +502,6 @@ symbols! { augmented_assignments, auto_traits, autodiff, - autodiff_fallback, automatically_derived, avx, avx512_target_feature, @@ -568,7 +567,6 @@ symbols! { cfg_accessible, cfg_attr, cfg_attr_multi, - cfg_autodiff_fallback, cfg_boolean_literals, cfg_doctest, cfg_emscripten_wasm_eh, @@ -1476,6 +1474,7 @@ symbols! { panic_location, panic_misaligned_pointer_dereference, panic_nounwind, + panic_null_pointer_dereference, panic_runtime, panic_str_2015, panic_unwind, diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 5c5ab435dbd..4312c82815c 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -151,7 +151,7 @@ fn symbol_name_provider<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty pub fn typeid_for_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyExistentialTraitRef<'tcx>, + trait_ref: ty::ExistentialTraitRef<'tcx>, ) -> String { v0::mangle_typeid_for_trait_ref(tcx, trait_ref) } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 5b3272feecd..7b040a8b2c4 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -72,7 +72,7 @@ pub(super) fn mangle<'tcx>( pub(super) fn mangle_typeid_for_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyExistentialTraitRef<'tcx>, + trait_ref: ty::ExistentialTraitRef<'tcx>, ) -> String { // FIXME(flip1995): See comment in `mangle_typeid_for_fnabi`. let mut cx = SymbolMangler { @@ -84,7 +84,7 @@ pub(super) fn mangle_typeid_for_trait_ref<'tcx>( binders: vec![], out: String::new(), }; - cx.print_def_path(trait_ref.def_id(), &[]).unwrap(); + cx.print_def_path(trait_ref.def_id, &[]).unwrap(); std::mem::take(&mut cx.out) } diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 1292f46f0c9..f17452b3ba0 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -934,6 +934,7 @@ pub enum InlineAsmClobberAbi { LoongArch, PowerPC, S390x, + Bpf, Msp430, } @@ -1003,6 +1004,10 @@ impl InlineAsmClobberAbi { "C" | "system" => Ok(InlineAsmClobberAbi::S390x), _ => Err(&["C", "system"]), }, + InlineAsmArch::Bpf => match name { + "C" | "system" => Ok(InlineAsmClobberAbi::Bpf), + _ => Err(&["C", "system"]), + }, InlineAsmArch::Msp430 => match name { "C" | "system" => Ok(InlineAsmClobberAbi::Msp430), _ => Err(&["C", "system"]), @@ -1278,6 +1283,14 @@ impl InlineAsmClobberAbi { a8, a9, a10, a11, a12, a13, a14, a15, } }, + InlineAsmClobberAbi::Bpf => clobbered_regs! { + Bpf BpfInlineAsmReg { + // Refs: Section 1.1 "Registers and calling convention" in BPF ABI Recommended Conventions and Guidelines v1.0 + // https://www.kernel.org/doc/html/latest/bpf/standardization/abi.html#registers-and-calling-convention + + r0, r1, r2, r3, r4, r5, + } + }, InlineAsmClobberAbi::Msp430 => clobbered_regs! { Msp430 Msp430InlineAsmReg { r11, r12, r13, r14, r15, diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index 7c72318b4d7..055a3edcc32 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -148,8 +148,6 @@ trait_selection_dtcs_has_req_note = the used `impl` has a `'static` requirement trait_selection_dtcs_introduces_requirement = calling this method introduces the `impl`'s `'static` requirement trait_selection_dtcs_suggestion = consider relaxing the implicit `'static` requirement -trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries} - trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]` .label = empty on-clause here diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 117b6a76425..db4a14356cc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1392,9 +1392,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { mut values: Option<ty::ParamEnvAnd<'tcx, ValuePairs<'tcx>>>, terr: TypeError<'tcx>, prefer_label: bool, + override_span: Option<Span>, ) { - let span = cause.span; - + // We use `override_span` when we want the error to point at a `Span` other than + // `cause.span`. This is used in E0271, when a closure is passed in where the return type + // isn't what was expected. We want to point at the closure's return type (or expression), + // instead of the expression where the closure is passed as call argument. + let span = override_span.unwrap_or(cause.span); // For some types of errors, expected-found does not make // sense, so just ignore the values we were given. if let TypeError::CyclicTy(_) = terr { @@ -2057,6 +2061,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { Some(param_env.and(trace.values)), terr, false, + None, ); diag } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 6d39cbce3b7..6416c539f26 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -708,6 +708,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { None, TypeError::Sorts(ty::error::ExpectedFound::new(expected_ty, ct_ty)), false, + None, ); diag } @@ -931,14 +932,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id); - let body_id = match self.tcx.hir_node(hir_id) { - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn { body: body_id, .. }, .. - }) => body_id, - _ => return false, - }; - let ControlFlow::Break(expr) = (FindMethodSubexprOfTry { search_span: span }) - .visit_body(self.tcx.hir().body(*body_id)) + let Some(body_id) = self.tcx.hir_node(hir_id).body_id() else { return false }; + let ControlFlow::Break(expr) = + (FindMethodSubexprOfTry { search_span: span }).visit_body(self.tcx.hir().body(body_id)) else { return false; }; @@ -1385,9 +1381,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => (None, error.err), }; - let msg = values + let (msg, span, closure_span) = values .and_then(|(predicate, normalized_term, expected_term)| { - self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term) + self.maybe_detailed_projection_msg( + obligation.cause.span, + predicate, + normalized_term, + expected_term, + ) }) .unwrap_or_else(|| { let mut cx = FmtPrinter::new_with_limit( @@ -1395,12 +1396,39 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { Namespace::TypeNS, rustc_session::Limit(10), ); - with_forced_trimmed_paths!(format!("type mismatch resolving `{}`", { - self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap(); - cx.into_buffer() - })) + ( + with_forced_trimmed_paths!(format!("type mismatch resolving `{}`", { + self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap(); + cx.into_buffer() + })), + obligation.cause.span, + None, + ) }); - let mut diag = struct_span_code_err!(self.dcx(), obligation.cause.span, E0271, "{msg}"); + let mut diag = struct_span_code_err!(self.dcx(), span, E0271, "{msg}"); + if let Some(span) = closure_span { + // Mark the closure decl so that it is seen even if we are pointing at the return + // type or expression. + // + // error[E0271]: expected `{closure@foo.rs:41:16}` to be a closure that returns + // `Unit3`, but it returns `Unit4` + // --> $DIR/foo.rs:43:17 + // | + // LL | let v = Unit2.m( + // | - required by a bound introduced by this call + // ... + // LL | f: |x| { + // | --- /* this span */ + // LL | drop(x); + // LL | Unit4 + // | ^^^^^ expected `Unit3`, found `Unit4` + // | + diag.span_label(span, "this closure"); + if !span.overlaps(obligation.cause.span) { + // Point at the binding corresponding to the closure where it is used. + diag.span_label(obligation.cause.span, "closure used here"); + } + } let secondary_span = (|| { let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) = @@ -1471,6 +1499,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }), err, false, + Some(span), ); self.note_obligation_cause(&mut diag, obligation); diag.emit() @@ -1479,34 +1508,66 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn maybe_detailed_projection_msg( &self, + mut span: Span, projection_term: ty::AliasTerm<'tcx>, normalized_ty: ty::Term<'tcx>, expected_ty: ty::Term<'tcx>, - ) -> Option<String> { + ) -> Option<(String, Span, Option<Span>)> { let trait_def_id = projection_term.trait_def_id(self.tcx); let self_ty = projection_term.self_ty(); with_forced_trimmed_paths! { if self.tcx.is_lang_item(projection_term.def_id, LangItem::FnOnceOutput) { let fn_kind = self_ty.prefix_string(self.tcx); + let (span, closure_span) = if let ty::Closure(def_id, _) = self_ty.kind() { + let def_span = self.tcx.def_span(def_id); + if let Some(local_def_id) = def_id.as_local() + && let node = self.tcx.hir_node_by_def_id(local_def_id) + && let Some(fn_decl) = node.fn_decl() + && let Some(id) = node.body_id() + { + span = match fn_decl.output { + hir::FnRetTy::Return(ty) => ty.span, + hir::FnRetTy::DefaultReturn(_) => { + let body = self.tcx.hir().body(id); + match body.value.kind { + hir::ExprKind::Block( + hir::Block { expr: Some(expr), .. }, + _, + ) => expr.span, + hir::ExprKind::Block( + hir::Block { + expr: None, stmts: [.., last], .. + }, + _, + ) => last.span, + _ => body.value.span, + } + } + }; + } + (span, Some(def_span)) + } else { + (span, None) + }; let item = match self_ty.kind() { ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(), _ => self_ty.to_string(), }; - Some(format!( + Some((format!( "expected `{item}` to be a {fn_kind} that returns `{expected_ty}`, but it \ returns `{normalized_ty}`", - )) + ), span, closure_span)) } else if self.tcx.is_lang_item(trait_def_id, LangItem::Future) { - Some(format!( + Some((format!( "expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it \ resolves to `{normalized_ty}`" - )) + ), span, None)) } else if Some(trait_def_id) == self.tcx.get_diagnostic_item(sym::Iterator) { - Some(format!( + Some((format!( "expected `{self_ty}` to be an iterator that yields `{expected_ty}`, but it \ yields `{normalized_ty}`" - )) + ), span, None)) } else { None } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 8111983c539..b4e5cc6185c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -482,11 +482,10 @@ pub fn report_dyn_incompatibility<'tcx>( for (span, msg) in iter::zip(multi_span, messages) { note_span.push_span_label(span, msg); } - // FIXME(dyn_compat_renaming): Update the URL. err.span_note( note_span, "for a trait to be dyn compatible it needs to allow building a vtable\n\ - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>", + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>", ); // Only provide the help if its a local trait, otherwise it's not actionable. diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index c8672b9dbd2..c5ab8a71c78 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -12,7 +12,7 @@ use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty}; use rustc_hir::{self as hir, AmbigArg, FnRetTy, GenericParamKind, Node}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath}; -use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, PolyTraitRef, Region, Ty, TyCtxt}; +use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, Region, Ty, TyCtxt}; use rustc_span::{BytePos, Ident, Span, Symbol, kw}; use crate::error_reporting::infer::ObligationCauseAsDiagArg; @@ -23,15 +23,6 @@ use crate::fluent_generated as fluent; pub mod note_and_explain; #[derive(Diagnostic)] -#[diag(trait_selection_dump_vtable_entries)] -pub struct DumpVTableEntries<'a> { - #[primary_span] - pub span: Span, - pub trait_ref: PolyTraitRef<'a>, - pub entries: String, -} - -#[derive(Diagnostic)] #[diag(trait_selection_unable_to_construct_constant_value)] pub struct UnableToConstructConstantValue<'a> { #[primary_span] diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 66491d9abe1..baa94ead9d4 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -64,7 +64,7 @@ fn is_dyn_compatible(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { } /// We say a method is *vtable safe* if it can be invoked on a trait -/// object. Note that object-safe traits can have some +/// object. Note that dyn-compatible traits can have some /// non-vtable-safe methods, so long as they require `Self: Sized` or /// otherwise ensure that they cannot be used when `Self = Trait`. pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::AssocItem) -> bool { @@ -421,7 +421,7 @@ fn virtual_call_violations_for_method<'tcx>( let receiver_ty = tcx.liberate_late_bound_regions(method.def_id, sig.input(0)); // Until `unsized_locals` is fully implemented, `self: Self` can't be dispatched on. - // However, this is already considered object-safe. We allow it as a special case here. + // However, this is already considered dyn compatible. We allow it as a special case here. // FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows // `Receiver: Unsize<Receiver[Self => dyn Trait]>`. if receiver_ty != tcx.types.self_param { @@ -631,7 +631,7 @@ fn object_ty_for_trait<'tcx>( /// - `self: Pin<Box<Self>>` requires `Pin<Box<Self>>: DispatchFromDyn<Pin<Box<dyn Trait>>>`. /// /// The only case where the receiver is not dispatchable, but is still a valid receiver -/// type (just not object-safe), is when there is more than one level of pointer indirection. +/// type (just not dyn compatible), is when there is more than one level of pointer indirection. /// E.g., `self: &&Self`, `self: &Rc<Self>`, `self: Box<Box<Self>>`. In these cases, there /// is no way, or at least no inexpensive way, to coerce the receiver from the version where /// `Self = dyn Trait` to the version where `Self = T`, where `T` is the unknown erased type diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index c9fb2a757e1..d30363ec158 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -25,7 +25,7 @@ use tracing::debug; /// trait Bar {} /// trait Foo = Bar + Bar; /// -/// let not_object_safe: dyn Foo; // bad, two `Bar` principals. +/// let dyn_incompatible: dyn Foo; // bad, two `Bar` principals. /// ``` pub fn expand_trait_aliases<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index b5bc8364c7b..000e6a765d3 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -2,26 +2,22 @@ use std::fmt::Debug; use std::ops::ControlFlow; use rustc_hir::def_id::DefId; -use rustc_infer::infer::at::ToTrace; -use rustc_infer::infer::{BoundRegionConversionTime, TyCtxtInferExt}; -use rustc_infer::traits::ObligationCause; use rustc_infer::traits::util::PredicateSet; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ self, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, Upcast, VtblEntry, }; -use rustc_span::{DUMMY_SP, Span, sym}; +use rustc_span::DUMMY_SP; use smallvec::{SmallVec, smallvec}; use tracing::debug; -use crate::errors::DumpVTableEntries; -use crate::traits::{ObligationCtxt, impossible_predicates, is_vtable_safe_method}; +use crate::traits::{impossible_predicates, is_vtable_safe_method}; #[derive(Clone, Debug)] pub enum VtblSegment<'tcx> { MetadataDSA, - TraitOwnEntries { trait_ref: ty::PolyTraitRef<'tcx>, emit_vptr: bool }, + TraitOwnEntries { trait_ref: ty::TraitRef<'tcx>, emit_vptr: bool }, } /// Prepare the segments for a vtable @@ -29,7 +25,7 @@ pub enum VtblSegment<'tcx> { // about our `Self` type here. pub fn prepare_vtable_segments<'tcx, T>( tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, + trait_ref: ty::TraitRef<'tcx>, segment_visitor: impl FnMut(VtblSegment<'tcx>) -> ControlFlow<T>, ) -> Option<T> { prepare_vtable_segments_inner(tcx, trait_ref, segment_visitor).break_value() @@ -39,7 +35,7 @@ pub fn prepare_vtable_segments<'tcx, T>( /// such that we can use `?` in the body. fn prepare_vtable_segments_inner<'tcx, T>( tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, + trait_ref: ty::TraitRef<'tcx>, mut segment_visitor: impl FnMut(VtblSegment<'tcx>) -> ControlFlow<T>, ) -> ControlFlow<T> { // The following constraints holds for the final arrangement. @@ -92,7 +88,7 @@ fn prepare_vtable_segments_inner<'tcx, T>( let mut emit_vptr_on_new_entry = false; let mut visited = PredicateSet::new(tcx); let predicate = trait_ref.upcast(tcx); - let mut stack: SmallVec<[(ty::PolyTraitRef<'tcx>, _, _); 5]> = + let mut stack: SmallVec<[(ty::TraitRef<'tcx>, _, _); 5]> = smallvec![(trait_ref, emit_vptr_on_new_entry, maybe_iter(None))]; visited.insert(predicate); @@ -125,10 +121,18 @@ fn prepare_vtable_segments_inner<'tcx, T>( let &(inner_most_trait_ref, _, _) = stack.last().unwrap(); let mut direct_super_traits_iter = tcx - .explicit_super_predicates_of(inner_most_trait_ref.def_id()) + .explicit_super_predicates_of(inner_most_trait_ref.def_id) .iter_identity_copied() .filter_map(move |(pred, _)| { - pred.instantiate_supertrait(tcx, inner_most_trait_ref).as_trait_clause() + pred.instantiate_supertrait(tcx, ty::Binder::dummy(inner_most_trait_ref)) + .as_trait_clause() + }) + .map(move |pred| { + tcx.normalize_erasing_late_bound_regions( + ty::TypingEnv::fully_monomorphized(), + pred, + ) + .trait_ref }); // Find an unvisited supertrait @@ -136,16 +140,11 @@ fn prepare_vtable_segments_inner<'tcx, T>( .find(|&super_trait| visited.insert(super_trait.upcast(tcx))) { // Push it to the stack for the next iteration of 'diving_in to pick up - Some(unvisited_super_trait) => { - // We're throwing away potential constness of super traits here. - // FIXME: handle ~const super traits - let next_super_trait = unvisited_super_trait.map_bound(|t| t.trait_ref); - stack.push(( - next_super_trait, - emit_vptr_on_new_entry, - maybe_iter(Some(direct_super_traits_iter)), - )) - } + Some(next_super_trait) => stack.push(( + next_super_trait, + emit_vptr_on_new_entry, + maybe_iter(Some(direct_super_traits_iter)), + )), // There are no more unvisited direct super traits, dive-in finished None => break 'diving_in, @@ -154,8 +153,7 @@ fn prepare_vtable_segments_inner<'tcx, T>( // emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level. while let Some((inner_most_trait_ref, emit_vptr, mut siblings)) = stack.pop() { - let has_entries = - has_own_existential_vtable_entries(tcx, inner_most_trait_ref.def_id()); + let has_entries = has_own_existential_vtable_entries(tcx, inner_most_trait_ref.def_id); segment_visitor(VtblSegment::TraitOwnEntries { trait_ref: inner_most_trait_ref, @@ -169,11 +167,6 @@ fn prepare_vtable_segments_inner<'tcx, T>( if let Some(next_inner_most_trait_ref) = siblings.find(|&sibling| visited.insert(sibling.upcast(tcx))) { - // We're throwing away potential constness of super traits here. - // FIXME: handle ~const super traits - let next_inner_most_trait_ref = - next_inner_most_trait_ref.map_bound(|t| t.trait_ref); - stack.push((next_inner_most_trait_ref, emit_vptr_on_new_entry, siblings)); // just pushed a new trait onto the stack, so we need to go through its super traits @@ -192,15 +185,6 @@ fn maybe_iter<I: Iterator>(i: Option<I>) -> impl Iterator<Item = I::Item> { i.into_iter().flatten() } -fn dump_vtable_entries<'tcx>( - tcx: TyCtxt<'tcx>, - sp: Span, - trait_ref: ty::PolyTraitRef<'tcx>, - entries: &[VtblEntry<'tcx>], -) { - tcx.dcx().emit_err(DumpVTableEntries { span: sp, trait_ref, entries: format!("{entries:#?}") }); -} - fn has_own_existential_vtable_entries(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { own_existential_vtable_entries_iter(tcx, trait_def_id).next().is_some() } @@ -239,8 +223,15 @@ fn own_existential_vtable_entries_iter( /// that come from `trait_ref`, including its supertraits. fn vtable_entries<'tcx>( tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, + trait_ref: ty::TraitRef<'tcx>, ) -> &'tcx [VtblEntry<'tcx>] { + debug_assert!(!trait_ref.has_non_region_infer() && !trait_ref.has_non_region_param()); + debug_assert_eq!( + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref), + trait_ref, + "vtable trait ref should be normalized" + ); + debug!("vtable_entries({:?})", trait_ref); let mut entries = vec![]; @@ -251,33 +242,26 @@ fn vtable_entries<'tcx>( entries.extend(TyCtxt::COMMON_VTABLE_ENTRIES); } VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { - let existential_trait_ref = trait_ref - .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + let existential_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref); // Lookup the shape of vtable for the trait. let own_existential_entries = - tcx.own_existential_vtable_entries(existential_trait_ref.def_id()); + tcx.own_existential_vtable_entries(existential_trait_ref.def_id); let own_entries = own_existential_entries.iter().copied().map(|def_id| { debug!("vtable_entries: trait_method={:?}", def_id); // The method may have some early-bound lifetimes; add regions for those. - let args = trait_ref.map_bound(|trait_ref| { + // FIXME: Is this normalize needed? + let args = tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), GenericArgs::for_item(tcx, def_id, |param, _| match param.kind { GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { trait_ref.args[param.index as usize] } - }) - }); - - // The trait type may have higher-ranked lifetimes in it; - // erase them if they appear, so that we get the type - // at some particular call site. - let args = tcx.normalize_erasing_late_bound_regions( - ty::TypingEnv::fully_monomorphized(), - args, + }), ); // It's possible that the method relies on where-clauses that @@ -317,11 +301,6 @@ fn vtable_entries<'tcx>( let _ = prepare_vtable_segments(tcx, trait_ref, vtable_segment_callback); - if tcx.has_attr(trait_ref.def_id(), sym::rustc_dump_vtable) { - let sp = tcx.def_span(trait_ref.def_id()); - dump_vtable_entries(tcx, sp, trait_ref, &entries); - } - tcx.arena.alloc_from_iter(entries) } @@ -329,14 +308,20 @@ fn vtable_entries<'tcx>( // for `Supertrait`'s methods in the vtable of `Subtrait`. pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRef<'tcx>) -> usize { debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param()); + debug_assert_eq!( + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key), + key, + "vtable trait ref should be normalized" + ); let ty::Dynamic(source, _, _) = *key.self_ty().kind() else { bug!(); }; - let source_principal = - source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self); + let source_principal = tcx.instantiate_bound_regions_with_erased( + source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self), + ); - let target_principal = ty::Binder::dummy(ty::ExistentialTraitRef::erase_self_ty(tcx, key)); + let target_principal = ty::ExistentialTraitRef::erase_self_ty(tcx, key); let vtable_segment_callback = { let mut vptr_offset = 0; @@ -346,17 +331,14 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len(); } VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => { - if trait_refs_are_compatible( - tcx, - vtable_principal - .map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)), - target_principal, - ) { + if ty::ExistentialTraitRef::erase_self_ty(tcx, vtable_principal) + == target_principal + { return ControlFlow::Break(vptr_offset); } vptr_offset += - tcx.own_existential_vtable_entries(vtable_principal.def_id()).len(); + tcx.own_existential_vtable_entries(vtable_principal.def_id).len(); if emit_vptr { vptr_offset += 1; @@ -382,20 +364,27 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( ), ) -> Option<usize> { debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param()); + debug_assert_eq!( + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key), + key, + "upcasting trait refs should be normalized" + ); + let (source, target) = key; // If the target principal is `None`, we can just return `None`. let ty::Dynamic(target, _, _) = *target.kind() else { bug!(); }; - let target_principal = target.principal()?; + let target_principal = tcx.instantiate_bound_regions_with_erased(target.principal()?); // Given that we have a target principal, it is a bug for there not to be a source principal. let ty::Dynamic(source, _, _) = *source.kind() else { bug!(); }; - let source_principal = - source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self); + let source_principal = tcx.instantiate_bound_regions_with_erased( + source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self), + ); let vtable_segment_callback = { let mut vptr_offset = 0; @@ -406,13 +395,10 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( } VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => { vptr_offset += - tcx.own_existential_vtable_entries(vtable_principal.def_id()).len(); - if trait_refs_are_compatible( - tcx, - vtable_principal - .map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)), - target_principal, - ) { + tcx.own_existential_vtable_entries(vtable_principal.def_id).len(); + if ty::ExistentialTraitRef::erase_self_ty(tcx, vtable_principal) + == target_principal + { if emit_vptr { return ControlFlow::Break(Some(vptr_offset)); } else { @@ -432,41 +418,6 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap() } -fn trait_refs_are_compatible<'tcx>( - tcx: TyCtxt<'tcx>, - hr_vtable_principal: ty::PolyExistentialTraitRef<'tcx>, - hr_target_principal: ty::PolyExistentialTraitRef<'tcx>, -) -> bool { - if hr_vtable_principal.def_id() != hr_target_principal.def_id() { - return false; - } - - let (infcx, param_env) = - tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized()); - let ocx = ObligationCtxt::new(&infcx); - let hr_source_principal = - ocx.normalize(&ObligationCause::dummy(), param_env, hr_vtable_principal); - let hr_target_principal = - ocx.normalize(&ObligationCause::dummy(), param_env, hr_target_principal); - infcx.enter_forall(hr_target_principal, |target_principal| { - let source_principal = infcx.instantiate_binder_with_fresh_vars( - DUMMY_SP, - BoundRegionConversionTime::HigherRankedType, - hr_source_principal, - ); - let Ok(()) = ocx.eq_trace( - &ObligationCause::dummy(), - param_env, - ToTrace::to_trace(&ObligationCause::dummy(), hr_target_principal, hr_source_principal), - target_principal, - source_principal, - ) else { - return false; - }; - ocx.select_all_or_error().is_empty() - }) -} - pub(super) fn provide(providers: &mut Providers) { *providers = Providers { own_existential_vtable_entries, diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 8686169c15d..eec6cd8d49b 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -251,6 +251,7 @@ pub enum AssertMessage { ResumedAfterReturn(CoroutineKind), ResumedAfterPanic(CoroutineKind), MisalignedPointerDereference { required: Operand, found: Operand }, + NullPointerDereference, } impl AssertMessage { @@ -306,6 +307,7 @@ impl AssertMessage { AssertMessage::MisalignedPointerDereference { .. } => { Ok("misaligned pointer dereference") } + AssertMessage::NullPointerDereference => Ok("null pointer dereference occured"), } } } diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index 81981bce202..6638f93e555 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -298,6 +298,9 @@ fn pretty_assert_message<W: Write>(writer: &mut W, msg: &AssertMessage) -> io::R "\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}" ) } + AssertMessage::NullPointerDereference => { + write!(writer, "\"null pointer dereference occured.\"") + } AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => { write!(writer, "{}", msg.description().unwrap()) } diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index 79efb83cebd..d985a98fcbf 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -426,7 +426,10 @@ pub trait MirVisitor { | AssertMessage::RemainderByZero(op) => { self.visit_operand(op, location); } - AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => { //nothing to visit + AssertMessage::ResumedAfterReturn(_) + | AssertMessage::ResumedAfterPanic(_) + | AssertMessage::NullPointerDereference => { + //nothing to visit } AssertMessage::MisalignedPointerDereference { required, found } => { self.visit_operand(required, location); diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 80f6e32b6b2..e5c1a64c12e 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -468,9 +468,11 @@ pub fn spin_loop() { /// // No assumptions can be made about either operand, so the multiplication is not optimized out. /// let y = black_box(5) * black_box(10); /// ``` +/// +/// During constant evaluation, `black_box` is treated as a no-op. #[inline] #[stable(feature = "bench_black_box", since = "1.66.0")] -#[rustc_const_unstable(feature = "const_black_box", issue = "none")] +#[rustc_const_stable(feature = "const_black_box", since = "CURRENT_RUSTC_VERSION")] pub const fn black_box<T>(dummy: T) -> T { crate::intrinsics::black_box(dummy) } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 41b2ffad668..c0d435f99c0 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3725,6 +3725,7 @@ pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: u #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] +#[rustc_intrinsic_const_stable_indirect] pub const fn black_box<T>(_dummy: T) -> T { unimplemented!() } diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 53e2b238bae..a89de12c02b 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -291,6 +291,22 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! { ) } +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] +#[cfg_attr(feature = "panic_immediate_abort", inline)] +#[track_caller] +#[cfg_attr(not(bootstrap), lang = "panic_null_pointer_dereference")] // needed by codegen for panic on null pointer deref +#[rustc_nounwind] // `CheckNull` MIR pass requires this function to never unwind +fn panic_null_pointer_dereference() -> ! { + if cfg!(feature = "panic_immediate_abort") { + super::intrinsics::abort() + } + + panic_nounwind_fmt( + format_args!("null pointer dereference occured"), + /* force_no_backtrace */ false, + ) +} + /// Panics because we cannot unwind out of a function. /// /// This is a separate function to avoid the codesize impact of each crate containing the string to diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 0061e33f986..73180bde54a 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -716,6 +716,12 @@ impl AtomicBool { /// AcqRel | AcqRel | Acquire /// SeqCst | SeqCst | SeqCst /// + /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use + /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`, + /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err` + /// rather than to infer success vs failure based on the value that was read. + /// + /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead. /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds, /// which allows the compiler to generate better assembly code when the compare and swap /// is used in a loop. @@ -1651,6 +1657,12 @@ impl<T> AtomicPtr<T> { /// AcqRel | AcqRel | Acquire /// SeqCst | SeqCst | SeqCst /// + /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use + /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`, + /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err` + /// rather than to infer success vs failure based on the value that was read. + /// + /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead. /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds, /// which allows the compiler to generate better assembly code when the compare and swap /// is used in a loop. @@ -2771,6 +2783,12 @@ macro_rules! atomic_int { /// AcqRel | AcqRel | Acquire /// SeqCst | SeqCst | SeqCst /// + /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use + /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`, + /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err` + /// rather than to infer success vs failure based on the value that was read. + /// + /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead. /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds, /// which allows the compiler to generate better assembly code when the compare and swap /// is used in a loop. diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 0607d508a48..7fe72862608 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -14,7 +14,6 @@ #![feature(bstr)] #![feature(cell_update)] #![feature(clone_to_uninit)] -#![feature(const_black_box)] #![feature(const_eval_select)] #![feature(const_swap_nonoverlapping)] #![feature(const_trait_impl)] diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index fd9bf47234c..f447d186a52 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1049,9 +1049,12 @@ pub fn rustc_cargo( // <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Internal.20lint.20for.20raw.20.60print!.60.20and.20.60println!.60.3F>. cargo.rustflag("-Zon-broken-pipe=kill"); - if builder.config.llvm_enzyme { - cargo.rustflag("-l").rustflag("Enzyme-19"); - } + // We temporarily disable linking here as part of some refactoring. + // This way, people can manually use -Z llvm-plugins and -C passes=enzyme for now. + // In a follow-up PR, we will re-enable linking here and load the pass for them. + //if builder.config.llvm_enzyme { + // cargo.rustflag("-l").rustflag("Enzyme-19"); + //} // Building with protected visibility reduces the number of dynamic relocations needed, giving // us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index c6bc19f9e6c..9af88709625 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -43,6 +43,10 @@ runners: os: windows-2022-8core-32gb <<: *base-job + - &job-windows-25-8c + os: windows-2025-8core-32gb + <<: *base-job + - &job-aarch64-linux # Free some disk space to avoid running out of space during the build. free_disk: true @@ -524,7 +528,7 @@ auto: # We are intentionally allowing an old toolchain on this builder (and that's # incompatible with LLVM downloads today). NO_DOWNLOAD_CI_LLVM: 1 - <<: *job-windows-8c + <<: *job-windows-25-8c # x86_64-mingw is split into two jobs to run tests in parallel. - name: x86_64-mingw-1 diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md index 1d9fa1b52d5..cd215277e69 100644 --- a/src/doc/rustc-dev-guide/src/building/new-target.md +++ b/src/doc/rustc-dev-guide/src/building/new-target.md @@ -4,8 +4,13 @@ These are a set of steps to add support for a new target. There are numerous end states and paths to get there, so not all sections may be relevant to your desired goal. +See also the associated documentation in the +[target tier policy][target_tier_policy_add]. + <!-- toc --> +[target_tier_policy_add]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target + ## Specifying a new LLVM For very new targets, you may need to use a different fork of LLVM diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md index a2a6c8085df..e2097b26e5c 100644 --- a/src/doc/rustc-dev-guide/src/compiler-debugging.md +++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md @@ -275,7 +275,7 @@ Here are some notable ones: | `rustc_dump_def_parents` | Dumps the chain of `DefId` parents of certain definitions. | | `rustc_dump_item_bounds` | Dumps the [`item_bounds`] of an item. | | `rustc_dump_predicates` | Dumps the [`predicates_of`] an item. | -| `rustc_dump_vtable` | | +| `rustc_dump_vtable` | Dumps the vtable layout of an impl, or a type alias of a dyn type. | | `rustc_hidden_type_of_opaques` | Dumps the [hidden type of each opaque types][opaq] in the crate. | | `rustc_layout` | [See this section](#debugging-type-layouts). | | `rustc_object_lifetime_default` | Dumps the [object lifetime defaults] of an item. | diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 4010e90821f..0e624a4566d 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -43,7 +43,7 @@ environment. ## Formatting and linting Python code -The Rust repository contains quite a lof of Python code. We try to keep +The Rust repository contains quite a lot of Python code. We try to keep it both linted and formatted by the [ruff][ruff] tool. When modifying Python code, use this command to format it: diff --git a/src/doc/rustc/src/profile-guided-optimization.md b/src/doc/rustc/src/profile-guided-optimization.md index 38b655b7542..4050494793a 100644 --- a/src/doc/rustc/src/profile-guided-optimization.md +++ b/src/doc/rustc/src/profile-guided-optimization.md @@ -3,7 +3,7 @@ `rustc` supports doing profile-guided optimization (PGO). This chapter describes what PGO is, what it is good for, and how it can be used. -## What Is Profiled-Guided Optimization? +## What Is Profile-Guided Optimization? The basic concept of PGO is to collect data about the typical execution of a program (e.g. which branches it is likely to take) and then use this data diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md index bdcf2c0b07e..a0acfdf0e4a 100644 --- a/src/doc/rustc/src/target-tier-policy.md +++ b/src/doc/rustc/src/target-tier-policy.md @@ -122,12 +122,23 @@ To propose addition of a new target, open a pull request on [`rust-lang/rust`]: r? compiler ``` +See also the documentation in the `rustc-dev-guide` on [adding a new target to +`rustc`][rustc_dev_guide_add_target]. + +Note that adding a new target that wants to support `std` would transitively +require `cc` and `libc` support. However, these would like to know about the +target from `rustc` as well. To break this cycle, you are strongly encouraged +to add a _minimal_ `#![no_core]` target spec first to teach `rustc` about the +target's existence, and add `std` support as a follow-up once you've added +support for the target in `cc` and `libc`. + [tier3example]: https://github.com/rust-lang/rust/pull/94872 [platform_template]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support/TEMPLATE.md [summary]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/SUMMARY.md [platformsupport]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support.md [rust_compiler_team]: https://www.rust-lang.org/governance/teams/compiler [`rust-lang/rust`]: https://github.com/rust-lang/rust +[rustc_dev_guide_add_target]: https://rustc-dev-guide.rust-lang.org/building/new-target.html ## Tier 3 target policy diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index d1d42e47322..7eb1b8df233 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -524,6 +524,8 @@ use `-o -`. ## `-w`/`--output-format`: output format +### json + `--output-format json` emits documentation in the experimental [JSON format](https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc_json_types/). `--output-format html` has no effect, and is also accepted on stable toolchains. @@ -542,6 +544,68 @@ It can also be used with `--show-coverage`. Take a look at its [documentation](#--show-coverage-calculate-the-percentage-of-items-with-documentation) for more information. +### doctest + +`--output-format doctest` emits JSON on stdout which gives you information about doctests in the +provided crate. + +Tracking issue: [#134529](https://github.com/rust-lang/rust/issues/134529) + +You can use this option like this: + +```bash +rustdoc -Zunstable-options --output-format=doctest src/lib.rs +``` + +For this rust code: + +```rust +/// ``` +/// let x = 12; +/// ``` +pub trait Trait {} +``` + +The generated output (formatted) will look like this: + +```json +{ + "format_version": 1, + "doctests": [ + { + "file": "foo.rs", + "line": 1, + "doctest_attributes": { + "original": "", + "should_panic": false, + "no_run": false, + "ignore": "None", + "rust": true, + "test_harness": false, + "compile_fail": false, + "standalone_crate": false, + "error_codes": [], + "edition": null, + "added_css_classes": [], + "unknown": [] + }, + "original_code": "let x = 12;", + "doctest_code": "#![allow(unused)]\nfn main() {\nlet x = 12;\n}", + "name": "foo.rs - Trait (line 1)" + } + ] +} +``` + + * `format_version` gives you the current version of the generated JSON. If we change the output in any way, the number will increase. + * `doctests` contains the list of doctests present in the crate. + * `file` is the file path where the doctest is located. + * `line` is the line where the doctest starts (so where the \`\`\` is located in the current code). + * `doctest_attributes` contains computed information about the attributes used on the doctests. For more information about doctest attributes, take a look [here](write-documentation/documentation-tests.html#attributes). + * `original_code` is the code as written in the source code before rustdoc modifies it. + * `doctest_code` is the code modified by rustdoc that will be run. If there is a fatal syntax error, this field will not be present. + * `name` is the name generated by rustdoc which represents this doctest. + ## `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests * Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245) diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md index b9a89c20cee..19e62c4867c 100644 --- a/src/doc/style-guide/src/editions.md +++ b/src/doc/style-guide/src/editions.md @@ -36,10 +36,6 @@ For a full history of changes in the Rust 2024 style edition, see the git history of the style guide. Notable changes in the Rust 2024 style edition include: -- [#114764](https://github.com/rust-lang/rust/pull/114764) As the last member - of a delimited expression, delimited expressions are generally combinable, - regardless of the number of members. Previously only applied with exactly - one member (except for closures with explicit blocks). - Miscellaneous `rustfmt` bugfixes. - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order). - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase". diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index 171a24cd89d..12037b5992e 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -818,11 +818,11 @@ E.g., `&&Some(foo)` matches, `Foo(4, Bar)` does not. ## Combinable expressions -When the last argument in a function call is formatted across -multiple-lines, format the outer call as if it were a single-line call, +Where a function call has a single argument, and that argument is formatted +across multiple-lines, format the outer call as if it were a single-line call, if the result fits. Apply the same combining behaviour to any similar expressions which have multi-line, block-indented lists of sub-expressions -delimited by parentheses, brackets, or braces. E.g., +delimited by parentheses (e.g., macros or tuple struct literals). E.g., ```rust foo(bar( @@ -848,61 +848,20 @@ let arr = [combinable( an_expr, another_expr, )]; - -let x = Thing(an_expr, another_expr, match cond { - A => 1, - B => 2, -}); - -let x = format!("Stuff: {}", [ - an_expr, - another_expr, -]); - -let x = func(an_expr, another_expr, SomeStruct { - field: this_is_long, - another_field: 123, -}); ``` Apply this behavior recursively. -If the last argument is a multi-line closure with an explicit block, -only apply the combining behavior if there are no other closure arguments. +For a function with multiple arguments, if the last argument is a multi-line +closure with an explicit block, there are no other closure arguments, and all +the arguments and the first line of the closure fit on the first line, use the +same combining behavior: ```rust -// Combinable foo(first_arg, x, |param| { action(); foo(param) }) -// Not combinable, because the closure is not the last argument -foo( - first_arg, - |param| { - action(); - foo(param) - }, - whatever, -) -// Not combinable, because the first line of the closure does not fit -foo( - first_arg, - x, - move |very_long_param_causing_line_to_overflow| -> Bar { - action(); - foo(param) - }, -) -// Not combinable, because there is more than one closure argument -foo( - first_arg, - |x| x.bar(), - |param| { - action(); - foo(param) - }, -) ``` ## Ranges diff --git a/src/doc/unstable-book/src/compiler-flags/autodiff.md b/src/doc/unstable-book/src/compiler-flags/autodiff.md new file mode 100644 index 00000000000..4e55be0ad95 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/autodiff.md @@ -0,0 +1,23 @@ +# `autodiff` + +The tracking issue for this feature is: [#124509](https://github.com/rust-lang/rust/issues/124509). + +------------------------ + +This feature allows you to differentiate functions using automatic differentiation. +Set the `-Zautodiff=<options>` compiler flag to adjust the behaviour of the autodiff feature. +Multiple options can be separated with a comma. Valid options are: + +`PrintTA` - print Type Analysis Information +`PrintAA` - print Activity Analysis Information +`PrintPerf` - print Performance Warnings from Enzyme +`Print` - prints all intermediate transformations +`PrintModBefore` - print the whole module, before running opts +`PrintModAfterOpts` - print the whole module just before we pass it to Enzyme +`PrintModAfterEnzyme` - print the module after Enzyme differentiated everything +`LooseTypes` - Enzyme's loose type debug helper (can cause incorrect gradients) +`Inline` - runs Enzyme specific Inlining +`NoModOptAfter` - do not optimize the module after Enzyme is done +`EnableFncOpt` - tell Enzyme to run LLVM Opts on each function it generated +`NoVecUnroll` - do not unroll vectorized loops +`RuntimeActivity` - allow specifying activity at runtime diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 80bc6cebd2a..cfba7895208 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -33,6 +33,7 @@ pub(crate) enum OutputFormat { Json, #[default] Html, + Doctest, } impl OutputFormat { @@ -48,6 +49,7 @@ impl TryFrom<&str> for OutputFormat { match value { "json" => Ok(OutputFormat::Json), "html" => Ok(OutputFormat::Html), + "doctest" => Ok(OutputFormat::Doctest), _ => Err(format!("unknown output format `{value}`")), } } @@ -445,14 +447,42 @@ impl Options { } } + let show_coverage = matches.opt_present("show-coverage"); + let output_format_s = matches.opt_str("output-format"); + let output_format = match output_format_s { + Some(ref s) => match OutputFormat::try_from(s.as_str()) { + Ok(out_fmt) => out_fmt, + Err(e) => dcx.fatal(e), + }, + None => OutputFormat::default(), + }; + // check for `--output-format=json` - if !matches!(matches.opt_str("output-format").as_deref(), None | Some("html")) - && !matches.opt_present("show-coverage") - && !nightly_options::is_unstable_enabled(matches) - { - dcx.fatal( - "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)", - ); + match ( + output_format_s.as_ref().map(|_| output_format), + show_coverage, + nightly_options::is_unstable_enabled(matches), + ) { + (None | Some(OutputFormat::Json), true, _) => {} + (_, true, _) => { + dcx.fatal(format!( + "`--output-format={}` is not supported for the `--show-coverage` option", + output_format_s.unwrap_or_default(), + )); + } + // If `-Zunstable-options` is used, nothing to check after this point. + (_, false, true) => {} + (None | Some(OutputFormat::Html), false, _) => {} + (Some(OutputFormat::Json), false, false) => { + dcx.fatal( + "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)", + ); + } + (Some(OutputFormat::Doctest), false, false) => { + dcx.fatal( + "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/134529)", + ); + } } let to_check = matches.opt_strs("check-theme"); @@ -704,8 +734,6 @@ impl Options { }) .collect(); - let show_coverage = matches.opt_present("show-coverage"); - let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) { Ok(types) => types, Err(e) => { @@ -713,20 +741,6 @@ impl Options { } }; - let output_format = match matches.opt_str("output-format") { - Some(s) => match OutputFormat::try_from(s.as_str()) { - Ok(out_fmt) => { - if !out_fmt.is_json() && show_coverage { - dcx.fatal( - "html output format isn't supported for the --show-coverage option", - ); - } - out_fmt - } - Err(e) => dcx.fatal(e), - }, - None => OutputFormat::default(), - }; let crate_name = matches.opt_str("crate-name"); let bin_crate = crate_types.contains(&CrateType::Executable); let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro); diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 8c3e28ecec3..8b522e614b8 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1,3 +1,4 @@ +mod extracted; mod make; mod markdown; mod runner; @@ -30,7 +31,7 @@ use tempfile::{Builder as TempFileBuilder, TempDir}; use tracing::debug; use self::rust::HirCollector; -use crate::config::Options as RustdocOptions; +use crate::config::{Options as RustdocOptions, OutputFormat}; use crate::html::markdown::{ErrorCodes, Ignore, LangString, MdRelLine}; use crate::lint::init_lints; @@ -209,15 +210,8 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let args_path = temp_dir.path().join("rustdoc-cfgs"); crate::wrap_return(dcx, generate_args_file(&args_path, &options)); - let CreateRunnableDocTests { - standalone_tests, - mergeable_tests, - rustdoc_options, - opts, - unused_extern_reports, - compiling_test_count, - .. - } = interface::run_compiler(config, |compiler| { + let extract_doctests = options.output_format == OutputFormat::Doctest; + let result = interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { @@ -226,22 +220,53 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let opts = scrape_test_config(crate_name, crate_attrs, args_path); let enable_per_target_ignores = options.enable_per_target_ignores; - let mut collector = CreateRunnableDocTests::new(options, opts); let hir_collector = HirCollector::new( ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), enable_per_target_ignores, tcx, ); let tests = hir_collector.collect_crate(); - tests.into_iter().for_each(|t| collector.add_test(t)); + if extract_doctests { + let mut collector = extracted::ExtractedDocTests::new(); + tests.into_iter().for_each(|t| collector.add_test(t, &opts, &options)); + + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + if let Err(error) = serde_json::ser::to_writer(&mut stdout, &collector) { + eprintln!(); + Err(format!("Failed to generate JSON output for doctests: {error:?}")) + } else { + Ok(None) + } + } else { + let mut collector = CreateRunnableDocTests::new(options, opts); + tests.into_iter().for_each(|t| collector.add_test(t)); - collector + Ok(Some(collector)) + } }); compiler.sess.dcx().abort_if_errors(); collector }); + let CreateRunnableDocTests { + standalone_tests, + mergeable_tests, + rustdoc_options, + opts, + unused_extern_reports, + compiling_test_count, + .. + } = match result { + Ok(Some(collector)) => collector, + Ok(None) => return, + Err(error) => { + eprintln!("{error}"); + std::process::exit(1); + } + }; + run_tests(opts, &rustdoc_options, &unused_extern_reports, standalone_tests, mergeable_tests); let compiling_test_count = compiling_test_count.load(Ordering::SeqCst); diff --git a/src/librustdoc/doctest/extracted.rs b/src/librustdoc/doctest/extracted.rs new file mode 100644 index 00000000000..03c8814a4c9 --- /dev/null +++ b/src/librustdoc/doctest/extracted.rs @@ -0,0 +1,141 @@ +//! Rustdoc's doctest extraction. +//! +//! This module contains the logic to extract doctests and output a JSON containing this +//! information. + +use serde::Serialize; + +use super::{DocTestBuilder, ScrapedDocTest}; +use crate::config::Options as RustdocOptions; +use crate::html::markdown; + +/// The version of JSON output that this code generates. +/// +/// This integer is incremented with every breaking change to the API, +/// and is returned along with the JSON blob into the `format_version` root field. +/// Consuming code should assert that this value matches the format version(s) that it supports. +const FORMAT_VERSION: u32 = 1; + +#[derive(Serialize)] +pub(crate) struct ExtractedDocTests { + format_version: u32, + doctests: Vec<ExtractedDocTest>, +} + +impl ExtractedDocTests { + pub(crate) fn new() -> Self { + Self { format_version: FORMAT_VERSION, doctests: Vec::new() } + } + + pub(crate) fn add_test( + &mut self, + scraped_test: ScrapedDocTest, + opts: &super::GlobalTestOptions, + options: &RustdocOptions, + ) { + let edition = scraped_test.edition(&options); + + let ScrapedDocTest { filename, line, langstr, text, name } = scraped_test; + + let doctest = DocTestBuilder::new( + &text, + Some(&opts.crate_name), + edition, + false, + None, + Some(&langstr), + ); + let (full_test_code, size) = doctest.generate_unique_doctest( + &text, + langstr.test_harness, + &opts, + Some(&opts.crate_name), + ); + self.doctests.push(ExtractedDocTest { + file: filename.prefer_remapped_unconditionaly().to_string(), + line, + doctest_attributes: langstr.into(), + doctest_code: if size != 0 { Some(full_test_code) } else { None }, + original_code: text, + name, + }); + } +} + +#[derive(Serialize)] +pub(crate) struct ExtractedDocTest { + file: String, + line: usize, + doctest_attributes: LangString, + original_code: String, + /// `None` if the code syntax is invalid. + doctest_code: Option<String>, + name: String, +} + +#[derive(Serialize)] +pub(crate) enum Ignore { + All, + None, + Some(Vec<String>), +} + +impl From<markdown::Ignore> for Ignore { + fn from(original: markdown::Ignore) -> Self { + match original { + markdown::Ignore::All => Self::All, + markdown::Ignore::None => Self::None, + markdown::Ignore::Some(values) => Self::Some(values), + } + } +} + +#[derive(Serialize)] +struct LangString { + pub(crate) original: String, + pub(crate) should_panic: bool, + pub(crate) no_run: bool, + pub(crate) ignore: Ignore, + pub(crate) rust: bool, + pub(crate) test_harness: bool, + pub(crate) compile_fail: bool, + pub(crate) standalone_crate: bool, + pub(crate) error_codes: Vec<String>, + pub(crate) edition: Option<String>, + pub(crate) added_css_classes: Vec<String>, + pub(crate) unknown: Vec<String>, +} + +impl From<markdown::LangString> for LangString { + fn from(original: markdown::LangString) -> Self { + let markdown::LangString { + original, + should_panic, + no_run, + ignore, + rust, + test_harness, + compile_fail, + standalone_crate, + error_codes, + edition, + added_classes, + unknown, + } = original; + + Self { + original, + should_panic, + no_run, + ignore: ignore.into(), + rust, + test_harness, + compile_fail, + standalone_crate, + error_codes, + edition: edition.map(|edition| edition.to_string()), + added_css_classes: added_classes, + unknown, + } + } +} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index bb954a31891..44adf92ff0e 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -814,7 +814,12 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { } }; - match (options.should_test, config::markdown_input(&input)) { + let output_format = options.output_format; + + match ( + options.should_test || output_format == config::OutputFormat::Doctest, + config::markdown_input(&input), + ) { (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)), (true, None) => return doctest::run(dcx, input, options), (false, Some(md_input)) => { @@ -849,7 +854,6 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { // plug/cleaning passes. let crate_version = options.crate_version.clone(); - let output_format = options.output_format; let scrape_examples_options = options.scrape_examples_options.clone(); let bin_crate = options.bin_crate; @@ -899,6 +903,8 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { config::OutputFormat::Json => sess.time("render_json", || { run_renderer::<json::JsonRenderer<'_>>(krate, render_opts, cache, tcx) }), + // Already handled above with doctest runners. + config::OutputFormat::Doctest => unreachable!(), } }) }) diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 8201f332d33..c548f262a92 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -166,6 +166,8 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // MIR passes can be enabled / disabled separately, we should figure out, what passes to // use for Clippy. config.opts.unstable_opts.mir_opt_level = Some(0); + config.opts.unstable_opts.mir_enable_passes = + vec![("CheckNull".to_owned(), false), ("CheckAlignment".to_owned(), false)]; // Disable flattening and inlining of format_args!(), so the HIR matches with the AST. config.opts.unstable_opts.flatten_format_args = false; diff --git a/src/tools/enzyme b/src/tools/enzyme -Subproject 2fe5164a2423dd67ef25e2c4fb204fd06362494 +Subproject 0e5fa4a3d475f4dece489c9e06b11164f83789f diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 0be981f70b0..86928a6e6e8 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -6c1d960d88dd3755548b3818630acb63fa98187e +9709af79014a150df7807671e6250ed940c488eb diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 2c4cb4bfce7..18a5a0612bb 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -904,10 +904,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { new_perm: NewPermission, ) -> InterpResult<'tcx> { let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?; - let val = self.ecx.sb_retag_reference(&val, new_perm, RetagInfo { - cause: self.retag_cause, - in_field: self.in_field, - })?; + let val = self.ecx.sb_retag_reference( + &val, + new_perm, + RetagInfo { cause: self.retag_cause, in_field: self.in_field }, + )?; self.ecx.write_immediate(*val, place)?; interp_ok(()) } @@ -996,10 +997,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { access: Some(AccessKind::Write), protector: Some(ProtectorKind::StrongProtector), }; - this.sb_retag_place(place, new_perm, RetagInfo { - cause: RetagCause::InPlaceFnPassing, - in_field: false, - }) + this.sb_retag_place( + place, + new_perm, + RetagInfo { cause: RetagCause::InPlaceFnPassing, in_field: false }, + ) } /// Mark the given tag as exposed. It was found on a pointer with the given AllocId. diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs index 5d7c3d8c219..5c12ce39d10 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs @@ -379,14 +379,18 @@ pub mod diagnostics { use super::*; impl fmt::Display for PermissionPriv { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", match self { - ReservedFrz { conflicted: false } => "Reserved", - ReservedFrz { conflicted: true } => "Reserved (conflicted)", - ReservedIM => "Reserved (interior mutable)", - Active => "Active", - Frozen => "Frozen", - Disabled => "Disabled", - }) + write!( + f, + "{}", + match self { + ReservedFrz { conflicted: false } => "Reserved", + ReservedFrz { conflicted: true } => "Reserved (conflicted)", + ReservedIM => "Reserved (interior mutable)", + Active => "Active", + Frozen => "Frozen", + Disabled => "Disabled", + } + ) } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index fd69278f20a..3389b1c602c 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -581,15 +581,18 @@ impl Tree { let mut debug_info = NodeDebugInfo::new(root_tag, root_default_perm, span); // name the root so that all allocations contain one named pointer debug_info.add_name("root of the allocation"); - nodes.insert(root_idx, Node { - tag: root_tag, - parent: None, - children: SmallVec::default(), - default_initial_perm: root_default_perm, - // The root may never be skipped, all accesses will be local. - default_initial_idempotent_foreign_access: IdempotentForeignAccess::None, - debug_info, - }); + nodes.insert( + root_idx, + Node { + tag: root_tag, + parent: None, + children: SmallVec::default(), + default_initial_perm: root_default_perm, + // The root may never be skipped, all accesses will be local. + default_initial_idempotent_foreign_access: IdempotentForeignAccess::None, + debug_info, + }, + ); nodes }; let rperms = { @@ -624,14 +627,17 @@ impl<'tcx> Tree { let parent_idx = self.tag_mapping.get(&parent_tag).unwrap(); let strongest_idempotent = default_initial_perm.strongest_idempotent_foreign_access(prot); // Create the node - self.nodes.insert(idx, Node { - tag: new_tag, - parent: Some(parent_idx), - children: SmallVec::default(), - default_initial_perm, - default_initial_idempotent_foreign_access: strongest_idempotent, - debug_info: NodeDebugInfo::new(new_tag, default_initial_perm, span), - }); + self.nodes.insert( + idx, + Node { + tag: new_tag, + parent: Some(parent_idx), + children: SmallVec::default(), + default_initial_perm, + default_initial_idempotent_foreign_access: strongest_idempotent, + debug_info: NodeDebugInfo::new(new_tag, default_initial_perm, span), + }, + ); // Register new_tag as a child of parent_tag self.nodes.get_mut(parent_idx).unwrap().children.push(idx); // Initialize perms diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index aeadba0d46e..5d3204a527f 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -169,7 +169,7 @@ pub const MIRI_DEFAULT_ARGS: &[&str] = &[ "-Zmir-emit-retag", "-Zmir-keep-place-mention", "-Zmir-opt-level=0", - "-Zmir-enable-passes=-CheckAlignment", + "-Zmir-enable-passes=-CheckAlignment,-CheckNull", // Deduplicating diagnostics means we miss events when tracking what happens during an // execution. Let's not do that. "-Zdeduplicate-diagnostics=no", diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 845ba484326..5cb6640bf89 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1111,10 +1111,13 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { // Call the lang item. let panic = ecx.tcx.lang_items().get(reason.lang_item()).unwrap(); let panic = ty::Instance::mono(ecx.tcx.tcx, panic); - ecx.call_function(panic, ExternAbi::Rust, &[], None, StackPopCleanup::Goto { - ret: None, - unwind: mir::UnwindAction::Unreachable, - })?; + ecx.call_function( + panic, + ExternAbi::Rust, + &[], + None, + StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable }, + )?; interp_ok(()) } diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index f0aebfe1693..20dd3c8db2a 100644 --- a/src/tools/miri/src/shims/extern_static.rs +++ b/src/tools/miri/src/shims/extern_static.rs @@ -60,10 +60,10 @@ impl<'tcx> MiriMachine<'tcx> { match ecx.tcx.sess.target.os.as_ref() { "linux" => { - Self::null_ptr_extern_statics(ecx, &[ - "__cxa_thread_atexit_impl", - "__clock_gettime64", - ])?; + Self::null_ptr_extern_statics( + ecx, + &["__cxa_thread_atexit_impl", "__clock_gettime64"], + )?; Self::weak_symbol_extern_statics(ecx, &["getrandom", "statx"])?; } "freebsd" => { diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index 93479540009..83f331bb173 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -247,10 +247,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Call the lang item associated with this message. let fn_item = this.tcx.require_lang_item(msg.panic_function(), None); let instance = ty::Instance::mono(this.tcx.tcx, fn_item); - this.call_function(instance, ExternAbi::Rust, &[], None, StackPopCleanup::Goto { - ret: None, - unwind, - })?; + this.call_function( + instance, + ExternAbi::Rust, + &[], + None, + StackPopCleanup::Goto { ret: None, unwind }, + )?; } } interp_ok(()) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs index 23e2122ee50..dc3ab2828fa 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs @@ -230,10 +230,10 @@ fn test_two_same_fd_in_same_epoll_instance() { //Two notification should be received. let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); let expected_value = 5 as u64; - check_epoll_wait::<8>(epfd, &[ - (expected_event, expected_value), - (expected_event, expected_value), - ]); + check_epoll_wait::<8>( + epfd, + &[(expected_event, expected_value), (expected_event, expected_value)], + ); } fn test_epoll_eventfd() { @@ -290,10 +290,10 @@ fn test_epoll_socketpair_both_sides() { let expected_value0 = fds[0] as u64; let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap(); let expected_value1 = fds[1] as u64; - check_epoll_wait::<8>(epfd, &[ - (expected_event0, expected_value0), - (expected_event1, expected_value1), - ]); + check_epoll_wait::<8>( + epfd, + &[(expected_event0, expected_value0), (expected_event1, expected_value1)], + ); // Read from fds[0]. let mut buf: [u8; 5] = [0; 5]; @@ -453,10 +453,10 @@ fn test_socketpair_read() { let expected_value0 = fds[0] as u64; let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap(); let expected_value1 = fds[1] as u64; - check_epoll_wait::<8>(epfd, &[ - (expected_event0, expected_value0), - (expected_event1, expected_value1), - ]); + check_epoll_wait::<8>( + epfd, + &[(expected_event0, expected_value0), (expected_event1, expected_value1)], + ); // Read 3 bytes from fds[0]. let mut buf: [u8; 3] = [0; 3]; diff --git a/src/tools/miri/tests/pass/dyn-upcast.rs b/src/tools/miri/tests/pass/dyn-upcast.rs index 61410f7c4e0..f100c4d6a86 100644 --- a/src/tools/miri/tests/pass/dyn-upcast.rs +++ b/src/tools/miri/tests/pass/dyn-upcast.rs @@ -10,6 +10,8 @@ fn main() { replace_vptr(); vtable_nop_cast(); drop_principal(); + modulo_binder(); + modulo_assoc(); } fn vtable_nop_cast() { @@ -482,3 +484,53 @@ fn drop_principal() { println!("before"); drop(y); } + +// Test for <https://github.com/rust-lang/rust/issues/135316>. +fn modulo_binder() { + trait Supertrait<T> { + fn _print_numbers(&self, mem: &[usize; 100]) { + println!("{mem:?}"); + } + } + impl<T> Supertrait<T> for () {} + + trait Trait<T, U>: Supertrait<T> + Supertrait<U> { + fn say_hello(&self, _: &usize) { + println!("Hello!"); + } + } + impl<T, U> Trait<T, U> for () {} + + (&() as &'static dyn for<'a> Trait<&'static (), &'a ()> + as &'static dyn Trait<&'static (), &'static ()>) + .say_hello(&0); +} + +// Test for <https://github.com/rust-lang/rust/issues/135315>. +fn modulo_assoc() { + trait Supertrait<T> { + fn _print_numbers(&self, mem: &[usize; 100]) { + println!("{mem:?}"); + } + } + impl<T> Supertrait<T> for () {} + + trait Identity { + type Selff; + } + impl<Selff> Identity for Selff { + type Selff = Selff; + } + + trait Middle<T>: Supertrait<()> + Supertrait<T> { + fn say_hello(&self, _: &usize) { + println!("Hello!"); + } + } + impl<T> Middle<T> for () {} + + trait Trait: Middle<<() as Identity>::Selff> {} + impl Trait for () {} + + (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0); +} diff --git a/src/tools/miri/tests/pass/dyn-upcast.stdout b/src/tools/miri/tests/pass/dyn-upcast.stdout index edd99a114a1..379600db3d9 100644 --- a/src/tools/miri/tests/pass/dyn-upcast.stdout +++ b/src/tools/miri/tests/pass/dyn-upcast.stdout @@ -2,3 +2,5 @@ before goodbye before goodbye +Hello! +Hello! diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index a3760d306f8..3bc953c3a5f 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -129,22 +129,25 @@ fn miri_config( config.comment_defaults.base().add_custom("edition", Edition("2021".into())); if let Some(WithDependencies { bless }) = with_dependencies { - config.comment_defaults.base().set_custom("dependencies", DependencyBuilder { - program: CommandBuilder { - // Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary. - // (It's a separate crate, so we don't get an env var from cargo.) - program: miri_path() - .with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)), - // There is no `cargo miri build` so we just use `cargo miri run`. - args: ["miri", "run"].into_iter().map(Into::into).collect(), - // Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>. - envs: vec![("RUSTFLAGS".into(), None)], - ..CommandBuilder::cargo() + config.comment_defaults.base().set_custom( + "dependencies", + DependencyBuilder { + program: CommandBuilder { + // Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary. + // (It's a separate crate, so we don't get an env var from cargo.) + program: miri_path() + .with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)), + // There is no `cargo miri build` so we just use `cargo miri run`. + args: ["miri", "run"].into_iter().map(Into::into).collect(), + // Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>. + envs: vec![("RUSTFLAGS".into(), None)], + ..CommandBuilder::cargo() + }, + crate_manifest_path: Path::new("test_dependencies").join("Cargo.toml"), + build_std: None, + bless_lockfile: bless, }, - crate_manifest_path: Path::new("test_dependencies").join("Cargo.toml"), - build_std: None, - bless_lockfile: bless, - }); + ); } config } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index e83ce6dc42c..38733577d1c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -411,6 +411,7 @@ language_item_table! { PanicLocation, sym::panic_location, panic_location, Target::Struct, GenericRequirement::None; PanicImpl, sym::panic_impl, panic_impl, Target::Fn, GenericRequirement::None; PanicCannotUnwind, sym::panic_cannot_unwind, panic_cannot_unwind, Target::Fn, GenericRequirement::Exact(0); + PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, Target::Fn, GenericRequirement::None; /// libstd panic entry point. Necessary for const eval to be able to catch it BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None; diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 9bc78ff87b8..ae1c6efe0cb 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -363,6 +363,7 @@ define_symbols! { panic_location, panic_misaligned_pointer_dereference, panic_nounwind, + panic_null_pointer_dereference, panic, Param, parse, diff --git a/src/tools/rustfmt/src/bin/main.rs b/src/tools/rustfmt/src/bin/main.rs index 34984798ae6..28df49b9304 100644 --- a/src/tools/rustfmt/src/bin/main.rs +++ b/src/tools/rustfmt/src/bin/main.rs @@ -817,7 +817,6 @@ mod test { options.inline_config = HashMap::from([("version".to_owned(), "Two".to_owned())]); let config = get_config(None, Some(options)); assert_eq!(config.style_edition(), StyleEdition::Edition2024); - assert_eq!(config.overflow_delimited_expr(), true); } #[nightly_only_test] @@ -827,7 +826,6 @@ mod test { let config_file = Some(Path::new("tests/config/style-edition/just-version")); let config = get_config(config_file, Some(options)); assert_eq!(config.style_edition(), StyleEdition::Edition2024); - assert_eq!(config.overflow_delimited_expr(), true); } #[nightly_only_test] @@ -872,7 +870,6 @@ mod test { ]); let config = get_config(None, Some(options)); assert_eq!(config.style_edition(), StyleEdition::Edition2024); - assert_eq!(config.overflow_delimited_expr(), true); } #[nightly_only_test] @@ -938,7 +935,6 @@ mod test { options.style_edition = Some(StyleEdition::Edition2024); let config = get_config(None, Some(options)); assert_eq!(config.style_edition(), StyleEdition::Edition2024); - assert_eq!(config.overflow_delimited_expr(), true); } #[nightly_only_test] @@ -948,6 +944,8 @@ mod test { let config_file = Some(Path::new("tests/config/style-edition/overrides")); let config = get_config(config_file, Some(options)); assert_eq!(config.style_edition(), StyleEdition::Edition2024); + // FIXME: this test doesn't really exercise anything, since + // `overflow_delimited_expr` is disabled by default in edition 2024. assert_eq!(config.overflow_delimited_expr(), false); } @@ -959,7 +957,8 @@ mod test { options.inline_config = HashMap::from([("overflow_delimited_expr".to_owned(), "false".to_owned())]); let config = get_config(config_file, Some(options)); - assert_eq!(config.style_edition(), StyleEdition::Edition2024); + // FIXME: this test doesn't really exercise anything, since + // `overflow_delimited_expr` is disabled by default in edition 2024. assert_eq!(config.overflow_delimited_expr(), false); } } diff --git a/src/tools/rustfmt/src/config/mod.rs b/src/tools/rustfmt/src/config/mod.rs index 7355adc9f9d..6b63108c037 100644 --- a/src/tools/rustfmt/src/config/mod.rs +++ b/src/tools/rustfmt/src/config/mod.rs @@ -848,7 +848,7 @@ binop_separator = "Front" remove_nested_parens = true combine_control_expr = true short_array_element_width_threshold = 10 -overflow_delimited_expr = true +overflow_delimited_expr = false struct_field_align_threshold = 0 enum_discrim_align_threshold = 0 match_arm_blocks = true diff --git a/src/tools/rustfmt/src/config/options.rs b/src/tools/rustfmt/src/config/options.rs index bbc99a2dced..71865ec75ce 100644 --- a/src/tools/rustfmt/src/config/options.rs +++ b/src/tools/rustfmt/src/config/options.rs @@ -627,7 +627,7 @@ config_option_with_style_edition_default!( RemoveNestedParens, bool, _ => true; CombineControlExpr, bool, _ => true; ShortArrayElementWidthThreshold, usize, _ => 10; - OverflowDelimitedExpr, bool, Edition2024 => true, _ => false; + OverflowDelimitedExpr, bool, _ => false; StructFieldAlignThreshold, usize, _ => 0; EnumDiscrimAlignThreshold, usize, _ => 0; MatchArmBlocks, bool, _ => true; @@ -644,7 +644,7 @@ config_option_with_style_edition_default!( BlankLinesLowerBound, usize, _ => 0; EditionConfig, Edition, _ => Edition::Edition2015; StyleEditionConfig, StyleEdition, - Edition2024 => StyleEdition::Edition2024, _ => StyleEdition::Edition2015; + Edition2024 => StyleEdition::Edition2024, _ => StyleEdition::Edition2015; VersionConfig, Version, Edition2024 => Version::Two, _ => Version::One; InlineAttributeWidth, usize, _ => 0; FormatGeneratedFiles, bool, _ => true; diff --git a/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs b/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs index ecd2e8ca797..1b2d12ce320 100644 --- a/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs +++ b/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs @@ -25,10 +25,13 @@ fn combine_blocklike() { y: value2, }); - do_thing(x, Bar { - x: value, - y: value2, - }); + do_thing( + x, + Bar { + x: value, + y: value2, + }, + ); do_thing( x, @@ -46,12 +49,15 @@ fn combine_blocklike() { value4_with_longer_name, ]); - do_thing(x, &[ - value_with_longer_name, - value2_with_longer_name, - value3_with_longer_name, - value4_with_longer_name, - ]); + do_thing( + x, + &[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); do_thing( x, @@ -71,12 +77,15 @@ fn combine_blocklike() { value4_with_longer_name, ]); - do_thing(x, vec![ - value_with_longer_name, - value2_with_longer_name, - value3_with_longer_name, - value4_with_longer_name, - ]); + do_thing( + x, + vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); do_thing( x, @@ -99,22 +108,28 @@ fn combine_blocklike() { } fn combine_struct_sample() { - let identity = verify(&ctx, VerifyLogin { - type_: LoginType::Username, - username: args.username.clone(), - password: Some(args.password.clone()), - domain: None, - })?; + let identity = verify( + &ctx, + VerifyLogin { + type_: LoginType::Username, + username: args.username.clone(), + password: Some(args.password.clone()), + domain: None, + }, + )?; } fn combine_macro_sample() { rocket::ignite() - .mount("/", routes![ - http::auth::login, - http::auth::logout, - http::cors::options, - http::action::dance, - http::action::sleep, - ]) + .mount( + "/", + routes![ + http::auth::login, + http::auth::logout, + http::cors::options, + http::action::dance, + http::action::sleep, + ], + ) .launch(); } diff --git a/tests/codegen/addr-of-mutate.rs b/tests/codegen/addr-of-mutate.rs index f10f01274b1..14bc4b8ab28 100644 --- a/tests/codegen/addr-of-mutate.rs +++ b/tests/codegen/addr-of-mutate.rs @@ -5,7 +5,7 @@ // Test for the absence of `readonly` on the argument when it is mutated via `&raw const`. // See <https://github.com/rust-lang/rust/issues/111502>. -// CHECK: i8 @foo(ptr noalias nocapture noundef align 1 dereferenceable(128) %x) +// CHECK: i8 @foo(ptr noalias{{( nocapture)?}} noundef align 1{{( captures\(none\))?}} dereferenceable(128) %x) #[no_mangle] pub fn foo(x: [u8; 128]) -> u8 { let ptr = core::ptr::addr_of!(x).cast_mut(); @@ -15,7 +15,7 @@ pub fn foo(x: [u8; 128]) -> u8 { x[0] } -// CHECK: i1 @second(ptr noalias nocapture noundef align {{[0-9]+}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) +// CHECK: i1 @second(ptr noalias{{( nocapture)?}} noundef align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) #[no_mangle] pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut(); @@ -24,7 +24,7 @@ pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { } // If going through a deref (and there are no other mutating accesses), then `readonly` is fine. -// CHECK: i1 @third(ptr noalias nocapture noundef readonly align {{[0-9]+}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) +// CHECK: i1 @third(ptr noalias{{( nocapture)?}} noundef readonly align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) #[no_mangle] pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut(); diff --git a/tests/codegen/asm/bpf-clobbers.rs b/tests/codegen/asm/bpf-clobbers.rs new file mode 100644 index 00000000000..1117549b1ec --- /dev/null +++ b/tests/codegen/asm/bpf-clobbers.rs @@ -0,0 +1,31 @@ +//@ add-core-stubs +//@ compile-flags: --target bpfel-unknown-none +//@ needs-llvm-components: bpf + +#![crate_type = "rlib"] +#![feature(no_core, asm_experimental_arch)] +#![no_core] + +extern crate minicore; +use minicore::*; + +// CHECK-LABEL: @flags_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn flags_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// CHECK: asm sideeffect "", "={r0},={r1},={r2},={r3},={r4},={r5}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs index db76aae3dd0..b3a35cbf3b1 100644 --- a/tests/codegen/cast-target-abi.rs +++ b/tests/codegen/cast-target-abi.rs @@ -392,7 +392,7 @@ pub fn call_fiveu16s() { } // CHECK-LABEL: @return_fiveu16s -// CHECK-SAME: (ptr {{.+}} sret([10 x i8]) align [[RUST_ALIGN:2]] dereferenceable(10) [[RET_PTR:%.+]]) +// CHECK-SAME: (ptr {{.+}} sret([10 x i8]) align [[RUST_ALIGN:2]] {{.*}}dereferenceable(10) [[RET_PTR:%.+]]) #[no_mangle] pub fn return_fiveu16s() -> FiveU16s { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs index 503799d3ed2..1a211dfe096 100644 --- a/tests/codegen/function-arguments.rs +++ b/tests/codegen/function-arguments.rs @@ -135,7 +135,7 @@ pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {} #[no_mangle] pub fn notunpin_borrow(_: &NotUnpin) {} -// CHECK: @indirect_struct(ptr noalias nocapture noundef readonly align 4 dereferenceable(32) %_1) +// CHECK: @indirect_struct(ptr noalias{{( nocapture)?}} noundef readonly align 4{{( captures\(none\))?}} dereferenceable(32) %_1) #[no_mangle] pub fn indirect_struct(_: S) {} @@ -198,7 +198,7 @@ pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> { x } -// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias nocapture noundef{{( writable)?}} sret([32 x i8]) align 4 dereferenceable(32){{( %_0)?}}) +// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([32 x i8]) align 4{{( captures\(none\))?}} dereferenceable(32){{( %_0)?}}) #[no_mangle] pub fn struct_return() -> S { S { _field: [0, 0, 0, 0, 0, 0, 0, 0] } diff --git a/tests/codegen/i128-x86-align.rs b/tests/codegen/i128-x86-align.rs index 6b1da445c40..ac101b72513 100644 --- a/tests/codegen/i128-x86-align.rs +++ b/tests/codegen/i128-x86-align.rs @@ -19,8 +19,10 @@ pub struct ScalarPair { #[no_mangle] pub fn load(x: &ScalarPair) -> ScalarPair { // CHECK-LABEL: @load( - // CHECK-SAME: sret([32 x i8]) align 16 dereferenceable(32) %_0, - // CHECK-SAME: align 16 dereferenceable(32) %x + // CHECK-SAME: sret([32 x i8]) align 16 + // CHECK-SAME: dereferenceable(32) %_0, + // CHECK-SAME: align 16 + // CHECK-SAME: dereferenceable(32) %x // CHECK: [[A:%.*]] = load i32, ptr %x, align 16 // CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr %x, i64 16 // CHECK-NEXT: [[B:%.*]] = load i128, ptr [[GEP]], align 16 @@ -34,7 +36,8 @@ pub fn load(x: &ScalarPair) -> ScalarPair { #[no_mangle] pub fn store(x: &mut ScalarPair) { // CHECK-LABEL: @store( - // CHECK-SAME: align 16 dereferenceable(32) %x + // CHECK-SAME: align 16 + // CHECK-SAME: dereferenceable(32) %x // CHECK: store i32 1, ptr %x, align 16 // CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr %x, i64 16 // CHECK-NEXT: store i128 2, ptr [[GEP]], align 16 @@ -55,8 +58,10 @@ pub fn alloca() { #[no_mangle] pub fn load_volatile(x: &ScalarPair) -> ScalarPair { // CHECK-LABEL: @load_volatile( - // CHECK-SAME: sret([32 x i8]) align 16 dereferenceable(32) %_0, - // CHECK-SAME: align 16 dereferenceable(32) %x + // CHECK-SAME: sret([32 x i8]) align 16 + // CHECK-SAME: dereferenceable(32) %_0, + // CHECK-SAME: align 16 + // CHECK-SAME: dereferenceable(32) %x // CHECK: [[LOAD:%.*]] = load volatile %ScalarPair, ptr %x, align 16 // CHECK-NEXT: store %ScalarPair [[LOAD]], ptr %_0, align 16 // CHECK-NEXT: ret void @@ -66,7 +71,8 @@ pub fn load_volatile(x: &ScalarPair) -> ScalarPair { #[no_mangle] pub fn transmute(x: ScalarPair) -> (std::mem::MaybeUninit<i128>, i128) { // CHECK-LABEL: @transmute( - // CHECK-SAME: sret([32 x i8]) align 16 dereferenceable(32) %_0, + // CHECK-SAME: sret([32 x i8]) align 16 + // CHECK-SAME: dereferenceable(32) %_0, // CHECK-SAME: i32 noundef %x.0, i128 noundef %x.1 // CHECK: store i32 %x.0, ptr %_0, align 16 // CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr %_0, i64 16 @@ -86,7 +92,8 @@ pub struct Struct { #[no_mangle] pub fn store_struct(x: &mut Struct) { // CHECK-LABEL: @store_struct( - // CHECK-SAME: align 16 dereferenceable(32) %x + // CHECK-SAME: align 16 + // CHECK-SAME: dereferenceable(32) %x // CHECK: [[TMP:%.*]] = alloca [32 x i8], align 16 // CHECK: store i32 1, ptr [[TMP]], align 16 // CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[TMP]], i64 4 diff --git a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs index cba1a980caa..b147d01b38e 100644 --- a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs +++ b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs @@ -259,11 +259,11 @@ pub struct IntDoubleInt { c: i32, } -// CHECK: define void @f_int_double_int_s_arg(ptr noalias nocapture noundef align 8 dereferenceable(24) %a) +// CHECK: define void @f_int_double_int_s_arg(ptr noalias{{( nocapture)?}} noundef align 8{{( captures\(none\))?}} dereferenceable(24) %a) #[no_mangle] pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {} -// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias nocapture noundef{{( writable)?}} sret([24 x i8]) align 8 dereferenceable(24) %_0) +// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([24 x i8]) align 8{{( captures\(none\))?}} dereferenceable(24) %_0) #[no_mangle] pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt { IntDoubleInt { a: 1, b: 2., c: 3 } diff --git a/tests/codegen/packed.rs b/tests/codegen/packed.rs index 790d618b2ea..66df978d48c 100644 --- a/tests/codegen/packed.rs +++ b/tests/codegen/packed.rs @@ -52,7 +52,7 @@ pub struct BigPacked2 { #[no_mangle] pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 { // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8] - // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) + // CHECK: call void %{{.*}}(ptr{{( captures(none))?}} noalias{{( nocapture)?}} noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) // check that calls whose destination is a field of a packed struct // go through an alloca rather than calling the function with an @@ -64,7 +64,7 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 { #[no_mangle] pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 { // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8] - // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) + // CHECK: call void %{{.*}}(ptr{{( captures(none))?}} noalias{{( nocapture)?}} noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) // check that calls whose destination is a field of a packed struct // go through an alloca rather than calling the function with an diff --git a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs index bcd9b0eae71..c14d5c01450 100644 --- a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs +++ b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs @@ -263,7 +263,7 @@ pub struct IntDoubleInt { #[no_mangle] pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {} -// CHECK: define void @f_ret_int_double_int_s(ptr {{.*}} sret([24 x i8]) align 8 dereferenceable(24) %_0) +// CHECK: define void @f_ret_int_double_int_s(ptr {{.*}} sret([24 x i8]) align 8 {{.*}}dereferenceable(24) %_0) #[no_mangle] pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt { IntDoubleInt { a: 1, b: 2., c: 3 } diff --git a/tests/mir-opt/null_check_references.rs b/tests/mir-opt/null_check_references.rs new file mode 100644 index 00000000000..85f98865646 --- /dev/null +++ b/tests/mir-opt/null_check_references.rs @@ -0,0 +1,16 @@ +//@ compile-flags: -C debug-assertions + +struct Null { + a: u32, +} + +fn main() { + // CHECK-LABEL: fn main( + // CHECK-NOT: {{assert.*}} + let val: u32 = 42; + let val_ref: &u32 = &val; + let _access1: &u32 = &*val_ref; + + let val = Null { a: 42 }; + let _access2: &u32 = &val.a; +} diff --git a/tests/rustdoc-ui/coverage/html.stderr b/tests/rustdoc-ui/coverage/html.stderr index adca375d4bc..764179820c5 100644 --- a/tests/rustdoc-ui/coverage/html.stderr +++ b/tests/rustdoc-ui/coverage/html.stderr @@ -1,2 +1,2 @@ -error: html output format isn't supported for the --show-coverage option +error: `--output-format=html` is not supported for the `--show-coverage` option diff --git a/tests/rustdoc-ui/doctest-output.rs b/tests/rustdoc-ui/doctest-output.rs new file mode 100644 index 00000000000..720f2952980 --- /dev/null +++ b/tests/rustdoc-ui/doctest-output.rs @@ -0,0 +1 @@ +//@ compile-flags:-Z unstable-options --show-coverage --output-format=doctest diff --git a/tests/rustdoc-ui/doctest-output.stderr b/tests/rustdoc-ui/doctest-output.stderr new file mode 100644 index 00000000000..20c618dc61b --- /dev/null +++ b/tests/rustdoc-ui/doctest-output.stderr @@ -0,0 +1,2 @@ +error: `--output-format=doctest` is not supported for the `--show-coverage` option + diff --git a/tests/rustdoc-ui/extract-doctests.rs b/tests/rustdoc-ui/extract-doctests.rs new file mode 100644 index 00000000000..06bd35969d0 --- /dev/null +++ b/tests/rustdoc-ui/extract-doctests.rs @@ -0,0 +1,15 @@ +// Test to ensure that it generates expected output for `--output-format=doctest` command-line +// flag. + +//@ compile-flags:-Z unstable-options --output-format=doctest +//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ check-pass + +//! ```ignore (checking attributes) +//! let x = 12; +//! let y = 14; +//! ``` +//! +//! ```edition2018,compile_fail +//! let +//! ``` diff --git a/tests/rustdoc-ui/extract-doctests.stdout b/tests/rustdoc-ui/extract-doctests.stdout new file mode 100644 index 00000000000..fa8604cae94 --- /dev/null +++ b/tests/rustdoc-ui/extract-doctests.stdout @@ -0,0 +1 @@ +{"format_version":1,"doctests":[{"file":"$DIR/extract-doctests.rs","line":8,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":"#![allow(unused)]\nfn main() {\nlet x = 12;\nlet y = 14;\n}","name":"$DIR/extract-doctests.rs - (line 8)"},{"file":"$DIR/extract-doctests.rs","line":13,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":"#![allow(unused)]\nfn main() {\nlet\n}","name":"$DIR/extract-doctests.rs - (line 13)"}]} \ No newline at end of file diff --git a/tests/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs b/tests/rustdoc-ui/intra-doc/auxiliary/issue-103463-aux.rs index 2b8fdec1f12..2b8fdec1f12 100644 --- a/tests/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs +++ b/tests/rustdoc-ui/intra-doc/auxiliary/issue-103463-aux.rs diff --git a/tests/rustdoc/intra-doc/issue-104145.rs b/tests/rustdoc-ui/intra-doc/ice-extern-trait-local-impl-104145.rs index 5690803af5a..0e403b21c8a 100644 --- a/tests/rustdoc/intra-doc/issue-104145.rs +++ b/tests/rustdoc-ui/intra-doc/ice-extern-trait-local-impl-104145.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/104145 +//@ check-pass + // Doc links in `Trait`'s methods are resolved because it has a local impl. //@ aux-build:issue-103463-aux.rs diff --git a/tests/rustdoc/intra-doc/issue-103463.rs b/tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs index 9b5cb67fd32..10894282e55 100644 --- a/tests/rustdoc/intra-doc/issue-103463.rs +++ b/tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/103463 +//@ check-pass + // The `Trait` is not pulled into the crate resulting in doc links in its methods being resolved. //@ aux-build:issue-103463-aux.rs diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr index 180ba63927b..2c25589a553 100644 --- a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr @@ -99,7 +99,7 @@ LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/invalid_const_in_lifetime_position.rs:2:10 | LL | trait X { diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr index 72d1a52f710..1e52b699820 100644 --- a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr +++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr @@ -301,7 +301,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/ice-generic-type-alias-105742.rs:15:17 | LL | pub trait SVec: Index< diff --git a/tests/rustdoc/inline_cross/issue-28480.rs b/tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs index 004510fd922..e1ca7403c03 100644 --- a/tests/rustdoc/inline_cross/issue-28480.rs +++ b/tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/28480 +#![crate_name="foobar"] + //@ aux-build:rustdoc-hidden-sig.rs //@ build-aux-docs //@ ignore-cross-compile @@ -7,7 +10,7 @@ //@ has - '//a' 'u8' extern crate rustdoc_hidden_sig; -//@ has issue_28480/struct.Bar.html +//@ has foobar/struct.Bar.html //@ !has - '//a/@title' 'Hidden' //@ has - '//a' 'u8' pub use rustdoc_hidden_sig::Bar; diff --git a/tests/rustdoc/inline_cross/issue-31948-1.rs b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs index e59da87c29d..baab1da9547 100644 --- a/tests/rustdoc/inline_cross/issue-31948-1.rs +++ b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs @@ -1,27 +1,30 @@ +// https://github.com/rust-lang/rust/issues/31948 +#![crate_name="foobar"] + //@ aux-build:rustdoc-nonreachable-impls.rs //@ build-aux-docs //@ ignore-cross-compile extern crate rustdoc_nonreachable_impls; -//@ has issue_31948_1/struct.Wobble.html +//@ has foobar/struct.Wobble.html //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for' //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for' pub use rustdoc_nonreachable_impls::hidden::Wobble; -//@ has issue_31948_1/trait.Bark.html +//@ has foobar/trait.Bark.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ has - '//h3[@class="code-header"]' 'for Wobble' //@ !has - '//h3[@class="code-header"]' 'for Wibble' pub use rustdoc_nonreachable_impls::Bark; -//@ has issue_31948_1/trait.Woof.html +//@ has foobar/trait.Woof.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ has - '//h3[@class="code-header"]' 'for Wobble' //@ !has - '//h3[@class="code-header"]' 'for Wibble' pub use rustdoc_nonreachable_impls::Woof; -//@ !has issue_31948_1/trait.Bar.html -//@ !has issue_31948_1/trait.Qux.html +//@ !has foobar/trait.Bar.html +//@ !has foobar/trait.Qux.html diff --git a/tests/rustdoc/inline_cross/issue-31948-2.rs b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs index 34b57052883..40e9108ec62 100644 --- a/tests/rustdoc/inline_cross/issue-31948-2.rs +++ b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs @@ -1,21 +1,24 @@ +// https://github.com/rust-lang/rust/issues/31948 +#![crate_name="foobar"] + //@ aux-build:rustdoc-nonreachable-impls.rs //@ build-aux-docs //@ ignore-cross-compile extern crate rustdoc_nonreachable_impls; -//@ has issue_31948_2/struct.Wobble.html +//@ has foobar/struct.Wobble.html //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for' //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for' //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for' pub use rustdoc_nonreachable_impls::hidden::Wobble; -//@ has issue_31948_2/trait.Qux.html +//@ has foobar/trait.Qux.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ has - '//h3[@class="code-header"]' 'for Wobble' pub use rustdoc_nonreachable_impls::hidden::Qux; -//@ !has issue_31948_2/trait.Bar.html -//@ !has issue_31948_2/trait.Woof.html -//@ !has issue_31948_2/trait.Bark.html +//@ !has foobar/trait.Bar.html +//@ !has foobar/trait.Woof.html +//@ !has foobar/trait.Bark.html diff --git a/tests/rustdoc/inline_cross/issue-31948.rs b/tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs index 7a43fc7b279..ab0048513c7 100644 --- a/tests/rustdoc/inline_cross/issue-31948.rs +++ b/tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs @@ -1,29 +1,32 @@ +// https://github.com/rust-lang/rust/issues/31948 +#![crate_name="foobar"] + //@ aux-build:rustdoc-nonreachable-impls.rs //@ build-aux-docs //@ ignore-cross-compile extern crate rustdoc_nonreachable_impls; -//@ has issue_31948/struct.Foo.html +//@ has foobar/struct.Foo.html //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for' //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for' pub use rustdoc_nonreachable_impls::Foo; -//@ has issue_31948/trait.Bark.html +//@ has foobar/trait.Bark.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ !has - '//h3[@class="code-header"]' 'for Wibble' //@ !has - '//h3[@class="code-header"]' 'for Wobble' pub use rustdoc_nonreachable_impls::Bark; -//@ has issue_31948/trait.Woof.html +//@ has foobar/trait.Woof.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ !has - '//h3[@class="code-header"]' 'for Wibble' //@ !has - '//h3[@class="code-header"]' 'for Wobble' pub use rustdoc_nonreachable_impls::Woof; -//@ !has issue_31948/trait.Bar.html -//@ !has issue_31948/trait.Qux.html -//@ !has issue_31948/struct.Wibble.html -//@ !has issue_31948/struct.Wobble.html +//@ !has foobar/trait.Bar.html +//@ !has foobar/trait.Qux.html +//@ !has foobar/struct.Wibble.html +//@ !has foobar/struct.Wobble.html diff --git a/tests/rustdoc/inline_cross/issue-32881.rs b/tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs index d4ebf10a1ca..f7dc7414455 100644 --- a/tests/rustdoc/inline_cross/issue-32881.rs +++ b/tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs @@ -1,10 +1,13 @@ +// https://github.com/rust-lang/rust/issues/32881 +#![crate_name="foobar"] + //@ aux-build:rustdoc-trait-object-impl.rs //@ build-aux-docs //@ ignore-cross-compile extern crate rustdoc_trait_object_impl; -//@ has issue_32881/trait.Bar.html +//@ has foobar/trait.Bar.html //@ has - '//h3[@class="code-header"]' "impl<'a> dyn Bar" //@ has - '//h3[@class="code-header"]' "impl<'a> Debug for dyn Bar" diff --git a/tests/rustdoc/inline_cross/issue-33113.rs b/tests/rustdoc/inline_cross/impl-ref-33113.rs index 05e87d962cb..9ac4f02e00c 100644 --- a/tests/rustdoc/inline_cross/issue-33113.rs +++ b/tests/rustdoc/inline_cross/impl-ref-33113.rs @@ -1,10 +1,13 @@ +// https://github.com/rust-lang/rust/issues/33113 +#![crate_name="foobar"] + //@ aux-build:issue-33113.rs //@ build-aux-docs //@ ignore-cross-compile extern crate bar; -//@ has issue_33113/trait.Bar.html +//@ has foobar/trait.Bar.html //@ has - '//h3[@class="code-header"]' "for &'a char" //@ has - '//h3[@class="code-header"]' "for Foo" pub use bar::Bar; diff --git a/tests/rustdoc/inline_cross/issue-76736-1.rs b/tests/rustdoc/inline_cross/rustc-private-76736-1.rs index fe52702fd6f..3ffa5e6cc06 100644 --- a/tests/rustdoc/inline_cross/issue-76736-1.rs +++ b/tests/rustdoc/inline_cross/rustc-private-76736-1.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/76736 + //@ aux-build:issue-76736-1.rs //@ aux-build:issue-76736-2.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-2.rs b/tests/rustdoc/inline_cross/rustc-private-76736-2.rs index df376ebe9a1..843b2941602 100644 --- a/tests/rustdoc/inline_cross/issue-76736-2.rs +++ b/tests/rustdoc/inline_cross/rustc-private-76736-2.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/76736 + //@ aux-build:issue-76736-1.rs //@ aux-build:issue-76736-2.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-3.rs b/tests/rustdoc/inline_cross/rustc-private-76736-3.rs index 1bed4621c04..f9b46caa02f 100644 --- a/tests/rustdoc/inline_cross/issue-76736-3.rs +++ b/tests/rustdoc/inline_cross/rustc-private-76736-3.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/76736 + //@ compile-flags: -Zforce-unstable-if-unmarked //@ aux-build:issue-76736-1.rs //@ aux-build:issue-76736-2.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-4.rs b/tests/rustdoc/inline_cross/rustc-private-76736-4.rs index 487e9030108..511464f2c49 100644 --- a/tests/rustdoc/inline_cross/issue-76736-4.rs +++ b/tests/rustdoc/inline_cross/rustc-private-76736-4.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/76736 + //@ aux-build:issue-76736-1.rs //@ aux-build:issue-76736-2.rs diff --git a/tests/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html b/tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html index f3c1c045202..f3c1c045202 100644 --- a/tests/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html +++ b/tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html diff --git a/tests/rustdoc/inline_cross/issue-24183.rs b/tests/rustdoc/inline_cross/self-sized-bounds-24183.rs index 8299eecc575..909005532f5 100644 --- a/tests/rustdoc/inline_cross/issue-24183.rs +++ b/tests/rustdoc/inline_cross/self-sized-bounds-24183.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/24183 #![crate_type = "lib"] #![crate_name = "usr"] diff --git a/tests/rustdoc/inline_local/issue-32343.rs b/tests/rustdoc/inline_local/doc-no-inline-32343.rs index 2ec123fdc5c..ed11614a500 100644 --- a/tests/rustdoc/inline_local/issue-32343.rs +++ b/tests/rustdoc/inline_local/doc-no-inline-32343.rs @@ -1,12 +1,15 @@ -//@ !has issue_32343/struct.Foo.html -//@ has issue_32343/index.html +// https://github.com/rust-lang/rust/issues/32343 +#![crate_name="foobar"] + +//@ !has foobar/struct.Foo.html +//@ has foobar/index.html //@ has - '//code' 'pub use foo::Foo' //@ !has - '//code/a' 'Foo' #[doc(no_inline)] pub use foo::Foo; -//@ !has issue_32343/struct.Bar.html -//@ has issue_32343/index.html +//@ !has foobar/struct.Bar.html +//@ has foobar/index.html //@ has - '//code' 'pub use foo::Bar' //@ has - '//code/a' 'Bar' #[doc(no_inline)] @@ -18,6 +21,6 @@ mod foo { } pub mod bar { - //@ has issue_32343/bar/struct.Bar.html + //@ has foobar/bar/struct.Bar.html pub use ::foo::Bar; } diff --git a/tests/rustdoc/inline_local/issue-28537.rs b/tests/rustdoc/inline_local/pub-re-export-28537.rs index d5ba94d2e6c..0e9836c7cee 100644 --- a/tests/rustdoc/inline_local/issue-28537.rs +++ b/tests/rustdoc/inline_local/pub-re-export-28537.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/28537 +#![crate_name="foo"] + #[doc(hidden)] pub mod foo { pub struct Foo; @@ -10,8 +13,8 @@ mod bar { } } -//@ has issue_28537/struct.Foo.html +//@ has foo/struct.Foo.html pub use foo::Foo; -//@ has issue_28537/struct.Bar.html +//@ has foo/struct.Bar.html pub use self::bar::Bar; diff --git a/tests/rustdoc/intra-doc/issue-82209.rs b/tests/rustdoc/intra-doc/enum-self-82209.rs index 46d028e535c..615115a5f8b 100644 --- a/tests/rustdoc/intra-doc/issue-82209.rs +++ b/tests/rustdoc/intra-doc/enum-self-82209.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/82209 + #![crate_name = "foo"] #![deny(rustdoc::broken_intra_doc_links)] pub enum Foo { diff --git a/tests/rustdoc/intra-doc/issue-108459.rs b/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs index 18424c069d3..0b339eaf6b2 100644 --- a/tests/rustdoc/intra-doc/issue-108459.rs +++ b/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/pull/108459 +#![crate_name="foobar"] + #![deny(rustdoc::broken_intra_doc_links)] #![allow(rustdoc::redundant_explicit_links)] @@ -13,13 +16,13 @@ pub struct MyStruct1; // the same target but different text /// See also [crate::char] and [mod@char] and [prim@char] -//@ has issue_108459/struct.MyStruct2.html '//*[@href="char/index.html"]' 'crate::char' +//@ has foobar/struct.MyStruct2.html '//*[@href="char/index.html"]' 'crate::char' //@ has - '//*[@href="char/index.html"]' 'char' //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char' pub struct MyStruct2; /// See also [mod@char] and [prim@char] and [crate::char] -//@ has issue_108459/struct.MyStruct3.html '//*[@href="char/index.html"]' 'crate::char' +//@ has foobar/struct.MyStruct3.html '//*[@href="char/index.html"]' 'crate::char' //@ has - '//*[@href="char/index.html"]' 'char' //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char' pub struct MyStruct3; @@ -28,11 +31,11 @@ pub struct MyStruct3; // different targets /// See also [char][mod@char] and [char][prim@char] -//@ has issue_108459/struct.MyStruct4.html '//*[@href="char/index.html"]' 'char' +//@ has foobar/struct.MyStruct4.html '//*[@href="char/index.html"]' 'char' //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char' pub struct MyStruct4; /// See also [char][prim@char] and [char][crate::char] -//@ has issue_108459/struct.MyStruct5.html '//*[@href="char/index.html"]' 'char' +//@ has foobar/struct.MyStruct5.html '//*[@href="char/index.html"]' 'char' //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char' pub struct MyStruct5; diff --git a/tests/rustdoc/intra-doc/issue-66159.rs b/tests/rustdoc/intra-doc/same-name-different-crates-66159.rs index 5d50f63f299..7e3ace9355a 100644 --- a/tests/rustdoc/intra-doc/issue-66159.rs +++ b/tests/rustdoc/intra-doc/same-name-different-crates-66159.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/66159 +#![crate_name="foobar"] + //@ aux-crate:priv:pub_struct=pub-struct.rs //@ compile-flags:-Z unstable-options @@ -6,5 +9,5 @@ // Since we don't generate the docs for the auxiliary files, we can't actually // verify that the struct is linked correctly. -//@ has issue_66159/index.html +//@ has foobar/index.html //! [pub_struct::SomeStruct] diff --git a/tests/ui/abi/segfault-no-out-of-stack.rs b/tests/ui/abi/segfault-no-out-of-stack.rs index b5af13ebfb5..5e8b4e0dbf2 100644 --- a/tests/ui/abi/segfault-no-out-of-stack.rs +++ b/tests/ui/abi/segfault-no-out-of-stack.rs @@ -1,5 +1,6 @@ //@ run-pass //@ needs-subprocess +//@ compile-flags: -Zub-checks=no -Zmir-enable-passes=-CheckNull //@ ignore-fuchsia must translate zircon signal to SIGSEGV/SIGBUS, FIXME (#58590) #![feature(rustc_private)] diff --git a/tests/ui/associated-consts/associated-const-in-trait.stderr b/tests/ui/associated-consts/associated-const-in-trait.stderr index 107ceeaf113..5aaa6f6be05 100644 --- a/tests/ui/associated-consts/associated-const-in-trait.stderr +++ b/tests/ui/associated-consts/associated-const-in-trait.stderr @@ -5,7 +5,7 @@ LL | impl dyn Trait { | ^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/associated-const-in-trait.rs:4:11 | LL | trait Trait { @@ -21,7 +21,7 @@ LL | const fn n() -> usize { Self::N } | ^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/associated-const-in-trait.rs:4:11 | LL | trait Trait { diff --git a/tests/ui/associated-item/issue-48027.stderr b/tests/ui/associated-item/issue-48027.stderr index 1baaefd7720..513961e2bd0 100644 --- a/tests/ui/associated-item/issue-48027.stderr +++ b/tests/ui/associated-item/issue-48027.stderr @@ -5,7 +5,7 @@ LL | impl dyn Bar {} | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-48027.rs:2:11 | LL | trait Bar { diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr index f9d2a669477..7d5b37bdbe7 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.stderr +++ b/tests/ui/async-await/async-fn/dyn-pos.stderr @@ -5,7 +5,7 @@ LL | fn foo(x: &dyn AsyncFn()) {} | ^^^^^^^^^ `AsyncFnMut` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL | = note: the trait is not dyn compatible because it contains the generic associated type `CallRefFuture` diff --git a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr index b60f6a08338..f478d55d10e 100644 --- a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr +++ b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr @@ -21,18 +21,14 @@ LL | true found type `bool` error[E0271]: expected `{closure@dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10}` to be a closure that returns `bool`, but it returns `Option<()>` - --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10 + --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:6:16 | -LL | call(|| -> Option<()> { - | _____----_^ - | | | - | | required by a bound introduced by this call -LL | | -LL | | if true { -LL | | false -... | -LL | | }) - | |_____^ expected `bool`, found `Option<()>` +LL | call(|| -> Option<()> { + | ---- ------^^^^^^^^^^ + | | | | + | | | expected `bool`, found `Option<()>` + | | this closure + | required by a bound introduced by this call | = note: expected type `bool` found enum `Option<()>` diff --git a/tests/ui/async-await/in-trait/dyn-compatibility.stderr b/tests/ui/async-await/in-trait/dyn-compatibility.stderr index c6c406902f6..553bcbf89d5 100644 --- a/tests/ui/async-await/in-trait/dyn-compatibility.stderr +++ b/tests/ui/async-await/in-trait/dyn-compatibility.stderr @@ -5,7 +5,7 @@ LL | let x: &dyn Foo = todo!(); | ^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-compatibility.rs:5:14 | LL | trait Foo { diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr index a674fc0f3a5..1fccc32470f 100644 --- a/tests/ui/async-await/inference_var_self_argument.stderr +++ b/tests/ui/async-await/inference_var_self_argument.stderr @@ -14,7 +14,7 @@ LL | async fn foo(self: &dyn Foo) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/inference_var_self_argument.rs:5:14 | LL | trait Foo { diff --git a/tests/ui/closures/return-type-doesnt-match-bound.rs b/tests/ui/closures/return-type-doesnt-match-bound.rs new file mode 100644 index 00000000000..f9098d0cb5c --- /dev/null +++ b/tests/ui/closures/return-type-doesnt-match-bound.rs @@ -0,0 +1,25 @@ +use std::error::Error; +use std::process::exit; + +fn foo<F>(f: F) -> () +where + F: FnOnce() -> Result<(), Box<dyn Error>>, +{ + f().or_else(|e| -> ! { //~ ERROR to be a closure that returns + eprintln!("{:?}", e); + exit(1) + }); +} + +fn bar<F>(f: F) -> () +where + F: FnOnce() -> Result<(), Box<dyn Error>>, +{ + let c = |e| -> ! { //~ ERROR to be a closure that returns + eprintln!("{:?}", e); + exit(1) + }; + f().or_else(c); +} + +fn main() {} diff --git a/tests/ui/closures/return-type-doesnt-match-bound.stderr b/tests/ui/closures/return-type-doesnt-match-bound.stderr new file mode 100644 index 00000000000..f796a5552ac --- /dev/null +++ b/tests/ui/closures/return-type-doesnt-match-bound.stderr @@ -0,0 +1,37 @@ +error[E0271]: expected `{closure@return-type-doesnt-match-bound.rs:8:17}` to be a closure that returns `Result<(), _>`, but it returns `!` + --> $DIR/return-type-doesnt-match-bound.rs:8:24 + | +LL | f().or_else(|e| -> ! { + | ------- -------^ + | | | | + | | | expected `Result<(), _>`, found `!` + | | this closure + | required by a bound introduced by this call + | + = note: expected enum `Result<(), _>` + found type `!` +note: required by a bound in `Result::<T, E>::or_else` + --> $SRC_DIR/core/src/result.rs:LL:COL + +error[E0271]: expected `{closure@return-type-doesnt-match-bound.rs:18:13}` to be a closure that returns `Result<(), _>`, but it returns `!` + --> $DIR/return-type-doesnt-match-bound.rs:18:20 + | +LL | let c = |e| -> ! { + | -------^ + | | | + | | expected `Result<(), _>`, found `!` + | this closure +... +LL | f().or_else(c); + | ------- - closure used here + | | + | required by a bound introduced by this call + | + = note: expected enum `Result<(), _>` + found type `!` +note: required by a bound in `Result::<T, E>::or_else` + --> $SRC_DIR/core/src/result.rs:LL:COL + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/coherence/coherence-impl-trait-for-trait-dyn-compatible.stderr b/tests/ui/coherence/coherence-impl-trait-for-trait-dyn-compatible.stderr index 20257bbaf28..033bfee226f 100644 --- a/tests/ui/coherence/coherence-impl-trait-for-trait-dyn-compatible.stderr +++ b/tests/ui/coherence/coherence-impl-trait-for-trait-dyn-compatible.stderr @@ -5,7 +5,7 @@ LL | impl DynIncompatible for dyn DynIncompatible { } | ^^^^^^^^^^^^^^^^^^^ `DynIncompatible` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/coherence-impl-trait-for-trait-dyn-compatible.rs:6:45 | LL | trait DynIncompatible { fn eq(&self, other: Self); } diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr index cd7f3a3c21d..6fa9b591ad2 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr @@ -5,7 +5,7 @@ LL | fn foo(a: &dyn ConstParamTy_) {} | ^^^^^^^^^^^^^ `ConstParamTy_` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: the trait is not dyn compatible because it uses `Self` as a type parameter @@ -21,7 +21,7 @@ LL | fn bar(a: &dyn UnsizedConstParamTy) {} | ^^^^^^^^^^^^^^^^^^^ `UnsizedConstParamTy` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: the trait is not dyn compatible because it uses `Self` as a type parameter diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr index 763bc626c9d..8bc6ef093d0 100644 --- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr @@ -5,7 +5,7 @@ LL | fn use_dyn(v: &dyn Foo) { | ^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-compatibility-err-ret.rs:8:8 | LL | trait Foo { @@ -24,7 +24,7 @@ LL | v.test(); | ^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-compatibility-err-ret.rs:8:8 | LL | trait Foo { diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr index 56678e4e9af..f5eaaa37916 100644 --- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr @@ -5,7 +5,7 @@ LL | fn use_dyn(v: &dyn Foo) { | ^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-compatibility-err-where-bounds.rs:8:8 | LL | trait Foo { @@ -22,7 +22,7 @@ LL | v.test(); | ^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-compatibility-err-where-bounds.rs:8:8 | LL | trait Foo { diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr index bd1811bd2cc..57b61006631 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr @@ -99,7 +99,7 @@ LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-102768.rs:5:10 | LL | trait X { diff --git a/tests/ui/consts/const-slice-array-deref.rs b/tests/ui/consts/const-slice-array-deref.rs new file mode 100644 index 00000000000..9d84ed4bdb0 --- /dev/null +++ b/tests/ui/consts/const-slice-array-deref.rs @@ -0,0 +1,9 @@ +const ONE: [u16] = [1]; +//~^ ERROR the size for values of type `[u16]` cannot be known at compilation time +//~| ERROR the size for values of type `[u16]` cannot be known at compilation time +//~| ERROR mismatched types + +const TWO: &'static u16 = &ONE[0]; +//~^ ERROR cannot move a value of type `[u16]` + +fn main() {} diff --git a/tests/ui/consts/const-slice-array-deref.stderr b/tests/ui/consts/const-slice-array-deref.stderr new file mode 100644 index 00000000000..6e69744144e --- /dev/null +++ b/tests/ui/consts/const-slice-array-deref.stderr @@ -0,0 +1,33 @@ +error[E0277]: the size for values of type `[u16]` cannot be known at compilation time + --> $DIR/const-slice-array-deref.rs:1:12 + | +LL | const ONE: [u16] = [1]; + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u16]` + +error[E0308]: mismatched types + --> $DIR/const-slice-array-deref.rs:1:20 + | +LL | const ONE: [u16] = [1]; + | ^^^ expected `[u16]`, found `[u16; 1]` + +error[E0277]: the size for values of type `[u16]` cannot be known at compilation time + --> $DIR/const-slice-array-deref.rs:1:20 + | +LL | const ONE: [u16] = [1]; + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u16]` + = note: constant expressions must have a statically known size + +error[E0161]: cannot move a value of type `[u16]` + --> $DIR/const-slice-array-deref.rs:6:28 + | +LL | const TWO: &'static u16 = &ONE[0]; + | ^^^ the size of `[u16]` cannot be statically determined + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0161, E0277, E0308. +For more information about an error, try `rustc --explain E0161`. diff --git a/tests/ui/diagnostic-width/long-E0308.ascii.stderr b/tests/ui/diagnostic-width/long-E0308.ascii.stderr index d45d6bf329b..3053e37a87a 100644 --- a/tests/ui/diagnostic-width/long-E0308.ascii.stderr +++ b/tests/ui/diagnostic-width/long-E0308.ascii.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/long-E0308.rs:46:9 + --> $DIR/long-E0308.rs:48:9 | LL | let x: Atype< | _____________- @@ -20,11 +20,11 @@ LL | | )))))))))))))))))))))))))))))); | = note: expected struct `Atype<Btype<..., ...>, ...>` found enum `Result<Result<..., ...>, ...>` - = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.ascii/long-E0308.long-type-hash.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - --> $DIR/long-E0308.rs:59:26 + --> $DIR/long-E0308.rs:61:26 | LL | ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O... | __________________________^ @@ -36,11 +36,11 @@ LL | | )))))))))))))))))))))))); | = note: expected enum `Option<Result<..., ...>>` found enum `Result<Result<..., ...>, ...>` - = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.ascii/long-E0308.long-type-hash.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - --> $DIR/long-E0308.rs:90:9 + --> $DIR/long-E0308.rs:92:9 | LL | let x: Atype< | ____________- @@ -56,11 +56,11 @@ LL | | > = (); | = note: expected struct `Atype<Btype<..., ...>, ...>` found unit type `()` - = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.ascii/long-E0308.long-type-hash.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - --> $DIR/long-E0308.rs:93:17 + --> $DIR/long-E0308.rs:95:17 | LL | let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O... | ____________--___^ @@ -74,7 +74,7 @@ LL | | )))))))))))))))))))))))); | = note: expected unit type `()` found enum `Result<Result<..., ...>, ...>` - = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.ascii/long-E0308.long-type-hash.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 4 previous errors diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs index 93987226020..26383d9418d 100644 --- a/tests/ui/diagnostic-width/long-E0308.rs +++ b/tests/ui/diagnostic-width/long-E0308.rs @@ -1,7 +1,9 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes //@[unicode] compile-flags: -Zunstable-options --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" + +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" mod a { // Force the "short path for unique types" machinery to trip up diff --git a/tests/ui/diagnostic-width/long-E0308.unicode.stderr b/tests/ui/diagnostic-width/long-E0308.unicode.stderr index 3e8d881d7a6..50b386325b9 100644 --- a/tests/ui/diagnostic-width/long-E0308.unicode.stderr +++ b/tests/ui/diagnostic-width/long-E0308.unicode.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:46:9 + ╭▸ $DIR/long-E0308.rs:48:9 │ LL │ let x: Atype< │ ┌─────────────┘ @@ -20,11 +20,11 @@ LL │ ┃ )))))))))))))))))))))))))))))); │ ├ note: expected struct `Atype<Btype<..., ...>, ...>` │ found enum `Result<Result<..., ...>, ...>` - ├ note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.unicode/long-E0308.long-type-hash.txt' + ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:59:26 + ╭▸ $DIR/long-E0308.rs:61:26 │ LL │ ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(… │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┛ @@ -36,11 +36,11 @@ LL │ ┃ )))))))))))))))))))))))); │ ├ note: expected enum `Option<Result<..., ...>>` │ found enum `Result<Result<..., ...>, ...>` - ├ note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.unicode/long-E0308.long-type-hash.txt' + ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:90:9 + ╭▸ $DIR/long-E0308.rs:92:9 │ LL │ let x: Atype< │ ┌────────────┘ @@ -56,11 +56,11 @@ LL │ │ > = (); │ ├ note: expected struct `Atype<Btype<..., ...>, ...>` │ found unit type `()` - ├ note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.unicode/long-E0308.long-type-hash.txt' + ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:93:17 + ╭▸ $DIR/long-E0308.rs:95:17 │ LL │ let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(… │ ┏━━━━━━━━━━━━┬─━━━┛ @@ -74,7 +74,7 @@ LL │ ┃ )))))))))))))))))))))))); │ ├ note: expected unit type `()` │ found enum `Result<Result<..., ...>, ...>` - ├ note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.unicode/long-E0308.long-type-hash.txt' + ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' ╰ note: consider using `--verbose` to print the full type name to the console error: aborting due to 4 previous errors diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.rs b/tests/ui/diagnostic-width/non-copy-type-moved.rs index a5593ad7b2a..a220c62775e 100644 --- a/tests/ui/diagnostic-width/non-copy-type-moved.rs +++ b/tests/ui/diagnostic-width/non-copy-type-moved.rs @@ -1,5 +1,7 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (String, String, String, String); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.stderr b/tests/ui/diagnostic-width/non-copy-type-moved.stderr index da9385a5b4d..889a2b3666d 100644 --- a/tests/ui/diagnostic-width/non-copy-type-moved.stderr +++ b/tests/ui/diagnostic-width/non-copy-type-moved.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/non-copy-type-moved.rs:14:14 + --> $DIR/non-copy-type-moved.rs:16:14 | LL | fn foo(x: D) { | - move occurs because `x` has type `((..., ..., ..., ...), ..., ..., ...)`, which does not implement the `Copy` trait @@ -8,7 +8,7 @@ LL | let _a = x; LL | let _b = x; | ^ value used here after move | - = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/non-copy-type-moved/non-copy-type-moved.long-type-hash.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console help: consider cloning the value if the performance cost is acceptable | diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs index 6ed600c48ac..4caa9424425 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs @@ -1,5 +1,7 @@ //@ compile-flags: --diagnostic-width=100 -Zwrite-long-types-to-disk=yes -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr index 1e890455156..346b112019f 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/secondary-label-with-long-type.rs:9:9 + --> $DIR/secondary-label-with-long-type.rs:11:9 | LL | let () = x; | ^^ - this expression has type `((..., ..., ..., ...), ..., ..., ...)` @@ -8,7 +8,7 @@ LL | let () = x; | = note: expected tuple `((..., ..., ..., ...), ..., ..., ...)` found unit type `()` - = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/secondary-label-with-long-type/secondary-label-with-long-type.long-type-hash.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr index 7994ddf11c3..4fee6cc9a22 100644 --- a/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr +++ b/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -28,7 +28,7 @@ LL | let _: &Copy + 'static; | = note: the trait is not dyn compatible because it requires `Self: Sized` = note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> error: aborting due to 3 previous errors diff --git a/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr b/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr index f241333f2a7..a384697ee08 100644 --- a/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr +++ b/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr @@ -5,7 +5,7 @@ LL | impl<T, U> Dyn for dyn Foo<T, U> + '_ { | ^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/almost-supertrait-associated-type.rs:33:34 | LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T> @@ -22,7 +22,7 @@ LL | (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t) | ^^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/almost-supertrait-associated-type.rs:33:34 | LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T> @@ -39,7 +39,7 @@ LL | (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t) | ^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/almost-supertrait-associated-type.rs:33:34 | LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T> diff --git a/tests/ui/dyn-compatibility/associated-consts.curr.stderr b/tests/ui/dyn-compatibility/associated-consts.curr.stderr index 45d4f795542..de243938123 100644 --- a/tests/ui/dyn-compatibility/associated-consts.curr.stderr +++ b/tests/ui/dyn-compatibility/associated-consts.curr.stderr @@ -5,7 +5,7 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/associated-consts.rs:9:11 | LL | trait Bar { @@ -21,7 +21,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/associated-consts.rs:9:11 | LL | trait Bar { diff --git a/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr index 4c8c82196ed..704d833f00b 100644 --- a/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr @@ -5,7 +5,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/associated-consts.rs:9:11 | LL | trait Bar { diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr index ff5e9fdb6b3..b811ef40c26 100644 --- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr @@ -34,7 +34,7 @@ LL | fn id<F>(f: Copy) -> usize { | = note: the trait is not dyn compatible because it requires `Self: Sized` = note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> error[E0618]: expected function, found `(dyn Copy + 'static)` --> $DIR/avoid-ice-on-warning-2.rs:12:5 diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr index 92a2d340115..d8935be5609 100644 --- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr @@ -72,7 +72,7 @@ LL | trait B { fn f(a: A) -> A; } | ^ `A` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/avoid-ice-on-warning-3.rs:14:14 | LL | trait A { fn g(b: B) -> B; } @@ -109,7 +109,7 @@ LL | trait A { fn g(b: B) -> B; } | ^ `B` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/avoid-ice-on-warning-3.rs:4:14 | LL | trait B { fn f(a: A) -> A; } diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr index e3ec5b9c3c8..7be6cb0d03b 100644 --- a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr +++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr @@ -23,7 +23,7 @@ LL | fn ord_prefer_dot(s: String) -> Ord { | ^^^ `Ord` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: the trait is not dyn compatible because it uses `Self` as a type parameter diff --git a/tests/ui/dyn-compatibility/bounds.stderr b/tests/ui/dyn-compatibility/bounds.stderr index d45e66b1d5e..5473af388c0 100644 --- a/tests/ui/dyn-compatibility/bounds.stderr +++ b/tests/ui/dyn-compatibility/bounds.stderr @@ -5,7 +5,7 @@ LL | fn f() -> Box<dyn X<U = u32>> { | ^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/bounds.rs:4:13 | LL | trait X { diff --git a/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr b/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr index 04dc0b1d6f4..cfebd5d6947 100644 --- a/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr +++ b/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr @@ -5,7 +5,7 @@ LL | fn take_dyn(_: &dyn Child) {} | ^^^^^ `Super` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/gat-incompatible-supertrait.rs:10:10 | LL | trait Super { diff --git a/tests/ui/dyn-compatibility/generics.curr.stderr b/tests/ui/dyn-compatibility/generics.curr.stderr index 1607954ab70..d29d02b2ff3 100644 --- a/tests/ui/dyn-compatibility/generics.curr.stderr +++ b/tests/ui/dyn-compatibility/generics.curr.stderr @@ -5,7 +5,7 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/generics.rs:10:8 | LL | trait Bar { @@ -21,7 +21,7 @@ LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar { | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/generics.rs:10:8 | LL | trait Bar { @@ -37,7 +37,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/generics.rs:10:8 | LL | trait Bar { @@ -54,7 +54,7 @@ LL | t as &dyn Bar | ^^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/generics.rs:10:8 | LL | trait Bar { @@ -70,7 +70,7 @@ LL | t as &dyn Bar | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/generics.rs:10:8 | LL | trait Bar { diff --git a/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr index 7f31b29b39c..b3565a766fe 100644 --- a/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr @@ -5,7 +5,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/generics.rs:10:8 | LL | trait Bar { @@ -22,7 +22,7 @@ LL | t as &dyn Bar | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/generics.rs:10:8 | LL | trait Bar { diff --git a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr index 1ed78e1e659..bb3f7899bf1 100644 --- a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr +++ b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr @@ -5,7 +5,7 @@ LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mention-correct-dyn-incompatible-trait.rs:4:8 | LL | fn foo<T>(&self, val: T); @@ -23,7 +23,7 @@ LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mention-correct-dyn-incompatible-trait.rs:4:8 | LL | fn foo<T>(&self, val: T); diff --git a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr index eba2c15dd74..cf3a7b23084 100644 --- a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr +++ b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr @@ -5,7 +5,7 @@ LL | elements: Vec<Box<dyn Expr + 'x>>, | ^^^^ `Expr` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mentions-Self-in-super-predicates.rs:5:21 | LL | trait Expr: Debug + PartialEq { @@ -20,7 +20,7 @@ LL | let a: Box<dyn Expr> = Box::new(SExpr::new()); | ^^^^ `Expr` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mentions-Self-in-super-predicates.rs:5:21 | LL | trait Expr: Debug + PartialEq { @@ -35,7 +35,7 @@ LL | let b: Box<dyn Expr> = Box::new(SExpr::new()); | ^^^^ `Expr` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mentions-Self-in-super-predicates.rs:5:21 | LL | trait Expr: Debug + PartialEq { diff --git a/tests/ui/dyn-compatibility/mentions-Self.curr.stderr b/tests/ui/dyn-compatibility/mentions-Self.curr.stderr index 90db86ffef9..2d3fe5ce636 100644 --- a/tests/ui/dyn-compatibility/mentions-Self.curr.stderr +++ b/tests/ui/dyn-compatibility/mentions-Self.curr.stderr @@ -5,7 +5,7 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mentions-Self.rs:11:22 | LL | trait Bar { @@ -21,7 +21,7 @@ LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz { | ^^^^^^^ `Baz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mentions-Self.rs:15:22 | LL | trait Baz { @@ -37,7 +37,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mentions-Self.rs:11:22 | LL | trait Bar { @@ -54,7 +54,7 @@ LL | t | ^ `Baz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mentions-Self.rs:15:22 | LL | trait Baz { diff --git a/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr index 4a50d3f07e4..91c26a86025 100644 --- a/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr @@ -5,7 +5,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mentions-Self.rs:11:22 | LL | trait Bar { @@ -22,7 +22,7 @@ LL | t | ^ `Baz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/mentions-Self.rs:15:22 | LL | trait Baz { diff --git a/tests/ui/dyn-compatibility/missing-assoc-type.stderr b/tests/ui/dyn-compatibility/missing-assoc-type.stderr index 3f550494b33..5a7560682f2 100644 --- a/tests/ui/dyn-compatibility/missing-assoc-type.stderr +++ b/tests/ui/dyn-compatibility/missing-assoc-type.stderr @@ -5,7 +5,7 @@ LL | fn bar(x: &dyn Foo) {} | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/missing-assoc-type.rs:2:10 | LL | trait Foo { diff --git a/tests/ui/dyn-compatibility/no-static.curr.stderr b/tests/ui/dyn-compatibility/no-static.curr.stderr index 867c485053d..bf9b48e7a43 100644 --- a/tests/ui/dyn-compatibility/no-static.curr.stderr +++ b/tests/ui/dyn-compatibility/no-static.curr.stderr @@ -5,7 +5,7 @@ LL | fn diverges() -> Box<dyn Foo> { | ^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/no-static.rs:9:8 | LL | trait Foo { @@ -29,7 +29,7 @@ LL | let b: Box<dyn Foo> = Box::new(Bar); | ^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/no-static.rs:9:8 | LL | trait Foo { @@ -53,7 +53,7 @@ LL | let b: Box<dyn Foo> = Box::new(Bar); | ^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/no-static.rs:9:8 | LL | trait Foo { diff --git a/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr index 65608a9cca7..d5ad4510334 100644 --- a/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr @@ -5,7 +5,7 @@ LL | let b: Box<dyn Foo> = Box::new(Bar); | ^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/no-static.rs:9:8 | LL | trait Foo { diff --git a/tests/ui/dyn-compatibility/sized-2.curr.stderr b/tests/ui/dyn-compatibility/sized-2.curr.stderr index c8fd1056237..2d262072d5d 100644 --- a/tests/ui/dyn-compatibility/sized-2.curr.stderr +++ b/tests/ui/dyn-compatibility/sized-2.curr.stderr @@ -5,7 +5,7 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/sized-2.rs:9:18 | LL | trait Bar @@ -20,7 +20,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/sized-2.rs:9:18 | LL | trait Bar diff --git a/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr index 477dacdf5a1..1fbc10c0c3f 100644 --- a/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr @@ -5,7 +5,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/sized-2.rs:9:18 | LL | trait Bar diff --git a/tests/ui/dyn-compatibility/sized.curr.stderr b/tests/ui/dyn-compatibility/sized.curr.stderr index d86ea9197b9..a197d967005 100644 --- a/tests/ui/dyn-compatibility/sized.curr.stderr +++ b/tests/ui/dyn-compatibility/sized.curr.stderr @@ -5,7 +5,7 @@ LL | fn make_bar<T: Bar>(t: &T) -> &dyn Bar { | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/sized.rs:8:12 | LL | trait Bar: Sized { @@ -20,7 +20,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/sized.rs:8:12 | LL | trait Bar: Sized { diff --git a/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr index b763173594b..350c8992c6f 100644 --- a/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr @@ -5,7 +5,7 @@ LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/sized.rs:8:12 | LL | trait Bar: Sized { diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr b/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr index f5dea256469..8e139ee6b48 100644 --- a/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr +++ b/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr @@ -27,7 +27,7 @@ LL | fn c(&self) -> dyn SuperTrait<T>; | ^^^^^^^^^^^^^^^^^ `SuperTrait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/supertrait-mentions-GAT.rs:4:10 | LL | type Gat<'a> diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr index f9ef0c9b2e0..a763649e9c6 100644 --- a/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr +++ b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr @@ -25,7 +25,7 @@ LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz { | ^^^ `Baz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/supertrait-mentions-Self.rs:8:13 | LL | trait Baz : Bar<Self> { diff --git a/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr b/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr index 8442314835e..7e80a1d2e42 100644 --- a/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr +++ b/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr @@ -5,7 +5,7 @@ LL | static FOO: &(dyn Qux + Sync) = "desc"; | ^^^^^^^^^^^^^^ `Qux` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/taint-const-eval.rs:8:8 | LL | trait Qux { @@ -28,7 +28,7 @@ LL | static FOO: &(dyn Qux + Sync) = "desc"; | ^^^^^^ `Qux` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/taint-const-eval.rs:8:8 | LL | trait Qux { @@ -52,7 +52,7 @@ LL | static FOO: &(dyn Qux + Sync) = "desc"; | ^^^^^^^^^^^^^^ `Qux` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/taint-const-eval.rs:8:8 | LL | trait Qux { diff --git a/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr index 1c51df8501f..0bc7d0b14d3 100644 --- a/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr @@ -5,7 +5,7 @@ LL | static FOO: &(dyn Qux + Sync) = "desc"; | ^^^^^^ `Qux` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/taint-const-eval.rs:8:8 | LL | trait Qux { diff --git a/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr b/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr index 45a924008c7..1299167159e 100644 --- a/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr +++ b/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr @@ -8,7 +8,7 @@ LL | fn fetcher() -> Box<dyn Fetcher> { | ^^^^^^^^^^^ `Fetcher` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/undispatchable-receiver-and-wc-references-Self.rs:11:22 | LL | pub trait Fetcher: Send + Sync { @@ -26,7 +26,7 @@ LL | let fetcher = fetcher(); | ^^^^^^^^^ `Fetcher` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/undispatchable-receiver-and-wc-references-Self.rs:11:22 | LL | pub trait Fetcher: Send + Sync { @@ -44,7 +44,7 @@ LL | let _ = fetcher.get(); | ^^^^^^^^^^^^^ `Fetcher` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/undispatchable-receiver-and-wc-references-Self.rs:11:22 | LL | pub trait Fetcher: Send + Sync { diff --git a/tests/ui/error-codes/E0038.stderr b/tests/ui/error-codes/E0038.stderr index 59e9f504d17..63a5249a386 100644 --- a/tests/ui/error-codes/E0038.stderr +++ b/tests/ui/error-codes/E0038.stderr @@ -5,7 +5,7 @@ LL | fn call_foo(x: Box<dyn Trait>) { | ^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/E0038.rs:2:22 | LL | trait Trait { @@ -21,7 +21,7 @@ LL | let y = x.foo(); | ^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/E0038.rs:2:22 | LL | trait Trait { diff --git a/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr index b4de6b66469..ab8c092a826 100644 --- a/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr +++ b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr @@ -5,7 +5,7 @@ LL | async fn takes_dyn_trait(x: &dyn Foo) { | ^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14 | LL | trait Foo { @@ -21,7 +21,7 @@ LL | x.bar().await; | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14 | LL | trait Foo { @@ -37,7 +37,7 @@ LL | x.bar().await; | ^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14 | LL | trait Foo { diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr index f8fc086c441..6634ce12118 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr @@ -8,7 +8,7 @@ LL | Ptr(Box::new(4)) as Ptr<dyn Trait>; | ^^^^^^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:25:18 | LL | trait Trait { @@ -27,7 +27,7 @@ LL | Ptr(Box::new(4)) as Ptr<dyn Trait>; | ^^^^^^^^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:25:18 | LL | trait Trait { diff --git a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr index 10540f0219d..2c3edd6e6a5 100644 --- a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr +++ b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr @@ -5,7 +5,7 @@ LL | fn takes_dyn_incompatible_ref<T>(obj: &dyn DynIncompatible1) { | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25 | LL | trait DynIncompatible1: Sized {} @@ -20,7 +20,7 @@ LL | fn return_dyn_incompatible_ref() -> &'static dyn DynIncompatible2 { | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible2` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:7:8 | LL | trait DynIncompatible2 { @@ -43,7 +43,7 @@ LL | fn takes_dyn_incompatible_box(obj: Box<dyn DynIncompatible3>) { | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible3` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:11:8 | LL | trait DynIncompatible3 { @@ -59,7 +59,7 @@ LL | fn return_dyn_incompatible_rc() -> std::rc::Rc<dyn DynIncompatible4> { | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible4` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:15:22 | LL | trait DynIncompatible4 { @@ -75,7 +75,7 @@ LL | impl Trait for dyn DynIncompatible1 {} | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25 | LL | trait DynIncompatible1: Sized {} diff --git a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr index 4c5a47e73c6..c9b46de5c33 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr +++ b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr @@ -43,7 +43,7 @@ LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:2:8 | LL | trait X { diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.stderr index df79556c825..e57f6b48401 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path.stderr +++ b/tests/ui/generic-associated-types/gat-in-trait-path.stderr @@ -5,7 +5,7 @@ LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/gat-in-trait-path.rs:6:10 | LL | trait Foo { @@ -21,7 +21,7 @@ LL | f(Box::new(foo)); | ^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/gat-in-trait-path.rs:6:10 | LL | trait Foo { @@ -37,7 +37,7 @@ LL | f(Box::new(foo)); | ^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/gat-in-trait-path.rs:6:10 | LL | trait Foo { diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr index 499ce8e4a32..52fed354edf 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -130,7 +130,7 @@ LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 | LL | trait X { @@ -196,7 +196,7 @@ LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {} | ^^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 | LL | trait X { diff --git a/tests/ui/generic-associated-types/issue-67510-pass.stderr b/tests/ui/generic-associated-types/issue-67510-pass.stderr index f6846f833fe..4b56c4ef35f 100644 --- a/tests/ui/generic-associated-types/issue-67510-pass.stderr +++ b/tests/ui/generic-associated-types/issue-67510-pass.stderr @@ -5,7 +5,7 @@ LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-67510-pass.rs:4:10 | LL | trait X { diff --git a/tests/ui/generic-associated-types/issue-67510.stderr b/tests/ui/generic-associated-types/issue-67510.stderr index e8555a7aa1f..f5c494788ea 100644 --- a/tests/ui/generic-associated-types/issue-67510.stderr +++ b/tests/ui/generic-associated-types/issue-67510.stderr @@ -36,7 +36,7 @@ LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-67510.rs:2:10 | LL | trait X { diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr index a78151384d4..56439f6dfea 100644 --- a/tests/ui/generic-associated-types/issue-71176.stderr +++ b/tests/ui/generic-associated-types/issue-71176.stderr @@ -55,7 +55,7 @@ LL | inner: Box<dyn Provider<A = B>>, | ^^^^^^^^^^^^^^^^^^^ `Provider` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-71176.rs:2:10 | LL | trait Provider { @@ -72,7 +72,7 @@ LL | inner: Box::new(()), | ^^^^^^^^^^^^ `Provider` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-71176.rs:2:10 | LL | trait Provider { @@ -89,7 +89,7 @@ LL | inner: Box::new(()), | ^^^^^^^^^^^^ `Provider` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-71176.rs:2:10 | LL | trait Provider { diff --git a/tests/ui/generic-associated-types/issue-76535.stderr b/tests/ui/generic-associated-types/issue-76535.stderr index 6b7c3bfe731..b828234afa1 100644 --- a/tests/ui/generic-associated-types/issue-76535.stderr +++ b/tests/ui/generic-associated-types/issue-76535.stderr @@ -21,7 +21,7 @@ LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruc | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-76535.rs:4:10 | LL | pub trait SuperTrait { @@ -39,7 +39,7 @@ LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruc | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-76535.rs:4:10 | LL | pub trait SuperTrait { diff --git a/tests/ui/generic-associated-types/issue-78671.stderr b/tests/ui/generic-associated-types/issue-78671.stderr index c85e97067cb..c6da137672d 100644 --- a/tests/ui/generic-associated-types/issue-78671.stderr +++ b/tests/ui/generic-associated-types/issue-78671.stderr @@ -21,7 +21,7 @@ LL | Box::new(Family) as &dyn CollectionFamily<Member=usize> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-78671.rs:2:10 | LL | trait CollectionFamily { diff --git a/tests/ui/generic-associated-types/issue-79422.stderr b/tests/ui/generic-associated-types/issue-79422.stderr index a81217e96c3..6311e4de272 100644 --- a/tests/ui/generic-associated-types/issue-79422.stderr +++ b/tests/ui/generic-associated-types/issue-79422.stderr @@ -21,7 +21,7 @@ LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-79422.rs:18:10 | LL | trait MapLike<K, V> { @@ -37,7 +37,7 @@ LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-79422.rs:18:10 | LL | trait MapLike<K, V> { diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.rs b/tests/ui/generic-associated-types/issue-90014-tait2.rs index ef54a89aaae..3f7a9ff63c3 100644 --- a/tests/ui/generic-associated-types/issue-90014-tait2.rs +++ b/tests/ui/generic-associated-types/issue-90014-tait2.rs @@ -3,8 +3,6 @@ //! Unfortunately we don't even reach opaque type collection, as we ICE in typeck before that. //! See #109281 for the original report. //@ edition:2018 -//@ error-pattern: expected generic lifetime parameter, found `'a` - #![feature(type_alias_impl_trait)] use std::future::Future; @@ -24,6 +22,7 @@ impl<'x, T: 'x> Trait<'x> for (T,) { impl Foo<'_> { fn make_fut(&self) -> Box<dyn for<'a> Trait<'a, Thing = Fut<'a>>> { Box::new((async { () },)) + //~^ ERROR expected generic lifetime parameter, found `'a` } } diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.stderr b/tests/ui/generic-associated-types/issue-90014-tait2.stderr index be6f4272ce1..aa427d42649 100644 --- a/tests/ui/generic-associated-types/issue-90014-tait2.stderr +++ b/tests/ui/generic-associated-types/issue-90014-tait2.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/issue-90014-tait2.rs:26:9 + --> $DIR/issue-90014-tait2.rs:24:9 | LL | type Fut<'a> = impl Future<Output = ()>; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr index 6b8df5cc12f..7b6888817f4 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_args.stderr +++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr @@ -55,7 +55,7 @@ LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y = (&'c u32, &'d u32)>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/missing_lifetime_args.rs:2:10 | LL | trait X { diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr index 5c9e9dbe3d7..45bca1a7628 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr @@ -99,7 +99,7 @@ LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/trait-path-type-error-once-implemented.rs:2:10 | LL | trait X { diff --git a/tests/ui/generic-associated-types/trait-objects.stderr b/tests/ui/generic-associated-types/trait-objects.stderr index 56a1cb1906f..7d95718ec87 100644 --- a/tests/ui/generic-associated-types/trait-objects.stderr +++ b/tests/ui/generic-associated-types/trait-objects.stderr @@ -5,7 +5,7 @@ LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> u | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/trait-objects.rs:2:10 | LL | trait StreamingIterator { @@ -21,7 +21,7 @@ LL | x.size_hint().0 | ^^^^^^^^^ `StreamingIterator` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/trait-objects.rs:2:10 | LL | trait StreamingIterator { @@ -37,7 +37,7 @@ LL | x.size_hint().0 | ^^^^^^^^^^^^^ `StreamingIterator` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/trait-objects.rs:2:10 | LL | trait StreamingIterator { diff --git a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs index e70f6fc3430..f2b73d69261 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs +++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs @@ -36,12 +36,10 @@ trait Ty<'a> { fn main() { let v = Unit2.m( - L { - //~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4` - //~| ERROR type mismatch + L { //~ ERROR type mismatch f: |x| { drop(x); - Unit4 + Unit4 //~ ERROR to be a closure that returns `Unit3`, but it returns `Unit4` }, }, ); diff --git a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr index 74610b55dc3..d0675d5020c 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr @@ -1,16 +1,15 @@ -error[E0271]: type mismatch resolving `<L<{closure@issue-62203-hrtb-ice.rs:42:16}> as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` +error[E0271]: type mismatch resolving `<L<{closure@issue-62203-hrtb-ice.rs:40:16}> as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` --> $DIR/issue-62203-hrtb-ice.rs:39:9 | LL | let v = Unit2.m( | - required by a bound introduced by this call LL | / L { -LL | | -LL | | LL | | f: |x| { -... | +LL | | drop(x); +LL | | Unit4 LL | | }, LL | | }, - | |_________^ type mismatch resolving `<L<{closure@issue-62203-hrtb-ice.rs:42:16}> as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` + | |_________^ type mismatch resolving `<L<{closure@issue-62203-hrtb-ice.rs:40:16}> as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` | note: expected this to be `<_ as Ty<'_>>::V` --> $DIR/issue-62203-hrtb-ice.rs:21:14 @@ -30,21 +29,19 @@ LL | where LL | F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>, | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` -error[E0271]: expected `{closure@issue-62203-hrtb-ice.rs:42:16}` to be a closure that returns `Unit3`, but it returns `Unit4` - --> $DIR/issue-62203-hrtb-ice.rs:39:9 - | -LL | let v = Unit2.m( - | - required by a bound introduced by this call -LL | / L { -LL | | -LL | | -LL | | f: |x| { -... | -LL | | }, -LL | | }, - | |_________^ expected `Unit3`, found `Unit4` - | -note: required for `L<{closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19}>` to implement `for<'r> T0<'r, (&'r u8,)>` +error[E0271]: expected `{closure@issue-62203-hrtb-ice.rs:40:16}` to be a closure that returns `Unit3`, but it returns `Unit4` + --> $DIR/issue-62203-hrtb-ice.rs:42:17 + | +LL | let v = Unit2.m( + | - required by a bound introduced by this call +LL | L { +LL | f: |x| { + | --- this closure +LL | drop(x); +LL | Unit4 + | ^^^^^ expected `Unit3`, found `Unit4` + | +note: required for `L<{closure@$DIR/issue-62203-hrtb-ice.rs:40:16: 40:19}>` to implement `for<'r> T0<'r, (&'r u8,)>` --> $DIR/issue-62203-hrtb-ice.rs:17:16 | LL | impl<'a, A, T> T0<'a, A> for L<T> diff --git a/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr b/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr index fc3d9c2171d..183ee678d7a 100644 --- a/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr +++ b/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr @@ -5,7 +5,7 @@ LL | let x: &dyn Foo = &(); | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/span-bug-issue-121597.rs:4:12 | LL | trait Foo: for<T> Bar<T> {} @@ -21,7 +21,7 @@ LL | let x: &dyn Foo = &(); | ^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/span-bug-issue-121597.rs:4:12 | LL | trait Foo: for<T> Bar<T> {} diff --git a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr index 4abd7bcf31c..2869702d7fc 100644 --- a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr +++ b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr @@ -5,7 +5,7 @@ LL | fn car() -> dyn DynIncompatible { | ^^^^^^^^^^^^^^^^^^^ `DynIncompatible` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8 | LL | trait DynIncompatible { @@ -33,7 +33,7 @@ LL | fn cat() -> Box<dyn DynIncompatible> { | ^^^^^^^^^^^^^^^^^^^ `DynIncompatible` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8 | LL | trait DynIncompatible { @@ -78,7 +78,7 @@ LL | return Box::new(A); | ^^^^^^^^^^^ `DynIncompatible` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8 | LL | trait DynIncompatible { @@ -107,7 +107,7 @@ LL | Box::new(B) | ^^^^^^^^^^^ `DynIncompatible` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8 | LL | trait DynIncompatible { diff --git a/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-dyn-compatibility-check.stderr b/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-dyn-compatibility-check.stderr index 44ca09150fe..61fe9432a1e 100644 --- a/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-dyn-compatibility-check.stderr +++ b/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-dyn-compatibility-check.stderr @@ -15,7 +15,7 @@ LL | MyTrait::foo(&self) | ^^^^^^^^^^^^ `MyTrait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/cycle-effective-visibilities-during-dyn-compatibility-check.rs:5:22 | LL | trait MyTrait { @@ -40,7 +40,7 @@ LL | impl dyn MyTrait { | ^^^^^^^^^^^ `MyTrait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/cycle-effective-visibilities-during-dyn-compatibility-check.rs:5:22 | LL | trait MyTrait { @@ -57,7 +57,7 @@ LL | fn other(&self) -> impl Marker { | ^^^^ `MyTrait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/cycle-effective-visibilities-during-dyn-compatibility-check.rs:5:22 | LL | trait MyTrait { diff --git a/tests/ui/impl-trait/in-trait/dont-consider-unconstrained-rpitits.rs b/tests/ui/impl-trait/in-trait/dont-consider-unconstrained-rpitits.rs new file mode 100644 index 00000000000..fe73306966e --- /dev/null +++ b/tests/ui/impl-trait/in-trait/dont-consider-unconstrained-rpitits.rs @@ -0,0 +1,14 @@ +// There's a suggestion that turns `Iterator<u32>` into `Iterator<Item = u32>` +// if we have more generics than the trait wants. Let's not consider RPITITs +// for this, since that makes no sense right now. + +trait Foo { + fn bar(self) -> impl Sized; +} + +impl Foo<u8> for () { + //~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied + fn bar(self) -> impl Sized {} +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/dont-consider-unconstrained-rpitits.stderr b/tests/ui/impl-trait/in-trait/dont-consider-unconstrained-rpitits.stderr new file mode 100644 index 00000000000..fb497b89c5f --- /dev/null +++ b/tests/ui/impl-trait/in-trait/dont-consider-unconstrained-rpitits.stderr @@ -0,0 +1,17 @@ +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/dont-consider-unconstrained-rpitits.rs:9:6 + | +LL | impl Foo<u8> for () { + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: trait defined here, with 0 generic parameters + --> $DIR/dont-consider-unconstrained-rpitits.rs:5:7 + | +LL | trait Foo { + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/impl-trait/in-trait/dyn-compatibility.stderr b/tests/ui/impl-trait/in-trait/dyn-compatibility.stderr index 87a5480b1e3..840c27e183f 100644 --- a/tests/ui/impl-trait/in-trait/dyn-compatibility.stderr +++ b/tests/ui/impl-trait/in-trait/dyn-compatibility.stderr @@ -5,7 +5,7 @@ LL | let i = Box::new(42_u32) as Box<dyn Foo>; | ^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-compatibility.rs:4:22 | LL | trait Foo { @@ -22,7 +22,7 @@ LL | let s = i.baz(); | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-compatibility.rs:4:22 | LL | trait Foo { @@ -39,7 +39,7 @@ LL | let s = i.baz(); | ^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-compatibility.rs:4:22 | LL | trait Foo { @@ -56,7 +56,7 @@ LL | let i = Box::new(42_u32) as Box<dyn Foo>; | ^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-compatibility.rs:4:22 | LL | trait Foo { diff --git a/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr index 07d09468b04..29235ca78a5 100644 --- a/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr +++ b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr @@ -5,7 +5,7 @@ LL | let _: &dyn rpitit::Foo = todo!(); | ^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/auxiliary/rpitit.rs:4:21 | LL | fn bar(self) -> impl Deref<Target = impl Sized>; diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs index e28b8f373da..62fc079d9d9 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs @@ -3,6 +3,9 @@ //@ error-pattern: reached the recursion limit while instantiating //@ error-pattern: reached the recursion limit finding the struct tail +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" + // Regression test for #114484: This used to ICE during monomorphization, because we treated // `<VirtualWrapper<...> as Pointee>::Metadata` as a rigid projection after reaching the recursion // limit when finding the struct tail. diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr index 7c961b79c0c..b67e000bf74 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr @@ -18,7 +18,7 @@ error: reached the recursion limit finding the struct tail for `[u8; 256]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ error: reached the recursion limit finding the struct tail for `SomeData<256>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ error: reached the recursion limit finding the struct tail for `VirtualWrapper<S = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -76,11 +76,11 @@ LL | unsafe { virtualize_my_trait(L, self) } error: reached the recursion limit while instantiating `<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<..., 1>, 1>, 1>, 1>, 1> as MyTrait>::virtualize` | note: `<VirtualWrapper<T, L> as MyTrait>::virtualize` defined here - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:5 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:28:5 | LL | fn virtualize(&self) -> &dyn MyTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/infinite/infinite-instantiation-struct-tail-ice-114484/infinite-instantiation-struct-tail-ice-114484.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' error: aborting due to 13 previous errors diff --git a/tests/ui/infinite/infinite-instantiation.rs b/tests/ui/infinite/infinite-instantiation.rs index 7e1bff6b124..d5cb8e79592 100644 --- a/tests/ui/infinite/infinite-instantiation.rs +++ b/tests/ui/infinite/infinite-instantiation.rs @@ -1,5 +1,6 @@ //@ build-fail -//@ normalize-stderr: ".nll/" -> "/" +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" trait ToOpt: Sized { fn to_option(&self) -> Option<Self>; diff --git a/tests/ui/infinite/infinite-instantiation.stderr b/tests/ui/infinite/infinite-instantiation.stderr index 43d267fa46b..71c745cf5eb 100644 --- a/tests/ui/infinite/infinite-instantiation.stderr +++ b/tests/ui/infinite/infinite-instantiation.stderr @@ -1,15 +1,15 @@ error: reached the recursion limit while instantiating `function::<Option<Option<Option<Option<Option<...>>>>>>` - --> $DIR/infinite-instantiation.rs:22:9 + --> $DIR/infinite-instantiation.rs:23:9 | LL | function(counter - 1, t.to_option()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `function` defined here - --> $DIR/infinite-instantiation.rs:20:1 + --> $DIR/infinite-instantiation.rs:21:1 | LL | fn function<T:ToOpt + Clone>(counter: usize, t: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/infinite/infinite-instantiation/infinite-instantiation.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-18959.stderr b/tests/ui/issues/issue-18959.stderr index 49d501c397f..c37c4177bfc 100644 --- a/tests/ui/issues/issue-18959.stderr +++ b/tests/ui/issues/issue-18959.stderr @@ -5,7 +5,7 @@ LL | fn foo(b: &dyn Bar) { | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-18959.rs:1:20 | LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); } @@ -21,7 +21,7 @@ LL | b.foo(&0) | ^^^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-18959.rs:1:20 | LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); } @@ -37,7 +37,7 @@ LL | let test: &dyn Bar = &mut thing; | ^^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-18959.rs:1:20 | LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); } @@ -53,7 +53,7 @@ LL | let test: &dyn Bar = &mut thing; | ^^^^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-18959.rs:1:20 | LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); } @@ -70,7 +70,7 @@ LL | foo(test); | ^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-18959.rs:1:20 | LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); } diff --git a/tests/ui/issues/issue-19380.stderr b/tests/ui/issues/issue-19380.stderr index 7d4812c3693..f8509891d3a 100644 --- a/tests/ui/issues/issue-19380.stderr +++ b/tests/ui/issues/issue-19380.stderr @@ -5,7 +5,7 @@ LL | foos: &'static [&'static (dyn Qiz + 'static)] | ^^^^^^^^^^^^^^^^^ `Qiz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-19380.rs:2:6 | LL | trait Qiz { @@ -29,7 +29,7 @@ LL | const BAR : Bar = Bar { foos: &[&FOO]}; | ^^^^ `Qiz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-19380.rs:2:6 | LL | trait Qiz { @@ -54,7 +54,7 @@ LL | const BAR : Bar = Bar { foos: &[&FOO]}; | ^^^^^^^ `Qiz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-19380.rs:2:6 | LL | trait Qiz { diff --git a/tests/ui/issues/issue-26056.stderr b/tests/ui/issues/issue-26056.stderr index d1cdf43351e..c2168af9496 100644 --- a/tests/ui/issues/issue-26056.stderr +++ b/tests/ui/issues/issue-26056.stderr @@ -5,7 +5,7 @@ LL | as &dyn Map<Key=u32,MapValue=u32>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-26056.rs:9:12 | LL | trait Map: MapLookup<<Self as Map>::Key> { diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs index edf4f2fce26..ebaf244ac9c 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs @@ -1,5 +1,6 @@ //@ build-fail -//@ normalize-stderr: ".nll/" -> "/" +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" trait Mirror { type Image; diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr index 84ed97572b3..fbbf80021be 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr @@ -1,15 +1,15 @@ error: reached the recursion limit while instantiating `<(&(&(..., ...), ...), ...) as Foo>::recurse` - --> $DIR/issue-37311.rs:17:9 + --> $DIR/issue-37311.rs:18:9 | LL | (self, self).recurse(); | ^^^^^^^^^^^^^^^^^^^^^^ | note: `<T as Foo>::recurse` defined here - --> $DIR/issue-37311.rs:16:5 + --> $DIR/issue-37311.rs:17:5 | LL | fn recurse(&self) { | ^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-37311-type-length-limit/issue-37311/issue-37311.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-50781.stderr b/tests/ui/issues/issue-50781.stderr index 293e9839944..88b83a83e0c 100644 --- a/tests/ui/issues/issue-50781.stderr +++ b/tests/ui/issues/issue-50781.stderr @@ -5,7 +5,7 @@ LL | impl Trait for dyn X {} | ^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-50781.rs:4:8 | LL | trait X { @@ -22,7 +22,7 @@ LL | <dyn X as X>::foo(&()); | ^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-50781.rs:4:8 | LL | trait X { @@ -40,7 +40,7 @@ LL | <dyn X as X>::foo(&()); | ^^^^^ `X` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-50781.rs:4:8 | LL | trait X { diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs index 343ae4f262f..8c7e95bd2e3 100644 --- a/tests/ui/issues/issue-67552.rs +++ b/tests/ui/issues/issue-67552.rs @@ -1,6 +1,7 @@ //@ build-fail //@ compile-flags: -Copt-level=0 -//@ normalize-stderr: ".nll/" -> "/" +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" fn main() { rec(Empty); diff --git a/tests/ui/issues/issue-67552.stderr b/tests/ui/issues/issue-67552.stderr index 1a8d7248b45..f94cd78c870 100644 --- a/tests/ui/issues/issue-67552.stderr +++ b/tests/ui/issues/issue-67552.stderr @@ -1,17 +1,17 @@ error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>` - --> $DIR/issue-67552.rs:29:9 + --> $DIR/issue-67552.rs:30:9 | LL | rec(identity(&mut it)) | ^^^^^^^^^^^^^^^^^^^^^^ | note: `rec` defined here - --> $DIR/issue-67552.rs:22:1 + --> $DIR/issue-67552.rs:23:1 | LL | / fn rec<T>(mut it: T) LL | | where LL | | T: Iterator, | |________________^ - = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-67552/issue-67552.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-8727.rs b/tests/ui/issues/issue-8727.rs index b824be7c12f..7767729109e 100644 --- a/tests/ui/issues/issue-8727.rs +++ b/tests/ui/issues/issue-8727.rs @@ -2,7 +2,8 @@ // recursions. //@ build-fail -//@ normalize-stderr: ".nll/" -> "/" +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" fn generic<T>() { //~ WARN function cannot return without recursing generic::<Option<T>>(); diff --git a/tests/ui/issues/issue-8727.stderr b/tests/ui/issues/issue-8727.stderr index 9af598fe43f..22286eb8d7b 100644 --- a/tests/ui/issues/issue-8727.stderr +++ b/tests/ui/issues/issue-8727.stderr @@ -1,5 +1,5 @@ warning: function cannot return without recursing - --> $DIR/issue-8727.rs:7:1 + --> $DIR/issue-8727.rs:8:1 | LL | fn generic<T>() { | ^^^^^^^^^^^^^^^ cannot return without recursing @@ -10,17 +10,17 @@ LL | generic::<Option<T>>(); = note: `#[warn(unconditional_recursion)]` on by default error: reached the recursion limit while instantiating `generic::<Option<Option<Option<Option<Option<...>>>>>>` - --> $DIR/issue-8727.rs:8:5 + --> $DIR/issue-8727.rs:9:5 | LL | generic::<Option<T>>(); | ^^^^^^^^^^^^^^^^^^^^^^ | note: `generic` defined here - --> $DIR/issue-8727.rs:7:1 + --> $DIR/issue-8727.rs:8:1 | LL | fn generic<T>() { | ^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-8727/issue-8727.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr index 83446fc9ec0..95048c4454b 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -26,7 +26,7 @@ LL | let z = &x as &dyn Foo; | ^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/kindck-inherited-copy-bound.rs:10:13 | LL | trait Foo : Copy { @@ -41,7 +41,7 @@ LL | let z = &x as &dyn Foo; | ^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/kindck-inherited-copy-bound.rs:10:13 | LL | trait Foo : Copy { diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr index 271e5afb9e7..296f011193e 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr @@ -26,7 +26,7 @@ LL | let z = &x as &dyn Foo; | ^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/kindck-inherited-copy-bound.rs:10:13 | LL | trait Foo : Copy { diff --git a/tests/ui/mir/null/addrof_null.rs b/tests/ui/mir/null/addrof_null.rs new file mode 100644 index 00000000000..0d0b7edeef6 --- /dev/null +++ b/tests/ui/mir/null/addrof_null.rs @@ -0,0 +1,14 @@ +// Make sure that we don't insert a check for `addr_of!`. +//@ run-pass +//@ compile-flags: -C debug-assertions + +struct Field { + a: u32, +} + +fn main() { + unsafe { + let ptr: *const Field = std::ptr::null(); + let _ptr = core::ptr::addr_of!((*ptr).a); + } +} diff --git a/tests/ui/mir/null/borrowed_mut_null.rs b/tests/ui/mir/null/borrowed_mut_null.rs new file mode 100644 index 00000000000..437955c452b --- /dev/null +++ b/tests/ui/mir/null/borrowed_mut_null.rs @@ -0,0 +1,8 @@ +//@ run-fail +//@ compile-flags: -C debug-assertions +//@ error-pattern: null pointer dereference occured + +fn main() { + let ptr: *mut u32 = std::ptr::null_mut(); + let _ptr: &mut u32 = unsafe { &mut *ptr }; +} diff --git a/tests/ui/mir/null/borrowed_null.rs b/tests/ui/mir/null/borrowed_null.rs new file mode 100644 index 00000000000..eb0794efaa5 --- /dev/null +++ b/tests/ui/mir/null/borrowed_null.rs @@ -0,0 +1,8 @@ +//@ run-fail +//@ compile-flags: -C debug-assertions +//@ error-pattern: null pointer dereference occured + +fn main() { + let ptr: *const u32 = std::ptr::null(); + let _ptr: &u32 = unsafe { &*ptr }; +} diff --git a/tests/ui/mir/null/null_lhs.rs b/tests/ui/mir/null/null_lhs.rs new file mode 100644 index 00000000000..fd3bc3a78b8 --- /dev/null +++ b/tests/ui/mir/null/null_lhs.rs @@ -0,0 +1,10 @@ +//@ run-fail +//@ compile-flags: -C debug-assertions +//@ error-pattern: null pointer dereference occured + +fn main() { + let ptr: *mut u32 = std::ptr::null_mut(); + unsafe { + *(ptr) = 42; + } +} diff --git a/tests/ui/mir/null/null_rhs.rs b/tests/ui/mir/null/null_rhs.rs new file mode 100644 index 00000000000..45c8beb3fe8 --- /dev/null +++ b/tests/ui/mir/null/null_rhs.rs @@ -0,0 +1,10 @@ +//@ run-fail +//@ compile-flags: -C debug-assertions +//@ error-pattern: null pointer dereference occured + +fn main() { + let ptr: *mut u32 = std::ptr::null_mut(); + unsafe { + let _v = *ptr; + } +} diff --git a/tests/ui/mir/null/place_without_read.rs b/tests/ui/mir/null/place_without_read.rs new file mode 100644 index 00000000000..d6bfb089b01 --- /dev/null +++ b/tests/ui/mir/null/place_without_read.rs @@ -0,0 +1,10 @@ +// Make sure that we don't insert a check for places that do not read. +//@ run-pass +//@ compile-flags: -C debug-assertions + +fn main() { + let ptr: *const u16 = std::ptr::null(); + unsafe { + let _ = *ptr; + } +} diff --git a/tests/ui/mir/null/two_pointers.rs b/tests/ui/mir/null/two_pointers.rs new file mode 100644 index 00000000000..d9f0687fe0d --- /dev/null +++ b/tests/ui/mir/null/two_pointers.rs @@ -0,0 +1,12 @@ +//@ run-fail +//@ compile-flags: -C debug-assertions +//@ error-pattern: null pointer dereference occured + +fn main() { + let ptr = std::ptr::null(); + let mut dest = 0u32; + let dest_ptr = &mut dest as *mut u32; + unsafe { + *dest_ptr = *(ptr); + } +} diff --git a/tests/ui/mir/null/zero_sized_access.rs b/tests/ui/mir/null/zero_sized_access.rs new file mode 100644 index 00000000000..e8aaf820c49 --- /dev/null +++ b/tests/ui/mir/null/zero_sized_access.rs @@ -0,0 +1,15 @@ +// Make sure that we don't insert a check for zero-sized reads or writes to +// null, because they are allowed. +//@ run-pass +//@ compile-flags: -C debug-assertions + +fn main() { + let ptr: *mut () = std::ptr::null_mut(); + unsafe { + *(ptr) = (); + } + let ptr1: *const () = std::ptr::null_mut(); + unsafe { + let _ptr = *ptr1; + } +} diff --git a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr index aa4a2760ffd..a559a95a334 100644 --- a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr +++ b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr @@ -1,16 +1,15 @@ error[E0271]: expected `{closure@fallback-closure-wrap.rs:18:40}` to be a closure that returns `()`, but it returns `!` - --> $DIR/fallback-closure-wrap.rs:18:31 + --> $DIR/fallback-closure-wrap.rs:19:9 | -LL | let error = Closure::wrap(Box::new(move || { - | _______________________________^ -LL | | -LL | | panic!("Can't connect to server."); -LL | | }) as Box<dyn FnMut()>); - | |______^ expected `()`, found `!` +LL | let error = Closure::wrap(Box::new(move || { + | ------- this closure +LL | panic!("Can't connect to server."); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `!` | = note: expected unit type `()` found type `!` = note: required for the cast from `Box<{closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47}>` to `Box<dyn FnMut()>` + = note: this error originates in the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/never_type/fallback-closure-wrap.rs b/tests/ui/never_type/fallback-closure-wrap.rs index 27020289c68..e97505b6bc0 100644 --- a/tests/ui/never_type/fallback-closure-wrap.rs +++ b/tests/ui/never_type/fallback-closure-wrap.rs @@ -16,8 +16,8 @@ use std::marker::PhantomData; fn main() { let error = Closure::wrap(Box::new(move || { - //[fallback]~^ to be a closure that returns `()`, but it returns `!` panic!("Can't connect to server."); + //[fallback]~^ to be a closure that returns `()`, but it returns `!` }) as Box<dyn FnMut()>); } diff --git a/tests/ui/recursion/recursion.rs b/tests/ui/recursion/recursion.rs index f3c633983b1..ce56fe974b7 100644 --- a/tests/ui/recursion/recursion.rs +++ b/tests/ui/recursion/recursion.rs @@ -1,6 +1,7 @@ //@ build-fail //@ compile-flags:-C overflow-checks=off -//@ normalize-stderr: ".nll/" -> "/" +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" enum Nil {NilValue} struct Cons<T> {head:isize, tail:T} diff --git a/tests/ui/recursion/recursion.stderr b/tests/ui/recursion/recursion.stderr index 7a9f04d4bd6..cb9f67ba741 100644 --- a/tests/ui/recursion/recursion.stderr +++ b/tests/ui/recursion/recursion.stderr @@ -1,15 +1,15 @@ error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>` - --> $DIR/recursion.rs:18:11 + --> $DIR/recursion.rs:19:11 | LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `test` defined here - --> $DIR/recursion.rs:16:1 + --> $DIR/recursion.rs:17:1 | LL | fn test<T:Dot> (n:isize, i:isize, first:T, second:T) ->isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/recursion/recursion.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/resolve/issue-3907-2.stderr b/tests/ui/resolve/issue-3907-2.stderr index 4ab72a42eb8..40cdfb7a302 100644 --- a/tests/ui/resolve/issue-3907-2.stderr +++ b/tests/ui/resolve/issue-3907-2.stderr @@ -5,7 +5,7 @@ LL | fn bar(_x: Foo) {} | ^^^ `issue_3907::Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/auxiliary/issue-3907.rs:2:8 | LL | fn bar(); diff --git a/tests/ui/self/arbitrary-self-types-dyn-incompatible.curr.stderr b/tests/ui/self/arbitrary-self-types-dyn-incompatible.curr.stderr index 3e018995ba5..8382b4867e2 100644 --- a/tests/ui/self/arbitrary-self-types-dyn-incompatible.curr.stderr +++ b/tests/ui/self/arbitrary-self-types-dyn-incompatible.curr.stderr @@ -8,7 +8,7 @@ LL | let x = Rc::new(5usize) as Rc<dyn Foo>; | ^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/arbitrary-self-types-dyn-incompatible.rs:8:18 | LL | trait Foo { @@ -27,7 +27,7 @@ LL | let x = Rc::new(5usize) as Rc<dyn Foo>; | ^^^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/arbitrary-self-types-dyn-incompatible.rs:8:18 | LL | trait Foo { diff --git a/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr b/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr index 12c93d58537..d324f4641cf 100644 --- a/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr @@ -8,7 +8,7 @@ LL | let x = Rc::new(5usize) as Rc<dyn Foo>; | ^^^^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/arbitrary-self-types-dyn-incompatible.rs:8:18 | LL | trait Foo { diff --git a/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr b/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr index 08c744979f5..28427161e87 100644 --- a/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr +++ b/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr @@ -5,7 +5,7 @@ LL | pub desc: &'static dyn Qux, | ^^^^^^^ `Qux` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/unsizing-wfcheck-issue-127299.rs:4:8 | LL | trait Qux { @@ -44,7 +44,7 @@ LL | static FOO: &Lint = &Lint { desc: "desc" }; | ^^^^^^ `Qux` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/unsizing-wfcheck-issue-127299.rs:4:8 | LL | trait Qux { @@ -68,7 +68,7 @@ LL | static FOO: &Lint = &Lint { desc: "desc" }; | ^^^^^^ `Qux` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/unsizing-wfcheck-issue-127299.rs:4:8 | LL | trait Qux { diff --git a/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr b/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr index cb0e7fce910..ae009d26029 100644 --- a/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr +++ b/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr @@ -5,7 +5,7 @@ LL | fn bar(x: &dyn Trait) {} | ^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-references-self.rs:2:22 | LL | trait Trait { @@ -25,7 +25,7 @@ LL | fn foo(x: &dyn Other) {} | ^^^^^^^^^ `Other` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-references-self.rs:11:14 | LL | trait Other: Sized {} diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021.stderr index 2efcad1e7bd..742011ad0c0 100644 --- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021.stderr +++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021.stderr @@ -18,7 +18,7 @@ LL | fn f(a: dyn A) -> dyn A; | ^^^^^ `A` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:3:10 | LL | trait A: Sized { @@ -46,7 +46,7 @@ LL | fn f(a: dyn B) -> dyn B; | ^^^^^ `B` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:9:8 | LL | trait B { diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self.stderr index ecb3ee9185f..843c139851d 100644 --- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self.stderr +++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self.stderr @@ -18,7 +18,7 @@ LL | fn f(a: A) -> A; | ^ `A` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-should-use-self.rs:2:10 | LL | trait A: Sized { @@ -46,7 +46,7 @@ LL | fn f(a: B) -> B; | ^ `B` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-should-use-self.rs:8:8 | LL | trait B { diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr index 696840d3ba4..e2250807603 100644 --- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr +++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr @@ -5,7 +5,7 @@ LL | fn bar(x: &dyn Trait) {} | ^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/dyn-incompatible-trait-should-use-where-sized.rs:5:8 | LL | trait Trait { diff --git a/tests/ui/suggestions/issue-116434-2015.stderr b/tests/ui/suggestions/issue-116434-2015.stderr index 508c3ec5e4f..e7b8cd2f101 100644 --- a/tests/ui/suggestions/issue-116434-2015.stderr +++ b/tests/ui/suggestions/issue-116434-2015.stderr @@ -47,7 +47,7 @@ LL | fn foo() -> Clone; | = note: the trait is not dyn compatible because it requires `Self: Sized` = note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> help: there is an associated type with the same name | LL | fn foo() -> Self::Clone; @@ -74,7 +74,7 @@ LL | fn handle() -> DbHandle; | ^^^^^^^^ `DbHandle` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-116434-2015.rs:14:17 | LL | trait DbHandle: Sized {} diff --git a/tests/ui/suggestions/issue-98500.stderr b/tests/ui/suggestions/issue-98500.stderr index 97b712acfcb..ec984c0d60e 100644 --- a/tests/ui/suggestions/issue-98500.stderr +++ b/tests/ui/suggestions/issue-98500.stderr @@ -5,7 +5,7 @@ LL | struct S(Box<dyn B>); | ^^^^^ `B` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/auxiliary/dyn-incompatible.rs:4:8 | LL | fn f(); diff --git a/tests/ui/traits/alias/generic-default-in-dyn.stderr b/tests/ui/traits/alias/generic-default-in-dyn.stderr index 1ab9e6d5c5c..c6f8ab4137b 100644 --- a/tests/ui/traits/alias/generic-default-in-dyn.stderr +++ b/tests/ui/traits/alias/generic-default-in-dyn.stderr @@ -15,7 +15,7 @@ LL | struct Foo<T>(dyn SendEqAlias<T>); | ^^^^^^^^^^^^^^ `SendEqAlias` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/generic-default-in-dyn.rs:1:24 | LL | trait SendEqAlias<T> = PartialEq; @@ -30,7 +30,7 @@ LL | struct Bar<T>(dyn SendEqAlias<T>, T); | ^^^^^^^^^^^^^^ `SendEqAlias` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/generic-default-in-dyn.rs:1:24 | LL | trait SendEqAlias<T> = PartialEq; diff --git a/tests/ui/traits/alias/object-fail.stderr b/tests/ui/traits/alias/object-fail.stderr index 52ce79a4597..d60d8843407 100644 --- a/tests/ui/traits/alias/object-fail.stderr +++ b/tests/ui/traits/alias/object-fail.stderr @@ -5,7 +5,7 @@ LL | let _: &dyn EqAlias = &123; | ^^^^^^^ `EqAlias` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: ...because it uses `Self` as a type parameter diff --git a/tests/ui/traits/alias/self-in-const-generics.stderr b/tests/ui/traits/alias/self-in-const-generics.stderr index 3c799492591..b5538cb6e2f 100644 --- a/tests/ui/traits/alias/self-in-const-generics.stderr +++ b/tests/ui/traits/alias/self-in-const-generics.stderr @@ -5,7 +5,7 @@ LL | fn foo(x: &dyn BB) {} | ^^ `BB` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/self-in-const-generics.rs:7:12 | LL | trait BB = Bar<{ 2 + 1 }>; diff --git a/tests/ui/traits/alias/self-in-generics.stderr b/tests/ui/traits/alias/self-in-generics.stderr index 5639b2b44a1..afe4dff45ed 100644 --- a/tests/ui/traits/alias/self-in-generics.stderr +++ b/tests/ui/traits/alias/self-in-generics.stderr @@ -5,7 +5,7 @@ LL | pub fn f(_f: &dyn SelfInput) {} | ^^^^^^^^^ `SelfInput` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/self-in-generics.rs:6:23 | LL | pub trait SelfInput = Fn(&mut Self); diff --git a/tests/ui/traits/issue-20692.stderr b/tests/ui/traits/issue-20692.stderr index 50ea7cde961..32e29de49a1 100644 --- a/tests/ui/traits/issue-20692.stderr +++ b/tests/ui/traits/issue-20692.stderr @@ -5,7 +5,7 @@ LL | &dyn Array; | ^^^^^^^^^^ `Array` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-20692.rs:1:14 | LL | trait Array: Sized + Copy {} @@ -21,7 +21,7 @@ LL | let _ = x | ^ `Array` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-20692.rs:1:14 | LL | trait Array: Sized + Copy {} diff --git a/tests/ui/traits/issue-28576.stderr b/tests/ui/traits/issue-28576.stderr index ba113d573d6..ba61ce98554 100644 --- a/tests/ui/traits/issue-28576.stderr +++ b/tests/ui/traits/issue-28576.stderr @@ -27,7 +27,7 @@ LL | | <Assoc=()> | |________________________^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-28576.rs:5:16 | LL | pub trait Bar: Foo<Assoc=()> { diff --git a/tests/ui/traits/issue-38404.stderr b/tests/ui/traits/issue-38404.stderr index f9e592255dd..63269d3379e 100644 --- a/tests/ui/traits/issue-38404.stderr +++ b/tests/ui/traits/issue-38404.stderr @@ -5,7 +5,7 @@ LL | trait C<T>: A<dyn B<T, Output = usize>> {} | ^^^^^^^^^^^^^^^^^^^^ `B` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-38404.rs:1:13 | LL | trait A<T>: std::ops::Add<Self> + Sized {} @@ -20,7 +20,7 @@ LL | trait C<T>: A<dyn B<T, Output = usize>> {} | ^^^^^^^^^^^^^^^^^^^^ `B` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-38404.rs:1:13 | LL | trait A<T>: std::ops::Add<Self> + Sized {} @@ -36,7 +36,7 @@ LL | trait C<T>: A<dyn B<T, Output = usize>> {} | ^^^^^^^^^^^^^^^^^^^^ `B` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-38404.rs:1:13 | LL | trait A<T>: std::ops::Add<Self> + Sized {} diff --git a/tests/ui/traits/issue-38604.stderr b/tests/ui/traits/issue-38604.stderr index 94f9c1540ad..e6a6b44e730 100644 --- a/tests/ui/traits/issue-38604.stderr +++ b/tests/ui/traits/issue-38604.stderr @@ -5,7 +5,7 @@ LL | let _f: Box<dyn Foo> = | ^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-38604.rs:2:22 | LL | trait Foo where u32: Q<Self> { @@ -21,7 +21,7 @@ LL | Box::new(()); | ^^^^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-38604.rs:2:22 | LL | trait Foo where u32: Q<Self> { diff --git a/tests/ui/traits/issue-72410.stderr b/tests/ui/traits/issue-72410.stderr index 002345bff84..c9e133437dd 100644 --- a/tests/ui/traits/issue-72410.stderr +++ b/tests/ui/traits/issue-72410.stderr @@ -5,7 +5,7 @@ LL | where for<'a> &'a mut [dyn Bar]: ; | ^^^^^^^^^^^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-72410.rs:13:8 | LL | pub trait Bar { diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index c97158a5b76..58c558d6685 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -143,7 +143,7 @@ LL | <dyn C>::A; | ^^^^^ `assoc_const::C` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/item-privacy.rs:25:15 | LL | const A: u8 = 0; diff --git a/tests/ui/traits/missing-for-type-in-impl.e2015.stderr b/tests/ui/traits/missing-for-type-in-impl.e2015.stderr index 682d18842b8..c8a1329e3d0 100644 --- a/tests/ui/traits/missing-for-type-in-impl.e2015.stderr +++ b/tests/ui/traits/missing-for-type-in-impl.e2015.stderr @@ -41,7 +41,7 @@ LL | impl Foo<i64> { | ^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/missing-for-type-in-impl.rs:4:8 | LL | trait Foo<T> { diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr index 8448890c084..43b69d0b50e 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr @@ -14,7 +14,7 @@ LL | let x: &dyn Foo = &(); | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/supertrait-dyn-compatibility.rs:4:12 | LL | trait Foo: for<T> Bar<T> {} @@ -31,7 +31,7 @@ LL | let x: &dyn Foo = &(); | ^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/supertrait-dyn-compatibility.rs:4:12 | LL | trait Foo: for<T> Bar<T> {} @@ -47,7 +47,7 @@ LL | needs_bar(x); | ^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/supertrait-dyn-compatibility.rs:4:12 | LL | trait Foo: for<T> Bar<T> {} diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs index 2a301788525..2a301788525 100644 --- a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs +++ b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr index 38dcdbd0af2..38dcdbd0af2 100644 --- a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr +++ b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.rs index 23f3666618b..23f3666618b 100644 --- a/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs +++ b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.rs diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.stderr index 3c352c9889c..3c352c9889c 100644 --- a/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr +++ b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.stderr diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr index ae3762704c6..b4bbd65b2f4 100644 --- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr +++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr @@ -20,7 +20,7 @@ LL | let b: &dyn FromResidual = &(); | ^^^ `FromResidual` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:2:8 | LL | trait FromResidual<R = <Self as Try>::Residual> { @@ -44,7 +44,7 @@ LL | let b: &dyn FromResidual = &(); | ^^^^^^^^^^^^^^^^^ `FromResidual` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:2:8 | LL | trait FromResidual<R = <Self as Try>::Residual> { diff --git a/tests/ui/traits/object/macro-matcher.stderr b/tests/ui/traits/object/macro-matcher.stderr index ab0fc213c9f..3c668ce99c7 100644 --- a/tests/ui/traits/object/macro-matcher.stderr +++ b/tests/ui/traits/object/macro-matcher.stderr @@ -12,7 +12,7 @@ LL | m!(dyn Copy + Send + 'static); | = note: the trait is not dyn compatible because it requires `Self: Sized` = note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> error: aborting due to 2 previous errors diff --git a/tests/ui/traits/object/print_vtable_sizes.rs b/tests/ui/traits/object/print_vtable_sizes.rs deleted file mode 100644 index 2b1745da5f3..00000000000 --- a/tests/ui/traits/object/print_vtable_sizes.rs +++ /dev/null @@ -1,62 +0,0 @@ -//@ check-pass -//@ compile-flags: -Z print-vtable-sizes -#![crate_type = "lib"] - -trait A<T: help::V>: AsRef<[T::V]> + AsMut<[T::V]> {} - -trait B<T>: AsRef<T> + AsRef<T> + AsRef<T> + AsRef<T> {} - -trait C { - fn x() {} // not dyn-compatible, shouldn't be reported -} - -// This does not have any upcasting cost, -// because both `Send` and `Sync` are traits -// with no methods -trait D: Send + Sync + help::MarkerWithSuper {} - -// This can't have no cost without reordering, -// because `Super::f`. -trait E: help::MarkerWithSuper + Send + Sync {} - -trait F { - fn a(&self); - fn b(&self); - fn c(&self); - - fn d() -> Self - where - Self: Sized; -} - -trait G: AsRef<u8> + AsRef<u16> + help::MarkerWithSuper { - fn a(&self); - fn b(&self); - fn c(&self); - fn d(&self); - fn e(&self); - - fn f() -> Self - where - Self: Sized; -} - -// Traits with the same name -const _: () = { - trait S {} -}; -const _: () = { - trait S {} -}; - -mod help { - pub trait V { - type V; - } - - pub trait MarkerWithSuper: Super {} - - pub trait Super { - fn f(&self); - } -} diff --git a/tests/ui/traits/object/print_vtable_sizes.stdout b/tests/ui/traits/object/print_vtable_sizes.stdout deleted file mode 100644 index 4daf4769576..00000000000 --- a/tests/ui/traits/object/print_vtable_sizes.stdout +++ /dev/null @@ -1,11 +0,0 @@ -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "A", "entries": "6", "entries_ignoring_upcasting": "5", "entries_for_upcasting": "1", "upcasting_cost_percent": "20" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "G", "entries": "13", "entries_ignoring_upcasting": "11", "entries_for_upcasting": "2", "upcasting_cost_percent": "18.181818181818183" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "B", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "D", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "E", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "F", "entries": "6", "entries_ignoring_upcasting": "6", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "help::MarkerWithSuper", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "help::Super", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "help::V", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } diff --git a/tests/ui/traits/object/safety.stderr b/tests/ui/traits/object/safety.stderr index eab59f39c28..593e42619f4 100644 --- a/tests/ui/traits/object/safety.stderr +++ b/tests/ui/traits/object/safety.stderr @@ -5,7 +5,7 @@ LL | let _: &dyn Tr = &St; | ^^^ `Tr` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/safety.rs:4:8 | LL | trait Tr { @@ -30,7 +30,7 @@ LL | let _: &dyn Tr = &St; | ^^^^^^^ `Tr` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/safety.rs:4:8 | LL | trait Tr { diff --git a/tests/ui/traits/on_unimplemented_long_types.rs b/tests/ui/traits/on_unimplemented_long_types.rs index 98749b8db7a..c652b71e51a 100644 --- a/tests/ui/traits/on_unimplemented_long_types.rs +++ b/tests/ui/traits/on_unimplemented_long_types.rs @@ -1,5 +1,6 @@ //@ compile-flags: --diagnostic-width=60 -Z write-long-types-to-disk=yes -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" pub fn foo() -> impl std::fmt::Display { //~^ ERROR doesn't implement `std::fmt::Display` diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr index bddc5695696..5722f4006ff 100644 --- a/tests/ui/traits/on_unimplemented_long_types.stderr +++ b/tests/ui/traits/on_unimplemented_long_types.stderr @@ -1,5 +1,5 @@ error[E0277]: `Option<Option<Option<...>>>` doesn't implement `std::fmt::Display` - --> $DIR/on_unimplemented_long_types.rs:4:17 + --> $DIR/on_unimplemented_long_types.rs:5:17 | LL | pub fn foo() -> impl std::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^^ `Option<Option<Option<...>>>` cannot be formatted with the default formatter @@ -13,11 +13,11 @@ LL | | ))))))))))), LL | | ))))))))))) | |_______________- return type was inferred to be `Option<Option<Option<...>>>` here | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/traits/on_unimplemented_long_types/on_unimplemented_long_types.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console = help: the trait `std::fmt::Display` is not implemented for `Option<Option<Option<...>>>` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: the full name for the type has been written to '$TEST_BUILD_DIR/traits/on_unimplemented_long_types/on_unimplemented_long_types.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/traits/sized-coniductive.rs b/tests/ui/traits/sized-coniductive.rs deleted file mode 100644 index 5f63b166f98..00000000000 --- a/tests/ui/traits/sized-coniductive.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ check-pass -// https://github.com/rust-lang/rust/issues/129541 - -#[derive(Clone)] -struct Test { - field: std::borrow::Cow<'static, [Self]>, -} - -#[derive(Clone)] -struct Hello { - a: <[Hello] as std::borrow::ToOwned>::Owned, -} - -fn main(){} diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs deleted file mode 100644 index defb39aae06..00000000000 --- a/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Regression test for #129541 - -//@ check-pass - -trait Bound {} -trait Normalize { - type Assoc; -} - -impl<T: Bound> Normalize for T { - type Assoc = T; -} - -impl<T: Bound> Normalize for [T] { - type Assoc = T; -} - -impl Bound for Hello {} -struct Hello { - a: <[Hello] as Normalize>::Assoc, -} - -fn main() {} diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs index d4339dd54d6..4fbcbefec91 100644 --- a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs +++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs @@ -1,5 +1,6 @@ // Regression test for #129541 +//@ revisions: unique multiple //@ check-pass trait Bound {} @@ -7,6 +8,10 @@ trait Normalize { type Assoc; } +#[cfg(multiple)] +impl<T: Bound> Normalize for T { + type Assoc = T; +} impl<T: Bound> Normalize for [T] { type Assoc = T; } diff --git a/tests/ui/traits/test-2.stderr b/tests/ui/traits/test-2.stderr index 8915e490b4d..6a6cb503aa4 100644 --- a/tests/ui/traits/test-2.stderr +++ b/tests/ui/traits/test-2.stderr @@ -33,7 +33,7 @@ LL | (Box::new(10) as Box<dyn bar>).dup(); | ^^^^^^^^^^^^ `bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/test-2.rs:4:30 | LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); } @@ -56,7 +56,7 @@ LL | (Box::new(10) as Box<dyn bar>).dup(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/test-2.rs:4:30 | LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); } @@ -79,7 +79,7 @@ LL | (Box::new(10) as Box<dyn bar>).dup(); | ^^^^^^^^^^^^ `bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/test-2.rs:4:30 | LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); } diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.rs new file mode 100644 index 00000000000..796ddec46ac --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.rs @@ -0,0 +1,27 @@ +#![feature(rustc_attrs)] + +// Test for <https://github.com/rust-lang/rust/issues/135316>. + +trait Supertrait<T> { + fn _print_numbers(&self, mem: &[usize; 100]) { + } +} +impl<T> Supertrait<T> for () {} + +trait Trait<T, U>: Supertrait<T> + Supertrait<U> { + fn say_hello(&self, _: &usize) { + } +} +impl<T, U> Trait<T, U> for () {} + +// We should observe compatibility between these two vtables. + +#[rustc_dump_vtable] +type First = dyn for<'a> Trait<&'static (), &'a ()>; +//~^ ERROR vtable entries + +#[rustc_dump_vtable] +type Second = dyn Trait<&'static (), &'static ()>; +//~^ ERROR vtable entries + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.stderr b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.stderr new file mode 100644 index 00000000000..24fa1650ca1 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.stderr @@ -0,0 +1,26 @@ +error: vtable entries: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(<dyn for<'a> Trait<&(), &'a ()> as Supertrait<&()>>::_print_numbers - shim(reify)), + Method(<dyn for<'a> Trait<&(), &'a ()> as Trait<&(), &()>>::say_hello - shim(reify)), + ] + --> $DIR/multiple-supertraits-modulo-binder-vtable.rs:20:1 + | +LL | type First = dyn for<'a> Trait<&'static (), &'a ()>; + | ^^^^^^^^^^ + +error: vtable entries: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(<dyn Trait<&(), &()> as Supertrait<&()>>::_print_numbers - shim(reify)), + Method(<dyn Trait<&(), &()> as Trait<&(), &()>>::say_hello - shim(reify)), + ] + --> $DIR/multiple-supertraits-modulo-binder-vtable.rs:24:1 + | +LL | type Second = dyn Trait<&'static (), &'static ()>; + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs new file mode 100644 index 00000000000..510a1471af2 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs @@ -0,0 +1,26 @@ +//@ run-pass +//@ check-run-results + +// Test for <https://github.com/rust-lang/rust/issues/135316>. + +#![feature(trait_upcasting)] + +trait Supertrait<T> { + fn _print_numbers(&self, mem: &[usize; 100]) { + println!("{mem:?}"); + } +} +impl<T> Supertrait<T> for () {} + +trait Trait<T, U>: Supertrait<T> + Supertrait<U> { + fn say_hello(&self, _: &usize) { + println!("Hello!"); + } +} +impl<T, U> Trait<T, U> for () {} + +fn main() { + (&() as &'static dyn for<'a> Trait<&'static (), &'a ()> + as &'static dyn Trait<&'static (), &'static ()>) + .say_hello(&0); +} diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.run.stdout b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.run.stdout new file mode 100644 index 00000000000..10ddd6d257e --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.run.stdout @@ -0,0 +1 @@ +Hello! diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs new file mode 100644 index 00000000000..69a71859a5c --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs @@ -0,0 +1,37 @@ +#![feature(rustc_attrs)] +#![feature(trait_upcasting)] + +// Test for <https://github.com/rust-lang/rust/issues/135315>. + +trait Supertrait<T> { + fn _print_numbers(&self, mem: &[usize; 100]) { + println!("{mem:?}"); + } +} +impl<T> Supertrait<T> for () {} + +trait Identity { + type Selff; +} +impl<Selff> Identity for Selff { + type Selff = Selff; +} + +trait Middle<T>: Supertrait<()> + Supertrait<T> { + fn say_hello(&self, _: &usize) { + println!("Hello!"); + } +} +impl<T> Middle<T> for () {} + +trait Trait: Middle<<() as Identity>::Selff> {} + +#[rustc_dump_vtable] +impl Trait for () {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] +type Virtual = dyn Middle<()>; +//~^ ERROR vtable entries + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr new file mode 100644 index 00000000000..757e2dc6939 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr @@ -0,0 +1,26 @@ +error: vtable entries: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(<() as Supertrait<()>>::_print_numbers), + Method(<() as Middle<()>>::say_hello), + ] + --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:30:1 + | +LL | impl Trait for () {} + | ^^^^^^^^^^^^^^^^^ + +error: vtable entries: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(<dyn Middle<()> as Supertrait<()>>::_print_numbers - shim(reify)), + Method(<dyn Middle<()> as Middle<()>>::say_hello - shim(reify)), + ] + --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:34:1 + | +LL | type Virtual = dyn Middle<()>; + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs new file mode 100644 index 00000000000..c744e6e64f5 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs @@ -0,0 +1,34 @@ +//@ run-pass +//@ check-run-results + +#![feature(trait_upcasting)] + +// Test for <https://github.com/rust-lang/rust/issues/135315>. + +trait Supertrait<T> { + fn _print_numbers(&self, mem: &[usize; 100]) { + println!("{mem:?}"); + } +} +impl<T> Supertrait<T> for () {} + +trait Identity { + type Selff; +} +impl<Selff> Identity for Selff { + type Selff = Selff; +} + +trait Middle<T>: Supertrait<()> + Supertrait<T> { + fn say_hello(&self, _: &usize) { + println!("Hello!"); + } +} +impl<T> Middle<T> for () {} + +trait Trait: Middle<<() as Identity>::Selff> {} +impl Trait for () {} + +fn main() { + (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0); +} diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.run.stdout b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.run.stdout new file mode 100644 index 00000000000..10ddd6d257e --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.run.stdout @@ -0,0 +1 @@ +Hello! diff --git a/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs b/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs new file mode 100644 index 00000000000..6cd74b6c7f7 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs @@ -0,0 +1,30 @@ +//@ run-pass + +#![feature(trait_upcasting)] + +trait Super<U> { + fn call(&self) + where + U: HigherRanked, + { + } +} + +impl<T> Super<T> for () {} + +trait HigherRanked {} +impl HigherRanked for for<'a> fn(&'a ()) {} + +trait Unimplemented {} +impl<T: Unimplemented> HigherRanked for T {} + +trait Sub: Super<fn(&'static ())> + Super<for<'a> fn(&'a ())> {} +impl Sub for () {} + +fn main() { + let a: &dyn Sub = &(); + // `Super<fn(&'static ())>` and `Super<for<'a> fn(&'a ())>` have different + // vtables and we need to upcast to the latter! + let b: &dyn Super<for<'a> fn(&'a ())> = a; + b.call(); +} diff --git a/tests/ui/traits/vtable/multiple-markers.rs b/tests/ui/traits/vtable/multiple-markers.rs index 8a9e7a006cf..8eba5135582 100644 --- a/tests/ui/traits/vtable/multiple-markers.rs +++ b/tests/ui/traits/vtable/multiple-markers.rs @@ -2,8 +2,7 @@ // // This test makes sure that multiple marker (method-less) traits can reuse the // same pointer for upcasting. -// -//@ build-fail + #![crate_type = "lib"] #![feature(rustc_attrs)] @@ -17,17 +16,13 @@ trait T { fn method(&self) {} } -#[rustc_dump_vtable] -trait A: M0 + M1 + M2 + T {} //~ error: vtable entries for `<S as A>`: +trait A: M0 + M1 + M2 + T {} -#[rustc_dump_vtable] -trait B: M0 + M1 + T + M2 {} //~ error: vtable entries for `<S as B>`: +trait B: M0 + M1 + T + M2 {} -#[rustc_dump_vtable] -trait C: M0 + T + M1 + M2 {} //~ error: vtable entries for `<S as C>`: +trait C: M0 + T + M1 + M2 {} -#[rustc_dump_vtable] -trait D: T + M0 + M1 + M2 {} //~ error: vtable entries for `<S as D>`: +trait D: T + M0 + M1 + M2 {} struct S; @@ -35,13 +30,21 @@ impl M0 for S {} impl M1 for S {} impl M2 for S {} impl T for S {} + +#[rustc_dump_vtable] impl A for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl B for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl C for S {} -impl D for S {} +//~^ ERROR vtable entries -pub fn require_vtables() { - fn require_vtables(_: &dyn A, _: &dyn B, _: &dyn C, _: &dyn D) {} +#[rustc_dump_vtable] +impl D for S {} +//~^ ERROR vtable entries - require_vtables(&S, &S, &S, &S) -} +fn main() {} diff --git a/tests/ui/traits/vtable/multiple-markers.stderr b/tests/ui/traits/vtable/multiple-markers.stderr index 36ac8b24eb5..35dd3c2516d 100644 --- a/tests/ui/traits/vtable/multiple-markers.stderr +++ b/tests/ui/traits/vtable/multiple-markers.stderr @@ -1,46 +1,46 @@ -error: vtable entries for `<S as A>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as T>::method), ] - --> $DIR/multiple-markers.rs:21:1 + --> $DIR/multiple-markers.rs:35:1 | -LL | trait A: M0 + M1 + M2 + T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl A for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as B>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as T>::method), ] - --> $DIR/multiple-markers.rs:24:1 + --> $DIR/multiple-markers.rs:39:1 | -LL | trait B: M0 + M1 + T + M2 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl B for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as C>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as T>::method), ] - --> $DIR/multiple-markers.rs:27:1 + --> $DIR/multiple-markers.rs:43:1 | -LL | trait C: M0 + T + M1 + M2 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl C for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as D>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as T>::method), ] - --> $DIR/multiple-markers.rs:30:1 + --> $DIR/multiple-markers.rs:47:1 | -LL | trait D: T + M0 + M1 + M2 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl D for S {} + | ^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/ui/traits/vtable/vtable-diamond.rs b/tests/ui/traits/vtable/vtable-diamond.rs index 2cfa86c526d..56053f6d026 100644 --- a/tests/ui/traits/vtable/vtable-diamond.rs +++ b/tests/ui/traits/vtable/vtable-diamond.rs @@ -1,44 +1,37 @@ -//@ build-fail #![feature(rustc_attrs)] -#[rustc_dump_vtable] trait A { fn foo_a(&self) {} } -#[rustc_dump_vtable] trait B: A { fn foo_b(&self) {} } -#[rustc_dump_vtable] trait C: A { - //~^ error vtable fn foo_c(&self) {} } -#[rustc_dump_vtable] trait D: B + C { - //~^ error vtable fn foo_d(&self) {} } struct S; +#[rustc_dump_vtable] impl A for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl B for S {} -impl C for S {} -impl D for S {} +//~^ ERROR vtable entries -fn foo(d: &dyn D) { - d.foo_d(); -} +#[rustc_dump_vtable] +impl C for S {} +//~^ ERROR vtable entries -fn bar(d: &dyn C) { - d.foo_c(); -} +#[rustc_dump_vtable] +impl D for S {} +//~^ ERROR vtable entries -fn main() { - foo(&S); - bar(&S); -} +fn main() {} diff --git a/tests/ui/traits/vtable/vtable-diamond.stderr b/tests/ui/traits/vtable/vtable-diamond.stderr index f3718c5d852..4644bf339b1 100644 --- a/tests/ui/traits/vtable/vtable-diamond.stderr +++ b/tests/ui/traits/vtable/vtable-diamond.stderr @@ -1,29 +1,52 @@ -error: vtable entries for `<S as D>`: [ +error: vtable entries: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(<S as A>::foo_a), + ] + --> $DIR/vtable-diamond.rs:22:1 + | +LL | impl A for S {} + | ^^^^^^^^^^^^ + +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as A>::foo_a), Method(<S as B>::foo_b), + ] + --> $DIR/vtable-diamond.rs:26:1 + | +LL | impl B for S {} + | ^^^^^^^^^^^^ + +error: vtable entries: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(<S as A>::foo_a), Method(<S as C>::foo_c), - TraitVPtr(<S as C>), - Method(<S as D>::foo_d), ] - --> $DIR/vtable-diamond.rs:21:1 + --> $DIR/vtable-diamond.rs:30:1 | -LL | trait D: B + C { - | ^^^^^^^^^^^^^^ +LL | impl C for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as C>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as A>::foo_a), + Method(<S as B>::foo_b), Method(<S as C>::foo_c), + TraitVPtr(<S as C>), + Method(<S as D>::foo_d), ] - --> $DIR/vtable-diamond.rs:15:1 + --> $DIR/vtable-diamond.rs:34:1 | -LL | trait C: A { - | ^^^^^^^^^^ +LL | impl D for S {} + | ^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/traits/vtable/vtable-dyn-incompatible.rs b/tests/ui/traits/vtable/vtable-dyn-incompatible.rs index 64a8138bdcf..fb19dec4ace 100644 --- a/tests/ui/traits/vtable/vtable-dyn-incompatible.rs +++ b/tests/ui/traits/vtable/vtable-dyn-incompatible.rs @@ -1,15 +1,16 @@ -//@ build-fail #![feature(rustc_attrs)] // Ensure that dyn-incompatible methods in Iterator does not generate // vtable entries. -#[rustc_dump_vtable] trait A: Iterator {} -//~^ error vtable impl<T> A for T where T: Iterator {} +#[rustc_dump_vtable] +type Test = dyn A<Item=u8>; +//~^ error vtable + fn foo(_a: &mut dyn A<Item=u8>) { } diff --git a/tests/ui/traits/vtable/vtable-dyn-incompatible.stderr b/tests/ui/traits/vtable/vtable-dyn-incompatible.stderr index e442c3eac00..c80a763998b 100644 --- a/tests/ui/traits/vtable/vtable-dyn-incompatible.stderr +++ b/tests/ui/traits/vtable/vtable-dyn-incompatible.stderr @@ -1,16 +1,16 @@ -error: vtable entries for `<std::vec::IntoIter<u8> as A>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, - Method(<std::vec::IntoIter<u8> as Iterator>::next), - Method(<std::vec::IntoIter<u8> as Iterator>::size_hint), - Method(<std::vec::IntoIter<u8> as Iterator>::advance_by), - Method(<std::vec::IntoIter<u8> as Iterator>::nth), + Method(<dyn A<Item = u8> as Iterator>::next - shim(reify)), + Method(<dyn A<Item = u8> as Iterator>::size_hint - shim(reify)), + Method(<dyn A<Item = u8> as Iterator>::advance_by - shim(reify)), + Method(<dyn A<Item = u8> as Iterator>::nth - shim(reify)), ] - --> $DIR/vtable-dyn-incompatible.rs:8:1 + --> $DIR/vtable-dyn-incompatible.rs:11:1 | -LL | trait A: Iterator {} - | ^^^^^^^^^^^^^^^^^ +LL | type Test = dyn A<Item=u8>; + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/traits/vtable/vtable-multi-level.rs b/tests/ui/traits/vtable/vtable-multi-level.rs index bedbf84d303..67bac49f9f6 100644 --- a/tests/ui/traits/vtable/vtable-multi-level.rs +++ b/tests/ui/traits/vtable/vtable-multi-level.rs @@ -1,4 +1,3 @@ -//@ build-fail #![feature(rustc_attrs)] // O --> G --> C --> A @@ -10,134 +9,126 @@ // |-> M --> K // \-> L -#[rustc_dump_vtable] trait A { - //~^ error vtable fn foo_a(&self) {} } -#[rustc_dump_vtable] trait B { - //~^ error vtable fn foo_b(&self) {} } -#[rustc_dump_vtable] trait C: A + B { - //~^ error vtable fn foo_c(&self) {} } -#[rustc_dump_vtable] trait D { - //~^ error vtable fn foo_d(&self) {} } -#[rustc_dump_vtable] trait E { - //~^ error vtable fn foo_e(&self) {} } -#[rustc_dump_vtable] trait F: D + E { - //~^ error vtable fn foo_f(&self) {} } -#[rustc_dump_vtable] trait G: C + F { fn foo_g(&self) {} } -#[rustc_dump_vtable] trait H { - //~^ error vtable fn foo_h(&self) {} } -#[rustc_dump_vtable] trait I { - //~^ error vtable fn foo_i(&self) {} } -#[rustc_dump_vtable] trait J: H + I { - //~^ error vtable fn foo_j(&self) {} } -#[rustc_dump_vtable] trait K { - //~^ error vtable fn foo_k(&self) {} } -#[rustc_dump_vtable] trait L { - //~^ error vtable fn foo_l(&self) {} } -#[rustc_dump_vtable] trait M: K + L { - //~^ error vtable fn foo_m(&self) {} } -#[rustc_dump_vtable] trait N: J + M { - //~^ error vtable fn foo_n(&self) {} } -#[rustc_dump_vtable] trait O: G + N { - //~^ error vtable fn foo_o(&self) {} } struct S; +#[rustc_dump_vtable] impl A for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl B for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl C for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl D for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl E for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl F for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl G for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl H for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl I for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl J for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl K for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl L for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl M for S {} +//~^ ERROR vtable entries + +#[rustc_dump_vtable] impl N for S {} -impl O for S {} +//~^ ERROR vtable entries -macro_rules! monomorphize_vtable { - ($trait:ident) => {{ - fn foo(_ : &dyn $trait) {} - foo(&S); - }} -} +#[rustc_dump_vtable] +impl O for S {} +//~^ ERROR vtable entries -fn main() { - monomorphize_vtable!(O); - - monomorphize_vtable!(A); - monomorphize_vtable!(B); - monomorphize_vtable!(C); - monomorphize_vtable!(D); - monomorphize_vtable!(E); - monomorphize_vtable!(F); - monomorphize_vtable!(H); - monomorphize_vtable!(I); - monomorphize_vtable!(J); - monomorphize_vtable!(K); - monomorphize_vtable!(L); - monomorphize_vtable!(M); - monomorphize_vtable!(N); -} +fn main() {} diff --git a/tests/ui/traits/vtable/vtable-multi-level.stderr b/tests/ui/traits/vtable/vtable-multi-level.stderr index c4389e23fc1..961900aa3d2 100644 --- a/tests/ui/traits/vtable/vtable-multi-level.stderr +++ b/tests/ui/traits/vtable/vtable-multi-level.stderr @@ -1,134 +1,119 @@ -error: vtable entries for `<S as O>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as A>::foo_a), - Method(<S as B>::foo_b), - TraitVPtr(<S as B>), - Method(<S as C>::foo_c), - Method(<S as D>::foo_d), - TraitVPtr(<S as D>), - Method(<S as E>::foo_e), - TraitVPtr(<S as E>), - Method(<S as F>::foo_f), - TraitVPtr(<S as F>), - Method(<S as G>::foo_g), - Method(<S as H>::foo_h), - TraitVPtr(<S as H>), - Method(<S as I>::foo_i), - TraitVPtr(<S as I>), - Method(<S as J>::foo_j), - TraitVPtr(<S as J>), - Method(<S as K>::foo_k), - TraitVPtr(<S as K>), - Method(<S as L>::foo_l), - TraitVPtr(<S as L>), - Method(<S as M>::foo_m), - TraitVPtr(<S as M>), - Method(<S as N>::foo_n), - TraitVPtr(<S as N>), - Method(<S as O>::foo_o), ] - --> $DIR/vtable-multi-level.rs:97:1 + --> $DIR/vtable-multi-level.rs:75:1 | -LL | trait O: G + N { - | ^^^^^^^^^^^^^^ +LL | impl A for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as A>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, - Method(<S as A>::foo_a), + Method(<S as B>::foo_b), ] - --> $DIR/vtable-multi-level.rs:14:1 + --> $DIR/vtable-multi-level.rs:79:1 | -LL | trait A { - | ^^^^^^^ +LL | impl B for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as B>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, + Method(<S as A>::foo_a), Method(<S as B>::foo_b), + TraitVPtr(<S as B>), + Method(<S as C>::foo_c), ] - --> $DIR/vtable-multi-level.rs:20:1 + --> $DIR/vtable-multi-level.rs:83:1 | -LL | trait B { - | ^^^^^^^ +LL | impl C for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as C>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, - Method(<S as A>::foo_a), - Method(<S as B>::foo_b), - TraitVPtr(<S as B>), - Method(<S as C>::foo_c), + Method(<S as D>::foo_d), ] - --> $DIR/vtable-multi-level.rs:26:1 + --> $DIR/vtable-multi-level.rs:87:1 | -LL | trait C: A + B { - | ^^^^^^^^^^^^^^ +LL | impl D for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as D>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, - Method(<S as D>::foo_d), + Method(<S as E>::foo_e), ] - --> $DIR/vtable-multi-level.rs:32:1 + --> $DIR/vtable-multi-level.rs:91:1 | -LL | trait D { - | ^^^^^^^ +LL | impl E for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as E>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, + Method(<S as D>::foo_d), Method(<S as E>::foo_e), + TraitVPtr(<S as E>), + Method(<S as F>::foo_f), ] - --> $DIR/vtable-multi-level.rs:38:1 + --> $DIR/vtable-multi-level.rs:95:1 | -LL | trait E { - | ^^^^^^^ +LL | impl F for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as F>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, + Method(<S as A>::foo_a), + Method(<S as B>::foo_b), + TraitVPtr(<S as B>), + Method(<S as C>::foo_c), Method(<S as D>::foo_d), + TraitVPtr(<S as D>), Method(<S as E>::foo_e), TraitVPtr(<S as E>), Method(<S as F>::foo_f), + TraitVPtr(<S as F>), + Method(<S as G>::foo_g), ] - --> $DIR/vtable-multi-level.rs:44:1 + --> $DIR/vtable-multi-level.rs:99:1 | -LL | trait F: D + E { - | ^^^^^^^^^^^^^^ +LL | impl G for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as H>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as H>::foo_h), ] - --> $DIR/vtable-multi-level.rs:55:1 + --> $DIR/vtable-multi-level.rs:103:1 | -LL | trait H { - | ^^^^^^^ +LL | impl H for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as I>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as I>::foo_i), ] - --> $DIR/vtable-multi-level.rs:61:1 + --> $DIR/vtable-multi-level.rs:107:1 | -LL | trait I { - | ^^^^^^^ +LL | impl I for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as J>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, @@ -137,34 +122,34 @@ error: vtable entries for `<S as J>`: [ TraitVPtr(<S as I>), Method(<S as J>::foo_j), ] - --> $DIR/vtable-multi-level.rs:67:1 + --> $DIR/vtable-multi-level.rs:111:1 | -LL | trait J: H + I { - | ^^^^^^^^^^^^^^ +LL | impl J for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as K>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as K>::foo_k), ] - --> $DIR/vtable-multi-level.rs:73:1 + --> $DIR/vtable-multi-level.rs:115:1 | -LL | trait K { - | ^^^^^^^ +LL | impl K for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as L>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as L>::foo_l), ] - --> $DIR/vtable-multi-level.rs:79:1 + --> $DIR/vtable-multi-level.rs:119:1 | -LL | trait L { - | ^^^^^^^ +LL | impl L for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as M>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, @@ -173,12 +158,12 @@ error: vtable entries for `<S as M>`: [ TraitVPtr(<S as L>), Method(<S as M>::foo_m), ] - --> $DIR/vtable-multi-level.rs:85:1 + --> $DIR/vtable-multi-level.rs:123:1 | -LL | trait M: K + L { - | ^^^^^^^^^^^^^^ +LL | impl M for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as N>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, @@ -194,10 +179,46 @@ error: vtable entries for `<S as N>`: [ TraitVPtr(<S as M>), Method(<S as N>::foo_n), ] - --> $DIR/vtable-multi-level.rs:91:1 + --> $DIR/vtable-multi-level.rs:127:1 + | +LL | impl N for S {} + | ^^^^^^^^^^^^ + +error: vtable entries: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(<S as A>::foo_a), + Method(<S as B>::foo_b), + TraitVPtr(<S as B>), + Method(<S as C>::foo_c), + Method(<S as D>::foo_d), + TraitVPtr(<S as D>), + Method(<S as E>::foo_e), + TraitVPtr(<S as E>), + Method(<S as F>::foo_f), + TraitVPtr(<S as F>), + Method(<S as G>::foo_g), + Method(<S as H>::foo_h), + TraitVPtr(<S as H>), + Method(<S as I>::foo_i), + TraitVPtr(<S as I>), + Method(<S as J>::foo_j), + TraitVPtr(<S as J>), + Method(<S as K>::foo_k), + TraitVPtr(<S as K>), + Method(<S as L>::foo_l), + TraitVPtr(<S as L>), + Method(<S as M>::foo_m), + TraitVPtr(<S as M>), + Method(<S as N>::foo_n), + TraitVPtr(<S as N>), + Method(<S as O>::foo_o), + ] + --> $DIR/vtable-multi-level.rs:131:1 | -LL | trait N: J + M { - | ^^^^^^^^^^^^^^ +LL | impl O for S {} + | ^^^^^^^^^^^^ -error: aborting due to 14 previous errors +error: aborting due to 15 previous errors diff --git a/tests/ui/traits/vtable/vtable-multiple.rs b/tests/ui/traits/vtable/vtable-multiple.rs index beaaf4db6b1..51e20ee20c9 100644 --- a/tests/ui/traits/vtable/vtable-multiple.rs +++ b/tests/ui/traits/vtable/vtable-multiple.rs @@ -1,33 +1,29 @@ -//@ build-fail #![feature(rustc_attrs)] -#[rustc_dump_vtable] trait A { fn foo_a(&self) {} } -#[rustc_dump_vtable] trait B { - //~^ error vtable fn foo_b(&self) {} } -#[rustc_dump_vtable] trait C: A + B { - //~^ error vtable fn foo_c(&self) {} } struct S; +#[rustc_dump_vtable] impl A for S {} +//~^ error vtable + +#[rustc_dump_vtable] impl B for S {} -impl C for S {} +//~^ error vtable -fn foo(c: &dyn C) {} -fn bar(c: &dyn B) {} +#[rustc_dump_vtable] +impl C for S {} +//~^ error vtable -fn main() { - foo(&S); - bar(&S); -} +fn main() {} diff --git a/tests/ui/traits/vtable/vtable-multiple.stderr b/tests/ui/traits/vtable/vtable-multiple.stderr index 0dcd8443309..bae44148baa 100644 --- a/tests/ui/traits/vtable/vtable-multiple.stderr +++ b/tests/ui/traits/vtable/vtable-multiple.stderr @@ -1,27 +1,38 @@ -error: vtable entries for `<S as C>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, Method(<S as A>::foo_a), + ] + --> $DIR/vtable-multiple.rs:18:1 + | +LL | impl A for S {} + | ^^^^^^^^^^^^ + +error: vtable entries: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, Method(<S as B>::foo_b), - TraitVPtr(<S as B>), - Method(<S as C>::foo_c), ] - --> $DIR/vtable-multiple.rs:16:1 + --> $DIR/vtable-multiple.rs:22:1 | -LL | trait C: A + B { - | ^^^^^^^^^^^^^^ +LL | impl B for S {} + | ^^^^^^^^^^^^ -error: vtable entries for `<S as B>`: [ +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, + Method(<S as A>::foo_a), Method(<S as B>::foo_b), + TraitVPtr(<S as B>), + Method(<S as C>::foo_c), ] - --> $DIR/vtable-multiple.rs:10:1 + --> $DIR/vtable-multiple.rs:26:1 | -LL | trait B { - | ^^^^^^^ +LL | impl C for S {} + | ^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/traits/vtable/vtable-vacant.rs b/tests/ui/traits/vtable/vtable-vacant.rs index b3c76815703..b023565c56e 100644 --- a/tests/ui/traits/vtable/vtable-vacant.rs +++ b/tests/ui/traits/vtable/vtable-vacant.rs @@ -1,18 +1,14 @@ -//@ build-fail #![feature(rustc_attrs)] #![feature(negative_impls)] // B --> A -#[rustc_dump_vtable] trait A { fn foo_a1(&self) {} fn foo_a2(&self) where Self: Send {} } -#[rustc_dump_vtable] trait B: A { - //~^ error vtable fn foo_b1(&self) {} fn foo_b2(&self) where Self: Send {} } @@ -20,11 +16,12 @@ trait B: A { struct S; impl !Send for S {} +#[rustc_dump_vtable] impl A for S {} -impl B for S {} +//~^ error vtable -fn foo(_: &dyn B) {} +#[rustc_dump_vtable] +impl B for S {} +//~^ error vtable -fn main() { - foo(&S); -} +fn main() {} diff --git a/tests/ui/traits/vtable/vtable-vacant.stderr b/tests/ui/traits/vtable/vtable-vacant.stderr index f6961ca010e..ed8466f7f2e 100644 --- a/tests/ui/traits/vtable/vtable-vacant.stderr +++ b/tests/ui/traits/vtable/vtable-vacant.stderr @@ -1,4 +1,16 @@ -error: vtable entries for `<S as B>`: [ +error: vtable entries: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method(<S as A>::foo_a1), + Vacant, + ] + --> $DIR/vtable-vacant.rs:20:1 + | +LL | impl A for S {} + | ^^^^^^^^^^^^ + +error: vtable entries: [ MetadataDropInPlace, MetadataSize, MetadataAlign, @@ -7,10 +19,10 @@ error: vtable entries for `<S as B>`: [ Method(<S as B>::foo_b1), Vacant, ] - --> $DIR/vtable-vacant.rs:14:1 + --> $DIR/vtable-vacant.rs:24:1 | -LL | trait B: A { - | ^^^^^^^^^^ +LL | impl B for S {} + | ^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr index 71717c6945e..eea2e75a238 100644 --- a/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr +++ b/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -17,7 +17,7 @@ LL | let y = x as dyn MyAdd<i32>; | ^^^^^^^^^^^^^^ `MyAdd` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:6:55 | LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; } diff --git a/tests/ui/type_length_limit.rs b/tests/ui/type_length_limit.rs index 87f5ffd76d7..b629455aced 100644 --- a/tests/ui/type_length_limit.rs +++ b/tests/ui/type_length_limit.rs @@ -2,6 +2,9 @@ //@ compile-flags: -Copt-level=0 -Zenforce-type-length-limit //~^^ ERROR reached the type-length limit +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" + // Test that the type length limit can be changed. // The exact type depends on optimizations, so disable them. diff --git a/tests/ui/type_length_limit.stderr b/tests/ui/type_length_limit.stderr index 83353547d34..d913b661c6f 100644 --- a/tests/ui/type_length_limit.stderr +++ b/tests/ui/type_length_limit.stderr @@ -1,11 +1,11 @@ error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((..., ..., ...), ..., ...), ..., ...), ..., ...)>>` - --> $DIR/type_length_limit.rs:32:5 + --> $DIR/type_length_limit.rs:35:5 | LL | drop::<Option<A>>(None); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate - = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` | diff --git a/tests/ui/wf/issue-87495.stderr b/tests/ui/wf/issue-87495.stderr index 7be327e61d1..0c293e3576d 100644 --- a/tests/ui/wf/issue-87495.stderr +++ b/tests/ui/wf/issue-87495.stderr @@ -5,7 +5,7 @@ LL | const CONST: (bool, dyn T); | ^^^^^ `T` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/issue-87495.rs:4:11 | LL | trait T { diff --git a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr index 0b7f4cd4362..f3e4f2a63e9 100644 --- a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr +++ b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr @@ -5,7 +5,7 @@ LL | let t_box: Box<dyn Trait> = Box::new(S); | ^^^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:6:14 | LL | trait Trait: Sized {} @@ -22,7 +22,7 @@ LL | takes_box(Box::new(S)); | ^^^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:6:14 | LL | trait Trait: Sized {} @@ -39,7 +39,7 @@ LL | Box::new(S) as Box<dyn Trait>; | ^^^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:6:14 | LL | trait Trait: Sized {} diff --git a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr index 3f50e1192cf..716d0e78ff1 100644 --- a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr +++ b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr @@ -5,7 +5,7 @@ LL | let t: &dyn Trait = &S; | ^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:6:14 | LL | trait Trait: Sized {} @@ -22,7 +22,7 @@ LL | takes_trait(&S); | ^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:6:14 | LL | trait Trait: Sized {} @@ -39,7 +39,7 @@ LL | &S as &dyn Trait; | ^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:6:14 | LL | trait Trait: Sized {} diff --git a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr index 8f68f9c5b6b..a7405ce4caa 100644 --- a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr +++ b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr @@ -19,7 +19,7 @@ LL | Some(()) => &S, | ^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/wf-dyn-incompat-trait-obj-match.rs:6:14 | LL | trait Trait: Sized {} @@ -40,7 +40,7 @@ LL | None => &R, | ^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/wf-dyn-incompat-trait-obj-match.rs:6:14 | LL | trait Trait: Sized {} diff --git a/tests/ui/wf/wf-dyn-incompatible.stderr b/tests/ui/wf/wf-dyn-incompatible.stderr index 1803376aaa1..e61b37d9293 100644 --- a/tests/ui/wf/wf-dyn-incompatible.stderr +++ b/tests/ui/wf/wf-dyn-incompatible.stderr @@ -5,7 +5,7 @@ LL | let _x: &dyn A; | ^^^^^^ `A` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> --> $DIR/wf-dyn-incompatible.rs:5:23 | LL | trait A { diff --git a/tests/ui/wf/wf-fn-where-clause.stderr b/tests/ui/wf/wf-fn-where-clause.stderr index d73376e9861..b419bc8347f 100644 --- a/tests/ui/wf/wf-fn-where-clause.stderr +++ b/tests/ui/wf/wf-fn-where-clause.stderr @@ -22,7 +22,7 @@ LL | fn bar() where Vec<dyn Copy>:, {} | = note: the trait is not dyn compatible because it requires `Self: Sized` = note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time --> $DIR/wf-fn-where-clause.rs:12:16 diff --git a/tests/ui/wf/wf-trait-default-fn-ret.rs b/tests/ui/wf/wf-trait-default-fn-ret.rs index 2103dae8d23..a7f83dcf678 100644 --- a/tests/ui/wf/wf-trait-default-fn-ret.rs +++ b/tests/ui/wf/wf-trait-default-fn-ret.rs @@ -1,5 +1,4 @@ -// Check that we test WF conditions for fn arguments. Because the -// current code is so goofy, this is only a warning for now. +// Check that we test WF conditions for fn arguments. #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/tests/ui/wf/wf-trait-default-fn-ret.stderr b/tests/ui/wf/wf-trait-default-fn-ret.stderr index f749ac7b1b3..f0d1b55edc4 100644 --- a/tests/ui/wf/wf-trait-default-fn-ret.stderr +++ b/tests/ui/wf/wf-trait-default-fn-ret.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Self: Eq` is not satisfied - --> $DIR/wf-trait-default-fn-ret.rs:11:22 + --> $DIR/wf-trait-default-fn-ret.rs:10:22 | LL | fn bar(&self) -> Bar<Self> { | ^^^^^^^^^ the trait `Eq` is not implemented for `Self` | note: required by a bound in `Bar` - --> $DIR/wf-trait-default-fn-ret.rs:8:14 + --> $DIR/wf-trait-default-fn-ret.rs:7:14 | LL | struct Bar<T:Eq+?Sized> { value: Box<T> } | ^^ required by this bound in `Bar` diff --git a/triagebot.toml b/triagebot.toml index 29c84e19c56..49cf1213987 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1025,7 +1025,6 @@ users_on_vacation = [ "nnethercote", "workingjubilee", "kobzol", - "jieyouxu", ] [[assign.warn_non_default_branch.exceptions]] |
