Skip to content

Commit 899eb03

Browse files
committed
Auto merge of #128703 - compiler-errors:normalizing-tails, r=lcnr
Miscellaneous improvements to struct tail normalization 1. Make checks for foreign tails more accurate by normalizing the struct tail. I didn't write a test for this one. 2. Normalize when computing struct tail for `offset_of` for slice/str. This fixes the new solver only. 3. Normalizing when computing tails for disaligned reference check. This fixes both solvers. r? lcnr
2 parents 97e7252 + b916431 commit 899eb03

File tree

22 files changed

+245
-46
lines changed

22 files changed

+245
-46
lines changed

Diff for: compiler/rustc_codegen_cranelift/src/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
107107
return false;
108108
}
109109

110-
let tail = tcx.struct_tail_erasing_lifetimes(ty, ParamEnv::reveal_all());
110+
let tail = tcx.struct_tail_for_codegen(ty, ParamEnv::reveal_all());
111111
match tail.kind() {
112112
ty::Foreign(..) => false,
113113
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,

Diff for: compiler/rustc_codegen_cranelift/src/unsize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub(crate) fn unsized_info<'tcx>(
2222
old_info: Option<Value>,
2323
) -> Value {
2424
let (source, target) =
25-
fx.tcx.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
25+
fx.tcx.struct_lockstep_tails_for_codegen(source, target, ParamEnv::reveal_all());
2626
match (&source.kind(), &target.kind()) {
2727
(&ty::Array(_, len), &ty::Slice(_)) => fx
2828
.bcx

Diff for: compiler/rustc_codegen_llvm/src/builder.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use rustc_data_structures::small_c_str::SmallCStr;
1212
use rustc_hir::def_id::DefId;
1313
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
1414
use rustc_middle::ty::layout::{
15-
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
15+
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
16+
TyAndLayout,
1617
};
1718
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
1819
use rustc_sanitizers::{cfi, kcfi};
@@ -531,7 +532,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
531532
#[instrument(level = "trace", skip(self))]
532533
fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx, &'ll Value> {
533534
if place.layout.is_unsized() {
534-
let tail = self.tcx.struct_tail_with_normalize(place.layout.ty, |ty| ty, || {});
535+
let tail = self.tcx.struct_tail_for_codegen(place.layout.ty, self.param_env());
535536
if matches!(tail.kind(), ty::Foreign(..)) {
536537
// Unsized locals and, at least conceptually, even unsized arguments must be copied
537538
// around, which requires dynamically determining their size. Therefore, we cannot

Diff for: compiler/rustc_codegen_llvm/src/debuginfo/utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub(crate) fn fat_pointer_kind<'ll, 'tcx>(
6262
cx: &CodegenCx<'ll, 'tcx>,
6363
pointee_ty: Ty<'tcx>,
6464
) -> Option<FatPtrKind> {
65-
let pointee_tail_ty = cx.tcx.struct_tail_erasing_lifetimes(pointee_ty, cx.param_env());
65+
let pointee_tail_ty = cx.tcx.struct_tail_for_codegen(pointee_ty, cx.param_env());
6666
let layout = cx.layout_of(pointee_tail_ty);
6767
trace!(
6868
"fat_pointer_kind: {:?} has layout {:?} (is_unsized? {})",

Diff for: compiler/rustc_codegen_ssa/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
143143
) -> Bx::Value {
144144
let cx = bx.cx();
145145
let (source, target) =
146-
cx.tcx().struct_lockstep_tails_erasing_lifetimes(source, target, bx.param_env());
146+
cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.param_env());
147147
match (source.kind(), target.kind()) {
148148
(&ty::Array(_, len), &ty::Slice(_)) => {
149149
cx.const_usize(len.eval_target_usize(cx.tcx(), ty::ParamEnv::reveal_all()))

Diff for: compiler/rustc_codegen_ssa/src/traits/type_.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
9191
return false;
9292
}
9393

94-
let tail = self.tcx().struct_tail_erasing_lifetimes(ty, param_env);
94+
let tail = self.tcx().struct_tail_for_codegen(ty, param_env);
9595
match tail.kind() {
9696
ty::Foreign(..) => false,
9797
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,

Diff for: compiler/rustc_const_eval/src/interpret/call.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -678,9 +678,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
678678
} else {
679679
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
680680
// (For that reason we also cannot use `unpack_dyn_trait`.)
681-
let receiver_tail = self
682-
.tcx
683-
.struct_tail_erasing_lifetimes(receiver_place.layout.ty, self.param_env);
681+
let receiver_tail =
682+
self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.param_env);
684683
let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else {
685684
span_bug!(
686685
self.cur_span(),

Diff for: compiler/rustc_const_eval/src/interpret/cast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
386386
) -> InterpResult<'tcx> {
387387
// A<Struct> -> A<Trait> conversion
388388
let (src_pointee_ty, dest_pointee_ty) =
389-
self.tcx.struct_lockstep_tails_erasing_lifetimes(source_ty, cast_ty, self.param_env);
389+
self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.param_env);
390390

391391
match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) {
392392
(&ty::Array(_, length), &ty::Slice(_)) => {

Diff for: compiler/rustc_const_eval/src/interpret/validity.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
343343
meta: MemPlaceMeta<M::Provenance>,
344344
pointee: TyAndLayout<'tcx>,
345345
) -> InterpResult<'tcx> {
346-
let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env);
346+
let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.param_env);
347347
match tail.kind() {
348348
ty::Dynamic(data, _, ty::Dyn) => {
349349
let vtable = meta.unwrap_meta().to_pointer(self.ecx)?;

Diff for: compiler/rustc_const_eval/src/util/alignment.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ where
2222
};
2323

2424
let ty = place.ty(local_decls, tcx).ty;
25-
let unsized_tail = || tcx.struct_tail_with_normalize(ty, |ty| ty, || {});
25+
let unsized_tail = || tcx.struct_tail_for_codegen(ty, param_env);
2626
match tcx.layout_of(param_env.and(ty)) {
2727
Ok(layout)
2828
if layout.align.abi <= pack

Diff for: compiler/rustc_hir_analysis/src/check/wfcheck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1276,7 +1276,7 @@ fn check_item_type(
12761276
UnsizedHandling::Forbid => true,
12771277
UnsizedHandling::Allow => false,
12781278
UnsizedHandling::AllowIfForeignTail => {
1279-
let tail = tcx.struct_tail_erasing_lifetimes(item_ty, wfcx.param_env);
1279+
let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.param_env);
12801280
!matches!(tail.kind(), ty::Foreign(_))
12811281
}
12821282
};

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
404404
code: traits::ObligationCauseCode<'tcx>,
405405
) {
406406
if !ty.references_error() {
407-
let tail =
408-
self.tcx.struct_tail_with_normalize(ty, |ty| self.normalize(span, ty), || {});
407+
let tail = self.tcx.struct_tail_with_normalize(
408+
ty,
409+
|ty| {
410+
if self.next_trait_solver() {
411+
self.try_structurally_resolve_type(span, ty)
412+
} else {
413+
self.normalize(span, ty)
414+
}
415+
},
416+
|| {},
417+
);
409418
// Sized types have static alignment, and so do slices.
410419
if tail.is_trivially_sized(self.tcx) || matches!(tail.kind(), ty::Slice(..)) {
411420
// Nothing else is required here.

Diff for: compiler/rustc_middle/src/ty/layout.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ where
869869
metadata
870870
}
871871
} else {
872-
match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() {
872+
match tcx.struct_tail_for_codegen(pointee, cx.param_env()).kind() {
873873
ty::Slice(_) | ty::Str => tcx.types.usize,
874874
ty::Dynamic(data, _, ty::Dyn) => mk_dyn_vtable(data.principal()),
875875
_ => bug!("TyAndLayout::field({:?}): not applicable", this),
@@ -1348,7 +1348,7 @@ impl<'tcx> TyCtxt<'tcx> {
13481348
layout = layout.field(&cx, index);
13491349
if !layout.is_sized() {
13501350
// If it is not sized, then the tail must still have at least a known static alignment.
1351-
let tail = self.struct_tail_erasing_lifetimes(layout.ty, param_env);
1351+
let tail = self.struct_tail_for_codegen(layout.ty, param_env);
13521352
if !matches!(tail.kind(), ty::Slice(..)) {
13531353
bug!(
13541354
"offset of not-statically-aligned field (type {:?}) cannot be computed statically",

Diff for: compiler/rustc_middle/src/ty/util.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,7 @@ impl<'tcx> TyCtxt<'tcx> {
186186
/// Should only be called if `ty` has no inference variables and does not
187187
/// need its lifetimes preserved (e.g. as part of codegen); otherwise
188188
/// normalization attempt may cause compiler bugs.
189-
pub fn struct_tail_erasing_lifetimes(
190-
self,
191-
ty: Ty<'tcx>,
192-
param_env: ty::ParamEnv<'tcx>,
193-
) -> Ty<'tcx> {
189+
pub fn struct_tail_for_codegen(self, ty: Ty<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
194190
let tcx = self;
195191
tcx.struct_tail_with_normalize(ty, |ty| tcx.normalize_erasing_regions(param_env, ty), || {})
196192
}
@@ -203,7 +199,7 @@ impl<'tcx> TyCtxt<'tcx> {
203199
/// handle `<T as Trait>::Assoc` and `impl Trait`); pass the identity
204200
/// function to indicate no normalization should take place.
205201
///
206-
/// See also `struct_tail_erasing_lifetimes`, which is suitable for use
202+
/// See also `struct_tail_for_codegen`, which is suitable for use
207203
/// during codegen.
208204
pub fn struct_tail_with_normalize(
209205
self,
@@ -272,13 +268,13 @@ impl<'tcx> TyCtxt<'tcx> {
272268
/// Same as applying `struct_tail` on `source` and `target`, but only
273269
/// keeps going as long as the two types are instances of the same
274270
/// structure definitions.
275-
/// For `(Foo<Foo<T>>, Foo<dyn Trait>)`, the result will be `(Foo<T>, Trait)`,
271+
/// For `(Foo<Foo<T>>, Foo<dyn Trait>)`, the result will be `(Foo<T>, dyn Trait)`,
276272
/// whereas struct_tail produces `T`, and `Trait`, respectively.
277273
///
278274
/// Should only be called if the types have no inference variables and do
279275
/// not need their lifetimes preserved (e.g., as part of codegen); otherwise,
280276
/// normalization attempt may cause compiler bugs.
281-
pub fn struct_lockstep_tails_erasing_lifetimes(
277+
pub fn struct_lockstep_tails_for_codegen(
282278
self,
283279
source: Ty<'tcx>,
284280
target: Ty<'tcx>,
@@ -296,7 +292,7 @@ impl<'tcx> TyCtxt<'tcx> {
296292
/// For `(Foo<Foo<T>>, Foo<dyn Trait>)`, the result will be `(Foo<T>, Trait)`,
297293
/// whereas struct_tail produces `T`, and `Trait`, respectively.
298294
///
299-
/// See also `struct_lockstep_tails_erasing_lifetimes`, which is suitable for use
295+
/// See also `struct_lockstep_tails_for_codegen`, which is suitable for use
300296
/// during codegen.
301297
pub fn struct_lockstep_tails_with_normalize(
302298
self,

Diff for: compiler/rustc_monomorphize/src/collector.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,7 @@ fn find_vtable_types_for_unsizing<'tcx>(
10191019
if ty.is_sized(tcx.tcx, param_env) {
10201020
return false;
10211021
}
1022-
let tail = tcx.struct_tail_erasing_lifetimes(ty, param_env);
1022+
let tail = tcx.struct_tail_for_codegen(ty, param_env);
10231023
match tail.kind() {
10241024
ty::Foreign(..) => false,
10251025
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
@@ -1029,7 +1029,7 @@ fn find_vtable_types_for_unsizing<'tcx>(
10291029
if type_has_metadata(inner_source) {
10301030
(inner_source, inner_target)
10311031
} else {
1032-
tcx.struct_lockstep_tails_erasing_lifetimes(inner_source, inner_target, param_env)
1032+
tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, param_env)
10331033
}
10341034
};
10351035

Diff for: compiler/rustc_ty_utils/src/abi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ fn fn_abi_sanity_check<'tcx>(
549549
// With metadata. Must be unsized and not on the stack.
550550
assert!(arg.layout.is_unsized() && !on_stack);
551551
// Also, must not be `extern` type.
552-
let tail = cx.tcx.struct_tail_with_normalize(arg.layout.ty, |ty| ty, || {});
552+
let tail = cx.tcx.struct_tail_for_codegen(arg.layout.ty, cx.param_env());
553553
if matches!(tail.kind(), ty::Foreign(..)) {
554554
// These types do not have metadata, so having `meta_attrs` is bogus.
555555
// Conceptually, unsized arguments must be copied around, which requires dynamically

Diff for: compiler/rustc_ty_utils/src/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ fn layout_of_uncached<'tcx>(
244244

245245
metadata
246246
} else {
247-
let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
247+
let unsized_part = tcx.struct_tail_for_codegen(pointee, param_env);
248248

249249
match unsized_part.kind() {
250250
ty::Foreign(..) => {

Diff for: src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ fn check_rvalue<'tcx>(
142142
// We cannot allow this for now.
143143
return Err((span, "unsizing casts are only allowed for references right now".into()));
144144
};
145-
let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id));
145+
let unsized_ty = tcx.struct_tail_for_codegen(pointee_ty, tcx.param_env(def_id));
146146
if let ty::Slice(_) | ty::Str = unsized_ty.kind() {
147147
check_operand(tcx, op, span, body, msrv)?;
148148
// Casting/coercing things to slices is fine.

Diff for: tests/ui/lint/unaligned_references.stderr renamed to tests/ui/lint/unaligned_references.current.stderr

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0793]: reference to packed field is unaligned
2-
--> $DIR/unaligned_references.rs:28:13
2+
--> $DIR/unaligned_references.rs:32:13
33
|
44
LL | &self.x;
55
| ^^^^^^^
@@ -9,7 +9,7 @@ LL | &self.x;
99
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
1010

1111
error[E0793]: reference to packed field is unaligned
12-
--> $DIR/unaligned_references.rs:40:24
12+
--> $DIR/unaligned_references.rs:44:24
1313
|
1414
LL | println!("{:?}", &*foo.0);
1515
| ^^^^^
@@ -19,7 +19,7 @@ LL | println!("{:?}", &*foo.0);
1919
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
2020

2121
error[E0793]: reference to packed field is unaligned
22-
--> $DIR/unaligned_references.rs:42:24
22+
--> $DIR/unaligned_references.rs:46:24
2323
|
2424
LL | println!("{:?}", &*foo.0);
2525
| ^^^^^
@@ -29,7 +29,7 @@ LL | println!("{:?}", &*foo.0);
2929
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
3030

3131
error[E0793]: reference to packed field is unaligned
32-
--> $DIR/unaligned_references.rs:47:24
32+
--> $DIR/unaligned_references.rs:51:24
3333
|
3434
LL | println!("{:?}", &*foo.0);
3535
| ^^^^^
@@ -39,7 +39,7 @@ LL | println!("{:?}", &*foo.0);
3939
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
4040

4141
error[E0793]: reference to packed field is unaligned
42-
--> $DIR/unaligned_references.rs:57:17
42+
--> $DIR/unaligned_references.rs:81:17
4343
|
4444
LL | let _ = &good.ptr;
4545
| ^^^^^^^^^
@@ -49,7 +49,7 @@ LL | let _ = &good.ptr;
4949
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
5050

5151
error[E0793]: reference to packed field is unaligned
52-
--> $DIR/unaligned_references.rs:58:17
52+
--> $DIR/unaligned_references.rs:82:17
5353
|
5454
LL | let _ = &good.data;
5555
| ^^^^^^^^^^
@@ -59,7 +59,7 @@ LL | let _ = &good.data;
5959
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
6060

6161
error[E0793]: reference to packed field is unaligned
62-
--> $DIR/unaligned_references.rs:60:17
62+
--> $DIR/unaligned_references.rs:84:17
6363
|
6464
LL | let _ = &good.data as *const _;
6565
| ^^^^^^^^^^
@@ -69,7 +69,7 @@ LL | let _ = &good.data as *const _;
6969
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
7070

7171
error[E0793]: reference to packed field is unaligned
72-
--> $DIR/unaligned_references.rs:61:27
72+
--> $DIR/unaligned_references.rs:85:27
7373
|
7474
LL | let _: *const _ = &good.data;
7575
| ^^^^^^^^^^
@@ -79,7 +79,7 @@ LL | let _: *const _ = &good.data;
7979
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
8080

8181
error[E0793]: reference to packed field is unaligned
82-
--> $DIR/unaligned_references.rs:63:17
82+
--> $DIR/unaligned_references.rs:87:17
8383
|
8484
LL | let _ = good.data.clone();
8585
| ^^^^^^^^^
@@ -89,7 +89,7 @@ LL | let _ = good.data.clone();
8989
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
9090

9191
error[E0793]: reference to packed field is unaligned
92-
--> $DIR/unaligned_references.rs:65:17
92+
--> $DIR/unaligned_references.rs:89:17
9393
|
9494
LL | let _ = &good.data2[0];
9595
| ^^^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL | let _ = &good.data2[0];
9999
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
100100

101101
error[E0793]: reference to packed field is unaligned
102-
--> $DIR/unaligned_references.rs:74:17
102+
--> $DIR/unaligned_references.rs:98:17
103103
|
104104
LL | let _ = &packed2.x;
105105
| ^^^^^^^^^^
@@ -109,7 +109,7 @@ LL | let _ = &packed2.x;
109109
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
110110

111111
error[E0793]: reference to packed field is unaligned
112-
--> $DIR/unaligned_references.rs:113:20
112+
--> $DIR/unaligned_references.rs:137:20
113113
|
114114
LL | let _ref = &m1.1.a;
115115
| ^^^^^^^
@@ -119,7 +119,7 @@ LL | let _ref = &m1.1.a;
119119
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
120120

121121
error[E0793]: reference to packed field is unaligned
122-
--> $DIR/unaligned_references.rs:116:20
122+
--> $DIR/unaligned_references.rs:140:20
123123
|
124124
LL | let _ref = &m2.1.a;
125125
| ^^^^^^^

0 commit comments

Comments
 (0)