jiebi/CodeConvo huggingface dataset:
Code change:
let mut buf = [0; 2]; self.code_points.next().map(|code_point| { <del> let c = unsafe { char::from_u32_unchecked(code_point.value) }; let n = c.encode_utf16(&mut buf).len(); </del> <ins> let n = char::encode_utf16_raw(code_point.value, &mut buf).len(); </ins> if n == 2 { self.extra = buf[1]; }

Related discussion:
text: The following program causes UB: Miri says: The problem is this code: This calls unless the new code point is in , but what about surrogates in ? This code is unchanged since its introduction in I am not sure what the intended safety contract of is. That method is not marked but clearly should be -- it calls . So my guess is the safety precondition is that must not be part of a surrogate pair, but the thing is, calls it without actually ensuring that condition. The condition it does ensure is that the codepoint is not in , but that does not help.
is excluded from Unicode scalar values a.k.a. , but it’s fine as a Unicode code point. I think this bug is not in the contract of (which is private anyway) but in its implementation, namely going through . The fix is to either duplicate the logic of into , or (to avoid duplication) move that logic to a new function in libcore that takes a parameter and that is called by both and . This function would need to be public because is in a different crate, but it should be prema-unstable and .
I would classify the priority of this bug as low. Although this call to is UB, I expect Miri checking for it explicitly is the only case where that has any consequence in today’s implementation: behaves as expected (for the purpose of WTF-8) in the surrogate range and does not exploit this UB The "layout" of in rustc excludes values beyond but not surrogates:
By the way, the docs at feel insufficient: Which values are invalid? Similarly, and say that represents Unicode Scalar values, but I couldn’t find it documented anywhere that constructing an out of range is Undefined Behavior rather than "merely" a logic bug. Is this specified elsewhere? What is the closest we have to a written down normative resource that specifies what is or isn’t UB in the the Rust language? (For APIs I assume this is the responsibility of their respective doc-comments.)
I agree the impact is low, but it's not just Miri -- this blocks , which is how I discovered the problem. That would be
But then what is "unchecked" about it? Elsewhere in that file the code is careful not to construct a from a without checking for surrogates: That made me assume the author was aware that surrogates in are UB.
Code change:
let mut buf = [0; 2]; self.code_points.next().map(|code_point| { <del> let c = unsafe { char::from_u32_unchecked(code_point.value) }; let n = c.encode_utf16(&mut buf).len(); </del> <ins> let n = char::encode_utf16_raw(code_point.value, &mut buf).len(); </ins> if n == 2 { self.extra = buf[1]; }

Related discussion:
text: The type contains a (generalized-UTF-8-encoded) sequence of code point (including potentially surrogates) that doesn’t form a surrogate pair. doesn’t check for surrogate pairs. is a public method that is documented as returning a scalar value, therefore excluding all surrogates. Ok I looked into it, there are three different people involved. The original code in 2014 was YOLO Later in 2014, moved to duplicating logic instead. In 2015, PR which first imported WTF-8 support in libstd deduplicated that logic by adding a function that takes . (I knew that approach sounded familiar…) In 2016, PR changed the signature of and in passing removed . It made use + instead, presumably in the middle of updating many callers other.
Okay, so the fix would be to revert the part of that removed ?
That or copy into . I find them both not great, so meh.
Even with that done, there's still UB in another testcase: This is converting something to a before calling -- so probably the same issue as the above, just for a different encoding.
Code change:
#![omit_gdb_pretty_printer_section] <del> // ignore-android: FIXME(#10381) </del> // min-lldb-version: 310 // aux-build:cross_crate_spans.rs

Related discussion:
text: Triggers an LLVM assertion when targeting Android:
Something that works on any host (i.e. you needn’t compile libstd for android to repro):
As the error says, isn't a supported calling convention for the ARM target in LLVM. Not really much we can do from the rustc side unless we want to error early based on cc/target combinations. In any case, it should not crash.
I'm hitting this when I tried to run tests for 1.10.0 on arm64 (aarch64-unknown-linux-gnu). The build succeeds otherwise. I'm just adding and to for the time being.
Neither example crashes today. Closing, since I don't see any good opportunity for a test here (it'd have to be something like and that's probably not worth it). With (original example): Updated example:
Code change:
/// If the hash of the input doesn't match or no input is supplied via None, /// it is interpreted as an error and the corresponding enum variant is set. /// The return value signifies whether some kind of source is present. <del> pub fn add_external_src(&self, src: Option<String>) -> bool { </del> <ins> pub fn add_external_src<F>(&self, get_src: F) -> bool where F: FnOnce() -> Option<String> { </ins> if *self.external_src.borrow() == ExternalSource::AbsentOk { <ins> let src = get_src(); </ins> let mut external_src = self.external_src.borrow_mut(); if let Some(src) = src { let mut hasher: StableHasher<u128> = StableHasher::new();

Related discussion:
text: In investigating I was generating some source code, and using the shell script listed in we can see: That's a lot of time to expand a crate that doesn't have any macros in it!
cc you may be interested in this!
A looks like almost all the time is spent in In which case, cc
Apparently most time is spent
called ~38k times
Since we need to build the module graph and resolve imports during expansion for macros 2.0, we must construct node ids and def ids throughout expansion (i.e. interleaved arbitrarily many times until we hit fix-point). Ideally we'd keep running totals of the time spent assigning node ids, assigning def ids, etc. for more accurate profiling information within the expansion step.
in theory though isn't the fixed point for this crate the crate itself? (e.g. there's no macros here). Or are the def ids persisted for the rest of compilation, so "blaming" expansion isn't quite correct here?
Yeah, the def ids are persisted for the rest of compilation. We could move the "first round" of def id collection (in which we collect the raw, unexpanded source) outside of expansion, but that would introduce more code complexity and wouldn't count the time we spend collecting def ids for AST that comes from macro expansions.
Ah ok, nah it seems fine! I think there's a number of cases where is attributing time in the wrong place nowadays... Still it seems odd that 30-50k invocations of this function would take so long to execute?
Do I understand this correctly that all DefIds generated are actually used, right? There are no "temporary" DefIds? Each of these invocations creates a Blake2 hasher. I'd be interested how the performance looks with other hashing algorithms. I'd like to switch to something faster anyway:
Are you sure this isn't the other quadratic case fixed in ?
It may very well be! Feel free to close this w/ that PR landing, I'll verify to be sure but I'd imagine you're correct in that it's fixed by
er, didn't mean to close just yet
Code change:
/// If the hash of the input doesn't match or no input is supplied via None, /// it is interpreted as an error and the corresponding enum variant is set. /// The return value signifies whether some kind of source is present. <del> pub fn add_external_src(&self, src: Option<String>) -> bool { </del> <ins> pub fn add_external_src<F>(&self, get_src: F) -> bool where F: FnOnce() -> Option<String> { </ins> if *self.external_src.borrow() == ExternalSource::AbsentOk { <ins> let src = get_src(); </ins> let mut external_src = self.external_src.borrow_mut(); if let Some(src) = src { let mut hasher: StableHasher<u128> = StableHasher::new();

Related discussion:
text: A of Servo's crate shows a huge amount of time (46 seconds!) in name resolution. It turns out that is calling , specifically . That's a lot of unused imports! Sure enough if we create a synthetic file locally with this script: we find: That's a lot of time spent processing unused imports! The slowdown here isn't quite the same as the style crate, unfortunately. The style crate only has ~7k unused imports, which apparently takes it 48s in that profile. In any case the intent here is clear, lots of unused imports seem to slow down compilation, and the crate looks to have a lot of unused imports!
cc
We could address this quickly by just emitting the first 10 unused imports warnings and then warning that there are more unused imports not shown.
I can never deal with more than 10 lints at a time anyway myself, so seems like a reasonable solution to me!
Dumping out a ton of warnings is useful when you're hooked into an IDE and you can see them as e.g. green squiggles under the offending text as opposed to 10k lines on a terminal.
I think the reason is slow is because it calls , which does this: I don't think we want to read source files multiple times like that.
Thank you for looking into Servo compile times Alex, and great find here! Could you CC me or someone from the Servo team for Servo-related issues? Thanks.
Can do!
In general I've always wanted the lint system to avoid even running in blocks. Currently the lint system runs all lints in parallel on the tree. This is great since it means we only traverse it once, and the cost of the traversal is consolidated. We don't need to reduce that cost itself (which is nice because then we don't have to worry about inside ). Most lints do not maintain state. The lint framework has the capability to do so, and we use this a couple times in Clippy, but most lints are , so they won't notice if or whatever isn't called in a region of . The "allowness" of a lint is tied to where in the tree the lint traversal is, not the span emitted by the lint.
Code change:
/// If the hash of the input doesn't match or no input is supplied via None, /// it is interpreted as an error and the corresponding enum variant is set. /// The return value signifies whether some kind of source is present. <del> pub fn add_external_src(&self, src: Option<String>) -> bool { </del> <ins> pub fn add_external_src<F>(&self, get_src: F) -> bool where F: FnOnce() -> Option<String> { </ins> if *self.external_src.borrow() == ExternalSource::AbsentOk { <ins> let src = get_src(); </ins> let mut external_src = self.external_src.borrow_mut(); if let Some(src) = src { let mut hasher: StableHasher<u128> = StableHasher::new();

Related discussion:
text: It's perfectly possible to a block of code and have the lint still be emit there because a different block of code (where it is ) hit the lint but emitted a span it got from elsewhere. We've had trouble with this before in clipyp iirc. All of this enables this proposal: If we had a specialized trait for this, then when we have an we can turn off calling lint methods entirely, and when there's a turn it on again. It doesn't even have to be a trait, really, it could just be a defaulted fake-static method (until happens) on LateLintPass. I suspect this will get significant speedups for crates like Style. I may_ be able to take a crack at this if y'all think this is a good approach.
It occurs to me that a boolean check per lint each tree node might actually end up being more expensive? I'll have look at this code closer. Might be possible to make this fast by having a second array of trait objects which only contains the active lint passes.
It seems like we do a large enough amount of work that the whole "vector of active lints" stuff won't really be necessary. However, I just realized that this bug is not during the lint pass but during the resolution phase (which defers linting to the actual lint pass). This won't be able to help, though we can fix it by doing the spantosnippet in the actual lint and then making this optimization. So in that case I suspect this optimization is unnecessary. In general we've rarely had performance issues with lints in clippy (which has way more lints than rustc), and we've been pretty careful to measure impact there. Still, if folks think this optimization can help, let me know.
Code change:
<ins> #![feature(const_generics)] #![allow(incomplete_features)] struct Test(*const usize); type PassArg = (); unsafe extern "C" fn pass(args: PassArg) { println!("Hello, world!"); } impl Test { pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { //~^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline::<Args, IDX, FN> as _ } unsafe extern "C" fn trampiline< Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { FN(args) } } fn main() { let x = Test(); x.call_me::<PassArg, 30, pass>() } </ins>

Related discussion:
text: I've tried reducing this but wasn't really able to so far. I might try again some other time. The code below currently ICEs on Nightly (). When trying to reproduce locally for the backtrace, I had an older Nightly first () where this actually didn't crash the compiler, so it's apparently a regression. <details<summary<strongBacktrace</strong</summary<p</p</details
This is my first time using cargo-bisect-rustc and it's fantastic. It identified the regression as... searched nightlies: from nightly-2020-02-13 to nightly-2020-05-14 regressed nightly: nightly-2020-03-20 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.5.2</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
is a rollup commit. The only PR which was part of that and (to me) looks like it could have caused this issue is .
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.
Code change:
<ins> #![feature(const_generics)] #![allow(incomplete_features)] struct Test(*const usize); type PassArg = (); unsafe extern "C" fn pass(args: PassArg) { println!("Hello, world!"); } impl Test { pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { //~^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline::<Args, IDX, FN> as _ } unsafe extern "C" fn trampiline< Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { FN(args) } } fn main() { let x = Test(); x.call_me::<PassArg, 30, pass>() } </ins>

Related discussion:
text: produces: <details</detailsIt should not be possible to access the type parameter in the type of the const parameter. cc Thanks to for .
Hi, I am new to rust compiler development and have decided to try to fix this issue to get started. If I understand the const-generics RFC correctly, type parameters can not be used in a const generic parameter because it cannot be ensured that the actual types have the "structural match" property. However, checking reveals that fn pointers (as well as raw pointers and empty arrays) always support structural matching, regardless of the types used within. My question is: is there another reason why const generic parameters are not allowed to use type parameters? If so, I think an additional check has to be to .
Actually, I think I may have interpreted. It looks like this example is intended to work to me. cc just to clarify.
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.
Code change:
<ins> #![feature(const_generics)] #![allow(incomplete_features)] struct Test(*const usize); type PassArg = (); unsafe extern "C" fn pass(args: PassArg) { println!("Hello, world!"); } impl Test { pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { //~^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline::<Args, IDX, FN> as _ } unsafe extern "C" fn trampiline< Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { FN(args) } } fn main() { let x = Test(); x.call_me::<PassArg, 30, pass>() } </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. -- <!-- 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
Probably related to
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.
Code change:
<ins> #![feature(const_generics)] #![allow(incomplete_features)] struct Test(*const usize); type PassArg = (); unsafe extern "C" fn pass(args: PassArg) { println!("Hello, world!"); } impl Test { pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { //~^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline::<Args, IDX, FN> as _ } unsafe extern "C" fn trampiline< Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { FN(args) } } fn main() { let x = Test(); x.call_me::<PassArg, 30, pass>() } </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. -- <!-- 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
Depends on const generics in type dependent paths afaict. See for more info. EDIT: Also depends on const generics with generic types. Merging does not close this issue
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.
Adding the following as a test might still be useful, even if it only errors with "using function pointers as const parameters is forbidden":
Code change:
#[stable(feature = "unicode_encode_char", since = "1.15.0")] #[inline] pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] { <del> let mut code = self as u32; // SAFETY: each arm checks whether there are enough bits to write into unsafe { if (code & 0xFFFF) == code && !dst.is_empty() { // The BMP falls through (assuming non-surrogate, as it should) *dst.get_unchecked_mut(0) = code as u16; slice::from_raw_parts_mut(dst.as_mut_ptr(), 1) } else if dst.len() >= 2 { // Supplementary planes break into surrogates. code -= 0x1_0000; *dst.get_unchecked_mut(0) = 0xD800 | ((code >> 10) as u16); *dst.get_unchecked_mut(1) = 0xDC00 | ((code as u16) & 0x3FF); slice::from_raw_parts_mut(dst.as_mut_ptr(), 2) } else { panic!( "encode_utf16: need {} units to encode U+{:X}, but the buffer has {}", from_u32_unchecked(code).len_utf16(), code, dst.len(), ) } } </del> <ins> encode_utf16_raw(self as u32, dst) </ins> } /// Returns `true` if this `char` has the `Alphabetic` property.

Related discussion:
text: The type contains a (generalized-UTF-8-encoded) sequence of code point (including potentially surrogates) that doesn’t form a surrogate pair. doesn’t check for surrogate pairs. is a public method that is documented as returning a scalar value, therefore excluding all surrogates. Ok I looked into it, there are three different people involved. The original code in 2014 was YOLO Later in 2014, moved to duplicating logic instead. In 2015, PR which first imported WTF-8 support in libstd deduplicated that logic by adding a function that takes . (I knew that approach sounded familiar…) In 2016, PR changed the signature of and in passing removed . It made use + instead, presumably in the middle of updating many callers other.
Okay, so the fix would be to revert the part of that removed ?
That or copy into . I find them both not great, so meh.
Even with that done, there's still UB in another testcase: This is converting something to a before calling -- so probably the same issue as the above, just for a different encoding.
Code change:
.lifetime_ribs .iter() .rev() <del> .take_while(|rib| !matches!(rib.kind, LifetimeRibKind::Item)) </del> <ins> .take_while(|rib| { !matches!(rib.kind, LifetimeRibKind::Item | LifetimeRibKind::ConstParamTy) }) </ins> .flat_map(|rib| rib.bindings.iter()) .map(|(&ident, &res)| (ident, res)) .filter(|(ident, _)| ident.name != kw::UnderscoreLifetime)

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. --<!-- 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
searched nightlies: from nightly-2023-02-17 to nightly-2023-02-19 regressed nightly: nightly-2023-02-18 searched commit range: regressed commit: - -cc <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.6</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
Code change:
///   both arguments were negative, then it is -0.0. Subtraction `a - b` is ///   regarded as a sum `a + (-b)`. /// <del> /// For more information on floating point numbers, see [Wikipedia][wikipedia]. </del> <ins> /// For more information on floating-point numbers, see [Wikipedia][wikipedia]. </ins> /// /// *[See also the `std::f32::consts` module](crate::f32::consts).* ///

Related discussion:
text: Pointed out by in the float docs are using the term "arithmetic" operations in a few places, but that term is never defined. Furthermore, the new NaN docs probably should use that term as well when discussing which operations the NaN rules apply to (instead of "non-bitwise floating point operations" which they use currently). By "arithmetic operations", the docs likely mean all operations except for unary , , , , , and .
Code change:
"num_cpus", "ordslice", "racer", <del> "rand 0.6.1", </del> <ins> "rand 0.7.0", </ins> "rayon", "regex", "rls-analysis",

Related discussion:
text: Hello, this is your friendly neighborhood mergebot. After merging PR rust-lang/rust, I observed that the tool rls no longer builds. A follow-up PR to the repository is needed to fix the fallout. cc do you think you would have time to do the follow-up work? If so, that would be great! cc the PR reviewer, and nominating for compiler team prioritization.