profile
viewpoint
Eduard-Mihai Burtescu eddyb @LykenSol Bucharest, Romania Senior Compiler/PL Engineer

alexcrichton/rustc-demangle 92

Rust symbol demangling

Centril/rfc-effects 8

Preparing an RFC on effect polymorphism in Rust with focus on 'const'

eddyb/cprep 6

C/C++ preprocessor.

eddyb/aoc 2

Advent of Code solutions in Rust

eddyb/bootstrap 2

HTML, CSS, and JS toolkit from Twitter

eddyb/hematite 2

A simple Minecraft written in Rust with the Piston game engine

eddyb/1ml 0

1ML prototype interpreter

eddyb/cargo 0

The Rust package manager

eddyb/clap-rs 0

A full featured, fast Command Line Argument Parser for Rust

pull request commentrust-lang/rust

Lift: take self by value

I have nothing against this change, FWIW.

lcnr

comment created time in a day

Pull request review commentrust-lang/rust

Lift: take self by value

 CloneTypeFoldableAndLiftImpls! { // FIXME(eddyb) replace all the uses of `Option::map` with `?`. impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {     type Lifted = (A::Lifted, B::Lifted);-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {-        tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))+    fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {+        let (a, b) = self;+        tcx.lift(a).and_then(|a| tcx.lift(b).map(|b| (a, b)))     } }  impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {     type Lifted = (A::Lifted, B::Lifted, C::Lifted);-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {-        tcx.lift(&self.0)-            .and_then(|a| tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c))))+    fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {+        let (a, b, c) = self;+        tcx.lift(a).and_then(|a| tcx.lift(b).and_then(|b| tcx.lift(c).map(|c| (a, b, c))))

If you're going to rewrite these, you can use ? nowadays. E.g. Some((tcx.lift(a)?, tcx.lift(b)?, tcx.lift(c)?))

lcnr

comment created time in a day

PullRequestReviewEvent

Pull request review commentrust-lang/rust

Lift: take self by value

 impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc                 // "Lift" into the tcx -- once regions are erased, this type should be in the                 // global arenas; this "lift" operation basically just asserts that is true, but                 // that is useful later.-                tcx.lift(&drop_place_ty).unwrap();+                tcx.lift(drop_place_ty).unwrap();

Yeah, I don't know what this did but it should be unnecessary. cc @nikomatsakis

lcnr

comment created time in a day

PullRequestReviewEvent

pull request commentrust-lang/rust

Fix control flow check for breaking with diverging values

r? @nikomatsakis

varkor

comment created time in a day

pull request commentrust-lang/rust

normalize substs while inlining

@bors r+

lcnr

comment created time in a day

pull request commentrust-lang/rust

fix def collector for impl trait

@bors r+

lcnr

comment created time in a day

PullRequestReviewEvent

pull request commentrust-lang/rust

mangling: mangle impl params w/ v0 scheme

r=me though I'm not sure what's wrong with CI

davidtwco

comment created time in 4 days

PullRequestReviewEvent

issue commentjlgreathouse/AMD_IBS_Toolkit

Zen workaround missing for Zen 2 (which is also affected by SpecLockMap).

because IBS Op sampling only samples fully retired ops

Sadly it does seem to affect the "retired instructions" counter, so I guess it's not as "fully" retired as what IBS sees.

In any case, thanks for taking the time to respond! (I believe this might be the first time we heard back from anyone at AMD regarding the whole SpecLockMap saga, at all - then again, I don't think there was any attempt at grabbing anyone's attention, so no surprises there, heh)

And you can tell I'm also bad with notifications lately, didn't notice your reply until now.

eddyb

comment created time in 5 days

issue commentrust-lang/rust

Implementation detail exposed in short backtrace (RUST_BACKTRACE=1)

This would go away if lang_start would be generic over main's type as F: FnOnce() -> R instead of taking a fn pointer, right? If you use -Z symbol-mangling-version=v0, you can see that the "inlined sometimes" call_once is <fn() as core::ops::function::FnOnce<()>>::call_once, i.e. the shim for calling a fn pointer via FnOnce.

One nice thing would that is we could theoretically allow varying not just main's return type, but also argument counts/types (which frankly I don't know why it hasn't come up before?).

solson

comment created time in 11 days

issue commentrust-lang/rust

Add `-Zrandomize-layout` flag to better detect code that rely on unspecified behavior related to memory layout

@marmeladema It's pretty much all in rustc_middle::ty::layout. Wherever field offsets are computed (univariant_uninterned), you can, for example, add the final alignment to all of the field offsets - this will increase the size of the whole type but keep all fields correctly aligned (and it's slightly simpler than changing field order, which has to be done similarly to how we sort fields by alignment). You should be able to PM if you have more questions.

If you rely on the same flag to be passed across all the crates, or if you record what the choices were when a certain crate was contained (you could look at how -Z symbol-mangling-version is handled), you should be able to avoid problems with cross-crate consistency, which as per https://github.com/rust-lang/rust/issues/77316#issuecomment-701367977 was my main worry.

marmeladema

comment created time in 12 days

pull request commentrust-lang/rust

Don't run `resolve_vars_if_possible` in `normalize_erasing_regions`

I know what it's for (normalize may create inference variables), I'm just surprised it doesn't seem to be needed.

jyn514

comment created time in 13 days

pull request commentrust-lang/rust

Let backends access span information

@bors r+

khyperia

comment created time in 13 days

PullRequestReviewEvent

pull request commentrust-lang/rust

Force posix-style quoting on lld, independent of host platform

@bors r+

Mark-Simulacrum

comment created time in 14 days

PullRequestReviewEvent

pull request commentrust-lang/rust

fix def collector for impl trait

@bors r+

lcnr

comment created time in 15 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

Support signed integers and `char` in v0 mangling

 impl Printer<'tcx> for SymbolMangler<'tcx> {         }         let start = self.out.len(); -        match ct.ty.kind() {-            ty::Uint(_) => {}-            ty::Bool => {}+        let mut neg = false;+        let val = match ct.ty.kind() {+            ty::Uint(_) | ty::Bool | ty::Char => {+                ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty)+            }+            ty::Int(_) => {+                neg = true;+                ct.val

neg = true doesn't seem right when the value could be positive.

varkor

comment created time in 15 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust

fix def collector for impl trait

 impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {         // we are currently in. So for those it's correct that they have a         // different owner.     }++    fn visit_generic_param(&mut self, param: &'hir hir::GenericParam<'hir>) {+        if let hir::GenericParamKind::Type {+            synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),+            ..+        } = param.kind+        {+            // Do nothing because bodging is fun.

This needs a comment like visit_impl_item_ref, explaining that synthetic generics from impl Trait are HIR ID owners.

lcnr

comment created time in 15 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

fix def collector for impl trait

 impl Generics<'hir> { #[derive(HashStable_Generic)] pub enum SyntheticTyParamKind {     ImplTrait,+    // Created by the `#[rustc_synthetic]` attribute.+    Rustc,

I'd call this RustcSyntheticAttr if you want to include Rustc in the name.

lcnr

comment created time in 15 days

PullRequestReviewEvent

pull request commentrust-lang/rust

fix def collector for impl trait

@bors rollup=never (this is turning into something that may have sharp edge cases)

lcnr

comment created time in 15 days

Pull request review commentrust-lang/rust

fix def collector for impl trait

+// run-pass+#![allow(unused_must_use)]+fn bug<T>() -> impl Iterator<Item = [(); { |x: u32| { x }; 4 }]> {

We're running into issues which suggest we also want examples where the impl Trait is in argument position. (As that lowers to a generic parameter, which currently isn't a HIR owner)

lcnr

comment created time in 15 days

PullRequestReviewEvent

pull request commentrust-lang/rust

fix def collector for impl trait

@bors r+ Thanks! (looks like this was an oversight)

lcnr

comment created time in 15 days

PullRequestReviewEvent

issue commentbevyengine/bevy

Create and use StableTypeId instead of TypeId

Could building the "host" as an example in the bevy repo and the "dynamic plugin" as a separate cargo project that references the bevy repo cause the inconsistencies I saw?

That could cause two incompatible builds of bevy, you should check target/{debug,release}/deps/libbevy-*.rlib in both cases - if they have different hashes in the filenames, you are already introducing UB (Rust doesn't guarantee the ABI is the same, though we sadly don't do as much as we could to make it break much earlier).

But even then, two recompiles of the plugin shouldn't result in different TypeIds of type defined in the plugin itself.

cart

comment created time in 15 days

issue commentgodot-rust/godot-rust

Change type_tag implementation to consider the possibility of a change in the layout of TypeId

Ah, I see, found it: https://github.com/godot-rust/godot-rust/blob/836fa993c875883702fbca4f3bc8347da4146bea/gdnative-core/src/nativescript/type_tag.rs#L73-L83

Yeah, you shouldn't rely on this. Consider amortizing the cost of using the boxed version instead (and, really, you can replace your Vec with an IndexSet<TypeId> and use even 32-bit integers, or smaller, instead of usize).

toasteater

comment created time in 15 days

issue commentgodot-rust/godot-rust

Change type_tag implementation to consider the possibility of a change in the layout of TypeId

It's not usize, though? It's currently u64, are you sure the code in question compiles on 32-bit targets? You can write [u8; size_of::<TypeId>()], but ideally you would rely on Eq and/or Hash.

toasteater

comment created time in 15 days

issue commentbevyengine/bevy

Create and use StableTypeId instead of TypeId

If you are rebuilding the same Cargo project to obtain a newer build of the plugin, and this is a feature meant primarily for development uses, please use TypeId. If it breaks, that's great, because it means you're doing something wrong all of a sudden.

It's a very weak litmus test for basic things like "did I upgrade my Rust version and forgot to recompile the host binary" (if you're not linking bevy as a dylib, you will get duplication of everything between the host and the plugin, so things will appear to work even when they shouldn't - and I guess even if you do have a common dylib it will also probably succeed dynamic loading even if it's an incompatible version).

At the very least, if you move to something like "language-agnostic ComponentId", consider checking, on plugin loading, that things like TypeId::of::<bevy::SomeType>() agree between the host and the plugin. If they don't, do not run the plugin. This is the least you can do to make sure you're not accidentally loading incompatible code.

cart

comment created time in 15 days

pull request commentrust-lang/rust

Widen TypeId from 64 bits to 128.

the fallback (hash comparison) will be known-length which will be faster than comparing strings.

But any fixed length of hash is a mere probabilistic improvement, but not a soundness fix.

The reason we were even talking about strings is because they can encode enough information to be sound.

eddyb

comment created time in 15 days

pull request commentrust-lang/rust

normalize substs while inlining

@bors r+ Thanks!

lcnr

comment created time in 15 days

pull request commentrust-lang/reference

Document expression order for tuple expressions.

Why document any one thing in particular? The order is universally "postorder" (on the AST), i.e. "more nested" expressions first (effectively mandated by "expressions depend on the result of their subexpressions"), and between siblings it's specifically left-to-right (outside of perhaps assignments' LHS? I forget how we resolved that one).

Can't we specify it in one place? Doing it on a case-by-case basis seems inefficient and would suggest the order isn't uniformly defined, whereas it is (otherwise e.g. the borrow-checker couldn't possibly work).

cc @rust-lang/lang

Havvy

comment created time in 15 days

pull request commentrust-lang/rust

updated p! macro to accept literals

@bors r+

jakevossen5

comment created time in 16 days

PullRequestReviewEvent

pull request commentrust-lang/rust

Permit ty::Bool in const generics for v0 mangling

@bors r+ Btw do you have a matching rustc-demangle PR?

Mark-Simulacrum

comment created time in 17 days

PullRequestReviewEvent

issue commentoschwald/maxminddb-rust

Can't build with panic = "abort"

It shouldn't impact anyone, you should avoid specifying crate_type in general, looks like it was left over from pre-Rust-1.0 days.

We should've deprecated dylib a long time ago, and staticlib is only useful if you're building a standalone C library (with a C API, which you don't have, so it does nothing for you).

ye2020

comment created time in 17 days

issue commentrust-lang/cargo

indicate in cargo build whether incremental is in use

I've just spent my day telling different people about CARGO_INCREMENTAL=1 (and the .cargo/config.toml incremental = true, which is probably a better semi-permanent solution), and none of them were aware that release mode had it disabled.

So I think it would be useful to say incremental or non-incremental so that there's at least a hint.

nikomatsakis

comment created time in 17 days

Pull request review commentrust-lang/rust

Returns values up to 2*usize by value

 where                     _ => return,                 } -                let max_by_val_size =-                    if is_ret { call::max_ret_by_val(cx) } else { Pointer.size(cx) };+                // Return structures up to 2 pointers in size by value, matching `ScalarPair`. LLVM+                // will usually return these in 2 registers, which is more efficient than by-ref.+                let max_by_val_size = if is_ret { Pointer.size(cx) * 2 } else { Pointer.size(cx) };

I wonder if it makes sense to limit this to returns, but also whether 3 might work better than 2 as the multiplier. But I guess there's a risk it might get downgraded from registers... I really wish LLVM modeled ABIs more precisely so we can control that.

jonas-schievink

comment created time in 17 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

Returns values up to 2*usize by value

 impl<'a, Ty> FnAbi<'a, Ty> {         Ok(())     } }--/// Returns the maximum size of return values to be passed by value in the Rust ABI.-///-/// Return values beyond this size will use an implicit out-pointer instead.-pub fn max_ret_by_val<C: HasTargetSpec + HasDataLayout>(spec: &C) -> Size {-    match spec.target_spec().arch.as_str() {-        // System-V will pass return values up to 128 bits in RAX/RDX.-        "x86_64" => Size::from_bits(128),

I was hoping removing this string comparison would help perf but I guess not?

jonas-schievink

comment created time in 17 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust

Return values up to 128 bits in registers

 impl<'a, Ty> FnAbi<'a, Ty> {         Ok(())     } }++/// Returns the maximum size of return values to be passed by value in the Rust ABI.+///+/// Return values beyond this size will use an implicit out-pointer instead.+pub fn max_ret_by_val<C: HasTargetSpec + HasDataLayout>(spec: &C) -> Size {+    match spec.target_spec().arch.as_str() {+        // System-V will pass return values up to 128 bits in RAX/RDX.+        "x86_64" => Size::from_bits(128),++        _ => spec.data_layout().pointer_size,+    }+}

That is, we already do 2 * pointer_size on all architectures, just not for arbitrary data, only pairs of scalars.

jonas-schievink

comment created time in 18 days

issue commentrust-lang/compiler-team

`ty.kind()` -> `ty.data()`

@rustbot second

nikomatsakis

comment created time in 18 days

Pull request review commentrust-lang/rust

Improve std::sys::windows::compat

 pub fn lookup(module: &str, symbol: &str) -> Option<usize> {     } } -pub fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str, fallback: usize) -> usize {-    let value = lookup(module, symbol).unwrap_or(fallback);-    ptr.store(value, Ordering::SeqCst);-    value-}- macro_rules! compat_fn {-    ($module:ident: $(+    ($module:literal: $(         $(#[$meta:meta])*-        pub fn $symbol:ident($($argname:ident: $argtype:ty),*)-                                  -> $rettype:ty {-            $($body:expr);*-        }+        pub fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty $body:block     )*) => ($(-        #[allow(unused_variables)]         $(#[$meta])*-        pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {+        pub mod $symbol {+            use super::*;             use crate::sync::atomic::{AtomicUsize, Ordering};             use crate::mem;-            type F = unsafe extern "system" fn($($argtype),*) -> $rettype;              static PTR: AtomicUsize = AtomicUsize::new(0); +            #[allow(unused_variables)]+            unsafe extern "system" fn fallback($($argname: $argtype),*) -> $rettype $body++            #[cold]             fn load() -> usize {-                crate::sys::compat::store_func(&PTR,-                                          stringify!($module),-                                          stringify!($symbol),-                                          fallback as usize)+                // There is no locking here. It's okay if this is executed by multiple threads in+                // parallel. `lookup` will result in the same value, and it's okay if they overwrite+                // eachothers result as long as they do so atomically. We don't need any guarantees+                // about memory ordering, as this involves just a single atomic variable which is+                // not used to protect or order anything else.+                let addr = crate::sys::compat::lookup($module, stringify!($symbol))+                    .unwrap_or(fallback as usize);+                PTR.store(addr, Ordering::Relaxed);+                addr             }-            unsafe extern "system" fn fallback($($argname: $argtype),*)-                                               -> $rettype {-                $($body);*++            fn addr() -> usize {+                match PTR.load(Ordering::Relaxed) {+                    0 => load(),+                    addr => addr,+                }             } -            let addr = match PTR.load(Ordering::SeqCst) {-                0 => load(),-                n => n,-            };-            mem::transmute::<usize, F>(addr)($($argname),*)+            #[allow(dead_code)]+            pub fn is_available() -> bool {+                addr() != fallback as usize

FWIW this looks fine to me now.

m-ou-se

comment created time in 18 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

Return values up to 128 bits in registers

 impl<'a, Ty> FnAbi<'a, Ty> {         Ok(())     } }++/// Returns the maximum size of return values to be passed by value in the Rust ABI.+///+/// Return values beyond this size will use an implicit out-pointer instead.+pub fn max_ret_by_val<C: HasTargetSpec + HasDataLayout>(spec: &C) -> Size {+    match spec.target_spec().arch.as_str() {+        // System-V will pass return values up to 128 bits in RAX/RDX.+        "x86_64" => Size::from_bits(128),++        _ => spec.data_layout().pointer_size,+    }+}

Is there anything wrong with 2 * pointer_size? IIRC we already return pairs in two registers.

jonas-schievink

comment created time in 18 days

PullRequestReviewEvent

pull request commentrust-lang/rust

Only use LOCAL_{STDOUT,STDERR} when set_{print/panic} is used.

You could use a thread-local Cell<bool>, that won't register a destructor, at least on cfg(target_thread_local) platforms.

m-ou-se

comment created time in 18 days

issue commentmicrosoft/vscode

Task terminal truncates long/quick output.

IIUC, #38137 was fixed in version 1.49 but I can still reproduce my testcase above with:

Version: 1.49.1
Commit: 58bb7b2331731bf72587010e943852e13e6fd3cf
Date: 2020-09-16T23:23:33.049Z
Electron: 9.2.1
Chrome: 83.0.4103.122
Node.js: 12.14.1
V8: 8.3.110.13-electron.0
OS: Linux x64 5.4.59

So I'm pretty sure this is a different bug than #38137.

eddyb

comment created time in 19 days

issue commentrust-lang/rfcs

Impl Copy for Range

Because Copy is a marker trait (no associated items), and its absence doesn't confer any additional powers (in general we try to avoid negative reasoning, I think - also see the previous comment where I show coherence is already future-proofed), I believe we can implement Copy on Range and feature-gate it.

While we still can't feature-gate individual impls without running into the complexity of all possible trait system interactions (and how it may behave across crates), we could "just" pretend Copy impls aren't there for types marked with #[must_clone], unless the feature-gate, e.g. #![feature(must_clone_copy_impls)] (bikeshed-ready name) is enabled.

There's one issue I see with this: if a dependency uses #![feature(must_clone_copy_impls)], definitions from it may result in ICEs when used/codegen'd in a downstream crate without the feature-gate. And I can think of two mitigations:

  1. avoid the feature in the standard library - this should avoid any cross-crate interactions for users which don't touch the feature-gate (or are on beta/stable), though it would limit dogfooding
  2. only hide the #[must_clone] + Copy impls in Reveal::UserFacing mode (i.e. type-checking, borrow-checking, lints), not Reveal::All mode (everything else, including MIR optimizations, miri, codegen, etc.) - that way, MIR from dependencies should continue to codegen correctly, even in downstream crates without the feature-gate
    • this should make mitigation 1. irrelevant but we might still want to be careful about it

cc @nikomatsakis @matthewjasper Do you have any opinions on this strategy? I think if we can feature-gate Range<_>: Copy, we can land it much sooner, and go through the normal stabilization process.

jyn514

comment created time in 19 days

PR closed rust-lang/rust

[experiment] Add MustClone and impl Copy+MustClone on Range{,From,Inclusive}. S-waiting-on-author

Background: (second half of) https://github.com/rust-lang/rfcs/issues/2848#issuecomment-697257283.

I'm opening this for two reasons:

  • demonstrating the (relatively simple) implementation (though it could use specialized diagnostics)
  • doing a crater run just in case simply having Range<_>: Copy breaks something through e.g. inference
+118 -54

20 comments

21 changed files

eddyb

pr closed time in 19 days

pull request commentrust-lang/rust

[experiment] Add MustClone and impl Copy+MustClone on Range{,From,Inclusive}.

I'm closing this experiment PR, please continue discussion over at https://github.com/rust-lang/rfcs/issues/2848#issuecomment-701951599, to avoid fragmentation.

eddyb

comment created time in 19 days

issue commentrust-lang/rfcs

Impl Copy for Range

If anyone is wondering, part of the reason adding Copy impls is backwards-compatible is, well, we future-proofed for it:

trait Trait {}
impl<T: Copy> Trait for T {}
impl Trait for std::ops::Range<usize> {}

That snippet produces (on playground) an error with this note:

upstream crates may add a new impl of trait std::marker::Copy for type std::ops::Range<usize> in future versions

jyn514

comment created time in 19 days

issue commentrust-lang/rfcs

Impl Copy for Range

Update on the experiment I was doing in https://github.com/rust-lang/rust/pull/77180: Range<_>: Copy appears to be backwards-compatible, like I was hoping it would be (see https://github.com/rust-lang/rust/pull/77180#issuecomment-701487663).

Quoting myself from that PR:

So we should be able to proceed here with an RFC or similar - though at the moment I don't have the bandwidth for anything like that, but if someone is interested in writing a #[must_clone] / trait MustClone RFC, feel free to show me drafts etc.

Importantly, I don't have a strong opinion on "attribute vs trait", and both implementation strategies should work (the attribute might be slightly easier even). I'd suggest looking for previous discussions of #[must_use] deficiencies (sadly I only have a vague memory of there being some discussion), or starting a t-lang thread on Zulip to discuss attribute vs trait.

jyn514

comment created time in 19 days

pull request commentrust-lang/rust

[experiment] Add MustClone and impl Copy+MustClone on Range{,From,Inclusive}.

Thanks! At least it being a lint means it shouldn't impact any crates that depend on conrod_core / kiss3d_conrod. And having that lint trip is a nice way to confirm that something is different.

So we should be able to proceed here with an RFC or similar - though at the moment I don't have the bandwidth for anything like that, but if someone is interested in writing a #[must_clone] / trait MustClone RFC, feel free to show me drafts etc.

eddyb

comment created time in 19 days

issue commentrust-lang/rust

Add `-Zrandomize-layout` flag to better detect code that rely on unspecified behavior related to memory layout

On Zulip @RalfJung pointed out that I didn't explain why you would want to make this deterministic (or why that's the main difficulty), so here's 3 reasons why this has to be deterministic:

  • unsizing coercions mean that generic types need to have the same field order across instantiations, when the field types match (ignoring the field that would be unsized) - so we can reorder based on alignment, but not randomize differently each time
  • layouts have to be the same for the same type across sibling crates (which do not know about eachother)
  • introducing non-determinism into the query system is unsound at least for incremental recompilation (where you will get miscompiles, i.e. potentially UB in safe code, if you have things like order-dependency or outright RNG)

There's two ways to get deterministic per-type-definition "seeds":

  • generate a random number when compiling the definition (and use that one value for shuffling the layout of every instance in any crate) - this is still troublesome with incremental, you would have to add it explicitly as an incremental input, in order to be sound, and it will cause a lot of invalidation
  • use the def_path_hash (which I mentioned in the previous comment), which is effectively the TypeId hash corresponding to a DefId, and rely on its hash properties be pseudo-random (it should change with compiler releases and crate versions specified in the Cargo.toml, so at least we should get some variety - though maybe not as much on nightly sadly)

You might probably also want a CLI flag to e.g. XOR in a fixed seed as well, even with the latter method, but it would have to be embedded in the type definition (so that it's correct cross-crate without requiring the same flag to passed in order to avoid miscompilation), so it's as much effort as both.

marmeladema

comment created time in 19 days

Pull request review commentrust-lang/rust

Fix control flow check for breaking with diverging values

 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {                 assert!(expr_opt.is_none() || self.tcx.sess.has_errors());             } -            ctxt.may_break = true;+            // If we encountered a `break`, then (no surprise) it may be possible to break from the+            // loop... unless the value being returned from the loop diverges itself, e.g.+            // `break return 5` or `break loop {}`.+            ctxt.may_break |= !e_ty.is_never();

Like self.diverges (was looking for it).

varkor

comment created time in 20 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

Fix control flow check for breaking with diverging values

 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {                 assert!(expr_opt.is_none() || self.tcx.sess.has_errors());             } -            ctxt.may_break = true;+            // If we encountered a `break`, then (no surprise) it may be possible to break from the+            // loop... unless the value being returned from the loop diverges itself, e.g.+            // `break return 5` or `break loop {}`.+            ctxt.may_break |= !e_ty.is_never();

Is is_never() correct? I would've expected something more general.

varkor

comment created time in 20 days

PullRequestReviewEvent

issue commentrust-lang/rust

Add `-Zrandomize-layout` flag to better detect code that rely on unspecified behavior related to memory layout

You can make this deterministic by using the def_path_hash for a given definition (it's an equivalent of DefId that's stable across incremental recompilation) - you might not even need to seed a PRNG with it if all you need is one value!

We can also do a limited version of this by default, but since it won't change the size, it would only fail at runtime https://github.com/rust-lang/rust/issues/38550#issuecomment-697115713

marmeladema

comment created time in 20 days

pull request commentrust-lang/rust

normalize in codegen_fulfill_obligations

LGTM but r? @nikomatsakis or @matthewjasper (this feels like a matter of policy, i.e. fixing bugs or working around them).

lcnr

comment created time in 21 days

pull request commentrust-lang/rust

normalize in codegen_fulfill_obligations

Hmm, this might be expensive. What I would do is assert that normalizing doesn't change the type, then track down the source of the unnormalized type and fix that. But just to see what impact it has on its own:

@bors try @rust-timer queue

lcnr

comment created time in 21 days

issue commentrust-lang/project-error-handling

Prototype `core::error::Error` to prove that stabilizing `fn backtrace` will not prevent a later move of the error trait to core

This is a full example of what @yaahc, @mystor and I have discussed (I don't plan to be actively involved, but felt like I needed to exemplify my suggestions): https://play.rust-lang.org/?version=nightly&mode=release&edition=2018&gist=63b4720d0347d05391643df9da08c72f

Also here's a more pseudocode version of it (and without most implementation details), to facilitate discussion:

mod core::panic {
    // perma(?)-unstable
    pub trait RawBacktraceImpl: fmt::Debug + fmt::Display + 'static {
        unsafe fn drop_and_free(self: *mut Self);
    }

    #[stable]
    pub struct Backtrace(*mut dyn RawBacktraceImpl);

    impl Backtrace {
        // perma(?)-unstable
        pub unsafe fn new(p: *mut dyn RawBacktraceImpl) -> Self {
            Self(p)
        }

        #[stable]
        pub fn capture() -> Option<Self> {
            extern "Rust" {
                #[lang_item = "backtrace_capture"]
                fn backtrace_capture() -> Option<Backtrace>;
            }
            unsafe { backtrace_capture() }
        }
    }

    impl !Send for Backtrace {}
    impl !Sync for Backtrace {}
    impl Drop for Backtrace {...}
    impl fmt::Debug for Backtrace {...}
    impl fmt::Display for Backtrace {...}
}
mod alloc::panic {
    #[stable]
    pub trait BacktraceImpl: fmt::Debug + fmt::Display + 'static {}

    impl<T: BacktraceImpl> From<Box<T>> for Backtrace {
        fn from(x: Box<T>) -> Self {
            struct Wrapper<T>(T);

            impl<T: BacktraceImpl> RawBacktraceImpl for Wrapper<T> {...}
            impl<T: fmt::Debug> fmt::Debug for Wrapper<T> {...}
            impl<T: fmt::Display> fmt::Display for Wrapper<T> {...}

            unsafe {
                Backtrace::new(Box::into_raw(x) as *mut Wrapper<T> as *mut dyn RawBacktraceImpl)
            }
        }
    }
}
mod std::panic {
    #[lang_item = "backtrace_capture"]
    fn backtrace_capture() -> Option<Backtrace> {
        struct StdBacktrace;

        impl fmt::Debug for StdBacktrace {...}
        impl fmt::Display for StdBacktrace {...}
        impl BacktraceImpl for StdBacktrace {}

        Some(Box::new(StdBacktrace).into())
    }
}
yaahc

comment created time in 23 days

Pull request review commentrust-lang/rust

Implement const expressions and patterns (RFC 2920)

 impl<'a, 'tcx> Builder<'a, 'tcx> {                 let region_scope = (region_scope, source_info);                 this.in_scope(region_scope, lint_level, |this| this.as_rvalue(block, scope, value))             }+            ExprKind::AnonConst { value } => {+                block.and(Rvalue::Use(Operand::Constant(box Constant {+                    span: expr_span,+                    user_ty: None,+                    literal: value,+                })))+            }

Can probably deduplicate this with the literal case, or place it nearby it.

spastorino

comment created time in 24 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

Implement const expressions and patterns (RFC 2920)

 impl Category {             | ExprKind::Box { .. }             | ExprKind::Cast { .. }             | ExprKind::Pointer { .. }+            | ExprKind::AnonConst { .. }

This should be like ExprKind::Literal { .. }, in the Constant arm below. In general, it would be great to place the new ExprKind case below the Lit(eral) one everywhere, because they're very similar in most cases.

spastorino

comment created time in 24 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

Implement const expressions and patterns (RFC 2920)

 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {         self.tcx.mk_array(element_ty, args.len() as u64)     } +    fn check_expr_anon_const(&self, anon_const: &'tcx hir::AnonConst) -> Ty<'tcx> {+        self.to_const(anon_const).ty+    }

No need for a separate method, this is far too simple.

spastorino

comment created time in 24 days

PullRequestReviewEvent

pull request commentrust-lang/rust

Move from {{closure}}#0 syntax to {closure#0} for (def) path components

@bors r+ Thanks!

marmeladema

comment created time in 24 days

PullRequestReviewEvent

pull request commentrust-lang/rust

Widen TypeId from 64 bits to 128.

@bjorn3 Thanks. Even if disabled by default at runtime, the fact that it's built into Firefox means that we can easily break Firefox building with newer Rust versions if we change something about TypeId, so this deserves the most investigation.

eddyb

comment created time in 24 days

issue commentrust-lang/rfcs

Impl Copy for Range

@programmerjake I think there were issues with those attributes that relying on traits could've resolved, but also it doesn't really matter either way, an attribute could also work, the only difference is if we ever stabilize it.

jyn514

comment created time in 24 days

pull request commentrust-lang/rust

Widen TypeId from 64 bits to 128.

Huh, so the worst breakage would be Servo (a component of it that's benchmarked on perf broke when I tried to do a perf run)? Do we know if that code is in Firefox?

eddyb

comment created time in 24 days

issue commentrust-lang/rust

Linker error with wasm target with spaces in install path

Summarizing from the Zulip discussion:

I believe this was introduced by https://github.com/llvm/llvm-project/commit/928e9e172305752583a75a8174ab5a87b4e09d80, which fixed parsing "response files" (@file indicating file's contents should be inlined in the command-line arguments), to use the encoding style of the host platform instead of hardcoding "GNU". But our code still outputs the GNU style, even on Windows, and that's why it breaks.

I expect all we need to do is pass -rsp-quoting=posix here (these are arguments passed outside of the @ file): https://github.com/rust-lang/rust/blob/b984ef6797ff17faa2b1e0ebb54b78de1491e5fd/compiler/rustc_codegen_ssa/src/back/command.rs#L109

Alternatively, we could try and come up with an escaping method that is a superset of the two implemented variants: https://github.com/rust-lang/rust/blob/b984ef6797ff17faa2b1e0ebb54b78de1491e5fd/compiler/rustc_codegen_ssa/src/back/link.rs#L1148-L1181

Then it wouldn't matter what style is expected, it would always be correct. I believe our Windows escaping would be valid everywhere, at least from briefly reading the comments in the snippet above, so we could just always use that.

jminer

comment created time in 24 days

pull request commentrust-lang/rust

[experiment] Add MustClone and impl Copy+MustClone on Range{,From,Inclusive}.

@craterbot check

eddyb

comment created time in 24 days

pull request commentrust-lang/rust

Ignore ZST offsets when deciding whether to use Scalar/ScalarPair layout

I got the Zulip PM but then because of how Zulip forces you to always see messages when navigating, it marked it as read, I'm really sorry. I'm still generally months behind most things on GitHub (and even waiting-on-review PRs) but trying to help where I can (don't mind repeated PMs, it helps with various platforms being all over the place).

@bors r+

erikdesjardins

comment created time in 24 days

PullRequestReviewEvent

push eventeddyb/rust

Eduard-Mihai Burtescu

commit sha 346ede0510b7b9d4089a9be10ae3565773337e31

[experiment] Add MustClone and impl Copy+MustClone on Range{,From,Inclusive}.

view details

push time in 24 days

Pull request review commentrust-lang/rust

[experiment] Add MustClone and impl Copy+MustClone on Range{,From,Inclusive}.

 fn copy_or_move<'a, 'tcx>(     mc: &mc::MemCategorizationContext<'a, 'tcx>,     place_with_id: &PlaceWithHirId<'tcx>, ) -> ConsumeMode {+    // FIXME(eddyb) add `|| type_is_must_clone(ty)`.

Oh I need to fix this so we don't end up with by-ref captures that the MIR borrowck later errors on because we generate MIR Moves out of those.

eddyb

comment created time in 24 days

PullRequestReviewEvent

issue commentrust-lang/rfcs

Impl Copy for Range

Opened #77180 for the MustClone idea, in its simplest implementation.

jyn514

comment created time in 24 days

pull request commentrust-lang/rust

[experiment] Add MustClone and impl Copy+MustClone on Range{,From,Inclusive}.

Oh and since this may require a fast path to not regress perf: @rust-timer queue

eddyb

comment created time in 24 days

PR opened rust-lang/rust

[experiment] Add MustClone and impl Copy+MustClone on Range{,From,Inclusive}.

Background: (second half of) https://github.com/rust-lang/rfcs/issues/2848#issuecomment-697257283.

I'm opening this for two reasons:

  • demonstrating the (relatively simple) implementation (though it could use specialized diagnostics)
  • doing a crater run just in case simply having Range<_>: Copy breaks something through e.g. inference
+112 -50

0 comment

20 changed files

pr created time in 24 days

create barncheddyb/rust

branch : must-clone

created branch time in 24 days

pull request commentrust-lang/rust

[experiment/perf] Disable jemalloc's time-delayed purging, for extra determinism.

Okay that does nothing, but I won't go through the trouble of doing another try build, especially with SpecLockMap still undisabled on the perf collection server (i.e. the Python script from https://github.com/mozilla/rr/wiki/Zen needs to be run).

eddyb

comment created time in 25 days

more