diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 24d1e35536..72c0107fa5 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -680,13 +680,18 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { if span.is_dummy() { self.custom_inst(void_ty, CustomInst::ClearDebugSrcLoc); } else { - let (file, line, col) = self.builder.file_line_col_for_op_line(span); + let (file, line_col_range) = self.builder.file_line_col_range_for_debuginfo(span); + let ((line_start, col_start), (line_end, col_end)) = + (line_col_range.start, line_col_range.end); + self.custom_inst( void_ty, CustomInst::SetDebugSrcLoc { file: Operand::IdRef(file.file_name_op_string_id), - line: Operand::IdRef(self.const_u32(line).def(self)), - col: Operand::IdRef(self.const_u32(col).def(self)), + line_start: Operand::IdRef(self.const_u32(line_start).def(self)), + line_end: Operand::IdRef(self.const_u32(line_end).def(self)), + col_start: Operand::IdRef(self.const_u32(col_start).def(self)), + col_end: Operand::IdRef(self.const_u32(col_end).def(self)), }, ); } @@ -696,7 +701,9 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { if span.is_dummy() { self.emit().no_line(); } else { - let (file, line, col) = self.builder.file_line_col_for_op_line(span); + let (file, line_col_range) = self.builder.file_line_col_range_for_debuginfo(span); + let (line, col) = line_col_range.start; + self.emit().line(file.file_name_op_string_id, line, col); } } diff --git a/crates/rustc_codegen_spirv/src/builder_spirv.rs b/crates/rustc_codegen_spirv/src/builder_spirv.rs index 51b9901898..ee55c01851 100644 --- a/crates/rustc_codegen_spirv/src/builder_spirv.rs +++ b/crates/rustc_codegen_spirv/src/builder_spirv.rs @@ -21,6 +21,7 @@ use std::assert_matches::assert_matches; use std::cell::{RefCell, RefMut}; use std::hash::{Hash, Hasher}; use std::iter; +use std::ops::Range; use std::str; use std::{fs::File, io::Write, path::Path}; @@ -678,13 +679,28 @@ impl<'tcx> BuilderSpirv<'tcx> { } } - pub fn file_line_col_for_op_line(&self, span: Span) -> (DebugFileSpirv<'tcx>, u32, u32) { - let loc = self.source_map.lookup_char_pos(span.lo()); - ( - self.def_debug_file(loc.file), - loc.line as u32, - loc.col_display as u32, - ) + pub fn file_line_col_range_for_debuginfo( + &self, + span: Span, + ) -> (DebugFileSpirv<'tcx>, Range<(u32, u32)>) { + let (lo, hi) = (span.lo(), span.hi()); + + let lo_loc = self.source_map.lookup_char_pos(lo); + let lo_line_col = (lo_loc.line as u32, lo_loc.col_display as u32); + + // Only use `hi` if the span is actually a range within a file. + let hi_line_col = if lo <= hi { + let hi_loc = self.source_map.lookup_char_pos(hi); + if lo_loc.file.start_pos == hi_loc.file.start_pos { + (hi_loc.line as u32, hi_loc.col_display as u32) + } else { + lo_line_col + } + } else { + lo_line_col + }; + + (self.def_debug_file(lo_loc.file), lo_line_col..hi_line_col) } fn def_debug_file(&self, sf: Lrc) -> DebugFileSpirv<'tcx> { diff --git a/crates/rustc_codegen_spirv/src/custom_decorations.rs b/crates/rustc_codegen_spirv/src/custom_decorations.rs index 0bbd16a63b..63f386a2d5 100644 --- a/crates/rustc_codegen_spirv/src/custom_decorations.rs +++ b/crates/rustc_codegen_spirv/src/custom_decorations.rs @@ -124,18 +124,20 @@ impl<'a> CustomDecoration<'a> for ZombieDecoration<'a> { } } -/// Equivalent of `OpLine`, for the places where `rspirv` currently doesn't let -/// us actually emit a real `OpLine`, the way generating SPIR-T directly might. +/// Equivalent of `CustomInst::SetDebugSrcLoc` (see `crate::custom_insts`), +/// for global definitions (i.e. outside functions), where limitations of +/// `rspirv`/`spirt` prevent us from using anything other than decorations. // -// NOTE(eddyb) by keeping `line`+`col`, we mimick `OpLine` limitations -// (which could be lifted in the future using custom SPIR-T debuginfo). -// NOTE(eddyb) `NonSemantic.Shader.DebugInfo`'s `DebugLine` has both start & end, -// might be good to invest in SPIR-T being able to use NonSemantic debuginfo. +// NOTE(eddyb) `CustomInst::SetDebugSrcLoc` is modelled after `DebugLine` from +// `NonSemantic.Shader.DebugInfo`, might be good to invest in SPIR-T being able +// to use `NonSemantic.Shader.DebugInfo` directly, in all situations. #[derive(Copy, Clone)] pub struct SrcLocDecoration<'a> { pub file_name: &'a str, - pub line: u32, - pub col: u32, + pub line_start: u32, + pub line_end: u32, + pub col_start: u32, + pub col_end: u32, } impl<'a> CustomDecoration<'a> for SrcLocDecoration<'a> { @@ -144,24 +146,33 @@ impl<'a> CustomDecoration<'a> for SrcLocDecoration<'a> { fn encode(self, w: &mut impl fmt::Write) -> fmt::Result { let Self { file_name, - line, - col, + line_start, + line_end, + col_start, + col_end, } = self; - write!(w, "{file_name}:{line}:{col}") + write!( + w, + "{file_name}:{line_start}:{col_start}-{line_end}:{col_end}" + ) } fn decode(s: &'a str) -> Self { #[derive(Copy, Clone, Debug)] struct InvalidSrcLoc<'a>(&'a str); let err = InvalidSrcLoc(s); - let (s, col) = s.rsplit_once(':').ok_or(err).unwrap(); - let (s, line) = s.rsplit_once(':').ok_or(err).unwrap(); + let (s, col_end) = s.rsplit_once(':').ok_or(err).unwrap(); + let (s, line_end) = s.rsplit_once('-').ok_or(err).unwrap(); + let (s, col_start) = s.rsplit_once(':').ok_or(err).unwrap(); + let (s, line_start) = s.rsplit_once(':').ok_or(err).unwrap(); let file_name = s; Self { file_name, - line: line.parse().unwrap(), - col: col.parse().unwrap(), + line_start: line_start.parse().unwrap(), + line_end: line_end.parse().unwrap(), + col_start: col_start.parse().unwrap(), + col_end: col_end.parse().unwrap(), } } } @@ -174,12 +185,16 @@ impl<'tcx> SrcLocDecoration<'tcx> { return None; } - let (file, line, col) = builder.file_line_col_for_op_line(span); + let (file, line_col_range) = builder.file_line_col_range_for_debuginfo(span); + let ((line_start, col_start), (line_end, col_end)) = + (line_col_range.start, line_col_range.end); Some(Self { file_name: file.file_name, - line, - col, + line_start, + line_end, + col_start, + col_end, }) } } @@ -361,24 +376,37 @@ impl<'a> SpanRegenerator<'a> { .spv_debug_info .get_or_insert_with(|| SpvDebugInfo::collect(self.module)); - let (file_id, line, col) = match inst.class.opcode { - Op::Line => ( - inst.operands[0].unwrap_id_ref(), - inst.operands[1].unwrap_literal_int32(), - inst.operands[2].unwrap_literal_int32(), - ), + let (file_id, line_start, line_end, col_start, col_end) = match inst.class.opcode { + Op::Line => { + let file = inst.operands[0].unwrap_id_ref(); + let line = inst.operands[1].unwrap_literal_int32(); + let col = inst.operands[2].unwrap_literal_int32(); + (file, line, line, col, col) + } Op::ExtInst if Some(inst.operands[0].unwrap_id_ref()) == spv_debug_info.custom_ext_inst_set_import => { match CustomInst::decode(inst) { - CustomInst::SetDebugSrcLoc { file, line, col } => ( - file.unwrap_id_ref(), - spv_debug_info.id_to_op_constant_operand[&line.unwrap_id_ref()] - .unwrap_literal_int32(), - spv_debug_info.id_to_op_constant_operand[&col.unwrap_id_ref()] - .unwrap_literal_int32(), - ), + CustomInst::SetDebugSrcLoc { + file, + line_start, + line_end, + col_start, + col_end, + } => { + let const_u32 = |operand: Operand| { + spv_debug_info.id_to_op_constant_operand[&operand.unwrap_id_ref()] + .unwrap_literal_int32() + }; + ( + file.unwrap_id_ref(), + const_u32(line_start), + const_u32(line_end), + const_u32(col_start), + const_u32(col_end), + ) + } custom_inst @ CustomInst::ClearDebugSrcLoc => { unreachable!("src_loc_from_debug_inst({inst:?} => {custom_inst:?})") } @@ -392,8 +420,10 @@ impl<'a> SpanRegenerator<'a> { .get(&file_id) .map(|&file_name| SrcLocDecoration { file_name, - line, - col, + line_start, + line_end, + col_start, + col_end, }) } @@ -455,66 +485,77 @@ impl<'a> SpanRegenerator<'a> { pub fn src_loc_to_rustc(&mut self, src_loc: SrcLocDecoration<'_>) -> Option { let SrcLocDecoration { file_name, - line, - col, + line_start, + line_end, + col_start, + col_end, } = src_loc; let file = self.regenerate_rustc_source_file(file_name)?; - let line_bpos_range = file.line_bounds(line.checked_sub(1)? as usize); + // FIXME(eddyb) avoid some of the duplicated work when this closure is + // called with `line`/`col` values that are near eachother - thankfully, + // this code should only be hit on the error reporting path anyway. + let line_col_to_bpos = |line: u32, col: u32| { + let line_bpos_range = file.line_bounds(line.checked_sub(1)? as usize); - // Find the special cases (`MultiByteChar`s/`NonNarrowChar`s) in the line. - let multibyte_chars = { - let find = |bpos| { - file.multibyte_chars - .binary_search_by_key(&bpos, |mbc| mbc.pos) - .unwrap_or_else(|x| x) + // Find the special cases (`MultiByteChar`s/`NonNarrowChar`s) in the line. + let multibyte_chars = { + let find = |bpos| { + file.multibyte_chars + .binary_search_by_key(&bpos, |mbc| mbc.pos) + .unwrap_or_else(|x| x) + }; + let Range { start, end } = line_bpos_range; + file.multibyte_chars[find(start)..find(end)].iter() }; - let Range { start, end } = line_bpos_range; - file.multibyte_chars[find(start)..find(end)].iter() - }; - let non_narrow_chars = { - let find = |bpos| { - file.non_narrow_chars - .binary_search_by_key(&bpos, |nnc| nnc.pos()) - .unwrap_or_else(|x| x) + let non_narrow_chars = { + let find = |bpos| { + file.non_narrow_chars + .binary_search_by_key(&bpos, |nnc| nnc.pos()) + .unwrap_or_else(|x| x) + }; + let Range { start, end } = line_bpos_range; + file.non_narrow_chars[find(start)..find(end)].iter() }; - let Range { start, end } = line_bpos_range; - file.non_narrow_chars[find(start)..find(end)].iter() - }; - let mut special_chars = multibyte_chars - .merge_join_by(non_narrow_chars, |mbc, nnc| mbc.pos.cmp(&nnc.pos())) - .peekable(); + let mut special_chars = multibyte_chars + .merge_join_by(non_narrow_chars, |mbc, nnc| mbc.pos.cmp(&nnc.pos())) + .peekable(); - // Increment the `BytePos` until we reach the right `col_display`, using - // `MultiByteChar`s/`NonNarrowChar`s to track non-trivial contributions - // (this may look inefficient, but lines tend to be short, and `rustc` - // itself is even worse than this, when it comes to `BytePos` lookups). - let (mut cur_bpos, mut cur_col_display) = (line_bpos_range.start, 0); - while cur_bpos < line_bpos_range.end && cur_col_display < col { - let next_special_bpos = special_chars.peek().map(|special| { - special - .as_ref() - .map_any(|mbc| mbc.pos, |nnc| nnc.pos()) - .reduce(|x, _| x) - }); + // Increment the `BytePos` until we reach the right `col_display`, using + // `MultiByteChar`s/`NonNarrowChar`s to track non-trivial contributions + // (this may look inefficient, but lines tend to be short, and `rustc` + // itself is even worse than this, when it comes to `BytePos` lookups). + let (mut cur_bpos, mut cur_col_display) = (line_bpos_range.start, 0); + while cur_bpos < line_bpos_range.end && cur_col_display < col { + let next_special_bpos = special_chars.peek().map(|special| { + special + .as_ref() + .map_any(|mbc| mbc.pos, |nnc| nnc.pos()) + .reduce(|x, _| x) + }); - // Batch trivial chars (i.e. chars 1:1 wrt `BytePos` vs `col_display`). - let following_trivial_chars = - next_special_bpos.unwrap_or(line_bpos_range.end).0 - cur_bpos.0; - if following_trivial_chars > 0 { - let wanted_trivial_chars = following_trivial_chars.min(col - cur_col_display); - cur_bpos.0 += wanted_trivial_chars; - cur_col_display += wanted_trivial_chars; - continue; + // Batch trivial chars (i.e. chars 1:1 wrt `BytePos` vs `col_display`). + let following_trivial_chars = + next_special_bpos.unwrap_or(line_bpos_range.end).0 - cur_bpos.0; + if following_trivial_chars > 0 { + let wanted_trivial_chars = following_trivial_chars.min(col - cur_col_display); + cur_bpos.0 += wanted_trivial_chars; + cur_col_display += wanted_trivial_chars; + continue; + } + + // Add a special char's `BytePos` and `col_display` contributions. + let mbc_nnc = special_chars.next().unwrap(); + cur_bpos.0 += mbc_nnc.as_ref().left().map_or(1, |mbc| mbc.bytes as u32); + cur_col_display += mbc_nnc.as_ref().right().map_or(1, |nnc| nnc.width() as u32); } + Some(cur_bpos) + }; - // Add a special char's `BytePos` and `col_display` contributions. - let mbc_nnc = special_chars.next().unwrap(); - cur_bpos.0 += mbc_nnc.as_ref().left().map_or(1, |mbc| mbc.bytes as u32); - cur_col_display += mbc_nnc.as_ref().right().map_or(1, |nnc| nnc.width() as u32); - } - - Some(Span::with_root_ctxt(cur_bpos, cur_bpos)) + Some(Span::with_root_ctxt( + line_col_to_bpos(line_start, col_start)?, + line_col_to_bpos(line_end, col_end)?, + )) } } diff --git a/crates/rustc_codegen_spirv/src/custom_insts.rs b/crates/rustc_codegen_spirv/src/custom_insts.rs index 2b2b736956..19926f02c8 100644 --- a/crates/rustc_codegen_spirv/src/custom_insts.rs +++ b/crates/rustc_codegen_spirv/src/custom_insts.rs @@ -109,10 +109,11 @@ macro_rules! def_custom_insts { } } +// NOTE(eddyb) several of these are similar to `NonSemantic.Shader.DebugInfo.100` +// instructions, but simpler (to aid implementation, for now). def_custom_insts! { - // `OpLine` equivalent. - // FIXME(eddyb) improve on this, by adding more information. - 0 => SetDebugSrcLoc { file, line, col }, - // `OpNoLine` equivalent. + // Like `DebugLine` (from `NonSemantic.Shader.DebugInfo.100`) or `OpLine`. + 0 => SetDebugSrcLoc { file, line_start, line_end, col_start, col_end }, + // Like `DebugNoLine` (from `NonSemantic.Shader.DebugInfo.100`) or `OpNoLine`. 1 => ClearDebugSrcLoc, } diff --git a/crates/rustc_codegen_spirv/src/linker/spirt_passes/debuginfo.rs b/crates/rustc_codegen_spirv/src/linker/spirt_passes/debuginfo.rs index c6263e45f6..9db741aa18 100644 --- a/crates/rustc_codegen_spirv/src/linker/spirt_passes/debuginfo.rs +++ b/crates/rustc_codegen_spirv/src/linker/spirt_passes/debuginfo.rs @@ -86,7 +86,13 @@ impl Transformer for CustomDebuginfoToSpv<'_> { { if ext_set == self.custom_ext_inst_set { match CustomOp::decode(ext_inst).with_operands(&data_inst_def.inputs) { - CustomInst::SetDebugSrcLoc { file, line, col } => { + CustomInst::SetDebugSrcLoc { + file, + line_start: line, + line_end: _, + col_start: col, + col_end: _, + } => { let const_ctor = |v: Value| match v { Value::Const(ct) => &self.cx[ct].ctor, _ => unreachable!(), diff --git a/crates/rustc_codegen_spirv/src/linker/spirt_passes/diagnostics.rs b/crates/rustc_codegen_spirv/src/linker/spirt_passes/diagnostics.rs index 3f3f2c9d44..2e8d322bb6 100644 --- a/crates/rustc_codegen_spirv/src/linker/spirt_passes/diagnostics.rs +++ b/crates/rustc_codegen_spirv/src/linker/spirt_passes/diagnostics.rs @@ -213,8 +213,10 @@ impl UseOrigin<'_> { col, } => span_regen.src_loc_to_rustc(SrcLocDecoration { file_name: &cx[file_path.0], - line, - col, + line_start: line, + line_end: line, + col_start: col, + col_end: col, }), _ => None, }) @@ -251,10 +253,17 @@ impl UseOrigin<'_> { } _ => unreachable!(), }; - let (file, line, col) = match custom_op.with_operands(&debug_inst_def.inputs) { - CustomInst::SetDebugSrcLoc { file, line, col } => (file, line, col), - CustomInst::ClearDebugSrcLoc => unreachable!(), - }; + let (file, line_start, line_end, col_start, col_end) = + match custom_op.with_operands(&debug_inst_def.inputs) { + CustomInst::SetDebugSrcLoc { + file, + line_start, + line_end, + col_start, + col_end, + } => (file, line_start, line_end, col_start, col_end), + CustomInst::ClearDebugSrcLoc => unreachable!(), + }; let const_ctor = |v: Value| match v { Value::Const(ct) => &cx[ct].ctor, _ => unreachable!(), @@ -276,8 +285,10 @@ impl UseOrigin<'_> { span_regen.src_loc_to_rustc(SrcLocDecoration { file_name: &cx[const_str(file)], - line: const_u32(line), - col: const_u32(col), + line_start: const_u32(line_start), + line_end: const_u32(line_end), + col_start: const_u32(col_start), + col_end: const_u32(col_end), }) }) .or_else(|| from_attrs(func_attrs, span_regen)), diff --git a/tests/ui/dis/ptr_copy.normal.stderr b/tests/ui/dis/ptr_copy.normal.stderr index 42d4114aa3..2242059d6f 100644 --- a/tests/ui/dis/ptr_copy.normal.stderr +++ b/tests/ui/dis/ptr_copy.normal.stderr @@ -2,28 +2,28 @@ error: cannot memcpy dynamically sized data --> $CORE_SRC/intrinsics.rs:2460:9 | 2460 | copy(src, dst, count) - | ^ + | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` --> $CORE_SRC/intrinsics.rs:2447:21 | 2447 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { - | ^ + | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 | 28 | unsafe { core::ptr::copy(src, dst, 1) } - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: called by `ptr_copy::main` --> $DIR/ptr_copy.rs:33:5 | 33 | copy_via_raw_ptr(&i, o); - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^ note: called by `main` --> $DIR/ptr_copy.rs:31:1 | 31 | #[spirv(fragment)] - | ^ + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/lang/consts/nested-ref-in-composite.stderr b/tests/ui/lang/consts/nested-ref-in-composite.stderr index d6205a866a..6e91db40d5 100644 --- a/tests/ui/lang/consts/nested-ref-in-composite.stderr +++ b/tests/ui/lang/consts/nested-ref-in-composite.stderr @@ -2,35 +2,35 @@ error: constant arrays/structs cannot contain pointers to other constants --> $DIR/nested-ref-in-composite.rs:20:17 | 20 | *pair_out = pair_deep_load(&(&123, &3.14)); - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: used from within `nested_ref_in_composite::main_pair` --> $DIR/nested-ref-in-composite.rs:20:17 | 20 | *pair_out = pair_deep_load(&(&123, &3.14)); - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: called by `main_pair` --> $DIR/nested-ref-in-composite.rs:18:1 | 18 | #[spirv(fragment)] - | ^ + | ^^^^^^^^^^^^^^^^^^ error: constant arrays/structs cannot contain pointers to other constants --> $DIR/nested-ref-in-composite.rs:25:19 | 25 | *array3_out = array3_deep_load(&[&0, &1, &2]); - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: used from within `nested_ref_in_composite::main_array3` --> $DIR/nested-ref-in-composite.rs:25:19 | 25 | *array3_out = array3_deep_load(&[&0, &1, &2]); - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: called by `main_array3` --> $DIR/nested-ref-in-composite.rs:23:1 | 23 | #[spirv(fragment)] - | ^ + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/lang/core/ptr/allocate_const_scalar.stderr b/tests/ui/lang/core/ptr/allocate_const_scalar.stderr index c6ca98ddc3..8c2fca2b50 100644 --- a/tests/ui/lang/core/ptr/allocate_const_scalar.stderr +++ b/tests/ui/lang/core/ptr/allocate_const_scalar.stderr @@ -4,12 +4,12 @@ note: used from within `allocate_const_scalar::main` --> $DIR/allocate_const_scalar.rs:15:20 | 15 | let _pointer = POINTER; - | ^ + | ^^^^^^^ note: called by `main` --> $DIR/allocate_const_scalar.rs:13:1 | 13 | #[spirv(fragment)] - | ^ + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/lang/core/ref/zst_member_ref_arg-broken.stderr b/tests/ui/lang/core/ref/zst_member_ref_arg-broken.stderr index 2d1234f377..95972f2686 100644 --- a/tests/ui/lang/core/ref/zst_member_ref_arg-broken.stderr +++ b/tests/ui/lang/core/ref/zst_member_ref_arg-broken.stderr @@ -4,18 +4,18 @@ error: cannot cast between pointer types --> $DIR/zst_member_ref_arg-broken.rs:23:5 | 23 | f(&s.y); - | ^ + | ^^^^^^^ | note: used from within `zst_member_ref_arg_broken::main_scalar` --> $DIR/zst_member_ref_arg-broken.rs:23:5 | 23 | f(&s.y); - | ^ + | ^^^^^^^ note: called by `main_scalar` --> $DIR/zst_member_ref_arg-broken.rs:21:1 | 21 | #[spirv(fragment)] - | ^ + | ^^^^^^^^^^^^^^^^^^ error: cannot cast between pointer types from `*struct S { u32, u32 }` @@ -23,18 +23,18 @@ error: cannot cast between pointer types --> $DIR/zst_member_ref_arg-broken.rs:28:5 | 28 | f(&s.y); - | ^ + | ^^^^^^^ | note: used from within `zst_member_ref_arg_broken::main_scalar_pair` --> $DIR/zst_member_ref_arg-broken.rs:28:5 | 28 | f(&s.y); - | ^ + | ^^^^^^^ note: called by `main_scalar_pair` --> $DIR/zst_member_ref_arg-broken.rs:26:1 | 26 | #[spirv(fragment)] - | ^ + | ^^^^^^^^^^^^^^^^^^ error: cannot cast between pointer types from `*struct (usize, usize) { u32, u32 }` @@ -42,18 +42,18 @@ error: cannot cast between pointer types --> $DIR/zst_member_ref_arg-broken.rs:33:5 | 33 | f(&s.y); - | ^ + | ^^^^^^^ | note: used from within `zst_member_ref_arg_broken::main_scalar_scalar_pair_nested` --> $DIR/zst_member_ref_arg-broken.rs:33:5 | 33 | f(&s.y); - | ^ + | ^^^^^^^ note: called by `main_scalar_scalar_pair_nested` --> $DIR/zst_member_ref_arg-broken.rs:31:1 | 31 | #[spirv(fragment)] - | ^ + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors