diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index c1e947720452c..30fd72c2f8fd5 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1408,6 +1408,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, "`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen" ), + rustc_attr!( + rustc_no_ubchecks, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, + "#[rustc_no_ubchecks] asks the compiler to delete UB checks from a function" + ), rustc_attr!( rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes, "`#[rustc_force_inline]` forces a free function to be inlined" diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 4922d74743c9a..4039a02a9fe14 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -29,6 +29,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify { } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let def_id = body.source.def_id(); let ctx = InstSimplifyContext { tcx, local_decls: &body.local_decls, @@ -36,14 +37,21 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify { }; let preserve_ub_checks = attr::contains_name(tcx.hir_krate_attrs(), sym::rustc_preserve_ub_checks); + let remove_ub_checks = if tcx.is_coroutine(def_id) { + false + } else { + tcx.has_attr(def_id, sym::rustc_no_ubchecks) + }; for block in body.basic_blocks.as_mut() { for statement in block.statements.iter_mut() { let StatementKind::Assign(box (.., rvalue)) = &mut statement.kind else { continue; }; - if !preserve_ub_checks { - ctx.simplify_ub_check(rvalue); + if remove_ub_checks { + ctx.simplify_ub_check(rvalue, false); + } else if !preserve_ub_checks { + ctx.simplify_ub_check(rvalue, tcx.sess.ub_checks()); } ctx.simplify_bool_cmp(rvalue); ctx.simplify_ref_deref(rvalue); @@ -168,13 +176,13 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { } } - fn simplify_ub_check(&self, rvalue: &mut Rvalue<'tcx>) { + fn simplify_ub_check(&self, rvalue: &mut Rvalue<'tcx>, ub_checks: bool) { // FIXME: Should we do the same for overflow checks? let Rvalue::NullaryOp(NullOp::RuntimeChecks(RuntimeChecks::UbChecks)) = *rvalue else { return; }; - let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks()); + let const_ = Const::from_bool(self.tcx, ub_checks); let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None }; *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant))); } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index cd730ede4ba1f..1aa3e4690db3e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1961,6 +1961,7 @@ symbols! { rustc_no_implicit_autorefs, rustc_no_implicit_bounds, rustc_no_mir_inline, + rustc_no_ubchecks, rustc_nonnull_optimization_guaranteed, rustc_nounwind, rustc_objc_class, diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 2b767ffe02bee..eed388c1a5413 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1475,6 +1475,7 @@ impl Box { #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "allocator_api", issue = "32838")] #[inline] + #[rustc_no_ubchecks] pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let mut b = mem::ManuallyDrop::new(b); // We carefully get the raw pointer out in a way that Miri's aliasing model understands what diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 7d49da8509577..ceda2759a1fda 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -219,6 +219,7 @@ impl ManuallyDrop { #[stable(feature = "manually_drop_take", since = "1.42.0")] #[rustc_const_unstable(feature = "const_manually_drop_take", issue = "148773")] #[inline] + #[rustc_no_ubchecks] pub const unsafe fn take(slot: &mut ManuallyDrop) -> T { // SAFETY: we are reading from a reference, which is guaranteed // to be valid for reads. diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index f4fcc9b1f3665..977a1386bc84a 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -876,6 +876,7 @@ pub const fn take(dest: &mut T) -> T { #[must_use = "if you don't need the old value, you can just assign the new value directly"] #[rustc_const_stable(feature = "const_replace", since = "1.83.0")] #[rustc_diagnostic_item = "mem_replace"] +#[rustc_no_ubchecks] pub const fn replace(dest: &mut T, src: T) -> T { // It may be tempting to use `swap` to avoid `unsafe` here. Don't! // The compiler optimizes the implementation below to two `memcpy`s diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index ea0514f405f1e..2e91f193ec38b 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1400,6 +1400,7 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { /// Same behavior and safety conditions as [`swap_nonoverlapping`] #[inline] +#[rustc_no_ubchecks] const unsafe fn swap_nonoverlapping_const(x: *mut T, y: *mut T, count: usize) { let mut i = 0; while i < count { @@ -1695,7 +1696,6 @@ pub const unsafe fn read(src: *const T) -> T { // SAFETY: the caller must guarantee that `src` is valid for reads. unsafe { - #[cfg(debug_assertions)] // Too expensive to always enable (for now?) ub_checks::assert_unsafe_precondition!( check_language_ub, "ptr::read requires that the pointer argument is aligned and non-null", @@ -1895,7 +1895,6 @@ pub const unsafe fn write(dst: *mut T, src: T) { // `dst` cannot overlap `src` because the caller has mutable access // to `dst` while `src` is owned by this function. unsafe { - #[cfg(debug_assertions)] // Too expensive to always enable (for now?) ub_checks::assert_unsafe_precondition!( check_language_ub, "ptr::write requires that the pointer argument is aligned and non-null", diff --git a/tests/codegen-llvm/mem-replace-big-type.rs b/tests/codegen-llvm/mem-replace-big-type.rs index 0b2229ba7d104..34a8bea0919d7 100644 --- a/tests/codegen-llvm/mem-replace-big-type.rs +++ b/tests/codegen-llvm/mem-replace-big-type.rs @@ -4,8 +4,6 @@ // known to be `1` after inlining). //@ compile-flags: -C no-prepopulate-passes -Zinline-mir=no -//@ ignore-std-debug-assertions -// Reason: precondition checks in ptr::read make them a bad candidate for MIR inlining //@ needs-deterministic-layouts #![crate_type = "lib"] diff --git a/tests/codegen-llvm/mem-replace-simple-type.rs b/tests/codegen-llvm/mem-replace-simple-type.rs index 9f3c6bacb712c..cc8830a700c03 100644 --- a/tests/codegen-llvm/mem-replace-simple-type.rs +++ b/tests/codegen-llvm/mem-replace-simple-type.rs @@ -1,7 +1,5 @@ //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes //@ only-x86_64 (to not worry about usize differing) -//@ ignore-std-debug-assertions -// Reason: precondition checks make mem::replace not a candidate for MIR inlining #![crate_type = "lib"] diff --git a/tests/mir-opt/pre-codegen/loops.rs b/tests/mir-opt/pre-codegen/loops.rs index 952dd8cac60fd..d0b8cc8db7a90 100644 --- a/tests/mir-opt/pre-codegen/loops.rs +++ b/tests/mir-opt/pre-codegen/loops.rs @@ -1,6 +1,5 @@ // skip-filecheck //@ compile-flags: -O -Zmir-opt-level=2 -g -//@ ignore-std-debug-assertions (debug assertions result in different inlines) //@ needs-unwind #![crate_type = "lib"] diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir index 4260ec3eaedf1..e537dd6a28ef8 100644 --- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir @@ -3,316 +3,72 @@ fn vec_move(_1: Vec) -> () { debug v => _1; let mut _0: (); - let mut _21: std::vec::IntoIter; - let mut _22: std::vec::IntoIter; - let mut _23: &mut std::vec::IntoIter; - let mut _24: std::option::Option; - let mut _25: isize; - let _27: (); + let mut _2: std::vec::IntoIter; + let mut _3: std::vec::IntoIter; + let mut _4: &mut std::vec::IntoIter; + let mut _5: std::option::Option; + let mut _6: isize; + let _8: (); scope 1 { - debug iter => _22; - let _26: impl Sized; + debug iter => _3; + let _7: impl Sized; scope 2 { - debug x => _26; - } - } - scope 3 (inlined as IntoIterator>::into_iter) { - debug self => _1; - let _2: std::mem::ManuallyDrop>; - let mut _3: *const std::alloc::Global; - let mut _8: usize; - let mut _10: *mut impl Sized; - let mut _11: *const impl Sized; - let mut _12: usize; - let _28: &std::vec::Vec; - let mut _29: &std::mem::ManuallyDrop>; - let mut _30: &alloc::raw_vec::RawVec; - let mut _31: &std::mem::ManuallyDrop>; - let _32: &std::vec::Vec; - let mut _33: &std::mem::ManuallyDrop>; - let _34: &std::vec::Vec; - let mut _35: &std::mem::ManuallyDrop>; - let mut _36: &alloc::raw_vec::RawVec; - let mut _37: &std::mem::ManuallyDrop>; - scope 4 { - debug me => _2; - scope 5 { - debug alloc => const ManuallyDrop:: {{ value: std::alloc::Global }}; - let _6: std::ptr::NonNull; - scope 6 { - debug buf => _6; - let _7: *mut impl Sized; - scope 7 { - debug begin => _7; - scope 8 { - debug end => _11; - let _19: usize; - scope 9 { - debug cap => _19; - } - scope 39 (inlined > as Deref>::deref) { - debug self => _37; - } - scope 40 (inlined alloc::raw_vec::RawVec::::capacity) { - debug self => _36; - let mut _38: &alloc::raw_vec::RawVecInner; - scope 41 (inlined std::mem::size_of::) { - } - scope 42 (inlined alloc::raw_vec::RawVecInner::capacity) { - debug self => _38; - debug elem_size => const ::SIZE; - let mut _20: core::num::niche_types::UsizeNoHighBit; - scope 43 (inlined core::num::niche_types::UsizeNoHighBit::as_inner) { - debug self => _20; - } - } - } - } - scope 25 (inlined > as Deref>::deref) { - debug self => _33; - } - scope 26 (inlined Vec::::len) { - debug self => _32; - let mut _13: bool; - scope 27 { - } - } - scope 28 (inlined std::ptr::mut_ptr::::wrapping_byte_add) { - debug self => _7; - debug count => _12; - let mut _14: *mut u8; - let mut _18: *mut u8; - scope 29 (inlined std::ptr::mut_ptr::::cast::) { - debug self => _7; - } - scope 30 (inlined std::ptr::mut_ptr::::wrapping_add) { - debug self => _14; - debug count => _12; - let mut _15: isize; - scope 31 (inlined std::ptr::mut_ptr::::wrapping_offset) { - debug self => _14; - debug count => _15; - let mut _16: *const u8; - let mut _17: *const u8; - } - } - scope 32 (inlined std::ptr::mut_ptr::::with_metadata_of::) { - debug self => _18; - debug meta => _5; - scope 33 (inlined std::ptr::metadata::) { - debug ptr => _5; - } - scope 34 (inlined std::ptr::from_raw_parts_mut::) { - } - } - } - scope 35 (inlined > as Deref>::deref) { - debug self => _35; - } - scope 36 (inlined Vec::::len) { - debug self => _34; - let mut _9: bool; - scope 37 { - } - } - scope 38 (inlined #[track_caller] std::ptr::mut_ptr::::add) { - debug self => _7; - debug count => _8; - } - } - scope 24 (inlined NonNull::::as_ptr) { - debug self => _6; - } - } - scope 17 (inlined > as Deref>::deref) { - debug self => _31; - } - scope 18 (inlined alloc::raw_vec::RawVec::::non_null) { - debug self => _30; - scope 19 (inlined alloc::raw_vec::RawVecInner::non_null::) { - let mut _4: std::ptr::NonNull; - scope 20 (inlined Unique::::cast::) { - scope 21 (inlined NonNull::::cast::) { - let mut _5: *const impl Sized; - scope 22 (inlined NonNull::::as_ptr) { - } - } - } - scope 23 (inlined Unique::::as_non_null_ptr) { - } - } - } - } - scope 11 (inlined > as Deref>::deref) { - debug self => _29; - } - scope 12 (inlined Vec::::allocator) { - debug self => _28; - scope 13 (inlined alloc::raw_vec::RawVec::::allocator) { - scope 14 (inlined alloc::raw_vec::RawVecInner::allocator) { - } - } - } - scope 15 (inlined #[track_caller] std::ptr::read::) { - debug src => _3; - } - scope 16 (inlined ManuallyDrop::::new) { - debug value => const std::alloc::Global; - } - } - scope 10 (inlined ManuallyDrop::>::new) { - debug value => _1; + debug x => _7; } } bb0: { - StorageLive(_21); - StorageLive(_6); - StorageLive(_7); - StorageLive(_11); - StorageLive(_19); - StorageLive(_5); - StorageLive(_4); - StorageLive(_17); StorageLive(_2); - _2 = ManuallyDrop::> { value: copy _1 }; - StorageLive(_3); - // DBG: _29 = &_2; - // DBG: _28 = &(_2.0: std::vec::Vec); - _3 = &raw const ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).2: std::alloc::Global); - StorageDead(_3); - // DBG: _31 = &_2; - // DBG: _30 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); - _4 = copy (((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); - _5 = copy _4 as *const impl Sized (Transmute); - _6 = NonNull:: { pointer: copy _5 }; - _7 = copy _4 as *mut impl Sized (Transmute); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; + _2 = as IntoIterator>::into_iter(move _1) -> [return: bb1, unwind continue]; } bb1: { - StorageLive(_10); - StorageLive(_8); - // DBG: _35 = &_2; - // DBG: _34 = &(_2.0: std::vec::Vec); - _8 = copy ((_2.0: std::vec::Vec).1: usize); - StorageLive(_9); - _9 = Le(copy _8, const ::MAX_SLICE_LEN); - assume(move _9); - StorageDead(_9); - _10 = Offset(copy _7, copy _8); - _11 = copy _10 as *const impl Sized (PtrToPtr); - StorageDead(_8); - StorageDead(_10); - goto -> bb4; + StorageLive(_3); + _3 = move _2; + goto -> bb2; } bb2: { - StorageLive(_12); - // DBG: _33 = &_2; - // DBG: _32 = &(_2.0: std::vec::Vec); - _12 = copy ((_2.0: std::vec::Vec).1: usize); - StorageLive(_13); - _13 = Le(copy _12, const ::MAX_SLICE_LEN); - assume(move _13); - StorageDead(_13); - StorageLive(_18); - StorageLive(_14); - _14 = copy _4 as *mut u8 (Transmute); - StorageLive(_15); - _15 = copy _12 as isize (IntToInt); - StorageLive(_16); - _16 = copy _4 as *const u8 (Transmute); - _17 = arith_offset::(move _16, move _15) -> [return: bb3, unwind unreachable]; + StorageLive(_5); + _4 = &mut _3; + _5 = as Iterator>::next(move _4) -> [return: bb3, unwind: bb9]; } bb3: { - StorageDead(_16); - _18 = copy _17 as *mut u8 (PtrToPtr); - StorageDead(_15); - StorageDead(_14); - StorageDead(_18); - StorageDead(_12); - _11 = copy _17 as *const impl Sized (PtrToPtr); - goto -> bb4; + _6 = discriminant(_5); + switchInt(move _6) -> [0: bb4, 1: bb6, otherwise: bb8]; } bb4: { - // DBG: _37 = &_2; - // DBG: _36 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); - // DBG: _38 = &(((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner); - switchInt(const ::SIZE) -> [0: bb5, otherwise: bb6]; + StorageDead(_5); + drop(_3) -> [return: bb5, unwind continue]; } bb5: { - _19 = const usize::MAX; - goto -> bb7; + StorageDead(_3); + StorageDead(_2); + return; } bb6: { - StorageLive(_20); - _20 = copy ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).1: core::num::niche_types::UsizeNoHighBit); - _19 = copy _20 as usize (Transmute); - StorageDead(_20); - goto -> bb7; + _7 = move ((_5 as Some).0: impl Sized); + _8 = opaque::(move _7) -> [return: bb7, unwind: bb9]; } bb7: { - _21 = std::vec::IntoIter:: { buf: copy _6, phantom: const ZeroSized: PhantomData, cap: move _19, alloc: const ManuallyDrop:: {{ value: std::alloc::Global }}, ptr: copy _6, end: copy _11 }; - StorageDead(_2); - StorageDead(_17); - StorageDead(_4); StorageDead(_5); - StorageDead(_19); - StorageDead(_11); - StorageDead(_7); - StorageDead(_6); - StorageLive(_22); - _22 = move _21; - goto -> bb8; + goto -> bb2; } bb8: { - StorageLive(_24); - _23 = &mut _22; - _24 = as Iterator>::next(move _23) -> [return: bb9, unwind: bb15]; - } - - bb9: { - _25 = discriminant(_24); - switchInt(move _25) -> [0: bb10, 1: bb12, otherwise: bb14]; - } - - bb10: { - StorageDead(_24); - drop(_22) -> [return: bb11, unwind continue]; - } - - bb11: { - StorageDead(_22); - StorageDead(_21); - return; - } - - bb12: { - _26 = move ((_24 as Some).0: impl Sized); - _27 = opaque::(move _26) -> [return: bb13, unwind: bb15]; - } - - bb13: { - StorageDead(_24); - goto -> bb8; - } - - bb14: { unreachable; } - bb15 (cleanup): { - drop(_22) -> [return: bb16, unwind terminate(cleanup)]; + bb9 (cleanup): { + drop(_3) -> [return: bb10, unwind terminate(cleanup)]; } - bb16 (cleanup): { + bb10 (cleanup): { resume; } } diff --git a/tests/mir-opt/pre-codegen/mem_replace.rs b/tests/mir-opt/pre-codegen/mem_replace.rs index be23dcdb22ae5..3fa5674d73285 100644 --- a/tests/mir-opt/pre-codegen/mem_replace.rs +++ b/tests/mir-opt/pre-codegen/mem_replace.rs @@ -1,7 +1,5 @@ // skip-filecheck //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 -Zinline-mir -//@ ignore-std-debug-assertions -// Reason: precondition checks on ptr::read/write are under cfg(debug_assertions) // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] diff --git a/tests/mir-opt/pre-codegen/ptr_offset.rs b/tests/mir-opt/pre-codegen/ptr_offset.rs index 120be99fc94af..138ff74483038 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.rs +++ b/tests/mir-opt/pre-codegen/ptr_offset.rs @@ -1,6 +1,6 @@ // skip-filecheck //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 -Zinline-mir -//@ ignore-std-debug-assertions (precondition checks are under cfg(debug_assertions)) +//@ ignore-std-debug-assertions (precondition checks on ptr::add are under cfg(debug_assertions)) // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index e1b6ea9349b42..fe1feb9720cb9 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -68,7 +68,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).10)) - span: $DIR/offset_of.rs:37:5: 1435:57 (#0) + span: $DIR/offset_of.rs:37:5: 1436:57 (#0) } } Stmt { @@ -117,7 +117,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).20)) - span: $DIR/offset_of.rs:38:5: 1435:57 (#0) + span: $DIR/offset_of.rs:38:5: 1436:57 (#0) } } Stmt { @@ -166,7 +166,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).30)) - span: $DIR/offset_of.rs:39:5: 1435:57 (#0) + span: $DIR/offset_of.rs:39:5: 1436:57 (#0) } } Stmt { @@ -215,7 +215,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).40)) - span: $DIR/offset_of.rs:40:5: 1435:57 (#0) + span: $DIR/offset_of.rs:40:5: 1436:57 (#0) } } Stmt { @@ -264,7 +264,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).50)) - span: $DIR/offset_of.rs:41:5: 1435:57 (#0) + span: $DIR/offset_of.rs:41:5: 1436:57 (#0) } } ] @@ -864,7 +864,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).12)) - span: $DIR/offset_of.rs:45:5: 1435:57 (#0) + span: $DIR/offset_of.rs:45:5: 1436:57 (#0) } } Stmt { @@ -913,7 +913,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).24)) - span: $DIR/offset_of.rs:46:5: 1435:57 (#0) + span: $DIR/offset_of.rs:46:5: 1436:57 (#0) } } Stmt { @@ -962,7 +962,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).36)) - span: $DIR/offset_of.rs:47:5: 1435:57 (#0) + span: $DIR/offset_of.rs:47:5: 1436:57 (#0) } } Stmt { @@ -1011,7 +1011,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).48)) - span: $DIR/offset_of.rs:48:5: 1435:57 (#0) + span: $DIR/offset_of.rs:48:5: 1436:57 (#0) } } ]