Question:
Hi there! I encountered a weird situation when writing a device driver using . Despite getting correct temperature readings in byte form from my thermocouple converter, all readings were incorrect after casting them to floats and applying some fundamental transformations. After much confusion, I tried using instead and found it worked perfectly! However, I knew the transformations should be correct either way: I tested this exact setup and formula using Linux and the crate. That led me to test those transformations on a few different machines. Please take a look at the results below to gain better insight. Arduino Device Other machines for all below MacBook Pro M1 on macOS and Asahi Linux () Linux () macOS () Ryzen desktop machine running Linux () Milk-V Duo () I can do more if you'd like! If there's any additional context I can give, or checking to be done, please let me know, and I'll happily look into it! Also, I did check the crate to see if it was working properly! I assume that since the and ufmt_float'd are the same, it must be an issue with itself. Please see and of the original test to get more info. Thank you for taking a look at my problem!
trying to figure out if this is a regression. I see that you tested on , does it also reproduce on other versions of the rust compiler? Did you try using a stable compiler (if usable for your project)?
AVR doesn't support 64-bit floats in Rust (operations on them should end up being linker errors, though ): The fundamental issue is that AVR intrinsics (e.g. operations for i32 or f32) require a special calling convention that hasn't been yet exposed from LLVM, preventing Rust's compiler-builtins from chiming in with its own implementation. Some intrinsics (such as those for i32, u32, f32 etc.) get implemented by linking the resulting AVR binaries with (that's why working with AVR requires avr-gcc), but GCC doesn't provide implementations for f64. tl;dr f64 is not supported, but (probably) should throw a linker error instead of trying to link with compiler-builtin's implementation (because that implementation uses a different calling convention than the LLVM's codegen expects) Edit: GCC does seem to contain proper impls nowadays (, actually) - maybe LLVM gets the calling convention wrong? I'll take a look over the weekend.
Alright, got it! -- fix at: (note that merging that merge request in compiler-builtins doesn't yet solve the issue here, because then I'll need to prepare another merge request bumping compiler-builtins inside rustc - all should be ready within a few days) As for the cause - since AVRs don't have a native support for floating-point operations, those must be implemented in software; usually implementations for things like that end up in a crate called compiler-builtins (linked above), which implements them in Rust using simple bitwise operations and whatnot. There's a difference, though, between the ABI as expected by LLVM and the code that's present inside compiler-builtins - for "bigger" types (like i64, i128, f32 etc.), AVR requires a special calling convention (which defines things like "which register should contain which value") that is not yet supported by compiler-builtins (and not so easy to expose there). So instead, we pull hand-written functions ("intrinsics") from GCC's standard library (which is why avr-gcc is required as the linker) - those functions use the correct registers -- but the linking order is that stuff from compiler-builtins gets linked before GCC's, that's why those invalid intrinsics have to be commented out in compiler-builtins (so that the avr-gcc can provide its own, correct definitions). This is exactly the same case as we used to have .
Woah, thanks for the fix! Sorry for not updating this issue for a bit - my wired internet hasn't been working, so I haven't had access to my Linux machine to test this functionality. Thank you for taking the time to get it working (and explain it to me)!

wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false } [target.'cfg(target_os = "uefi")'.dependencies] <del> r-efi = { version = "4.2.0", features = ['rustc-dep-of-std']} r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std']} </del> <ins> r-efi = { version = "4.2.0", features = ['rustc-dep-of-std'] } r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] } </ins> [features] backtrace = [


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
another one

let debugger_visualizers = stat!("debugger-visualizers", || self.encode_debugger_visualizers()); <del> // Encode exported symbols info. This is prefetched in `encode_metadata` so we encode // this as late as possible to give the prefetching as much time as possible to complete. </del> <ins> // Encode exported symbols info. This is prefetched in `encode_metadata`. </ins> let exported_symbols = stat!("exported-symbols", || { self.encode_exported_symbols(tcx.exported_symbols(LOCAL_CRATE)) });


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
another one

// there's no need to do dep-graph tracking for any of it. tcx.dep_graph.assert_ignored(); <del> join( || encode_metadata_impl(tcx, path), || { if tcx.sess.threads() == 1 { return; } // Prefetch some queries used by metadata encoding. // This is not necessary for correctness, but is only done for performance reasons. // It can be removed if it turns out to cause trouble or be detrimental to performance. join(|| prefetch_mir(tcx), || tcx.exported_symbols(LOCAL_CRATE)); }, ); } </del> <ins> if tcx.sess.threads() != 1 { // Prefetch some queries used by metadata encoding. // This is not necessary for correctness, but is only done for performance reasons. // It can be removed if it turns out to cause trouble or be detrimental to performance. join(|| prefetch_mir(tcx), || tcx.exported_symbols(LOCAL_CRATE)); } </ins> <del> fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) { </del> let mut encoder = opaque::FileEncoder::new(path) .unwrap_or_else(|err| tcx.sess.emit_fatal(FailCreateFileEncoder { err })); encoder.emit_raw_bytes(METADATA_HEADER);


Question:
This code panics, but it should not: The panic disappears when the is inlined (because then we hit a different code path in ). What happens here is a bug in the logic that computes the offset of : since it is an unsized field, the offset is computed dynamically, by taking the statically known offset and then rounding it up to the dynamic alignment of the field. However, since the struct is packed, we need to cap the dynamic alignment of the field to the packing of the surrounding struct -- which we currently do not do. This is just yet another case where the non-compositional nature of is causing issues...
A slight variant of this code ICEs: It hits which, it seems, was never updated when support for was implemented.
WG-prioritization assigning priority (). label -I-prioritize +P-medium EDIT: lowered priority after discussion on Zulip

// Simple cases, which don't need DST adjustment: //   * no metadata available - just log the case //   * known alignment - sized types, `[T]`, `str` or a foreign type <del> //   * packed struct - there is no alignment padding </del> <ins> // Note that looking at `field.align` is incorrect since that is not necessarily equal // to the dynamic alignment of the type. </ins> match field.ty.kind() { _ if self.llextra.is_none() => { debug!(


Question:
This code panics, but it should not: The panic disappears when the is inlined (because then we hit a different code path in ). What happens here is a bug in the logic that computes the offset of : since it is an unsized field, the offset is computed dynamically, by taking the statically known offset and then rounding it up to the dynamic alignment of the field. However, since the struct is packed, we need to cap the dynamic alignment of the field to the packing of the surrounding struct -- which we currently do not do. This is just yet another case where the non-compositional nature of is causing issues...
A slight variant of this code ICEs: It hits which, it seems, was never updated when support for was implemented.
WG-prioritization assigning priority (). label -I-prioritize +P-medium EDIT: lowered priority after discussion on Zulip

} _ if field.is_sized() => return simple(), ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(), <del> ty::Adt(def, _) => { if def.repr().packed() { // FIXME(eddyb) generalize the adjustment when we // start supporting packing to larger alignments. assert_eq!(self.layout.align.abi.bytes(), 1); return simple(); } } </del> _ => {} }


Question:
This code panics, but it should not: The panic disappears when the is inlined (because then we hit a different code path in ). What happens here is a bug in the logic that computes the offset of : since it is an unsized field, the offset is computed dynamically, by taking the statically known offset and then rounding it up to the dynamic alignment of the field. However, since the struct is packed, we need to cap the dynamic alignment of the field to the packing of the surrounding struct -- which we currently do not do. This is just yet another case where the non-compositional nature of is causing issues...
A slight variant of this code ICEs: It hits which, it seems, was never updated when support for was implemented.
WG-prioritization assigning priority (). label -I-prioritize +P-medium EDIT: lowered priority after discussion on Zulip

let unaligned_offset = bx.cx().const_usize(offset.bytes()); // Get the alignment of the field <del> let (_, unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta); </del> <ins> let (_, mut unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta); // For packed types, we need to cap alignment. if let ty::Adt(def, _) = self.layout.ty.kind() && let Some(packed) = def.repr().pack { let packed = bx.const_usize(packed.bytes()); let cmp = bx.icmp(IntPredicate::IntULT, unsized_align, packed); unsized_align = bx.select(cmp, unsized_align, packed) } </ins> // Bump the unaligned offset up to the appropriate alignment let offset = round_up_const_value_to_alignment(bx, unaligned_offset, unsized_align);


Question:
This code panics, but it should not: The panic disappears when the is inlined (because then we hit a different code path in ). What happens here is a bug in the logic that computes the offset of : since it is an unsized field, the offset is computed dynamically, by taking the statically known offset and then rounding it up to the dynamic alignment of the field. However, since the struct is packed, we need to cap the dynamic alignment of the field to the packing of the surrounding struct -- which we currently do not do. This is just yet another case where the non-compositional nature of is causing issues...
A slight variant of this code ICEs: It hits which, it seems, was never updated when support for was implemented.
WG-prioritization assigning priority (). label -I-prioritize +P-medium EDIT: lowered priority after discussion on Zulip

// With custom DSTS, this *will* execute user-defined code, but the same // happens at run-time so that's okay. match self.size_and_align_of(&base_meta, &field_layout)? { <del> Some((_, align)) => (base_meta, offset.align_to(align)), </del> <ins> Some((_, align)) => { // For packed types, we need to cap alignment. let align = if let ty::Adt(def, _) = base.layout().ty.kind() && let Some(packed) = def.repr().pack { align.min(packed) } else { align }; (base_meta, offset.align_to(align)) } </ins> None => { // For unsized types with an extern type tail we perform no adjustments. // NOTE: keep this in sync with `PlaceRef::project_field` in the codegen backend.


Question:
This code panics, but it should not: The panic disappears when the is inlined (because then we hit a different code path in ). What happens here is a bug in the logic that computes the offset of : since it is an unsized field, the offset is computed dynamically, by taking the statically known offset and then rounding it up to the dynamic alignment of the field. However, since the struct is packed, we need to cap the dynamic alignment of the field to the packing of the surrounding struct -- which we currently do not do. This is just yet another case where the non-compositional nature of is causing issues...
A slight variant of this code ICEs: It hits which, it seems, was never updated when support for was implemented.
WG-prioritization assigning priority (). label -I-prioritize +P-medium EDIT: lowered priority after discussion on Zulip

<ins> #![feature(layout_for_ptr)] use std::mem; #[repr(packed, C)] struct PackedSized { f: u8, d: [u32; 4], } #[repr(packed, C)] struct PackedUnsized { f: u8, d: [u32], } impl PackedSized { fn unsize(&self) -> &PackedUnsized { // We can't unsize via a generic type since then we get the error // that packed structs with unsized tail don't work if the tail // might need dropping. let len = 4usize; unsafe { mem::transmute((self, len)) } } } fn main() { unsafe { let p = PackedSized { f: 0, d: [1, 2, 3, 4] }; let p = p.unsize() as *const PackedUnsized; // Make sure the size computation does *not* think there is // any padding in front of the `d` field. assert_eq!(mem::size_of_val_raw(p), 1 + 4*4); // And likewise for the offset computation. let d = std::ptr::addr_of!((*p).d); assert_eq!(d.cast::<u32>().read_unaligned(), 1); } } </ins>


Question:
This code panics, but it should not: The panic disappears when the is inlined (because then we hit a different code path in ). What happens here is a bug in the logic that computes the offset of : since it is an unsized field, the offset is computed dynamically, by taking the statically known offset and then rounding it up to the dynamic alignment of the field. However, since the struct is packed, we need to cap the dynamic alignment of the field to the packing of the surrounding struct -- which we currently do not do. This is just yet another case where the non-compositional nature of is causing issues...
A slight variant of this code ICEs: It hits which, it seems, was never updated when support for was implemented.
WG-prioritization assigning priority (). label -I-prioritize +P-medium EDIT: lowered priority after discussion on Zulip

<ins> #![feature(layout_for_ptr)] use std::mem; #[repr(packed(4))] struct Slice([u32]); #[repr(packed(2), C)] struct PackedSized { f: u8, d: [u32; 4], } #[repr(packed(2), C)] struct PackedUnsized { f: u8, d: Slice, } impl PackedSized { fn unsize(&self) -> &PackedUnsized { // We can't unsize via a generic type since then we get the error // that packed structs with unsized tail don't work if the tail // might need dropping. let len = 4usize; unsafe { mem::transmute((self, len)) } } } fn main() { unsafe { let p = PackedSized { f: 0, d: [1, 2, 3, 4] }; let p = p.unsize() as *const PackedUnsized; // Make sure the size computation correctly adds exact 1 byte of padding // in front of the `d` field. assert_eq!(mem::size_of_val_raw(p), 1 + 1 + 4*4); // And likewise for the offset computation. let d = std::ptr::addr_of!((*p).d); assert_eq!(d.cast::<u32>().read_unaligned(), 1); } } </ins>


Question:
This code panics, but it should not: The panic disappears when the is inlined (because then we hit a different code path in ). What happens here is a bug in the logic that computes the offset of : since it is an unsized field, the offset is computed dynamically, by taking the statically known offset and then rounding it up to the dynamic alignment of the field. However, since the struct is packed, we need to cap the dynamic alignment of the field to the packing of the surrounding struct -- which we currently do not do. This is just yet another case where the non-compositional nature of is causing issues...
A slight variant of this code ICEs: It hits which, it seems, was never updated when support for was implemented.
WG-prioritization assigning priority (). label -I-prioritize +P-medium EDIT: lowered priority after discussion on Zulip

<ins> // run-pass #![feature(layout_for_ptr)] use std::mem; #[repr(packed(4))] struct Slice([u32]); #[repr(packed(2), C)] struct PackedSized { f: u8, d: [u32; 4], } #[repr(packed(2), C)] struct PackedUnsized { f: u8, d: Slice, } impl PackedSized { fn unsize(&self) -> &PackedUnsized { // We can't unsize via a generic type since then we get the error // that packed structs with unsized tail don't work if the tail // might need dropping. let len = 4usize; unsafe { mem::transmute((self, len)) } } } fn main() { unsafe { let p = PackedSized { f: 0, d: [1, 2, 3, 4] }; let p = p.unsize() as *const PackedUnsized; // Make sure the size computation correctly adds exact 1 byte of padding // in front of the `d` field. assert_eq!(mem::size_of_val_raw(p), 1 + 1 + 4*4); // And likewise for the offset computation. let d = std::ptr::addr_of!((*p).d); assert_eq!(d.cast::<u32>().read_unaligned(), 1); } } </ins>


Question:
This code panics, but it should not: The panic disappears when the is inlined (because then we hit a different code path in ). What happens here is a bug in the logic that computes the offset of : since it is an unsized field, the offset is computed dynamically, by taking the statically known offset and then rounding it up to the dynamic alignment of the field. However, since the struct is packed, we need to cap the dynamic alignment of the field to the packing of the surrounding struct -- which we currently do not do. This is just yet another case where the non-compositional nature of is causing issues...
A slight variant of this code ICEs: It hits which, it seems, was never updated when support for was implemented.
WG-prioritization assigning priority (). label -I-prioritize +P-medium EDIT: lowered priority after discussion on Zulip

<ins> // run-pass #![feature(layout_for_ptr)] use std::mem; #[repr(packed, C)] struct PackedSized { f: u8, d: [u32; 4], } #[repr(packed, C)] struct PackedUnsized { f: u8, d: [u32], } impl PackedSized { fn unsize(&self) -> &PackedUnsized { // We can't unsize via a generic type since then we get the error // that packed structs with unsized tail don't work if the tail // might need dropping. let len = 4usize; unsafe { mem::transmute((self, len)) } } } fn main() { unsafe { let p = PackedSized { f: 0, d: [1, 2, 3, 4] }; let p = p.unsize() as *const PackedUnsized; // Make sure the size computation does *not* think there is // any padding in front of the `d` field. assert_eq!(mem::size_of_val_raw(p), 1 + 4*4); // And likewise for the offset computation. let d = std::ptr::addr_of!((*p).d); assert_eq!(d.cast::<u32>().read_unaligned(), 1); } } </ins>


Question:
I believe the intention in let-else is that this code should be considered syntactically invalid, but it compiles successfully today. If you replace with , it correctly fails to parse.
I believe here is the missing case for ExprKind::ConstBlock: This should be changed to an exhaustive match so that future new ExprKind variants are forced to touch this code. Some other unhandled cases that can end in : ExprKind::Become ExprKind::FormatArgs ExprKind::IncludedBytes ExprKind::InlineAsm ExprKind::MacCall ExprKind::OffsetOf ExprKind::Yeet

| Range(_, Some(e), _) | Ret(Some(e)) | Unary(_, e) <del> | Yield(Some(e)) => { </del> <ins> | Yield(Some(e)) | Yeet(Some(e)) | Become(e) => { </ins> expr = e; } Closure(closure) => { expr = &closure.body; } Gen(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..) <del> | TryBlock(..) | While(..) => break Some(expr), _ => break None, </del> <ins> | TryBlock(..) | While(..) | ConstBlock(_) => break Some(expr), // FIXME: These can end in `}`, but changing these would break stable code. InlineAsm(_) | OffsetOf(_, _) | MacCall(_) | IncludedBytes(_) | FormatArgs(_) => { break None; } Break(_, None) | Range(_, None, _) | Ret(None) | Yield(None) | Array(_) | Call(_, _) | MethodCall(_) | Tup(_) | Lit(_) | Cast(_, _) | Type(_, _) | Await(_, _) | Field(_, _) | Index(_, _, _) | Underscore | Path(_, _) | Continue(_) | Repeat(_, _) | Paren(_) | Try(_) | Yeet(None) | Err => break None, </ins> } } }


Question:
I believe the intention in let-else is that this code should be considered syntactically invalid, but it compiles successfully today. If you replace with , it correctly fails to parse.
I believe here is the missing case for ExprKind::ConstBlock: This should be changed to an exhaustive match so that future new ExprKind variants are forced to touch this code. Some other unhandled cases that can end in : ExprKind::Become ExprKind::FormatArgs ExprKind::IncludedBytes ExprKind::InlineAsm ExprKind::MacCall ExprKind::OffsetOf ExprKind::Yeet

<ins> #![feature(inline_const)] #![feature(yeet_expr)] #![allow(incomplete_features)] // Necessary for now, while explicit_tail_calls is incomplete #![feature(explicit_tail_calls)] fn a() { let foo = { 1 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn b() { let foo = for i in 1..2 { break; } else { //~^ ERROR `for...else` loops are not supported return; }; } fn c() { let foo = if true { 1 } else { 0 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn d() { let foo = loop { break; } else { //~^ ERROR loop...else` loops are not supported return; }; } fn e() { let foo = match true { true => 1, false => 0 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } struct X {a: i32} fn f() { let foo = X { a: 1 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn g() { let foo = while false { break; } else { //~^ ERROR `while...else` loops are not supported return; }; } fn h() { let foo = const { 1 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn i() { let foo = &{ 1 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn j() { let bar = 0; let foo = bar = { 1 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn k() { let foo = 1 + { 1 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn l() { let foo = 1..{ 1 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn m() { let foo = return { () } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn n() { let foo = -{ 1 } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn o() -> Result<(), ()> { let foo = do yeet { () } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return Ok(()); }; } fn p() { let foo = become { () } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn q() { let foo = |x: i32| { x } else { //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed return; }; } fn main() {} </ins>


Question:
I believe the intention in let-else is that this code should be considered syntactically invalid, but it compiles successfully today. If you replace with , it correctly fails to parse.
I believe here is the missing case for ExprKind::ConstBlock: This should be changed to an exhaustive match so that future new ExprKind variants are forced to touch this code. Some other unhandled cases that can end in : ExprKind::Become ExprKind::FormatArgs ExprKind::IncludedBytes ExprKind::InlineAsm ExprKind::MacCall ExprKind::OffsetOf ExprKind::Yeet

<ins> error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:9:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = ({ LL |         1 LL ~     }) else { | error: `for...else` loops are not supported --> $DIR/bad-let-else-statement.rs:18:7 | LL |       let foo = for i in 1..2 { |                 --- `else` is attached to this loop LL |           break; LL |       } else { |  _______^ LL | | LL | |         return; LL | |     }; | |_____^ | = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:29:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = (if true { LL |         1 LL |     } else { LL |         0 LL ~     }) else { | error: `loop...else` loops are not supported --> $DIR/bad-let-else-statement.rs:38:7 | LL |       let foo = loop { |                 ---- `else` is attached to this loop LL |           break; LL |       } else { |  _______^ LL | | LL | |         return; LL | |     }; | |_____^ | = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:48:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = (match true { LL |         true => 1, LL |         false => 0 LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:58:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = (X { LL |         a: 1 LL ~     }) else { | error: `while...else` loops are not supported --> $DIR/bad-let-else-statement.rs:67:7 | LL |       let foo = while false { |                 ----- `else` is attached to this loop LL |           break; LL |       } else { |  _______^ LL | | LL | |         return; LL | |     }; | |_____^ | = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:76:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = (const { LL |         1 LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:85:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = &({ LL |         1 LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:95:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = bar = ({ LL |         1 LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:104:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = 1 + ({ LL |         1 LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:113:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = 1..({ LL |         1 LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:122:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = return ({ LL |         () LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:131:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = -({ LL |         1 LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:140:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = do yeet ({ LL |         () LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:149:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = become ({ LL |         () LL ~     }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:158:5 | LL |     } else { |     ^ | help: wrap the expression in parentheses | LL ~     let foo = |x: i32| ({ LL |         x LL ~     }) else { | error: aborting due to 17 previous errors </ins>


Question:
and currently store pointers as , which is not ideal: They should really work with pointers and strict provenance APIs like , , etc. See a PR fixing a similar issue for some context: (note: in that one I ended up rewriting the whole thing, I think this issue requires far less changes). <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
(I do plan to work on this, but if you want to work on this instead — feel free to , I can mentor you) <subcc
claim
Could you briefly describe and , also a comprehensive insight about this issue would greatly help, although I had a look at which currently is an . If I understand correctly, we are building a for this and aim to improve existing implementations as seen in languages like C++ by making it more strict, and there is some discussion that can basically do most of what C++ can and this addition might have some diverging path. Let me know, so I can move forward!
claim
Hi strict provenance means that we aren't doing pointer-int conversions and only operate through pointer types like suggested by OP. and currently use which doesn't work under strict provenance. If you'd like I can work on this issue.
Did you mean to mentor me for the same? I would be happy to learn!
is already working on this issue, is this right? Let's not override other people working on it already unless they agree or it's been several weeks with no response.
Hi yes I am working on this issue. This is my first time contributing so it will take me sometime. I will reassign the issue to me.
claim
Hi Just checking in :) Are you still working on this issue?
Yup I am still working on this issue :)
Let us know on Zulip if you need any help
with this resolved, I think rustc is free from "fuzzy provenance casts" :)
Awesome :-)

use std::mem; use std::num::NonZeroUsize; use std::ops::{ControlFlow, Deref}; <ins> use std::ptr::NonNull; </ins> /// An entity in the Rust type system, which can be one of /// several kinds (types, lifetimes, and consts).


Question:
and currently store pointers as , which is not ideal: They should really work with pointers and strict provenance APIs like , , etc. See a PR fixing a similar issue for some context: (note: in that one I ended up rewriting the whole thing, I think this issue requires far less changes). <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
(I do plan to work on this, but if you want to work on this instead — feel free to , I can mentor you) <subcc
claim
Could you briefly describe and , also a comprehensive insight about this issue would greatly help, although I had a look at which currently is an . If I understand correctly, we are building a for this and aim to improve existing implementations as seen in languages like C++ by making it more strict, and there is some discussion that can basically do most of what C++ can and this addition might have some diverging path. Let me know, so I can move forward!
claim
Hi strict provenance means that we aren't doing pointer-int conversions and only operate through pointer types like suggested by OP. and currently use which doesn't work under strict provenance. If you'd like I can work on this issue.
Did you mean to mentor me for the same? I would be happy to learn!
is already working on this issue, is this right? Let's not override other people working on it already unless they agree or it's been several weeks with no response.
Hi yes I am working on this issue. This is my first time contributing so it will take me sometime. I will reassign the issue to me.
claim
Hi Just checking in :) Are you still working on this issue?
Yup I am still working on this issue :)
Let us know on Zulip if you need any help
with this resolved, I think rustc is free from "fuzzy provenance casts" :)
Awesome :-)

/// `Region` and `Const` are all interned. #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct GenericArg<'tcx> { <del> ptr: NonZeroUsize, </del> <ins> ptr: NonNull<()>, </ins> marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>, } <ins> #[cfg(parallel_compiler)] unsafe impl<'tcx> rustc_data_structures::sync::DynSend for GenericArg<'tcx> where &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSend { } #[cfg(parallel_compiler)] unsafe impl<'tcx> rustc_data_structures::sync::DynSync for GenericArg<'tcx> where &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSync { } unsafe impl<'tcx> Send for GenericArg<'tcx> where &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Send { } unsafe impl<'tcx> Sync for GenericArg<'tcx> where &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Sync { } </ins> impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { self.to_string().into_diagnostic_arg()


Question:
and currently store pointers as , which is not ideal: They should really work with pointers and strict provenance APIs like , , etc. See a PR fixing a similar issue for some context: (note: in that one I ended up rewriting the whole thing, I think this issue requires far less changes). <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
(I do plan to work on this, but if you want to work on this instead — feel free to , I can mentor you) <subcc
claim
Could you briefly describe and , also a comprehensive insight about this issue would greatly help, although I had a look at which currently is an . If I understand correctly, we are building a for this and aim to improve existing implementations as seen in languages like C++ by making it more strict, and there is some discussion that can basically do most of what C++ can and this addition might have some diverging path. Let me know, so I can move forward!
claim
Hi strict provenance means that we aren't doing pointer-int conversions and only operate through pointer types like suggested by OP. and currently use which doesn't work under strict provenance. If you'd like I can work on this issue.
Did you mean to mentor me for the same? I would be happy to learn!
is already working on this issue, is this right? Let's not override other people working on it already unless they agree or it's been several weeks with no response.
Hi yes I am working on this issue. This is my first time contributing so it will take me sometime. I will reassign the issue to me.
claim
Hi Just checking in :) Are you still working on this issue?
Yup I am still working on this issue :)
Let us know on Zulip if you need any help
with this resolved, I think rustc is free from "fuzzy provenance casts" :)
Awesome :-)

GenericArgKind::Lifetime(lt) => { // Ensure we can use the tag bits. assert_eq!(mem::align_of_val(&*lt.0.0) & TAG_MASK, 0); <del> (REGION_TAG, lt.0.0 as *const ty::RegionKind<'tcx> as usize) </del> <ins> (REGION_TAG, NonNull::from(lt.0.0).cast()) </ins> } GenericArgKind::Type(ty) => { // Ensure we can use the tag bits. assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0); <del> (TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyKind<'tcx>> as usize) </del> <ins> (TYPE_TAG, NonNull::from(ty.0.0).cast()) </ins> } GenericArgKind::Const(ct) => { // Ensure we can use the tag bits. assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0); <del> (CONST_TAG, ct.0.0 as *const WithCachedTypeInfo<ty::ConstData<'tcx>> as usize) </del> <ins> (CONST_TAG, NonNull::from(ct.0.0).cast()) </ins> } }; <del> GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } </del> <ins> GenericArg { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData } </ins> } }


Question:
and currently store pointers as , which is not ideal: They should really work with pointers and strict provenance APIs like , , etc. See a PR fixing a similar issue for some context: (note: in that one I ended up rewriting the whole thing, I think this issue requires far less changes). <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
(I do plan to work on this, but if you want to work on this instead — feel free to , I can mentor you) <subcc
claim
Could you briefly describe and , also a comprehensive insight about this issue would greatly help, although I had a look at which currently is an . If I understand correctly, we are building a for this and aim to improve existing implementations as seen in languages like C++ by making it more strict, and there is some discussion that can basically do most of what C++ can and this addition might have some diverging path. Let me know, so I can move forward!
claim
Hi strict provenance means that we aren't doing pointer-int conversions and only operate through pointer types like suggested by OP. and currently use which doesn't work under strict provenance. If you'd like I can work on this issue.
Did you mean to mentor me for the same? I would be happy to learn!
is already working on this issue, is this right? Let's not override other people working on it already unless they agree or it's been several weeks with no response.
Hi yes I am working on this issue. This is my first time contributing so it will take me sometime. I will reassign the issue to me.
claim
Hi Just checking in :) Are you still working on this issue?
Yup I am still working on this issue :)
Let us know on Zulip if you need any help
with this resolved, I think rustc is free from "fuzzy provenance casts" :)
Awesome :-)

impl<'tcx> GenericArg<'tcx> { #[inline] pub fn unpack(self) -> GenericArgKind<'tcx> { <del> let ptr = self.ptr.get(); </del> <ins> let ptr = unsafe { self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK)) }; </ins> // SAFETY: use of `Interned::new_unchecked` here is ok because these // pointers were originally created from `Interned` types in `pack()`, // and this is just going in the other direction. unsafe { <del> match ptr & TAG_MASK { </del> <ins> match self.ptr.addr().get() & TAG_MASK { </ins> REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked( <del> &*((ptr & !TAG_MASK) as *const ty::RegionKind<'tcx>), </del> <ins> ptr.cast::<ty::RegionKind<'tcx>>().as_ref(), </ins> ))), TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked( <del> &*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>), </del> <ins> ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(), </ins> ))), CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked( <del> &*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>), </del> <ins> ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(), </ins> ))), _ => intrinsics::unreachable(), }


Question:
and currently store pointers as , which is not ideal: They should really work with pointers and strict provenance APIs like , , etc. See a PR fixing a similar issue for some context: (note: in that one I ended up rewriting the whole thing, I think this issue requires far less changes). <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
(I do plan to work on this, but if you want to work on this instead — feel free to , I can mentor you) <subcc
claim
Could you briefly describe and , also a comprehensive insight about this issue would greatly help, although I had a look at which currently is an . If I understand correctly, we are building a for this and aim to improve existing implementations as seen in languages like C++ by making it more strict, and there is some discussion that can basically do most of what C++ can and this addition might have some diverging path. Let me know, so I can move forward!
claim
Hi strict provenance means that we aren't doing pointer-int conversions and only operate through pointer types like suggested by OP. and currently use which doesn't work under strict provenance. If you'd like I can work on this issue.
Did you mean to mentor me for the same? I would be happy to learn!
is already working on this issue, is this right? Let's not override other people working on it already unless they agree or it's been several weeks with no response.
Hi yes I am working on this issue. This is my first time contributing so it will take me sometime. I will reassign the issue to me.
claim
Hi Just checking in :) Are you still working on this issue?
Yup I am still working on this issue :)
Let us know on Zulip if you need any help
with this resolved, I think rustc is free from "fuzzy provenance casts" :)
Awesome :-)

use std::mem; use std::num::NonZeroUsize; use std::ops::ControlFlow; <ins> use std::ptr::NonNull; </ins> use std::{fmt, str}; pub use crate::ty::diagnostics::*;


Question:
and currently store pointers as , which is not ideal: They should really work with pointers and strict provenance APIs like , , etc. See a PR fixing a similar issue for some context: (note: in that one I ended up rewriting the whole thing, I think this issue requires far less changes). <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
(I do plan to work on this, but if you want to work on this instead — feel free to , I can mentor you) <subcc
claim
Could you briefly describe and , also a comprehensive insight about this issue would greatly help, although I had a look at which currently is an . If I understand correctly, we are building a for this and aim to improve existing implementations as seen in languages like C++ by making it more strict, and there is some discussion that can basically do most of what C++ can and this addition might have some diverging path. Let me know, so I can move forward!
claim
Hi strict provenance means that we aren't doing pointer-int conversions and only operate through pointer types like suggested by OP. and currently use which doesn't work under strict provenance. If you'd like I can work on this issue.
Did you mean to mentor me for the same? I would be happy to learn!
is already working on this issue, is this right? Let's not override other people working on it already unless they agree or it's been several weeks with no response.
Hi yes I am working on this issue. This is my first time contributing so it will take me sometime. I will reassign the issue to me.
claim
Hi Just checking in :) Are you still working on this issue?
Yup I am still working on this issue :)
Let us know on Zulip if you need any help
with this resolved, I think rustc is free from "fuzzy provenance casts" :)
Awesome :-)

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Term<'tcx> { <del> ptr: NonZeroUsize, </del> <ins> ptr: NonNull<()>, </ins> marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>, } <ins> #[cfg(parallel_compiler)] unsafe impl<'tcx> rustc_data_structures::sync::DynSend for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSend { } #[cfg(parallel_compiler)] unsafe impl<'tcx> rustc_data_structures::sync::DynSync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSync { } unsafe impl<'tcx> Send for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Send {} unsafe impl<'tcx> Sync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Sync {} </ins> impl Debug for Term<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let data = if let Some(ty) = self.ty() {


Question:
and currently store pointers as , which is not ideal: They should really work with pointers and strict provenance APIs like , , etc. See a PR fixing a similar issue for some context: (note: in that one I ended up rewriting the whole thing, I think this issue requires far less changes). <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
(I do plan to work on this, but if you want to work on this instead — feel free to , I can mentor you) <subcc
claim
Could you briefly describe and , also a comprehensive insight about this issue would greatly help, although I had a look at which currently is an . If I understand correctly, we are building a for this and aim to improve existing implementations as seen in languages like C++ by making it more strict, and there is some discussion that can basically do most of what C++ can and this addition might have some diverging path. Let me know, so I can move forward!
claim
Hi strict provenance means that we aren't doing pointer-int conversions and only operate through pointer types like suggested by OP. and currently use which doesn't work under strict provenance. If you'd like I can work on this issue.
Did you mean to mentor me for the same? I would be happy to learn!
is already working on this issue, is this right? Let's not override other people working on it already unless they agree or it's been several weeks with no response.
Hi yes I am working on this issue. This is my first time contributing so it will take me sometime. I will reassign the issue to me.
claim
Hi Just checking in :) Are you still working on this issue?
Yup I am still working on this issue :)
Let us know on Zulip if you need any help
with this resolved, I think rustc is free from "fuzzy provenance casts" :)
Awesome :-)

impl<'tcx> Term<'tcx> { #[inline] pub fn unpack(self) -> TermKind<'tcx> { <del> let ptr = self.ptr.get(); </del> <ins> let ptr = unsafe { self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK)) }; </ins> // SAFETY: use of `Interned::new_unchecked` here is ok because these // pointers were originally created from `Interned` types in `pack()`, // and this is just going in the other direction. unsafe { <del> match ptr & TAG_MASK { </del> <ins> match self.ptr.addr().get() & TAG_MASK { </ins> TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked( <del> &*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>), </del> <ins> ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(), </ins> ))), CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked( <del> &*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>), </del> <ins> ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(), </ins> ))), _ => core::intrinsics::unreachable(), }


Question:
and currently store pointers as , which is not ideal: They should really work with pointers and strict provenance APIs like , , etc. See a PR fixing a similar issue for some context: (note: in that one I ended up rewriting the whole thing, I think this issue requires far less changes). <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
(I do plan to work on this, but if you want to work on this instead — feel free to , I can mentor you) <subcc
claim
Could you briefly describe and , also a comprehensive insight about this issue would greatly help, although I had a look at which currently is an . If I understand correctly, we are building a for this and aim to improve existing implementations as seen in languages like C++ by making it more strict, and there is some discussion that can basically do most of what C++ can and this addition might have some diverging path. Let me know, so I can move forward!
claim
Hi strict provenance means that we aren't doing pointer-int conversions and only operate through pointer types like suggested by OP. and currently use which doesn't work under strict provenance. If you'd like I can work on this issue.
Did you mean to mentor me for the same? I would be happy to learn!
is already working on this issue, is this right? Let's not override other people working on it already unless they agree or it's been several weeks with no response.
Hi yes I am working on this issue. This is my first time contributing so it will take me sometime. I will reassign the issue to me.
claim
Hi Just checking in :) Are you still working on this issue?
Yup I am still working on this issue :)
Let us know on Zulip if you need any help
with this resolved, I think rustc is free from "fuzzy provenance casts" :)
Awesome :-)

TermKind::Ty(ty) => { // Ensure we can use the tag bits. assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0); <del> (TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyKind<'tcx>> as usize) </del> <ins> (TYPE_TAG, NonNull::from(ty.0.0).cast()) </ins> } TermKind::Const(ct) => { // Ensure we can use the tag bits. assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0); <del> (CONST_TAG, ct.0.0 as *const WithCachedTypeInfo<ty::ConstData<'tcx>> as usize) </del> <ins> (CONST_TAG, NonNull::from(ct.0.0).cast()) </ins> } }; <del> Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } </del> <ins> Term { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData } </ins> } }


Question:
The inliner strategy for dealing with storage statements is simple. If a callee local already has some storage statements, they are preserved as is when integrating callee into the caller. There are no new storage statements for such locals. Turns out this approach is unsound due to peculiar semantics of MIR. It is well defined to return from a function while there are still some live locals. At the same time it is undefined behaviour to execute StorageLive for already live local. Effectively inliner is obliged to end the storage for locals that are still live when callee returns, which it doesn't do at the moment. Arguably this is more of a bug in MIR semantics, then one in the inliner
hey would you like to first T-opsem discuss this? Maybe have this topic on a meeting and figure out a plan to fix this?
Oh, interesting catch. Cc Maybe we should just allow StorageLive on an already live local (and declare it to first implicitly free the local, and then make it live again)...

dividing by zero const_eval_division_overflow = overflow in signed division (dividing MIN by -1) <del> const_eval_double_storage_live = StorageLive on a local that was already live </del> const_eval_dyn_call_not_a_method = `dyn` call trying to call something that is not a method


Question:
The inliner strategy for dealing with storage statements is simple. If a callee local already has some storage statements, they are preserved as is when integrating callee into the caller. There are no new storage statements for such locals. Turns out this approach is unsound due to peculiar semantics of MIR. It is well defined to return from a function while there are still some live locals. At the same time it is undefined behaviour to execute StorageLive for already live local. Effectively inliner is obliged to end the storage for locals that are still live when callee returns, which it doesn't do at the moment. Arguably this is more of a bug in MIR semantics, then one in the inliner
hey would you like to first T-opsem discuss this? Maybe have this topic on a meeting and figure out a plan to fix this?
Oh, interesting catch. Cc Maybe we should just allow StorageLive on an already live local (and declare it to first implicitly free the local, and then make it live again)...

Operand::Immediate(Immediate::Uninit) }); <del> // StorageLive expects the local to be dead, and marks it live. </del> <ins> // If the local is already live, deallocate its old memory. </ins> let old = mem::replace(&mut self.frame_mut().locals[local].value, local_val); <del> if !matches!(old, LocalValue::Dead) { throw_ub_custom!(fluent::const_eval_double_storage_live); } </del> <ins> self.deallocate_local(old)?; </ins> Ok(()) }


Question:
The inliner strategy for dealing with storage statements is simple. If a callee local already has some storage statements, they are preserved as is when integrating callee into the caller. There are no new storage statements for such locals. Turns out this approach is unsound due to peculiar semantics of MIR. It is well defined to return from a function while there are still some live locals. At the same time it is undefined behaviour to execute StorageLive for already live local. Effectively inliner is obliged to end the storage for locals that are still live when callee returns, which it doesn't do at the moment. Arguably this is more of a bug in MIR semantics, then one in the inliner
hey would you like to first T-opsem discuss this? Maybe have this topic on a meeting and figure out a plan to fix this?
Oh, interesting catch. Cc Maybe we should just allow StorageLive on an already live local (and declare it to first implicitly free the local, and then make it live again)...

assert!(local != mir::RETURN_PLACE, "Cannot make return place dead"); trace!("{:?} is now dead", local); <del> // It is entirely okay for this local to be already dead (at least that's how we currently generate MIR) </del> <ins> // If the local is already dead, this is a NOP. </ins> let old = mem::replace(&mut self.frame_mut().locals[local].value, LocalValue::Dead); self.deallocate_local(old)?; Ok(())


Question:
The inliner strategy for dealing with storage statements is simple. If a callee local already has some storage statements, they are preserved as is when integrating callee into the caller. There are no new storage statements for such locals. Turns out this approach is unsound due to peculiar semantics of MIR. It is well defined to return from a function while there are still some live locals. At the same time it is undefined behaviour to execute StorageLive for already live local. Effectively inliner is obliged to end the storage for locals that are still live when callee returns, which it doesn't do at the moment. Arguably this is more of a bug in MIR semantics, then one in the inliner
hey would you like to first T-opsem discuss this? Maybe have this topic on a meeting and figure out a plan to fix this?
Oh, interesting catch. Cc Maybe we should just allow StorageLive on an already live local (and declare it to first implicitly free the local, and then make it live again)...

/// At any point during the execution of a function, each local is either allocated or /// unallocated. Except as noted below, all locals except function parameters are initially /// unallocated. `StorageLive` statements cause memory to be allocated for the local while <del> /// `StorageDead` statements cause the memory to be freed. Using a local in any way (not only /// reading/writing from it) while it is unallocated is UB. </del> <ins> /// `StorageDead` statements cause the memory to be freed. In other words, /// `StorageLive`/`StorageDead` act like the heap operations `allocate`/`deallocate`, but for /// stack-allocated local variables. Using a local in any way (not only reading/writing from it) /// while it is unallocated is UB. </ins> /// /// Some locals have no `StorageLive` or `StorageDead` statements within the entire MIR body. /// These locals are implicitly allocated for the full duration of the function. There is a /// convenience method at `rustc_mir_dataflow::storage::always_storage_live_locals` for /// computing these locals. /// <del> /// If the local is already allocated, calling `StorageLive` again is UB. However, for an /// unallocated local an additional `StorageDead` all is simply a nop. </del> <ins> /// If the local is already allocated, calling `StorageLive` again will implicitly free the /// local and then allocate fresh uninitilized memory. If a local is already deallocated, /// calling `StorageDead` again is a NOP. </ins> StorageLive(Local), /// See `StorageLive` above.


Question:
The inliner strategy for dealing with storage statements is simple. If a callee local already has some storage statements, they are preserved as is when integrating callee into the caller. There are no new storage statements for such locals. Turns out this approach is unsound due to peculiar semantics of MIR. It is well defined to return from a function while there are still some live locals. At the same time it is undefined behaviour to execute StorageLive for already live local. Effectively inliner is obliged to end the storage for locals that are still live when callee returns, which it doesn't do at the moment. Arguably this is more of a bug in MIR semantics, then one in the inliner
hey would you like to first T-opsem discuss this? Maybe have this topic on a meeting and figure out a plan to fix this?
Oh, interesting catch. Cc Maybe we should just allow StorageLive on an already live local (and declare it to first implicitly free the local, and then make it live again)...

<ins> #![feature(core_intrinsics, custom_mir)] use std::intrinsics::mir::*; #[custom_mir(dialect = "runtime")] fn main() { mir! { let val: i32; { val = 42; //~ERROR: accessing a dead local variable StorageLive(val); // too late... (but needs to be here to make `val` not implicitly live) Return() } } } </ins>


Question:
The inliner strategy for dealing with storage statements is simple. If a callee local already has some storage statements, they are preserved as is when integrating callee into the caller. There are no new storage statements for such locals. Turns out this approach is unsound due to peculiar semantics of MIR. It is well defined to return from a function while there are still some live locals. At the same time it is undefined behaviour to execute StorageLive for already live local. Effectively inliner is obliged to end the storage for locals that are still live when callee returns, which it doesn't do at the moment. Arguably this is more of a bug in MIR semantics, then one in the inliner
hey would you like to first T-opsem discuss this? Maybe have this topic on a meeting and figure out a plan to fix this?
Oh, interesting catch. Cc Maybe we should just allow StorageLive on an already live local (and declare it to first implicitly free the local, and then make it live again)...

<ins> error: Undefined Behavior: accessing a dead local variable --> $DIR/storage-live-dead-var.rs:LL:CC | LL |             val = 42; |             ^^^^^^^^ accessing a dead local variable | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `main` at $DIR/storage-live-dead-var.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to 1 previous error </ins>


Question:
The inliner strategy for dealing with storage statements is simple. If a callee local already has some storage statements, they are preserved as is when integrating callee into the caller. There are no new storage statements for such locals. Turns out this approach is unsound due to peculiar semantics of MIR. It is well defined to return from a function while there are still some live locals. At the same time it is undefined behaviour to execute StorageLive for already live local. Effectively inliner is obliged to end the storage for locals that are still live when callee returns, which it doesn't do at the moment. Arguably this is more of a bug in MIR semantics, then one in the inliner
hey would you like to first T-opsem discuss this? Maybe have this topic on a meeting and figure out a plan to fix this?
Oh, interesting catch. Cc Maybe we should just allow StorageLive on an already live local (and declare it to first implicitly free the local, and then make it live again)...

<ins> #![feature(core_intrinsics, custom_mir)] use std::intrinsics::mir::*; #[custom_mir(dialect = "runtime")] fn main() { mir! { let val: i32; let _val2: i32; { StorageLive(val); val = 42; StorageLive(val); // reset val to `uninit` _val2 = val; //~ERROR: uninitialized Return() } } } </ins>


Question:
The inliner strategy for dealing with storage statements is simple. If a callee local already has some storage statements, they are preserved as is when integrating callee into the caller. There are no new storage statements for such locals. Turns out this approach is unsound due to peculiar semantics of MIR. It is well defined to return from a function while there are still some live locals. At the same time it is undefined behaviour to execute StorageLive for already live local. Effectively inliner is obliged to end the storage for locals that are still live when callee returns, which it doesn't do at the moment. Arguably this is more of a bug in MIR semantics, then one in the inliner
hey would you like to first T-opsem discuss this? Maybe have this topic on a meeting and figure out a plan to fix this?
Oh, interesting catch. Cc Maybe we should just allow StorageLive on an already live local (and declare it to first implicitly free the local, and then make it live again)...

<ins> error: Undefined Behavior: constructing invalid value: encountered uninitialized memory, but expected an integer --> $DIR/storage-live-resets-var.rs:LL:CC | LL |             _val2 = val; |             ^^^^^^^^^^^ constructing invalid value: encountered uninitialized memory, but expected an integer | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `main` at $DIR/storage-live-resets-var.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to 1 previous error </ins>


Question:
For this snippet (): rustc gives: Since , for const-able values, rustc suggests the creation of a constant binding. Here this is not possible because is not const fn. However, we can suggest instead.
Personally, I prefer over a separate binding. Even in the case, the generated code will call the initialization function many times. Maybe in the case where bindings are possible, we can suggest both? Where they are not possible, we don't suggest anything right now, so at the least we should suggest there. what do you think?
Once is stable we can suggest that :3. But until then sounds reasonable.
Agreed, good point about . It seems to have a stabilization PR open with an FCP, which is blocked: . Maybe there might be progress on it this month: . Even if we stabilize inline const, it might make sense to wait with suggesting it for a while so that we don't make code depend on the latest MSRV immediately. So therefore, I think that it might still make sense to implement this in the meantime.
I think this should (in the future) suggest  instead, since the function would only be called once if were , whereas calls it for every element.

], Applicability::MachineApplicable, ); <ins> } else { // FIXME: we may suggest array::repeat instead err.help("consider using `core::array::from_fn` to initialize the array"); err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information"); </ins> } if self.tcx.sess.is_nightly_build()


Question:
For this snippet (): rustc gives: Since , for const-able values, rustc suggests the creation of a constant binding. Here this is not possible because is not const fn. However, we can suggest instead.
Personally, I prefer over a separate binding. Even in the case, the generated code will call the initialization function many times. Maybe in the case where bindings are possible, we can suggest both? Where they are not possible, we don't suggest anything right now, so at the least we should suggest there. what do you think?
Once is stable we can suggest that :3. But until then sounds reasonable.
Agreed, good point about . It seems to have a stabilization PR open with an FCP, which is blocked: . Maybe there might be progress on it this month: . Even if we stabilize inline const, it might make sense to wait with suggesting it for a while so that we don't make code depend on the latest MSRV immediately. So therefore, I think that it might still make sense to implement this in the meantime.
I think this should (in the future) suggest  instead, since the function would only be called once if were , whereas calls it for every element.

|                    ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>` | = note: the `Copy` trait is required because this value will be copied for each element of the array <ins> = help: consider using `core::array::from_fn` to initialize the array = help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information </ins> help: consider annotating `Header<'_>` with `#[derive(Copy)]` | LL + #[derive(Copy)]


Question:
For this snippet (): rustc gives: Since , for const-able values, rustc suggests the creation of a constant binding. Here this is not possible because is not const fn. However, we can suggest instead.
Personally, I prefer over a separate binding. Even in the case, the generated code will call the initialization function many times. Maybe in the case where bindings are possible, we can suggest both? Where they are not possible, we don't suggest anything right now, so at the least we should suggest there. what do you think?
Once is stable we can suggest that :3. But until then sounds reasonable.
Agreed, good point about . It seems to have a stabilization PR open with an FCP, which is blocked: . Maybe there might be progress on it this month: . Even if we stabilize inline const, it might make sense to wait with suggesting it for a while so that we don't make code depend on the latest MSRV immediately. So therefore, I think that it might still make sense to implement this in the meantime.
I think this should (in the future) suggest  instead, since the function would only be called once if were , whereas calls it for every element.

|                    ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>` | = note: the `Copy` trait is required because this value will be copied for each element of the array <ins> = help: consider using `core::array::from_fn` to initialize the array = help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information </ins> help: consider annotating `Header<'_>` with `#[derive(Copy)]` | LL + #[derive(Copy)]


Question:
For this snippet (): rustc gives: Since , for const-able values, rustc suggests the creation of a constant binding. Here this is not possible because is not const fn. However, we can suggest instead.
Personally, I prefer over a separate binding. Even in the case, the generated code will call the initialization function many times. Maybe in the case where bindings are possible, we can suggest both? Where they are not possible, we don't suggest anything right now, so at the least we should suggest there. what do you think?
Once is stable we can suggest that :3. But until then sounds reasonable.
Agreed, good point about . It seems to have a stabilization PR open with an FCP, which is blocked: . Maybe there might be progress on it this month: . Even if we stabilize inline const, it might make sense to wait with suggesting it for a while so that we don't make code depend on the latest MSRV immediately. So therefore, I think that it might still make sense to implement this in the meantime.
I think this should (in the future) suggest  instead, since the function would only be called once if were , whereas calls it for every element.

|      ^ the trait `Copy` is not implemented for `T` | = note: the `Copy` trait is required because this value will be copied for each element of the array <ins> = help: consider using `core::array::from_fn` to initialize the array = help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information </ins> help: consider restricting type parameter `T` | LL | fn g<T: std::marker::Copy, const N: usize>(x: T) -> [T; N] {


Question:
For this snippet (): rustc gives: Since , for const-able values, rustc suggests the creation of a constant binding. Here this is not possible because is not const fn. However, we can suggest instead.
Personally, I prefer over a separate binding. Even in the case, the generated code will call the initialization function many times. Maybe in the case where bindings are possible, we can suggest both? Where they are not possible, we don't suggest anything right now, so at the least we should suggest there. what do you think?
Once is stable we can suggest that :3. But until then sounds reasonable.
Agreed, good point about . It seems to have a stabilization PR open with an FCP, which is blocked: . Maybe there might be progress on it this month: . Even if we stabilize inline const, it might make sense to wait with suggesting it for a while so that we don't make code depend on the latest MSRV immediately. So therefore, I think that it might still make sense to implement this in the meantime.
I think this should (in the future) suggest  instead, since the function would only be called once if were , whereas calls it for every element.

| = note: required for `Option<Bar>` to implement `Copy` = note: the `Copy` trait is required because this value will be copied for each element of the array <ins> = help: consider using `core::array::from_fn` to initialize the array = help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information </ins> help: consider annotating `Bar` with `#[derive(Copy)]` | LL + #[derive(Copy)]


Question:
For this snippet (): rustc gives: Since , for const-able values, rustc suggests the creation of a constant binding. Here this is not possible because is not const fn. However, we can suggest instead.
Personally, I prefer over a separate binding. Even in the case, the generated code will call the initialization function many times. Maybe in the case where bindings are possible, we can suggest both? Where they are not possible, we don't suggest anything right now, so at the least we should suggest there. what do you think?
Once is stable we can suggest that :3. But until then sounds reasonable.
Agreed, good point about . It seems to have a stabilization PR open with an FCP, which is blocked: . Maybe there might be progress on it this month: . Even if we stabilize inline const, it might make sense to wait with suggesting it for a while so that we don't make code depend on the latest MSRV immediately. So therefore, I think that it might still make sense to implement this in the meantime.
I think this should (in the future) suggest  instead, since the function would only be called once if were , whereas calls it for every element.

|               ^ the trait `Copy` is not implemented for `Foo` | = note: the `Copy` trait is required because this value will be copied for each element of the array <ins> = help: consider using `core::array::from_fn` to initialize the array = help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information </ins> help: consider annotating `Foo` with `#[derive(Copy)]` | LL + #[derive(Copy)]


Question:
For this snippet (): rustc gives: Since , for const-able values, rustc suggests the creation of a constant binding. Here this is not possible because is not const fn. However, we can suggest instead.
Personally, I prefer over a separate binding. Even in the case, the generated code will call the initialization function many times. Maybe in the case where bindings are possible, we can suggest both? Where they are not possible, we don't suggest anything right now, so at the least we should suggest there. what do you think?
Once is stable we can suggest that :3. But until then sounds reasonable.
Agreed, good point about . It seems to have a stabilization PR open with an FCP, which is blocked: . Maybe there might be progress on it this month: . Even if we stabilize inline const, it might make sense to wait with suggesting it for a while so that we don't make code depend on the latest MSRV immediately. So therefore, I think that it might still make sense to implement this in the meantime.
I think this should (in the future) suggest  instead, since the function would only be called once if were , whereas calls it for every element.

<ins> fn foo() -> String { String::new() } fn main() { let string_arr = [foo(); 64]; //~ ERROR the trait bound `String: Copy` is not satisfied } </ins>


Question:
For this snippet (): rustc gives: Since , for const-able values, rustc suggests the creation of a constant binding. Here this is not possible because is not const fn. However, we can suggest instead.
Personally, I prefer over a separate binding. Even in the case, the generated code will call the initialization function many times. Maybe in the case where bindings are possible, we can suggest both? Where they are not possible, we don't suggest anything right now, so at the least we should suggest there. what do you think?
Once is stable we can suggest that :3. But until then sounds reasonable.
Agreed, good point about . It seems to have a stabilization PR open with an FCP, which is blocked: . Maybe there might be progress on it this month: . Even if we stabilize inline const, it might make sense to wait with suggesting it for a while so that we don't make code depend on the latest MSRV immediately. So therefore, I think that it might still make sense to implement this in the meantime.
I think this should (in the future) suggest  instead, since the function would only be called once if were , whereas calls it for every element.

<ins> error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/issue-119530-sugg-from-fn.rs:4:23 | LL |     let string_arr = [foo(); 64]; |                       ^^^^^ the trait `Copy` is not implemented for `String` | = note: the `Copy` trait is required because this value will be copied for each element of the array = help: consider using `core::array::from_fn` to initialize the array = help: see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. </ins>


Question:
The compiler struggles to optimize the for position on Iterators. Simplifying the implementation has increased the efficiency in various scenarios OMM: Old position(): #[inline] fn check<T( mut predicate: impl FnMut(T) -bool, ) -impl FnMut(usize, T) -ControlFlow<usize, usize{ #[rustcinheritoverflowchecks] move { if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i + 1) } } } self.tryfold(0, check(predicate)).breakvalue() Simplified version (There are several alternative implementations producing similar results as well): let mut position = 0; while let Some(x) = () { if predicate(x) { return Some(position); } position += 1; } None Bench results: <details </summary<br</detailsBenchmarks are named after the iterator and were run using . Ranges benefit massively (big ones by multiple orders of magnitude), while for other types, speedups are usually between 0% and 100%. A specific implementation for range calculating the position would of course be even faster, but I don't think position() is called that often on ranges. The implementation is similar to the one, which was introduced to reduce compile times , so perhaps this would help in that regard as well. However, the compiler appears to occasionally forget how to optimize the function after editing unrelated code. This also happens with the current implementation, so I don't know how reproducible the speedups are (FWIW Ranges have never failed to improve, though). I did not attempt to benchmark compilation speed, but according to the memory usage is down from 11.8 MB to 8.3 MB which looks promising. I was motivated by a on reddit, where some context and speculation can be found.
The -based implementation is likely intended to speed up position-finding in or iterators. So measuring range or slice iters doesn't exercise it well. That said, they should be equally fast for slices. Going through should end up with a very similar white-let loop. The call-tree is deeper, so this might affect optimizations. Have you tried compiling with 1CGU or LTO to see if that makes a difference? Benchmarks are fickle.
The godbolt example does show that try_fold version results in a few more instructions. looks like it's trying to do some branchless version of the accumulator increments here: while is an unconditional increment sitting in its own block. Maybe ControlFlow is not well-suited for carrying the value and the loop state at the same time? CC
I did some quick measurements for a chain of vecs: So the current impl does indeed work better for chains Yes, the difference is the ControlFlow abstraction Yes: No real differences though, results were with these settings. This made me retest an alternative I used previously (reducing ControlFlow size from <usize, usizeto <usize, ()): And this one actually beats the current one for the chain test: The chain_alt is even faster, but it's an attempt to keep the current style, updated for keeping the counter outside the fold: It isn't pretty, but it works The Assembly and IR are too long for me too really identify where the benefit comes from, curiously the faster version has more instructions, but I guess with all the jumps everywhere that doesn't mean a lot. I am interested in testing these more thoroughly, is there a nice resource with some real world data to test them on? Edit: Went digging in recent projects and I had a solution for Advent of Code Day 6 using .rposition() and .position() with the relevant part being: And changing to the alt version (with check(predicate, acc)) improved runtime from 8.8 ms to 6.2 ms, a 40% speedup! (I know there is an algebraic solution to the problem, but still)
You could make a PR and we can do a perf run. It doesn't have dedicated benchmarks that stress and I haven't checked if any of the runtime benchmarks make use of at all, but the compiler also makes use of it internally so it might show up in builds too.
Yes, we learned in that if you don't need move access to the accumulator -- either because is fine, as in that thread, or seemingly because you can , as seen here -- then it's better to use with a closure instead of needing LLVM to understand the threading through the +. (Maybe this'll be better once LLVM does better with 2-variant enums and stops losing information about them, but for now we're stuck with this.)

P: FnMut(Self::Item) -> bool, { #[inline] <del> fn check<T>( mut predicate: impl FnMut(T) -> bool, ) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> { </del> <ins> fn check<'a, T>( mut predicate: impl FnMut(T) -> bool + 'a, acc: &'a mut usize, ) -> impl FnMut((), T) -> ControlFlow<usize, ()> + 'a { </ins> #[rustc_inherit_overflow_checks] <del> move |i, x| { if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i + 1) } </del> <ins> move |_, x| { if predicate(x) { ControlFlow::Break(*acc) } else { *acc += 1; ControlFlow::Continue(()) } </ins> } } <del> self.try_fold(0, check(predicate)).break_value() </del> <ins> let mut acc = 0; self.try_fold((), check(predicate, &mut acc)).break_value() </ins> } /// Searches for an element in an iterator from the right, returning its


Question: run Output: Miri: The underlying issue was found when reviewing the implementation of . The code is a reproduction to trigger the unsoundness. The implementation in question features: Where is turned into and dropped. Yes, that’s , not . The code for seems to be doing the same thing. For comparison: The code for (and the same thing for ) seems to properly use a … no actually, that’s a with zero lengths… notably the allocator is correct though. So the buggy code for should just switch to create a presumably. label I-unsound requires-nightly T-libs

// Free the allocation without dropping its contents let (bptr, alloc) = Box::into_raw_with_allocator(src); <del> let src = Box::from_raw(bptr as *mut mem::ManuallyDrop<T>); </del> <ins> let src = Box::from_raw_in(bptr as *mut mem::ManuallyDrop<T>, alloc.by_ref()); </ins> drop(src); Self::from_ptr_in(ptr, alloc)


Question: creates an error string dynamically, then passes it as an unsafe pointer to , which then casts the string to , then to , then throws it to another task. Nominating.

//! Runtime calls emitted by the compiler. <del> use c_str::ToCStr; </del> <ins> use c_str::CString; use libc::c_char; use cast; use option::Some; </ins> #[cold] #[lang="fail_"]


Question: creates an error string dynamically, then passes it as an unsafe pointer to , which then casts the string to , then to , then throws it to another task. Nominating.

pub fn fail_bounds_check(file: *u8, line: uint, index: uint, len: uint) -> ! { let msg = format!("index out of bounds: the len is {} but the index is {}", len as uint, index as uint); <del> msg.with_c_str(|buf| fail_(buf as *u8, file, line)) </del> <ins> let file_str = match unsafe { CString::new(file as *c_char, false) }.as_str() { // This transmute is safe because `file` is always stored in rodata. Some(s) => unsafe { cast::transmute::<&str, &'static str>(s) }, None    => "file wasn't UTF-8 safe" }; ::rt::begin_unwind(msg, file_str, line) </ins> } #[lang="malloc"]


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: is not fully resolved', 'error: internal compiler error: is not fully resolved' File: --Another regression of snippet: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [checkmodimpl_wf] checking that impls are well-formed in top-level module [analysis] running analysis passes on this crate --
This is caused by the fact that  does not check for const effect vars when visiting . It should be relatively simple to match on in the folder.
Working on this one.

UnresolvedFloatTy(FloatVid), UnresolvedTy(TyVid), UnresolvedConst(ConstVid), <ins> UnresolvedEffect(EffectVid), </ins> } /// See the `region_obligations` field for more information.


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: is not fully resolved', 'error: internal compiler error: is not fully resolved' File: --Another regression of snippet: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [checkmodimpl_wf] checking that impls are well-formed in top-level module [analysis] running analysis passes on this crate --
This is caused by the fact that  does not check for const effect vars when visiting . It should be relatively simple to match on in the folder.
Working on this one.

), UnresolvedTy(_) => write!(f, "unconstrained type"), UnresolvedConst(_) => write!(f, "unconstrained const value"), <ins> UnresolvedEffect(_) => write!(f, "unconstrained effect value"), </ins> } } }


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: is not fully resolved', 'error: internal compiler error: is not fully resolved' File: --Another regression of snippet: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [checkmodimpl_wf] checking that impls are well-formed in top-level module [analysis] running analysis passes on this crate --
This is caused by the fact that  does not check for const effect vars when visiting . It should be relatively simple to match on in the folder.
Working on this one.

ty::ConstKind::Infer(InferConst::Fresh(_)) => { bug!("Unexpected const in full const resolver: {:?}", c); } <ins> ty::ConstKind::Infer(InferConst::EffectVar(evid)) => { return Err(FixupError::UnresolvedEffect(evid)); } </ins> _ => {} } c.try_super_fold_with(self)


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: is not fully resolved', 'error: internal compiler error: is not fully resolved' File: --Another regression of snippet: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [checkmodimpl_wf] checking that impls are well-formed in top-level module [analysis] running analysis passes on this crate --
This is caused by the fact that  does not check for const effect vars when visiting . It should be relatively simple to match on in the folder.
Working on this one.

<del> //@ known-bug: #119830 #![feature(effects)] #![feature(min_specialization)] trait Specialize {} trait Foo {} impl<T> const Foo for T {} impl<T> const Foo for T where T: const Specialize {} </del>


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: is not fully resolved', 'error: internal compiler error: is not fully resolved' File: --Another regression of snippet: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [checkmodimpl_wf] checking that impls are well-formed in top-level module [analysis] running analysis passes on this crate --
This is caused by the fact that  does not check for const effect vars when visiting . It should be relatively simple to match on in the folder.
Working on this one.

<ins> //@ check-fail // Fixes #119830 #![feature(effects)] #![feature(min_specialization)] #![feature(const_trait_impl)] trait Specialize {} trait Foo {} impl<T> const Foo for T {} //~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` //~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] impl<T> const Foo for T where T: const Specialize {} //~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` //~| error: `const` can only be applied to `#[const_trait]` traits //~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] //~| error: specialization impl does not specialize any associated items //~| error: could not resolve generic parameters on overridden impl fn main() { } </ins>


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: is not fully resolved', 'error: internal compiler error: is not fully resolved' File: --Another regression of snippet: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [checkmodimpl_wf] checking that impls are well-formed in top-level module [analysis] running analysis passes on this crate --
This is caused by the fact that  does not check for const effect vars when visiting . It should be relatively simple to match on in the folder.
Working on this one.

<ins> error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` --> $DIR/spec-effectvar-ice.rs:12:15 | LL | trait Foo {} | - help: mark `Foo` as const: `#[const_trait]` LL | LL | impl<T> const Foo for T {} |               ^^^ | = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` --> $DIR/spec-effectvar-ice.rs:16:15 | LL | trait Foo {} | - help: mark `Foo` as const: `#[const_trait]` ... LL | impl<T> const Foo for T where T: const Specialize {} |               ^^^ | = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error: `const` can only be applied to `#[const_trait]` traits --> $DIR/spec-effectvar-ice.rs:16:40 | LL | impl<T> const Foo for T where T: const Specialize {} |                                        ^^^^^^^^^^ error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates --> $DIR/spec-effectvar-ice.rs:12:9 | LL | impl<T> const Foo for T {} |         ^^^^^ unconstrained const parameter | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates --> $DIR/spec-effectvar-ice.rs:16:9 | LL | impl<T> const Foo for T where T: const Specialize {} |         ^^^^^ unconstrained const parameter | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported error: specialization impl does not specialize any associated items --> $DIR/spec-effectvar-ice.rs:16:1 | LL | impl<T> const Foo for T where T: const Specialize {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: impl is a specialization of this impl --> $DIR/spec-effectvar-ice.rs:12:1 | LL | impl<T> const Foo for T {} | ^^^^^^^^^^^^^^^^^^^^^^^ error: could not resolve generic parameters on overridden impl --> $DIR/spec-effectvar-ice.rs:16:1 | LL | impl<T> const Foo for T where T: const Specialize {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0207`. </ins>


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: cannot get associated-item of ', 'error: internal compiler error: cannot get associated-item of ' File: --another one caused by auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [associated_item] computing associated item data for [typeck] type-checking [analysis] running analysis passes on this crate --
fyi
not caused by that, only exposed by it. The issue is a typo using instead of in diagnostic code, getting the wrong and then attempting to treat as an associated item

.extend( // Group the return ty with its def id, if we had one. entry.return_ty.map(|ty| { <del> (tcx.require_lang_item(LangItem::FnOnce, None), ty) </del> <ins> (tcx.require_lang_item(LangItem::FnOnceOutput, None), ty) </ins> }), ); }


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: cannot get associated-item of ', 'error: internal compiler error: cannot get associated-item of ' File: --another one caused by auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [associated_item] computing associated item data for [typeck] type-checking [analysis] running analysis passes on this crate --
fyi
not caused by that, only exposed by it. The issue is a typo using instead of in diagnostic code, getting the wrong and then attempting to treat as an associated item

<ins> //! This is a regression test to avoid an ICE in diagnostics code. //! A typo in the compiler used to get the DefId of FnOnce, and //! use it where an associated item was expected. fn frob() -> impl Fn<P, Output = T> + '_ {} //~^ ERROR missing lifetime specifier //~| ERROR cannot find type `P` //~| ERROR cannot find type `T` //~| ERROR `Fn`-family traits' type parameters is subject to change fn open_parent<'path>() { todo!() } fn main() { let old_path = frob("hello"); //~^ ERROR function takes 0 arguments open_parent(&old_path) //~^ ERROR function takes 0 arguments } </ins>


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: cannot get associated-item of ', 'error: internal compiler error: cannot get associated-item of ' File: --another one caused by auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [associated_item] computing associated item data for [typeck] type-checking [analysis] running analysis passes on this crate --
fyi
not caused by that, only exposed by it. The issue is a typo using instead of in diagnostic code, getting the wrong and then attempting to treat as an associated item

<ins> error[E0106]: missing lifetime specifier --> $DIR/opaque-used-in-extraneous-argument.rs:5:39 | LL | fn frob() -> impl Fn<P, Output = T> + '_ {} |                                       ^^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values | LL | fn frob() -> impl Fn<P, Output = T> + 'static {} |                                       ~~~~~~~ error[E0412]: cannot find type `P` in this scope --> $DIR/opaque-used-in-extraneous-argument.rs:5:22 | LL | fn frob() -> impl Fn<P, Output = T> + '_ {} |                      ^ not found in this scope | help: you might be missing a type parameter | LL | fn frob<P>() -> impl Fn<P, Output = T> + '_ {} |        +++ error[E0412]: cannot find type `T` in this scope --> $DIR/opaque-used-in-extraneous-argument.rs:5:34 | LL | fn frob() -> impl Fn<P, Output = T> + '_ {} |                                  ^ not found in this scope | help: you might be missing a type parameter | LL | fn frob<T>() -> impl Fn<P, Output = T> + '_ {} |        +++ error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change --> $DIR/opaque-used-in-extraneous-argument.rs:5:19 | LL | fn frob() -> impl Fn<P, Output = T> + '_ {} |                   ^^^^^^^^^^^^^^^^^ help: use parenthetical notation instead: `Fn(P) -> T` | = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/opaque-used-in-extraneous-argument.rs:16:20 | LL |     let old_path = frob("hello"); |                    ^^^^ ------- |                         | |                         unexpected argument of type `&'static str` |                         help: remove the extra argument | note: function defined here --> $DIR/opaque-used-in-extraneous-argument.rs:5:4 | LL | fn frob() -> impl Fn<P, Output = T> + '_ {} |    ^^^^ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/opaque-used-in-extraneous-argument.rs:19:5 | LL |     open_parent(&old_path) |     ^^^^^^^^^^^ --------- |                 | |                 unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static` |                 help: remove the extra argument | note: function defined here --> $DIR/opaque-used-in-extraneous-argument.rs:11:4 | LL | fn open_parent<'path>() { |    ^^^^^^^^^^^ error: aborting due to 6 previous errors Some errors have detailed explanations: E0061, E0106, E0412, E0658. For more information about an error, try `rustc --explain E0061`. </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed: expect 1 RPITITs in call to '', 'thread 'rustc' panicked at 'assertion failed: expect 1 RPITITs in call to '' File: --auto-reduced (treereduce-rust): original: Version information ` <!-- query stack: [collectreturnpositionimpltraitintraittys] comparing an impl and trait method signature, inferring any hidden types in the process [typeof] computing type of [checkmodimplwf] checking that impls are well-formed in top-level module [analysis] running analysis passes on this crate --
Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details

<ins> #![feature(associated_type_bounds)] // Test for <https://github.com/rust-lang/rust/issues/119857>. pub trait Iter { type Item<'a>: 'a where Self: 'a; fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>; //~^ ERROR associated type bindings are not allowed here } impl Iter for () { type Item<'a> = &'a mut [()]; fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> { None } } fn main() {} </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed: expect 1 RPITITs in call to '', 'thread 'rustc' panicked at 'assertion failed: expect 1 RPITITs in call to '' File: --auto-reduced (treereduce-rust): original: Version information ` <!-- query stack: [collectreturnpositionimpltraitintraittys] comparing an impl and trait method signature, inferring any hidden types in the process [typeof] computing type of [checkmodimplwf] checking that impls are well-formed in top-level module [analysis] running analysis passes on this crate --
Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details

<ins> error[E0229]: associated type bindings are not allowed here --> $DIR/no-gat-position.rs:8:56 | LL |     fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>; |                                                        ^^^^^^^^^ associated type not allowed here error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0229`. </ins>