profile
viewpoint

japaric/xargo 768

The sysroot manager that lets you build and customize `std`

Gilnaa/memoffset 74

offsetof for Rust

opatut/dudel 29

This used to be a webapp for scheduling meetings easily. Now it's no longer maintained. Have a look at Bitpoll instead:

Diggsey/rust-field-offset 19

Safe pointer-to-member functionality for rust

RalfJung/ansible 1

ansible playbooks for my servers

freifunk-saar/tunneldigger 0

Client and broker for our custom L2TPv3 NAT-traversing tunnel setup protocol based on L2TPv3 support in the Linux kernel.

hacksaar/Firmware 0

ESP32 firmware for the SHA2017 badge

hacksaar/micropython-esp32 0

MicroPython ported to the SHA2017 badge

pull request commentrust-lang/rust

Miri: Renamed "undef" to "uninit"

@bors r+ rollup (there's no email notification after a force-push so I did not realize this was ready for review again. feel free to ping me in such cases.)

pnadon

comment created time in 9 hours

Pull request review commentwlanslovenija/tunneldigger

handle hook process being closed twice

 def close(self):         Closes the hook process.         """ +        if not hasattr(self, "buffer"):

That's still not atomic, so it will not solve race conditions. But also, this is all sequential, right?

RalfJung

comment created time in 10 hours

PR opened wlanslovenija/tunneldigger

handle hook process being closed twice

After merging https://github.com/wlanslovenija/tunneldigger/pull/148, I started seeing exceptions terminating the broker on one (the slowest) of our servers. Seems like reacting to EPOLLHUP means we now close some things twice, which the HookProcess class did not handle well. This fixes the exceptions, but I am not sure if it is a proper fix.

+4 -0

0 comment

1 changed file

pr created time in 11 hours

create barnchfreifunk-saar/tunneldigger

branch : hook-close

created branch time in 11 hours

push eventfreifunk-saar/tunneldigger

Ralf Jung

commit sha 5e9b5d93c8dbb6efa7e2bdddfb426789e2d78578

handle hook process being closed twice

view details

push time in 11 hours

push eventfreifunk-saar/tunneldigger

Ralf Jung

commit sha 2951a3bc81771038f44c5c4a730c2f48a4e285e3

handle hook process being closed twice

view details

push time in 11 hours

push eventrust-lang/const-eval

Ralf Jung

commit sha 0d168d005e05bf9e13427d2eb9f2e67d88607290

fix skill tree for real, hopefully

view details

push time in 12 hours

pull request commentrust-lang/const-eval

Link to skill tree and fix some nodes

I did a direct push to hopefully fix this.

RalfJung

comment created time in 12 hours

push eventrust-lang/const-eval

Ralf Jung

commit sha cabcc4e3c20cb40e6f0467f3b84589c64a1e891e

fix skill tree

view details

push time in 12 hours

pull request commentrust-lang/const-eval

Link to skill tree and fix some nodes

CI said

Warning: The mdbook-skill-tree preprocessor was built against version 0.3.7 of mdbook, but we're being called from version 0.4.1
thread 'main' panicked at 'encountered error missing field `items` for key `group` at line 279 column 1', mdbook-skill-tree/src/preprocessor.rs:85:31
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
2020-08-10 13:22:09 [ERROR] (mdbook::utils): Error: The preprocessor exited unsuccessfully
##[error]Process completed with exit code 101.
RalfJung

comment created time in 12 hours

delete branch RalfJung/const-eval

delete branch : skills

delete time in 12 hours

pull request commentrust-lang/const-eval

Link to skill tree and fix some nodes

Hm, https://rust-lang.github.io/const-eval/ still contains that "rfc" node?

RalfJung

comment created time in 12 hours

issue commentrust-lang/rust

LLVM loop optimization can make safe programs crash

I have no idea if that is an instance of this problem or something else... embedded devices are not my specialty at all and with all these external crate dependencies I have no idea what else that code is doing.^^ But your program is not safe and it does have a volatile access in the loop, so I'd say it is a separate problem. When I put your example on the playground, I think it is compiled correctly, so I'd suspect the problem is with one of the extra dependencies.

RalfJung

comment created time in 12 hours

issue commentrust-lang/rust

Perform validation in const_eval_raw and return valtree from const_eval

I just realized MirConstValue is identical to our current ConstValue :rofl:

RalfJung

comment created time in 12 hours

issue commentrust-lang/rust

Perform validation in const_eval_raw and return valtree from const_eval

We don't really need the full Valtree in MirConstValue though, we just need Scalar and ScalarPair. I am not sure what is easier for producers and/or consumers here. I think if we can make it actually just be Scalar and ScalarPair then codegen and Miri do not have to handle valtrees, which would be good. So maybe more like

enum MirConstValue {
  Scalar(...),
  ScalarPair(...), // or "Slice" or so -- I suppose we cannot entirely avoid this
  Alloc(&'tcx Allocation),
}

mod ty { type Const = NotSureWhatToCallThis<Valtree>; }
mod mir { type Const = NotSureWhatToCallThis<MirConstValue>; }
RalfJung

comment created time in 12 hours

issue commentrust-lang/rust

Perform validation in const_eval_raw and return valtree from const_eval

It's something that should be evaluable to a valtree and will error if trying to do so fails.

:+1:

This is similar to my first attempt, but it failed badly because getting there is very hard with the way ty::Const is hardwired into things like

Those would be two different types then, ty::Const and mir::Const respectively. What is the problem?

I'm not sure we can just use NotSureWhatToCallThis<&'tcx Allocation> for mir::Const, as we also have to allow for literals that came from the AST to be in an "optimized" representation.

Good point, I had forgotten about that. It would be more like

enum MirConstValue {
  Literal(Valtree),
  Alloc(&'tcx Allocation),
}

mod ty { type Const = NotSureWhatToCallThis<Valtree>; }
mod mir { type Const = NotSureWhatToCallThis<MirConstValue>; }
RalfJung

comment created time in 12 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> {     pub tcx: TyCtxt<'tcx>, } -/// Return the `tcx` allocation containing the initial value of the given static-pub fn get_static(tcx: TyCtxt<'tcx>, def_id: DefId) -> InterpResult<'tcx, &'tcx Allocation> {

Miri also calls this -- can you prepare a Miri patch?

oli-obk

comment created time in 12 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {          let gid = GlobalId { instance, promoted: None }; -        let place = self.const_eval_raw(gid)?;+        let place = self.const_eval(gid)?;

Ah I think I see it now. :)

oli-obk

comment created time in 12 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 rustc_queries! {     }      Other {-        /// Evaluates a constant without running sanity checks.-        ///-        /// **Do not use this** outside const eval. Const eval uses this to break query cycles-        /// during validation. Please add a comment to every use site explaining why using-        /// `const_eval_validated` isn't sufficient. The returned constant also isn't in a suitable-        /// form to be used outside of const eval.-        query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)+        /// Evaluates a constant and returns the computed allocation.+        query const_eval(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)

Should this also get a comment like "do not use directly, use one of the following wrappers"?

oli-obk

comment created time in 12 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 rustc_queries! {     }      Other {-        /// Evaluates a constant without running sanity checks.-        ///-        /// **Do not use this** outside const eval. Const eval uses this to break query cycles-        /// during validation. Please add a comment to every use site explaining why using-        /// `const_eval_validated` isn't sufficient. The returned constant also isn't in a suitable-        /// form to be used outside of const eval.-        query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)+        /// Evaluates a constant and returns the computed allocation.+        query const_eval(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)             -> ConstEvalRawResult<'tcx> {

We should make a note to change the type of this type -- and its doc comment also needs adjusting.

oli-obk

comment created time in 12 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 impl<'tcx> TyCtxt<'tcx> {         // improve caching of queries.         let inputs = self.erase_regions(&param_env.and(cid));         if let Some(span) = span {-            self.at(span).const_eval_validated(inputs)+            self.at(span).const_eval_for_ty(inputs)         } else {-            self.const_eval_validated(inputs)+            self.const_eval_for_ty(inputs)         }     }++    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.+    pub fn eval_static_initializer(self, def_id: DefId) -> Result<&'tcx Allocation, ErrorHandled> {+        trace!("eval_static_initializer: Need to compute {:?}", def_id);+        assert!(self.is_static(def_id));+        let instance = ty::Instance::mono(self, def_id);+        let gid = GlobalId { instance, promoted: None };+        self.eval_mir_const(gid, ty::ParamEnv::reveal_all())+    }++    /// Evaluate anything constant-like, returning the allocation of the final memory.+    fn eval_mir_const(

Since mir::Const will likely be something different, this name is still potentially confusing,

An alternative would be eval_global. But that is very close to const_eval_global_id, which maybe should be eval_global_for_ty.

Why do some functions that with const_eval and some with eval?

oli-obk

comment created time in 12 hours

issue commentrust-lang/unsafe-code-guidelines

Define: Byte

I don't think the actual Abstract Machine byte can be reflected into the standard library. That would be more like Option<u8>, plus taking into account provenance.

The abstract machine byte is defined outside the language and says how e.g. an interpreter would have to represent a Rust byte. It allows explicitly inspecting whether a byte is initialized and what its provenance is. In contrast, your Byte type is defined inside the language and used e.g. by low-level functions that want to be able to move around arbitrary data, but it is fundamentally impossible to test if a given byte is initialized.

RalfJung

comment created time in 12 hours

issue openedwlanslovenija/tunneldigger

The client can get stuck in a high-frequency retry loop

Sometimes a client seems to be stuck in a high-frequency retry loop, establishing a new connection every 2-5s and immediately abandoning it. https://github.com/wlanslovenija/tunneldigger/issues/143 is resolved, which means the servers do not have heavy load from such a loop any more, but the question remains what is going on with those clients.

Unfortunately, so far I was not able to acquire a log from one of the affected nodes. @kaechele you said you also experienced this problem; were/are you able to get a logfile from the problematic node?

created time in 12 hours

push eventfreifunk-saar/tunneldigger

Ralf Jung

commit sha 1ea5b139ca63c5f8791bf39e0d75e0e0ae45f3ec

print warning when we run out of tunnel IDs

view details

Ralf Jung

commit sha 93a11a8123479fa1ca951fade84c9bac80bcae24

use lazy string interpolation

view details

Ralf Jung

commit sha 3e530f159c193f35c0019b91ecb4228f84a31d33

close pollable when its FDs errors

view details

Ralf Jung

commit sha b8fd97efbacfc0ec5d67b153bc83eb5dbc1cb1f9

also close pollables on HUP

view details

push time in 13 hours

delete branch freifunk-saar/tunneldigger

delete branch : close-on-err

delete time in 13 hours

push eventwlanslovenija/tunneldigger

Ralf Jung

commit sha 3e530f159c193f35c0019b91ecb4228f84a31d33

close pollable when its FDs errors

view details

Ralf Jung

commit sha b8fd97efbacfc0ec5d67b153bc83eb5dbc1cb1f9

also close pollables on HUP

view details

push time in 13 hours

PR merged wlanslovenija/tunneldigger

close pollable when its FD errors

When an FD errors, epoll returns immediately reporting the error. This leads to a tight loop (instead of epoll waiting until there is a new event), causing very high load (https://github.com/wlanslovenija/tunneldigger/issues/143). So we should stop polling FDs once they error. This PR achieves that by simply closing the associated pollable.

I checked that on our server with a misbehaving client whose connections keep dropping this reduces the load from 100% to basically nothing.

Fixes https://github.com/wlanslovenija/tunneldigger/issues/143.

+2 -0

2 comments

1 changed file

RalfJung

pr closed time in 13 hours

issue closedwlanslovenija/tunneldigger

High CPU load due to a single misbehaving client

We occasionally see a client misbehave and establish multiple connections at the same time to all our servers. For some reason, even when there are just around 20 connections per 10 minutes, this causes 100% CPU load by tunneldigger. Python is not the most efficient language, but this seems eccessive -- I'd like to better understand where in the broker all that CPU time is spent. Unfortunately, so far I found no good way to do such an analysis for python (what I am looking for is something like callgrind).

closed time in 13 hours

RalfJung

pull request commentwlanslovenija/tunneldigger

close pollable when its FD errors

All right, merging then.

RalfJung

comment created time in 13 hours

push eventfreifunk-saar/tunneldigger

Ralf Jung

commit sha 1ea5b139ca63c5f8791bf39e0d75e0e0ae45f3ec

print warning when we run out of tunnel IDs

view details

Ralf Jung

commit sha 93a11a8123479fa1ca951fade84c9bac80bcae24

use lazy string interpolation

view details

Ralf Jung

commit sha 6b49527b0e65f6f7126ca2edfacdf363062fdf38

Merge branch 'master' into close-on-err

view details

push time in 14 hours

delete branch freifunk-saar/tunneldigger

delete branch : tunnel-id-warn

delete time in 14 hours

push eventwlanslovenija/tunneldigger

Ralf Jung

commit sha 1ea5b139ca63c5f8791bf39e0d75e0e0ae45f3ec

print warning when we run out of tunnel IDs

view details

Ralf Jung

commit sha 93a11a8123479fa1ca951fade84c9bac80bcae24

use lazy string interpolation

view details

push time in 14 hours

pull request commentrust-lang/const-eval

add document on consts in patterns

Thanks for the help @oli-obk :)

RalfJung

comment created time in 17 hours

delete branch RalfJung/const-eval

delete branch : patterns

delete time in 17 hours

Pull request review commentrust-lang/rust

Make `<*const T>::is_null` const fn

+// compile-flags: --crate-type=lib++#![feature(const_ptr_is_null, const_panic)]++const FOO: &usize = &42;++pub const FOO_PTR_IS_NULL: bool = (FOO as *const usize).is_null();+pub const CHECK: () = assert!(FOO_PTR_IS_NULL);+//~^ ERROR any use of this value will cause an error

That's such a weird test, the assertions are the opposite of what we want! Please either add a comment, or (better IMO) make it a normal positive assertion.

oli-obk

comment created time in 18 hours

pull request commentrust-lang/rust

Make `<*const T>::is_null` const fn

r=me with the last nit fixed and after squashing

oli-obk

comment created time in 18 hours

Pull request review commentrust-lang/rust

Make `<*const T>::is_null` const fn

 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {         Ok(true)     } +    fn guaranteed_eq(&mut self, a: Scalar<M::PointerTag>, b: Scalar<M::PointerTag>) -> bool {+        match (a, b) {+            // Comparisons between integers are always known.+            (Scalar::Raw { .. }, Scalar::Raw { .. }) => a == b,+            // Equality with integers can never be known for sure.+            (Scalar::Raw { .. }, Scalar::Ptr(_)) | (Scalar::Ptr(_), Scalar::Raw { .. }) => false,+            // FIXME: return `true` for when both sides are the same pointer, *except* that+            // some things (like functions and vtables) do not have stable addresses+            // so we need to be careful around them.+            (Scalar::Ptr(_), Scalar::Ptr(_)) => false,+        }+    }++    fn guaranteed_ne(&mut self, a: Scalar<M::PointerTag>, b: Scalar<M::PointerTag>) -> bool {+        match (a, b) {+            // Comparisons between integers are always known.+            (Scalar::Raw { .. }, Scalar::Raw { .. }) => a != b,+            // Comparisons of abstract pointers with null pointers are known if the pointer+            // is in bounds, because if they are in bounds, the pointer can't be null.+            (Scalar::Raw { data: 0, .. }, Scalar::Ptr(ptr))+            | (Scalar::Ptr(ptr), Scalar::Raw { data: 0, .. }) => !self.memory.ptr_may_be_null(ptr),+            // Inequality with integers other than null can never be known for sure unless+            // we figure out a way to define that in a way that soundness can rely on it.
            // Inequality with integers other than null can never be known for sure.

Not sure what the "figure out a way to define in a way" is referring to, but I think the shorter comment is clear and correct.

oli-obk

comment created time in 18 hours

Pull request review commentrust-lang/const-eval

add document on consts in patterns

+# Constants in patterns++Constants that pass the [structural equality check][struct-eq] can be used in patterns:+```rust+const FOO: i32 = 13;++fn is_foo(x: i32) -> bool {+  match x {+    FOO => true,+    _ => false,+  }+}+```+However, that check has some loopholes, so e.g. `&T` can be used in a pattern no matter the `T`.++Any reference type const-pattern is compiled by [calling `PartialEq::eq`][compile-partial-eq] to compare the subject of the `match` with the constant. Const-patterns with other types (enum, struct, tuple, array) are treated as if the constant was inlined as a pattern (and the usual `match` tree is constructed).+Note that this is in contradiction with what has been RFC'd, which specifies that we should always call `PartialEq::eq`.

I adjusted the text to reflect what I think the RFC says.

RalfJung

comment created time in 18 hours

push eventRalfJung/const-eval

Ralf Jung

commit sha 18f3020b9fa40e21852b6ef0dce7ac0fab92946d

compare with RFC 1445

view details

push time in 18 hours

Pull request review commentrust-lang/const-eval

add document on consts in patterns

+# Constants in patterns++Constants that pass the [structural equality check][struct-eq] can be used in patterns:+```rust+const FOO: i32 = 13;++fn is_foo(x: i32) -> bool {+  match x {+    FOO => true,+    _ => false,+  }+}+```+However, that check has some loopholes, so e.g. `&T` can be used in a pattern no matter the `T`.++Any reference type const-pattern is compiled by [calling `PartialEq::eq`][compile-partial-eq] to compare the subject of the `match` with the constant. Const-patterns with other types (enum, struct, tuple, array) are treated as if the constant was inlined as a pattern (and the usual `match` tree is constructed).+Note that this is in contradiction with what has been RFC'd, which specifies that we should always call `PartialEq::eq`.

I don't think that is more explicit that "The goal of this RFC is not to decide between semantic and structural equality".

That text you quoted does not say anywhere that we should use semantic equality for anything.

RalfJung

comment created time in 18 hours

Pull request review commentrust-lang/const-eval

add document on consts in patterns

+# Constants in patterns++Constants that pass the [structural equality check][struct-eq] can be used in patterns:+```rust+const FOO: i32 = 13;++fn is_foo(x: i32) -> bool {+  match x {+    FOO => true,+    _ => false,+  }+}+```+However, that check has some loopholes, so e.g. `&T` can be used in a pattern no matter the `T`.++Any reference type const-pattern is compiled by [calling `PartialEq::eq`][compile-partial-eq] to compare the subject of the `match` with the constant. Const-patterns with other types (enum, struct, tuple, array) are treated as if the constant was inlined as a pattern (and the usual `match` tree is constructed).+Note that this is in contradiction with what has been RFC'd, which specifies that we should always call `PartialEq::eq`.

But later the RFC explicitly says

The goal of this RFC is not to decide between semantic and structural equality. Rather, the goal is to restrict pattern matching to that subset of types where the two variants behave roughly the same.

RalfJung

comment created time in 18 hours

Pull request review commentrust-lang/const-eval

add document on consts in patterns

+# Constants in patterns++Constants that pass the [structural equality check][struct-eq] can be used in patterns:+```rust+const FOO: i32 = 13;++fn is_foo(x: i32) -> bool {+  match x {+    FOO => true,+    _ => false,+  }+}+```+However, that check has some loopholes, so e.g. `&T` can be used in a pattern no matter the `T`.++Any reference type const-pattern is compiled by [calling `PartialEq::eq`][compile-partial-eq] to compare the subject of the `match` with the constant. Const-patterns with other types (enum, struct, tuple, array) are treated as if the constant was inlined as a pattern (and the usual `match` tree is constructed).+Note that this is in contradiction with what has been RFC'd, which specifies that we should always call `PartialEq::eq`.

The RFC calls this "semantic equality" and makes some preparation for maybe switching to it in the future, but it dosn't actually say that we want to adopt semantic equality. That's my reading, anyway.

RalfJung

comment created time in 18 hours

Pull request review commentrust-lang/const-eval

add document on consts in patterns

+# Constants in patterns++Constants that pass the [structural equality check][struct-eq] can be used in patterns:+```rust+const FOO: i32 = 13;++fn is_foo(x: i32) -> bool {+  match x {+    FOO => true,+    _ => false,+  }+}+```+However, that check has some loopholes, so e.g. `&T` can be used in a pattern no matter the `T`.++Any reference type const-pattern is compiled by [calling `PartialEq::eq`][compile-partial-eq] to compare the subject of the `match` with the constant. Const-patterns with other types (enum, struct, tuple, array) are treated as if the constant was inlined as a pattern (and the usual `match` tree is constructed).+Note that this is in contradiction with what has been RFC'd, which specifies that we should always call `PartialEq::eq`.

Would be good to link to the RFC here. I assume that's https://github.com/rust-lang/rfcs/blob/master/text/1445-restrict-constants-in-patterns.md but so far I have not found where it says that we should use PartialEq.

RalfJung

comment created time in 18 hours

push eventRalfJung/const-eval

Ralf Jung

commit sha fe9275698786569c9701893ef79df769871c41a9

note that the implementation does not match the RFC

view details

push time in 18 hours

push eventRalfJung/const-eval

Ralf Jung

commit sha bd37599e594db12aa87215700cf7d4114184bf0b

Explain how patterns are compiled Co-authored-by: Oliver Scherer <github35764891676564198441@oli-obk.de>

view details

push time in 18 hours

issue commentrust-lang/const-eval

Link to skill tree

We could but that would be much more work... and then suddenly we have two URLs for the same document, which I think is rather confusing.

RalfJung

comment created time in 18 hours

Pull request review commentrust-lang/rust

Make `<*const T>::is_null` const fn

 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {         Ok(true)     } +    fn guaranteed_eq(&mut self, a: Scalar<M::PointerTag>, b: Scalar<M::PointerTag>) -> bool {+        match (a, b) {+            // Comparisons between integers are always known.+            (Scalar::Raw { .. }, Scalar::Raw { .. }) => a == b,+            // Equality with integers can never be known for sure.+            (Scalar::Raw { .. }, Scalar::Ptr(_)) | (Scalar::Ptr(_), Scalar::Raw { .. }) => false,+            // FIXME: return `true` for at least some comparisons where we can reliably+            // determine the result of runtime equality tests at compile-time.+            // Examples include comparison of addresses in static items, for these we can+            // give reliable results.
            // FIXME: return `true` for when both sides are the same pointer, *except* that
            // some things (like functions and vtables) do not have stable addresses
            // so we need to be careful around them.
oli-obk

comment created time in 18 hours

Pull request review commentrust-lang/const-eval

add document on consts in patterns

+# Constants in patterns++Constants that pass the [structural equality check](https://github.com/rust-lang/rust/issues/74446) can be used in patterns:+```rust+const FOO: i32 = 13;++fn is_foo(x: i32) -> bool {+  match x {+    FOO => true,+    _ => false,+  }+}+```+However, that check has some loopholes, so e.g. `&T` can be used in a pattern no matter the `T`.++A const-pattern is compiled by calling `PartialEq::eq` to compare the subject of the `match` with the constant,+except for TODO where the constant is treated as if it was inlined as a pattern (and the usual `match` tree is constructed).++## Soundness concerns++Most of the time there are no extra soundness concerns due to const-patterns; except for surprising behavior nothing can go wrong when the structural equality check gives a wrong answer.+However, there is one exception: some constants participate in exhaustiveness checking.+If a pattern is incorrectly considered exhaustive, that leads to a critical soundness bug.++Exhaustiveness checking is done for constants of type TODO, as well as `&[u8]` and `&str` (but no other types with references).

I adjusted the text, please check. :)

RalfJung

comment created time in 18 hours

Pull request review commentrust-lang/const-eval

add document on consts in patterns

+# Constants in patterns++Constants that pass the [structural equality check](https://github.com/rust-lang/rust/issues/74446) can be used in patterns:+```rust+const FOO: i32 = 13;++fn is_foo(x: i32) -> bool {+  match x {+    FOO => true,+    _ => false,+  }+}+```+However, that check has some loopholes, so e.g. `&T` can be used in a pattern no matter the `T`.++A const-pattern is compiled by calling `PartialEq::eq` to compare the subject of the `match` with the constant,

@oli-obk could you propose something concrete we could write for the remaining TODO?

RalfJung

comment created time in 18 hours

push eventRalfJung/const-eval

Ralf Jung

commit sha c67ebb514020443f3253af617c05c1c4e1f9911c

document for which consts we do exhaustiveness checking

view details

push time in 18 hours

Pull request review commentrust-lang/const-eval

add document on consts in patterns

+# Constants in patterns++Constants that pass the [structural equality check](https://github.com/rust-lang/rust/issues/74446) can be used in patterns:+```rust+const FOO: i32 = 13;++fn is_foo(x: i32) -> bool {+  match x {+    FOO => true,+    _ => false,+  }+}+```+However, that check has some loopholes, so e.g. `&T` can be used in a pattern no matter the `T`.++A const-pattern is compiled by calling `PartialEq::eq` to compare the subject of the `match` with the constant,+except for TODO where the constant is treated as if it was inlined as a pattern (and the usual `match` tree is constructed).++## Soundness concerns++Most of the time there are no extra soundness concerns due to const-patterns; except for surprising behavior nothing can go wrong when the structural equality check gives a wrong answer.+However, there is one exception: some constants participate in exhaustiveness checking.+If a pattern is incorrectly considered exhaustive, that leads to a critical soundness bug.++Exhaustiveness checking is done for constants of type TODO, as well as `&[u8]` and `&str` (but no other types with references).

Okay somehow I expected a match where I'd clearly see references being treated separately. I guess I'll just transcribe what you said into the text, there is no way for me to verify that.

RalfJung

comment created time in 18 hours

Pull request review commentrust-lang/rust

Make `<*const T>::is_null` const fn

 check!(!eq, 0, 1); check!(!ne, 0, 0); check!(ne, FOO as *const _, 0); check!(!eq, FOO as *const _, 0);+// We want pointers to be equal to themselves, but aren't checking this yet because+// there are some open questions (e.g. whether function pointers to the same function+// compare equal, they don't necessarily at runtime).+// But at least the case tested here should work.
// The case tested here should work eventually, but does not work yet.

I find it very confusing when the test says "X should work" but tests the opposite.^^

oli-obk

comment created time in 18 hours

push eventRalfJung/const-eval

Ralf Jung

commit sha 5371e4db5973d3b9de1acaaf6c63584ac0796802

add node for const_ptr_offset feature

view details

push time in 18 hours

Pull request review commentrust-lang/const-eval

Link to skill tree and fix some nodes

 href = "https://github.com/rust-lang/const-eval/issues/14"  [[group]] name = "offset_of"-label = "offset_of\nfeature:const_ptr_offset"-href = "https://github.com/rust-lang/rust/issues/71499"

offset_of has very little to do with offset/wrapping_offset. If we want the latter in the skill tree, they should be a separate node.

RalfJung

comment created time in 18 hours

push eventRalfJung/const-eval

Ralf Jung

commit sha a5856eb19f526a6baa6ccf70a25a8699c446bbde

remove some incorrect links

view details

push time in 18 hours

PR opened rust-lang/const-eval

Link to skill tree and change const-blocks node

r? @oli-obk Fixes https://github.com/rust-lang/const-eval/issues/51

+5 -11

0 comment

3 changed files

pr created time in 18 hours

create barnchRalfJung/const-eval

branch : skills

created branch time in 18 hours

issue openedrust-lang/const-eval

Link to skill tree

Somewhere in our md files we should have a link to https://rust-lang.github.io/const-eval/. maybe from the "skill tree" item in the ToC?

created time in 18 hours

Pull request review commentrust-lang/rust

Make `<*const T>::is_null` const fn

+// compile-flags: --crate-type=lib++#![feature(const_panic, core_intrinsics, const_raw_ptr_comparison, const_ptr_offset)]++const FOO: &usize = &42;++macro_rules! check {+    (eq, $a:expr, $b:expr) => {+        pub const _: () =+            assert!(std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));+    };+    (ne, $a:expr, $b:expr) => {+        pub const _: () =+            assert!(std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));+    };+    (!eq, $a:expr, $b:expr) => {+        pub const _: () =+            assert!(!std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));+    };+    (!ne, $a:expr, $b:expr) => {+        pub const _: () =+            assert!(!std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));+    };+}++check!(eq, 0, 0);+check!(ne, 0, 1);+check!(!eq, 0, 1);+check!(!ne, 0, 0);+check!(ne, FOO as *const _, 0);+check!(!eq, FOO as *const _, 0);+check!(!eq, FOO as *const _, FOO as *const _);

For now I'd be happy with a comment saying that we probably want to change behavior of that check! at some point.

oli-obk

comment created time in 18 hours

Pull request review commentrust-lang/rust

Make `<*const T>::is_null` const fn

+// compile-flags: --crate-type=lib++#![feature(const_panic, core_intrinsics, const_raw_ptr_comparison, const_ptr_offset)]++const FOO: &usize = &42;++macro_rules! check {+    (eq, $a:expr, $b:expr) => {+        pub const _: () =+            assert!(std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));+    };+    (ne, $a:expr, $b:expr) => {+        pub const _: () =+            assert!(std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));+    };+    (!eq, $a:expr, $b:expr) => {+        pub const _: () =+            assert!(!std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));+    };+    (!ne, $a:expr, $b:expr) => {+        pub const _: () =+            assert!(!std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));+    };+}++check!(eq, 0, 0);+check!(ne, 0, 1);+check!(!eq, 0, 1);+check!(!ne, 0, 0);+check!(ne, FOO as *const _, 0);+check!(!eq, FOO as *const _, 0);+check!(!eq, FOO as *const _, FOO as *const _);+check!(ne, unsafe { (FOO as *const usize).offset(1) }, 0);+check!(!eq, unsafe { (FOO as *const usize).offset(1) }, 0);+const _: *const usize = unsafe { (FOO as *const usize).offset(2) };+//~^ NOTE

This is great, thanks. :)

oli-obk

comment created time in 18 hours

Pull request review commentrust-lang/rust

BTreeMap: move up reference to map's root from NodeRef

 where     type Key = K;      fn get(&self, key: &Q) -> Option<&K> {-        match search::search_tree(self.root.as_ref()?.as_ref(), key) {+        let root_node = self.root.as_ref()?.node_as_ref();+        match search::search_tree(root_node, key) {             Found(handle) => Some(handle.into_kv().0),             GoDown(_) => None,         }     }      fn take(&mut self, key: &Q) -> Option<K> {-        match search::search_tree(self.root.as_mut()?.as_mut(), key) {-            Found(handle) => Some(-                OccupiedEntry { handle, length: &mut self.length, _marker: PhantomData }-                    .remove_kv()-                    .0,-            ),+        let (maplease, search_result) = DormantMutRef::maybe_new(self, |this| {+            let root = unsafe { (*this.as_ptr()).root.as_mut() }?;

Ah you are right, my new contains a safety hole. It can be fixed with a lifetime bound, but I am not sure if the API is still useful with that bound:

    pub fn new<'n>(t: &'t mut T) -> (Self, &'n mut T)
        where 't: 'n
ssomers

comment created time in 18 hours

Pull request review commentrust-lang/rust

BTreeMap: move up reference to map's root from NodeRef

 where     type Key = K;      fn get(&self, key: &Q) -> Option<&K> {-        match search::search_tree(self.root.as_ref()?.as_ref(), key) {+        let root_node = self.root.as_ref()?.node_as_ref();+        match search::search_tree(root_node, key) {             Found(handle) => Some(handle.into_kv().0),             GoDown(_) => None,         }     }      fn take(&mut self, key: &Q) -> Option<K> {-        match search::search_tree(self.root.as_mut()?.as_mut(), key) {-            Found(handle) => Some(-                OccupiedEntry { handle, length: &mut self.length, _marker: PhantomData }-                    .remove_kv()-                    .0,-            ),+        let (maplease, search_result) = DormantMutRef::maybe_new(self, |this| {+            let root = unsafe { (*this.as_ptr()).root.as_mut() }?;

This is the API I had in mind. I also adjusted the doc comments.

ssomers

comment created time in 19 hours

Pull request review commentrust-lang/rust

BTreeMap: move up reference to map's root from NodeRef

 where     type Key = K;      fn get(&self, key: &Q) -> Option<&K> {-        match search::search_tree(self.root.as_ref()?.as_ref(), key) {+        let root_node = self.root.as_ref()?.node_as_ref();+        match search::search_tree(root_node, key) {             Found(handle) => Some(handle.into_kv().0),             GoDown(_) => None,         }     }      fn take(&mut self, key: &Q) -> Option<K> {-        match search::search_tree(self.root.as_mut()?.as_mut(), key) {-            Found(handle) => Some(-                OccupiedEntry { handle, length: &mut self.length, _marker: PhantomData }-                    .remove_kv()-                    .0,-            ),+        let (maplease, search_result) = DormantMutRef::maybe_new(self, |this| {+            let root = unsafe { (*this.as_ptr()).root.as_mut() }?;

I don't remember seeing the sibling wording and couldn't yet figure out what it means.

Fair, I didn't define it. I am trying different terminology to see what works best. ;) These are siblings:

fn foo(parent: &mut i32) {
  let sibling1 = &mut *parent;
  let sibling2 = &mut *parent;
}

The both reborrow from the same parent reference.

it no longer complains about this code that it complained about a month ago.

I don't think there were any changes in Miri that would affect this code...

Now I really don't know anymore if or when dereferencing a &mut invalidates a pointer to the same area.

Dereferencing a ptr of type &mut invalidates all pointers to that area except the pointers from which ptr was derived, i.e., except for ptr's "ancestors".

ssomers

comment created time in 19 hours

Pull request review commentrust-lang/rust

BTreeMap: move up reference to map's root from NodeRef

+use core::marker::PhantomData;+use core::ptr::NonNull;++/// A mutable borrow of a type T, that allows intermediately borrowing part of itself,+/// until waking up the borrow of the entire T.+pub struct DormantMutRef<'t, T> {+    ptr: NonNull<T>,+    _marker: PhantomData<&'t mut T>,+}++impl<'t, T> DormantMutRef<'t, T> {+    /// Capture a unique borrow and immediately sublet it to something else,+    /// that contains one or more unique references to a part of the T object.+    /// `compute_sub` returns that something, starting from a pointer.+    /// `compute_sub`, and all code using the returned something later, must not+    /// dereference that pointer entirely but only one or more of its fields.+    /// It's wise to store the returned`Self` and `Sub` in the same object,+    /// so that they are consumed jointly.+    pub fn new<Sub, ComputeSub>(t: &'t mut T, compute_sub: ComputeSub) -> (Self, Sub)+    where+        ComputeSub: FnOnce(NonNull<T>) -> Sub,

If the borrow checker was that smart, we wouldn't need this entire abstraction at all -- we'd just use a normal reborrow for this. The entire point of this abstraction, as I see it, is to handle cases where the lifetime of this (the thing passed to the closure) is too complicated for the compiler to understand.

Hence my thinking that the closure can be eliminated entirely and NonNull be hidden from the public interface.

ssomers

comment created time in 19 hours

issue commentrust-lang/rust

Invalid equality check result for usizes obtained from function pointers

But MIR optimizations also have to be aware that folding equality tests on functions is subtle (Cc @rust-lang/wg-mir-opt). And @oli-obk recently had to prevent me from making a similar mistake for pointer equality tests in CTFE (Cc @rust-lang/wg-const-eval).

Riateche

comment created time in 19 hours

issue commentrust-lang/rust

Invalid equality check result for usizes obtained from function pointers

This is an LLVM bug: https://bugs.llvm.org/show_bug.cgi?id=47090

Riateche

comment created time in 19 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {          let gid = GlobalId { instance, promoted: None }; -        let place = self.const_eval_raw(gid)?;+        let place = self.const_eval(gid)?;

The rest of the PR still calls const_eval_raw in a few places, and the commit message is

Do not call the const_eval query in mir interpretation except for caching of nulary intrinsics

Am I the only one who is very confused now?^^

oli-obk

comment created time in 19 hours

issue commentrust-lang/rust

Perform validation in const_eval_raw and return valtree from const_eval

mir::Const is a hypothetical thing that we haven't specified, and I think we both have different pictures of it and are thus talking past each other.

Yeah that sounds accurate.^^

We don't need it at all if I'm understanding your proposal correctly, as it would just be a &'tcx Allocation (or AllocId), so we can use that directly instead of having a wrapper.

Indeed, I think that's what I had in mind.

What we do need is for the mir::Body to contain both ty::Const (for const generics, unevaluated and literals) as well as &'tcx Allocation/AllocId for successfully evaluated constants. This is the main thing I was talking about, essentially the literal field of mir::Constant.

Okay, so we actually have two places where we do not want to use ty::Const (valtree) or &'tcx Allocation: in mir::Operand, because when constructing we often have a known scalar (or ScalarPair?) value that we want to embed directly without having to create an allocation; and in codegen, because LLVM likewise has a more efficient way to put scalar (ScalarPair?) literals into the code (rather than always using a raw allocation).

I would treat those separately. In particular, codegen is just one of several consumers of the final value of a const, and different backends could have different things that they can more efficiently represent in the target IR. So the LLVM-specific knowledge of what should become an IR literal vs a raw allocation should be handled in codegen.

For mir::Operand::Constant, indeed maybe that's the thing that we should call mir::Const. It would basically be either a valtree or an &Allocation, right? Hm, or it is unevaluated or a paremeter... so a lot like the current ty::ConstValue. So maybe we should have ty::ConstValtree, and then ty::Const is the thing that is "unevaluated or a parameter or an error or a valtree"? And mir::Const would be ty::Const or &Allocation?

But there's still a problem with that... I'd think a ty::Const is something that is evaluable to a valtree, so we shouldn't use it for all general mir::Const that are not evaluated yet. OTOH it might be too confusing to also have an "unevaluated" variant in mir::Const itself. Not sure what is best here. Maybe we need a type like

enum NotSureWhatToCallThis<T> {
  Unevaluated(...),
  Param(...),
  Error(...),
  Evaluated(T)
}

mod ty { type Const = NotSureWhatToCallThis<Valtree>; }
mod mir { type Const = NotSureWhatToCallThis<&'tcx Allocation>; }
RalfJung

comment created time in 19 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 // check-pass  // This test exhibits undefined behavior, but it is impossible to prevent generally during-// const eval, even if possible to prevent in the cases here. The reason it's impossible in general+// const eval, even if it could be prevented in the cases here if we added expensive and+// complex checks in rustc.+// The reason it's impossible in general

we should probably replace the const_eval_raw query in miri to run full miri during const eval so we catch UB during const eval.

Hm, I am not sure we want that TBH. It would seem rather surprising to me if CTFE behaved differently in Miri than normally. Const-UB is somewhat different from runtime-UB, and Miri does detect runtime-UB caused by consts having wrong results due to const-UB.

oli-obk

comment created time in 19 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {          let gid = GlobalId { instance, promoted: None }; -        let place = self.const_eval_raw(gid)?;+        let place = self.const_eval(gid)?;

Again this seems surprising -- we don't want valtree conversion here, do we? And it's not codegen with its special needs either. So why not a raw const?

oli-obk

comment created time in 19 hours

issue commentrust-lang/miri

Miri stdout is buffered and stdin in always empty

So IPC channels have a file name or so that can be passed around? Also, does this work on Windows? The ipc_channel crate only mentions macOS and Linux.

RalfJung

comment created time in 19 hours

issue commentrust-lang/miri

Miri stdout is buffered and stdin in always empty

mitosis says it is "WIP", so that seems a bit too fragile. Also I don't see how that helps because we have cargo sitting between cargo-miri and miri -- without cargo support, I don't see how we could forward the true stdout/stdin to miri.

RalfJung

comment created time in 20 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 impl<'tcx> TyCtxt<'tcx> {             self.const_eval_validated(inputs)         }     }++    /// Evaluate a static, returning the allocation of the initializer's memory.+    pub fn const_eval_static(self, def_id: DefId) -> Result<&'tcx Allocation, ErrorHandled> {

It is getting a bit frustrating that you keep ignoring my requests to move the discussion, not even explaining why you think that the discussion should not be moved.

oli-obk

comment created time in 20 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 impl<'tcx> TyCtxt<'tcx> {             self.const_eval_validated(inputs)         }     }++    /// Evaluate a static, returning the allocation of the initializer's memory.+    pub fn const_eval_static(self, def_id: DefId) -> Result<&'tcx Allocation, ErrorHandled> {

Please let's stop this off-topic discussion here.

oli-obk

comment created time in 20 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 // check-pass  // This test exhibits undefined behavior, but it is impossible to prevent generally during-// const eval, even if possible to prevent in the cases here. The reason it's impossible in general+// const eval, even if it could be prevented in the cases here if we added expensive and+// complex checks in rustc.+// The reason it's impossible in general

I still don't agree that this is impossible in general.

oli-obk

comment created time in 20 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 impl<'tcx> TyCtxt<'tcx> {         }     } -    /// Evaluate a static, returning the allocation of the initializer's memory.-    pub fn const_eval_static(self, def_id: DefId) -> Result<&'tcx Allocation, ErrorHandled> {-        trace!("const_eval_static: Need to compute {:?}", def_id);+    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.+    pub fn eval_static_initializer(self, def_id: DefId) -> Result<&'tcx Allocation, ErrorHandled> {+        trace!("eval_static_initializer: Need to compute {:?}", def_id);         let instance = ty::Instance::mono(self, def_id);

Would this be a good place for another assertion making sure this is really a static?

oli-obk

comment created time in 20 hours

issue commentrust-lang/rust

Perform validation in const_eval_raw and return valtree from const_eval

In another thread, @oli-obk wrote something that confused me a lot:

Since we still have (and maybe forever will have) ty::Const as an optimization for literals, even in mir::Const, we need to support this anyway, so I think for now we should just do this for statics where it's unambiguous.

I do not understand this statement. Are you saying mir::Const will not just be an AllocId? I think that is the wrong approach, I'd rather make the caller that has these weird special needs (i.e., codegen for consts) deal with "I want raw representation except sometimes", than making everyone deal with it.

@oli-obk, could you clarify? :)

RalfJung

comment created time in 20 hours

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 impl<'tcx> TyCtxt<'tcx> {             self.const_eval_validated(inputs)         }     }++    /// Evaluate a static, returning the allocation of the initializer's memory.+    pub fn const_eval_static(self, def_id: DefId) -> Result<&'tcx Allocation, ErrorHandled> {

ty::Const as an optimization for literals, even in mir::Const

I do not understand this statement. Are you saying mir::Const will not just be an AllocId? I think that is the wrong approach, I'd rather make the caller that has these weird special needs (i.e., codegen for consts) deal with "I want raw representation except sometimes", than making everyone deal with it.

oli-obk

comment created time in 20 hours

push eventrust-lang/const-eval

Oliver Scherer

commit sha 0869c0ca617f0d0c06b3f90ea39d9f00b3388421

Skill tree additions and restructurings

view details

Oliver Scherer

commit sha 945d4341aab69252c247d79db7fa2d1d80ba257a

`is_null` has a tracking issue

view details

Oliver Scherer

commit sha 966c4cbf70d56f34d4e99ad2daaf5cd9757e3276

Mutexes don't necessarily need a heap

view details

Oliver Scherer

commit sha 3cdef2e5f1a967fb2851781676a7a951b6cb85af

Apply suggestions from code review Co-authored-by: Ralf Jung <post@ralfj.de>

view details

Oliver Scherer

commit sha 3475faf0e2032ae76bad8528a0a62d7f1c45b9be

Link to parking lot "tracking issue"

view details

Oliver Scherer

commit sha 587b407750d1eb8ae6c230f2f959ce918d19c843

Offset from is a prerequisite for `offset_of`

view details

Oliver Scherer

commit sha bcffb34d202c5535d02c8ab8f900a0031db9fa85

Clarify where we want to use mutable references

view details

Oliver Scherer

commit sha 368107dc0d34271f2f7c64637bacddd6fcf586ec

question mark operator has a tracking issue

view details

Oliver Scherer

commit sha c7a5866788cf4db390c6517314c828ae84a671f7

Re-add lost requirement

view details

Oliver Scherer

commit sha fc4050dd105346508410650a72c7fa72aa086f1e

Remove sub-feature that doesn't have a tracking issue

view details

Oliver Scherer

commit sha d4cc946430c36952b7046dde46cc0f0726aac456

Fix up some typos

view details

Oliver Scherer

commit sha 47873f20e091f8451bc6eb0f4626bbdef9cdcafc

Mention all feature gate names

view details

Oliver Scherer

commit sha 13c23efef26ae68859baeae018012d6f23de4194

Use `feature` instead of `fg` and adjust some item names that tried to use newlines (which isn't supported)

view details

Ralf Jung

commit sha af332ac927fe1be9884b8d72561f5fe44ea5d652

Merge pull request #50 from rust-lang/skill-tree Skill tree additions and restructurings

view details

push time in 20 hours

pull request commentrust-lang/const-eval

Skill tree additions and restructurings

Thanks a lot! Let's merge this so we can see how it looks rendered.

oli-obk

comment created time in 20 hours

issue commentrust-lang/rust

LLVM loop optimization can make safe programs crash

stack overflow

Stack overflows are challenging to model indeed, good question. Same for out-of-memory situations. As a first approxmation, we formally pretend they do not happen. A better approach is to say that any time you call a function, you may get an error due to stack overflow, or the program may continue. This way you can soundly approximate what actually happens.

we can reorder (in the execution order) only the expressions that we can prove as terminating

Indeed. Morevoer they have to be "pure", i.e., side-effect-free -- you cannot reorder two println!.

Divison is also potentially impure, but only when dividing by 0 -- which causes a panic, i.e., a control effect. This is not directly observable but indirectly (e.g. by having the panic handler print something to stdout, which is then observable). Thus division can only be reordered of we are sure we are not dividing by 0.

RalfJung

comment created time in 20 hours

Pull request review commentwlanslovenija/tunneldigger

print warning when we run out of tunnel IDs

 def create_tunnel(self, broker, address, uuid, remote_tunnel_id, client_features         try:             tunnel_id = self.tunnel_ids.pop()         except KeyError:+            logger.warning("No more tunnel IDs available -- {} active tunnels".format(len(self.tunnels)))

Agreed.

So this PR is read to be merged then?

RalfJung

comment created time in 21 hours

Pull request review commentwlanslovenija/tunneldigger

close pollable when its FD errors

 def start(self):                      if event & select.EPOLLIN:                         pollable.read(file_object)+                    elif event & select.EPOLLERR:

Good catch! I made it also close the pollable on HUP.

RalfJung

comment created time in 21 hours

push eventfreifunk-saar/tunneldigger

Ralf Jung

commit sha 3c35c5d61f503c4e1d3b391404526ce324022fd2

also close pollables on HUP

view details

push time in 21 hours

Pull request review commentwlanslovenija/tunneldigger

print warning when we run out of tunnel IDs

 def create_tunnel(self, broker, address, uuid, remote_tunnel_id, client_features         try:             tunnel_id = self.tunnel_ids.pop()         except KeyError:+            logger.warning("No more tunnel IDs available -- {} active tunnels".format(len(self.tunnels)))

I just wanted to share because in one other project I am using Python logging a lot and using this feature to direct logs to a central server, not as strings, but as log records (so log message + dict with parameters separate), and then have rules there to detect error conditions. It is easier this way because you do not have to parse things out of the string again.

Oh that's really cool. :D

In Python not really. I just always use %(...)s everywhere and it just generally does the right thing

Ah so %s works for integers and floats? That's good to know.

Also, it is better to use keyword-based interpolation than position one. Less error prone and more metadata what each value is.

Tunneldigger uses positional stye everywhere so I don't think this PR is the right time to change coding style.

RalfJung

comment created time in 21 hours

pull request commentwlanslovenija/tunneldigger

switch per per-IP to per-UUID rate limiting

For that we always assumed that security is done on another level (IPSec).

Well, that's not really possible for Freifunk because we run open infrastructure... (Also I don't think the docs ever said that, so when switching to tunneldigger there was no way we could have been aware of this. Now it's a bit too late with several big Freifunk networks relying on tunneldigger already.^^)

RalfJung

comment created time in 21 hours

pull request commentrust-lang/const-eval

Skill tree additions and restructurings

Awesome!

What does fg: mean?

oli-obk

comment created time in 21 hours

issue commentrust-lang/rust

LLVM loop optimization can make safe programs crash

@olotenko I don't know what you mean by "watching the loop outcome". A non-terminating loop makes the entire program diverge, which is considered observable behavior -- this means it is observable outside the program. As in, the user can run the program and see that it goes on forever. A program that goes on forever may not be compiled into a program that terminates, because that changes what the user can observe about the program.

It doesn't matter what that loop was computing or if the "return value" of the loop is used or not. What matters is what the user can observe when running the program. The compiler must make sure that this observable behavior stays the same. Non-termination is considered observable.

To give another example:

fn main() {
  loop {}
  println!("Hello");
}

This program will never print anything, because of the loop. But if you optimized the loop away (or reordered the loop with the print), suddenly the program would print "Hello". Thus these optimizations change the observable behavior of the program, and are disallowed.

RalfJung

comment created time in 21 hours

Pull request review commentrust-lang/rust

BTreeMap: move up reference to map's root from NodeRef

+use core::marker::PhantomData;+use core::ptr::NonNull;++/// A mutable borrow of a type T, that allows intermediately borrowing part of itself,+/// until waking up the borrow of the entire T.+pub struct DormantMutRef<'t, T> {+    ptr: NonNull<T>,+    _marker: PhantomData<&'t mut T>,+}++impl<'t, T> DormantMutRef<'t, T> {+    /// Capture a unique borrow and immediately sublet it to something else,+    /// that contains one or more unique references to a part of the T object.+    /// `compute_sub` returns that something, starting from a pointer.+    /// `compute_sub`, and all code using the returned something later, must not+    /// dereference that pointer entirely but only one or more of its fields.+    /// It's wise to store the returned`Self` and `Sub` in the same object,+    /// so that they are consumed jointly.+    pub fn new<Sub, ComputeSub>(t: &'t mut T, compute_sub: ComputeSub) -> (Self, Sub)+    where+        ComputeSub: FnOnce(NonNull<T>) -> Sub,

I don't understand how you jumped from "keep NonNull confined in closure" to

Having "Sub" as a part of "Self"

so I do not follow any part of that post.

ssomers

comment created time in a day

Pull request review commentrust-lang/rust

BTreeMap: move up reference to map's root from NodeRef

 where     type Key = K;      fn get(&self, key: &Q) -> Option<&K> {-        match search::search_tree(self.root.as_ref()?.as_ref(), key) {+        let root_node = self.root.as_ref()?.node_as_ref();+        match search::search_tree(root_node, key) {             Found(handle) => Some(handle.into_kv().0),             GoDown(_) => None,         }     }      fn take(&mut self, key: &Q) -> Option<K> {-        match search::search_tree(self.root.as_mut()?.as_mut(), key) {-            Found(handle) => Some(-                OccupiedEntry { handle, length: &mut self.length, _marker: PhantomData }-                    .remove_kv()-                    .0,-            ),+        let (maplease, search_result) = DormantMutRef::maybe_new(self, |this| {+            let root = unsafe { (*this.as_ptr()).root.as_mut() }?;

Using a pointer invalidates all child and sibling pointers. But here self is a parent pointer of the NonNull.

ssomers

comment created time in a day

issue commentrust-lang/rust

Perform validation in const_eval_raw and return valtree from const_eval

My assumption with this plan was that for const items, codegen would work pretty similar to static items, as both have to work with all types (not just valtree-compatible types). But @oli-obk points out in https://github.com/rust-lang/rust/pull/74949 that e.g. for consts of integer type, we want to emit LLVM integer constants.

Does this also apply to larger valtree-representable types, e.g. a big struct full of integers? We could try to get a valtree and fall back to a raw allocation when that fails. Or maybe we just want to do with this scalars, in which case we could check the layout before deciding if we want to ask for a valtree or a raw allocation.

RalfJung

comment created time in a day

Pull request review commentrust-lang/rust

Validate constants during `const_eval_raw`

 impl<'tcx> TyCtxt<'tcx> {             self.const_eval_validated(inputs)         }     }++    /// Evaluate a static, returning the allocation of the initializer's memory.+    pub fn const_eval_static(self, def_id: DefId) -> Result<&'tcx Allocation, ErrorHandled> {

We can do that in a separate PR though. Let's discuss in https://github.com/rust-lang/rust/issues/72396.

oli-obk

comment created time in a day

pull request commentrust-lang/rust

evaluate required_consts when pushing stack frame in Miri engine

@oli-obk I added a test.

RalfJung

comment created time in a day

push eventRalfJung/rust

Ralf Jung

commit sha fd3851aadb3f5326480f9e9ced57ade2db86480b

add test for unused erroneous const in CTFE

view details

push time in a day

pull request commentrust-lang/rust

update Miri

Things work locally. @bors r+ p=1

RalfJung

comment created time in a day

pull request commentrust-lang/rust

evaluate required_consts when pushing stack frame in Miri engine

So this is a breaking change, but only if your code was UB anyway

It is, just like the corresponding change in codegen was a breaking change. I am not sure if the old code was UB (dead code cannot cause UB), but it is a bug that we fixed for codegen and should likewise fix for CTFE.

the test should still be in this repo, not just in miri

Fair, I'll add it.

RalfJung

comment created time in a day

PullRequestEvent

PR closed rust-lang/rust

update Miri

Fixes https://github.com/rust-lang/rust/issues/75274 Cc @rust-lang/miri r? @ghost

+1 -1

1 comment

1 changed file

RalfJung

pr closed time in a day

more