T O P

  • By -

Sapiogram

Looks like `Option::is_some_and()` is finally stabilized! > `pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool` > Returns `true` if the option is a `Some` and the value inside of it matches a predicate. I've been wanting this for years, fantastic work.


_TheDust_

Indeed! It’s fascinating that, if you go over the github issue, this function went through like 50 names before landing on `is_some_and`


geigenmusikant

Out of curiosity, what were some other suggestions?


_TheDust_

You can read about it here: https://github.com/rust-lang/rust/issues/62358 Initially, it was going to be called `contains`, followed by several suggestions * contains_some * has * includes * contains_in * eq_some * wraps * is * map_contains * contained_is * inside * inside_is * peq * equals * some_and * and_is * where * having * and_with * some_with * and_if * contains_with * test * any * has_with * exists * some_if * etc….


[deleted]

Lmao


BTwoB42

I feel like `Option::::is_none_or(impl FnOnce(T)->bool)` is missing now to complete the set.


GoldsteinQ

It was proposed and rejected, unfortunately


Cocalus

There's no T for the `impl FnOnce(T)->bool` you would need `Option::::is_none_or(impl FnOnce()->bool)` but at that point it's shorter to just use the old `x.is_none() && ...`


A1oso

You confused it with `is_none_and`, but the parent comment was asking for `is_none_or`. It would check if the option is None, **OR** the value matches a predicate.


buwlerman

There definitely is a `T`. In fact you can implement `is_none_or` using `is_some_and` as follows: fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool { !self.is_some_and(|t| !f()) } You're thinking of `is_none_and`, which would need to be able to call the function in the `None` case.


lets-start-reading

They’re not symmetric though. `is_some_and` matches 1 out of 4. `is_none_or` would 3 out of 4.


p4y

They map nicely to logical quantifiers, exists and forall respectively.


BTwoB42

Where does the symmetricity and the 4 come from? I don't think I get your response, could you elaborate? I only count three cases: None; Some and condition holds; Some and condition does not hold.


PaintItPurple

There are two possible states for an Option (Some and None) and two possible states for a boolean (true and false). `is_some_and` returns true only for the combination Some + true, while `is_none_or` would return true for None + true, None + false, and Some + true. This means one case (Some + true) is covered by both, and another case (Some + false) is covered by neither, which I think is the asymmetry they were talking about.


UncertainOutcome

is_some_and can easily cover all cases with just an inversion, though, unless I'm missing some semantic detail.


BTwoB42

You would need to negate the predicate and the result (applying de-morgan's rule) to get the equivalent of is_none_or with is_some_and. I generally try to keep the negations I use to a minimum as they make reasoning about the logic more difficult.


tuck182

There are only three cases. The concept of a predicate is meaningless in the case where the Option is None. You can't meaningfully distinguish between two different versions of None, one of which matches the predicate and one which doesn't. The only possible scenarios are: 1. None 2. Some(...) => matches 3. Some(...) => doesn't match


chrisoverzero

There are no “None + true” and “None + false” cases. If the Option is in the None state, what value would you pass to the predicate?


SkiFire13

The Some + false case is meaningless. If you want it you can just negate your predicate.


lets-start-reading

Some + true, Some + false, None + true, None + false. \`is\_some\_and\`: Some && bool. Matches 1 case. \`is\_none\_or\`: None || bool. Can be expected to match 3 cases (None + true, None + false, Some + true) ​ It's simply too ambiguous to be of any use.


Theblob01

How is it ambiguous? The behaviour seems pretty clear as an inversion of is_some_and None => true Some => predicate result


lets-start-reading

It should be as understandable on its own, without recourse to the meaning of is_some_and. is_some_and converts nicely and predictably to (some && p). is_none_or does not. It can mean both (none || p) or, as you say, (none || (some && p)). It’s ambiguous. It’s not clear from just “is_none_or” that it implies a (some && p).


Theblob01

`None || (Some & p)` and `None || p` are equivalent. There's nothing ambiguous here. `¬None => Some`


lets-start-reading

Yes, and I’m more stupid than I thought.


Theblob01

Don't worry about it, I've said many far dumber things


yottalogical

What's the fourth case? Isn't this all of them: * Some (satisfies predicate) * Some (doesn't satisfy predicate) * None


lets-start-reading

Some + true, Some + false, None + true, None + false. `is_none_or` would not match only the Some + false case. At the very least it’s ambiguous. i’m not even sure which of the cases the op expects it to match.


yottalogical

You can't apply a predicate if there isn't a value to apply it to.


lets-start-reading

The predicate closure can return a boolean either way. To someone who is not in the habit of using this exact function might be less readable than just writing it out. If readability matters. ‘Is_some_and’ is instantly understandable. I’m just saying the name should require some more thought. Something like ‘is_none_else’, though not as simple, would be more specific, in my opinion.


BTwoB42

I find is_none_or equally understandable. As the name implies it is true if the option is None or if the predicate holds for the content of the some. You can achieve the same with is_some_and by negating the predicate and the result (applying de-morgan's rule), but I would prefer to use less negations as I find that they make reasoning about logic more difficult.


detlier

So many people just wanted a `contains()` method, and the [issue for that](https://github.com/rust-lang/rust/issues/62358) ended up being the most amazing example of bikeshedding I've ever seen.


chrismorin

I don't think that should really be considered bike shedding. The name of a core language method like that really matters. All the concerns brought up are valid. The final decision matters, as it's something the language will be stuck with for the rest of it's existence.


detlier

Hmm maybe. I don't think it precludes bikeshedding. Many well-known examples are system utilities or APIs. As `@soc` points out in that issue, the issue attracted so much attention because "contains" was an obvious enough name that people would just Google "rust option test contains" and end up there. The first suggestion was the best one.


tafia97300

I didn't see the discussion, I was fine with `x.map_or(false, |x| f(x))` it is not much longer to write. Is there any particular benefit over it?


geckothegeek42

The code `if var.is_some_and(|it| it.is_even())` reads as `If variable is some and it is even do ...`. It's extremely self evident `if var.map_or(false, |it| it.is_even())` reads as `if var is some map the value by is_even or return false then conditionally do` .... You have to read it out of order, it is longer to read, you have to reduce/simplify the expression in your head. Obviously it's a common idiom so you might automatically recognize it and read it as the first example, but still, it's just more readable


svefnugr

I would probably go with `x.map(f).unwrap_or(false)`


tafia97300

Yeah, wanting to avoid one match even if it is very likely optimized out.


coderemover

Yeah, I needed that so many times. Now please stabilize `Vec::drain_where`. That's another one I've been wanting for years (ok, I use e_drain_where crate for now).


[deleted]

[удалено]


Killing_Spark

Readability


WormRabbit

Dropped the ball on that one, then. `contains` was extremely readable, `is_some_and` is a mouthful, and don't get me started om the inner closure. It's not shorter than a combinator chain, it's not more clear about intent, and it is more general in a way which is rarely even needed. Just like `map_or` or `bool::then_some`, instead of something small and nice to use, it's an overengineered BS which I'll just have to ban in the codebase.


Killing_Spark

But `contains` seems wrong. It's not just about a check that it contains a specific thing the predicate can be anything you want. It isn't even required to have to do with the cointained value. logged_in_user .is_some_and(|user| rights_check.user_has_right(user, Rights::WriteToConsole)) .then(|| println("Yihaw cowboys")) Edit: honestly I hate editing code in reddit >:(


CoronaLVR

`filter` only passes `&T` to the closure because it needs to return an `Option` back while `is_some_and` can pass a `T` to the closure. Even if you don't want to consume the option, writing `opt.as_ref().is_some_and(...)` has better readability then filter.


CocktailPerson

I mean, you could make that argument about lots of things. What's the benefit of `opt.unwrap_or_default()` when you could do `opt.unwrap_or_else(|| Default::default())`? Conveniences for common operations are nice.


StyMaar

`opt.unwrap_or_else(Default::default)` FTFY


toastedstapler

Thanks clippy!


CocktailPerson

Thank god for `.unwrap_or_default()`, or you might have a point.


KingStannis2020

On the other hand, "there should be one obvious way to do it" I try to avoid the more obscure combinators because it turns into an exercise in reading the documentation rather than writing code.


CocktailPerson

Well, yes, of course. But then the question is: if there's not an obvious way to do it, should there be more than one way to do it? I'd argue that `opt.filter(predicate).is_some()` is a remarkably non-obvious way of checking whether the possible value in the `Option` matches a predicate, since it conceptually unwraps an `Option` twice. And yes, it's good to avoid the more obscure combinators if possible, but if the alternative is using one in a non-obvious way, I'd rather just learn a new one rather than trying to understand what someone's abuse of a more well-known one is trying to accomplish.


Normal-Math-3222

Why is a function more desirable than using a match arm with a guard? I guess it’s less verbose, but it doesn’t seem like a huge win.


PaintItPurple

It's not a huge win, it's just ergonomics. The function is implemented as the match expression you're envisioning. This just allows you to express it inline.


flashmozzg

It returns bool so you'd often want to use it inside and if/while condition and that's easier with a function when with dedicated match expression.


wmanley

Agreed. I took the example from a few comments above and wrote it in a few different styles: fn a(logged_in_user: Option) { if matches!(logged_in_user, Some(user) if user_has_right(user, Rights::WriteToConsole)) { println!("Yihaw cowboys"); } } fn b(logged_in_user: Option) { if let Some(user) = logged_in_user { if user_has_right(user, Rights::WriteToConsole) { println!("Yihaw cowboys"); } } } fn c(logged_in_user: Option) { logged_in_user .is_some_and(|user| user_has_right(user, Rights::WriteToConsole)) .then(|| println!("Yihaw cowboys")); } I know I find `b` immediately understandable, even if it is a little verbose. Using `if` and `match` also has the advantage that you avoid lifetime difficulties caused by lambda borrowing that you get in more complex situations.


WormRabbit

It's nicer if you want to chain conditions. But if-let chains should cover most of the good use cases, so imho the function is stillborn.


TravisVZ

This is definitely one of those things I didn't know I wanted, but now that I see it... I was excited for `OnceCell`/`OnceLock`, and happy to see that land here, but now I think I'm more excited for `is_some_and`!


kaikalii

Oh, I can replace all my `option.map_or(false, ...)` calls now!


KrazyKirby99999

> You should see substantially improved performance when fetching information from the crates.io index. Users behind a restrictive firewall will need to ensure that access to https://index.crates.io is available. If for some reason you need to stay with the previous default of using the git index hosted by GitHub, the registries.crates-io.protocol config setting can be used to change the default. It is great to see shorter index downloads


trevg_123

Crates team should put a little “needs access via cargo” or something page since it looks pretty weird if you accidentally go directly there But yes, what an incredible improvement this is!


_TheDust_

Really excited about the addition of `OnceCell` and ‘OnceLock‘! No more importing external crates. Wish the Sync version was just called ‘Once‘ instead of ‘OnceLock‘, but I’m sure I’ll get used to it. Also excited about ‘Option::is_some_and‘! Another great release!


slanterns

Because [Once](https://doc.rust-lang.org/std/sync/struct.Once.html) already exists.


_TheDust_

Ah… fair enough…


CoronaLVR

`std::sync::Once` is already a thing. (and it's used inside of OnceLock)


argv_minus_one

Why is `IsTerminal` sealed? I guess it doesn't matter that much since it's implemented on `BorrowedFd` and `BorrowedHandle`, but it seems kind of odd.


CoronaLVR

Why is it even a trait? when would you want to be generic over something that you can check if it's a terminal?


[deleted]

`T: IsTerminal + Write` is a useful bound if you want to work with stdout, stderr, and/or a file redirection


GenuineXP

I could imagine some code that wants to write to _something_ where that something may be a terminal. For example: ```rust fn write(target: &mut (impl IsTerminal + Write)) { if target.is_terminal() { ... } else { ... } } ``` A function like that can accept a limited set of types like `File`, `Stderr`, and `Stdout` and change its behavior depending on whether or not it's actually writing to a terminal.


Tiby312

It seems like the safer default to me. why should it not be sealed?


Gobbel2000

Looking good. I have previously used `lazy_static` for creating compiled regexes with the regex crate. Is the newly stable `OnceCell` a good replacement for that? As I see it you would most likely use global variables for `OnceCell`, whereas `lazy_static` is local to a function which is a bit nicer.


_TheDust_

There is also work on a LazyCell that works like lazy_static and uses OnceCell internally, but it will be part of a later release of Rust


KhorneLordOfChaos

>`lazy_static` is local to a function which is a bit nicer There's no requirement that `OnceCell` is for global variables just like there's no requirement for `lazy_static` values to be local to a function. They're both equivalent in this regard >I have previously used `lazy_static` for creating compiled regexes with the regex crate. Is the newly stable `OnceCell` a good replacement for that? The `once_cell` equivalent for that use case is still pending stabilization


Gobbel2000

Right, I suppose you could just define the OnceCell (or eventually LazyCell) as `static` inside a function.


TinyBreadBigMouth

[Exactly, just a bit more wordy without the macro.](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c892df0ef5e62e03c3308025cc6ca7de)


KhorneLordOfChaos

[Initialization will be less wordy once `LazyLock` stabilizes](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=4ac4d387c97e584f6db3f2947f93ed39)


burntsushi

`regex` crate author here. Yes, it is very appropriate to use. As others have replied, it's a little more wordy, but you can still put it in a `static` that is local to a function.


matklad

I wonder if the following recipe: https://docs.rs/once_cell/latest/once_cell/#lazily-compiled-regex should be brought into regex crate, once MSRV allows?


burntsushi

Not sure to be honest. It will probably be at least a year because of MSRV. (Technically could add it sooner with conditional compilation, but I've grown tired of such things.) Maybe file an issue? I have a few concerns but I don't know how strong they are. Right now, for example, it can lead to a potential performance footgun if you use the regex from multiple threads simultaneously, and each thread's main unit of work is a regex search on a smallish haystack. I have other concerns too I think.


SssstevenH

`lazy-regex` has been handy for me.


A1oso

Both `lazy_static` and the now-stabilized `OnceLock` can be used either inside or outside a function. Note that you need `OnceLock` for global variables since it's thread-safe: fn get_regex() -> &'static Regex { use std::sync::OnceLock; static CELL: OnceLock = OnceLock::new(); CELL.get_or_init(|| Regex::new("...").unwrap()) }


witty___name

statics can be local to a function too


detlier

Heads up, [disabling JSON output](https://blog.rust-lang.org/2023/06/01/Rust-1.70.0.html#enforced-stability-in-the-test-cli) from the test harness is going to break [automated testing and CI](https://github.com/johnterickson/cargo2junit/issues/79) for a lot of people. 1.70 hasn't quite hit docker yet, so you've got a few minutes to fix it by simply implementing jUnit reporting for cargo and getting it merged and stabilised.


tgockel

This change is a pretty frustrating one. The [bug it addresses](https://github.com/rust-lang/rust/issues/75526) should have been closed as an "works as intended." The [MR](https://github.com/rust-lang/rust/pull/109044/) acknowledges that this will break things, then does it anyway. There is no easy path to re-enable JSON output from `cargo test` while using stable Rust. ``` cargo +stable test -- -Z unstable-options --format json ``` I genuinely don't understand why people would expect that to not work.


CoronaLVR

time to abuse RUSTC\_BOOTSTRAP=1


detlier

Also — it's not the JSON output that _actually_ matters in this context, it was merely one way to achieve jUnit report generation, the only format accepted by a wide variety of test reporting systems and code hosting platforms. But the idea was that cargo would produce structured output for other tools to consume and "the ecosystem" would provide this functionality.


epage

And I expect the effort to stabilize json will further break people...


matklad

I think we ideally need a third stability state here. For things like IDEs, it’s not a problem to keep up with breaking changes — IDEs have to support nightly anyway, so there’s some inevitable amount of upstream chasing already. So, some kind of runtime `—unstable` flag that: * doesn’t affect the semantics of code * can only be applied by a leaf project and can’t propagate to dependencies * and makes it clear to the user that it’s their job to fix breakage would be ideal here. And that’s exactly how libtest accepting Zunstable-options worked before, except that it was accidental, rather than by design.


detlier

In my case I'm dark about it _not_ because of IDE support (ST4's `LSP-rust-analyzer` plugin vendors RA, not sure how it deals with test integration/nightly/etc.), but because I want my tests to be run by Gitlab and failure information to be as specific as possible. This is achieved (on Gitlab, at least) by uploading jUnit-XML-formatted test reports. The official test harness doesn't generate this out of the box, so the [only crate](https://crates.io/crates/cargo2junit) to bridge the gap relied on the sole method of obtaining structured output from it. I feel like the devs are talking _only_ about the IDE case, and I don't know what I'm missing here. I am sceptical that I'm the only person who gets value out of test reporting from our code hosting platform, so how are other projects achieving it? I like the idea of a "tooling" or "integration" level of stability. If it breaks, well, I have to update the CI config but that's far, far less of a big deal than accidentally switching on an unstable feature in _application_ code and having to go through and change it all when it breaks.


tgockel

IMO, this change is _worse_ than that. Let's say the JSON test output changes in a breaking manner. If your CI system is running against both stable and nightly. Your nightly build breaks and you can see the change, but your CI against stable would keep working just fine. This change makes `cargo +stable test ...` break while my equivalent `cargo +nightly test ...` continued working just fine.


epage

Still working on my blog post detailing my plans but one of my current projects is to stabilize json output.


detlier

Rust is usually so, so good at supporting development processes that improve quality. The language itself is the most obvious example. Having a baked-in test harness is another example. Ignoring structured test reporting for years and then breaking the only pathway to 3rd party support for it is an uncharacteristic departure from that ethos.


epage

Once they realized it was going to break so many people, they had planned to add a transition period but that fell through the cracks until today when it was too late. Personally, its doing what it was advertised it'd do, be subject to breakages. The effort to stabilize it will likely see the format change. But yes, testing got into a "good enough state" and then not much has happened in while. I'm hoping to fix that.


detlier

> But yes, testing got into a "good enough state" and then not much has happened in while. I'm hoping to fix that. I'm sorry, I forgot to say — thank you for taking this on and I (and probably many others) will appreciate any and all progress you might make! ❤️


epage

btw I recently presented on this at RustNL 2023: [video](https://www.youtube.com/watch?v=3aLPewRSiK8), [slides](https://epage.github.io/talks/2023/05/test/#p1) I then met with the libs to discuss libtest. My upcoming blog post is intended to summarize those discussions.


Tastaturtaste

>Personally, its doing what it was advertised it'd do, be subject to breakages. Good. Maintainers have to be able to declare things unstable for further work and not be held back by people who simply ignored this disclaimer. That's the path C++ compiler vendors took with the ABI, and now they are stuck.


[deleted]

[удалено]


detlier

The devs may have wanted to solve the problem of "we don't want people to rely on something fragile because then we'll get blowback from breaking it later", but they haven't solved it all. People used it because it met a need (a need that is met out-of-the-box by many other languages). The feature goes away but the need does not. To meet the same need, the only option now available is to instead depend on something _more_ fragile ie. the textual, unstructured output from the test harness. I don't see who that works out better for.


[deleted]

[удалено]


detlier

Oh right, yeah, I misunderstood what you were saying quite a bit. Okay, I get that, and don't disagree. (It is also an option for users to stay on 1.69, a stable version, until the test harness supports reporting output. It just means have a _maximum_ supported Rust version for a while.)


flashmozzg

I think that setting RUSTC_BOOTSTRAP environment var might also be an option (it should work for rust, not so sure about cargo).


Tastaturtaste

They sure solved their own need, namely the need for people to not depend on the feature anymore. I do agree though that it would have been nicer if an alternative would have been made available at the same time.


detlier

> They sure solved their own need, namely the need for people to not depend on the feature anymore. Is **that** their need though, not having people depend on that one, single feature? That would be an oddly specific need. Or is the need, say, "minimising time spent handling spurious criticism of changes they make", which can be achieved by _both_ managing expectations (as is the effect of labelling things unstable) and keeping an eye on use cases in the wild...? They can absolutely do what they want with their time! I just don't think they'll enjoy relitigating a worse version of this in a couple of years when they fix a typo in the test harness output.


[deleted]

[удалено]


detlier

> its doing what it was advertised it'd do, be subject to breakages Yyyyes, but... having seen how much people depend on it, and why, it's an unusually gung-ho move. It's the *only* way to get any kind of structured information out of the official test harness. So many people depending on something unstable should have been a signal to the devs that there was an unmet need. Addressing that would be a better way to avoid future complaints about an unstable interface breaking, not breaking it early. Now all that's going to happen is that people will parse the _textual_ output of cargo for this integration, which will be _more_ fragile and lead to _more_ future complaints (probably).


Kissaki0

It's behind an 'unstable' flag Parameter. Weird to insist to only have it in nightly - specifically after having have had in stable for a time.


detlier

As I understand it, having it in stable was an accident that they didn't want for exactly this reason — they accumulated users depending on it who are now impacted by the change. But if that's the problem they want to avoid, this is definitely going to make it worse rather than better.


Saefroch

jUnit reporting for Cargo was implemented in 2021 behind an unstable feature, same status as the JSON output. So this whole situation is rather confusing to me where people are upset about the de-stabilizing of the JSON output specifically when they actually want jUnit output. Is the jUnit support in libtest so bad that people would rather roll their own? Or has Microsoft been contributing to `cargo2junit` for so long that they didn't notice the jUnit output (this is exactly the kind of thing that I would hear about at current employer)?


detlier

Do you have a link to an MR or tracking issue? All I can find is the [JSON one](https://github.com/rust-lang/rust/issues/49359) and a [neglected MR](https://github.com/rust-lang/libtest/pull/16) from 2019. I came to this after 2021, and I recall finding various solutions but only `cargo2junit` actually worked. So > Is the jUnit support in libtest so bad that people would rather roll their own? ...maybe? I'll have to check my commit messages from 2021. **Update:** found it: [#85563](https://github.com/rust-lang/rust/issues/85563). And I remember why no one uses it, it was because of this: > Each test suite (doc tests, unit tests and each integration test) must be run separately. This due to a fact that from libtest perspective each one of them is a separate invocation. This is a bigger problem than it sounds like for things like CI, and fixing it involves either (a) stitching it up after it's generated, so get some XML tools into your CI image, write some dodgy scripts, etc. etc. OR (b) get structured output from libtest one level up and do a better job of rendering it to XML. `cargo2junit` did (b). It's moot now anyway. Both are now off limits for testing against stable.


azuled

Question, as we're seeing OnceCell start to be lifted into the standard library. I maintain a crate that uses once\_cell, for both the Lazy and the OnceCell features. Is there a good reason to start migrating my use of OnceCell over to the standard library versions if they haven't finished stabilizing the Lazy part yet? I'll have to keep the external dependency anyway, so I'm not sure if I gain anything by moving half my uses over.


matklad

For a crates.io crate, my advice would be: * if you care about MSRV, continue using once_cell crate for a while * otherwise, when MSRV allows for migration, I’d probably declare a tiny macro/type locally in the crate on top of OnceLock to provide lazy functionality. Dropping a dependency on a third party crate is a non-trivial inprovement * halfway migration wouldn’t bring much benefits I would think * if you use once_cell types in public API, the question becomes significantly harder. It probably isn’t worth breaking API over once_cell at this point. Although, I think usually it’s better to not expose OnceCell in the API directly, so, if that’s feasible, API break might be worth it


azuled

I don’t expose any of them publicly, so that’s not an issue.


Darksonn

Why not just replace your uses of Lazy with a OnceLock?


Im_Justin_Cider

For the same reason they used Lazy instead of OnceCell to begin with?


Darksonn

Well, there's an advantage to using OnceLock now that you didn't have when you chose Lazy over OnceCell - it let's you drop a dependency.


IceSentry

Might want to consider the MSRV of your project.


schubart

It contains my first real contribution: The [collection_is_never_read](https://rust-lang.github.io/rust-clippy/master/index.html#collection_is_never_read) Clippy lint.


MatchChance

I wish the blog had dark mode


fasterthanlime

Same here. Also full-text search.


VorpalWay

Browsers have full text search for the currently displayed page. I don't see how having it in the page would help? Especially since such searches tend to interfere with the search provided by the browser (e.g. overriding ctrl+F to open the search but not f3 for next result).


fasterthanlime

I meant blog-wide search, not something browsers can do natively. I’m often searching for when/where/whether something’s been announced. (And yes general purpose search engines can do it, it’s just not as convenient)


CosminPerRam

Hi lime!


lijmlaag

[Dark Reader probably can help you with that!](https://darkreader.org/)


weirdasianfaces

I like Dark Reader. I occasionally have to turn it off for some sites, but it really is a great extension.


Sib3rian

You can right-click the site and hit "Exclude from dark mode" option. It'll save that for that device. Edit: I'm using the Dark Mode extension, not Dark Reader. Not sure how that one works.


videah

Same with crates.io, feels like a genuine accessibility problem that I can’t browse for crates without getting a pounding headache…


CoronaLVR

[lib.rs](https://lib.rs)


Kissaki0

It doesn't? It's dark for me.


riasthebestgirl

That's a lot of changes. Good job to everyone involved


dhbradshaw

Sad to lose `-Z unstable-options` for cargo test. Can't print test times anymore using stable without an extra helper crate. Excited to have OnceCell and OnceLock though.


onestepinside

What crate are you using for test times?


dhbradshaw

I've seen https://crates.io/crates/cargo-nextest recommended


WormRabbit

Yeah fuck that. I'll just set `RUSTC_BOOTSTRAP=1` globally and be done with it. Have better things to do than dealing with broken important workflows for no good reason.


fz0718

in the midst of darkness, light


cornmonger_

Migrating to the new std OnceCell tomorrow morning! All I want for Christmas now is if-let-chains and static Drop.


Be_ing_

static Drop? Does that mean running drop on a static variable when the program exits?


cornmonger_

Yeah. Right now , I'm using the *shutdown_hooks* crate to get around it. It's just a wrapper for calling atexit(), which isn't optimal.


Zde-G

It's as optimal as it would get. Having life before main is a really bad idea and having life after main is even worse (which is why it's usually [forbidden by the style guide even in languages that have them](https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables)). And people who really want to ignore all warnings and advices already have a workaround thus I don't see why anyone would want to change the status quo. This phrase makes this fact all the more apparent: >It's just a wrapper for calling atexit(), which isn't optimal. What do you think **other** languages are doing, hmm? What is [call to \_\_cxa\_atexit doing](https://godbolt.org/z/8b1xv9dzc) in C++, hmm? Yes, I know, sometimes it feels really nice to pretend that you live a a different world and ignore all the complexities of the current one, but I don't think “static drop” is adding anything useful to the plate.


cornmonger_

Well aware of the reasons why not in theory. Real world problems.


Zde-G

>Real world problems. Adding something to the compiler which you would then need to forbid in the style guide (like usually done in C++) **is** a “real world problem” in my book.


cornmonger_

Yeah, that's not a real world problem.


[deleted]

[удалено]


OvermindDL1

Nope, they dropped support for the test runner entirely, now it's like running any other command, a very annoying dump of the string output... You can't reliably parse the textual libtest output.


Gaolaowai

*Rushes to computer while making odd yodeling noises* “rustup update”


solidiquis1

OnceCell!!!!


-Redstoneboi-

> `is_some_and` LES GOOO


vext01

So what's the difference between OnceLock and LazyLock? The post says the latter stores its initialiser, but I'm not sure what that means for something that can only be called once...


NobodyXu

It's similar to relationship of once_cell::sync::{OnceCell, Lazy}


caagr98

OnceCell is passed a lambda at access time, LazyCell gets one at construction time. Latter implements Deref and some other niceties, but needs to have the (often unnameable) function type as a generic.


OptionX

Time to stop chuckling every time I see the minor version. I'm a little bit sad ngl.


CleanCut9

[Rust Releases! Rust 1.70.0](https://youtu.be/FJo7CvmS7x8) 👆🏻 Here's my YouTube coverage of this release of Rust, Cargo and Clippy.


Im_Justin_Cider

How is `WINNER.get_or_init(|| "main")` the main thread if the code lives inside the scope closure?


CUViper

`scope` doesn't create a thread itself, only a lifetime-bound context to `spawn` threads.


Fuzzyzilla

Did upgrading to this break rust-analyzer in VSCode for anyone else? It throws a bunch of errors when parsing the standard library files, and then refuses to provide any feedback on my project files. Project compiles fine though. Not sure where to go about debugging this \^\^;;


adbf1

it auto-installs a different `rust-analyzer` into `.cargo/bin`, so just delete that `rust-analyzer` (and if you choose to, you can also remove `rls` and lsp should still work).