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. --Repro repository and steps: I've bisected between 1.79.0 and 1.80.0: searched nightlies: from nightly-2024-04-28 to nightly-2024-06-07 regressed nightly: nightly-2024-05-10 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.9</summaryHost triple: x8664-pc-windows-msvc Reproduce with: </details<details<summaryOld context</summaryIt's a company project with a workspace that compiles ~680 crates on a clean compile. From initial testing it seems like an incremental compilation bug :S works, fails, but when setting in , succeeds again. also reproduces the issue, dropping the number of crates down to "only" 203. This is our profile config: </details<!-- 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. --This reproduces on 1.80 and the current nightly (as of writing this ticket). This does not reproduce on 1.79.0. : and <!-- Include a backtrace in the code block by setting in your environment. E.g. . --There is no backtrace being printed, even with . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
It's a proprietary code base, but I'll try my best to minimize the dependencies and code and see if I can get to something shareable. If you've got any other ideas on what to test or try, please let me know!
That LLVM metadata in the error looks like the kind that would be used with , but it's particularly surprising to me because as far as I know rustc only ever emits range metadata with a single range in it: might have some guesses here? Not sure why it would be incremental-related, though.
It's weird. My guess is that it's due to some LLVM Passes.
My first guess here would be a bug in getMostGenericRange(), but at least the basic case seems to work correctly:
Making progress on figuring out the minimal code to comment out to successfully compile again, on the way I've now got this:
Fully-minimized repro: Do note the release profile settings. Run with to repro. with Notes: Reordering the enum variants in Outer fixes it. Reducing the discriminant value of B or C fixes it. fixes it.
Thanks!
Reduced repro even further, with the minimal B and C values (thx Reduce them any further and the error is gone. Also removed the slice and replaced with just an equals check (since the bisect pointed to a check anyway)
Very interesting, I can trigger random crashes locally at stage 1, for example:
Never really looked at LLVM IR before, but guessing by what posted with the metadata: According to : The generated IR between 1.79.0 and 1.80.0 has changed significantly for builds. Rust 1.80.0, : Rust 1.80.0, Rust 1.79.0,
Ah, the minimal reproducible example is: (But I'm going to bed.
IIUC, this should be :
Upstreamed issue: claim
This can happen in any version:

<del> Subproject commit 57ae1a3474057fead2c438928ed368b3740bf0ec </del> <ins> Subproject commit ccf4c38bdd73f1a37ec266c73bdaef80e39f8cf6 </ins>


Question:
The documentation of and for any signed integer type, e.g.: In the "Panics" section it says "This function will panic if is 0 or if is -1 and is .", but I believe this is the wrong way around: the panic happens on , not on , as (correctly) explained in and all other related functions. Also, is there any situation where someone would want over ? Mathematically, should really just be 0, that it panics is more of an implementation artifact (the corresponding division overflows). Maybe it would be a good idea to add something like "If this is a problem, use instead." to the documentation of ? Though in most applications will probably be positive anyway. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
claim
the error is also present on and .

/// /// # Panics /// <del> /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is /// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag. </del> <ins> /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` and /// `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. </ins> /// /// # Examples ///


Question:
The documentation of and for any signed integer type, e.g.: In the "Panics" section it says "This function will panic if is 0 or if is -1 and is .", but I believe this is the wrong way around: the panic happens on , not on , as (correctly) explained in and all other related functions. Also, is there any situation where someone would want over ? Mathematically, should really just be 0, that it panics is more of an implementation artifact (the corresponding division overflows). Maybe it would be a good idea to add something like "If this is a problem, use instead." to the documentation of ? Though in most applications will probably be positive anyway. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
claim
the error is also present on and .

/// assert_eq!(a.rem_euclid(-b), 3); /// assert_eq!((-a).rem_euclid(-b), 1); /// ``` <ins> /// /// This will panic: /// ```should_panic #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.rem_euclid(-1);")] /// ``` </ins> #[doc(alias = "modulo", alias = "mod")] #[stable(feature = "euclidean_division", since = "1.38.0")] #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")]


Question:
The documentation of and for any signed integer type, e.g.: In the "Panics" section it says "This function will panic if is 0 or if is -1 and is .", but I believe this is the wrong way around: the panic happens on , not on , as (correctly) explained in and all other related functions. Also, is there any situation where someone would want over ? Mathematically, should really just be 0, that it panics is more of an implementation artifact (the corresponding division overflows). Maybe it would be a good idea to add something like "If this is a problem, use instead." to the documentation of ? Though in most applications will probably be positive anyway. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
claim
the error is also present on and .

/// /// # Panics /// <del> /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is /// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag. </del> <ins> /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. </ins> /// /// # Examples ///


Question:
<!-- ICE: Rustc '-Zvalidate-mir --edition=2018 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'', 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'' File: --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: [mirbuilt] building MIR for [checkunsafety] unsafety-checking -- label +F-async_closure
nightly-2024-05-23 =
With this full minimization: The real blame commit is:

use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_target::abi::{FieldIdx, VariantIdx}; <ins> use crate::pass_manager::validate_body; </ins> pub struct ByMoveBody; impl<'tcx> MirPass<'tcx> for ByMoveBody {


Question:
<!-- ICE: Rustc '-Zvalidate-mir --edition=2018 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'', 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'' File: --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: [mirbuilt] building MIR for [checkunsafety] unsafety-checking -- label +F-async_closure
nightly-2024-05-23 =
With this full minimization: The real blame commit is:

|(parent_field_idx, parent_capture), (child_field_idx, child_capture)| { // Store this set of additional projections (fields and derefs). // We need to re-apply them later. <del> let child_precise_captures = &child_capture.place.projections[parent_capture.place.projections.len()..]; </del> <ins> let mut child_precise_captures = child_capture.place.projections [parent_capture.place.projections.len()..] .to_vec(); </ins> <del> // If the parent captures by-move, and the child captures by-ref, then we // need to peel an additional `deref` off of the body of the child. let needs_deref = child_capture.is_by_ref() && !parent_capture.is_by_ref(); if needs_deref { assert_ne!( coroutine_kind, ty::ClosureKind::FnOnce, </del> <ins> // If the parent capture is by-ref, then we need to apply an additional // deref before applying any further projections to this place. if parent_capture.is_by_ref() { child_precise_captures.insert( 0, Projection { ty: parent_capture.place.ty(), kind: ProjectionKind::Deref }, ); } // If the child capture is by-ref, then we need to apply a "ref" // projection (i.e. `&`) at the end. But wait! We don't have that // as a projection kind. So instead, we can apply its dual and // *peel* a deref off of the place when it shows up in the MIR body. // Luckily, by construction this is always possible. let peel_deref = if child_capture.is_by_ref() { assert!( parent_capture.is_by_ref() || coroutine_kind != ty::ClosureKind::FnOnce, </ins> "`FnOnce` coroutine-closures return coroutines that capture from  their body; it will always result in a borrowck error!" ); <del> } </del> <ins> true } else { false }; // Regarding the behavior above, you may think that it's redundant to both // insert a deref and then peel a deref if the parent and child are both // captured by-ref. This would be correct, except for the case where we have // precise capturing projections, since the inserted deref is to the *beginning* // and the peeled deref is at the *end*. I cannot seem to actually find a // case where this happens, though, but let's keep this code flexible. </ins> // Finally, store the type of the parent's captured place. We need // this when building the field projection in the MIR body later on.


Question:
<!-- ICE: Rustc '-Zvalidate-mir --edition=2018 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'', 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'' File: --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: [mirbuilt] building MIR for [checkunsafety] unsafety-checking -- label +F-async_closure
nightly-2024-05-23 =
With this full minimization: The real blame commit is:

( FieldIdx::from_usize(parent_field_idx + num_args), parent_capture_ty, <del> needs_deref, </del> <ins> peel_deref, </ins> child_precise_captures, ), )


Question:
<!-- ICE: Rustc '-Zvalidate-mir --edition=2018 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'', 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'' File: --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: [mirbuilt] building MIR for [checkunsafety] unsafety-checking -- label +F-async_closure
nightly-2024-05-23 =
With this full minimization: The real blame commit is:

let mut by_move_body = body.clone(); MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body); dump_mir(tcx, false, "coroutine_by_move", &0, &by_move_body, |_, _| Ok(())); <ins> // Let's just always validate this body. validate_body(tcx, &mut by_move_body, "Initial coroutine_by_move body".to_string()); </ins> // FIXME: use query feeding to generate the body right here and then only store the `DefId` of the new body. by_move_body.source = mir::MirSource::from_instance(InstanceKind::CoroutineKindShim { coroutine_def_id: coroutine_def_id.to_def_id(),


Question:
<!-- ICE: Rustc '-Zvalidate-mir --edition=2018 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'', 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'' File: --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: [mirbuilt] building MIR for [checkunsafety] unsafety-checking -- label +F-async_closure
nightly-2024-05-23 =
With this full minimization: The real blame commit is:

struct MakeByMoveBody<'tcx> { tcx: TyCtxt<'tcx>, <del> field_remapping: UnordMap<FieldIdx, (FieldIdx, Ty<'tcx>, bool, &'tcx [Projection<'tcx>])>, </del> <ins> field_remapping: UnordMap<FieldIdx, (FieldIdx, Ty<'tcx>, bool, Vec<Projection<'tcx>>)>, </ins> by_move_coroutine_ty: Ty<'tcx>, }


Question:
<!-- ICE: Rustc '-Zvalidate-mir --edition=2018 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'', 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'' File: --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: [mirbuilt] building MIR for [checkunsafety] unsafety-checking -- label +F-async_closure
nightly-2024-05-23 =
With this full minimization: The real blame commit is:

if place.local == ty::CAPTURE_STRUCT_LOCAL && let Some((&mir::ProjectionElem::Field(idx, _), projection)) = place.projection.split_first() <del> && let Some(&(remapped_idx, remapped_ty, needs_deref, bridging_projections)) = </del> <ins> && let Some(&(remapped_idx, remapped_ty, peel_deref, ref bridging_projections)) = </ins> self.field_remapping.get(&idx) { // As noted before, if the parent closure captures a field by value, and // the child captures a field by ref, then for the by-move body we're // generating, we also are taking that field by value. Peel off a deref, // since a layer of ref'ing has now become redundant. <del> let final_projections = if needs_deref { </del> <ins> let final_projections = if peel_deref { </ins> let Some((mir::ProjectionElem::Deref, projection)) = projection.split_first() else { bug!(


Question:
<!-- ICE: Rustc '-Zvalidate-mir --edition=2018 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'', 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'' File: --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: [mirbuilt] building MIR for [checkunsafety] unsafety-checking -- label +F-async_closure
nightly-2024-05-23 =
With this full minimization: The real blame commit is:

<ins> //@ compile-flags: -Zvalidate-mir //@ edition: 2021 #![feature(async_closure)] // NOT copy. struct Ty; fn hello(x: &Ty) { let c = async || { *x; //~^ ERROR cannot move out of `*x` which is behind a shared reference }; } fn main() {} </ins>


Question:
<!-- ICE: Rustc '-Zvalidate-mir --edition=2018 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'', 'thread 'rustc' panicked at 'broken MIR in CoroutineKindShim { coroutinedefid: DefId(0:8 ~ a[8079]::hello::{closure}::{closure}) } (after pass CheckPackedRef) at bb0[2]:'' File: --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: [mirbuilt] building MIR for [checkunsafety] unsafety-checking -- label +F-async_closure
nightly-2024-05-23 =
With this full minimization: The real blame commit is:

<ins> error[E0507]: cannot move out of `*x` which is behind a shared reference --> $DIR/move-out-of-ref.rs:11:9 | LL |         *x; |         ^^ move occurs because `*x` has type `Ty`, which does not implement the `Copy` trait | note: if `Ty` implemented `Clone`, you could clone the value --> $DIR/move-out-of-ref.rs:7:1 | LL | struct Ty; | ^^^^^^^^^ consider implementing `Clone` for this type ... LL |         *x; |         -- you could clone this value error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0507`. </ins>


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this : And compiled it with . I expected to see this happen: The compiler should generate a function which only contains the instruction. Instead, this happened: The compiler crashes with . <!-- 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. --: As requested in
This is an LLVM assertion
It was noted in that this comes from sanitizer annotations being to naked functions. Seems like we might not want to do that? Cc
Almost certainly, but is not supposed to be used in places where user input can cause it to be reached.
Reported at
To clarify, the fix that landed is just to make this an IR verification failure rather than a backend crash. The underlying issue with the kasan + naked combination still needs to be fixed.
Should we file an issue upstream to handle this in sanitizers as well, or is there one already opened?

// the string "false". Now it is disabled by absence of the attribute. to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false")); } <del> } else if llvm_util::get_version() >= (19, 0, 0) { // For non-naked functions, set branch protection attributes on aarch64. if let Some(BranchProtection { bti, pac_ret }) = cx.sess().opts.unstable_opts.branch_protection { assert!(cx.sess().target.arch == "aarch64"); if bti { to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement")); } if let Some(PacRet { leaf, key }) = pac_ret { to_add.push(llvm::CreateAttrStringValue( cx.llcx, "sign-return-address", if leaf { "all" } else { "non-leaf" }, )); to_add.push(llvm::CreateAttrStringValue( cx.llcx, "sign-return-address-key", if key == PAuthKey::A { "a_key" } else { "b_key" }, )); </del> <ins> } else { // Do not set sanitizer attributes for naked functions. to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); if llvm_util::get_version() >= (19, 0, 0) { // For non-naked functions, set branch protection attributes on aarch64. if let Some(BranchProtection { bti, pac_ret }) = cx.sess().opts.unstable_opts.branch_protection { assert!(cx.sess().target.arch == "aarch64"); if bti { to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement")); } if let Some(PacRet { leaf, key }) = pac_ret { to_add.push(llvm::CreateAttrStringValue( cx.llcx, "sign-return-address", if leaf { "all" } else { "non-leaf" }, )); to_add.push(llvm::CreateAttrStringValue( cx.llcx, "sign-return-address-key", if key == PAuthKey::A { "a_key" } else { "b_key" }, )); } </ins> } } }


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this : And compiled it with . I expected to see this happen: The compiler should generate a function which only contains the instruction. Instead, this happened: The compiler crashes with . <!-- 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. --: As requested in
This is an LLVM assertion
It was noted in that this comes from sanitizer annotations being to naked functions. Seems like we might not want to do that? Cc
Almost certainly, but is not supposed to be used in places where user input can cause it to be reached.
Reported at
To clarify, the fix that landed is just to make this an IR verification failure rather than a backend crash. The underlying issue with the kasan + naked combination still needs to be fixed.
Should we file an issue upstream to handle this in sanitizers as well, or is there one already opened?

if let Some(backchain) = backchain_attr(cx) { to_add.push(backchain); } <del> to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); </del> to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry)); // Always annotate functions with the target-cpu they are compiled for.


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this : And compiled it with . I expected to see this happen: The compiler should generate a function which only contains the instruction. Instead, this happened: The compiler crashes with . <!-- 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. --: As requested in
This is an LLVM assertion
It was noted in that this comes from sanitizer annotations being to naked functions. Seems like we might not want to do that? Cc
Almost certainly, but is not supposed to be used in places where user input can cause it to be reached.
Reported at
To clarify, the fix that landed is just to make this an IR verification failure rather than a backend crash. The underlying issue with the kasan + naked combination still needs to be fixed.
Should we file an issue upstream to handle this in sanitizers as well, or is there one already opened?

<ins> // Make sure we do not request sanitizers for naked functions. //@ only-x86_64 //@ needs-sanitizer-address //@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static #![crate_type = "lib"] #![no_std] #![feature(abi_x86_interrupt, naked_functions)] // CHECK: define x86_intrcc void @page_fault_handler(ptr {{.*}}%0, i64 {{.*}}%1){{.*}}#[[ATTRS:[0-9]+]] { // CHECK-NOT: memcpy #[naked] #[no_mangle] pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) { unsafe { core::arch::asm!("ud2", options(noreturn)); } } // CHECK: #[[ATTRS]] = // CHECK-NOT: sanitize_address </ins>


Question: I tried this code: I expected to see it work. Instead, this happened: This regressed in This only happens when coercing from safe to unsafe, not unsafe to unsafe or safe to safe. I probably forgot something about how we construct the adjustment from unsafe to safe fn.

let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig); <del> if let Err(terr) = self.eq_types( *ty, </del> <ins> if let Err(terr) = self.sub_types( </ins> ty_fn_ptr_from, <ins> *ty, </ins> location.to_locations(), ConstraintCategory::Cast { unsize_to: None }, ) {


Question: I tried this code: I expected to see it work. Instead, this happened: This regressed in This only happens when coercing from safe to unsafe, not unsafe to unsafe or safe to safe. I probably forgot something about how we construct the adjustment from unsafe to safe fn.

<ins> //@ check-pass fn higher_ranked_fndef(ctx: &mut ()) {} fn test(higher_ranked_fnptr: fn(&mut ())) { fn as_unsafe<T>(_: unsafe fn(T)) {} // Make sure that we can cast higher-ranked fn items and pointers to // a non-higher-ranked target. as_unsafe(higher_ranked_fndef); as_unsafe(higher_ranked_fnptr); } fn main() {} </ins>


Question:
<!-- ICE: Rustc '-Zunstable-options --edition=2024 -ooutputfile -Zdump-mir-dir=dir' 'error: internal compiler error: impossible case reached', 'error: internal compiler error: impossible case reached' File: --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: [coroutinebymovebodydefid] looking up the coroutine by-move body for [analysis] running analysis passes on this crate -- label +F-asyncclosure
As a step of reducing your code examples, could you please ensure that is necessary to reproduce this ICE before mentioning it in the issue? This ICE reproduces on edition 2021, which is the current stable edition.
My project fails on nightly also while using edition 2021.
Yep, a fix is already up and it's waiting for approval. I recommend downgrading to a slightly older nightly until this is fixed.

) -> DefId { let body = tcx.mir_built(coroutine_def_id).borrow(); <ins> // If the typeck results are tainted, no need to make a by-ref body. if body.tainted_by_errors.is_some() { return coroutine_def_id.to_def_id(); } </ins> let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) = tcx.coroutine_kind(coroutine_def_id) else {


Question:
<!-- ICE: Rustc '-Zunstable-options --edition=2024 -ooutputfile -Zdump-mir-dir=dir' 'error: internal compiler error: impossible case reached', 'error: internal compiler error: impossible case reached' File: --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: [coroutinebymovebodydefid] looking up the coroutine by-move body for [analysis] running analysis passes on this crate -- label +F-asyncclosure
As a step of reducing your code examples, could you please ensure that is necessary to reproduce this ICE before mentioning it in the issue? This ICE reproduces on edition 2021, which is the current stable edition.
My project fails on nightly also while using edition 2021.
Yep, a fix is already up and it's waiting for approval. I recommend downgrading to a slightly older nightly until this is fixed.

// the MIR body will be constructed well. let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty; <del> let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") }; </del> <ins> let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("tried to create by-move body of non-coroutine receiver"); }; </ins> let args = args.as_coroutine(); let coroutine_kind = args.kind_ty().to_opt_closure_kind().unwrap();


Question:
<!-- ICE: Rustc '-Zunstable-options --edition=2024 -ooutputfile -Zdump-mir-dir=dir' 'error: internal compiler error: impossible case reached', 'error: internal compiler error: impossible case reached' File: --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: [coroutinebymovebodydefid] looking up the coroutine by-move body for [analysis] running analysis passes on this crate -- label +F-asyncclosure
As a step of reducing your code examples, could you please ensure that is necessary to reproduce this ICE before mentioning it in the issue? This ICE reproduces on edition 2021, which is the current stable edition.
My project fails on nightly also while using edition 2021.
Yep, a fix is already up and it's waiting for approval. I recommend downgrading to a slightly older nightly until this is fixed.

let ty::CoroutineClosure(_, parent_args) = *tcx.type_of(parent_def_id).instantiate_identity().kind() else { <del> bug!(); </del> <ins> bug!("coroutine's parent was not a coroutine-closure"); </ins> }; if parent_args.references_error() { return coroutine_def_id.to_def_id();


Question:
<!-- ICE: Rustc '-Zunstable-options --edition=2024 -ooutputfile -Zdump-mir-dir=dir' 'error: internal compiler error: impossible case reached', 'error: internal compiler error: impossible case reached' File: --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: [coroutinebymovebodydefid] looking up the coroutine by-move body for [analysis] running analysis passes on this crate -- label +F-asyncclosure
As a step of reducing your code examples, could you please ensure that is necessary to reproduce this ICE before mentioning it in the issue? This ICE reproduces on edition 2021, which is the current stable edition.
My project fails on nightly also while using edition 2021.
Yep, a fix is already up and it's waiting for approval. I recommend downgrading to a slightly older nightly until this is fixed.

<ins> //@ edition: 2021 #![feature(async_closure)] // Ensure that building a by-ref async closure body doesn't ICE when the parent // body is tainted. fn main() { missing; //~^ ERROR cannot find value `missing` in this scope // We don't do numerical inference fallback when the body is tainted. // This leads to writeback folding the type of the coroutine-closure // into an error type, since its signature contains that numerical // infer var. let c = async |_| {}; c(1); } </ins>


Question:
<!-- ICE: Rustc '-Zunstable-options --edition=2024 -ooutputfile -Zdump-mir-dir=dir' 'error: internal compiler error: impossible case reached', 'error: internal compiler error: impossible case reached' File: --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: [coroutinebymovebodydefid] looking up the coroutine by-move body for [analysis] running analysis passes on this crate -- label +F-asyncclosure
As a step of reducing your code examples, could you please ensure that is necessary to reproduce this ICE before mentioning it in the issue? This ICE reproduces on edition 2021, which is the current stable edition.
My project fails on nightly also while using edition 2021.
Yep, a fix is already up and it's waiting for approval. I recommend downgrading to a slightly older nightly until this is fixed.

<ins> error[E0425]: cannot find value `missing` in this scope --> $DIR/tainted-body-2.rs:9:5 | LL |     missing; |     ^^^^^^^ not found in this scope error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0425`. </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'', 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'' File: --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: [issizedraw] computing whether is [layoutof] computing layout of -- label +F-impltraitinassoctype +F-inherentassociated_types
ah lol this regressed in cc

let mut span = None; let mut accum = 0u64; <del> for (index, arg_def) in fn_sig.inputs().iter().enumerate() { let layout = tcx.layout_of(ParamEnv::reveal_all().and(*arg_def.skip_binder()))?; </del> <ins> // this type is only used for layout computation, which does not rely on regions let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig); for (index, ty) in fn_sig.inputs().iter().enumerate() { let layout = tcx.layout_of(ParamEnv::reveal_all().and(*ty))?; </ins> let align = layout.layout.align().abi.bytes(); let size = layout.layout.size().bytes();


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'', 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'' File: --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: [issizedraw] computing whether is [layoutof] computing layout of -- label +F-impltraitinassoctype +F-inherentassociated_types
ah lol this regressed in cc

tcx: TyCtxt<'tcx>, fn_sig: ty::PolyFnSig<'tcx>, ) -> Result<bool, &'tcx LayoutError<'tcx>> { <del> let mut ret_ty = fn_sig.output().skip_binder(); </del> <ins> // this type is only used for layout computation, which does not rely on regions let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig); let mut ret_ty = fn_sig.output(); </ins> let layout = tcx.layout_of(ParamEnv::reveal_all().and(ret_ty))?; let size = layout.layout.size().bytes();


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'', 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'' File: --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: [issizedraw] computing whether is [layoutof] computing layout of -- label +F-impltraitinassoctype +F-inherentassociated_types
ah lol this regressed in cc

struct Wrapper<T>(T); struct Test<T: Copy> { <del> f1: extern "C-cmse-nonsecure-call" fn<U: Copy>(U, u32, u32, u32) -> u64, //~ ERROR cannot find type `U` in this scope //~^ ERROR function pointer types may not have generic parameters </del> <ins> f1: extern "C-cmse-nonsecure-call" fn<U: Copy>(U, u32, u32, u32) -> u64, //~^ ERROR cannot find type `U` in this scope //~| ERROR function pointer types may not have generic parameters </ins> f2: extern "C-cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> u64, //~^ ERROR `impl Trait` is not allowed in `fn` pointer parameters f3: extern "C-cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, //~ ERROR [E0798] f4: extern "C-cmse-nonsecure-call" fn(Wrapper<T>, u32, u32, u32) -> u64, //~ ERROR [E0798] } <ins> type WithReference = extern "C-cmse-nonsecure-call" fn(&usize); trait Trait {} type WithTraitObject = extern "C-cmse-nonsecure-call" fn(&dyn Trait) -> &dyn Trait; //~^ ERROR return value of `"C-cmse-nonsecure-call"` function too large to pass via registers [E0798] type WithStaticTraitObject = extern "C-cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn Trait; //~^ ERROR return value of `"C-cmse-nonsecure-call"` function too large to pass via registers [E0798] #[repr(transparent)] struct WrapperTransparent<'a>(&'a dyn Trait); type WithTransparentTraitObject = extern "C-cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTransparent; //~^ ERROR return value of `"C-cmse-nonsecure-call"` function too large to pass via registers [E0798] type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...); //~^ ERROR C-variadic function must have a compatible calling convention, like `C` or `cdecl` [E0045] </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'', 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'' File: --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: [issizedraw] computing whether is [layoutof] computing layout of -- label +F-impltraitinassoctype +F-inherentassociated_types
ah lol this regressed in cc

|                    +++ error[E0562]: `impl Trait` is not allowed in `fn` pointer parameters <del> --> $DIR/generics.rs:17:43 </del> <ins> --> $DIR/generics.rs:18:43 </ins> | LL |     f2: extern "C-cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> u64, |                                           ^^^^^^^^^


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'', 'thread 'rustc' panicked at ' has escaping bound vars, so it cannot be wrapped in a dummy binder.'' File: --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: [issizedraw] computing whether is [layoutof] computing layout of -- label +F-impltraitinassoctype +F-inherentassociated_types
ah lol this regressed in cc

= note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0798]: function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type <del> --> $DIR/generics.rs:19:9 </del> <ins> --> $DIR/generics.rs:20:9 </ins> | LL |     f3: extern "C-cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0798]: function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type <del> --> $DIR/generics.rs:20:9 </del> <ins> --> $DIR/generics.rs:21:9 </ins> | LL |     f4: extern "C-cmse-nonsecure-call" fn(Wrapper<T>, u32, u32, u32) -> u64, |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <del> error: aborting due to 5 previous errors </del> <ins> error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers --> $DIR/generics.rs:27:73 | LL | type WithTraitObject = extern "C-cmse-nonsecure-call" fn(&dyn Trait) -> &dyn Trait; |                                                                         ^^^^^^^^^^ this type doesn't fit in the available registers | = note: functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers --> $DIR/generics.rs:31:62 | LL |     extern "C-cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn Trait; |                                                              ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers | = note: functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers --> $DIR/generics.rs:38:62 | LL |     extern "C-cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTransparent; |                                                              ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers | = note: functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl` --> $DIR/generics.rs:41:20 | LL | type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...); |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention error: aborting due to 9 previous errors </ins> <del> Some errors have detailed explanations: E0412, E0562, E0798. For more information about an error, try `rustc --explain E0412`. </del> <ins> Some errors have detailed explanations: E0045, E0412, E0562, E0798. For more information about an error, try `rustc --explain E0045`. </ins>


Question:
When running any bootstrap command, it complains that it can't figure out whether my master branch is outdated. Of course it does, as it just YOLOs into , which is just a file and not a directory for worktrees: it should probably not do that (i don't have a suggestion on what to do instead) regressed by
i would say adding a bit of error handling that checks if it's in a worktree doesn't sound too hard. there's two options from there: emit the warning in a worktree. this is basically trivial, but if someone does 100% of their work in a worktree, they may end up with an outdated upstream and not know it back to a more reliable method when in a worktree

cmd_finder.must_have(s); } <del> // this warning is useless in CI, // and CI probably won't have the right branches anyway. if !build_helper::ci::CiEnv::is_ci() { if let Err(e) = warn_old_master_branch(&build.config.git_config(), &build.config.src) .map_err(|e| e.to_string()) { eprintln!("unable to check if upstream branch is old: {e}"); } } </del> <ins> warn_old_master_branch(&build.config.git_config(), &build.config.src); </ins> }


Question:
When running any bootstrap command, it complains that it can't figure out whether my master branch is outdated. Of course it does, as it just YOLOs into , which is just a file and not a directory for worktrees: it should probably not do that (i don't have a suggestion on what to do instead) regressed by
i would say adding a bit of error handling that checks if it's in a worktree doesn't sound too hard. there's two options from there: emit the warning in a worktree. this is basically trivial, but if someone does 100% of their work in a worktree, they may end up with an outdated upstream and not know it back to a more reliable method when in a worktree

/// /// This can result in formatting thousands of files instead of a dozen, /// so we should warn the user something is wrong. <del> pub fn warn_old_master_branch( config: &GitConfig<'_>, git_dir: &Path, ) -> Result<(), Box<dyn std::error::Error>> { use std::time::Duration; const WARN_AFTER: Duration = Duration::from_secs(60 * 60 * 24 * 10); let updated_master = updated_master_branch(config, Some(git_dir))?; let branch_path = git_dir.join(".git/refs/remotes").join(&updated_master); match std::fs::metadata(branch_path) { Ok(meta) => { if meta.modified()?.elapsed()? > WARN_AFTER { eprintln!("warning: {updated_master} has not been updated in 10 days"); } else { return Ok(()); </del> <ins> pub fn warn_old_master_branch(config: &GitConfig<'_>, git_dir: &Path) { if crate::ci::CiEnv::is_ci() { // this warning is useless in CI, // and CI probably won't have the right branches anyway. return; } // this will be overwritten by the actual name, if possible let mut updated_master = "the upstream master branch".to_string(); match warn_old_master_branch_(config, git_dir, &mut updated_master) { Ok(branch_is_old) => { if !branch_is_old { return; </ins> } <ins> // otherwise fall through and print the rest of the warning </ins> } Err(err) => { eprintln!("warning: unable to check if {updated_master} is old due to error: {err}")


Question:
When running any bootstrap command, it complains that it can't figure out whether my master branch is outdated. Of course it does, as it just YOLOs into , which is just a file and not a directory for worktrees: it should probably not do that (i don't have a suggestion on what to do instead) regressed by
i would say adding a bit of error handling that checks if it's in a worktree doesn't sound too hard. there's two options from there: emit the warning in a worktree. this is basically trivial, but if someone does 100% of their work in a worktree, they may end up with an outdated upstream and not know it back to a more reliable method when in a worktree

} eprintln!( "warning: {updated_master} is used to determine if files have been modifiedn <del> warning: if it is not updated, this may cause files to be needlessly reformatted" </del> <ins> warning: if it is not updated, this may cause files to be needlessly reformatted" </ins> ); <del> Ok(()) </del> <ins> } pub fn warn_old_master_branch_( config: &GitConfig<'_>, git_dir: &Path, updated_master: &mut String, ) -> Result<bool, Box<dyn std::error::Error>> { use std::time::Duration; *updated_master = updated_master_branch(config, Some(git_dir))?; let branch_path = git_dir.join(".git/refs/remotes").join(&updated_master); const WARN_AFTER: Duration = Duration::from_secs(60 * 60 * 24 * 10); let meta = match std::fs::metadata(&branch_path) { Ok(meta) => meta, Err(err) => { let gcd = git_common_dir(&git_dir)?; if branch_path.starts_with(&gcd) { return Err(Box::new(err)); } std::fs::metadata(Path::new(&gcd).join("refs/remotes").join(&updated_master))? } }; if meta.modified()?.elapsed()? > WARN_AFTER { eprintln!("warning: {updated_master} has not been updated in 10 days"); Ok(true) } else { Ok(false) } } fn git_common_dir(dir: &Path) -> Result<String, String> { output_result(Command::new("git").arg("-C").arg(dir).arg("rev-parse").arg("--git-common-dir")) .map(|x| x.trim().to_string()) </ins> }


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --When compiled as a standard binary on the host system, the exit codes are returned as expected. When compiled with wasm32-wasip1, the use of ExitCode results in the exit code of 1, regardless of the value provided to ExitCode::from. The following are the minimal examples used while reproducing the bug: The above example produces the expected error code of 10 when compiling for the the host system and (executed with wasmtime 24.0.0). The above example produces the exit code when compiled for the host system but returns exit code 1 when compiled with (again run in wasmtime 24.0.0). Looking at the resulting WASM (decompiled to WAT) we see the main function returns a (here compiled with ): For source code of the reproducer, see: Tested against stable, beta and nightly. : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
It seems that we just call ?
Minimized: claim label -O-wasi
Oh, "cool"!
that is so concise! Thanks. I’d also be very interested in getting some insight on where to look in the code base for this sort of thing.
I'm kinda just abusing my IDE (RustRover)’s Go To Declaration & Find Usages shortcuts, you may need to tell yours to use the wasm target for name resolution/code indexing instead of your OS’ default one.
I ran the tests in my reproducer repo against the latest nightly (post merge of ) and the all pass now. Thanks!

} #[derive(PartialEq, Eq, Clone, Copy, Debug)] <del> pub struct ExitCode(bool); </del> <ins> pub struct ExitCode(u8); </ins> impl ExitCode { <del> pub const SUCCESS: ExitCode = ExitCode(false); pub const FAILURE: ExitCode = ExitCode(true); </del> <ins> pub const SUCCESS: ExitCode = ExitCode(0); pub const FAILURE: ExitCode = ExitCode(1); </ins> pub fn as_i32(&self) -> i32 { self.0 as i32


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --When compiled as a standard binary on the host system, the exit codes are returned as expected. When compiled with wasm32-wasip1, the use of ExitCode results in the exit code of 1, regardless of the value provided to ExitCode::from. The following are the minimal examples used while reproducing the bug: The above example produces the expected error code of 10 when compiling for the the host system and (executed with wasmtime 24.0.0). The above example produces the exit code when compiled for the host system but returns exit code 1 when compiled with (again run in wasmtime 24.0.0). Looking at the resulting WASM (decompiled to WAT) we see the main function returns a (here compiled with ): For source code of the reproducer, see: Tested against stable, beta and nightly. : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
It seems that we just call ?
Minimized: claim label -O-wasi
Oh, "cool"!
that is so concise! Thanks. I’d also be very interested in getting some insight on where to look in the code base for this sort of thing.
I'm kinda just abusing my IDE (RustRover)’s Go To Declaration & Find Usages shortcuts, you may need to tell yours to use the wasm target for name resolution/code indexing instead of your OS’ default one.
I ran the tests in my reproducer repo against the latest nightly (post merge of ) and the all pass now. Thanks!

impl From<u8> for ExitCode { fn from(code: u8) -> Self { <del> match code { 0 => Self::SUCCESS, 1..=255 => Self::FAILURE, } </del> <ins> Self(code) </ins> } }


Question:
E.g. if a test doesn't have a fn it can prevent the test from ICEing because ICEing codepath might not yet be reached before compilation is aborted. In this case, the stderr should be printed to help the person figure out that "I forgor to annotate crate type" is the cause.
you can set env var which should print stdout, stderr and exit code
Oh right, good point, I forgor this existed. We should (I'll do this later unless you want to work on it): Mention this env var in the panic message for when the crashes test no longer crash. () Mention this env var in rustc-dev-guide. () EDIT: ended up duplicating some description of ` in because I would not have thought to look there for docs specifically.

// if a test does not crash, consider it an error if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) { self.fatal(&format!( <del> "crashtest no longer crashes/triggers ICE, horray! Please give it a meaningful name,  add a doc-comment to the start of the test explaining why it exists and  move it to tests/ui or wherever you see fit. Adding 'Fixes #<issueNr>' to your PR description  ensures that the corresponding ticket is auto-closed upon merge." </del> <ins> "crashtest no longer crashes/triggers ICE, horray! Please give it a meaningful  name, add a doc-comment to the start of the test explaining why it exists and  move it to tests/ui or wherever you see fit. Adding 'Fixes #<issueNr>' to your PR  description ensures that the corresponding ticket is auto-closed upon merge.  If you want to see verbose output, set `COMPILETEST_VERBOSE_CRASHES=1`." </ins> )); } }


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I ran the following commands: <details<summaryOn 2024-10-01, this renders like this</summary! </details<details<summaryOn 2024-10-02, this renders like this</summary! </detailsNote that the bullet points are spaced farther apart. I'm assuming this is a regression?
I think this is a consequence of which was intended to address . GG is adding a UI regression test for the spacing in for . cc
It's indeed something that we changed on purpose.
Little modification: the changes are improving the situation but introducing some new other issues. Talking about it currently to figure out what's the best solution.
I opened Please don't hesitate to take a look. Hopefully I was able to improve the current situation without going back to the original issue.
Certainly seems better than before!

} .docblock li { <del> margin-bottom: .8em; </del> <ins> margin-bottom: .4em; </ins> } <del> .docblock li p { margin-bottom: .1em; </del> <ins> .docblock li p:not(:last-child) { /* This margin is voluntarily smaller than `.docblock li` to keep the visual list element items separated while also having a visual separation (although smaller) for paragraphs. */ margin-bottom: .3em; </ins> } /* "where ..." clauses with block display are also smaller */


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I ran the following commands: <details<summaryOn 2024-10-01, this renders like this</summary! </details<details<summaryOn 2024-10-02, this renders like this</summary! </detailsNote that the bullet points are spaced farther apart. I'm assuming this is a regression?
I think this is a consequence of which was intended to address . GG is adding a UI regression test for the spacing in for . cc
It's indeed something that we changed on purpose.
Little modification: the changes are improving the situation but introducing some new other issues. Talking about it currently to figure out what's the best solution.
I opened Please don't hesitate to take a look. Hopefully I was able to improve the current situation without going back to the original issue.
Certainly seems better than before!

<ins> // This test ensures that the documentation list markers are correctly placed. // It also serves as a regression test for <https://github.com/rust-lang/rust/issues/130622>. go-to: "file://" + |DOC_PATH| + "/test_docs/long_list/index.html" show-text: true // 0.3em assert-css: (".docblock li p:not(last-child)", {"margin-bottom": "4.8px"}) assert-css: (".docblock li p + p:last-child", {"margin-bottom": "0px"}) // 0.4em assert-css: (".docblock li", {"margin-bottom": "6.4px"}) </ins>


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I ran the following commands: <details<summaryOn 2024-10-01, this renders like this</summary! </details<details<summaryOn 2024-10-02, this renders like this</summary! </detailsNote that the bullet points are spaced farther apart. I'm assuming this is a regression?
I think this is a consequence of which was intended to address . GG is adding a UI regression test for the spacing in for . cc
It's indeed something that we changed on purpose.
Little modification: the changes are improving the situation but introducing some new other issues. Talking about it currently to figure out what's the best solution.
I opened Please don't hesitate to take a look. Hopefully I was able to improve the current situation without going back to the original issue.
Certainly seems better than before!

/// subt_vec_num(x: &[f64], y: f64) pub fn subt_vec_num() {} } <ins> pub mod long_list { //! bla //! //! * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque et libero ut leo //!   interdum laoreet vitae a mi. Aliquam erat volutpat. Suspendisse volutpat non quam non //!   commodo. //! //!   Praesent enim neque, imperdiet sed nisl at, lobortis egestas augue. Sed vitae tristique //!   augue. Phasellus vel pretium lectus. //! * Praesent enim neque, imperdiet sed nisl at, lobortis egestas augue. Sed vitae tristique //!   augue. Phasellus vel pretium lectus. //! * Praesent enim neque, imperdiet sed nisl at, lobortis egestas augue. Sed vitae tristique //!   augue. Phasellus vel pretium lectus. //! //! Another list: //! //! * [`TryFromBytes`](#a) indicates that a type may safely be converted from certain byte //!   sequence (conditional on runtime checks) //! * [`FromZeros`](#a) indicates that a sequence of zero bytes represents a valid instance of //!   a type //! * [`FromBytes`](#a) indicates that a type may safely be converted from an arbitrary byte //!   sequence } </ins>


Question:
When I do , it says: Strangely, when I do , it uses the correct name: No idea how it is even possible for this tool to have two different names inside bootstrap...
I think this is just because cargo-miri's tool check step is generated through a macro this macro generates the check message via there's a in there too. The build step has a different name because that macro explicitly asks for a display name
If I make the macro use a display name,
Ah, I didn't realize those two steps were defined entirely independently.
Anyway, should make this more consistent.

} macro_rules! tool_check_step { <del> ($name:ident, $path:literal, $($alias:literal, )* $source_type:path $(, $default:literal )?) => { </del> <ins> ( $name:ident, $display_name:literal, $path:literal, $($alias:literal, )* $source_type:path $(, $default:literal )? ) => { </ins> #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { pub target: TargetSelection,


Question:
When I do , it says: Strangely, when I do , it uses the correct name: No idea how it is even possible for this tool to have two different names inside bootstrap...
I think this is just because cargo-miri's tool check step is generated through a macro this macro generates the check message via there's a in there too. The build step has a different name because that macro explicitly asks for a display name
If I make the macro use a display name,
Ah, I didn't realize those two steps were defined entirely independently.
Anyway, should make this more consistent.

cargo.arg("--all-targets"); } <del> let _guard = builder.msg_check(&concat!(stringify!($name), " artifacts").to_lowercase(), target); </del> <ins> let _guard = builder.msg_check(&format!("{} artifacts", $display_name), target); </ins> run_cargo( builder, cargo,


Question:
When I do , it says: Strangely, when I do , it uses the correct name: No idea how it is even possible for this tool to have two different names inside bootstrap...
I think this is just because cargo-miri's tool check step is generated through a macro this macro generates the check message via there's a in there too. The build step has a different name because that macro explicitly asks for a display name
If I make the macro use a display name,
Ah, I didn't realize those two steps were defined entirely independently.
Anyway, should make this more consistent.

}; } <del> tool_check_step!(Rustdoc, "src/tools/rustdoc", "src/librustdoc", SourceType::InTree); </del> <ins> tool_check_step!(Rustdoc, "rustdoc", "src/tools/rustdoc", "src/librustdoc", SourceType::InTree); </ins> // Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead // of a submodule. Since the SourceType only drives the deny-warnings // behavior, treat it as in-tree so that any new warnings in clippy will be // rejected. <del> tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree); tool_check_step!(Miri, "src/tools/miri", SourceType::InTree); tool_check_step!(CargoMiri, "src/tools/miri/cargo-miri", SourceType::InTree); tool_check_step!(Rls, "src/tools/rls", SourceType::InTree); tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree); tool_check_step!(MiroptTestTools, "src/tools/miropt-test-tools", SourceType::InTree); tool_check_step!(TestFloatParse, "src/etc/test-float-parse", SourceType::InTree); tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false); </del> <ins> tool_check_step!(Clippy, "clippy", "src/tools/clippy", SourceType::InTree); tool_check_step!(Miri, "miri", "src/tools/miri", SourceType::InTree); tool_check_step!(CargoMiri, "cargo-miri", "src/tools/miri/cargo-miri", SourceType::InTree); tool_check_step!(Rls, "rls", "src/tools/rls", SourceType::InTree); tool_check_step!(Rustfmt, "rustfmt", "src/tools/rustfmt", SourceType::InTree); tool_check_step!( MiroptTestTools, "miropt-test-tools", "src/tools/miropt-test-tools", SourceType::InTree ); tool_check_step!( TestFloatParse, "test-float-parse", "src/etc/test-float-parse", SourceType::InTree ); tool_check_step!(Bootstrap, "bootstrap", "src/bootstrap", SourceType::InTree, false); </ins> /// Cargo's output path for the standard library in a given stage, compiled /// by a particular compiler for the specified target.


Question:
The input for doc searches isn't sanitized, allowing for arbitrary HTML input.
Is this problematic? Afaik everything is done client-side.
Yes. For example, if rustdoc documentation is served on a site that uses a cookie for authentication, an attacker could perform XHRs on the victim's behalf by injecting a tag. It's not particularly problematic on the site, though.
But the search is done with client-side javascript on a client-side resources index; how can you secure that?
I'm not sure what you mean by the search being unsecurable because the index is searched on the client. The problem is that the Javascript responsible for rendering the search query does not properly escape it, so an attacker can insert arbitrary HTML and therefore execute arbitrary Javascript in another user's browser merely by tricking the user into following a link. This is easily fixed by escaping and here: If you're not convinced of the danger, see for an example. If I were more nefarious, and I knew of a site that served rustdoc HTML documentation on the same domain as another site that uses cookie authentication, I could impersonate a user of this site just by convincing them to follow a link I've sent them.
I see thanks for the explanations, opened up a PR for it.
I think this is the part that makes me go from "meh" to "OH!." There's not a lot of damage on rust-, but we shouldn't open up others to these issues.

}); }  function escape(content) { return $('
').text(content).html(); }  function showResults(results) { var output, shown, query = getQuery(); currentResults = query.id;  output = '
Results for ' + query.query + (query.type ? ' (type: ' + query.type + ')' : '') + '
';   output = '
Results for ' + escape(query.query) + (query.type ? ' (type: ' + escape(query.type) + ')' : '') + '
';  output += '
'; if (results.length > 0) {


Question:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

TcpWatcher { home: home, handle: handle, <del> stream: StreamWatcher::new(handle), </del> <ins> stream: StreamWatcher::new(handle, true), </ins> refcount: Refcount::new(), read_access: AccessTimeout::new(), write_access: AccessTimeout::new(),


Question:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

fn clone(&self) -> Box<rtio::RtioTcpStream + Send> { box TcpWatcher { handle: self.handle, <del> stream: StreamWatcher::new(self.handle), </del> <ins> stream: StreamWatcher::new(self.handle, false), </ins> home: self.home.clone(), refcount: self.refcount.clone(), read_access: self.read_access.clone(),


Question:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

handle }; PipeWatcher { <del> stream: StreamWatcher::new(handle), </del> <ins> stream: StreamWatcher::new(handle, true), </ins> home: home, defused: false, refcount: Refcount::new(),


Question:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

fn clone(&self) -> Box<rtio::RtioPipe + Send> { box PipeWatcher { <del> stream: StreamWatcher::new(self.stream.handle), </del> <ins> stream: StreamWatcher::new(self.stream.handle, false), </ins> defused: false, home: self.home.clone(), refcount: self.refcount.clone(),


Question:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

// will be manipulated on each of the methods called on this watcher. // Wrappers should ensure to always reset the field to an appropriate value // if they rely on the field to perform an action. <del> pub fn new(stream: *mut uvll::uv_stream_t) -> StreamWatcher { unsafe { uvll::set_data_for_uv_handle(stream, 0 as *mut int) } </del> <ins> pub fn new(stream: *mut uvll::uv_stream_t, init: bool) -> StreamWatcher { if init { unsafe { uvll::set_data_for_uv_handle(stream, 0 as *mut int) } } </ins> StreamWatcher { handle: stream, last_write_req: None,


Question:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

let handle = UvHandle::alloc(None::<TtyWatcher>, uvll::UV_TTY); let mut watcher = TtyWatcher { tty: handle, <del> stream: StreamWatcher::new(handle), </del> <ins> stream: StreamWatcher::new(handle, true), </ins> home: io.make_handle(), fd: fd, };


Question:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

rx2.recv(); }) <ins> iotest!(fn clone_while_reading() { let addr = next_test_ip6(); let listen = TcpListener::bind(addr.ip.to_str().as_slice(), addr.port); let mut accept = listen.listen().unwrap(); // Enqueue a task to write to a socket let (tx, rx) = channel(); let (txdone, rxdone) = channel(); let txdone2 = txdone.clone(); spawn(proc() { let mut tcp = TcpStream::connect(addr.ip.to_str().as_slice(), addr.port).unwrap(); rx.recv(); tcp.write_u8(0).unwrap(); txdone2.send(()); }); // Spawn off a reading clone let tcp = accept.accept().unwrap(); let tcp2 = tcp.clone(); let txdone3 = txdone.clone(); spawn(proc() { let mut tcp2 = tcp2; tcp2.read_u8().unwrap(); txdone3.send(()); }); // Try to ensure that the reading clone is indeed reading for _ in range(0i, 50) { ::task::deschedule(); } // clone the handle again while it's reading, then let it finish the // read. let _ = tcp.clone(); tx.send(()); rxdone.recv(); rxdone.recv(); }) </ins> }


Question:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

use std::io::timer; use mem; <del> let mut tb = TaskBuilder::new(); </del> <ins> let tb = TaskBuilder::new(); </ins> let rx = tb.try_future(proc() {}); mem::drop(rx); timer::sleep(1000);


Question:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

gimli.debug = 0 miniz_oxide.debug = 0 object.debug = 0 <ins> rustc-demangle.debug = 0 </ins> # These are very thin wrappers around executing lld with the right binary name. # Basically nothing within them can go wrong without having been explicitly logged anyway.


Question:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

<del> use crate::ffi::OsStr; </del> <ins> use crate::ffi::{OsStr, OsString}; </ins> use crate::fmt; use crate::io; <del> use crate::marker::PhantomData; </del> use crate::num::NonZero; use crate::path::Path; use crate::sys::fs::File;


Question:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

//////////////////////////////////////////////////////////////////////////////// pub struct Command { <ins> program: OsString, args: Vec<OsString>, </ins> env: CommandEnv, <ins> cwd: Option<OsString>, stdin: Option<Stdio>, stdout: Option<Stdio>, stderr: Option<Stdio>, </ins> } // passed back to std::process with the pipes connected to the child, if any


Question:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

pub stderr: Option<AnonPipe>, } <del> // FIXME: This should be a unit struct, so we can always construct it // The value here should be never used, since we cannot spawn processes. </del> <ins> #[derive(Debug)] </ins> pub enum Stdio { Inherit, Null, MakePipe, <ins> ParentStdout, ParentStderr, #[allow(dead_code)] // This variant exists only for the Debug impl InheritFile(File), </ins> } impl Command { <del> pub fn new(_program: &OsStr) -> Command { Command { env: Default::default() } </del> <ins> pub fn new(program: &OsStr) -> Command { Command { program: program.to_owned(), args: vec![program.to_owned()], env: Default::default(), cwd: None, stdin: None, stdout: None, stderr: None, } </ins> } <del> pub fn arg(&mut self, _arg: &OsStr) {} </del> <ins> pub fn arg(&mut self, arg: &OsStr) { self.args.push(arg.to_owned()); } </ins> pub fn env_mut(&mut self) -> &mut CommandEnv { &mut self.env } <del> pub fn cwd(&mut self, _dir: &OsStr) {} </del> <ins> pub fn cwd(&mut self, dir: &OsStr) { self.cwd = Some(dir.to_owned()); } </ins> <del> pub fn stdin(&mut self, _stdin: Stdio) {} </del> <ins> pub fn stdin(&mut self, stdin: Stdio) { self.stdin = Some(stdin); } </ins> <del> pub fn stdout(&mut self, _stdout: Stdio) {} </del> <ins> pub fn stdout(&mut self, stdout: Stdio) { self.stdout = Some(stdout); } </ins> <del> pub fn stderr(&mut self, _stderr: Stdio) {} </del> <ins> pub fn stderr(&mut self, stderr: Stdio) { self.stderr = Some(stderr); } </ins> pub fn get_program(&self) -> &OsStr { <del> panic!("unsupported") </del> <ins> &self.program </ins> } pub fn get_args(&self) -> CommandArgs<'_> { <del> CommandArgs { _p: PhantomData } </del> <ins> let mut iter = self.args.iter(); iter.next(); CommandArgs { iter } </ins> } pub fn get_envs(&self) -> CommandEnvs<'_> {


Question:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

} pub fn get_current_dir(&self) -> Option<&Path> { <del> None </del> <ins> self.cwd.as_ref().map(|cs| Path::new(cs)) </ins> } pub fn spawn(


Question:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

impl From<io::Stdout> for Stdio { fn from(_: io::Stdout) -> Stdio { <del> // FIXME: This is wrong. // Instead, the Stdio we have here should be a unit struct. panic!("unsupported") </del> <ins> Stdio::ParentStdout </ins> } } impl From<io::Stderr> for Stdio { fn from(_: io::Stderr) -> Stdio { <del> // FIXME: This is wrong. // Instead, the Stdio we have here should be a unit struct. panic!("unsupported") </del> <ins> Stdio::ParentStderr </ins> } } impl From<File> for Stdio { <del> fn from(_file: File) -> Stdio { // FIXME: This is wrong. // Instead, the Stdio we have here should be a unit struct. panic!("unsupported") </del> <ins> fn from(file: File) -> Stdio { Stdio::InheritFile(file) </ins> } } impl fmt::Debug for Command { <del> fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) </del> <ins> // show all attributes fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { let mut debug_command = f.debug_struct("Command"); debug_command.field("program", &self.program).field("args", &self.args); if !self.env.is_unchanged() { debug_command.field("env", &self.env); } if self.cwd.is_some() { debug_command.field("cwd", &self.cwd); } if self.stdin.is_some() { debug_command.field("stdin", &self.stdin); } if self.stdout.is_some() { debug_command.field("stdout", &self.stdout); } if self.stderr.is_some() { debug_command.field("stderr", &self.stderr); } debug_command.finish() } else { if let Some(ref cwd) = self.cwd { write!(f, "cd {cwd:?} && ")?; } if self.env.does_clear() { write!(f, "env -i ")?; // Altered env vars will be printed next, that should exactly work as expected. } else { // Removed env vars need the command to be wrapped in `env`. let mut any_removed = false; for (key, value_opt) in self.get_envs() { if value_opt.is_none() { if !any_removed { write!(f, "env ")?; any_removed = true; } write!(f, "-u {} ", key.to_string_lossy())?; } } } // Altered env vars can just be added in front of the program. for (key, value_opt) in self.get_envs() { if let Some(value) = value_opt { write!(f, "{}={value:?} ", key.to_string_lossy())?; } } if self.program != self.args[0] { write!(f, "[{:?}] ", self.program)?; } write!(f, "{:?}", self.args[0])?; for arg in &self.args[1..] { write!(f, " {:?}", arg)?; } Ok(()) } </ins> } }


Question:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

} pub struct CommandArgs<'a> { <del> _p: PhantomData<&'a ()>, </del> <ins> iter: crate::slice::Iter<'a, OsString>, </ins> } impl<'a> Iterator for CommandArgs<'a> { type Item = &'a OsStr; fn next(&mut self) -> Option<&'a OsStr> { <del> None </del> <ins> self.iter.next().map(|os| &**os) </ins> } fn size_hint(&self) -> (usize, Option<usize>) { <del> (0, Some(0)) </del> <ins> self.iter.size_hint() </ins> } } <del> impl<'a> ExactSizeIterator for CommandArgs<'a> {} </del> <ins> impl<'a> ExactSizeIterator for CommandArgs<'a> { fn len(&self) -> usize { self.iter.len() } fn is_empty(&self) -> bool { self.iter.is_empty() } } </ins> impl<'a> fmt::Debug for CommandArgs<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { <del> f.debug_list().finish() </del> <ins> f.debug_list().entries(self.iter.clone()).finish() </ins> } }


Question:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

rustup toolchain install --profile minimal nightly-${TOOLCHAIN} # Sanity check to see if the nightly exists echo nightly-${TOOLCHAIN} > rust-toolchain <del> echo "=> Uninstalling all old nighlies" </del> <ins> echo "=> Uninstalling all old nightlies" </ins> for nightly in $(rustup toolchain list | grep nightly | grep -v $TOOLCHAIN | grep -v nightly-x86_64); do rustup toolchain uninstall $nightly done


Question:
The expansion of and both currently cause code to fail the stability check because they expand to reveal unstable implementation details. A seemingly reasonable solution to this would be to just not run the analysis on any code that has been macro-expanded. cc
I definitely agree with this approach: we should be able to annotate a macro with a stability level, and that's what should count for its users. Do we have a way of telling what part of an AST was generated via macro expansion by the time we get to linting?
Mostly; there's the field of a : for normal code, for macro generated code (basically containing the backtrace of macro invocations that led to that point).
OK, that makes this sound like a pretty easy fix. I'll take a quick look at it tomorrow (unless wants to?)
Hm, this seems slightly subtle, since the contents of a macro would then never be checked for stability. This differs to a conventional function, e.g. given , won't warn, but the contents of is still checked, while where is just never checked. (Of course, macros and phasing are both feature gated so you have to opt-in to instability to use non-standard macros anyway.)
Good point. Also, it looks tricky with the current infrastructure to even lint on the macro invocation -- the backtrace of macro expansion does not appear to link to the def_id of the macro (or give any other way of getting at the macro's stability). Nevertheless, I think we should bail out of the lint when we hit the results of expansion; those should be checked, if anywhere, at the site of macro definition. One other question: do syntax extensions also produce the span information you mentioned above? I ask because original problematic cases are written syntax extensions. If not, is there some other way of telling that an expansion happened?
I have a patch ready that bails of out the lint on expanded code. This also seems to mask uses of . If y'all are ok with this strategy for now, I'll file a PR.
Sounds good to me. Thanks!
cc

} fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { <ins> // if the expression was produced by a macro expansion, if e.span.expn_info.is_some() { return } </ins> let id = match e.node { ast::ExprPath(..) | ast::ExprStruct(..) => { match cx.tcx.def_map.borrow().find(&e.id) {


Question:
The expansion of and both currently cause code to fail the stability check because they expand to reveal unstable implementation details. A seemingly reasonable solution to this would be to just not run the analysis on any code that has been macro-expanded. cc
I definitely agree with this approach: we should be able to annotate a macro with a stability level, and that's what should count for its users. Do we have a way of telling what part of an AST was generated via macro expansion by the time we get to linting?
Mostly; there's the field of a : for normal code, for macro generated code (basically containing the backtrace of macro invocations that led to that point).
OK, that makes this sound like a pretty easy fix. I'll take a quick look at it tomorrow (unless wants to?)
Hm, this seems slightly subtle, since the contents of a macro would then never be checked for stability. This differs to a conventional function, e.g. given , won't warn, but the contents of is still checked, while where is just never checked. (Of course, macros and phasing are both feature gated so you have to opt-in to instability to use non-standard macros anyway.)
Good point. Also, it looks tricky with the current infrastructure to even lint on the macro invocation -- the backtrace of macro expansion does not appear to link to the def_id of the macro (or give any other way of getting at the macro's stability). Nevertheless, I think we should bail out of the lint when we hit the results of expansion; those should be checked, if anywhere, at the site of macro definition. One other question: do syntax extensions also produce the span information you mentioned above? I ask because original problematic cases are written syntax extensions. If not, is there some other way of telling that an expansion happened?
I have a patch ready that bails of out the lint on expanded code. This also seems to mask uses of . If y'all are ok with this strategy for now, I'll file a PR.
Sounds good to me. Thanks!
cc

#![crate_id="lint_stability#0.1"] #![crate_type = "lib"] <ins> #![feature(macro_rules)] #![macro_escape] </ins> #[deprecated] pub fn deprecated() {} #[deprecated="text"]


Question:
The expansion of and both currently cause code to fail the stability check because they expand to reveal unstable implementation details. A seemingly reasonable solution to this would be to just not run the analysis on any code that has been macro-expanded. cc
I definitely agree with this approach: we should be able to annotate a macro with a stability level, and that's what should count for its users. Do we have a way of telling what part of an AST was generated via macro expansion by the time we get to linting?
Mostly; there's the field of a : for normal code, for macro generated code (basically containing the backtrace of macro invocations that led to that point).
OK, that makes this sound like a pretty easy fix. I'll take a quick look at it tomorrow (unless wants to?)
Hm, this seems slightly subtle, since the contents of a macro would then never be checked for stability. This differs to a conventional function, e.g. given , won't warn, but the contents of is still checked, while where is just never checked. (Of course, macros and phasing are both feature gated so you have to opt-in to instability to use non-standard macros anyway.)
Good point. Also, it looks tricky with the current infrastructure to even lint on the macro invocation -- the backtrace of macro expansion does not appear to link to the def_id of the macro (or give any other way of getting at the macro's stability). Nevertheless, I think we should bail out of the lint when we hit the results of expansion; those should be checked, if anywhere, at the site of macro definition. One other question: do syntax extensions also produce the span information you mentioned above? I ask because original problematic cases are written syntax extensions. If not, is there some other way of telling that an expansion happened?
I have a patch ready that bails of out the lint on expanded code. This also seems to mask uses of . If y'all are ok with this strategy for now, I'll file a PR.
Sounds good to me. Thanks!
cc

pub struct FrozenTupleStruct(pub int); #[locked] pub struct LockedTupleStruct(pub int); <ins> #[macro_export] macro_rules! macro_test( () => (deprecated()); ) </ins>