Question:
While checkout out this ice (which does not require a feature gate btw, so potential beta-to-stable regression, which is inconvenient <!-- ICE: Rustc '' 'error: internal compiler error: unsupported pattern for pattern type: Pat {', 'error: internal compiler error: unsupported pattern for pattern type: Pat {' File: --snippet: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [typeof] expanding type alias [checkwellformed] checking that is well-formed [checkmodtypewf] checking that types are well-formed in top-level module [analysis] running analysis passes on this crate --I clicked the tracking issue from = note: see issue more information = help: add to the crate attributes to enable = note: this compiler was built on 2024-04-08; consider upgrading it if it is out of date which is about an attribute and does not mention patterns or links to a related PR at all? :thinking:
What do you mean? Why would this beta a beta-to-stable regression? It regressed with .
cc pattern types need a real tracking issue, and you need to delay a span bug here rather than ICE
right now: beta -nightly regression once nightly gets promoted to beta: stable -beta regression once beta gets promoted to stable: stable -stable regression?
yes? but you can say that about every single regression that ever gets filed lol
exactly, unless it gets fixed in time :)
I don't see the purpose of pointing out that this is a potential beta regression before it has even landed on nightly, unless there's some reason that this is particularly difficult to fix, particularly affects user-facing code, or we expect it to slip the beta promotion for some reason.
Well, there are a few cases where feature gates actually do work and prevent crashes on stable
maybe internal features should just hard abort compilation if they aren't set
might also solve some of the internal-feature ices we are getting from time to time
...I do not see how it would be a regression, because we can safely bet on no one requiring the macro before the feature's library API landed. The code did not travel back in time to 1.77 compilers and suddenly become usable stable API.
its a regression because the compiler now crashes/ICEs where it would previously just show an error message.
please show me the codebase that regressed.
code that was not committed until April 8th, thus incapable of regressing on stable, yes.
ah yes not yet. this is why I wrote ;)
If it arrived on 1.79 on stable, it would be code that, since the moment it has been useful to write, has always ICEd. 1.79 cannot retrocausally regress code, unless you have a TARDIS or somesuch.
I it was code that did not ICE on 1.78, and now ICEs on 1.79, so that makes it a regression.
It was code that did not exist in this world on 1.78. It didn't exist in some timeless platonic realm of Forms. No actual programs were harmed in the making of this music video.
I suppose if you insist we can call them "regressions" when they involve code samples that just came into being, but I wish to know what I should call it when my actual tests fail from version to version of rustc and I have to spend hours bisecting the issue and figuring out where in the codebase it has gone wrong and fixing the problem before the new version comes out, either in the code or in rustc. Because it sure isn't a just-fabricated problem with just-fabricated code, it's something that matters in code that is supposed to build and work on the latest stable Rust version.
What it is is a feature gated feature ICEing without the feature gate, so we would see it ICE on stable if untreated. This means it is a higher priority ICE than an ICE that is only reachable with feature gates. We have not used "regression" as a term for "error -ICE" changes, as by definition that'a true for any ICE that does not require feature gates. If we flagged it as a regression, that would flood and taint the actually problematic regressions. We do flag these as regressions if there is no error before the ICE, as the user then has no information on how to fix it. So while is technically correct, in practice we don't and shouldn't use this terminology

<ins> //! This test ensures we do not ICE for unimplemented //! patterns unless the feature gate is enabled. #![feature(core_pattern_type)] #![feature(core_pattern_types)] use std::pat::pattern_type; type Always = pattern_type!(Option<u32> is Some(_)); //~^ ERROR: pattern types are unstable type Binding = pattern_type!(Option<u32> is x); //~^ ERROR: pattern types are unstable fn main() {} </ins>


Question:
While checkout out this ice (which does not require a feature gate btw, so potential beta-to-stable regression, which is inconvenient <!-- ICE: Rustc '' 'error: internal compiler error: unsupported pattern for pattern type: Pat {', 'error: internal compiler error: unsupported pattern for pattern type: Pat {' File: --snippet: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [typeof] expanding type alias [checkwellformed] checking that is well-formed [checkmodtypewf] checking that types are well-formed in top-level module [analysis] running analysis passes on this crate --I clicked the tracking issue from = note: see issue more information = help: add to the crate attributes to enable = note: this compiler was built on 2024-04-08; consider upgrading it if it is out of date which is about an attribute and does not mention patterns or links to a related PR at all? :thinking:
What do you mean? Why would this beta a beta-to-stable regression? It regressed with .
cc pattern types need a real tracking issue, and you need to delay a span bug here rather than ICE
right now: beta -nightly regression once nightly gets promoted to beta: stable -beta regression once beta gets promoted to stable: stable -stable regression?
yes? but you can say that about every single regression that ever gets filed lol
exactly, unless it gets fixed in time :)
I don't see the purpose of pointing out that this is a potential beta regression before it has even landed on nightly, unless there's some reason that this is particularly difficult to fix, particularly affects user-facing code, or we expect it to slip the beta promotion for some reason.
Well, there are a few cases where feature gates actually do work and prevent crashes on stable
maybe internal features should just hard abort compilation if they aren't set
might also solve some of the internal-feature ices we are getting from time to time
...I do not see how it would be a regression, because we can safely bet on no one requiring the macro before the feature's library API landed. The code did not travel back in time to 1.77 compilers and suddenly become usable stable API.
its a regression because the compiler now crashes/ICEs where it would previously just show an error message.
please show me the codebase that regressed.
code that was not committed until April 8th, thus incapable of regressing on stable, yes.
ah yes not yet. this is why I wrote ;)
If it arrived on 1.79 on stable, it would be code that, since the moment it has been useful to write, has always ICEd. 1.79 cannot retrocausally regress code, unless you have a TARDIS or somesuch.
I it was code that did not ICE on 1.78, and now ICEs on 1.79, so that makes it a regression.
It was code that did not exist in this world on 1.78. It didn't exist in some timeless platonic realm of Forms. No actual programs were harmed in the making of this music video.
I suppose if you insist we can call them "regressions" when they involve code samples that just came into being, but I wish to know what I should call it when my actual tests fail from version to version of rustc and I have to spend hours bisecting the issue and figuring out where in the codebase it has gone wrong and fixing the problem before the new version comes out, either in the code or in rustc. Because it sure isn't a just-fabricated problem with just-fabricated code, it's something that matters in code that is supposed to build and work on the latest stable Rust version.
What it is is a feature gated feature ICEing without the feature gate, so we would see it ICE on stable if untreated. This means it is a higher priority ICE than an ICE that is only reachable with feature gates. We have not used "regression" as a term for "error -ICE" changes, as by definition that'a true for any ICE that does not require feature gates. If we flagged it as a regression, that would flood and taint the actually problematic regressions. We do flag these as regressions if there is no error before the ICE, as the user then has no information on how to fix it. So while is technically correct, in practice we don't and shouldn't use this terminology

<ins> error[E0658]: pattern types are unstable --> $DIR/unimplemented_pat.rs:9:15 | LL | type Always = pattern_type!(Option<u32> is Some(_)); |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information = help: add `#![feature(pattern_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pattern types are unstable --> $DIR/unimplemented_pat.rs:12:16 | LL | type Binding = pattern_type!(Option<u32> is x); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information = help: add `#![feature(pattern_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. </ins>


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: Unexpected coroutine/closure type in variance computation', 'error: internal compiler error: Unexpected coroutine/closure type in variance computation' 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: [cratevariances] computing the variances for items in this crate [variancesof] computing the variances of [mirborrowck] borrow-checking [analysis] running analysis passes on this crate --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
smaller
ice since it seems
i can look into this claim

// Don't leak types into signatures unless they're nameable! // For example, if a function returns itself, we don't want that // recursive function definition to leak out into the fn sig. <del> let mut should_recover = false; </del> <ins> let mut recovered_ret_ty = None; </ins> <del> if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false, None) { </del> <ins> if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) { </ins> diag.span_suggestion( ty.span, "replace with the correct return type", <del> ret_ty, </del> <ins> suggestable_ret_ty, </ins> Applicability::MachineApplicable, ); <del> should_recover = true; </del> <ins> recovered_ret_ty = Some(suggestable_ret_ty); </ins> } else if let Some(sugg) = suggest_impl_trait(&tcx.infer_ctxt().build(), tcx.param_env(def_id), ret_ty) {


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: Unexpected coroutine/closure type in variance computation', 'error: internal compiler error: Unexpected coroutine/closure type in variance computation' 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: [cratevariances] computing the variances for items in this crate [variancesof] computing the variances of [mirborrowck] borrow-checking [analysis] running analysis passes on this crate --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
smaller
ice since it seems
i can look into this claim

} let guar = diag.emit(); <del> if should_recover { ty::Binder::dummy(fn_sig) } else { ty::Binder::dummy(tcx.mk_fn_sig( fn_sig.inputs().iter().copied(), Ty::new_error(tcx, guar), fn_sig.c_variadic, fn_sig.unsafety, fn_sig.abi, )) } </del> <ins> ty::Binder::dummy(tcx.mk_fn_sig( fn_sig.inputs().iter().copied(), recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)), fn_sig.c_variadic, fn_sig.unsafety, fn_sig.abi, )) </ins> } None => icx.lowerer().lower_fn_ty( hir_id,


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: Unexpected coroutine/closure type in variance computation', 'error: internal compiler error: Unexpected coroutine/closure type in variance computation' 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: [cratevariances] computing the variances for items in this crate [variancesof] computing the variances of [mirborrowck] borrow-checking [analysis] running analysis passes on this crate --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
smaller
ice since it seems
i can look into this claim

} ty::FnDef(..) | ty::Coroutine(..) | ty::Closure(..) | ty::CoroutineClosure(..) => { <del> bug!("Unexpected coroutine/closure type in variance computation"); </del> <ins> bug!("Unexpected unnameable type in variance computation: {ty}"); </ins> } ty::Ref(region, ty, mutbl) => {


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: Unexpected coroutine/closure type in variance computation', 'error: internal compiler error: Unexpected coroutine/closure type in variance computation' 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: [cratevariances] computing the variances for items in this crate [variancesof] computing the variances of [mirborrowck] borrow-checking [analysis] running analysis passes on this crate --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
smaller
ice since it seems
i can look into this claim

<ins> // Test variance computation doesn't explode when we leak unnameable // types due to `-> _` recovery. pub struct Type<'a>(&'a ()); pub fn g() {} pub fn f<T>() -> _ { //~^ ERROR the placeholder `_` is not allowed within types on item signatures g } fn main() {} </ins>


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: Unexpected coroutine/closure type in variance computation', 'error: internal compiler error: Unexpected coroutine/closure type in variance computation' 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: [cratevariances] computing the variances for items in this crate [variancesof] computing the variances of [mirborrowck] borrow-checking [analysis] running analysis passes on this crate --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
smaller
ice since it seems
i can look into this claim

<ins> error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/leaking-unnameables.rs:8:18 | LL | pub fn f<T>() -> _ { |                  ^ |                  | |                  not allowed in type signatures |                  help: replace with the correct return type: `fn()` error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0121`. </ins>


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm, ComputedLtoType, OngoingCodegen, }; use crate::common::{self, IntPredicate, RealPredicate, TypeKind}; <ins> use crate::meth::load_vtable; </ins> use crate::mir::operand::OperandValue; use crate::mir::place::PlaceRef; use crate::traits::*;


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

if let Some(entry_idx) = vptr_entry_idx { let ptr_size = bx.data_layout().pointer_size; <del> let ptr_align = bx.data_layout().pointer_align.abi; </del> let vtable_byte_offset = u64::try_from(entry_idx).unwrap() * ptr_size.bytes(); <del> let gep = bx.inbounds_ptradd(old_info, bx.const_usize(vtable_byte_offset)); let new_vptr = bx.load(bx.type_ptr(), gep, ptr_align); bx.nonnull_metadata(new_vptr); // VTable loads are invariant. bx.set_invariant_load(new_vptr); new_vptr </del> <ins> load_vtable(bx, old_info, bx.type_ptr(), vtable_byte_offset, source, true) </ins> } else { old_info }


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

let llty = bx.fn_ptr_backend_type(fn_abi); let ptr_size = bx.data_layout().pointer_size; <del> let ptr_align = bx.data_layout().pointer_align.abi; </del> let vtable_byte_offset = self.0 * ptr_size.bytes(); <del> if bx.cx().sess().opts.unstable_opts.virtual_function_elimination && bx.cx().sess().lto() == Lto::Fat { let typeid = bx .typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty))) .unwrap(); let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); func } else { let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset)); let ptr = bx.load(llty, gep, ptr_align); // VTable loads are invariant. bx.set_invariant_load(ptr); if nonnull { bx.nonnull_metadata(ptr); } ptr } </del> <ins> load_vtable(bx, llvtable, llty, vtable_byte_offset, ty, nonnull) </ins> } pub(crate) fn get_optional_fn<Bx: BuilderMethods<'a, 'tcx>>(


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

self, bx: &mut Bx, llvtable: Bx::Value, <ins> ty: Ty<'tcx>, </ins> ) -> Bx::Value { // Load the data pointer from the object. debug!("get_int({:?}, {:?})", llvtable, self); let llty = bx.type_isize(); let ptr_size = bx.data_layout().pointer_size; <del> let ptr_align = bx.data_layout().pointer_align.abi; </del> let vtable_byte_offset = self.0 * ptr_size.bytes(); <del> let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset)); let ptr = bx.load(llty, gep, ptr_align); // VTable loads are invariant. bx.set_invariant_load(ptr); ptr </del> <ins> load_vtable(bx, llvtable, llty, vtable_byte_offset, ty, false) </ins> } } /// This takes a valid `self` receiver type and extracts the principal trait <del> /// ref of the type. fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> { </del> <ins> /// ref of the type. Return `None` if there is no principal trait. fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> { </ins> for arg in ty.peel_refs().walk() { if let GenericArgKind::Type(ty) = arg.unpack() && let ty::Dynamic(data, _, _) = ty.kind() { <del> return data.principal().expect("expected principal trait object"); </del> <ins> return data.principal(); </ins> } }


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

cx.vtables().borrow_mut().insert((ty, trait_ref), vtable); vtable } <ins> /// Call this function whenever you need to load a vtable. pub(crate) fn load_vtable<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, llvtable: Bx::Value, llty: Bx::Type, vtable_byte_offset: u64, ty: Ty<'tcx>, nonnull: bool, ) -> Bx::Value { let ptr_align = bx.data_layout().pointer_align.abi; if bx.cx().sess().opts.unstable_opts.virtual_function_elimination && bx.cx().sess().lto() == Lto::Fat { if let Some(trait_ref) = dyn_trait_in_self(ty) { let typeid = bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref)).unwrap(); let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); return func; } else if nonnull { bug!("load nonnull value from a vtable without a principal trait") } } let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset)); let ptr = bx.load(llty, gep, ptr_align); // VTable loads are invariant. bx.set_invariant_load(ptr); if nonnull { bx.nonnull_metadata(ptr); } ptr } </ins>


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

sym::vtable_align => ty::COMMON_VTABLE_ENTRIES_ALIGN, _ => bug!(), }; <del> let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable); </del> <ins> let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable, callee_ty); </ins> match name { // Size is always <= isize::MAX. sym::vtable_size => {


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

// Load size/align from vtable. let vtable = info.unwrap(); let size = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_SIZE) <del> .get_usize(bx, vtable); </del> <ins> .get_usize(bx, vtable, t); </ins> let align = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_ALIGN) <del> .get_usize(bx, vtable); </del> <ins> .get_usize(bx, vtable, t); </ins> // Size is always <= isize::MAX. let size_bound = bx.data_layout().ptr_sized_integer().signed_max() as u128;


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

<del> //@ known-bug: #123955 //@ compile-flags: -Clto -Zvirtual-function-elimination //@ only-x86_64 pub fn main() { _ = Box::new(()) as Box<dyn Send>; } </del>


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

<del> //@ known-bug: #124092 //@ compile-flags: -Zvirtual-function-elimination=true -Clto=true //@ only-x86_64 const X: for<'b> fn(&'b ()) = |&()| (); fn main() { let dyn_debug = Box::new(X) as Box<fn(&'static ())> as Box<dyn Send>; } </del>


Question:
This happens when compiling the crate with . : The backtrace and output here are obtained during cross-compilation (host , target , build-std), but the panic also happens when the host is Windows and without build-std. <details<summary<strongBacktrace</strong</summary<p</p</details
Minimized:

<ins> //@ build-pass //@ compile-flags: -Zvirtual-function-elimination=true -Clto=true //@ only-x86_64 //@ no-prefer-dynamic // issue #123955 pub fn test0() { _ = Box::new(()) as Box<dyn Send>; } // issue #124092 const X: for<'b> fn(&'b ()) = |&()| (); pub fn test1() { let _dyn_debug = Box::new(X) as Box<fn(&'static ())> as Box<dyn Send>; } fn main() {} </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 in Alpine Linux cross compiled to : For reference I ran this in a container on an M1 Macbook: I always see printed, even when I pass the program arguments. I'm not sure this is an issue with the environment as the following C program works as expected: :
uh.
Could you clarify: Does this problem arise with code ran on an ordinary gnu system? Say, a Debian container? Or itself?
I can take a guess at why this happens. For glibc targets we assume that the arguments can be retrieved without needing to store and . However if this musl compatibility layer doesn't use the then we can't retrieve them.
Ah yeah, it seems that behavior is a GNU extension that Rich Felker doesn't want to support?
Does just not work at all on musl if we're a cdylib, then?
Correct. When libstd's start function isn't used, only works on Windows, macOS and Linux with Glibc. On any other target it returns an empty list.
Apparently we already have this comment: In other words, we are already hacking around this issue for the miri emulator, and not using the fact that we are still given argv "naturally" via execve. We should probably just unconditionally call .
That would fix on Linux + glibc too.
Note that this was intentionally done but there have been other issues
I still think we can consider to still be fixed, as we just get our and it will be the same thing, even if the s behind the have been rearranged, right? So we'll set the atomics twice to the same value, which sounds very Working As Intended.
— in Well, given the remarks here seem to position this as a "wouldn't it be nice if we didn't do extra work?" and that this seems to be non-resilient in practice, as it has caused more than one open issue, I think we should be unafraid of doing a bit of extra computation.
I more meant that the fact that libraries mess about with (what should be) immutable memory is a safety issue so ideally we would parse it at the point where it's least likely that the are multiple threads. But people would probably complain about doing unnecessary allocating and extra work pre-main. Just storing argc and argv should be cheap though so I'm definitely not arguing against that.
the dilemma: strictly conforming posix programs shouldn't mutate argc and argv, but strictly conforming posix programs also shouldn't be aware of argc and argv if if they're dylibs, eh?
Could we check, first, whether we've already had these initialized, and only call this in the unusual case where they're not initialized? That would avoid the extra work in the common case, and do the work in the unusual case.
I don't know what you mean? We aren't doing substantial extra work. The thing that costs the most in runtime startup, I expect, is having the static initializer at all, which we then don't get to make choices about whether its called. It simply is or isn't.
Nevermind: ; forgot that was just saving off the values and not doing anything with them.

} #[inline(always)] <del> pub unsafe fn init(_argc: isize, _argv: *const *const u8) { // On Linux-GNU, we rely on `ARGV_INIT_ARRAY` below to initialize // `ARGC` and `ARGV`. But in Miri that does not actually happen so we // still initialize here. #[cfg(any(miri, not(all(target_os = "linux", target_env = "gnu"))))] really_init(_argc, _argv); </del> <ins> pub unsafe fn init(argc: isize, argv: *const *const u8) { // on GNU/Linux if we are main then we will init argv and argc twice, it "duplicates work" // BUT edge-cases are real: only using .init_array can break most emulators, dlopen, etc. really_init(argc, argv); </ins> } /// glibc passes argc, argv, and envp to functions in .init_array, as a non-standard extension.


Question: As of current nightly, produces this: which is not valid Rust syntax. The correct output would contain . tracking issue:

self.space(); } MatchKind::Postfix => { <del> self.print_expr_as_cond(expr); </del> <ins> self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup); </ins> self.word_nbsp(".match"); } }


Question: As of current nightly, produces this: which is not valid Rust syntax. The correct output would contain . tracking issue:

<del> #![feature(postfix_match)] fn main() { let val = Some(42); val.match { Some(_) => 2, _ => 1 }; Some(2).match { Some(_) => true, None => false }.match { false => "ferris is cute", true => "I turn cats in to petted cats", }.match { _ => (), } } </del>


Question: As of current nightly, produces this: which is not valid Rust syntax. The correct output would contain . tracking issue:

<ins> #![feature(prelude_import)] #![no_std] #![feature(postfix_match)] #[prelude_import] use ::std::prelude::rust_2015::*; #[macro_use] extern crate std; use std::ops::Add; //@ pretty-mode:expanded //@ pp-exact:precedence.pp macro_rules! repro { ($e:expr) => { $e.match { _ => {} } }; } struct Struct {} impl Add<Struct> for usize { type Output = (); fn add(self, _: Struct) -> () { () } } pub fn main() { let a; ( { 1 } + 1).match { _ => {} }; (4 as usize).match { _ => {} }; (return).match { _ => {} }; (a = 42).match { _ => {} }; (|| {}).match { _ => {} }; (42..101).match { _ => {} }; (1 + Struct {}).match { _ => {} }; } </ins>


Question: As of current nightly, produces this: which is not valid Rust syntax. The correct output would contain . tracking issue:

<ins> #![feature(postfix_match)] use std::ops::Add; //@ pretty-mode:expanded //@ pp-exact:precedence.pp macro_rules! repro { ($e:expr) => { $e.match { _ => {} } }; } struct Struct {} impl Add<Struct> for usize { type Output = (); fn add(self, _: Struct) -> () { () } } pub fn main() { let a; repro!({ 1 } + 1); repro!(4 as usize); repro!(return); repro!(a = 42); repro!(|| {}); repro!(42..101); repro!(1 + Struct {}); } </ins>


Question: As of current nightly, produces this: which is not valid Rust syntax. The correct output would contain . tracking issue:

<ins> #![feature(postfix_match)] fn main() { let val = Some(42); val.match { Some(_) => 2, _ => 1 }; Some(2).match { Some(_) => true, None => false }.match { false => "ferris is cute", true => "I turn cats in to petted cats", }.match { _ => (), } } </ins>


Question:
Sometimes when things go really wrong the compiler emits a ton of error messages. This can actually take a while to render them all. And since somewhat recently, hitting Ctrl-C no longer interrupts that, I get a thousand error messages displayed after Ctrl-C. I suspect this may have to do with The Ctrl-C handler does nothing at all on the first Ctrl-C unless the compiler is in the middle of const-eval. Cc
Do you have a reproducer? I have not run into this myself. The implementation should also ensure that the compiler exits promptly if you hit ctrl+c again. Does it?
if stuff keeps going on ctrl+c, sometimes suspending the process (ctrl+z) and then killing the terminal does the trick somehow :sweat_smile:
Unfortunately no, I encountered this during some rustc hacking where I ended up getting well over 1k error messages in the standard library build and that turned out to be hard to cancel. I thought I had tried that, but I am not entirely sure.
Is it possible the shell is part of the problem? If, by the time you hit ctrl-c, it's working through a large amount of output it still has buffered then it might be awhile before you see a response.
It's possible, sure -- but usually it reacts to Ctrl-C immediately even when there's tons of output.
Have you tried reverting to check if that fixes it?
No. At the time I was busy getting a PR done and now I don't have a reproducing example any more.
only checks for ctrl-c during const eval, so if no const eval runs for an extended period of time, the ctrl-c will be silently ignored. This is not the only problem with that PR. It also caused , and shows the "compilation was interrupted" error after the prompt is already drawn by bash.
is there a good way to make rustc loop endlessly without ever touching const eval? maybe via the trait solver? :thinking: it would help for debugging this.
Yeah, just take any issue (none are anyway). I can reproduce this issue with for example: nightly-2024-03-26 (before ): Exits after a single ^C nightly-2024-03-27 (after ): Requires ^C^C to exit bjorn3's analysis checks out.
cool! I wasn't sure how much of the compiler's code flowed through const-eval, is why I asked.
Another case where this is observed: IMO we should revert or at least make the signal handler run after a short timeout.
I'll post a PR that adds a timeout later today, but by all means if you feel strongly just put up a PR. The initial handler here was just through the normal PR process, there's no reason to be more cautious on reverting or modifying it.

use std::str; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, OnceLock}; <del> use std::time::{Instant, SystemTime}; </del> <ins> use std::time::{Duration, Instant, SystemTime}; </ins> use time::OffsetDateTime; use tracing::trace;


Question:
Sometimes when things go really wrong the compiler emits a ton of error messages. This can actually take a while to render them all. And since somewhat recently, hitting Ctrl-C no longer interrupts that, I get a thousand error messages displayed after Ctrl-C. I suspect this may have to do with The Ctrl-C handler does nothing at all on the first Ctrl-C unless the compiler is in the middle of const-eval. Cc
Do you have a reproducer? I have not run into this myself. The implementation should also ensure that the compiler exits promptly if you hit ctrl+c again. Does it?
if stuff keeps going on ctrl+c, sometimes suspending the process (ctrl+z) and then killing the terminal does the trick somehow :sweat_smile:
Unfortunately no, I encountered this during some rustc hacking where I ended up getting well over 1k error messages in the standard library build and that turned out to be hard to cancel. I thought I had tried that, but I am not entirely sure.
Is it possible the shell is part of the problem? If, by the time you hit ctrl-c, it's working through a large amount of output it still has buffered then it might be awhile before you see a response.
It's possible, sure -- but usually it reacts to Ctrl-C immediately even when there's tons of output.
Have you tried reverting to check if that fixes it?
No. At the time I was busy getting a PR done and now I don't have a reproducing example any more.
only checks for ctrl-c during const eval, so if no const eval runs for an extended period of time, the ctrl-c will be silently ignored. This is not the only problem with that PR. It also caused , and shows the "compilation was interrupted" error after the prompt is already drawn by bash.
is there a good way to make rustc loop endlessly without ever touching const eval? maybe via the trait solver? :thinking: it would help for debugging this.
Yeah, just take any issue (none are anyway). I can reproduce this issue with for example: nightly-2024-03-26 (before ): Exits after a single ^C nightly-2024-03-27 (after ): Requires ^C^C to exit bjorn3's analysis checks out.
cool! I wasn't sure how much of the compiler's code flowed through const-eval, is why I asked.
Another case where this is observed: IMO we should revert or at least make the signal handler run after a short timeout.
I'll post a PR that adds a timeout later today, but by all means if you feel strongly just put up a PR. The initial handler here was just through the normal PR process, there's no reason to be more cautious on reverting or modifying it.

pub fn install_ctrlc_handler() { #[cfg(not(target_family = "wasm"))] ctrlc::set_handler(move || { <del> // Indicate that we have been signaled to stop. If we were already signaled, exit // immediately. In our interpreter loop we try to consult this value often, but if for // whatever reason we don't get to that check or the cleanup we do upon finding that // this bool has become true takes a long time, the exit here will promptly exit the // process on the second Ctrl-C. if CTRL_C_RECEIVED.swap(true, Ordering::Relaxed) { std::process::exit(1); } </del> <ins> // Indicate that we have been signaled to stop, then give the rest of the compiler a bit of // time to check CTRL_C_RECEIVED and run its own shutdown logic, but after a short amount // of time exit the process. This sleep+exit ensures that even if nobody is checking // CTRL_C_RECEIVED, the compiler exits reasonably promptly. CTRL_C_RECEIVED.store(true, Ordering::Relaxed); std::thread::sleep(Duration::from_millis(100)); std::process::exit(1); </ins> }) .expect("Unable to install ctrlc handler"); }


Question:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

//! //! The corresponding [`Sync`] version of `OnceCell<T>` is [`OnceLock<T>`]. //! <ins> //! ## `LazyCell<T, F>` //! //! A common pattern with OnceCell is, for a given OnceCell, to use the same function on every //! call to [`OnceCell::get_or_init`] with that cell. This is what is offered by [`LazyCell`], //! which pairs cells of `T` with functions of `F`, and always calls `F` before it yields `&T`. //! This happens implicitly by simply attempting to dereference the LazyCell to get its contents, //! so its use is much more transparent with a place which has been initialized by a constant. //! //! More complicated patterns that don't fit this description can be built on `OnceCell<T>` instead. //! //! `LazyCell` works by providing an implementation of `impl Deref` that calls the function, //! so you can just use it by dereference (e.g. `*lazy_cell` or `lazy_cell.deref()`). //! //! The corresponding [`Sync`] version of `LazyCell<T, F>` is [`LazyLock<T, F>`]. </ins> //! //! # When to choose interior mutability //!


Question:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

//! [`RwLock<T>`]: ../../std/sync/struct.RwLock.html //! [`Mutex<T>`]: ../../std/sync/struct.Mutex.html //! [`OnceLock<T>`]: ../../std/sync/struct.OnceLock.html <ins> //! [`LazyLock<T, F>`]: ../../std/sync/struct.LazyLock.html </ins> //! [`Sync`]: ../../std/marker/trait.Sync.html //! [`atomic`]: crate::sync::atomic


Question:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

/// # Examples /// /// Initialize static variables with `LazyLock`. <del> /// </del> /// ``` <del> /// use std::collections::HashMap; /// </del> /// use std::sync::LazyLock; /// <del> /// static HASHMAP: LazyLock<HashMap<i32, String>> = LazyLock::new(|| { ///     println!("initializing"); ///     let mut m = HashMap::new(); ///     m.insert(13, "Spica".to_string()); ///     m.insert(74, "Hoyten".to_string()); ///     m </del> <ins> /// // n.b. static items do not call [`Drop`] on program termination, so this won't be deallocated. /// // this is fine, as the OS can deallocate the terminated program faster than we can free memory /// // but tools like valgrind might report "memory leaks" as it isn't obvious this is intentional. /// static DEEP_THOUGHT: LazyLock<String> = LazyLock::new(|| { /// # mod another_crate { /// #     pub fn great_question() -> String { "42".to_string() } /// # } ///     // M3 Ultra takes about 16 million years in --release config ///     another_crate::great_question() </ins> /// }); /// <del> /// fn main() { ///     println!("ready"); ///     std::thread::spawn(|| { ///         println!("{:?}", HASHMAP.get(&13)); ///     }).join().unwrap(); ///     println!("{:?}", HASHMAP.get(&74)); /// ///     // Prints: ///     //   ready ///     //   initializing ///     //   Some("Spica") ///     //   Some("Hoyten") /// } </del> <ins> /// // The `String` is built, stored in the `LazyLock`, and returned as `&String`. /// let _ = &*DEEP_THOUGHT; /// // The `String` is retrieved from the `LazyLock` and returned as `&String`. /// let _ = &*DEEP_THOUGHT; </ins> /// ``` <ins> /// </ins> /// Initialize fields with `LazyLock`. /// ``` /// use std::sync::LazyLock;


Question:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

//! - [`Once`]: Used for a thread-safe, one-time global initialization routine //! //! - [`OnceLock`]: Used for thread-safe, one-time initialization of a <del> //!   global variable. </del> <ins> //!   variable, with potentially different initializers based on the caller. //! //! - [`LazyLock`]: Used for thread-safe, one-time initialization of a //!   variable, using one nullary initializer function provided at creation. </ins> //! //! - [`RwLock`]: Provides a mutual exclusion mechanism which allows //!   multiple readers at the same time, while allowing only one


Question:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

/// A synchronization primitive which can be written to only once. /// /// This type is a thread-safe [`OnceCell`], and can be used in statics. <ins> /// In many simple cases, you can use [`LazyLock<T, F>`] instead to get the benefits of this type /// with less effort: `LazyLock<T, F>` "looks like" `&T` because it initializes with `F` on deref! /// Where OnceLock shines is when LazyLock is too simple to support a given case, as LazyLock /// doesn't allow additional inputs to its function after you call [`LazyLock::new(|| ...)`]. </ins> /// /// [`OnceCell`]: crate::cell::OnceCell <ins> /// [`LazyLock<T, F>`]: crate::sync::LazyLock /// [`LazyLock::new(|| ...)`]: crate::sync::LazyLock::new </ins> /// /// # Examples /// <del> /// Using `OnceLock` to store a function’s previously computed value (a.k.a. /// ‘lazy static’ or ‘memoizing’): /// /// ``` /// use std::sync::OnceLock; /// /// struct DeepThought { ///     answer: String, /// } /// /// impl DeepThought { /// #   fn great_question() -> String { /// #       "42".to_string() /// #   } /// # ///     fn new() -> Self { ///         Self { ///             // M3 Ultra takes about 16 million years in --release config ///             answer: Self::great_question(), ///         } ///     } /// } /// /// fn computation() -> &'static DeepThought { ///     // n.b. static items do not call [`Drop`] on program termination, so if ///     // [`DeepThought`] impls Drop, that will not be used for this instance. ///     static COMPUTATION: OnceLock<DeepThought> = OnceLock::new(); ///     COMPUTATION.get_or_init(|| DeepThought::new()) /// } /// /// // The `DeepThought` is built, stored in the `OnceLock`, and returned. /// let _ = computation().answer; /// // The `DeepThought` is retrieved from the `OnceLock` and returned. /// let _ = computation().answer; /// ``` /// </del> /// Writing to a `OnceLock` from a separate thread: /// /// ```


Question:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

///     Some(&12345), /// ); /// ``` <ins> /// /// You can use `OnceLock` to implement a type that requires "append-only" logic: /// /// ``` /// use std::sync::{OnceLock, atomic::{AtomicU32, Ordering}}; /// use std::thread; /// /// struct OnceList<T> { ///     data: OnceLock<T>, ///     next: OnceLock<Box<OnceList<T>>>, /// } /// impl<T> OnceList<T> { ///     const fn new() -> OnceList<T> { ///         OnceList { data: OnceLock::new(), next: OnceLock::new() } ///     } ///     fn push(&self, value: T) { ///         // FIXME: this impl is concise, but is also slow for long lists or many threads. ///         // as an exercise, consider how you might improve on it while preserving the behavior ///         if let Err(value) = self.data.set(value) { ///             let next = self.next.get_or_init(|| Box::new(OnceList::new())); ///             next.push(value) ///         }; ///     } ///     fn contains(&self, example: &T) -> bool ///     where ///         T: PartialEq, ///     { ///         self.data.get().map(|item| item == example).filter(|v| *v).unwrap_or_else(|| { ///             self.next.get().map(|next| next.contains(example)).unwrap_or(false) ///         }) ///     } /// } /// /// // Let's exercise this new Sync append-only list by doing a little counting /// static LIST: OnceList<u32> = OnceList::new(); /// static COUNTER: AtomicU32 = AtomicU32::new(0); /// /// let vec = (0..thread::available_parallelism().unwrap().get()).map(|_| thread::spawn(|| { ///     while let i @ 0..=1000 = COUNTER.fetch_add(1, Ordering::Relaxed) { ///         LIST.push(i); ///     } /// })).collect::<Vec<thread::JoinHandle<_>>>(); /// vec.into_iter().for_each(|handle| handle.join().unwrap()); /// /// for i in 0..=1000 { ///     assert!(LIST.contains(&i)); /// } /// /// ``` </ins> #[stable(feature = "once_cell", since = "1.70.0")] pub struct OnceLock<T> { once: Once,


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

// Get the arguments for the found method, only specifying that `Self` is the receiver type. let Some(possible_rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id) else { return }; let args = GenericArgs::for_item(tcx, method_def_id, |param, _| { <del> if param.index == 0 { </del> <ins> if let ty::GenericParamDefKind::Lifetime = param.kind { tcx.lifetimes.re_erased.into() } else if param.index == 0 && param.name == kw::SelfUpper { </ins> possible_rcvr_ty.into() } else if param.index == closure_param.index { closure_ty.into()


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

Obligation::misc(tcx, span, self.mir_def_id(), self.param_env, pred) })); <del> if ocx.select_all_or_error().is_empty() { </del> <ins> if ocx.select_all_or_error().is_empty() && count > 0 { </ins> diag.span_suggestion_verbose( tcx.hir().body(*body).value.peel_blocks().span.shrink_to_lo(), "dereference the return value",


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

<del> //@ known-bug: rust-lang/rust#124563 use std::marker::PhantomData; pub trait Trait {} pub trait Foo { type Trait: Trait; type Bar: Bar; fn foo(&mut self); } pub struct FooImpl<'a, 'b, A: Trait>(PhantomData<&'a &'b A>); impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T> where T: Trait, { type Trait = T; type Bar = BarImpl<'a, 'b, T>; fn foo(&mut self) { self.enter_scope(|ctx| { BarImpl(ctx); }); } } impl<'a, 'b, T> FooImpl<'a, 'b, T> where T: Trait, { fn enter_scope(&mut self, _scope: impl FnOnce(&mut Self)) {} } pub trait Bar { type Foo: Foo; } pub struct BarImpl<'a, 'b, T: Trait>(&'b mut FooImpl<'a, 'b, T>); impl<'a, 'b, T> Bar for BarImpl<'a, 'b, T> where T: Trait, { type Foo = FooImpl<'a, 'b, T>; } </del>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

<ins> // #125634 struct Thing; // Invariant in 'a, Covariant in 'b struct TwoThings<'a, 'b>(*mut &'a (), &'b mut ()); impl Thing { fn enter_scope<'a>(self, _scope: impl for<'b> FnOnce(TwoThings<'a, 'b>)) {} } fn foo() { Thing.enter_scope(|ctx| { SameLifetime(ctx); //~ ERROR lifetime may not live long enough }); } struct SameLifetime<'a>(TwoThings<'a, 'a>); fn main() {} </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

<ins> error: lifetime may not live long enough --> $DIR/account-for-lifetimes-in-closure-suggestion.rs:13:22 | LL |     Thing.enter_scope(|ctx| { |                        --- |                        | |                        has type `TwoThings<'_, '1>` |                        has type `TwoThings<'2, '_>` LL |         SameLifetime(ctx); |                      ^^^ this usage requires that `'1` must outlive `'2` | = note: requirement occurs because of the type `TwoThings<'_, '_>`, which makes the generic argument `'_` invariant = note: the struct `TwoThings<'a, 'b>` is invariant over the parameter `'a` = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance error: aborting due to 1 previous error </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

<ins> // #124563 use std::marker::PhantomData; pub trait Trait {} pub trait Foo { type Trait: Trait; type Bar: Bar; fn foo(&mut self); } pub struct FooImpl<'a, 'b, A: Trait>(PhantomData<&'a &'b A>); impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T> where T: Trait, { type Trait = T; type Bar = BarImpl<'a, 'b, T>; //~ ERROR lifetime bound not satisfied fn foo(&mut self) { self.enter_scope(|ctx| { //~ ERROR lifetime may not live long enough BarImpl(ctx); //~ ERROR lifetime may not live long enough }); } } impl<'a, 'b, T> FooImpl<'a, 'b, T> where T: Trait, { fn enter_scope(&mut self, _scope: impl FnOnce(&mut Self)) {} } pub trait Bar { type Foo: Foo; } pub struct BarImpl<'a, 'b, T: Trait>(&'b mut FooImpl<'a, 'b, T>); impl<'a, 'b, T> Bar for BarImpl<'a, 'b, T> where T: Trait, { type Foo = FooImpl<'a, 'b, T>; } fn main() {} </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

<ins> error[E0478]: lifetime bound not satisfied --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:19:16 | LL |     type Bar = BarImpl<'a, 'b, T>; |                ^^^^^^^^^^^^^^^^^^ | note: lifetime parameter instantiated with the lifetime `'a` as defined here --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:14:6 | LL | impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T> |      ^^ note: but lifetime parameter must outlive the lifetime `'b` as defined here --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:14:10 | LL | impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T> |          ^^ error: lifetime may not live long enough --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:23:21 | LL |         self.enter_scope(|ctx| { |                           --- |                           | |                           has type `&'1 mut FooImpl<'_, '_, T>` |                           has type `&mut FooImpl<'2, '_, T>` LL |             BarImpl(ctx); |                     ^^^ this usage requires that `'1` must outlive `'2` error: lifetime may not live long enough --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:22:9 | LL |   impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T> |        --  -- lifetime `'b` defined here |        | |        lifetime `'a` defined here ... LL | /         self.enter_scope(|ctx| { LL | |             BarImpl(ctx); LL | |         }); | |__________^ argument requires that `'a` must outlive `'b` | = help: consider adding the following bound: `'a: 'b` = note: requirement occurs because of a mutable reference to `FooImpl<'_, '_, T>` = note: mutable references are invariant over their type parameter = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0478`. </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

<ins> // Test a method call where the parameter `B` would (illegally) be // inferred to a region bound in the method argument. If this program // were accepted, then the closure passed to `s.f` could escape its // argument. //@ run-rustfix struct S; impl S { fn f<B, F>(&self, _: F) where F: FnOnce(&i32) -> B { } } fn main() { let s = S; s.f(|p| *p) //~ ERROR lifetime may not live long enough } </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

// inferred to a region bound in the method argument. If this program // were accepted, then the closure passed to `s.f` could escape its // argument. <ins> //@ run-rustfix </ins> struct S;


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' 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: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

error: lifetime may not live long enough <del> --> $DIR/regions-escape-method.rs:15:13 </del> <ins> --> $DIR/regions-escape-method.rs:16:13 </ins> | LL |     s.f(|p| p) |          -- ^ returning this value requires that `'1` must outlive `'2` |          || |          |return type of closure is &'2 i32 |          has type `&'1 i32` <ins> | help: dereference the return value | LL |     s.f(|p| *p) |             + </ins> error: aborting due to 1 previous error


Question:
I tried this code: I expected to see this happen: no warnings Instead, this happened: : cc
It looks like there is an upstream issue about this , but it seems like this shouldn't be an issue for dependents as long as is on edition < 2024.
It is expected for the lint to lint on macro-generated code. It is also expected for the lint to lint on all editions (it is not a edition dependent lint).
What am I meant to do as a downstream of a macro crate that hasn't fixed it then? I don't want to be ing a FCW, but there's nothing else I can do to clear this warning from my code. (And that implies that the planned "hard error in 2027" actually means for all editions, not just Edition 2027?)
Allow the lint. Report the issue upstream. Consider switching to an unaffected crate. That's understandable, but until the upstream crate is fixed I don't have a better solution. Note, that it is quite unlikely that this point that the lint will become deny-by-default in Rust 2024. No, if hard-error there is, it would only be for edition 2027 and higher, not below.
Why?
Detecting and ignoring macro-generated code for a lint where possible is the expected behavior of rustc.
Because, in particular for macro-generated code, we can't lint at the source since, well it is only generated when using the proc-macro or . Yes, but we must still emit the warning in macro-generated code, since the goal is to make the lint deny-by-default and then hard-error in a future edition, and without the warn it would go straight to hard-error which is not good.
Is there no ability to enable the lint when in the same crate/workspace but disable it for "foreign" macro-generated spans?
Yes, but can't rely on this. Also, not all macros have tests. The lint is only warn-by-default so it wouldn't break any test yet. If you mean: "don't lint on external macro", that is possible for but not for proc-macro since they are always external. We did an crater run, to evaluate the impact, before merging the lint in We had many cases with derive-macro, most of them (82.2%) where fixable by a , the rest would need manual intervention, the crate in question here was detected, and I reported the issue upstream with the fix that would fix the issue.
that was why I was thinking of trying to reason cross-workspace, but hmm, true. And actually, proc macros are worse: they can , so at least some are going to almost certainly slip through either way.
I would love if we had the ability to do that, but unfortunately doesn't have that information. Workspaces are a Cargo-only concept. :eyes:
I was hoping that we could do something where cargo helps us out here by describing which things we pay attention to, but I am fully prepared to believe that such is not tractable, even if only because no one has figured out if the infra for doing such a thing is even possible.
Yeah, unfortunately there isn't really anything else the compiler can do, it would be great if we could lint at the macro definition but due to the way they work that isn't possible, we are therefore forced to do the second "best" thing and lint at the usage. should be make it clearer that the "macro needs to change". So let's reclassify this issue as not-a-bug but as a discussion. labels -C-bug +C-discussion

.bounds = `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration .const_anon = use a const-anon item to suppress this lint <ins> .macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed </ins> lint_non_local_definitions_impl_move_help = move the `impl` block outside of this {$body_kind_descr} {$depth ->


Question:
I tried this code: I expected to see this happen: no warnings Instead, this happened: : cc
It looks like there is an upstream issue about this , but it seems like this shouldn't be an issue for dependents as long as is on edition < 2024.
It is expected for the lint to lint on macro-generated code. It is also expected for the lint to lint on all editions (it is not a edition dependent lint).
What am I meant to do as a downstream of a macro crate that hasn't fixed it then? I don't want to be ing a FCW, but there's nothing else I can do to clear this warning from my code. (And that implies that the planned "hard error in 2027" actually means for all editions, not just Edition 2027?)
Allow the lint. Report the issue upstream. Consider switching to an unaffected crate. That's understandable, but until the upstream crate is fixed I don't have a better solution. Note, that it is quite unlikely that this point that the lint will become deny-by-default in Rust 2024. No, if hard-error there is, it would only be for edition 2027 and higher, not below.
Why?
Detecting and ignoring macro-generated code for a lint where possible is the expected behavior of rustc.
Because, in particular for macro-generated code, we can't lint at the source since, well it is only generated when using the proc-macro or . Yes, but we must still emit the warning in macro-generated code, since the goal is to make the lint deny-by-default and then hard-error in a future edition, and without the warn it would go straight to hard-error which is not good.
Is there no ability to enable the lint when in the same crate/workspace but disable it for "foreign" macro-generated spans?
Yes, but can't rely on this. Also, not all macros have tests. The lint is only warn-by-default so it wouldn't break any test yet. If you mean: "don't lint on external macro", that is possible for but not for proc-macro since they are always external. We did an crater run, to evaluate the impact, before merging the lint in We had many cases with derive-macro, most of them (82.2%) where fixable by a , the rest would need manual intervention, the crate in question here was detected, and I reported the issue upstream with the fix that would fix the issue.
that was why I was thinking of trying to reason cross-workspace, but hmm, true. And actually, proc macros are worse: they can , so at least some are going to almost certainly slip through either way.
I would love if we had the ability to do that, but unfortunately doesn't have that information. Workspaces are a Cargo-only concept. :eyes:
I was hoping that we could do something where cargo helps us out here by describing which things we pay attention to, but I am fully prepared to believe that such is not tractable, even if only because no one has figured out if the infra for doing such a thing is even possible.
Yeah, unfortunately there isn't really anything else the compiler can do, it would be great if we could lint at the macro definition but due to the way they work that isn't possible, we are therefore forced to do the second "best" thing and lint at the usage. should be make it clearer that the "macro needs to change". So let's reclassify this issue as not-a-bug but as a discussion. labels -C-bug +C-discussion

has_trait: bool, self_ty_str: String, of_trait_str: Option<String>, <ins> macro_to_change: Option<(String, &'static str)>, </ins> }, MacroRules { depth: u32,


Question:
I tried this code: I expected to see this happen: no warnings Instead, this happened: : cc
It looks like there is an upstream issue about this , but it seems like this shouldn't be an issue for dependents as long as is on edition < 2024.
It is expected for the lint to lint on macro-generated code. It is also expected for the lint to lint on all editions (it is not a edition dependent lint).
What am I meant to do as a downstream of a macro crate that hasn't fixed it then? I don't want to be ing a FCW, but there's nothing else I can do to clear this warning from my code. (And that implies that the planned "hard error in 2027" actually means for all editions, not just Edition 2027?)
Allow the lint. Report the issue upstream. Consider switching to an unaffected crate. That's understandable, but until the upstream crate is fixed I don't have a better solution. Note, that it is quite unlikely that this point that the lint will become deny-by-default in Rust 2024. No, if hard-error there is, it would only be for edition 2027 and higher, not below.
Why?
Detecting and ignoring macro-generated code for a lint where possible is the expected behavior of rustc.
Because, in particular for macro-generated code, we can't lint at the source since, well it is only generated when using the proc-macro or . Yes, but we must still emit the warning in macro-generated code, since the goal is to make the lint deny-by-default and then hard-error in a future edition, and without the warn it would go straight to hard-error which is not good.
Is there no ability to enable the lint when in the same crate/workspace but disable it for "foreign" macro-generated spans?
Yes, but can't rely on this. Also, not all macros have tests. The lint is only warn-by-default so it wouldn't break any test yet. If you mean: "don't lint on external macro", that is possible for but not for proc-macro since they are always external. We did an crater run, to evaluate the impact, before merging the lint in We had many cases with derive-macro, most of them (82.2%) where fixable by a , the rest would need manual intervention, the crate in question here was detected, and I reported the issue upstream with the fix that would fix the issue.
that was why I was thinking of trying to reason cross-workspace, but hmm, true. And actually, proc macros are worse: they can , so at least some are going to almost certainly slip through either way.
I would love if we had the ability to do that, but unfortunately doesn't have that information. Workspaces are a Cargo-only concept. :eyes:
I was hoping that we could do something where cargo helps us out here by describing which things we pay attention to, but I am fully prepared to believe that such is not tractable, even if only because no one has figured out if the infra for doing such a thing is even possible.
Yeah, unfortunately there isn't really anything else the compiler can do, it would be great if we could lint at the macro definition but due to the way they work that isn't possible, we are therefore forced to do the second "best" thing and lint at the usage. should be make it clearer that the "macro needs to change". So let's reclassify this issue as not-a-bug but as a discussion. labels -C-bug +C-discussion

has_trait, self_ty_str, of_trait_str, <ins> macro_to_change, </ins> } => { diag.primary_message(fluent::lint_non_local_definitions_impl); diag.arg("depth", depth);


Question:
I tried this code: I expected to see this happen: no warnings Instead, this happened: : cc
It looks like there is an upstream issue about this , but it seems like this shouldn't be an issue for dependents as long as is on edition < 2024.
It is expected for the lint to lint on macro-generated code. It is also expected for the lint to lint on all editions (it is not a edition dependent lint).
What am I meant to do as a downstream of a macro crate that hasn't fixed it then? I don't want to be ing a FCW, but there's nothing else I can do to clear this warning from my code. (And that implies that the planned "hard error in 2027" actually means for all editions, not just Edition 2027?)
Allow the lint. Report the issue upstream. Consider switching to an unaffected crate. That's understandable, but until the upstream crate is fixed I don't have a better solution. Note, that it is quite unlikely that this point that the lint will become deny-by-default in Rust 2024. No, if hard-error there is, it would only be for edition 2027 and higher, not below.
Why?
Detecting and ignoring macro-generated code for a lint where possible is the expected behavior of rustc.
Because, in particular for macro-generated code, we can't lint at the source since, well it is only generated when using the proc-macro or . Yes, but we must still emit the warning in macro-generated code, since the goal is to make the lint deny-by-default and then hard-error in a future edition, and without the warn it would go straight to hard-error which is not good.
Is there no ability to enable the lint when in the same crate/workspace but disable it for "foreign" macro-generated spans?
Yes, but can't rely on this. Also, not all macros have tests. The lint is only warn-by-default so it wouldn't break any test yet. If you mean: "don't lint on external macro", that is possible for but not for proc-macro since they are always external. We did an crater run, to evaluate the impact, before merging the lint in We had many cases with derive-macro, most of them (82.2%) where fixable by a , the rest would need manual intervention, the crate in question here was detected, and I reported the issue upstream with the fix that would fix the issue.
that was why I was thinking of trying to reason cross-workspace, but hmm, true. And actually, proc macros are worse: they can , so at least some are going to almost certainly slip through either way.
I would love if we had the ability to do that, but unfortunately doesn't have that information. Workspaces are a Cargo-only concept. :eyes:
I was hoping that we could do something where cargo helps us out here by describing which things we pay attention to, but I am fully prepared to believe that such is not tractable, even if only because no one has figured out if the infra for doing such a thing is even possible.
Yeah, unfortunately there isn't really anything else the compiler can do, it would be great if we could lint at the macro definition but due to the way they work that isn't possible, we are therefore forced to do the second "best" thing and lint at the usage. should be make it clearer that the "macro needs to change". So let's reclassify this issue as not-a-bug but as a discussion. labels -C-bug +C-discussion

diag.arg("of_trait_str", of_trait_str); } <ins> if let Some((macro_to_change, macro_kind)) = macro_to_change { diag.arg("macro_to_change", macro_to_change); diag.arg("macro_kind", macro_kind); diag.note(fluent::lint_macro_to_change); } if let Some(cargo_update) = cargo_update { diag.subdiagnostic(&diag.dcx, cargo_update); } </ins> if has_trait { diag.note(fluent::lint_bounds); diag.note(fluent::lint_with_trait);


Question:
I tried this code: I expected to see this happen: no warnings Instead, this happened: : cc
It looks like there is an upstream issue about this , but it seems like this shouldn't be an issue for dependents as long as is on edition < 2024.
It is expected for the lint to lint on macro-generated code. It is also expected for the lint to lint on all editions (it is not a edition dependent lint).
What am I meant to do as a downstream of a macro crate that hasn't fixed it then? I don't want to be ing a FCW, but there's nothing else I can do to clear this warning from my code. (And that implies that the planned "hard error in 2027" actually means for all editions, not just Edition 2027?)
Allow the lint. Report the issue upstream. Consider switching to an unaffected crate. That's understandable, but until the upstream crate is fixed I don't have a better solution. Note, that it is quite unlikely that this point that the lint will become deny-by-default in Rust 2024. No, if hard-error there is, it would only be for edition 2027 and higher, not below.
Why?
Detecting and ignoring macro-generated code for a lint where possible is the expected behavior of rustc.
Because, in particular for macro-generated code, we can't lint at the source since, well it is only generated when using the proc-macro or . Yes, but we must still emit the warning in macro-generated code, since the goal is to make the lint deny-by-default and then hard-error in a future edition, and without the warn it would go straight to hard-error which is not good.
Is there no ability to enable the lint when in the same crate/workspace but disable it for "foreign" macro-generated spans?
Yes, but can't rely on this. Also, not all macros have tests. The lint is only warn-by-default so it wouldn't break any test yet. If you mean: "don't lint on external macro", that is possible for but not for proc-macro since they are always external. We did an crater run, to evaluate the impact, before merging the lint in We had many cases with derive-macro, most of them (82.2%) where fixable by a , the rest would need manual intervention, the crate in question here was detected, and I reported the issue upstream with the fix that would fix the issue.
that was why I was thinking of trying to reason cross-workspace, but hmm, true. And actually, proc macros are worse: they can , so at least some are going to almost certainly slip through either way.
I would love if we had the ability to do that, but unfortunately doesn't have that information. Workspaces are a Cargo-only concept. :eyes:
I was hoping that we could do something where cargo helps us out here by describing which things we pay attention to, but I am fully prepared to believe that such is not tractable, even if only because no one has figured out if the infra for doing such a thing is even possible.
Yeah, unfortunately there isn't really anything else the compiler can do, it would be great if we could lint at the macro definition but due to the way they work that isn't possible, we are therefore forced to do the second "best" thing and lint at the usage. should be make it clearer that the "macro needs to change". So let's reclassify this issue as not-a-bug but as a discussion. labels -C-bug +C-discussion

); } <del> if let Some(cargo_update) = cargo_update { diag.subdiagnostic(&diag.dcx, cargo_update); } </del> if let Some(const_anon) = const_anon { diag.note(fluent::lint_exception); if let Some(const_anon) = const_anon {


Question:
I tried this code: I expected to see this happen: no warnings Instead, this happened: : cc
It looks like there is an upstream issue about this , but it seems like this shouldn't be an issue for dependents as long as is on edition < 2024.
It is expected for the lint to lint on macro-generated code. It is also expected for the lint to lint on all editions (it is not a edition dependent lint).
What am I meant to do as a downstream of a macro crate that hasn't fixed it then? I don't want to be ing a FCW, but there's nothing else I can do to clear this warning from my code. (And that implies that the planned "hard error in 2027" actually means for all editions, not just Edition 2027?)
Allow the lint. Report the issue upstream. Consider switching to an unaffected crate. That's understandable, but until the upstream crate is fixed I don't have a better solution. Note, that it is quite unlikely that this point that the lint will become deny-by-default in Rust 2024. No, if hard-error there is, it would only be for edition 2027 and higher, not below.
Why?
Detecting and ignoring macro-generated code for a lint where possible is the expected behavior of rustc.
Because, in particular for macro-generated code, we can't lint at the source since, well it is only generated when using the proc-macro or . Yes, but we must still emit the warning in macro-generated code, since the goal is to make the lint deny-by-default and then hard-error in a future edition, and without the warn it would go straight to hard-error which is not good.
Is there no ability to enable the lint when in the same crate/workspace but disable it for "foreign" macro-generated spans?
Yes, but can't rely on this. Also, not all macros have tests. The lint is only warn-by-default so it wouldn't break any test yet. If you mean: "don't lint on external macro", that is possible for but not for proc-macro since they are always external. We did an crater run, to evaluate the impact, before merging the lint in We had many cases with derive-macro, most of them (82.2%) where fixable by a , the rest would need manual intervention, the crate in question here was detected, and I reported the issue upstream with the fix that would fix the issue.
that was why I was thinking of trying to reason cross-workspace, but hmm, true. And actually, proc macros are worse: they can , so at least some are going to almost certainly slip through either way.
I would love if we had the ability to do that, but unfortunately doesn't have that information. Workspaces are a Cargo-only concept. :eyes:
I was hoping that we could do something where cargo helps us out here by describing which things we pay attention to, but I am fully prepared to believe that such is not tractable, even if only because no one has figured out if the infra for doing such a thing is even possible.
Yeah, unfortunately there isn't really anything else the compiler can do, it would be great if we could lint at the macro definition but due to the way they work that isn't possible, we are therefore forced to do the second "best" thing and lint at the usage. should be make it clearer that the "macro needs to change". So let's reclassify this issue as not-a-bug but as a discussion. labels -C-bug +C-discussion

Some((cx.tcx.def_span(parent), may_move)) }; <ins> let macro_to_change = if let ExpnKind::Macro(kind, name) = item.span.ctxt().outer_expn_data().kind { Some((name.to_string(), kind.descr())) } else { None }; </ins> cx.emit_span_lint( NON_LOCAL_DEFINITIONS, ms,


Question:
I tried this code: I expected to see this happen: no warnings Instead, this happened: : cc
It looks like there is an upstream issue about this , but it seems like this shouldn't be an issue for dependents as long as is on edition < 2024.
It is expected for the lint to lint on macro-generated code. It is also expected for the lint to lint on all editions (it is not a edition dependent lint).
What am I meant to do as a downstream of a macro crate that hasn't fixed it then? I don't want to be ing a FCW, but there's nothing else I can do to clear this warning from my code. (And that implies that the planned "hard error in 2027" actually means for all editions, not just Edition 2027?)
Allow the lint. Report the issue upstream. Consider switching to an unaffected crate. That's understandable, but until the upstream crate is fixed I don't have a better solution. Note, that it is quite unlikely that this point that the lint will become deny-by-default in Rust 2024. No, if hard-error there is, it would only be for edition 2027 and higher, not below.
Why?
Detecting and ignoring macro-generated code for a lint where possible is the expected behavior of rustc.
Because, in particular for macro-generated code, we can't lint at the source since, well it is only generated when using the proc-macro or . Yes, but we must still emit the warning in macro-generated code, since the goal is to make the lint deny-by-default and then hard-error in a future edition, and without the warn it would go straight to hard-error which is not good.
Is there no ability to enable the lint when in the same crate/workspace but disable it for "foreign" macro-generated spans?
Yes, but can't rely on this. Also, not all macros have tests. The lint is only warn-by-default so it wouldn't break any test yet. If you mean: "don't lint on external macro", that is possible for but not for proc-macro since they are always external. We did an crater run, to evaluate the impact, before merging the lint in We had many cases with derive-macro, most of them (82.2%) where fixable by a , the rest would need manual intervention, the crate in question here was detected, and I reported the issue upstream with the fix that would fix the issue.
that was why I was thinking of trying to reason cross-workspace, but hmm, true. And actually, proc macros are worse: they can , so at least some are going to almost certainly slip through either way.
I would love if we had the ability to do that, but unfortunately doesn't have that information. Workspaces are a Cargo-only concept. :eyes:
I was hoping that we could do something where cargo helps us out here by describing which things we pay attention to, but I am fully prepared to believe that such is not tractable, even if only because no one has figured out if the infra for doing such a thing is even possible.
Yeah, unfortunately there isn't really anything else the compiler can do, it would be great if we could lint at the macro definition but due to the way they work that isn't possible, we are therefore forced to do the second "best" thing and lint at the usage. should be make it clearer that the "macro needs to change". So let's reclassify this issue as not-a-bug but as a discussion. labels -C-bug +C-discussion

move_to, may_remove, has_trait: impl_.of_trait.is_some(), <ins> macro_to_change, </ins> }, ) }