jiebi/CodeConvo huggingface dataset:
Code change:
import.crate_lint(), ); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; <del> if let Some(orig_unusable_binding) = orig_unusable_binding { self.r.unusable_binding = orig_unusable_binding; } </del> import.vis.set(orig_vis); if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res { // Consider erroneous imports used to avoid duplicate diagnostics.

Related discussion:
text: I tried this code: I expected to see this happen: Compilation error. This shadows one (glob-imported) with another . As far as I know, this should be forbidden. Instead, this happened: this code successfully compiled. : c.c. c.c.
Shadowing a glob import with a specific item is allowed and will unambiguously resolve to the specific one. This is also how the prelude works. The following compiles fine as well: .
To clarify, the problem is not shadowing, but time travel. We shadow identifier which have been already used to resolve another import, so we end up with meaning two things at the same time in the same scope.
This is a change from Rust 1.44, in Rust 1.43 this is an ICE "inconsistent resolution for an import". Possibly a consequence of
I'm not sure this is a bug. When resolving we are looking at all names in scope except for the names introduced by itself. Otherwise we'd have cycles even in trivial cases like where is a name from extern prelude. If you take this detail into consideration, then all paths seem to be resolved correctly.
cc (somewhat related)
I think, the difference with is that doesn't replace one resolution with another. We already have a name in the scope that is resolved to a particular extern crate. In my example, uses name from the scope, and then rebinds this name to another item. I can complicate my example a bit. What this program prints, "111" or "222"? It'd say, it depends on imports resolution order, but looks like it always prints "111".
It'd say, it depends on imports resolution order The intent for the resolution results is to never depend on internal resolution order. (cc , order-dependence can probably happen in practice due to the current not very principled implementation, but hopefully still can be eliminated in backward-compatible-in-practice way by rewriting the main resolution/expansion loop more carefully.) but looks like it always prints "111" That's what I'd expect. resolves to in resolves to (because non-globs shadow globs) first in resolves to (which the only in scope after excluding itself)
I'd still be ok with replacing the former ICE with an error though, since that's a more conservative choice.
Code change:
import.crate_lint(), ); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; <del> if let Some(orig_unusable_binding) = orig_unusable_binding { self.r.unusable_binding = orig_unusable_binding; } </del> import.vis.set(orig_vis); if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res { // Consider erroneous imports used to avoid duplicate diagnostics.

Related discussion:
text: Actually enabling the property "name resolve to the same thing whether some items were excluded during its resolution to avoid cycles or not" may be useful for using something like "inference variables" for unresolved imports and making import resolution more like unification in type inference. That's an idea I had for quite some, but I hadn't realized that merging went against it.
Sigh, the issue already affects three stable releases - from 1.44 to 1.46. I'll try to prioritize it.
Addressed in
Assigning so this isn't lost. See the .
The fix caused some regressions -
The code in the issue produce no errors using Rust 1.67.1. Should we re-open the issue or is it not considered a bug now?
The fix was reverted due to breakage () and the current behavior is considered by design since then.
(Also it's not exactly a time travel - )
Code change:
&Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Public }, hir::CRATE_HIR_ID, &krate.item.module, <del> None, </del> <ins> Some(self.cx.tcx.crate_name), </ins> ); top_level_module.is_crate = true; // Attach the crate's exported macros to the top-level module.

Related discussion:
text: It should say instead.
Relevant code: I think the fix is to use the crate name instead of .
Also, I would be curious to see if you can remove altogether by using : That might break renamed modules maybe? I don't remember how modules interact with re-exports.
Code change:
#![feature(maybe_uninit_extra)] #![feature(maybe_uninit_ref)] #![feature(maybe_uninit_slice)] <ins> #![feature(maybe_uninit_uninit_array)] </ins> #![feature(min_specialization)] #![feature(needs_panic_runtime)] #![feature(negative_impls)]

Related discussion:
text: I was using std::io::copy from an SSD to memory using , which reported an eye-raising 30 MB/s. Wrapping it in a BufReader (either as the outer or middle layer) made no real difference. So I googled around a bit and found the recommended size was 64KB according to some random Microsoft article, so I decided to copy-paste the std::io::copy implementation and increase the buffer size. This got up to 600 MB/s at about 256KB which sounded a lot more it continued going upwards from there past the point of believability (unless the files were being pulled from RAM as a consequence of my repeated accesses). With a 10MB Vec, I got 228.36 GB/s . Unrealistic values aside, has anybody checked the buffer value to make sure there isn't some huge low-hanging fruit for std::io::copy speeds?
You mention windows. This may be platform-specific behavior. On unix systems I would fadvise on the input file for copying. Googling tells me that the windows equivalent is . Have you tried that?
After a coarse overview, my intuition is that there is some funny business going on with the length determined by and the subsequent calls on the , that could explain the unrealistic results.
It’s possible. The actual times did increase dramatically from the std::io::copy default though - my suspicion is that there is probably some caching to RAM going on or something as cold runs were generally slower than hot runs. This was for some work code that I’m no longer actively developing. I’ll leave this email marked as unread for awhile in case I have some spare time to write a benchmark. I don’t think the other flag that was mentioned is accessible with the default open file api, but in any case it at least appears there’s some low hanging fruit wrt to std::io::copy perf
I tried benchmarking on Windoze before and after changing to (instead of the original ) and the results were slightly worse (up to ~3%) with the modified setup, both on HDD and SSD. However, I'm not sure if my benchmarks were good enough - I was having a hard time tweaking them so that I could see any difference between results for different file sizes.
Code change:
#![feature(maybe_uninit_extra)] #![feature(maybe_uninit_ref)] #![feature(maybe_uninit_slice)] <ins> #![feature(maybe_uninit_uninit_array)] </ins> #![feature(min_specialization)] #![feature(needs_panic_runtime)] #![feature(negative_impls)]

Related discussion:
text: FWIW, I'm providing the benchmark code below; it can easily be expanded to different file sizes:
4MB isn’t a whole lot. That’s well within the size of hard drive caches or possibly an OS memory-based cache. I was noticing the difference with files several gigabytes in size. As a sanity check, maybe look to see what the actual time is, not just the % difference between timings with different buffer sizes. The actual time may be wildly different than the actual steady state performance of the disk if it’s reading the data from a cache. It may also be possible at a low level to pass a flag to encourage the OS to disable or flush the cache, but I don’t know if there’s any way to instruct the hard drive to do the same.
I only pasted the benchmark for 4MB as a reference - I tested files from 4KB up to 16MB. I'm not an expert with low-level hard drive stuff, just hoping my attempt can help someone else.
Ideally you would test with a file approximately twice as big as you have RAM, so if you have 8GB of RAM you would want to test with a 16GB file.
extended open flags are accessible via FWIW lots of bennchmarks exist showing synchronous IO calls improve when matching IO operations to the underlying block size (e.g. 4MB for modern SSD's) across multiple OS's, so its very likely that there are improvements to gain here. However, 4MB is stack-breaking size by default, and heap allocations will destroy potential improvements (and further, if we're optimising, we probably want overlapped IO and a ring of buffers rather than just one buffer which will always leave one device idle).... so its complex;)
heap allocations will destroy potential improvements How come? would allocate once at the beginning. Heap memory isn't inherently slower and one memory allocation is basically free compared to the heavy IO that's happening afterwards.
But we also don't want to be allocating 4MB every time we do as someone might be doing a bunch of small copies.
Code change:
#![feature(maybe_uninit_extra)] #![feature(maybe_uninit_ref)] #![feature(maybe_uninit_slice)] <ins> #![feature(maybe_uninit_uninit_array)] </ins> #![feature(min_specialization)] #![feature(needs_panic_runtime)] #![feature(negative_impls)]

Related discussion:
text: possible approaches: thread local buffers or a buffer pool stat the input before deciding on the buffer size (this is what gnu cp does I think) heap-allocate a bigger buffer after a few iterations of the copy loop with an on-stack buffer specialize copy operations from file to memory to directly into the already allocated target, thus skipping the need for a buffer
specialize copy operations from file to memory to directly into the already allocated target, thus skipping the need for a buffer I think some kind of specialization for sources would be ideal. Because in this case, should not buffer at all and simply use the reader's buffer. Effectively this also gives you a customizable buffer size by wrapping your in a with whatever size you want. As of today, if your source is then is always the wrong answer. I got a substantial performance improvement using a simple loop instead:
a single heap allocation is entirely reasonable for a single invocation of copy of a lot of data. For many copies of a small amount of data, one ends up with a lot of allocations again (consider for instance copying data out of a tar, where we have views on the data and there's no actual synchronous IO etc happening. I like some of the suggested possibilities with specialisation.
It's a nice general optimization, but not necesarily ideal if you use a as . Adding a on the reader size does let you control the buffer size but it still introduces an unnecessary memcopy compared to . Perhaps a writer-side optimization would be more flexible. Then you can specialize either for or
That sounds rather uncommon to me though. After all, is provided by the trait so it's always available. The only case I can see where you would invoke with a as destination is some generic interfaces that takes any . But IMO such interfaces are ill-designed, as they could simply implement instead and offer a much more flexible API.
yes, generic code taking a write was the concern. E.g. tar-rs has a tar archive which takes a and is fed with items. I'm not saying that creating an in-memory archive would be a good idea, just pointing out that these patterns do exist.
I had same kind of issue but with different library (). The copy rate was around 70 MB/s (inside single NVMe SSD). The problem was actually with running the debug version of my program.
Code change:
#![feature(maybe_uninit_extra)] #![feature(maybe_uninit_ref)] #![feature(maybe_uninit_slice)] <ins> #![feature(maybe_uninit_uninit_array)] </ins> #![feature(min_specialization)] #![feature(needs_panic_runtime)] #![feature(negative_impls)]

Related discussion:
text: When I built and ran the release version, the speed jumped to over 1 GB/s.
With merged you can now (on next nightly) use to control the chunk size of . Since this relies on specialization it only works if you pass a directly, any other wrapper around it would disable this optimization.
Code change:
} else if self.label_right - self.span_left <= self.column_width { // Attempt to fit the code window considering only the spans and labels. let padding_left = (self.column_width - (self.label_right - self.span_left)) / 2; <del> self.computed_left = self.span_left - padding_left; </del> <ins> self.computed_left = self.span_left.saturating_sub(padding_left); </ins> self.computed_right = self.computed_left + self.column_width; } else if self.span_right - self.span_left <= self.column_width { // Attempt to fit the code window considering the spans and labels plus padding. let padding_left = (self.column_width - (self.span_right - self.span_left)) / 5 * 2; <del> self.computed_left = self.span_left - padding_left; </del> <ins> self.computed_left = self.span_left.saturating_sub(padding_left); </ins> self.computed_right = self.computed_left + self.column_width; } else { // Mostly give up but still don't show the full line. self.computed_left = self.span_left;

Related discussion:
text: Hello, this is your friendly neighborhood mergebot. After merging PR rust-lang/rust, I observed that the tool miri has failing tests. 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 prioritization.
introduced an ICE (integer overflow) in the error emitting code, that Miri runs into.
will fix the issue on 's end, which should automatically fix this one.
Code change:
// Test that `-Cprofile-generate` creates expected instrumentation artifacts in LLVM IR. <del> // Compiling with `-Cpanic=abort` because PGO+unwinding isn't supported on all platforms. </del> // needs-profiler-support <del> // compile-flags: -Cprofile-generate -Ccodegen-units=1 -Cpanic=abort </del> <ins> // compile-flags: -Cprofile-generate -Ccodegen-units=1 </ins> // CHECK: @__llvm_profile_raw_version = // CHECK-DAG: @__profc_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = {{.*}}global

Related discussion:
text: LLVM's "IR-level" instrumentation, which is used by to generate PGO instrumented binaries, does not yet work with exception handling on Windows MSVC. The problem has been reported to LLVM for C++ here: This also affects Rust programs built with for Windows MSVC. As long as LLVM does not support exception handling there, it is a known limitation that PGO can only be used with on this platform.
PGO does not yet work on for other reasons (see ). Once it does, we should check if this problem is specific to MSVC.
I have working x86_64 windows-gnu (64 bit builds use SEH) build with PGO I'll open PR once is merged. I can do testing in meantime. FWIW simple hello world example works fine after going through PGO.
if you test, be sure to compile your LLVM with assertions: Thanks for looking into it!
I'll recompile it with assertions today later. Should the test case be using any specific code like ?
The following test case runs into the problem with MSVC: See for how the file is compiled.
It does not reproduce with gnu toolchain with Rust and LLVM assertions enabled, I'll try to remember about fixing along with gnu profiler.
Cool!
I just confirmed that (for me locally) PGO seems to work on Windows GNU. That is, I built with instrumentation, ran it, and rebuilt it with the profiling data collected. It worked just fine, no crashes. So I updated the original issue text to just mention MSVC instead of Windows in general.
It looks like is a bit too aggressive with its error reporting. For example when invoking rustc, but not compiling in our Firefox build we can the following : I'm not sure the best solution while mw is away; perhaps we should revert for now.
Maybe we can just convert the error to a warning?
Not the best long-term solution but seems ok
It looks like the was marked fixed a year ago. What's the status of this issue in rustc?
Code change:
<ins> // run-rustfix // check-only #[derive(Debug)] struct Demo { a: String } trait GetString { fn get_a(&self) -> &String; } trait UseString: std::fmt::Debug + GetString { fn use_string(&self) { println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self` } } trait UseString2: GetString { fn use_string(&self) { println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self` } } impl GetString for Demo { fn get_a(&self) -> &String { &self.a } } impl UseString for Demo {} impl UseString2 for Demo {} #[cfg(test)] mod tests { use crate::{Demo, UseString}; #[test] fn it_works() { let d = Demo { a: "test".to_string() }; d.use_string(); } } fn main() {} </ins>

Related discussion:
text: The following example code yields an error: It's unclear from this error message how to proceed - I'm not sure of the syntax, location, or where I should be putting the "GetString" trait bound. It should be shown with a better example or link when this error is presented, as the current message is not sufficient for a resolution to be arrived at.
cc
Fixing in . To fix your code write:
Thanks!
Code change:
/// /// [`to_ascii_lowercase`]: Self::to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] <del> #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] </del> <ins> #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] </ins> #[inline] <ins> #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] </ins> pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }

Related discussion:
text: Feature gate: This is a tracking issue for marking the and methods in , , , and as "const." [x] Implementation for : [x] Implementation for : [x] Implementation for and : [x] Final comment period (FCP) [x] Stabilization PRNone yet.
fcp merge / have been stable in const since 1.52. / are unblocked now by the stabilization of
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [ ] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
Can the methods be included in this? Similarly const stable / since 1.52.
Yes, that sounds like a good idea. I'll try adding another PR later.
:bell: This is now entering its final comment period, as per the . :bell:
stabilises this.
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.
Code change:
// * Our custom AssertRecoverSafe wrapper is indeed recover safe impl RecoverSafe for .. {} impl<'a, T: ?Sized> !RecoverSafe for &'a mut T {} <del> impl<'a, T: NoUnsafeCell + ?Sized> RecoverSafe for &'a T {} impl<T: NoUnsafeCell + ?Sized> RecoverSafe for *const T {} impl<T: NoUnsafeCell + ?Sized> RecoverSafe for *mut T {} </del> <ins> impl<'a, T: RefRecoverSafe + ?Sized> RecoverSafe for &'a T {} impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *const T {} impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *mut T {} </ins> impl<T: RecoverSafe> RecoverSafe for Unique<T> {} <del> impl<T: NoUnsafeCell + ?Sized> RecoverSafe for Shared<T> {} </del> <ins> impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Shared<T> {} </ins> impl<T: ?Sized> RecoverSafe for Mutex<T> {} impl<T: ?Sized> RecoverSafe for RwLock<T> {} impl<T> RecoverSafe for AssertRecoverSafe<T> {}

Related discussion:
text: Test Case 1: Test Case 2: Both produce errors like this: CC
Hm, so the first case here should work (e.g. should subvert basically everything), although the second case is correct in yielding an error (albeit not a very good one)
Is the second case not allowed then? 's documentation suggests that manually implementing it is okay to do: I figured only existed to wrap types which you couldn't yourself, but for which you can ensure their invariants are upheld across the boundary. And what about moving values into the closure? can't be unwrapped, at least not currently.
Oh wait sorry I misread your second example, I failed to notice the manual ! This is basically a case where closure captures are coming into play. The closures aren't annotated with , so outer variables are captured by-reference which means that the actual types being tested against the trait here are and . In the first case that should be handled by , but the second is legitimately indicating that it's not a recover-safe type (b/c the reference is different than the by-value). You should be able to get around this via either plus or via . Certainly an interesting interaction going on here though. One would likely expect that if isn't recover safe that would fix the problem but it's likely what you really need to do is due to the way closures largely work.
There's , why not ? Coherence?
Nah unfortunately that'd defeat the purpose of the distinction. The type is itself recover safe, it's just that's not (so the distinction need to be there)
It's unfortunate that fails due to coherence or something like that:
Hm interesting, I guess yeah you'll be forced to move the reference inside the wrapper rather than having a reference to the wrapper
Is it possible to implement then? My use case can contain and friends but I'm guaranteeing that they're unobservable in user code after recovery because I immediately re-panic after escaping the FFI stack.
I guess I can just use once it's fixed :stuckouttongue:. I see your PR has been accepted so I'll look forward to trying it on tonight's nightly. When do the buildbots fire?
Yeah currently you can implement (being renamed to ) I believe (although I can't say I've tried). For now though yeah I'd recommend just using plus closures.
Code change:
// * Our custom AssertRecoverSafe wrapper is indeed recover safe impl RecoverSafe for .. {} impl<'a, T: ?Sized> !RecoverSafe for &'a mut T {} <del> impl<'a, T: NoUnsafeCell + ?Sized> RecoverSafe for &'a T {} impl<T: NoUnsafeCell + ?Sized> RecoverSafe for *const T {} impl<T: NoUnsafeCell + ?Sized> RecoverSafe for *mut T {} </del> <ins> impl<'a, T: RefRecoverSafe + ?Sized> RecoverSafe for &'a T {} impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *const T {} impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *mut T {} </ins> impl<T: RecoverSafe> RecoverSafe for Unique<T> {} <del> impl<T: NoUnsafeCell + ?Sized> RecoverSafe for Shared<T> {} </del> <ins> impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Shared<T> {} </ins> impl<T: ?Sized> RecoverSafe for Mutex<T> {} impl<T: ?Sized> RecoverSafe for RwLock<T> {} impl<T> RecoverSafe for AssertRecoverSafe<T> {}

Related discussion:
text: The PR is in but'll take a few hours at least to land.
the problem with moving at this point in time is that I call in different branches of a but I pass the same closed-over value to it; I can't do the branch in the closure because I need to do some FFI cleanup afterwards regardless of whether a panic happened or not (which also requires the closed-over value). It would help if derived and/or so I could reuse it without constructing a new value for each arm, but that would probably require some discussion because I don't know if it's safe or not. I'll probably just implement and fix the name after your PR drops. A quick check confirms that it works just fine. Thanks anyways!
Oh yeah we could totally add more traits like and to , there shouldn't be any safety concerns there.
Updating code to modern functions and traits in makes this compile, so I'm going to close.