jiebi/CodeConvo huggingface dataset:
Code change:
<ins> // Copyright 2014 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. fn main() { (return)[0u]; //~ ERROR cannot index a value of type `!` } </ins>

Related discussion:
text: Taking a look.
Probably the best fix for now is to disallow deref of outright. I'll work up a PR that fixes this and a few other ICEs surrounding .
This is fixed with a test, closing.
Code change:
<ins> // Regression test for https://github.com/rust-lang/rust/issues/70673. // run-pass #![feature(thread_local)] #[thread_local] static A: &u8 = &42; fn main() { dbg!(*A); } </ins>

Related discussion:
text: When running on of the crate, panics: Platform: macos
FYI, this appears to be a macOS-specific bug:
Minimal repro:
Code change:
} } <ins> fn eq_coroutine_kind(a: Option<CoroutineKind>, b: Option<CoroutineKind>) -> bool { match (a, b) { (Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. })) | (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. })) | (Some(CoroutineKind::AsyncGen { .. }), Some(CoroutineKind::AsyncGen { .. })) | (None, None) => true, _ => false, } } </ins> pub fn eq_field(l: &ExprField, r: &ExprField) -> bool { l.is_placeholder == r.is_placeholder && eq_id(l.ident, r.ident)

Related discussion:
text: () Reproduces on the playground using . label +D-incorrect +F-gen_blocks +requires-nightly
Code change:
} None => { debug!(?param.ident, ?param.ident.span); let deletion_span = deletion_span(); <del> self.r.lint_buffer.buffer_lint_with_diagnostic( lint::builtin::UNUSED_LIFETIMES, param.id, param.ident.span, &format!("lifetime parameter `{}` never used", param.ident), lint::BuiltinLintDiagnostics::SingleUseLifetime { param_span: param.ident.span, use_span: None, deletion_span, }, ); </del> <ins> // the give lifetime originates from expanded code so we won't be able to remove it #104432 let lifetime_only_in_expanded_code = deletion_span.map(|sp| sp.in_derive_expansion()).unwrap_or(true); if !lifetime_only_in_expanded_code { self.r.lint_buffer.buffer_lint_with_diagnostic( lint::builtin::UNUSED_LIFETIMES, param.id, param.ident.span, &format!("lifetime parameter `{}` never used", param.ident), lint::BuiltinLintDiagnostics::SingleUseLifetime { param_span: param.ident.span, use_span: None, deletion_span, }, ); } </ins> } } }

Related discussion:
text: <!-- 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. --code from requires debug assertions <!-- 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<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
lol, nightly emits this:D : another one from
any updates? :upsidedownface:
claim I think I got a fix :slightlysmilingface:
Error: Parsing assign command in failed: ...' claim' ' I think I'... Please file an issue on GitHub at if there's a problem with this bot, or reach out on on Zulip.
claim
Code change:
multibyte_chars, non_narrow_chars, name_hash, <del> } </del> <ins> }) </ins> } /// Returns the `BytePos` of the beginning of the current line.

Related discussion:
text: I know that having huge literal in source is a bad idea, but it should not cause ICE :( It looks like something overflowed. Version: Command, output and backtrace: Here is the generator of the source:
cc
Took a quick look. We certainly have a restriction that any file can't be that large, because we use u32 for indexing. And looks like we never try to enforce it anywhere. I think the place to do that would be . Do we have any way to panic without this being marked as ICE? I don't want to thread to each , and this seems like a marginal error where it's totally OK to panic. This is even OK in the IDE context I think: IDE should enforce reasonable max size of the file (something like 10mb, not 4gb) at the virtual file system layer. The "just panic" fix is here:
Do we have any way to panic without this being marked as ICE? or if the context is available.
I tried to compile the same thing in gcc and clang: With gcc: With clang: EDIT: Opened
Code change:
fn ilog10_u128() { ilog10_loop! { u128, 38 } } <ins> #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog2_of_0_panic() { let _ = 0u32.ilog2(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog10_of_0_panic() { let _ = 0u32.ilog10(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog3_of_0_panic() { let _ = 0u32.ilog(3); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog0_of_1_panic() { let _ = 1u32.ilog(0); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog1_of_1_panic() { let _ = 1u32.ilog(1); } </ins>

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:
fn ilog10_u128() { ilog10_loop! { u128, 38 } } <ins> #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog2_of_0_panic() { let _ = 0u32.ilog2(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog10_of_0_panic() { let _ = 0u32.ilog10(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog3_of_0_panic() { let _ = 0u32.ilog(3); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog0_of_1_panic() { let _ = 1u32.ilog(0); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog1_of_1_panic() { let _ = 1u32.ilog(1); } </ins>

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:
fn ilog10_u128() { ilog10_loop! { u128, 38 } } <ins> #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog2_of_0_panic() { let _ = 0u32.ilog2(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog10_of_0_panic() { let _ = 0u32.ilog10(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog3_of_0_panic() { let _ = 0u32.ilog(3); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog0_of_1_panic() { let _ = 1u32.ilog(0); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog1_of_1_panic() { let _ = 1u32.ilog(1); } </ins>

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:
fn ilog10_u128() { ilog10_loop! { u128, 38 } } <ins> #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog2_of_0_panic() { let _ = 0u32.ilog2(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog10_of_0_panic() { let _ = 0u32.ilog10(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog3_of_0_panic() { let _ = 0u32.ilog(3); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog0_of_1_panic() { let _ = 1u32.ilog(0); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog1_of_1_panic() { let _ = 1u32.ilog(1); } </ins>

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:
fn ilog10_u128() { ilog10_loop! { u128, 38 } } <ins> #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog2_of_0_panic() { let _ = 0u32.ilog2(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog10_of_0_panic() { let _ = 0u32.ilog10(); } #[test] #[should_panic(expected = "argument of integer logarithm must be positive")] fn ilog3_of_0_panic() { let _ = 0u32.ilog(3); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog0_of_1_panic() { let _ = 1u32.ilog(0); } #[test] #[should_panic(expected = "base of integer logarithm must be at least 2")] fn ilog1_of_1_panic() { let _ = 1u32.ilog(1); } </ins>

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:
| LL |         MyEnum::Struct => "", |         ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant <ins> | help: the struct variant's field is being ignored | LL |         MyEnum::Struct { s: _ } => "", |                        ++++++++ </ins> error: aborting due to 2 previous errors

Related discussion:
text: I wrote code that looked like this while not having my brain turned on 100%. Due to said brain not functioning, it took me a while to understand what rustc was trying to tell me with the message pointing to the pattern with the text . sure looked like a unit variant to me! What rustc was trying to tell me was that the definition of the variant was a struct variant ("found struct variant") and my pattern wasn't matching the definition ("this pattern you specified looks like it's trying to match a variant that is not a unit struct, unit variant or constant"). The change I needed to make was adding to my pattern, because I was trying to distinguish different variants from each other, not use pieces within the variants. Suggesting seems like a decent starting point to me, but there could definitely be cases I'm not considering here and I'm totally open to hearing that No response No response <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
WEIRD this PR looks like it implements what I wish rustc did: but the test files in that PR say they're for and I'm getting
Aha ok this test shows that for tuple variants, rustc will suggest adding : and that test also shows that rustc isn't suggesting anything for struct variants!
Aha and it looks like adding struct fields was more complex so that's why it wasn't done?
claim
Code change:
<ins> error[E0308]: mismatched types --> $DIR/mut-mut-wont-coerce.rs:36:14 | LL |     make_foo(&mut &mut *result); |     -------- ^^^^^^^^^^^^^^^^^ expected `*mut *mut Foo`, found `&mut &mut Foo` |     | |     arguments to this function are incorrect | = note:    expected raw pointer `*mut *mut Foo` found mutable reference `&mut &mut Foo` note: function defined here --> $DIR/mut-mut-wont-coerce.rs:30:4 | LL | fn make_foo(_: *mut *mut Foo) { |    ^^^^^^^^ ---------------- error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. </ins>

Related discussion:
text: The title already says it, but as an illustrating example you can have a look at Since &mut T can be implicitly converted to *mut T, I wondered whether there's a reason that it doesn't work for &mut &mut T (besides "no one has implemented it" :smile: ). pointed out that this might be (in IRC). The example code also illustrates a somewhat unexpected failure of type inference, which might be worth filing as a separate issue.
Hmm... take the following: Rust will currently complain about mismatched types for the second coercion. It's not clear such a coercion should exist: it's like converting a to a .
Note that first coercing to instead of seems to work ().
Your testcase is constructing a , not a .
Ah, thanks for pointing that out.
In don't know if I understand your point, but if you argue that such a coercion should not exist because it might be unsafe, the line in my original example shows that this conversion is already possible in safe code.
Heh, C++ has special rules for multi-level pointer conversions exactly to prevent these kinds of type unsafeties: "More qualified" relations can be translated to Rust's // relations.
isn't doing the same thing: the outer is actually constructing a temporary, so you end up with an (as opposed to a ). Also, safety isn't really relevant; we allow arbitrary explicit pointer casts anyway.
Oh, wait, I see, you expect the original to interpreted as , and then converted from there to . That makes sense.
I think this would work if borrow expressions would take into account that they might get coerced later and pass down the from (where here), instead of only working for .
Triage: this still reproduces.
Closing this as the bug is fixed and playground link above works for all editions.
The playground link had the problematic line commented out: It still gives a compile error:
oops my bad then
This idea has been suggested. A T-compiler member has pointed out that other languages apply rules to restrain pointer coercion, specifically because multi-level pointer coercion is prone to being a bit of a footgun. Not quite "this is a bad idea", but despite the simplicity of the proposal, it deserves being treated with caution. There is no strong argument that this is a bug because it is consistent, if annoying.
Code change:
<ins> error[E0308]: mismatched types --> $DIR/mut-mut-wont-coerce.rs:36:14 | LL |     make_foo(&mut &mut *result); |     -------- ^^^^^^^^^^^^^^^^^ expected `*mut *mut Foo`, found `&mut &mut Foo` |     | |     arguments to this function are incorrect | = note:    expected raw pointer `*mut *mut Foo` found mutable reference `&mut &mut Foo` note: function defined here --> $DIR/mut-mut-wont-coerce.rs:30:4 | LL | fn make_foo(_: *mut *mut Foo) { |    ^^^^^^^^ ---------------- error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. </ins>

Related discussion:
text: Legalizing this behavior with narrow cases seems permissible, but amounts to a new language feature design request. Transitive coercions, as part of the revised coercion rules, are . Accordingly, I think this should also be closed... but not before documenting the current behavior in the form of a regression test.