diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 7c84530abbee2..c2260a4590975 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -986,16 +986,6 @@ impl<'a> MethodDef<'a> { f(cx, span, &substructure) } - fn get_ret_ty( - &self, - cx: &ExtCtxt<'_>, - trait_: &TraitDef<'_>, - generics: &Generics, - type_ident: Ident, - ) -> Box { - self.ret_ty.to_ty(cx, trait_.span, type_ident, generics) - } - fn is_static(&self) -> bool { !self.explicit_self } @@ -1068,10 +1058,14 @@ impl<'a> MethodDef<'a> { self_arg.into_iter().chain(nonself_args).collect() }; - let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident); + let ret_type = if let Ty::Unit = &self.ret_ty { + ast::FnRetTy::Default(span) + } else { + ast::FnRetTy::Ty(self.ret_ty.to_ty(cx, span, type_ident, generics)) + }; let method_ident = Ident::new(self.name, span); - let fn_decl = cx.fn_decl(args, ast::FnRetTy::Ty(ret_type)); + let fn_decl = cx.fn_decl(args, ret_type); let body_block = body.into_block(cx, span); let trait_lo_sp = span.shrink_to_lo(); diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 9379faf1156fc..ca4805a93e017 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1397,12 +1397,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn call( &mut self, llty: &'ll Type, - fn_call_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: &'ll Value, args: &[&'ll Value], funclet: Option<&Funclet<'ll>>, - instance: Option>, + callee_instance: Option>, ) -> &'ll Value { debug!("call {:?} with args ({:?})", llfn, args); @@ -1414,10 +1414,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } // Emit CFI pointer type membership test - self.cfi_type_test(fn_call_attrs, fn_abi, instance, llfn); + self.cfi_type_test(caller_attrs, fn_abi, callee_instance, llfn); // Emit KCFI operand bundle - let kcfi_bundle = self.kcfi_operand_bundle(fn_call_attrs, fn_abi, instance, llfn); + let kcfi_bundle = self.kcfi_operand_bundle(caller_attrs, fn_abi, callee_instance, llfn); if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.as_ref()) { bundles.push(kcfi_bundle); } @@ -1435,17 +1435,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { ) }; - if let Some(instance) = instance { + if let Some(callee_instance) = callee_instance { // Attributes on the function definition being called - let fn_defn_attrs = self.cx.tcx.codegen_fn_attrs(instance.def_id()); - if let Some(fn_call_attrs) = fn_call_attrs + let callee_attrs = self.cx.tcx.codegen_fn_attrs(callee_instance.def_id()); + if let Some(caller_attrs) = caller_attrs // If there is an inline attribute and a target feature that matches // we will add the attribute to the callsite otherwise we'll omit // this and not add the attribute to prevent soundness issues. - && let Some(inlining_rule) = attributes::inline_attr(&self.cx, self.cx.tcx, instance) + && let Some(inlining_rule) = attributes::inline_attr(&self.cx, self.cx.tcx, callee_instance) && self.cx.tcx.is_target_feature_call_safe( - &fn_defn_attrs.target_features, - &fn_call_attrs.target_features.iter().cloned().chain( + &callee_attrs.target_features, + &caller_attrs.target_features.iter().cloned().chain( self.cx.tcx.sess.target_features.iter().map(|feat| TargetFeature { name: *feat, kind: TargetFeatureKind::Implied, @@ -1470,14 +1470,15 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn tail_call( &mut self, llty: Self::Type, - fn_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, llfn: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, - instance: Option>, + callee_instance: Option>, ) { - let call = self.call(llty, fn_attrs, Some(fn_abi), llfn, args, funclet, instance); + let call = + self.call(llty, caller_attrs, Some(fn_abi), llfn, args, funclet, callee_instance); llvm::LLVMSetTailCallKind(call, llvm::TailCallKind::MustTail); match &fn_abi.ret.mode { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d22546dee5654..35de8b5e1486b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -199,12 +199,12 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { // do an invoke, otherwise do a call. let fn_ty = bx.fn_decl_backend_type(fn_abi); - let fn_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() { + let caller_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() { Some(bx.tcx().codegen_instance_attrs(fx.instance.def)) } else { None }; - let fn_attrs = fn_attrs.as_deref(); + let caller_attrs = caller_attrs.as_deref(); if !fn_abi.can_unwind { unwind = mir::UnwindAction::Unreachable; @@ -233,7 +233,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { }; if kind == CallKind::Tail { - bx.tail_call(fn_ty, fn_attrs, fn_abi, fn_ptr, llargs, self.funclet(fx), instance); + bx.tail_call(fn_ty, caller_attrs, fn_abi, fn_ptr, llargs, self.funclet(fx), instance); return MergingSucc::False; } @@ -245,7 +245,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { }; let invokeret = bx.invoke( fn_ty, - fn_attrs, + caller_attrs, Some(fn_abi), fn_ptr, llargs, @@ -268,8 +268,15 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } MergingSucc::False } else { - let llret = - bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx), instance); + let llret = bx.call( + fn_ty, + caller_attrs, + Some(fn_abi), + fn_ptr, + llargs, + self.funclet(fx), + instance, + ); if fx.mir[self.bb].is_cleanup { bx.apply_attrs_to_cleanup_callsite(llret); } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index ba36188f05d15..3486bd140eceb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -600,10 +600,13 @@ pub trait BuilderMethods<'a, 'tcx>: /// /// ## Arguments /// - /// The `fn_attrs`, `fn_abi`, and `instance` arguments are Options because they are advisory. - /// They relate to optional codegen enhancements like LLVM CFI, and do not affect ABI per se. - /// Any ABI-related transformations should be handled by different, earlier stages of codegen. - /// For instance, in the caller of `BuilderMethods::call`. + /// `caller_attrs` are the attributes of the surrounding caller; they have nothing to do with + /// the callee. + /// + /// The `caller_attrs`, `fn_abi`, and `callee_instance` arguments are Options because they are + /// advisory. They relate to optional codegen enhancements like LLVM CFI, and do not affect ABI + /// per se. Any ABI-related transformations should be handled by different, earlier stages of + /// codegen. For instance, in the caller of `BuilderMethods::call`. /// /// This means that a codegen backend which disregards `fn_attrs`, `fn_abi`, and `instance` /// should still do correct codegen, and code should not be miscompiled if they are omitted. @@ -620,23 +623,23 @@ pub trait BuilderMethods<'a, 'tcx>: fn call( &mut self, llty: Self::Type, - fn_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, fn_val: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, - instance: Option>, + callee_instance: Option>, ) -> Self::Value; fn tail_call( &mut self, llty: Self::Type, - fn_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, llfn: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, - instance: Option>, + callee_instance: Option>, ); fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 599f79d011989..f68f4e71520b3 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -527,6 +527,12 @@ LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttributeKind RustAttr) { *unwrap(C), CaptureInfo(CaptureComponents::Address | CaptureComponents::ReadProvenance))); } +#endif +#if LLVM_VERSION_GE(23, 0) + if (RustAttr == LLVMRustAttributeKind::DeadOnReturn) { + return wrap(Attribute::getWithDeadOnReturnInfo(*unwrap(C), + llvm::DeadOnReturnInfo())); + } #endif return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr))); } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 64bdb8e85e03d..051dda731881f 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -54,7 +54,7 @@ )] use crate::ffi::va_list::{VaArgSafe, VaList}; -use crate::marker::{ConstParamTy, Destruct, DiscriminantKind, PointeeSized, Tuple}; +use crate::marker::{ConstParamTy, DiscriminantKind, PointeeSized, Tuple}; use crate::{mem, ptr}; mod bounds; @@ -483,11 +483,14 @@ pub const fn unlikely(b: bool) -> bool { #[rustc_nounwind] #[miri::intrinsic_fallback_is_spec] #[inline] -pub const fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T -where - T: [const] Destruct, -{ - if b { true_val } else { false_val } +pub const fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T { + if b { + forget(false_val); + true_val + } else { + forget(true_val); + false_val + } } /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited: diff --git a/library/core/src/option.rs b/library/core/src/option.rs index ed31d4efaa754..eb4f978b7c19d 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2103,10 +2103,7 @@ impl Option<&T> { where T: Clone, { - match self { - Some(t) => Some(t.clone()), - None => None, - } + self.map(T::clone) } } @@ -2154,10 +2151,7 @@ impl Option<&mut T> { where T: Clone, { - match self { - Some(t) => Some(t.clone()), - None => None, - } + self.as_deref().map(T::clone) } } diff --git a/src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs b/src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs new file mode 100644 index 0000000000000..ecf9f4b92058b --- /dev/null +++ b/src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs @@ -0,0 +1,19 @@ +//! Check that `select_unpredictable` properly forgets the value it does not select. +#![feature(core_intrinsics)] +use std::cell::Cell; +use std::intrinsics::select_unpredictable; + +fn main() { + let (true_val, false_val) = (Cell::new(false), Cell::new(false)); + _ = select_unpredictable(true, TraceDrop(&true_val), TraceDrop(&false_val)); + assert!(true_val.get()); + assert!(!false_val.get()); +} + +struct TraceDrop<'a>(&'a Cell); + +impl<'a> Drop for TraceDrop<'a> { + fn drop(&mut self) { + self.0.set(true); + } +} diff --git a/tests/codegen-llvm/addr-of-mutate.rs b/tests/codegen-llvm/addr-of-mutate.rs index d59d85af62a91..d1939391b25de 100644 --- a/tests/codegen-llvm/addr-of-mutate.rs +++ b/tests/codegen-llvm/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 . -// CHECK: i8 @foo(ptr{{( dead_on_return)?}} noalias noundef align 1{{( captures\(address\))?}} dereferenceable(128) %x) +// CHECK: i8 @foo(ptr{{( dead_on_return)?}} noalias noundef align 1{{( captures\(address\))?}}{{( dead_on_return)?}} 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{{( dead_on_return)?}} noalias noundef align {{[0-9]+}}{{( captures\(address\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) +// CHECK: i1 @second(ptr{{( dead_on_return)?}} noalias noundef align {{[0-9]+}}{{( captures\(address\))?}}{{( dead_on_return)?}} 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{{( dead_on_return)?}} noalias noundef readonly align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) +// CHECK: i1 @third(ptr{{( dead_on_return)?}} noalias noundef readonly align {{[0-9]+}}{{( captures\(none\))?}}{{( dead_on_return)?}} 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-llvm/function-arguments.rs b/tests/codegen-llvm/function-arguments.rs index 4d557470504e0..b5febca3b87b5 100644 --- a/tests/codegen-llvm/function-arguments.rs +++ b/tests/codegen-llvm/function-arguments.rs @@ -134,7 +134,7 @@ pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {} #[no_mangle] pub fn notunpin_borrow(_: &NotUnpin) {} -// CHECK: @indirect_struct(ptr{{( dead_on_return)?}} noalias noundef readonly align 4{{( captures\(none\))?}} dereferenceable(32) %_1) +// CHECK: @indirect_struct(ptr{{( dead_on_return)?}} noalias noundef readonly align 4{{( captures\(none\))?}}{{( dead_on_return)?}} dereferenceable(32) %_1) #[no_mangle] pub fn indirect_struct(_: S) {} diff --git a/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs index 546007ab0f2cf..4c61224ac6d8f 100644 --- a/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs +++ b/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs @@ -256,7 +256,7 @@ pub struct IntDoubleInt { c: i32, } -// CHECK: define void @f_int_double_int_s_arg(ptr{{( dead_on_return)?}} noalias noundef align 8{{( captures\(address\))?}} dereferenceable(24) %a) +// CHECK: define void @f_int_double_int_s_arg(ptr{{( dead_on_return)?}} noalias noundef align 8{{( captures\(address\))?}}{{( dead_on_return)?}} dereferenceable(24) %a) #[no_mangle] pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {} diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout index b778eab605961..2a05d77f8f6da 100644 --- a/tests/ui/deriving/deriving-all-codegen.stdout +++ b/tests/ui/deriving/deriving-all-codegen.stdout @@ -51,7 +51,7 @@ impl ::core::default::Default for Empty { #[automatically_derived] impl ::core::hash::Hash for Empty { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {} + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {} } #[automatically_derived] impl ::core::marker::StructuralPartialEq for Empty { } @@ -65,7 +65,7 @@ impl ::core::cmp::Eq for Empty { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Empty { @@ -123,7 +123,7 @@ impl ::core::default::Default for Point { #[automatically_derived] impl ::core::hash::Hash for Point { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.x, state); ::core::hash::Hash::hash(&self.y, state) } @@ -142,7 +142,7 @@ impl ::core::cmp::Eq for Point { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -211,7 +211,7 @@ impl ::core::default::Default for PackedPoint { #[automatically_derived] impl ::core::hash::Hash for PackedPoint { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&{ self.x }, state); ::core::hash::Hash::hash(&{ self.y }, state) } @@ -230,7 +230,7 @@ impl ::core::cmp::Eq for PackedPoint { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -297,7 +297,7 @@ impl ::core::convert::From for TupleSingleField { #[automatically_derived] impl ::core::hash::Hash for TupleSingleField { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.0, state) } } @@ -313,7 +313,7 @@ impl ::core::cmp::Eq for TupleSingleField { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -372,7 +372,7 @@ impl ::core::convert::From for SingleField { #[automatically_derived] impl ::core::hash::Hash for SingleField { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.foo, state) } } @@ -388,7 +388,7 @@ impl ::core::cmp::Eq for SingleField { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -465,7 +465,7 @@ impl ::core::default::Default for Big { #[automatically_derived] impl ::core::hash::Hash for Big { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.b1, state); ::core::hash::Hash::hash(&self.b2, state); ::core::hash::Hash::hash(&self.b3, state); @@ -493,7 +493,7 @@ impl ::core::cmp::Eq for Big { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -741,7 +741,7 @@ impl ::core::convert::From<[u32]> for Unsized { #[automatically_derived] impl ::core::hash::Hash for Unsized { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.0, state) } } @@ -757,7 +757,7 @@ impl ::core::cmp::Eq for Unsized { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq<[u32]>; } } @@ -829,7 +829,7 @@ impl impl ::core::hash::Hash for Generic where T::A: ::core::hash::Hash { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.t, state); ::core::hash::Hash::hash(&self.ta, state); ::core::hash::Hash::hash(&self.u, state) @@ -852,7 +852,7 @@ impl ::core::cmp::Eq for #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; @@ -946,7 +946,7 @@ impl where T::A: ::core::hash::Hash + ::core::marker::Copy { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&{ self.0 }, state); ::core::hash::Hash::hash(&{ self.1 }, state); ::core::hash::Hash::hash(&{ self.2 }, state) @@ -974,7 +974,7 @@ impl () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; @@ -1043,7 +1043,7 @@ impl ::core::fmt::Debug for Enum0 { #[automatically_derived] impl ::core::hash::Hash for Enum0 { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { match *self {} } } @@ -1059,7 +1059,7 @@ impl ::core::cmp::Eq for Enum0 { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Enum0 { @@ -1105,7 +1105,7 @@ impl ::core::fmt::Debug for Enum1 { #[automatically_derived] impl ::core::hash::Hash for Enum1 { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { match self { Enum1::Single { x: __self_0 } => ::core::hash::Hash::hash(__self_0, state), @@ -1129,7 +1129,7 @@ impl ::core::cmp::Eq for Enum1 { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -1181,7 +1181,7 @@ impl ::core::default::Default for Fieldless1 { #[automatically_derived] impl ::core::hash::Hash for Fieldless1 { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {} + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {} } #[automatically_derived] impl ::core::marker::StructuralPartialEq for Fieldless1 { } @@ -1195,7 +1195,7 @@ impl ::core::cmp::Eq for Fieldless1 { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless1 { @@ -1251,7 +1251,7 @@ impl ::core::default::Default for Fieldless { #[automatically_derived] impl ::core::hash::Hash for Fieldless { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state) } @@ -1272,7 +1272,7 @@ impl ::core::cmp::Eq for Fieldless { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless { @@ -1345,7 +1345,7 @@ impl ::core::default::Default for Mixed { #[automatically_derived] impl ::core::hash::Hash for Mixed { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state); match self { @@ -1382,7 +1382,7 @@ impl ::core::cmp::Eq for Mixed { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; let _: ::core::cmp::AssertParamIsEq>; @@ -1545,7 +1545,7 @@ impl ::core::fmt::Debug for Fielded { #[automatically_derived] impl ::core::hash::Hash for Fielded { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state); match self { @@ -1580,7 +1580,7 @@ impl ::core::cmp::Eq for Fielded { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; @@ -1666,7 +1666,7 @@ impl ::core::fmt::Debug for impl ::core::hash::Hash for EnumGeneric { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state); match self { @@ -1702,7 +1702,7 @@ impl ::core::cmp::Eq for #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; } diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr index 11a6bfdfcd292..a48940460f91e 100644 --- a/tests/ui/stats/macro-stats.stderr +++ b/tests/ui/stats/macro-stats.stderr @@ -4,11 +4,11 @@ macro-stats Macro Name Uses Lines Avg Lines B macro-stats ----------------------------------------------------------------------------------- macro-stats #[derive(Clone)] 8 67 8.4 1_879 234.9 macro-stats #[derive(PartialOrd)] 1 17 17.0 675 675.0 -macro-stats #[derive(Hash)] 2 17 8.5 577 288.5 +macro-stats #[derive(Hash)] 2 17 8.5 565 282.5 macro-stats q! 1 26 26.0 519 519.0 macro-stats #[derive(Ord)] 1 15 15.0 503 503.0 macro-stats #[derive(Default)] 2 16 8.0 403 201.5 -macro-stats #[derive(Eq)] 1 11 11.0 325 325.0 +macro-stats #[derive(Eq)] 1 11 11.0 319 319.0 macro-stats #[derive(Debug)] 1 8 8.0 277 277.0 macro-stats #[derive(PartialEq)] 1 9 9.0 267 267.0 macro-stats #[derive(Copy)] 1 2 2.0 61 61.0