jiebi/CodeConvo huggingface dataset:
Code change:
without modifying the original"] #[inline] #[track_caller] <del> #[rustc_inherit_overflow_checks] #[allow(arithmetic_overflow)] </del> pub const fn ilog(self, base: Self) -> u32 { <del> match self.checked_ilog(base) { Some(n) => n, None => { // In debug builds, trigger a panic on None. // This should optimize completely out in release builds. let _ = Self::MAX + 1; 0 }, } </del> <ins> assert!(base >= 2, "base of integer logarithm must be at least 2"); self.checked_ilog(base).expect("argument of integer logarithm must be positive") </ins> } /// Returns the base 2 logarithm of the number, rounded down. /// /// # Panics /// <del> /// When the number is negative or zero 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. </ins> /// /// # Examples ///

Related discussion:
text: 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.
Code change:
without modifying the original"] #[inline] #[track_caller] <del> #[rustc_inherit_overflow_checks] #[allow(arithmetic_overflow)] </del> pub const fn ilog(self, base: Self) -> u32 { <del> match self.checked_ilog(base) { Some(n) => n, None => { // In debug builds, trigger a panic on None. // This should optimize completely out in release builds. let _ = Self::MAX + 1; 0 }, } </del> <ins> assert!(base >= 2, "base of integer logarithm must be at least 2"); self.checked_ilog(base).expect("argument of integer logarithm must be positive") </ins> } /// Returns the base 2 logarithm of the number, rounded down. /// /// # Panics /// <del> /// When the number is negative or zero 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. </ins> /// /// # Examples ///

Related discussion:
text: 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?
Code change:
without modifying the original"] #[inline] #[track_caller] <del> #[rustc_inherit_overflow_checks] #[allow(arithmetic_overflow)] </del> pub const fn ilog(self, base: Self) -> u32 { <del> match self.checked_ilog(base) { Some(n) => n, None => { // In debug builds, trigger a panic on None. // This should optimize completely out in release builds. let _ = Self::MAX + 1; 0 }, } </del> <ins> assert!(base >= 2, "base of integer logarithm must be at least 2"); self.checked_ilog(base).expect("argument of integer logarithm must be positive") </ins> } /// Returns the base 2 logarithm of the number, rounded down. /// /// # Panics /// <del> /// When the number is negative or zero 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. </ins> /// /// # Examples ///

Related discussion:
text: ]
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 &minus;&infin;, but would return NaN. So if would return some value for &minus;&infin;, 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.
Code change:
without modifying the original"] #[inline] #[track_caller] <del> #[rustc_inherit_overflow_checks] #[allow(arithmetic_overflow)] </del> pub const fn ilog(self, base: Self) -> u32 { <del> match self.checked_ilog(base) { Some(n) => n, None => { // In debug builds, trigger a panic on None. // This should optimize completely out in release builds. let _ = Self::MAX + 1; 0 }, } </del> <ins> assert!(base >= 2, "base of integer logarithm must be at least 2"); self.checked_ilog(base).expect("argument of integer logarithm must be positive") </ins> } /// Returns the base 2 logarithm of the number, rounded down. /// /// # Panics /// <del> /// When the number is negative or zero 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. </ins> /// /// # Examples ///

Related discussion:
text: 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.
Code change:
without modifying the original"] #[inline] #[track_caller] <del> #[rustc_inherit_overflow_checks] #[allow(arithmetic_overflow)] </del> pub const fn ilog(self, base: Self) -> u32 { <del> match self.checked_ilog(base) { Some(n) => n, None => { // In debug builds, trigger a panic on None. // This should optimize completely out in release builds. let _ = Self::MAX + 1; 0 }, } </del> <ins> assert!(base >= 2, "base of integer logarithm must be at least 2"); self.checked_ilog(base).expect("argument of integer logarithm must be positive") </ins> } /// Returns the base 2 logarithm of the number, rounded down. /// /// # Panics /// <del> /// When the number is negative or zero 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. </ins> /// /// # Examples ///

Related discussion:
text: 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.
Code change:
"this was erroneously allowed and will become a hard error in a future release" }).emit(); } <ins> fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt { Stmt { id: DUMMY_NODE_ID, kind, span } } </ins> }

Related discussion:
text: The idea of shortening to has been discussed many times before, and the general consensus always ends up being that it is not a good idea. I would like to propose something a bit different, so please hear me out. I propose that instead of aliasing to , we instead just make expand into when in the context of a variable declaration. For example: This solves the problems (readability, more concise) that people have with , whilst not causing the issues that people have (pattern matching and consistancy). The most common issue people have with aliasing to is that it doesn't fit well with patterns, like . However, gets rid of this problem, because you wouldn't write if you were trying to pattern match, so why would someone want to write ? You wouldn't do that, and it wouldn't compile. This would be optional, of course. would still work fine, and people would just have to option of removing the to let it be implied. There are a lot of other abbreviations used in rust (, , ) that all serve the purpose of writing less. It just doesn't feel right that one of the most commonly used keywords is so long. :heart::crab: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Rust wants to make to make you think when you try and use mutation, even if only a little bit, because mutation can be difficult to reason about. Shortening to doesn't fit this philosophy. Also, this makes mutation just as easy as no mutation. This will lead people to choose mutation because it will give them less compiler errors in the short term, and in doing so open themselves up to some weird bugs that could have been prevented with the syntactic salt that is . tldr: wasn't rejected because of the name , but because it allowed easy mutation, which runs counter to Rust's philosophy.
I politely disagree. In fact, it is actually the other way around. Using unnecessarily will cause compiler warnings, discouraging the use of unneeded mutability. The compiler doesn't warn when the use of is actually needed.
The fact that people will choose in the face of compiler warnings has been shown in practice, across many projects.
Code change:
"this was erroneously allowed and will become a hard error in a future release" }).emit(); } <ins> fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt { Stmt { id: DUMMY_NODE_ID, kind, span } } </ins> }

Related discussion:
text: Also, the problem isn't that people may choose to put just for the heck of it, but that they will unintentionally mutate something that was supposed to be immutable. And because it is being mutated, there is no warning, and they used because it is their default, it is their default because it gets rid of compiler errors that say they were trying to mutate things that are immutable even though they weren't supposed to mutate them in the first place. They will use because it is just as easy as making it immutable. So the problem is a bit more subtle than you seem to think.
Incorrect. Extreme brevity harms readability. See Perl. lol Readers would ignore the vs distinction far more often that vs , partially due to length difference, but works even better than say . It's true boilerplate often harms readability, but boilerplate requires some complexity be repeated, not merely the in . It harms readability even further if also works for , especially when you consider code readers need not actually know Rust. Rust syntax was designed largely to reduce cognitive load, not to reduce typing. We use , , and , not any shorter alternatives. And delegation RFCs have kinda given up the short syntaxes. I think Rust's omission of is now considered a mistake, but presumably helps C programmers. Rust has short keywords only really for fundamental "items" used repeatedly by basically every module. It's similar cognitive load if you write , , or , but actually just writing the shorter bare increases cognitive load. I think invokes the minor linguistic subtlety that variable means mutable binding, while acts like a common term for binding, which makes very slightly clearer.
The statement would be orthogonal to the current language in some sense though. is not a special syntax, but is composed of statement + pattern. It is in line with other places expects a pattern, where you can write , , or .
It seems unlikely to me that we would support as a short-hand. I'm personally opposed to it both because it adds unnecessary compiler complexity, stylistic schisms, and for the reasons outlined by However, I've taken the liberty of reusing this issue towards improved diagnostics: The idea here is to check . The idea here is to check: The relevant code is here: cc
claim
Error: Parsing assign command in failed: claim :)... Please let know if you're having trouble with this bot.
Code change:
"this was erroneously allowed and will become a hard error in a future release" }).emit(); } <ins> fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt { Stmt { id: DUMMY_NODE_ID, kind, span } } </ins> }

Related discussion:
text: Although I would also guess that the initial idea is very unlikely to end up accepted, it feels premature to unilaterally hijack the thread in your very first comment and make it have a different (and in a way opposite) purpose. Teams of the Rust project are designed to make decisions collectively. Improving diagnostics sounds good, but issue numbers are cheap.
Implementing something as a diagnostic actually brings you closer to a working implementation -- I think more proposals should start out as diagnostics. I will not bother the other language team members with not-fully-formed proposals that we will not accept in either case. I converted the issue into the most actionable and productive thing it could be. The place for ephemeral discussions is either on Discord or on internals. If you want to discuss this further, I'm available at Discord (but will not respond to it further here). wasting everyone's time with things that will go nowhere (because it won't be accepted and because it is not important enough to be raised at the team) is not.
IMHO, the original thing this issue was opened for should be an RFC, not an issue. I'd have closed this, pointed the OP to the RFCs repo, and opened a new issue for the diagnostic issue.
This issue was literally in the RFCs repo initially, transferred it from there.
Language bashing is not welcome here
Wait, so should I unassign here, and assign to the new issue?
Nah, just use this one.
Yeah, thats fine. You can just change this issue to be for diagnostics instead.
I'm sorry, I've been pretty busy with coursework, and I'm still fighting my Python installation to even build the compiler, let alone make progress on this. Sorry :(
I'll assign this to myself to work on when I have time. If you want to work on it however, feel free to work-steal it from me!
I would like to help with this
Sorry; should have updated this issue...! There's a PR at the moment. Feel free to leave suggestions on it if you like. :)
Code change:
"this was erroneously allowed and will become a hard error in a future release" }).emit(); } <ins> fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt { Stmt { id: DUMMY_NODE_ID, kind, span } } </ins> }

Related discussion:
text: From The following code should be using the common list parsing utilities: CC
What/where are the common list parsing utilties? Edit: never mind, I've got it. , , etc. for anyone who's wondering.
Code change:
// noop } <ins> fn no_position_independent_executable(&mut self) { // noop } </ins> fn partial_relro(&mut self) { // noop }

Related discussion:
text: I'm having trouble linking a Rust program to a non-position-independent C library. When I manually remove the flag from the ld step that rustc runs, everything works correctly. I think that should remove the flag for me, but it doesn't. Here's what I think is going on: When I run It runs ld with the flag: But when I read the rustc code , it seems like the intention is that should only be passed to ld when . That is, if we're not compiling a position independent executable, then we should not pass the position independent executable flag to ld. I think what may be happening here is that somehow the defaults from are overriding the command line options I'm setting. This happens with stable and also the nightly I tried:
and are two distinct things. is also unrelated to the option. Interestingly, I do not remember us having an option to disable PIE; we should have one.
I did a bit of reading and here's what I figured out, please correct me if any of this is wrong. Linkers are new to me! Rust builds position independent executables by default on platforms that support it. These platforms have a relocation model of pic in their target config. The is what sets that linker option, except if it's disallowed by . The correct solution to this is to add a codegen flag, or something like that. Does this sound right?
Hi, I am having the same issue. I am trying to link against non-position-independent C library, build process ends without error but results returned by Rust bindings are different (and incorrect) than those returned from clean C implementation. In order to overcome that issue currently I am setting RUSTFLAGS="-C relocation-model=dynamic-no-pic -C linker=./linker" where linker is bash script that wraps cc and filter -pie flags:
I'm also having this problem. I assumed that passing when doing a build would suppress on the linker command line. (cc:
I'm still seeing this issue. Not sure if it's a regression or I'm doing something wrong. I have a "hello world" program in , and when I run , the resulting call to includes . I'm using nightly rust on Ubuntu: .
So, the problem here isn't with rust, but with the linker.