Question: <ins> use rustc::hir::def_id::DefId; use rustc::mir; use rustc::ty::layout::HasTyCtxt; use rustc::ty::{self, Ty, TyCtxt}; use std::borrow::{Borrow, Cow}; use std::collections::hash_map::Entry; use std::hash::Hash; use rustc_data_structures::fx::FxHashMap; use syntax::source_map::Span; use crate::interpret::{ self, snapshot, AllocId, Allocation, AssertMessage, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind, OpTy, PlaceTy, Pointer, Scalar, }; use super::error::*; impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> { /// Evaluate a const function where all arguments (if any) are zero-sized types. /// The evaluation is memoized thanks to the query system. /// /// Returns `true` if the call has been evaluated. fn try_eval_const_fn_call( &mut self, instance: ty::Instance<'tcx>, ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>, args: &[OpTy<'tcx>], ) -> InterpResult<'tcx, bool> { trace!("try_eval_const_fn_call: {:?}", instance); // Because `#[track_caller]` adds an implicit non-ZST argument, we also cannot // perform this optimization on items tagged with it. if instance.def.requires_caller_location(self.tcx()) { return Ok(false); } // For the moment we only do this for functions which take no arguments // (or all arguments are ZSTs) so that we don't memoize too much. if args.iter().any(|a| !a.layout.is_zst()) { return Ok(false); } let gid = GlobalId { instance, promoted: None }; let place = self.const_eval_raw(gid)?; let dest = match ret { Some((dest, _)) => dest, // Don't memoize diverging function calls. None => return Ok(false), }; self.copy_op(place.into(), dest)?; self.return_to_block(ret.map(|r| r.1))?; self.dump_place(*dest); return Ok(true); } } /// Number of steps until the detector even starts doing anything. /// Also, a warning is shown to the user when this number is reached. const STEPS_UNTIL_DETECTOR_ENABLED: isize = 1_000_000; /// The number of steps between loop detector snapshots. /// Should be a power of two for performance reasons. const DETECTOR_SNAPSHOT_PERIOD: isize = 256; // Extra machine state for CTFE, and the Machine instance pub struct CompileTimeInterpreter<'mir, 'tcx> { /// When this value is negative, it indicates the number of interpreter /// steps *until* the loop detector is enabled. When it is positive, it is /// the number of steps after the detector has been enabled modulo the loop /// detector period. pub(super) steps_since_detector_enabled: isize, /// Extra state to detect loops. pub(super) loop_detector: snapshot::InfiniteLoopDetector<'mir, 'tcx>, } #[derive(Copy, Clone, Debug)] pub struct MemoryExtra { /// Whether this machine may read from statics can_access_statics: bool, } impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> { fn new() -> Self { CompileTimeInterpreter { loop_detector: Default::default(), steps_since_detector_enabled: -STEPS_UNTIL_DETECTOR_ENABLED, } } } impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxHashMap<K, V> { #[inline(always)] fn contains_key<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> bool where K: Borrow<Q>, { FxHashMap::contains_key(self, k) } #[inline(always)] fn insert(&mut self, k: K, v: V) -> Option<V> { FxHashMap::insert(self, k, v) } #[inline(always)] fn remove<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> Option<V> where K: Borrow<Q>, { FxHashMap::remove(self, k) } #[inline(always)] fn filter_map_collect<T>(&self, mut f: impl FnMut(&K, &V) -> Option<T>) -> Vec<T> { self.iter().filter_map(move |(k, v)| f(k, &*v)).collect() } #[inline(always)] fn get_or<E>(&self, k: K, vacant: impl FnOnce() -> Result<V, E>) -> Result<&V, E> { match self.get(&k) { Some(v) => Ok(v), None => { vacant()?; bug!("The CTFE machine shouldn't ever need to extend the alloc_map when reading") } } } #[inline(always)] fn get_mut_or<E>(&mut self, k: K, vacant: impl FnOnce() -> Result<V, E>) -> Result<&mut V, E> { match self.entry(k) { Entry::Occupied(e) => Ok(e.into_mut()), Entry::Vacant(e) => { let v = vacant()?; Ok(e.insert(v)) } } } } crate type CompileTimeEvalContext<'mir, 'tcx> = InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>; impl interpret::MayLeak for ! { #[inline(always)] fn may_leak(self) -> bool { // `self` is uninhabited self } } impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 'tcx> { type MemoryKinds = !; type PointerTag = (); type ExtraFnVal = !; type FrameExtra = (); type MemoryExtra = MemoryExtra; type AllocExtra = (); type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>; const STATIC_KIND: Option<!> = None; // no copying of statics allowed // We do not check for alignment to avoid having to carry an `Align` // in `ConstValue::ByRef`. const CHECK_ALIGN: bool = false; #[inline(always)] fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { false // for now, we don't enforce validity } fn find_mir_or_eval_fn( ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>, _unwind: Option<mir::BasicBlock>, // unwinding is not supported in consts ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> { debug!("find_mir_or_eval_fn: {:?}", instance); // Only check non-glue functions if let ty::InstanceDef::Item(def_id) = instance.def { // Execution might have wandered off into other crates, so we cannot do a stability- // sensitive check here.  But we can at least rule out functions that are not const // at all. if ecx.tcx.is_const_fn_raw(def_id) { // If this function is a `const fn` then under certain circumstances we // can evaluate call via the query system, thus memoizing all future calls. if ecx.try_eval_const_fn_call(instance, ret, args)? { return Ok(None); } } else { // Some functions we support even if they are non-const -- but avoid testing // that for const fn!  We certainly do *not* want to actually call the fn // though, so be sure we return here. return if ecx.hook_panic_fn(instance, args, ret)? { Ok(None) } else { throw_unsup_format!("calling non-const function `{}`", instance) }; } } // This is a const fn. Call it. Ok(Some(match ecx.load_mir(instance.def, None) { Ok(body) => *body, Err(err) => { if let err_unsup!(NoMirFor(ref path)) = err.kind { return Err(ConstEvalError::NeedsRfc(format!( "calling extern function `{}`", path )) .into()); } return Err(err); } })) } fn call_extra_fn( _ecx: &mut InterpCx<'mir, 'tcx, Self>, fn_val: !, _args: &[OpTy<'tcx>], _ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>, _unwind: Option<mir::BasicBlock>, ) -> InterpResult<'tcx> { match fn_val {} } fn call_intrinsic( ecx: &mut InterpCx<'mir, 'tcx, Self>, span: Span, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>, _unwind: Option<mir::BasicBlock>, ) -> InterpResult<'tcx> { if ecx.emulate_intrinsic(span, instance, args, ret)? { return Ok(()); } // An intrinsic that we do not support let intrinsic_name = ecx.tcx.item_name(instance.def_id()); Err(ConstEvalError::NeedsRfc(format!("calling intrinsic `{}`", intrinsic_name)).into()) } fn assert_panic( ecx: &mut InterpCx<'mir, 'tcx, Self>, _span: Span, msg: &AssertMessage<'tcx>, _unwind: Option<mir::BasicBlock>, ) -> InterpResult<'tcx> { use rustc::mir::interpret::PanicInfo::*; Err(match msg { BoundsCheck { ref len, ref index } => { let len = ecx .read_immediate(ecx.eval_operand(len, None)?) .expect("can't eval len") .to_scalar()? .to_machine_usize(&*ecx)?; let index = ecx .read_immediate(ecx.eval_operand(index, None)?) .expect("can't eval index") .to_scalar()? .to_machine_usize(&*ecx)?; err_panic!(BoundsCheck { len, index }) } Overflow(op) => err_panic!(Overflow(*op)), OverflowNeg => err_panic!(OverflowNeg), DivisionByZero => err_panic!(DivisionByZero), RemainderByZero => err_panic!(RemainderByZero), ResumedAfterReturn(generator_kind) => err_panic!(ResumedAfterReturn(*generator_kind)), ResumedAfterPanic(generator_kind) => err_panic!(ResumedAfterPanic(*generator_kind)), Panic { .. } => bug!("`Panic` variant cannot occur in MIR"), } .into()) } fn ptr_to_int(_mem: &Memory<'mir, 'tcx, Self>, _ptr: Pointer) -> InterpResult<'tcx, u64> { Err(ConstEvalError::NeedsRfc("pointer-to-integer cast".to_string()).into()) } fn binary_ptr_op( _ecx: &InterpCx<'mir, 'tcx, Self>, _bin_op: mir::BinOp, _left: ImmTy<'tcx>, _right: ImmTy<'tcx>, ) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> { Err(ConstEvalError::NeedsRfc("pointer arithmetic or comparison".to_string()).into()) } fn find_foreign_static( _tcx: TyCtxt<'tcx>, _def_id: DefId, ) -> InterpResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag>>> { throw_unsup!(ReadForeignStatic) } #[inline(always)] fn init_allocation_extra<'b>( _memory_extra: &MemoryExtra, _id: AllocId, alloc: Cow<'b, Allocation>, _kind: Option<MemoryKind<!>>, ) -> (Cow<'b, Allocation<Self::PointerTag>>, Self::PointerTag) { // We do not use a tag so we can just cheaply forward the allocation (alloc, ()) } #[inline(always)] fn tag_static_base_pointer(_memory_extra: &MemoryExtra, _id: AllocId) -> Self::PointerTag { () } fn box_alloc( _ecx: &mut InterpCx<'mir, 'tcx, Self>, _dest: PlaceTy<'tcx>, ) -> InterpResult<'tcx> { Err(ConstEvalError::NeedsRfc("heap allocations via `box` keyword".to_string()).into()) } fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { { let steps = &mut ecx.machine.steps_since_detector_enabled; *steps += 1; if *steps < 0 { return Ok(()); } *steps %= DETECTOR_SNAPSHOT_PERIOD; if *steps != 0 { return Ok(()); } } let span = ecx.frame().span; ecx.machine.loop_detector.observe_and_analyze(*ecx.tcx, span, &ecx.memory, &ecx.stack[..]) } #[inline(always)] fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { Ok(()) } fn before_access_static( memory_extra: &MemoryExtra, _allocation: &Allocation, ) -> InterpResult<'tcx> { if memory_extra.can_access_statics { Ok(()) } else { Err(ConstEvalError::ConstAccessesStatic.into()) } } } // Please do not add any code below the above `Machine` trait impl. I (oli-obk) plan more cleanups // so we can end up having a file with just that impl, but for now, let's keep the impl discoverable // at the bottom of this file. </ins>

Follow-up to agreed to move to . Generally I propose that should not contain code that is only needed by CTFE. We have and in there are they need some very deep access to Miri engine internals, but at least those are separate modules. Also, has grown pretty messy, and it does not seem like the order of definitions in that file follows any principle. We could split the file into two similar to what I did with Miri: for implementing the machine trait and defining everything that is needed during CTFE execution, and for defining the setup functions and all the glue that connects CTFE with the rest of the compiler.


Question: <del> // no-prefer-dynamic </del> fn main() { let _ = std::io::stdin(); let _ = std::io::stdout();

Right now on our bots we're basically in a state where if valgrind rpass tests are compiled dynamically they will all fail, but when compiled statically they will pass. I'm not really sure what's going on unfortunately, but this is either a bug in valgrind or a bug with us, and we should know precisely what it is to ensure something more sinister isn't lurking. Some links: - first pass at linking tests statically, fixed - another pass at linking all tests statically
All the failures seem to be within platform’s dynamic loader. Here’s a few things to try: updating kernel+glibc to the most recent versions (4.4-ish and 2.23-ish, respectively) help? downgrading kernel+glibc to some older version help? non-linux/non-glibc work correctly?
Any news/changes on this one ?


Question: /// Returns the number of leading zeros in the binary representation of `self`. /// <ins> /// Depending on what you're doing with the value, you might also be interested in the /// [`ilog2`] function which returns a consistent number, even if the type widens. /// </ins> /// # Examples /// /// Basic usage:

I was chatting with today, who mentioned it'd be helpful to mention the newly stabilized APIs from the docs. The benefit of using is that even if the type widens, the result doesn't change. It'd be nice if someone could contribute docs mentioning from . This probably just needs to be a one-liner. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim


Question: <ins> fn main() { let x = (1, 2, 3); match x { (_a, _x @ ..) => {} _ => {} } } //~^^^^ ERROR `_x @` is not allowed in a tuple </ins>

and I are working on diagnostics for the rest idiom in slice patterns () and came across this issue when an attempt is made to use it in tuples and tuple structs. IIUC, this is allowed: and this is not allowed (note the addition of ): The error messages for the tuple and tuple struct cases include the following incorrect information: This should state that the id binding to rest is not allowed. patterns are allowed. is only allowed in slice patterns, not in tuple or tuple struct patterns. This should state that the idiom is only allowed in slice patterns. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
appears to be the site of the check: This method is called:
Perhaps it's worth supporting "tuple slicing" pattern too in Rust:
that would implicitly create a tuple for (or a slice?). I don't think it'd be a good addition. We already support , which is much more useful in my eyes.
That syntax is meant to produce a shorter tuple xs with the omission of the first item of the tuple. lf you think it's an useless idea then let's ignore it :)
claim


Question: <del> // no-prefer-dynamic </del> static mut DROP_RAN: isize = 0; struct Foo;


Question: return; } <del> if self.in_scope_lifetimes.contains(&ident.modern()) { </del> <ins> if self.in_scope_lifetimes.contains(&ParamName::Plain(ident.modern())) { </ins> return; }

The diagnostics ("use of undeclared lifetime name") are bad, but this indeed must be an error because the inner is an illegal use of the outer rather than an implicitly defined fresh lifetime.
Hm, I don't think that's quite what I'd expect: previously using in that context would be fine because there is no shadowing so to speak, that is, this compiles:
From Similarly, if a fn definition is nested inside another fn definition, it is an error to mention lifetimes from that outer definition (without binding them explicitly). This is again intended for future-proofing and clarity, and is an edge case. (In the second example there's an explicit definition that shadows the previous definition for following uses, in the first example there's no second definition, only use)
I see that this is in the RFC, but I think I more or less disagree with the reasoning given. Disallowing the use of inband lifetimes when nesting function seems arbitrary and not entirely helpful; it also makes a mechanical change from "old" to "new" more difficult because shadowing is visible only based on indent levels.
IMO it should be an error, with a helpful note like the one you get when writing . Let's not make in-band lifetimes any more confusing than they already are.
The distinction is that inband lifetime's selling point is that you don't need to declare lifetimes. If we say that, and then clarify it with "except" then I think the feature feels incomplete. Inband lifetimes confusion does not increase with permitting this, IMO.
The problem is if it's allowed, then has a different meaning than This seems unfortunate and confusing. Even unergonomic if I may say so. There's no way that the distinction between and won't be missed in a quick scan of the second one. But, like, the RFC process did decide that isn't important, so whatever.
Well, somewhat, but not really. Nothing outside of imports/definitions inherits into the inner function, unlike the impl where there is a history and multiple things which inherit (, lifetimes, generics).


Question: <ins> mod b { pub struct A(u32); } trait Id { type Assoc; } impl Id for b::A { type Assoc = b::A; } impl Id for u32 { type Assoc = u32; } trait Trait<T> { fn method(&self) where T: Id<Assoc = b::A>; } impl<T: Id> Trait<T> for <T as Id>::Assoc { fn method(&self) where T: Id<Assoc = b::A>, { let Self(a) = self; //~^ ERROR: tuple struct constructor `A` is private println!("{a}"); } } fn main() {} </ins>

I tried this code: I expected to see this happen: compilation should fail because the trait impl is defined outside of the module for the type but refers to its private field. Instead, this happened: this compiled successfully This reproduces on the playground for stable Rust, version 1.69.0:
Adding a main function and attempting to call the (playground link: ) raises the compilation error: !
This can be reproduced with cross-crate (e.i., any other crate can access the private field). This means that all encapsulations that take advantage of the field being private can be bypassed. (For example, if we change Vec to a tuple struct, the same thing as setlen could be done in safe code by abusing this bug.) label +I-unsound Also, this can be reproduced in all versions where is stable (e.i., 1.32+). It's a matter of how you initialize Foo. If you provide a constructor for Foo, you won't get a compile error:
Just for completeness, turning this into a segfault without external crates/just std:
label A-visibility
this has been unsound ever since in version 1.32
WG-prioritization assigning priority (). label -I-prioritize +P-high


Question: --set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib  --set llvm.thin-lto=true  --set llvm.ninja=false  <del> --set llvm.use-linker=lld  --set rust.use-lld=true  </del> --set rust.jemalloc <del> ENV SCRIPT ../src/ci/pgo.sh python3 ../x.py dist  </del> <ins> ENV SCRIPT ../src/ci/pgo.sh python2.7 ../x.py dist  </ins> --host $HOSTS --target $HOSTS  --include-default-paths  src/tools/build-manifest

When I install the latest master toolchains via and try to build with them, linking fails: I did some bisection, and it looks like the problem started happening with Cc
The error is actually already mentioned in However, I am building Miri with cargo, so I don't know how I'd "use LLD instead".
Hm, we probably need to revert that PR. I did not realize we'd need lld downstream too, I thought that was only on our builder. cc
Yes, a revert seems appropriate. We're going to have to figure out where that's actually coming from. The only change I saw between 10 and 11 by grepping was the removal of llgo, but maybe there's some bad remnant.
Yeah, I thought this issue would be limited to the rustc build, but it makes sense that it can also affect project linking against rustc shared objects. I've looked a bit into what the root cause is, and what I have so far as that the symbol comes from and is present as a weak symbol both when compiling with clang-10 and clang-11. The only difference I see from is this: So apparently was treated as a symbol of the library, while now it's treated as a symbol of -- I'm not sure what that actually means, but presumably that refers to the compiler runtime libraries. My guess is that previously it just ended up being nulled out as a missing weak symbol, but now it's actually being found and linking fails because ... reasons. I'm not good at linkers :) Edit: shows these as:
can you prepare a revert PR?
Done in . If nobody has an idea on how to avoid the linker error, two more options would be to comment out the symbol in our llvm-project fork, or to avoid upgrading clang altogether and just build both Python 2 and Python 3 for that image.
The issue is probably going to be in how exactly the objects that comprise are compiled, not linked. I suspect just ends up ignoring the malformed object or otherwise not reporting the issue, but the object and the relevant symbols ultimately end up in the anyway. Alas, reasons these obscure failures can occur are many – I've seen them occur from things as trivial as forgetting to . The question is: is there perhaps a way to disable ExecutionEngine entirely? Intuitively nothing we do should depend on that code.


Question: --set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib  --set llvm.thin-lto=true  --set llvm.ninja=false  <del> --set llvm.use-linker=lld  --set rust.use-lld=true  </del> --set rust.jemalloc <del> ENV SCRIPT ../src/ci/pgo.sh python3 ../x.py dist  </del> <ins> ENV SCRIPT ../src/ci/pgo.sh python2.7 ../x.py dist  </ins> --host $HOSTS --target $HOSTS  --include-default-paths  src/tools/build-manifest

And if not, I'm comfortable patching out in our fork as we get closer to Feb 11 and continue having trouble pinpointing exact cause of this problem.
We normally don't link ExecutionEngine, but dist-x8664-linux in particular builds LLVM with ThinLTO, in which case we link as shared, instead of statically linking individual components into rustcllvm.
It seems to be possible to configure the components in using , but I'm not sure to what degree we can restrict those (not sure if this job also ships LLVM tools).
So, I think we could have used to exclude unnecessary parts from , as LLVM tools can still statically link the parts not in the dylib. But in the end, we can't use the option anyway due to
Looks like I'm getting this locally when trying to bootstrap rustc (while building ), might happen since the llvm upgrade but I'm not 100% sure. Are there some workarounds I can put into my for this? I'm using lld to link. <details<summaryBacktrace</summary<p</p</details
which commit are you trying to build?
latest git master
Probably best to open a new issue then; this one has been closed and the steps to reproduce it still work without error -- you might be having a different problem.
Opened
Did anyone file an upstream bug report about this? I'm observing it outside of Rust, but with a similar setup ( with lld+ThinLTO, then linking it into a binary with ). If not, I'd try to build a reproducer.
I've opened for this.
The bug has been fixed, the fix will be in LLVM 12.0.1.
Thanks! We can try updating clang again once the 12.0.1 tag is there.


Question: <ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. struct Foo<'r>(&'r mut i32); impl<'r> Drop for Foo<'r> { fn drop(&mut self) { *self.0 += 1; } } trait Trait {} impl<'r> Trait for Foo<'r> {} struct Holder<T: ?Sized>(T); fn main() { let mut drops = 0; { let y = &Holder([Foo(&mut drops)]) as &Holder<[Foo]>; // this used to cause an extra drop of the Foo instance let x = &y.0; } assert_eq!(1, drops); drops = 0; { let y = &Holder(Foo(&mut drops)) as &Holder<Trait>; // this used to cause an extra drop of the Foo instance let x = &y.0; } assert_eq!(1, drops); } </ins>

The following function can drop any object arbitrary number of times, using only safe code: Probably bad :) Found while researching
Nominating for P-high
cc
Too bad this doesn't just cancel out the Leakocalypse :stuckouttongue:
(well, any object that implements . But yes, I see the point being made here.)
look, no required. I guess it doesn't work for types that are already unsized.
to be clear, I am looking at this now as well. :)
I guess is related.
I hope it is unrelated. In particular I wrote this on that ticket:
Yeah, it's unrelated. The call happens for , which does need drop.


Question: 7331 })); assert_eq!(foo, 42); <ins> // Test trailing comma: assert_eq!(("Yeah",), dbg!(("Yeah",))); // Test multiple arguments: assert_eq!((1u8, 2u32), dbg!(1, 2)); // Test multiple arguments + trailing comma: assert_eq!((1u8, 2u32, "Yeah"), dbg!(1u8, 2u32, "Yeah",)); </ins> } fn validate_stderr(stderr: Vec<String>) {

It would be nice if the compiler suggested the intended form: as this seems like a reasonable mistake. This is specific to a particular macro, though, so I'm not sure how flexible we can be with diagnostics here.
Or we could just make the macro accept ...


Question: Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` necessary to detect this target may change as the target becomes more stable. <ins> ## Enabled WebAssembly features The default set of WebAssembly features enabled for compilation includes two more features in addition to that which [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables: * `bulk-memory` * `atomics` For more information about features see the documentation for [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the `mvp` CPU in LLVM does not support this target as it's required that `bulk-memory`, `atomics`, and `mutable-globals` are all enabled. </ins>

This can be replicated with a minimal : Compile it to WASM with Then, check if the generated WASM uses reference types: <!-- Provide the most recent version this worked on, for example: It most recently worked on: Rust 1.47 --It most recently worked on: (and previous stable rust versions) On those versions, compiling the above and then running with doesn't fail. <!-- Provide the version you are using that has the regression. --: <!-- If you know when this regression occurred, please add a line like below, replacing with one of stable, beta, or nightly. modify labels: +regression-from-stable-to-{channel} -regression-untriaged -- modify labels: +regression-from-stable-to-nightly -regression-untriaged This seems to have been caused by The compatibility note there says: However, the generated code seems to be indeed affected by default. Interestingly, reference types seem to be used unnecessarily, as using to turn the generated into wat and then to turn it back into wasm removes the reference types. As-is, this breaks compatibility with the WebAssembly 1.0 spec.
cc Looks like this causes issues in practice and we might want to do after all?
WG-prioritization assigning priority (). label -I-prioritize +P-high
I was unable to confirm the presence of any reference type instructions in the generated Wasm, even though I got the same error pointing towards a that looks perfectly valid to me. Interestingly enough, doing the back and forth conversion with and remove the issue, even though the output of both files is exactly the same, apart from the missing debug information. I'm assuming that this is another example of a tool making use of the , so this was already anticipated. Unfortunately (?) this isn't the first time LLVM has enabled features by default, in the past they even did affect code generation. From what I've read in the various WebAssembly specification groups, this was always intended. In conclusion, I agree this is a form of breakage, it seems to be intended, I believe if Rust wants to do anything about it the solution needs to a bit more comprehensive. E.g. actually disable all target features by default (I don't know if this is feasible with LLVM, would need research). See and .
I just spend some time digging into this error message that spits out.


Question: Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` necessary to detect this target may change as the target becomes more stable. <ins> ## Enabled WebAssembly features The default set of WebAssembly features enabled for compilation includes two more features in addition to that which [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables: * `bulk-memory` * `atomics` For more information about features see the documentation for [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the `mvp` CPU in LLVM does not support this target as it's required that `bulk-memory`, `atomics`, and `mutable-globals` are all enabled. </ins>

Locally I've produced exactly the same message, but it really doesn't make any sense to me. The location pointed out by the error message does indeed contain a call to , but the reserved value is , so I don't know what the issue is. Further, after using the -trick, it doesn't produce this error anymore, but the code location contains the exact same bytes. I also checked if reads the target feature section. While I confirmed it does, I don't believe it validates it from what I can see in the code. So maybe there is some sort of codegen difference, but I am unable to actually find it.
Could it be the encoding difference discussed in the description of this PR?
Yes, I just confirmed that's the issue. So it does affect codegen, even if in a minor way!
Yes the problem is the LEB-encoding of the table index immediate. Using on the output of rustc I see: which shows that 's type and table index are both using a 5-byte encoding of a zero value. This is not valid in MVP WebAssembly which required the table index to be a literal zero byte, not a LEB. Given I doubt LLVM will do anything here so it sounds like yes, we'll have to solve this in Rust. I believe this is due to the the binary encoding of the LEB. This isn't reflected in the text format and most other tools don't handle this well, so it's a subtle error. That's also why convert-to-text-and-back produces a working binary. To clarify, I don't believe that this is the case. I believe modifications to the target feature section are unrelated. Ok so the question now is what to do. I see a few possible routes: this change. That would entail updating the release notes for the LLVM upgrade PR to indicate that wasm targets are indeed affected. This would probably also detail the workaround of . Note that may not be enough given in . 't accept this change. That would require something along the lines of , perhaps modified to use then adding on features afterwards. "Fix" this change. This would require coordinating with upstream LLVM to change how this works. My guess is that given the existence of this seems unlikely to happen.


Question: Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` necessary to detect this target may change as the target becomes more stable. <ins> ## Enabled WebAssembly features The default set of WebAssembly features enabled for compilation includes two more features in addition to that which [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables: * `bulk-memory` * `atomics` For more information about features see the documentation for [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the `mvp` CPU in LLVM does not support this target as it's required that `bulk-memory`, `atomics`, and `mutable-globals` are all enabled. </ins>

There's not really a governing body per se around the Rust WebAssembly targets so there's not really a group of people we can point to and say "ok please tell us what to do". In lieu of that I would personally be tempted to go with route (1) because that keeps LLVM/C/C++ aligned with Rust and prevents divergence in the wasm ecosystem. Given the age of the proposal and the general intention for enabling more features by default over time as popular engines implement them this will also continue to change. So, concretely, I would propose: Do not change code as a result of this issue, leave it as-is. Update the release notes for LLVM 19 to indicate that WebAssembly targets are affected Update the WebAssembly documentation to explicitly document how to achieve and "MVP binary" by using and .
in the compiler team triage meeting. We think plan is reasonable at present but if there are additional issues or complications (such as it being more difficult to create an MVP binary than just using ), then option 2 (use by default) seems to be the way to go.
Looks like there may be complications. I am endeavouring to add a test to CI which asserts that a particular compiler invocation will generate MVP features. So far roadblocks are: Using is not sufficient. The attribute is not rewritten for IR of dependent libraries, like the standard library. That means that is only applied to the local crate and the standard library still codegens newer features. One can fix the above issue to additionally use but you'd have to pass for all active features. Not great. Even with there are still bulk-memory instructions in at least for example. These are coming from wasi-libc for the target which is what rustc tests in CI. This is not applicable to this issue as users typically use for this but would make adding a test difficult. Trying out the target locally I can't even get something to work it seems. LLVM is producing an invalid binary with alone when there's a memcpy in the binary. There's... a lot going on here apparently. Given the above I don't think that (2) I described above is a silver bullet by any means, even that seems doubtful to work. I need to investigate more what's going on here with all these features slinging all over the place.
Testing shows that plus Cargo's is sufficient.


Question: Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` necessary to detect this target may change as the target becomes more stable. <ins> ## Enabled WebAssembly features The default set of WebAssembly features enabled for compilation includes two more features in addition to that which [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables: * `bulk-memory` * `atomics` For more information about features see the documentation for [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the `mvp` CPU in LLVM does not support this target as it's required that `bulk-memory`, `atomics`, and `mutable-globals` are all enabled. </ins>

That's more-or-less the same as (1) so I'll take it on myself to document this and get it all written down. Unfortunately that doesn't lend itself well to a test in-repo but that's not necessarily worse than where we are at today.
I've proposed to close this issue as "this change is expected".


Question: Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` necessary to detect this target may change as the target becomes more stable. <ins> ## Enabled WebAssembly features The default set of WebAssembly features enabled for compilation includes two more features in addition to that which [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables: * `bulk-memory` * `atomics` For more information about features see the documentation for [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the `mvp` CPU in LLVM does not support this target as it's required that `bulk-memory`, `atomics`, and `mutable-globals` are all enabled. </ins>

and WebAssembly book () In Rust some requirements for WebAssembly targets. This makes Wasm binaries compiled with Rust (at least with default options/out of the box std) incompatible with older runtime environments, in particular not-so-old iOS safari (). Here is for example the support for Safari iOS 15.5 simulator: ! I searched but did not find any place where these requirements are written down. I think that this is a problem.
In principle Rust can produce binaries that only target the core subset of wasm 1.0 just fine. You do need to set some additional options with and build your own standard libraries though. But point taken, is missing dedicated pages on the wasm target that could contain this information.
The 2nd sentence right after the one you quoted outlines exactly what you need to do to take advantage of rustc’s capability to emit outputs to the wasm 1.0 spec (or any superset of it:) Make sure to do this and report back if you're still seeing the unexpected instructions/types/other entities after rustc is told to produce wasm binaries the way you need them to be. AFAIK, not for WASM.
Sorry, I realized I misunderstood your answer and deleted my post while you were answering it. Do you know how to show which features are enabled by default for a given target? I searched and did not find. I'm trying to discover whether is enabled by default on nowadays. As it seems to be because I am seeing types in the emitted wasm, even though I disabled the feature by "" in an environment variable RUSTFLAGS. It would be surprising to me that is built with that feature by default on wasm32, but maybe it is.
Hm, I'm actually not sure why you might be seeing simd128 in your modules. As far as I can tell it is not enabled by default for any wasm target. In order to print out features used you should look for lines in: For what it is worth I’ve been using this exact target at my $DAYJOB with a pretty primitive runtime and it has been working largely OOB if my memory serves me right. So it indeed could have something to do with your dependencies possibly using something like ? Not sure!


Question: Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` necessary to detect this target may change as the target becomes more stable. <ins> ## Enabled WebAssembly features The default set of WebAssembly features enabled for compilation includes two more features in addition to that which [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables: * `bulk-memory` * `atomics` For more information about features see the documentation for [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the `mvp` CPU in LLVM does not support this target as it's required that `bulk-memory`, `atomics`, and `mutable-globals` are all enabled. </ins>

It seems that the was built with as I see this WASM function: What I am not sure is whether 1. this was integrated with the standard library and then imported indirectly to my project, or 2. somehow one of the dependency managed to enable it by itself. I tend to favor 1 but I'm not sure. That is why it would be great for such things to be documented :-)
For reference, I asked on the about how the std lib is built.
I confirm that as of version 1.75, the standard library is not using any WebAssembly SIMD instructions. Here is my test: which shows nothing, so they get pulled in by the memchr package through some of my dependencies.
You yourself pointed out which crate produces the v128 types: . It uses to enable emission of these types, regardless of the global configuration it looks like. This is usually fine for other architectures, but rarely for wasm, so it might make sense to file an issue over there.
I fully agree and I just opened an issue there: BurntSushi/memchr
As a heads up I've proposed that close this issue with documentation of how to target MVP wasm.


Question: Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` necessary to detect this target may change as the target becomes more stable. <ins> ## Enabled WebAssembly features The default set of WebAssembly features enabled for compilation includes two more features in addition to that which [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables: * `bulk-memory` * `atomics` For more information about features see the documentation for [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the `mvp` CPU in LLVM does not support this target as it's required that `bulk-memory`, `atomics`, and `mutable-globals` are all enabled. </ins>

<!-- 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 to build a wasm binary with MVP opcode only, so I disabled the features: I expected to see no in the wasm binary. Instead, this happened: <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details
You can not deactivate default features, because std is prebuilt. You need to build std yourself. Also these features are considered the default by LLVM ever since the recent upgrade to LLVM 16: This should possibly be mentioned in the Rust 1.70 release notes though?
cc to confirm that we're fine with inheriting this change to default target features in Rust.
More context for this change can be found in these locations: - discussion about enabling new features in both Emscripten and LLVM. - the original LLVM patch for this - more follow-up discussion on LLVM In that sense this is an expected change, but at the same time the change was made with the expectation that most users are running on an engine that implements sign-extension. could you expand a bit more on your motivation for excluding these sign-extension instructions? I do agree, though, that this should be mentioned in the detailed release notes. It's unfortunately a bit opaque since not all users of wasm are intimately familiar with proposals and whether or not engines support them, but it's a change nonetheless worth mentioning.
I have tried to use , still not work: Our blockchain platform has used Wasm as a virtual machine running smart contracts and has been running steadily for many years. The MVP opcodes is fully sufficient for our use case. I hope there are ways to turn off these default extension features to avoid frequent upgrades every time a new feature is introduced.
Could you share the code used to reproduce this? These upgrades will not be frequent. This is the first time it's changed in 5 years.


Question: Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` necessary to detect this target may change as the target becomes more stable. <ins> ## Enabled WebAssembly features The default set of WebAssembly features enabled for compilation includes two more features in addition to that which [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables: * `bulk-memory` * `atomics` For more information about features see the documentation for [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the `mvp` CPU in LLVM does not support this target as it's required that `bulk-memory`, `atomics`, and `mutable-globals` are all enabled. </ins>

The use case I have for wanting to build without these extensions isn't critical (servers for a game which don't support the extensions in the old version of nodejs they're running), but a way to successfully disable them to be able to build for such environments would be appreciated!
It would be helpful to have a reproduction of this to run to test out fixes. I tested something locally and was sufficient to disable sign extension instructions. I don't know why isn't working and that may be an LLVM bug. I can't confirm whether this works for others though without a means of reproduction.
I just tried the following: compiled with: to make sure std being precompiled isn't causing problems, and it totally still contains the sign-ext instructions: So you are right, this is some sort of LLVM bug.
Confirming that results in a file without the sign-ext opcodes, while does not, in my testing as well.
would you perhaps know more about ? I would expect that with on the function then even without sign-extension instructions wouldn't get generated, but I'm not sure.
I wonder if this is a consequence of It looks like that might be unioning the module-level features along with the per-function features to form the effective feature set to use.
It can also be reproduced with:
FWIW, the above flags did not work for me with - the resulting binary still had sign-extension opcodes (namely ) - but this served as a workaround (): Command: ^ With the wasm-opt pass, sign-extension ops were gone; without the pass, still there. From the thread above, it sounds like those flags work for some people but not for others. My use case is (was) supporting old Apple devices stuck on iOS 12 and thus Safari 12. Now past this, the binary can load, but performance is enough of a problem to suggest dropping support anyway.
A slightly related issue is that the WebAssembly extensions used by default by the Rust compiler are not documented (besides in the change log, but new users won't look at it), I opened a specific issue for that () and just want to link it here.
As a heads up I've documentation about features to which I've currently got as flagged to close this issue. The documented solution for targetting MVP wasm is: which should solve the original OP of this issue.


Question: Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` necessary to detect this target may change as the target becomes more stable. <ins> ## Enabled WebAssembly features The default set of WebAssembly features enabled for compilation includes two more features in addition to that which [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables: * `bulk-memory` * `atomics` For more information about features see the documentation for [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the `mvp` CPU in LLVM does not support this target as it's required that `bulk-memory`, `atomics`, and `mutable-globals` are all enabled. </ins>

Other solutions in this issue such as using or that in conjunction with or others don't work for one reason or another. Using the target-cpu, however, plus recompiling the standard library with , does work.


Question: //! Types/fns concerning URLs (see RFC 3986) #![crate_name = "url"] <del> #![experimental] </del> <ins> #![deprecated="This is being removed. Use rust-url instead. http://servo.github.io/rust-url/"] </ins> #![crate_type = "rlib"] #![crate_type = "dylib"] #![license = "MIT/ASL2"]

Users should use the cargo-ified Deprecate for a release or two then delete. cc
:+1:
Related:
I tried this: Hoping to deprecate the whole crate, but then building this program does not emit any warning: I expected a deprecation warning on the line. Is there another way to achieve this, or do I need to annotate individual items in the crate?
That should have worked, but you may need to remove the annotation above (they may be conflicting). I would also personally find it very helpful to annotate methods in particular what the path forward is (or just a general post about how to migrate).
Removing worked, thanks. Should this deprecation go through the RFC process, or can I assume that the team wants it since filed this issue? The documentation at explains how to use rust-url, and in particular the concept of relative v.s. non-relative URL schemes (e.g. vs ) which is a bit unusual. I believe this sufficient to make migration straightforward, but I’m obviously biased. Any feedback on the documentation is welcome. (I’ll make the deprecation message include the documentation’s URL, it seems more useful landing page than the github repo.)
Having an issue is sometimes considered a "todo item" rather than "everyone has approved this", you'll find both styles of issues on the issue tracker. We don't have much precedent for deprecating an in-tree crate, so we're forging new territory here. I'd like to start moving crates out of the repo, however, so I hope to have some more on this topic soon.


Question: (accepted, macros_in_extern, "1.40.0", Some(49476), None), /// Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008). (accepted, non_exhaustive, "1.40.0", Some(44109), None), <ins> /// Allows calling constructor functions in `const fn`. (accepted, const_constructor, "1.40.0", Some(61456), None), </ins> // ------------------------------------------------------------------------- // feature-group-end: accepted features

The feature allows calling any expression of a tuple-like constructor in a : cc
Implemented on 2019-06-07 by in which was reviewed by
Is there anything else needs to be done to resolve this issue?
FCP and stabilization pull request.
Do you think you have time to write a report (e.g. in the style of ) and amend the reference after?
I propose that we stabilize . Tracking issue: Version target: 1.40 (2019-11-05 =beta, 2019-12-19 =stable). Tuple struct and tuple variant constructors are now considered to be constant functions. As such a call expression where the callee has a tuple struct or variant constructor "function item" type can be called : Consistency with other . This should also ensure that constructors implement traits and can be coerced to function pointers, if they are introduced. - Tests various syntactic forms, use in both and items, and constructors in both the current and extern crates. The case in should also get a test.
Thanks! Could you embed this report in a PR with the aforementioned test there as well? I'll FCP that PR.


Question: (accepted, macros_in_extern, "1.40.0", Some(49476), None), /// Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008). (accepted, non_exhaustive, "1.40.0", Some(44109), None), <ins> /// Allows calling constructor functions in `const fn`. (accepted, const_constructor, "1.40.0", Some(61456), None), </ins> // ------------------------------------------------------------------------- // feature-group-end: accepted features

When using to create an enum variant in Rust 1.37+, we get an error: results in: but if the enum is constructed explicitly, the compilation succeeds: Looking at , it looks like should be considered a with . Playground links for both variants: ,
Duplicate of (will close in a bit). It seems like folks open this issue because on stable, the error message does not point to the tracking issue, e.g. you don't see: can we fix this?
I think we should just stabilize it
Is this diagnostics problem specific to this feature gate? I meant a more general fix to const-fn related gates.
Not sure. I thought we're using the normal feature gate infra
Reopening this to make sure we add a test per


Question: <ins> error[E0425]: cannot find value `bogus` in this scope --> $DIR/issue-59134-0.rs:8:27 | LL |         const FLAG: u32 = bogus.field; |                           ^^^^^ not found in this scope error: aborting due to previous error For more information about this error, try `rustc --explain E0425`. </ins>

When using this branch of bitflags: through a patch in a local directory rls crashes with the following errors:
i had enabled dev overrides for dependencies in using: removing that out the output from rls is now the normal debug flags but still the same errors:
This is now causing widespread ICEs in the RLS. Nominating to get this fixed (maybe has an idea?). See for a simpler reproducer.
I encountered this issue trying out which causes rustc to crash on when invoked by RLS. I can confirm it's the exact same backtrace as
I ran into this trying out on Windows 10. RLS inside vscode ends up panicking with this backtrace: (note for repro: I had changed the default feature in tui-rs to be "crossterm" because the default feature "termion" doesn't compile on windows - but after the termion compile errors, rustc was giving me a similar panic anyway)
JFYI I could work around this problem by adding to my
I tried that with the tui-rs (it had ) but same panic. [Edit] you're right, I had missed the inside the version.
Thanks !
Running into the same issue when trying to build Clap
Same issue in vscode on linuxmint and rust 1.34.1 when trying to build glib (dependency of gtk).
There is no need to list every crate which depends on , it only clutters the thread and makes less visible.
Here's a small repro, extracted from what is doing: I'm struggling to get a repro without the compile error, though.
Thank you for such a small repro! I’ll take a closer look tomorrow and see what may be causing that. On Tue, 7 May 2019 at 22:32, Sean Gillespie <:
Looks like isn't written back for a resolution error? That still repros without , right?
Correct, it does. Further minimized repro:
Interesting. I managed to reduce it to: with: Any other combination is okay, it has to be under under and it has to be combined with a field access (bare unknown identifier doesn't ICE). I'm only guessing but it seems that it tries to emplace def 'path' under a which seems to skip a def path segment?


Question: <ins> error[E0425]: cannot find value `bogus` in this scope --> $DIR/issue-59134-0.rs:8:27 | LL |         const FLAG: u32 = bogus.field; |                           ^^^^^ not found in this scope error: aborting due to previous error For more information about this error, try `rustc --explain E0425`. </ins>

I think this is confirmed by A, what I believe is, more accurate guess is that we somehow don't correctly nest appropriate typeck tables when visiting .
Oh, you need to have one table per body: look in HIR for fields and map all of those cases back to the AST. This makes a lot more sense now: so is not wrong, but is looking in the wrong place.
What about this: Seems like we need to before walking the expression of the associated const?
Hm, probably! I imagined the problem is we don't nest it before visiting trait items (hence missing segment) but you may be right! Let's see :sweat_smile:
With the fix applied this still ICEs on (this time for type) which means we should nest tables for as well


Question: <del> //@ known-bug: #111699 //@ edition:2021 //@ compile-flags: -Copt-level=0 #![feature(core_intrinsics)] use std::intrinsics::offset; fn main() { let a = [1u8, 2, 3]; let ptr: *const u8 = a.as_ptr(); unsafe { assert_eq!(*offset(ptr, 0), 1); } } </del>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</detailsAdding an suffix fixes the issue: The error first appears with the toolchain. It works fine with .
The offset intrinsic does not support doing this, it requires isize or usize. ICEs using intrinsics wrongly are expected and not a bug. Thanks for the report anyways.
Shouldn't a occur for the argument?
There is nothing to be coerced to, since the intrinsics accept any type on the type level.
Is this specific to the intrinsic? I tried a couple of other intrinsics, and the compiler complained about mismatched types: : : Doing the same for results in an ICE, e.g.:
the intrinsic is generic, that's why it passes type checking
It's only generic in the first parameter. And has the exact same signature, but the issue doesn't occur for it.
Hi what is the motivation to keep this check as an ICE instead of a user friendly error since the error arises from misusage of the API?
Giving better errors for intrinsics and other internal-only features increases maintenance burden, so decided to not support it. Invalid usage of intrinsics may lead to ICEs (since intrinsics should not be used - I see for your case here it makes sense to use them in the tests, but I think you can live with ICEs). I guess it's not ideal that the ICE message says to report it - but fixing that is hard.


Question: "arch": "x86_64", "cpu": "x86-64", "crt-static-respected": true, <del> "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", </del> <ins> "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", </ins> "dynamic-linking": true, "env": "gnu", "has-rpath": true,

The commit a check that stars firing due to the changes to the default target layouts in LLVM 18 ():
Having this issue on as well: Why it's trying to compile for a 32-bit target is clearly beyond me because I'm using an entirely 64-bit host ― since happens to be the author of the crate this is failing on (namely, the 32-bit BIOS version of the bootloader crate which I explicitly avoid depending on for my intendedly UEFI-only kernel), pinging him for assistance.
I think this issue thread is about some failing tests in the Rust repo. Your issue seems to be specific to the crate, which required some updates to the custom targets it is using. I published a new version already, which should fix the issue. If you still have issues with the crate after a , please open an issue in the repository.


Question: ) -> R { I::with_global_cache(self, mode, f) } <ins> fn evaluation_is_concurrent(&self) -> bool { self.evaluation_is_concurrent() } </ins> }

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --After adding to , I get the ICE. The resulting : The full project: <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --
Looks like another label: +T-types +WG-trait-system-refactor +regression-from-stable-to-nightly
Stable passes, beta passes. Nightly passes with either or Discovered with It does sporadically succeed, thus needing to clean and rerun the build to make sure. Either something is up with or it only barely exercises these conditions in the parallel frontend, even after cleaning and running the build 100 times. Meanwhile, fails something like ~50% of the time on my machine.
stable passes obviously, as -Zthreads this is a unstable nightly-only flag?
Hm, not actually obvious given that works, though I suppose that does mean it isn't a regression per se. :^)
oh I thought you knew by now that this is the forbidden env flag that should only ever be used for bootstrapping and nothing else and we should not even tell users about it. If you set the flag, your "stable" will also eat nightly-only features, but why would that make a "to-stable" regression if you explicitly tell the compiler "please act like you are NOT a stable release"? I don't think it make sense to backport fixes for untable nightly features into stable lol
who mentioned backports?
The label is used to gather regressions between release channels, which are then discussed whether they are backport-worthy or not. Is that not how the label is used?
I don't really think regression-from-stable-to-nightly nor regression-from-stable-to-stable are used for that at all? Probably regression-from-stable-to-beta is?


Question: ) -> R { I::with_global_cache(self, mode, f) } <ins> fn evaluation_is_concurrent(&self) -> bool { self.evaluation_is_concurrent() } </ins> }

Pretty much what the title says, I've narrowed it down to and today's nightly with the following: I've attached some backtraces.
probably duplicate of but made more prevalent by next solver
Is it possible to provide a link to or a snippet of a reproducer? I know it probably happens to various crates, but it still would be nice to have something that reproduces.
See for an attached repro.
The repro case is basically the same as , but with other crates mentioned in the ICE logs from the issue comment.


Question: ) -> R { I::with_global_cache(self, mode, f) } <ins> fn evaluation_is_concurrent(&self) -> bool { self.evaluation_is_concurrent() } </ins> }

Compile with latest Nightly got ICE like below: when compiling in code OS: x86_64-apple-darwin
cc
Wyvern, could you provide some sort of reproducer? A link to some commit in some repository or better yet a smaller stripped down version of it?
Can you provide an example which triggers this behavior?
I'm not sure which commit/PR of lead to this crash, sometimes it compiled successfully, sometimes it not. Add this info to original post, hope to help investigation.
are you running with greater than 1? The cache is broken when used with more than 1 thread (which we should fix)
Sorry, I wasn't clear. I meant a link to your project (the project you are trying to compile) if publicly accessible / not proprietary.
I can hit plenty of these while fuzzing with -Zthreads so yeah its probably that.
Yeah, I think was the culprit. Comment out this option crashes disappears.
the easiest fix to rustc is to just disable this assert when we're using more than 1 thread. I've only it for debugging purposes to detect cases where we unnecessarily recompute cache entries
just hit this while trying to bootstrap with Zthreads :sweat_smile:
cc as this also showed up in your ci test run ^^
When I just disable this assert, all relevant UI tests passed with no other bugs or ICE
samle code that triggers this in around 5 of 6 cases with -Zthreads=16


Question: <ins> // build-fail #![feature(track_caller)] fn main() { (0..) .map( #[target_feature(enable = "")] //~^ ERROR: the feature named `` is not valid for this target //~| ERROR: `#[target_feature(..)]` can only be applied to `unsafe` functions #[track_caller] //~^ ERROR: `#[track_caller]` requires Rust ABI |_| (), ) .next(); } </ins>

This code () Produces ICE on any channel
This is the same issue as , attributes on expressions are not converted into HIR properly.
I checked on latest nightly - isn't produced anymore while this one still throws ICE.
could you reopen this issue?
triage: P-high. Removing nomination.
Reduced somewhat:


Question: } _ => bug!("Detected `&*` but didn't find `&*`!"), }; <del> *rvalue = Rvalue::Use(match mtbl { Mutability::Mut => Operand::Move(new_place), Mutability::Not => Operand::Copy(new_place), }); </del> <ins> *rvalue = Rvalue::Use(Operand::Copy(new_place)) </ins> } if let Some(constant) = self.optimizations.arrays_lengths.remove(&location) {

Since InstCombine can now introduce where there was none before, without checking that the value is in fact not used afterwards. This may cause a value to be marked as uninitialized by the dataflow, but still be used in that uninitialized state. If InstCombine ran before the generator transform this would be acutely unsound and could probably be exploited directly, but other than that transform I don't think we rely on this property yet. This impacts , which does run after InstCombine and relies on the dataflow. I've observed this on , where it produces this diff: The second use of occurs despite the first move deinitializing the local. cc
Maybe we should stop making instcombine convert to ? This could be done in the pre-codegen cleanups, but for MIR it is wrong to use or on such values in general. Alternatively instcombine needs to start using dataflow to only insert moves when the site is the last use of the local.


Question: <ins> error[E0412]: cannot find type `Oper` in this scope --> $DIR/issue-54966.rs:3:27 | LL | fn generate_duration() -> Oper<impl FnMut()> {} |                           ^^^^ not found in this scope error: aborting due to previous error For more information about this error, try `rustc --explain E0412`. </ins>

I expected just a compiler error . Compiler panicked: Meta
This is fixed in the beta version (1.30).


Question: <ins> error[E0412]: cannot find type `Oper` in this scope --> $DIR/issue-54966.rs:3:27 | LL | fn generate_duration() -> Oper<impl FnMut()> {} |                           ^^^^ not found in this scope error: aborting due to previous error For more information about this error, try `rustc --explain E0412`. </ins>

This lets you get a mutable reference to an immutable value under a specific case. Code: From what I can tell, the tuple and at least two depths of Enums are necessary, along with an on the right side. There's probably other variations, but that seems to work well enough. Expected output would be a compile error, instead output is This works on both stable and nightly
would fix this as well?
Fixed by . Off: I wonder why we can't ship nll yet. It would solve so many issues right now, because of the match ergonomics sigh Match ergonomics produces roughly 10% of all errors/unsoundness/ICEs atm (at least it feels like this)
Yes correctly fixed this issue.


Question: <ins> // run-rustfix fn main() { let a: usize = 123; let b: &usize = &a; if true { a } else { *b //~ ERROR `if` and `else` have incompatible types [E0308] }; if true { 1 } else { 1 //~ ERROR `if` and `else` have incompatible types [E0308] }; if true { 1 } else { 1 //~ ERROR `if` and `else` have incompatible types [E0308] }; } </ins>

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: I expected that the help text would give syntactically correct code, or that there would be no help text. Instead, this happened: The provided code snippet is not valid - it tries to deference the else-block, which is impossible. Better would be to put the inside the else-block. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: Also occurs on stable, 1.50.0. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim I have a fix for this bug + an improvement. Gotta got for now but will submit the PR later today.


Question: <ins> error: argument to `panic!()` in a const context must have type `&str` --> $DIR/issue-66693-panic-in-array-len.rs:8:20 | LL |     let _ = [0i32; panic!(2f32)]; |                    ^^^^^^^^^^^^ | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $DIR/issue-66693-panic-in-array-len.rs:12:21 | LL |     let _ = [false; panic!()]; |                     ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-66693-panic-in-array-len.rs:12:21 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. </ins>

The panic payload of the macro (as passed on to ) is generic, but the CTFE panic support assumes it will always be an . This leads to ICEs: Cc
I guess we could support this, but we'd have to find some way to render the errors. Maybe we need to wait for const traits so we can require const Debug?
Alternatively constck could require the argument to have type .
also requires a
Yeah, the libcore panic machinery does not support non-format-string panics.
Aye, left out the latter of my message. is likely the most common argument to , and it's not unusual with e.g. ; so I agree that waiting for const traits before supporting any other arguments is reasonable.
Im hitting this ICE on stable without feature flag:
Hm indeed, that is interesting: any idea why we go on here after seeing an error? Does this kind of behavior mean any part of CTFE is reachable on stable somehow?
yes. We're not gating CTFE on whether there were stability (or any other static checks) failing. I've been abusing this since 1.0 to demo things on the stable compiler and never got around to fixing it. I don't even know if we have a tracking issue for it.
:rofl: So what would be a possible approach here? Replace such consts by early enough that their MIR never actually gets evaluated? We might as well use this issue, IMO...
That would require us to mutate all MIR and potentially even HIR. Other possible solutions: poison the mir Body if const checks fail (by adding a field like or by just nuking the body by replacing it with ) and thus make allow const evaluation to check if the mir Body failed the checks and bail out before doing anything make the have an field similar to
On second thought, let's leave this issue for the ICE, and make a new one for "we can trigger nightly-only const code on stable because we don't abort compilation early enough":
Given that this ICE is pre-existing, as shown by , can we un-block ? I'd really like to see const_panic stabilized, and this seems like a minor issue to be blocking on.
That comment is an example of accidentally partially exposing an unstable feature on stable -- a separate bug tracked in I don't see how that's an argument for shipping that feature on stable when it is broken.


Question: <ins> error: argument to `panic!()` in a const context must have type `&str` --> $DIR/issue-66693-panic-in-array-len.rs:8:20 | LL |     let _ = [0i32; panic!(2f32)]; |                    ^^^^^^^^^^^^ | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $DIR/issue-66693-panic-in-array-len.rs:12:21 | LL |     let _ = [false; panic!()]; |                     ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-66693-panic-in-array-len.rs:12:21 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. </ins>

In particular, applies to all unstable const features. Fixing this bug here is not even that hard I think: somewhere around here there needs to be a check that the argument has type . Re: , AFAIK that one is also blocked on figuring out how the diagnostics should look like, and a further concern (though maybe not blocking) is .
I guess that might make this a non-issue, where it is proposed also would require as first argument.
For reference: , which was recently merged. The plan is to fix the behaviour of in the Rust 2021 edition. Given that this ICE is listed as a blocker for , does this mean that stabilizing that will have to wait for the next edition?
No, because breaking changes are allowed to be made to unstable features without moving to a new edition; that's kinda the whole idea. The 2021 edition will effectively just extend the same restriction to all invocations, const context or not.
I'd like to tackle this but I'm not very experienced with the CTFE code. I get that we need to check from the that we've matched on in this branch and we need to match on the enum, but: For the first question, I see and that we probably want to check that the type of the tuple and that there's variants of that are , but do we stop the iteration when we get one that is a type? Is the projection list always guaranteed to terminate in a variant of that has a ? And once we have an instance of , do we just check that there's any_ projection in the list that has a ?
you can use to get the type of the . Then you can test its to be .


Question: tinfo: *const TypeInfo, dest: extern "C" fn(*mut libc::c_void) -> *mut libc::c_void, ) -> !; <del> fn __gxx_personality_v0( version: c_int, actions: uw::_Unwind_Action, exception_class: uw::_Unwind_Exception_Class, exception_object: *mut uw::_Unwind_Exception, context: *mut uw::_Unwind_Context, ) -> uw::_Unwind_Reason_Code; </del> }

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: Compiling with , after the emsdk is activated and emcc works, to compile properly Instead, this happened: Prints this error: I've tried adding to no avail <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details
runs successfully
Also is broken on ubuntu with the same error message (at least windows subsystem for linux)
rustc 1.53.0-nightly ( 2021-04-24) emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.12 () Here's some info I gathered: Rust tries to . I think Rust is assuming that this symbol comes from emscripten. emscripten has a : libc++abi.a: emscripten exceptions: this is what rustc is trying to use; libc++abi-noexcept.a: no exceptions: does not compile libc++abi-except.a: wasm exceptions: experimental; in emscripten's repo shows that was never compiled into libc++abi.a by This commit looks suspicious: Prior to emscripten SDK version 2.0.10, I think has been and never did anything. Rust probably shouldn't be calling a stubbed function. seems untested if you ask me because I don't know how it could ever have worked. I successfully compiled hello world with emscripten SDK version 2.0.9. That version still has the stub.
label I-prioritize T-compiler O-wasm
thanks for the analysis. Assigning priority as discussed in the of the Prioritization Working Group. Let's find someone who can have a look at this. label -I-prioritize +P-high +I-nominated
I recall with the LLVM 11 upgrade, the compat notes mentioned which version of Emscripten to use when compiling with the target.


Question: tinfo: *const TypeInfo, dest: extern "C" fn(*mut libc::c_void) -> *mut libc::c_void, ) -> !; <del> fn __gxx_personality_v0( version: c_int, actions: uw::_Unwind_Action, exception_class: uw::_Unwind_Exception_Class, exception_object: *mut uw::_Unwind_Exception, context: *mut uw::_Unwind_Context, ) -> uw::_Unwind_Reason_Code; </del> }

Once this bug is resolved, can we add a similar note for the releases that upgrade Rust to LLVM 12?
As mentioned the panic=unwind strategy is broken on wasm32-unknown-emscripten. I recommend to switch default to panic=abort. Note that also rust std lib has to be rebuilt with panic=abort to fix the undefined symbol errors. Testing on my side showed that the problem could be fixed by changing TargetOptions on line 38 to "panicstrategy: PanicStrategy::Abort," in file. Unfortunatelly I do not have experience in preparing pull request and have no capacity to get into it now.
This issue can be solved by setting the env var which will override any flags passed to emcc. See this comment - Passing these flags using the won't work, as they are not passed to the linker. I received this error in two places, one for symbol and one for , hence the flag.
Reported this on Emscripten:


Question: // except according to those terms. struct Foo { <ins> field1: i32, //~ NOTE `field1` first declared here </ins> field1: i32, <del> field1: i32, //~ ERROR E0124 </del> <ins> //~^ ERROR field `field1` is already declared [E0124] //~| NOTE field already declared </ins> } fn main() {

From: src/test/compile- Error E0124 needs a spanlabel and a spannote replaced with a span_label, updating it from: To:
Error message updated in .


Question: // for closures and async closures, respectively. match closure_kind { hir::ClosureKind::Closure <del> if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() => {} </del> <ins> if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() => { self.extract_sig_from_projection(cause_span, projection) } hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) if self.tcx.async_fn_trait_kind_from_def_id(trait_def_id).is_some() => { self.extract_sig_from_projection(cause_span, projection) } // It's possible we've passed the closure to a (somewhat out-of-fashion) // `F: FnOnce() -> Fut, Fut: Future<Output = T>` style bound. Let's still // guide inference here, since it's beneficial for the user. </ins> hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) <del> if self.tcx.async_fn_trait_kind_from_def_id(trait_def_id).is_some() => {} _ => return None, </del> <ins> if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() => { self.extract_sig_from_projection_and_future_bound(cause_span, projection) } _ => None, </ins> } <ins> } /// Given an `FnOnce::Output` or `AsyncFn::Output` projection, extract the args /// and return type to infer a [`ty::PolyFnSig`] for the closure. fn extract_sig_from_projection( &self, cause_span: Option<Span>, projection: ty::PolyProjectionPredicate<'tcx>, ) -> Option<ExpectedSig<'tcx>> { let projection = self.resolve_vars_if_possible(projection); </ins> let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1); <del> let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty); </del> debug!(?arg_param_ty); let ty::Tuple(input_tys) = *arg_param_ty.kind() else {

When using async closures, rust since around 1.80 fails to infer parameter type in most scenarios. I expected to see this happen: All options used to work in past versions of rust Instead, this happened: Without explicit type hint it fails It used to work in the past, around 1.79
We don't typically mark nightly features with labels, so I'm removing those. Are you certain this regressed in 1.80? This should have regressed in , when I reimplemented async closures completely.
I am not 100% sure when it happened. I used to work with 1.7x a couple of months ago. Then I left my project for a moment. When I came back, after updating to 1.81 it no longer works. IIRC before leaving it was around 1.79, but I'm not sure.
This limitation to async closure signature inference has to do with the fact that the combinators you're using (e.g. ) take regular trait bounds. Is there a particular reason you're using async closures here? They're really not gaining you anything other than a dependency on the nightly compiler.
I posted a minimal example, indeed async does not make much sense here, but in project I work on it does. As a workaround I've just annotated parameters with original types, but I still believe this is a bug.
This indeed regressed in .
While the problem from first message in issue seems to be fixed, there are still cases when this fails. One of examples is when using instead of , when closure is expected to return : Should I open new issue, or this one will be reopened?
Please open a new issue, since it's likely a different root cause


Question: match &mut fields { Fields::Vec(pats) => { for (i, pat) in new_pats { <del> pats[i] = pat </del> <ins> if let Some(p) = pats.get_mut(i) { *p = pat; } </ins> } } Fields::Filtered { fields, .. } => {

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. -- <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Seems to be the indicated function:
.
Assigning as discussed as part of the and removing . label -I-prioritize +P-medium
Oh this is ugly x) Reading the PR, the problem is that there are two ways to match a Box: via a box-pattern or via . But we can't know which will be used based on the type only. Current code assumes box-patterns, hence the error. The PR works because luckily all the fields of are private. If you tried pattern-matching within the module that defines , you'd get crazy results like (actually wouldn't even typecheck): We'll need to figure out a real solution when we implement generalized Deref patterns...
in that case we should open a new ticket for that work, tagged something like or something.


Question: /// /// # Panics /// <del> /// When the number is negative, zero, or if the base is not at least 2; it /// panics in debug mode and the return value is 0 in release /// mode. </del> <ins> /// This function will panic if `self` is less than or equal to zero, /// or if `base` is less then 2. </ins> /// /// # Examples ///

Filing since it's in pFCP over at , and I don't think we can reasonably change it after stabilization (especially since it's documented). Currently, in release mode evaluates to . (And same for the other bases.) It's not obvious to me that that's necessarily the best option. For example, the implementation is slightly nicer on CPUs from the past or so (and I think would be just as nice on older ones ), but gives <subas u32</subin the wrapping case. It also might be nice to have the wrapping case give something clearly different from any of the successful cases, rather than having and give the same thing. For example returns in release mode, which isn't a power of two (according to ), so it's distinguishable from all the non-wrapping cases. This only affects // on . (The checked versions don't have an issue, nor do the ones on .)
I couldn't find any previous discussion of what the exact wrapping value ought to be, just that there ought to be one, as opposed to a . There was this note: For which I think the implementation I mention above is a counter-example, albeit only for the base-2 case. Also, currently in release mode is essentially , so we can pick any value we want to return for those cases. FWIW, the implementation in gives as the result for .
In Rust we try to do the right thing. Not even Python gives -1. Let's avoid in-band error values in Rust.
What's your proposal for what the "right" thing is, then? That panic in release too? Arguably the most-correct value is −∞ (like ), but that doesn't fit in any of our integer types. So would make sense, but release mode for the other un-prefixed things is wrapping, not saturating.
Python has some functions that return in-band values: "xy".find("y") 1 "xy".find("z") -1 From Rust I expect something better. In Rust if a function isn't naturally total and you can't restrict its input, then I expect it to return Option (or Result), or when that's isn't ergonomic enough, a panic (in release too). Returning -1 is dangerous as that Python find function, returning 0 is not math.


Question: /// /// # Panics /// <del> /// When the number is negative, zero, or if the base is not at least 2; it /// panics in debug mode and the return value is 0 in release /// mode. </del> <ins> /// This function will panic if `self` is less than or equal to zero, /// or if `base` is less then 2. </ins> /// /// # Examples ///

I think returning (wrapped if necessary) is a clear distinguish between normal and error result. Returning an is not ideal currently because it will makes the function practically unusable in const context (before const unwrap is stabilized) If getting closest to the "correct" math answer, how about choosing ? However it seems weird and still seems better to me
Perhaps in other languages. Rust is known for being better than that. I have chosen to use Rust because it's a bit better than Python (see above). Let's return Option and and wait for const unwrap to be stabilized before making ilog const, then.
That's what does already. Is your proposal, then, that the version of just shouldn't exist on ? How do you square that with precedent of other things -- like or -- that have the version return , but the un-prefixed one wrap in release mode?
what about treating it like division by zero and just panicking?
I'd be fine with -1. The point of these methods is to get fast code (otherwise many won't use them and will prefer to do to keep the code branchless and avoid the ugly ) and a defined value outside of the usual input range. (from above) is a good example. If you want stricter guarantees than that, you can use .
A minor point: being 0 is actually a reasonable choice - even though 0 is not a power of two, it is congruent to the correct power of two modulo 2^32 (which is 2^32 itself), so exactly what is expected in wrapping arithmetic. But unfortunately there's no "−∞ mod 2^32" that could be used for .
Modular arithmetic is confusing in the context of logarithm, if you want to return the discrete logarithm of 0 in the release mode, then there are a lot of candidates, because (in case of ) therefore in the sense of modular arithmetic, could be any multiple of . If you really want to achieve something close to , then I guess the best value is as I mentioned above. (Interestingly though, = , which is a multiple of 8, 16, 32, 64, 128)
That's certainly a possibility. suggested not doing that back in the original PR, though:
Doesn't implicitly include a check for zero in the code generated?


Question: /// /// # Panics /// <del> /// When the number is negative, zero, or if the base is not at least 2; it /// panics in debug mode and the return value is 0 in release /// mode. </del> <ins> /// This function will panic if `self` is less than or equal to zero, /// or if `base` is less then 2. </ins> /// /// # Examples ///

]
Also, since the methods are implemented for signed integers as well, another issue would be the log of negative values. For example for floating-point, would return −∞, but would return NaN. So if would return some value for −∞, would panic anyway, or return some value?
I don't think it makes sense to do anything other than panic in the case of negative values, which in turn is probably an argument for panicking on zero as well. I guess one could argue that "wrapping" could be interpreted as wrapping the preimage to fit in the function's domain (rather than just wrapping the image to fit in the range) but IMO that would be entirely unintuitive and unhelpful as well. After thinking about it a bit, it seems to me that simply cannot have a meaningful variant, because semantics (as reasonably interpreted) cannot answer the question "what should the result be for values for which the original function is undefined?" There are no elements in 's domain for which the function underflows or overflows.
That's only the case on old chips. As I linked in the OP (), that happens in the instruction generation very-last-phase of LLVM on old chips, and on newer chips it knows to emit a different instruction instead of the branching code: The good news is that it looks like newer LLVM has gotten smarter here. It used to be that, because of how the intrinsic gets translated, it would emit obviously-redundant assembly on old chips in some code patterns, as you could see in Rust 1.16:
is supposed to find the largest so that . Since computers use wrapping arithmetic, the equation is better put as . The largest satisfying this equation in the case is (aka ). So if we consider a wrapping to be the inverse of , makes perfect sense (and is very efficient on modern CPUs, as others have pointed out). I would also advocate for to be as a method which always has this behaviour. [Edit: it already behaves that way]
Note that's already how works . It's just that it wraps to in release right now -- this issue doesn't propose removing the panic in debug behaviour, just to figure out what the best value for release would be.


Question: /// /// # Panics /// <del> /// When the number is negative, zero, or if the base is not at least 2; it /// panics in debug mode and the return value is 0 in release /// mode. </del> <ins> /// This function will panic if `self` is less than or equal to zero, /// or if `base` is less then 2. </ins> /// /// # Examples ///

Since, from the notes, it seems like the libs-api meeting today said "how about we panic instead of wrap", I'll try to answer my own question from above: I would propose the following rule: Conceptually, the result is first calculated in true ℤ (aka to infinite precision). Then for the non-prefixed versions If that result is undefined (, , etc), then it panics (regardless of compilation mode) If that result is defined and fits in the result type, it's returned. If that result is defined but not in-range for the result type, it panics if overflow checking is enabled, and wraps (mod 2<supN</supfor uN) if overflow checking is disabled. I think that's consistent with all the current precedent. ( also is good reading about the distinction I'm drawing here.)
I would redefine that to include cases where the result is defined but you can't wrap that to the result type, e.g. or . that would cover and
I agree, but was considering that implied by "in ℤ", as that set includes neither −∞ nor ⅈ. (Like how is , not a complex number.)
I'm not necessarily against panicking in that case. I just pointed out how it's a bit inconsistent with the other operations we have on integers. (Whether it makes sense for the other operations to have this difference in behavior between debug and release mode is an interesting discussion too, but I'm afraid that ship has sailed.) The reason we don't always panic on overflow for and etc. is performance. It's simply too costly to do. (We always panic on division by zero because that's both mathematically undefined (even modulo 2<supBITS</sup) and because on some platforms, the native division instruction will signal/abort/trap the program when the right hand side is zero.) We applied the same reasoning to things like and , although one might reasonably argue that for those it might be fine to always panic, since these are not as common as and . (You could then still use if you really want to make sure there's no check, if you're sure it's unnecessary.) That seems reasonable. It'd be nice if it'd still be easy to get the efficient calculation through some usage of or though.


Question: /// /// # Panics /// <del> /// When the number is negative, zero, or if the base is not at least 2; it /// panics in debug mode and the return value is 0 in release /// mode. </del> <ins> /// This function will panic if `self` is less than or equal to zero, /// or if `base` is less then 2. </ins> /// /// # Examples ///

It looks like llvm isn't smart enough today to turn into simply a count-leading-zeros and a subtract instruction. :(
We discussed this again in the libs-api meeting, and we concluded pretty much the same as rule, meaning that these functions should panic on zero in all compilation modes, since there's not a modulo-2<supN</sup-correct result.


Question: let lookup = &lookup.as_str(); let max_dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3); <del> let (case_insensitive_match, levenshtein_match) = name_vec </del> <ins> // Priority of matches: // 1. Exact case insensitive match // 2. Levenshtein distance match // 3. Sorted word match if let Some(case_insensitive_match) = name_vec.iter().find(|candidate| candidate.as_str().to_uppercase() == lookup.to_uppercase()) { return Some(*case_insensitive_match); } let levenshtein_match = name_vec </ins> .iter() .filter_map(|&name| { let dist = lev_distance(lookup, &name.as_str()); if dist <= max_dist { Some((name, dist)) } else { None } }) // Here we are collecting the next structure: <del> // (case_insensitive_match, (levenshtein_match, levenshtein_distance)) .fold((None, None), |result, (candidate, dist)| { ( if candidate.as_str().to_uppercase() == lookup.to_uppercase() { Some(candidate) } else { result.0 }, match result.1 { None => Some((candidate, dist)), Some((c, d)) => Some(if dist < d { (candidate, dist) } else { (c, d) }), }, ) </del> <ins> // (levenshtein_match, levenshtein_distance) .fold(None, |result, (candidate, dist)| match result { None => Some((candidate, dist)), Some((c, d)) => Some(if dist < d { (candidate, dist) } else { (c, d) }), </ins> }); <del> // Priority of matches: // 1. Exact case insensitive match // 2. Levenshtein distance match // 3. Sorted word match if let Some(candidate) = case_insensitive_match { Some(candidate) } else if levenshtein_match.is_some() { </del> <ins> if levenshtein_match.is_some() { </ins> levenshtein_match.map(|(candidate, _)| candidate) } else { find_match_by_sorted_words(name_vec, lookup)

Given the following code: The current output is: <!-- The following is not always necessary. --Ideally the output should include a note suggesting the variant with the same name (but different case):
label +C-enhancement +D-newcomer-roadblock
This only doesn't Just Work because the Levenshtein thing is case sensitive, right? There is some special-casing for case-insensitive suggestions but afaict it only applies if the case-sensitive Levenshtein distance is also already low, which seems wrong at first glance.
im working on this Edit: I'm not working on this anymore because I ran out of time getting past incremental compilation / llvm errors after a rebase.
Okay, judging by , this is explicitly not supposed to work. shrug emoji Edit: Okay, maybe that test case didn't really care. The use of case-insensitive match as tie breaker for equal levenshtein distance only was introduced with afaict.


Question: = note: this expectation will create a diagnostic with the default lint level warning: this lint expectation is unfulfilled <del> --> $DIR/expect_unfulfilled_expectation.rs:24:22 </del> <ins> --> $DIR/expect_unfulfilled_expectation.rs:17:14 | LL |     #[expect(unused_mut, reason = "this expectation will create a diagnostic with the default lint level")] |              ^^^^^^^^^^ | = note: this expectation will create a diagnostic with the default lint level = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: this lint expectation is unfulfilled --> $DIR/expect_unfulfilled_expectation.rs:27:22 | LL |     #[expect(unused, unfulfilled_lint_expectations, reason = "the expectation for `unused` should be fulfilled")] |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the expectation for `unused` should be fulfilled = note: the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message warning: this lint expectation is unfulfilled --> $DIR/expect_unfulfilled_expectation.rs:27:22 </ins> | LL |     #[expect(unused, unfulfilled_lint_expectations, reason = "the expectation for `unused` should be fulfilled")] |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the expectation for `unused` should be fulfilled = note: the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message <ins> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` </ins> <del> warning: 4 warnings emitted </del> <ins> warning: 6 warnings emitted </ins>

I tried this code: I expected to catch lint and suppress it, as it should. Instead, compiler issues a diagnostic both about unused value and unfulfilled lint expectation: It does work as expected though if is applied to function. I used the latest stable (Rust 1.81), but it is reproducible both on latest beta (2024-09-04 ) and latest nightly (2024-09-05 ). labels: +F-lintreasons, +A-diagnostics <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
This issue is not limited to just . Others attrs like or don't work either. For instance, the following variant of the reproducer with replaced with emits the warning even though it shouldn't: Playground: This broken behaviour goes as far back as at least 2021 (couldn't build and test earlier rustc) We emit the lint on the HIR node corresponding to . However, the or levels, which are supposed to override the default level of the lint, are associated with or bound to the node underlying the as shown in the figure below: The end result is that the lint's level is never knocked down to or since when searching for levels we start from the node on which the lint is triggered and go up the chain of parents. So in this case we look for the level on and then on the and so on. We never look for it on the where the levels actually exist. As it happens in the lowered HIR does have the / attrs for both the node and its child node. However when adding the levels in the we do not add anything for the node as shown here (note the comment): If were to add the level for as well the issue will go away. However, if we do that we will still have one problem in the case of which is that we will end up with two expectations and the one on the will not be fullfilled and hence we will still see a warning about unfulfilled expectation. To prevent that I think we should take the following approach: when an attr like or etc.


Question: = note: this expectation will create a diagnostic with the default lint level warning: this lint expectation is unfulfilled <del> --> $DIR/expect_unfulfilled_expectation.rs:24:22 </del> <ins> --> $DIR/expect_unfulfilled_expectation.rs:17:14 | LL |     #[expect(unused_mut, reason = "this expectation will create a diagnostic with the default lint level")] |              ^^^^^^^^^^ | = note: this expectation will create a diagnostic with the default lint level = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: this lint expectation is unfulfilled --> $DIR/expect_unfulfilled_expectation.rs:27:22 | LL |     #[expect(unused, unfulfilled_lint_expectations, reason = "the expectation for `unused` should be fulfilled")] |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the expectation for `unused` should be fulfilled = note: the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message warning: this lint expectation is unfulfilled --> $DIR/expect_unfulfilled_expectation.rs:27:22 </ins> | LL |     #[expect(unused, unfulfilled_lint_expectations, reason = "the expectation for `unused` should be fulfilled")] |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the expectation for `unused` should be fulfilled = note: the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message <ins> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` </ins> <del> warning: 4 warnings emitted </del> <ins> warning: 6 warnings emitted </ins>

are present for more than one HIR node in the and if one node is the (direct or indirect) parent of the other node, then add the level only_ for parent node. This will take care of any lints on the child (since we always walk up the HIR hierachy as mentioned earlier) as well as the parent and it will not cause any warnings about missed expectations. I am new to this area so if someone can review this idea or suggest alternatives that will be great. since you seemed to have worked in this area recently, can you please weigh in?
Your investigation is accurate, and the fix is simple: visit the statement node when building lint levels. Do you mind making such a pr ? I don't think we need any special adjustment for cases, duplicated attributes are already taken into account, but a test won't hurt.
Thanks . Yes, I'll put together a PR. My only concern is if all we do is add the level at , although it will work perfectly for , etc., in the case of we will end up with an unfulfilled expectation on the node which will appear to the user as a warning. But anyway let me have a go and see what happens.
Opened draft PR that adds the lint on . It does suffer from the extra warning problem.


Question: severity: ChangeSeverity::Info, summary: "The `build.profiler` option now tries to use source code from `download-ci-llvm` if possible, instead of checking out the `src/llvm-project` submodule.", }, <ins> ChangeInfo { change_id: 129152, severity: ChangeSeverity::Info, summary: "New option `build.cargo-clippy` added for supporting the use of custom/external clippy.", }, </ins> ];

I'm pretty sure it is possible to set custom paths for , & in but not for clippy.
label +T-bootstrap