[HN Gopher] Rust--: Rust without the borrow checker
       ___________________________________________________________________
        
       Rust--: Rust without the borrow checker
        
       Author : ravenical
       Score  : 113 points
       Date   : 2026-01-01 10:53 UTC (12 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | boxed wrote:
       | A motivation section in the readme seems like it is needed.
        
         | poly2it wrote:
         | https://github.com/buyukakyuz/corroded/issues/11#issuecommen...
        
           | corrode2711 wrote:
           | Yes, that was my motivation.
        
       | bhaney wrote:
       | Are the compile times noticeably faster?
        
         | worldsavior wrote:
         | Probably not, because it seems like it still checks for errors
         | but just suppresses them.
        
           | misnome wrote:
           | Even so, the borrow checker repeatedly profiles as an
           | insignificant part of compile times, so wouldn't make a
           | difference.
        
       | throwawayffffas wrote:
       | C++ with extra steps?
        
         | corrode2711 wrote:
         | C++ with a package manager.
        
       | dorianniemiec wrote:
       | Uh oh, this might look like a potentially memory-unsafe version
       | of Rust...
        
         | mkl95 wrote:
         | Rust++ would be a nicer name then
        
           | dorianniemiec wrote:
           | Rust++? :)
        
             | thushanfernando wrote:
             | Bust?
        
               | corrode2711 wrote:
               | Bust++
        
       | petcat wrote:
       | [flagged]
        
         | scott_w wrote:
         | Honestly, I thought it was serious because I've seen people do
         | things exactly like this, just in different languages.
         | 
         | By "this" I mean "spend all their time fighting against the
         | language/framework because they don't like it, rather than just
         | picking a different language."
        
           | eru wrote:
           | There can be good reasons for choosing a language that you
           | otherwise don't like.
           | 
           | Eg legacy software, or because your boss tells you, or
           | because of legal requirements, or because of library
           | availability etc.
        
             | scott_w wrote:
             | Those are excellent reasons but then you shouldn't fight
             | the language, you should go with the language/framework
             | conventions as much as possible. Trying to fight the
             | language design will only lead to buggy, hard to understand
             | code, so either suck it up or get a different job.
             | 
             | EDIT: That last sentence is a bit harsher than I intended.
             | I'm trying to convey the importance of professionalism in
             | our work and remembering the experience of working with
             | people who couldn't do this brought back some bad memories!
        
         | MangoToupe wrote:
         | Certain people feel very emotional about the compilers and
         | interpreters they use
         | 
         | You couldn't pay me to work with them
        
           | josephg wrote:
           | Don't worry, they probably wouldn't want to work with you
           | either.
           | 
           | Some programmers think and care a lot about software
           | correctness in a kind of mathematical way. Others just want
           | to ship features and enjoy their lives. Both approaches are
           | fine. They just don't necessarily mix super well.
           | 
           | Some people like to tell you that diverse teams work better.
           | Years ago I worked with someone who had a PhD in
           | psychometrics. She said that's kind of a lie. If you actually
           | look at the research it shows something more interesting. She
           | said the research shows that having a diverse set of
           | backgrounds makes a team perform better. But having a diverse
           | set of values makes a team perform worse. It makes sense. If
           | one person on the team wants to vibe code and someone else
           | wants to make every line of code perfect, you're all in for a
           | bad time.
        
             | qsera wrote:
             | There is a third kind. Those who want to have a lot of fun
             | by using their imagination to come up with interesting ways
             | build something, but in rust, the borrow checker often
             | won't have any of it.
             | 
             | In rust you have to learn and internalize lot of the non-
             | intutive borrow checker reasoning to remain sane. If you
             | remember to spend a fraction of that effort to remember the
             | "unsafe" things you could end up doing in C, then I think
             | most people would be fine.
             | 
             | But rust enforces it, which is good for a small fraction of
             | all software that is being written. But "Rust for
             | everything!?"..Give me a fucking break!
        
               | MangoToupe wrote:
               | This persona is the heart and soul of the "weirdly
               | emotional about languages" archetype along with ruby
               | fanatics. Look, y'all have notable and significant value,
               | but only in very specific and unusual circumstances
        
         | corrode2711 wrote:
         | And you were right.
        
         | dang wrote:
         | Could you please not post this sort of snarky-generic-meta
         | comment? They attract upvotes and then stick at the top of the
         | thread, choking out actually interesting discussion. (That's
         | where this one was, but I'm going to mark it off topic and
         | downweight it now.)
         | 
         | I completely understand your frustration about how common
         | shallow-indignant comments are. But it doesn't help to post
         | shallow-indignant or snarky comments of your own about it - it
         | just produces even more of the same, or worse.
         | 
         | The way to combat shallow-indignant, predictable, tedious,
         | etc., threads is to find something that you're genuinely
         | curious and open about, and post from that place instead.
         | 
         | https://news.ycombinator.com/newsguidelines.html
        
       | fithisux wrote:
       | This should be called trust, because it does view the developer
       | as evil.
        
         | fithisux wrote:
         | I meant "it does not view"
        
       | gspr wrote:
       | Tangentially related: the opposite, Rust's borrow checker sans
       | the compiler, is actually very useful. As far as I understand,
       | the borrow checker is a significant part of the work of writing a
       | Rust compiler. Therefore, having the official borrow checker
       | available as a standalone program can make alternative compilers
       | (e.g. for exotic hardware) feasible faster, because they won't
       | need a borrow checker of their own from the get-go.
        
         | bananaflag wrote:
         | I get your point, but still you haven't identified a use for
         | the borrow checker sans the compiler.
        
         | tialaramex wrote:
         | Why would this matter? The borrowck is (a) not needed during
         | bring-up because as its name suggests it is merely a check, so
         | going without it just means you can write nonsense and then
         | unbounded undefined behaviour results, but (b) written entirely
         | in Rust so you can just compile it with the rest of this
         | "exotic hardware" Rust compiler you've built.
        
           | gspr wrote:
           | Yeah, you're right, I'm misremembering something here. Thanks
           | for the correction.
        
       | raluk wrote:
       | What are protental issues with compiler, by just disabling borrow
       | checker? If I recall correctly some compiler optimisations for
       | rust can not be done in C/C++ because of restrictions implied by
       | borrow checker.
        
         | 0xdeafbeef wrote:
         | Rust can set restricts to all pointers, because 1 mut xor many
         | shared refs rule. Borrow checker empowers this.
         | https://en.wikipedia.org/wiki/Restrict
        
           | imtringued wrote:
           | The crazy part about this is that (auto) vectorization in
           | Rust looks something like this:
           | iter.chunks(32).map(vectorized)
           | 
           | Where the vectorized function checks if the chunk has length
           | 32, if yes run the algorithm, else run the algorithm.
           | 
           | The compiler knows that the chunk has a fixed size at compile
           | time in the first block, which means it can now attempt to
           | vectorize the algorithm with a SIMD size of 32. The else
           | block handles the scalar case, where the chunk is smaller
           | than 32.
        
         | vanviegen wrote:
         | Without the borrow checker, how should memory be managed? Just
         | never deallocate?
        
           | flohofwoe wrote:
           | It would be the same as in any language with manual memory
           | management, you'd simply get a dangling pointer access. The
           | 'move-by-default' semantics of Rust just makes this a lot
           | trickier than in a 'copy-by-default' language though.
           | 
           | It's actually interesting to me that the Rust borrow checker
           | can 'simply' be disabled (e.g. no language- or stdlib-
           | features really depending on the borrow checker pass) - not
           | that it's very useful in practice though.
        
           | masklinn wrote:
           | The borrow checker does not deal with ownership, which is
           | what rust's memory management leverages. The borrow checker
           | validates that borrows (references) are valid aka that they
           | don't outlive their sources and that exclusive borrows don't
           | overlap.
           | 
           | The borrow checker does not influence codegen at all.
        
           | eptcyka wrote:
           | The same as C++, destructors get called when an object goes
           | out of scope.
        
       | nineteen999 wrote:
       | Love the "Note for LLMs" and the NSFW license.
        
       | user3939382 wrote:
       | Rust- is you use C with ring buffers. If you think you need
       | dynamic memory allocation your program is underspecified.
        
         | oskarbh7 wrote:
         | How does "zero dynamic allocation" work in practice for
         | something like a text editor IE. vscode or other apps that let
         | users open arbitrary files?
        
           | lpcvoid wrote:
           | Just impose a maximum buffer size ;)
        
           | Const-me wrote:
           | It's technically possible to do, just very complicated and
           | hard. Quite often, prohibitively so.
           | 
           | Still, the main idea is despite the input files are
           | arbitrarily large, you don't need an entire file in memory
           | because displays aren't remotely large enough to render a
           | megabyte of text. Technically, you can only load a visible
           | portion of the input file, and stream from/to disk when user
           | scrolls. Furthermore, if you own the file format, you can
           | design it in a way which allowing editing without overwriting
           | the entire file: mark deleted portions without moving
           | subsequent content, write inserts to the end of files, maybe
           | organize the file as a B+ tree, etc.
           | 
           | That's how software like Word 97 supported editing of
           | documents much larger than available memory. As you can
           | imagine, the complexity of such file format, and the software
           | handling them, was overwhelming. Which is why software
           | developers stopped doing things like that as soon as
           | computers gained enough memory to keep entire documents, and
           | instead serialize them into sane formats like zipped XMLs in
           | case of modern MS office.
        
             | eru wrote:
             | What if you don't know ahead of time how big that monitor
             | is that you are displaying stuff on?
             | 
             | In any case, what you are describing sounds like an ad-hoc
             | re-implementation of virtual memory?
        
               | Const-me wrote:
               | > What if you don't know ahead of time how big that
               | monitor is that you are displaying stuff on?
               | 
               | Use a reasonable upper estimate?
               | 
               | > ad-hoc re-implementation of virtual memory?
               | 
               | If you rely on actual virtual memory instead of specially
               | designed file format, saving large files will become
               | prohibitively slow. On each save you have to stream the
               | entire document from page file to actual memory,
               | serialize the document, produce the entire file, then
               | replace. And then when resuming editing after the save,
               | you probably have to load the visible portion back from
               | disk.
        
               | 1718627440 wrote:
               | Either take the biggest one or render in chunks.
        
         | mrits wrote:
         | Instead of over specifying a program you can just use dynamic
         | memory allocation
        
         | rcxdude wrote:
         | Avoiding dynamic allocation does not avoid memory unsafety in
         | C.
        
       | throwawayffffas wrote:
       | It would be great if it only allowed multiple mutable borrows.
       | That's the only one that always bugs me, for mostly innocuous
       | stuff.
        
         | threethirtytwo wrote:
         | This isn't actually unsafe unless shared across threads right?
         | Maybe the borrow checker needs to be more nuanced to
         | differentiate this rather then outright banning it all
         | together. It would increase the logic of the borrow checker by
         | a lot though.
        
       | xlii wrote:
       | > In addition to meeting the Open Source Definition, the
       | following standards apply to new licenses:         > (...) The
       | license does not have terms that structurally put the licensor in
       | a more favored position than any licensee.
       | https://opensource.org/licenses/review-process
       | 
       | That's a funfact I learned from IP lawyer when discussing
       | possibility of open-source but otherwise LLVM-extempt license. If
       | there is extemption (even in LLM) such license is most likely
       | OSI-incompatible.
        
       | w4rh4wk5 wrote:
       | I am wondering whether this would actually be a helpful compile
       | option in upstream rustc for quick prototyping. I don't want prod
       | code to use this, but if I want to try things out during
       | development, this could substantially shorten the dev cycle.
        
         | 0xdeafbeef wrote:
         | What the point, though? You will get compiling code, but later
         | you would need to reachitecture code to avoid violating rust
         | rules.
        
           | withinboredom wrote:
           | Sometimes, you just need to know if an idea will even work or
           | what it would look like. If you have to refactor half the
           | codebase (true story for me once), it makes the change a much
           | harder sell without showing some benefits. IE, it keeps you
           | from discovering better optimizations because you have to pay
           | the costs upfront.
        
             | eru wrote:
             | Can't you usually just throw some quick referenced counted
             | cells in there, to make the borrow checker happy enough for
             | a prototype without refactoring the whole code base?
        
             | LoganDark wrote:
             | In Rust, it's a lot easier to refactor half the codebase
             | than it would be in another language. Once you're done
             | fighting the compiler, you're usually done! instead of
             | NEVER being sure if you did enough testing.
        
               | withinboredom wrote:
               | I can't tell if you missed the whole point of
               | "exploratory"...
        
             | aw1621107 wrote:
             | > Sometimes, you just need to know if an idea will even
             | work or what it would look like.
             | 
             | I think what GP is trying to say is that the value of such
             | exploration might be limited if you end up with something
             | incompatible with "proper" Rust anyways.
             | 
             | I suppose it depends on how frequently "transition through
             | invalid Rust while experimenting and end up with valid
             | Rust" happens instead of "transition through invalid Rust
             | while experimenting and end up with invalid Rust", as well
             | as how hard it is to fix the invalid Rust in the latter
             | case.
        
         | Philpax wrote:
         | After a while, you just don't write code that would cause
         | substantial borrow-checker problems, even when prototyping. I'd
         | say the slow compile times are much more of an impediment for a
         | practicing Rust prototyper than the borrow checker.
        
       | ismailmaj wrote:
       | undefined behavior on steroids be like:
        
       | hacker_homie wrote:
       | I wish I could make the borrow checker give warnings not errors.
       | It would make exploration so much easier, so I don't have to
       | fight the borrow checker until I know how to build what I want.
        
         | hoppp wrote:
         | Then you have code full of warnings and undefined behavior?
         | 
         | I think fighting the borrow checker is more like a rite of
         | passage. Rust is not my favorite language but the borrow
         | checker is great.
        
           | leoh wrote:
           | This is not a hacker's take
        
             | hoppp wrote:
             | I'm lazy. If you turn off the borrow checker the code will
             | need a rewrite later, since it's there for a very good
             | reason.
        
       | dataflow wrote:
       | This can't possibly be guaranteed to work just by disabling the
       | checker, can it? If Rust optimizes based on borrow-checker
       | assumptions (which I understand it can and does) then wouldn't
       | violating them be UB, unless you also mess with the compiler to
       | disable those optimizations?
        
         | tialaramex wrote:
         | If you write correct Rust code it'll work, the borrowck is just
         | that, a check, if the teacher doesn't check your homework where
         | you wrote that 10 + 5 = 15 it's still correct. If you write
         | incorrect code where you break Rust's borrowing rules it'll
         | have unbounded Undefined Behaviour, unlike the actual Rust
         | where that'd be an error this thing will just give you broken
         | garbage, exactly like a C++ compiler.
         | 
         | Evidently millions of people _want_ broken garbage, Herb Sutter
         | even wrote a piece celebrating how many more C++ programmers
         | and projects there were last year, churning out yet more broken
         | garbage, it 's a metaphor for 2025 I guess.
        
           | ozgrakkurt wrote:
           | I have been using kde for years now without a single problem.
           | Calling cpp garbage sounds wrong.
        
             | LtWorf wrote:
             | People who can't do something, sometimes assume nobody else
             | possibly could.
        
               | zzrrt wrote:
               | I'm sure some people could tiptoe through minefields
               | daily for years, until they fail. Nobody is perfect at
               | real or metaphorical minefields, and hubris is probably
               | the only reason to scoff at people suggesting
               | alternatives.
        
               | 3836293648 wrote:
               | People hate C because it's hard, people hate C++ because
               | it truly is rubbish. Rubbish that deserved to be tried
               | but that we've now learned was a mistake and should move
               | on from.
        
             | doodlesdev wrote:
             | KDE is a great desktop environment , but it's also
             | notorious for being a buggy and unpolished DE [1]. It's
             | good your experience wasn't like that, but it's certainly
             | not how the software is generally perceived.
             | 
             | [1]: Of course, different versions have different levels of
             | stability. Also, some of these bugs and problems wouldn't
             | be prevented by using an alternative language such as Rust.
        
             | danudey wrote:
             | Well FWIW, the original poster's anti-C++ statements aside,
             | removing the borrow checker does nothing except allow you
             | to write thread-unsafe (or race condition-unsafe) code.
             | Therefore, the only change this really makes is allowing
             | you to write slightly more ergonomic code that could well
             | break somewhere at some point in time unexpectedly.
        
           | amelius wrote:
           | People don't want garbage. But in any case, they don't want
           | straightjackets like the borrow checker.
           | 
           | Hence, they use GC'd languages like Go whenever they can.
        
             | eru wrote:
             | Straightjackets can be very useful.
             | 
             | Haskell (and OCaml etc) give you both straightjackets and a
             | garbage collector. Straightjackets and GC are very
             | compatible.
             | 
             | Compared to C, which has neither straightjackets nor a GC
             | (at least not by default).
        
               | reactordev wrote:
               | >Straitjackets can be very useful.
               | 
               | Only if you're insane.
        
               | qsera wrote:
               | Damn! This is the funniest HN comment that I have ever
               | come across...
        
               | josephg wrote:
               | How dare you. C is a fine language.
               | 
               | Just don't accidentally step on any of these landmines
               | and we'll all get along great.
        
               | reactordev wrote:
               | Not to mention your sidearm is a Sig P365. We like to
               | call them footguns.
        
               | imtringued wrote:
               | The meaning of straightjacket here is inherently
               | subjective and not to be meant literally.
        
               | qsera wrote:
               | >Haskell (and OCaml etc) give you both straightjackets..
               | 
               | Haskell's thing with purity and IO does not feel like
               | that. In fact Haskell does it right (IO type is reflected
               | in type). And rust messed it up ("safety" does not show
               | up in types).
               | 
               | You want a global mutable thing in Haskell? just use
               | something like an `IORef` and that is it. It does not
               | involve any complicated type magic. But mutations to it
               | will only happen in IO, and thus will be reflected in
               | types. That is how you do it. That is how it does not
               | feel like a straight jacket.
               | 
               | Haskell as a language is tiny. But Rust is really huge,
               | with endless behavior and expectation to keep in mind,
               | for some some idea of safety that only matter for a small
               | fraction of the programs.
               | 
               | And that I why I find that comment very funny. Always
               | using rust is like always wearing something that
               | constrains you greatly for some idea of "safety" even
               | when it does not really matter. That is insane..
        
               | gpm wrote:
               | > "safety" does not show up in types
               | 
               | It does in rust. An `unsafe fn()` is a different type
               | than a (implicitly safe by the lack of keyword) `fn()`.
               | 
               | The difference is that unsafe fn's can be encapsulated in
               | safe wrappers, where as IO functions sort of
               | fundamentally can't be encapsulated in non-IO wrappers.
               | This makes the IO tagged type signatures viral throughout
               | your program (and as a result annoying), while the safety
               | tagged type signatures are things you only have to think
               | about if you're touching the non-encapsulated unsafe code
               | yourself.
        
               | qsera wrote:
               | >The difference is that unsafe fn's can be encapsulated
               | in safe wrappers
               | 
               | This is the koolaid I am not willing to drink.
               | 
               | If you can add safety very carefully on top of unsafe
               | stuff (without any help from compiler), why not just use
               | `c` and add safety by just being very careful?
               | 
               | > IO tagged type signatures viral throughout your program
               | (and as a result annoying)..
               | 
               | Well, that is what good type systems do. Carry
               | information about the types "virally". Anything short is
               | a flawed system.
        
               | gpm wrote:
               | > This is the koolaid I am not willing to drink.
               | 
               | > If you can add safety very carefully on top of unsafe
               | stuff (without any help from compiler), why not just use
               | `c` and add safety by just being very careful?
               | 
               | There is help from the compiler - the compiler lets the
               | safe code expose an interface that creates strict
               | requirements about how it is being called with and
               | interacted with. The C language isn't expressive enough
               | to define the same safe interface and have the compiler
               | check it.
               | 
               | You can absolutely write the _unsafe_ part in C. Rust is
               | as good at encapsulating C into a safe rust interface as
               | it is at encapsulating unsafe-rust into a safe rust
               | interface. Just about every non-embedded rust program
               | depends on C code encapsulated in this manner.
               | 
               | > Well, that is what good type systems do. Carry
               | information about the types "virally". Anything short is
               | a flawed system.
               | 
               | Good type systems describe the interface, not every
               | implementation detail. Virality is the consequence of
               | implementation details showing up in the interface.
               | 
               | Good type systems minimize the amount of work needed to
               | use them.
               | 
               | IO is arguably part of the interface, but without further
               | description of what IO it's a pretty useless detail of
               | the interface. Meanwhile exposing a viral detail like
               | this as part of the type system results in lots of work.
               | It's a tradeoff that I think is generally not worth it.
        
               | qsera wrote:
               | >the compiler lets the safe code expose an interface that
               | creates strict requirements about how it is being called
               | with and interacted with..
               | 
               | The compiler does not and cannot check if these strict
               | requirements are enough for the intended "safety". Right?
               | It is the judgement of the programmer.
               | 
               | And what is stopping a `c` function with such
               | requirements to be wrapped in some code that actually
               | checks these requirements are met? The only thing that
               | the rust compiler enables is to include a feature to mark
               | a specific function as unsafe.
               | 
               | In both cases there is zero help from the compiler to
               | actually verify that the checks that are done on top are
               | sufficient.
               | 
               | And if you want to mark a `c` function as unsafe, just
               | follow some naming convention...
               | 
               | >but without further description of what IO it's a pretty
               | useless detail of the interface..
               | 
               | Take a look at effect-system libraries which can actually
               | encode "What IO" at the type level and make it available
               | everywhere. It is a pretty basic and widely used thing.
        
               | gpm wrote:
               | > The compiler does not and cannot check if these strict
               | requirements are enough for the intended "safety". Right?
               | It is the judgement of the programmer.
               | 
               | Yes*. It's up to the programmer to check that the safe
               | abstraction they create around unsafe code guarantees all
               | the requirements the unsafe code needs are upheld. The
               | point is that that's done once, and then all the safe
               | code using that safe abstraction can't possibly fail to
               | meet those requirements - or in other words any safety
               | related bug is always in the relatively small amount of
               | code that uses unsafe and builds those safe abstraction.
               | 
               | > And what is stopping a `c` function with such
               | requirements to be wrapped in some code that [doesn't]
               | actually checks these requirements are met?
               | 
               | Assuming my edit to your comment is correct - nothing.
               | It's merely the case that any such bug would be in the
               | small amount of clearly labelled (with the unsafe
               | keyword) binding code instead of "anywhere".
               | 
               | > The only thing that the rust compiler enables is to
               | include a feature to mark a specific function as unsafe.
               | 
               | No, the rust compiler has a lot more features than just a
               | way to mark specific functions as unsafe. The borrow
               | checker, and it's associated lifetime constraints,
               | enforcing that variables that are moved out of (and
               | aren't `Copy`) aren't used, is one obvious example.
               | 
               | Another example is marking how data can be used across
               | threads with traits like `Send` and `Sync`. Another -
               | when compared to C anyways - is simply having a
               | visibility system so that you can create structs with
               | fields that aren't directly accessible via other code (so
               | you can control every single function that directly
               | accesses them and maintain invariants in those
               | functions).
               | 
               | > In both cases there is zero help from the compiler to
               | actually verify that the checks that are done on top are
               | sufficient.
               | 
               | Yes and no, "unsafe" in rust is synonymous with "the
               | compiler isn't able to verify this for you". Typically
               | rust docs do a pretty good job of enumerating exactly
               | what the programmer must verify. There are tools that try
               | to _help_ the programmer do this, from simple things like
               | being able to enable a lint that checks every time you
               | wrote unsafe you left a comment saying why it 's ok, and
               | that you actually wrote something the compiler couldn't
               | verify in the first place. To complex things like having
               | a (very slow) interpreter that carefully checks that in
               | at least one specific execution every required invariant
               | is maintained (with the exception of some FFI stuff that
               | it fails on as it is unable to see across language
               | boundaries sufficiently well).
               | 
               | The rust ecosystem is very interested in tools that make
               | it easier to write correct unsafe code. It's just rather
               | fundamentally a hard problem.
               | 
               | * Technically there are very experimental proof systems
               | that can check some cases these days. But I wouldn't say
               | they are ready for prime time use yet.
        
               | elbear wrote:
               | When I started learning Haskell, it did feel like coding
               | with a straightjacket.
        
               | qsera wrote:
               | I think that is because when you start learning Haskell,
               | you are not typically told about state monads, `IORefs`
               | and likes that enables safe mutability.
               | 
               | It might be because Monads could have a tad bit advanced
               | type machinery. But IORefs are straightforward, but
               | typically one does not come across it until a bit too
               | late into their Haskell journey.
        
             | 127 wrote:
             | You call it a straightjacket, I call it a railroad track
             | for reliably delivering software.
        
           | jjgreen wrote:
           | It is possible to like something without hating people who
           | like something else, can't people just live and let live?
        
             | tialaramex wrote:
             | Did I write that I hated somebody? I don't think I wrote
             | anything of the sort. I can't say my thoughts about Bjarne
             | for example rise to hatred, nobody should have humoured him
             | in the 1980s, but we're not talking about what happened
             | when rich idiots humoured The Donald or something as
             | serious as that - nobody died, we just got a lot of
             | software written in a crap programming language, I've had
             | worse Thursdays.
             | 
             | And although of course things could have been better they
             | could also have been worse. C++ drinks too much OO kool
             | aid, but hey it introduced lots of people to generic
             | programming which is good.
        
               | jjgreen wrote:
               | Correct me if I'm wrong, but I don't think you think that
               | C++ programmers actually _want_ to write  "broken
               | garbage", so when you say "millions of people _want_
               | broken garbage " the implication is that a) they do write
               | broken garbage, b) they're so stupid don't even know that
               | is what they are doing. I can't really read else than in
               | the same vein as an apartheid-era white South-African
               | statement starting "all blacks ...", i.e., an insult to a
               | large class of people simply for their membership in that
               | class. Maybe that's not your intent, but that's how it
               | reads to me, sorry.
        
               | dminik wrote:
               | Considering how many people will defend C++ compilers
               | bending over backwards to exploit some accidental
               | undefined behaviour with "but it's fast though" then
               | yeah, that's not an inaccurate assessment.
        
               | tialaramex wrote:
               | I can't help how you feel about it, but what I see is
               | people who supposedly "don't want" something to happen
               | and yet take little or no concrete action to prevent it.
               | When it comes to their memory safety problem WG21 talks
               | about how they want to address the problem but won't take
               | appropriate steps. Years of conference talks about
               | safety, and C++ 26 is going to... encourage tool vendors
               | to diagnose some common mistakes. Safe C++ was rejected,
               | and indeed Herb had WG21 write a new "standing rule"
               | which imagines into existence principles for the language
               | that in effect forbid any such change.
               | 
               | Think Republican Senators offering thoughts and prayers
               | after a school shooting, rather than Apartheid era white
               | South Africans.
        
               | 3836293648 wrote:
               | Are you seriously comparing discrimination based on
               | factors noone can control to a group literally defined by
               | a choice they made? And you think that's a good faith
               | argument?
        
           | ada0000 wrote:
           | herb sutter and the c++ community as a whole have put a lot
           | of energy into improving the language and reducing UB; this
           | has been a primary focus of C++26. they are not encouraging
           | people to "churn out more broken garbage", they are
           | encouraging people to write better code in the language they
           | have spent years developing libraries and expertise in.
        
             | lordgroff wrote:
             | And for which there's often no serious alternative to in
             | many domains anyway.
        
               | ada0000 wrote:
               | even when there are alternatives, sometimes it makes
               | sense to use a library like Qt in its native language
               | with its native documentation rather than a binding - if
               | you can do so safely
        
               | nemetroid wrote:
               | Yes, many or even most domains where C++ sees a large
               | market share are domains with no other serious
               | alternative. But this is an indictment of C++ and not
               | praise. What it tells us is that when there are other
               | viable options, C++ is rarely chosen.
               | 
               | The number of such domains has gone down over time, and
               | will probably continue to do so.
        
               | pron wrote:
               | The number of domains where low-level languages are
               | required, and that includes C, C++, Rust, and Zig, has
               | gone down over time and continues to do so. All of these
               | languages are rarely chosen when there are viable
               | alternatives (and I say "rarely" taking into account
               | total number of lines of code, not necessarily number of
               | projects). Nevertheless, there are still some very
               | important domains where such languages are needed, and
               | Rust's adoption rate is low enough to suggest serious
               | problems with it, too. When language X offers significant
               | advantages over language Y, its adoption compared to Y is
               | usually quite fast (which is why most languages get close
               | to their peak adoption relatively quickly, i.e. within
               | about a decade).
               | 
               | If we ignore external factors like experience and
               | ecosystem size, Rust is a better language than C++, but
               | not better enough to justify faster adoption, which is
               | exactly what we're seeing. It's certainly gained some
               | sort of foothold, but as it's already quite old, it's
               | doubtful it will ever be as popular as C++ is now, let
               | alone in its heydey. To get there, Rust's market share
               | will need to grow by about a factor of 10 compared to
               | what it is now, and while that's possible, if it does
               | that it will have been the first language to ever do so
               | at such an advanced age.
        
           | lordgroff wrote:
           | The attitude expressed here and that tends to surface in any
           | Rust discussion is the reason I completely lost interest in
           | the language.
        
             | tempodox wrote:
             | You're expressing the same attitude here, just in reverse.
             | Some users not thinking highly of C++ doesn't make Rust a
             | worse or less interesting language.
        
             | maxbond wrote:
             | Rust isn't a one true language, no one necessarily needs to
             | learn it, and I'm sure your preffered language is
             | excellent. C and C++ are critical languages with legitimate
             | advantages and use cases. Don't learn Rust of you aren't
             | interested.
             | 
             | But Rust, its community, and language flame wars are
             | separate concerns. When I talk shop with other Rust people,
             | we talk about our projects, not about hating C++.
        
             | Maxatar wrote:
             | So don't use it. Rust is not intended to be used by
             | everyone. If you are happy using your current set of tools
             | and find yourself productive with them then by all means be
             | happy with it.
        
           | pron wrote:
           | For all its faults, and it has many (though Rust shares most
           | of them), few programming languages have yielded more value
           | than C++. Maybe only C and Java. Calling C++ software
           | "garbage" is a bonkers exaggeration and a wildly distorted
           | view of the state of software.
        
           | Spivak wrote:
           | How are we still having the same trade off discussion being
           | argued so black and white when reality has shown that both
           | options are preferred by different groups.
           | 
           | Rust says that all incorrect programs (in terms of memory
           | safety) are invalid but the trade is that some correct
           | programs will also be marked as invalid because the compiler
           | can't prove them correct.
           | 
           | C++ says that all correct programs are valid but the trade is
           | that some incorrect programs are also valid.
           | 
           | You see the same trade being made with various type systems
           | and people still debate about it but ultimately accept that
           | they're both valid and not garbage.
        
             | Maxatar wrote:
             | >C++ says that all correct programs are valid but the trade
             | is that some incorrect programs are also valid.
             | 
             | C++ does not say this, in fact no statically typed
             | programming language says this, they all reject programs
             | that could in principle be correct but get rejected because
             | of some property of the type system.
             | 
             | You are trying to present a false dichotomy that simply
             | does not exist and ignoring the many nuances and trade-offs
             | that exist among these (and other) languages.
        
               | tialaramex wrote:
               | Nope. C++ really does deliberately require that compilers
               | will in some cases emit a program which does... something
               | even though what you wrote isn't a C++ program.
               | 
               | Yes, that's very stupid, but they did it with eyes open,
               | it's not a mistake. In the C++ ISO document the words
               | you're looking are roughly (exact phrasing varies from
               | one clause to another) Ill-formed No Diagnostic Required
               | (abbreviated as IFNDR).
               | 
               | What this means is that these programs are Ill-formed
               | (not C++ programs) but they compile anyway (No diagnostic
               | is required - a diagnostic would be an error or warning).
               | 
               | Why do this? Well because of Rice's Theorem. They want a
               | lot of tricky semantic requirements for their language
               | but Rice showed (back in like 1950) that all the non-
               | trivial semantic requirements are Undecidable. So it's
               | impossible for the compiler to correctly diagnose these
               | for all cases. Now, you could (and Rust does) choose to
               | say if we're not sure we'll reject the program. But C++
               | chose the exact opposite path.
        
               | Maxatar wrote:
               | I'm not sure what your replying to, but it can't be my
               | comment because what you're saying has absolutely nothing
               | to do with it.
               | 
               | But kudos to you on writing an irrelevant wall of text.
        
               | 1718627440 wrote:
               | It does. The UB is false positives to the question "Is
               | this a valid program".
        
               | Maxatar wrote:
               | No one disputes that C++ accepts some invalid programs, I
               | never claimed otherwise. I said that C++'s type system
               | will reject _some_ programs that are in principle
               | correct, as opposed to what Spivak originally claimed
               | about C++ accepting all correct programs as valid.
               | 
               | The fact that some people can only think in terms of all
               | or nothing is really saying a lot about the quality of
               | discourse on this topic. There is a huge middle ground
               | here and difficult trade-offs that C++ and Rust make.
        
               | Spivak wrote:
               | I knew I should have also put the (in terms of memory
               | safety) on the C++ paragraph but I held off because I
               | thought it would be obvious both talking about the borrow
               | checker and in contrast to Rust with the borrow checker.
               | 
               | Yes, when it comes to types C++ will reject theoretically
               | sound programs that don't type correctly. And different
               | type system "strengths" tune themselves to how many
               | correct programs they're willing to reject in order to
               | accept fewer incorrect ones.
               | 
               | I don't mean to make it a dichotomy at all, every
               | "checker", linter, static analysis tool--they all seek to
               | invalidate some correct programs which hopefully isn't
               | too much of a burden to the programmer but in trade
               | invalidate a much much larger set of incorrect programs.
               | So full agreement that there's a lot of nuance as well as
               | a lot of opinions when it goes too far or not far enough.
        
         | MangoToupe wrote:
         | > If Rust optimizes based on borrow-checker assumptions
         | 
         | This is a binary assumption that you can understand to evaluate
         | to "true" in the absence of a borrow checker. If it is "false"
         | it halts the compiler
        
         | CGamesPlay wrote:
         | Yes. An analog would be uninitialized memory. The compiler is
         | free to make optimizations that assume that uninitialized
         | memory holds every value and no value simultaneously (because
         | it is undefined behavior to ever read it).
         | 
         | In the following example, z is dereferenced one time and
         | assigned to both x and y, but if z and x are aliased, then this
         | is an invalid optimization.                   fn
         | increment_by(x: &mut i32, y: &mut i32, z: &i32) {
         | *x = *z;             *y = *z;         }
         | 
         | https://rust.godbolt.org/z/Mc6fvTzPG
        
         | masklinn wrote:
         | > This can't possibly be guaranteed to work just by disabling
         | the checker, can it?
         | 
         | It works in the sense that the borrow checker stops bothering
         | you and the compiler will compile your code. It will even work
         | fine as long as you don't write code which invokes UB (which
         | does include code which would not pass the borrow checker, as
         | the borrow checker necessarily rejects valid programs in order
         | to forbid all invalid programs).
        
           | dataflow wrote:
           | > It will even work fine as long as you don't write code
           | which invokes UB (which does include code which would not
           | pass the borrow checker, as the borrow checker necessarily
           | rejects valid programs in order to forbid all invalid
           | programs).
           | 
           | To be clear, by "this" I meant "[allowing] code that would
           | normally violate Rust's borrowing rules to compile and run
           | successfully," which both of us seem to believe to be UB.
        
             | masklinn wrote:
             | Not quite, there _is_ code which fails borrow checking but
             | is safe and sound.
             | 
             | That is part of why a number of people have been waiting
             | for Polonius and / or the tree borrows model, most classic
             | are relatively trivial cases of "check then update" which
             | fail to borrow check but are obviously non-problematic e.g.
             | pub fn get_or_insert (             map: &'_ mut
             | HashMap<u32, String>,         ) -> &'_ String         {
             | if let Some(v) = map.get(&22) {                 return v;
             | }             map.insert(22, String::from("hi"));
             | &map[&22]         }
             | 
             | Though ultimately even if either or both efforts bear
             | fruits they will still reject programs which are well
             | formed: that is the halting problem, a compiler can
             | _either_ reject all invalid programs or accept all valid
             | programs, but it can not do both, and the former is
             | generally considered more valuable, so in order to reject
             | all invalid programs compilers will necessarily reject some
             | valid programs.
        
         | Sytten wrote:
         | Correct, I was reading a very interesting blog post [1] on how
         | the rust compiler will change the LLVM annotaions like sending
         | noalias for mutable pointer. This changes a lot the generated
         | machine code. Disabling the borrow checker won't enable those
         | LLVM flags.
         | 
         | [1] https://lukefleed.xyz/posts/who-owns-the-memory-pt1/
        
       | jokoon wrote:
       | To me it feels like rust is barely readable sometimes. When I
       | read some rust cost, I am often incapable to guess what it does,
       | so it does not feel intuitive.
       | 
       | I wish they made something simpler. At least C and C++ have a low
       | barrier of entry and any beginner can write code.
       | 
       | I don't think the borrow checker forced rust to be such a
       | complicated language.
        
         | mentalgear wrote:
         | I can just second that. Maybe someone (or some LLM) can write a
         | nice superset of Rust that is more readable - so the barrier of
         | entry drops significantly and we can all write better, more
         | efficient and memory-safe code!
        
         | torginus wrote:
         | I feel exactly the same - C++ might be a much more complex and
         | arcane language when you consider its entire feature set, and
         | all the syntactic machinery (I figured out by looking at STL or
         | Boost code, just how much of C++ I don't know or understand),
         | you can choose to not engage with most of the language. Hell,
         | even stuff like unique_ptr is optional when you're just
         | starting out.
         | 
         | But with Rust, you have to understand almost all of the
         | language very intimately to be a productive programmer, and
         | Rust is not that great at hiding complexity, as in fairly
         | innocious decisions often have far-reaching consequences down
         | the line.
        
           | mrits wrote:
           | I've shipped a lot of Rust software without the understanding
           | or even attempting to learn a lot of the language. There is
           | plenty of things in core libraries around traits that I have
           | no idea how they work or really care.
        
           | drogus wrote:
           | > you have to understand almost all of the language very
           | intimately to be a productive programmer,
           | 
           | I've seen absolute Rust noobs write production code in Rust,
           | I have no idea where did you get that notion from. Most of
           | the apps I've written or I've worked with don't even need to
           | use explicit lifetimes at all. If you don't need absolute
           | performance with almost none memory allocations, it's
           | honestly not rocket science. Even more so if you're writing
           | web backends. Then the code doesn't really differ that much
           | from Go.
        
         | sesm wrote:
         | C++ doesn't have low barrier of entry, I almost quit
         | programming as a teen because of C++.
        
           | torginus wrote:
           | Imo the worst thing about starting out with C++ (which is
           | much better with Rust), is the lack of credible package
           | management/build system that allows you to just install
           | packages.
           | 
           | This used to be even more true previously than today.
           | Nowadays, there's stuff like vcpkg, and tons of resources,
           | but I still wouldn't call it straightforward compared to
           | something like nuget or cargo.
           | 
           | It tooke me more time to figure out CMake than entire other
           | programming languages.
        
             | tialaramex wrote:
             | It does really help, in modern languages where they provide
             | tools in the box and the ecosystem just accepts those as
             | the default+ tools, to have the default be that when you
             | make a new project it just works, often by having it print
             | "Hello, World!" or something else simple but definitive as
             | proof we made a program.
             | 
             | + Default means just that, neither Rust's own compiler nor
             | the Linux kernel need the cargo tooling, but these projects
             | both have _actual toolsmiths_ to maintain their build
             | infrastructure and your toy program does not. There should
             | be a default which Just Works at this small scale.
        
             | 1718627440 wrote:
             | > the lack of credible package management
             | 
             | APT/dpkg/yast/rpm/pacman/... ?
             | 
             | Make is very simple, you don't even need a makefile. Just
             | type "make main" for main.cpp and it works.
        
           | tialaramex wrote:
           | There's a weird cognitive bias where somehow people justify
           | "I compiled this Hello World C++ project " as "C++ is easy"
           | and yet "I wasn't able to understand how this optimized
           | linear algebra library works" gets classed as "Rust is hard".
           | 
           | In reality it matters what you already know, and whether you
           | want to understand deeply or are just interested in enough
           | surface understanding to write software. There's a reason C++
           | has an entire _book_ about its many, many types of
           | initialization for example.
        
         | vanviegen wrote:
         | Yes, Rust has a pretty steep learning curve. If you're not
         | writing very low level stuff and don't need to squeeze out
         | every last bit of performance, there are many other, simpler
         | languages to choose from.
         | 
         | I think we may safely assume that Rust's designers are smart
         | people that have made every effort to keep Rust as simple as it
         | can be, given its intended use.
        
           | estebank wrote:
           | If you're not writing very low level stuff and don't need to
           | squeeze out every last bit of performance, Rust code can be
           | very simple and easy to understand as well.
        
         | Someone1234 wrote:
         | > At least C and C++ have a low barrier of entry and any
         | beginner can write code.
         | 
         | C/C++ is great at giving that false sense of competence. Then
         | suddenly you're getting a segfault, and you'll never determine
         | why with beginner knowledge, since the crash-line and the
         | mistake-line aren't even in the same zipcode (and or same Git
         | changeset).
         | 
         | Rust forces you to not "skip" knowledge steps. If you have a
         | gap in your knowledge/understanding the compiler will call you
         | out immediately. C/C++ will happily let your dangerously bad
         | code compile and kinda-run, until it doesn't.
         | 
         | I'm not anti-C/C++, I've actually written tons. I love C in
         | particular. But saying that they're beginner-friendly feels
         | wrong, a lot of people quit the language because "random stuff"
         | starts to go wrong, and they lack the knowledge to determine
         | _why_.
        
           | josephg wrote:
           | Yep. I've heard it said that Rust forces you to experience
           | all the pain up front. C will happily compile very broken
           | code.
           | 
           | One of my formative memories learning C came after I wrote a
           | function which accidentally returned a pointer to a variable
           | on the stack. It took me about a week to track that bug down.
           | I found it eventually - and then realised the compiler had
           | been warning me about it the whole time. I'd just been
           | ignoring the warnings "while I got my code working". Ugh. The
           | rust borrow checker wouldn't let you even compile code like
           | that.
           | 
           | If you're going to be working in a programming language for
           | years or even decades, I think the extra complexity (and
           | extra difficulty while learning) is an investment that will
           | pay off. But I'd be very happy for rust to stay a niche
           | language for systems software. C#, Go, Typescript and Swift
           | seem like great choices for making webpages and apps.
        
         | spoiler wrote:
         | I think the barrier to entry with Rust is lower than C++. Like
         | was way lower... And I've been writing C++ for way long than
         | Rust, so I'm probably a bit biased
        
         | josephg wrote:
         | > To me it feels like rust is barely readable sometimes. When I
         | read some rust cost, I am often incapable to guess what it
         | does, so it does not feel intuitive.
         | 
         | I feel torn with this sentiment.
         | 
         | On one hand, I totally agree. Rust's "foreign" ideas (borrowck,
         | lifetimes, match expressions, traits, etc) make it harder to
         | learn because there's a bunch of new concepts that nobody has
         | really worked with before. Some of this stuff - lifetimes and
         | borrows especially - really demand a lot of imagination on
         | behalf of the programmer to be able to understand what's
         | actually going on. The amount of thinking I do per shipped line
         | of code seems higher for rust than it does for languages like
         | Go, Typescript and C#. And sometimes C.
         | 
         | On the other hand, I learned C about 30 years ago. Not only
         | have I forgotten how hard it was to learn, but I had the brain
         | of a teenager at the time. And now I'm in my (early) 40s. I'm
         | scared that some of the struggle I went through learning rust
         | came because my brain is old now, and I've forgotten what its
         | like to be out of my depth with a programming language.
         | Learning rust requires shaking up some old neurons. And that's
         | really good for us, but it sucks.
         | 
         | In reality, I think its a bit of both. I've been using rust a
         | lot for about 3-4 years now. Its gotten way easier. But I still
         | prototype a fair bit of algorithmic code in typescript first
         | because I find TS makes it easier to iterate. That implies rust
         | is actually more complex. But, some people pick rust as their
         | first language and it seems to work out fine? I'm not sure.
         | 
         | > I don't think the borrow checker forced rust to be such a
         | complicated language.
         | 
         | Which parts of rust seem complicated? I've found a lot of the
         | things I struggled with at first got a lot easier with
         | familiarity. I love traits and match expressions. I love rust's
         | implementation of generics. I love most things about cargo and
         | the module system. But also, some parts of rust annoy me a lot
         | more now, a few years in.
         | 
         | I disagree with your comment. I think the main source of
         | complexity in rust comes from lifetimes - which are required by
         | the borrow checker. For example, its not obvious when you need
         | to put lifetimes in explicitly and when you can elide them.
         | When does the borrow checker understand my code? (Eg, can you
         | mutably borrow two different elements in an array at the same
         | time?). I also still don't really understand Higher-Rank Trait
         | Bounds.
         | 
         | I also still find Pin really confusing. In general I think
         | async and Futures in rust have some big design flaws. It also
         | really bothers me that there's a class of data types that the
         | compiler can generate and use, which are impossible to name in
         | the language. And some of the rules around derive and traits
         | are annoying and silly. Eg derive(Clone) on a generic struct
         | adds the constraint T: Clone, which is straight out wrong. And
         | rust needs a better answer to the orphan rule.
         | 
         | But in general, if you take out the borrow checker, I find rust
         | to be simpler and easier to read than most C++. There's no
         | headers. No exceptions. No wild template nonsense. And there's
         | generally way less weird magic going on. Eg, Foo(bar); could
         | mean about 8 different things in C++. Rust isn't like that.
         | Rust is simple enough you can just read the standard library,
         | even as a beginner, and its great. C++'s STL is a disaster to
         | read.
         | 
         | Rust is definitely more complex than C. But you do get some
         | lovely features for that extra cognitive overhead. Whether or
         | not thats worth it is up to you. In general - and I've been
         | saying this for years - I feel like the language I really want
         | is rust 2. I can't wait for someone to take rust's best ideas
         | and refine them into a simpler language.
        
         | masklinn wrote:
         | > To me it feels like rust is barely readable sometimes. [...]
         | C++ have a low barrier of entry and any beginner can write
         | code.
         | 
         | Here's rust code:                   fn main() {
         | println!("Hello, world");         }
         | 
         | Here is the equivalent C++ for the vast majority of its life
         | (any time before C++23, has MS even shipped C++23 support
         | yet?):                   #include <iostream>              int
         | main() {           std::cout << "Hello World!" << std::endl;
         | return 0;         }
         | 
         | C++ initialisation alone is a more complex topic than pretty
         | much any facet of Rust. And it's not hard to find C++ which is
         | utterly inscrutable.
        
       | andrewshadura wrote:
       | I don't have a slightest idea why would anyone want this. Borrow
       | checking is one of the greatest benefits of Rust.
        
         | Someone1234 wrote:
         | It is funny.
        
       | ViewTrick1002 wrote:
       | For everyone unaware, this repo is a meme:
       | 
       | https://www.reddit.com/r/rust/comments/1q0kvn1/corroded_upda...
       | 
       | As a follow on to the corroded meme crate:
       | 
       | https://github.com/buyukakyuz/corroded
       | 
       | > _What Is This_
       | 
       | > The rust compiler thinks it knows better than you. It won't let
       | you have two pointers to the same thing. It treats you like a
       | mass of incompetence that can't be trusted with a pointer.
       | 
       | > We fix that.
        
         | amluto wrote:
         | It does seem like satire. The very first example is:
         | fn main() {             let a = String::from("hello");
         | let b = a;             println!("{a}");  // Works! Prints:
         | hello         }
         | 
         | This is not "I have correct code but Rust can't tell it's
         | correct." This is "wow, this code is intentionally outrageously
         | wrong, obviously dereferences a pointer that is invalid, and
         | happens to work anyway."
        
           | 1718627440 wrote:
           | > this code is intentionally outrageously wrong
           | 
           | Can you explain why? Why can't both a and b point at the same
           | string object? Does `let b = a;` do something like a
           | destructive move?
        
             | gpm wrote:
             | I'm not 100% sure the semantics here are nailed down - but
             | I think there's no guarantee that `a` continues to _exist_
             | after assignment to `b`. The value in it has been moved out
             | of it after all... The memory which was used for the
             | variable `a` can probably be re-used for something else,
             | e.g. for some inlined variable used by `println!`...
             | 
             | In normal rust `let a = b` where the variable is of a non-
             | Copy type (including String) is "destructive" in the sense
             | that you can no longer use b.
             | 
             | The question about semantics in normal rust turns to "so if
             | I have a raw-pointer to a hanging around and use unsafe
             | code to copy the value out of it what do I get" and I'm not
             | 100% sure... but I think the answer is probably it's a use
             | after free and you get undefined behavior. The rust--
             | version is basically just this except you don't have to
             | explicitly make that raw pointer to read the old memory.
        
             | tredre3 wrote:
             | The rust way isn't intuitive if you're coming from C, but b
             | = a does indeed transfer the ownership to b and a is now
             | invalid/unusable. You would need to make a mutable
             | reference if you want two variables that point to the same
             | object.                   error[E0382]: borrow of moved
             | value: `a`          --> main.rs:4:16           |         2
             | |     let a = String::from("hello");           |         -
             | move occurs because `a` has type `String`, which does not
             | implement the `Copy` trait         3 |     let b = a;
             | |             - value moved here         4 |
             | println!("{a}");  // Works! Prints: hello           |
             | ^ value borrowed here after move           |           =
             | note: this error originates in the macro
             | `$crate::format_args_nl` which comes from the expansion of
             | the macro `println` (in Nightly builds, run with -Z macro-
             | backtrace for more info)         help: consider cloning the
             | value if the performance cost is acceptable           |
             | 3 |     let b = a.clone();           |
             | ++++++++
        
             | aw1621107 wrote:
             | > Does `let b = a;` do something like a destructive move?
             | 
             | Yes. Semantically, Rust performs destructive moves by
             | default, and as a result using `a` after `let b = a;` would
             | normally result in a hard error [0].
             | 
             | The way destructive moves are (currently?) actually
             | implemented, however, is as a shallow memcpy of the value
             | in question coupled with compiler checks that the moved-
             | from thing isn't used. As a result, if you disable the
             | compiler check simple uses of the moved-from value
             | immediately after the move could still work since the
             | compiler doesn't take explicit steps to modify the moved-
             | from value immediately after a move.
             | 
             | [0]: https://rust.godbolt.org/z/Wdr6G1GsK
        
       | kace91 wrote:
       | I'm not picturing how it works.
       | 
       | In rust you don't have a garbage collector and you don't manually
       | deallocate - if the compiler is not certain of who drops memory
       | and when, what happens with those ambiguous drops ?
       | 
       | In other words, are the silenced errors guaranteed to be memory
       | leaks/use after frees?
        
         | eru wrote:
         | I don't think so, I don't think Rust's borrow checker is free
         | of false negatives.
        
         | gliptic wrote:
         | The borrow checker doesn't decide when things are dropped. It
         | only checks reference uses and doesn't generate any code. This
         | will work exactly the same as long as your program doesn't
         | violate any borrowing rules.
        
           | kace91 wrote:
           | No, I get that from an architectural perspective they are
           | separate processes. The point is, unlike in other languages,
           | the compiler is developed assuming the input has been borrow
           | checked, right? So it is surprising to me that it doesn't
           | blow up somewhere when that invariant doesn't hold.
        
             | masklinn wrote:
             | > So it is surprising to me that it doesn't blow up
             | somewhere when that invariant doesn't hold.
             | 
             | The final program may be broken in various manners because
             | you don't respect the language's prescribed semantics, in
             | about the same way they do in C and C++. From the
             | compiler's perspective the borrow checker validates that
             | rules it assumes are upheld are actually upheld.
             | 
             | mrustc already compiles rust code without having a borrow
             | checker (well IIRC recent-ish versions of mrustc have some
             | borrow checking bits, but for the most part it still
             | assumes that somebody else has done all the borrow
             | checking).
        
             | pornel wrote:
             | The compiler has deep assumptions about exclusive ownership
             | and moves, which affects destructors and deallocation of
             | objects.
             | 
             | It doesn't actually depend on the borrow checker. All
             | lifetime labels are discarded after being checked. Code
             | generation has no idea about borrow checking. Once the code
             | is checked, it is compiled just like C or C++ would, just
             | assuming the code is valid and doesn't use dangling
             | pointers.
             | 
             | Borrow checker doesn't affect program behavior. It either
             | stops compilation or does nothing at all. It's like an
             | external static analysis tool.
        
             | andrewaylett wrote:
             | In a correct program, the borrow checker has no effect.
             | 
             | Languages like C compile code with the understanding that
             | if the compiler can't prove the code is incorrect, it'll
             | assume it's correct. Rust compiles with the expectation
             | that unless the compiler can prove the code correct
             | (according to the language rules), it won't compile it. In
             | C, all programs that only perform defined behaviour are
             | valid, but many programs which exhibit undefined behaviour
             | are also valid. In safe Rust, all programs which exhibit
             | undefined behaviour are invalid. But as a trade-off, many
             | programs which would actually execute perfectly well are
             | also considered invalid.
             | 
             | In both cases, once you get past the layers that check
             | stuff, you may normally assume that whatever you have has
             | already been shown to be OK and you probably don't have
             | enough information to re-check while compiling. It might
             | blow up at runtime, it might not.
        
         | MangoToupe wrote:
         | Rust's concept of lifetime and scopes exists independently of
         | the borrow checker
        
         | juliangoldsmith wrote:
         | The silenced errors aren't guaranteed to be memory leaks or use
         | after frees. There are some situations where memory is being
         | handled properly, but the borrow checker isn't able to prove
         | it.
         | 
         | One example might be a tree-like struct where a parent and
         | child have references to each other. Even if everything is
         | cleaned up properly, the borrow checker has no way to know that
         | when the struct is created. Solving it requires unsafe at some
         | point, usually through something like RefCell.
        
         | antonvs wrote:
         | > In other words, are the silenced errors guaranteed to be
         | memory leaks/use after frees?
         | 
         | No, not at all. The examples at the beginning of the article
         | show this - they'll execute correctly. The borrow checker is
         | quite conservative, and rules out all sorts of code that won't
         | (normally!) cause runtime errors.
         | 
         | It's fairly easy to see this if you think about the core of
         | Rust's ownership model: every value in Rust has a single owner.
         | The compiler enforces that for any value, there's either one
         | mutable reference or any number of immutable references to it
         | at a time.
         | 
         | This model has the advantage of being simple, easy to reason
         | about, and ruling out large classes of errors. But like most
         | static checks, including e.g. traditional type checks, it also
         | rules out a great deal of otherwise valid code.
         | 
         | It's easy to think of examples in which you have multiple
         | mutable references to a value that won't cause errors. Aside
         | from trivial examples like in the article, in C-like languages
         | you can have many concurrent mutable references to the same
         | mutable value. You can safely (with some caveats) manage access
         | to it via locks, protocols, documentation, or just being
         | careful. Rust with the borrow checker simply doesn't allow
         | multiple concurrent mutable references to the same value to
         | exist. Rust without the borrow checker, as in the article,
         | would allow this.
        
         | gpm wrote:
         | I'm pretty sure that every example except example-3 in the
         | readme intentionally invokes undefined behavior - if that helps
         | you picture how it works ;)
        
       | tmtvl wrote:
       | Amazing, this is like the bizarro version of what I'd want. Like
       | someone said 'hey, there's this kinda crappy language with a
       | really cool feature, let's _not_ make a great language with that
       | feature, but instead take the crappy language and remove the cool
       | feature which is the only thing keeping it from being trash '.
       | Okay, sure, tagged unions, closures, and hygienic macros are
       | nice; but there are plenty of other languages with the first two
       | and when your syntax is atrocious even the most hygienic macro is
       | going to look like something that crawled out of the sewer at
       | R'lyeh.
        
       | p0w3n3d wrote:
       | There are easier ways of making segfault than writing a custom
       | compiler.
        
       | NooneAtAll3 wrote:
       | I'd prefer the opposite - borrow checker, but remove the useless
       | "fn" and "let" keywords
        
       | reverseblade2 wrote:
       | Should be named in rust we don't trust
        
       | 0xMohan wrote:
       | I'm assuming it's a meme project. In case it isn't, what's the
       | point? Just trying to understand.
       | 
       | Isn't rust's one of the main selling point is the barrow checker
       | right?
       | 
       | Also how's the memory is handled? I know it'll drop every thing
       | once it's out of scope but it seems you can make copies as much
       | as you want. Looking at the loop example, I feel like this
       | introduces memory leaks & undefined behavior.
        
       | joelthelion wrote:
       | I would actually enjoy that for certain small projects. Rust
       | without the borrow checker is a very elegant language. The borrow
       | checker is great, of course, but it can be a pain to deal with.
       | So, for small projects it would be nice to be able to disable it.
        
         | estebank wrote:
         | Instead of disabling the borrow checker what should be possible
         | is to promote borrows to Rc/Arc as needed. I would want to
         | restrict this mode to one where it can only work locally, never
         | publishable to crates.io. It would be particularly useful when
         | running tests, then instead of a compile error you can also get
         | a runtime error with better information about the cases the
         | borrow checker was actually encountering.
        
       | corrode2711 wrote:
       | I'm the author of this repo. I see some really angry comments,
       | some of them even personal. Obviously I didn't think that just by
       | tinkering with a compiler, I'd get personally attacked, but
       | anyway, fair enough.
       | 
       | For those of you confused: yes, this started as a satirical
       | project with the corroded lib. Then I thought "why not just
       | remove the borrow checker?" without any real motivation. Then I
       | just went ahead and did it. To my surprise, it was really simple
       | and easy. I thought it would be heavily tangled into the rustc
       | compiler, but once I figured out where the error emitter is, it
       | was pretty straightforward.
       | 
       | I'm not sure about my long-term goals, but besides the joke, I
       | genuinely think for debugging and prototyping purposes, I'd like
       | the borrow checker to shut up. I'm the kind of guy that prints
       | everything while debugging and prototyping. Maybe you're using a
       | debugger, okay, but I don't. I don't like debuggers. It's just
       | more convenient for me. So what constantly happens is I run into
       | issues like: does this implement Debug? Can I print this after it
       | moved? The borrow checker won't let me access this because of
       | some other borrow. Stuff like that.
       | 
       | Another point is, as you guys are well aware, the borrow checker
       | will reject some valid programs in order to never pass any
       | invalid program. What if I'm sure about what I'm doing and I
       | don't want that check to run?
       | 
       | In the repo there's a doubly linked list example. Without the
       | borrow checker it's fairly simple and easy to implement. With it,
       | you know how complicated and ugly it gets.
       | 
       | Anyway, have a good new year, and don't get angry over compilers,
       | you know.
        
         | whatshisface wrote:
         | I think there is probably a way to do what you're doing with
         | unsafe. You could write a library that copies handles and can
         | dump potentially freed memory afterwards.
        
           | g-mork wrote:
           | Some kind of cargo plugin that transforms all references in
           | the project into pointers and casts prior to feeding to rustc
           | would probably be the best practice and highly maintainable
           | route I'd go. like "cargo expand" but with a fancy catchier
           | name that encourages new users to rely on it. "cargo autofix"
           | might work
        
           | jvanderbot wrote:
           | There's definitely a way to do it without unsafe! It just
           | isn't as simple as dropping one println out so.... Lets alter
           | the compiler?
           | 
           | I gotta applaud that level of my-way-or-the-highway
        
         | CodeMage wrote:
         | > Then I thought "why not just remove the borrow checker?"
         | without any real motivation.
         | 
         | Reminds me of a chemistry kit I had as a kid. None of this
         | tame, safe stuff you can buy these days. Mine was a gift from
         | my dad and I never thought of asking him where he dug it up,
         | but it had stuff like pure sulfuric acid in it.
         | 
         | One day, when I was done with all of the experiments I had
         | planned to do, I decided to mix a few things and heat them up,
         | just for fun, without any real motivation other than "let's see
         | what happens".
         | 
         | Let's just say I was lucky we only had to replace some of the
         | clothes my mom had left out for me to put away. ;)
         | 
         | > Another point is, as you guys are well aware, the borrow
         | checker will reject some valid programs in order to never pass
         | any invalid program. What if I'm sure about what I'm doing and
         | I don't want that check to run?
         | 
         | Then you do it using the "unsafe" keyword, and you think long
         | and hard about how to design and structure the code so that the
         | unsafe code is small in scope, surface, and blast radius.
         | 
         | That's precisely what unsafe code is for: to get around the
         | borrow checker and assert you know what you're doing. Of
         | course, if you're wrong, that means your program will blow up,
         | but at least you know that the culprit is hiding in one of
         | those unsafe areas, rather than literally anywhere in the whole
         | codebase.
         | 
         | Alternately, you can switch to a language with a different
         | ethos.
         | 
         | The ethos of Rust is caring for memory safety so much that you
         | willingly limit yourself in terms of what kind of code you
         | write and you only step out of those limits reluctantly and
         | with great care. That's something that resonates with a lot of
         | people and Rust has been built on top of that for years.
         | 
         | If you suddenly take the product of those years of hard work,
         | strip out the foundation it has been built on, and unironically
         | offer it as a good idea, a lot of people won't like it and will
         | tell you so. Mind, I'm not excusing the personal attacks, I'm
         | just explaining the reaction.
        
           | corrode2711 wrote:
           | Anything fun is dangerous. Or anything dangerous is fun.
           | Something like that.
        
         | npalli wrote:
         | You just need to master one package managed in depth and you
         | will get what you really want with Modern C++.
        
         | oblio wrote:
         | You, sir, might one day belong to the Computing Hall of Fame,
         | together with the creators of Brainf*k, Visual Basic, PHP,
         | Javascript, ColdFusion, etc. :-p
        
       | indigoabstract wrote:
       | My controversial opinion:
       | 
       | If Rust were to "borrow" something from the C/C++ spirit, then
       | disabling the borrow checker should be available as a compiler
       | option.
       | 
       | As in, you're an adult: if you want it, you can have it, instead
       | of "we know better".
        
         | whatshisface wrote:
         | If you could disable the borrow checker globally, projects
         | would do it, and it would become impossible to compile anything
         | with it enabled.
         | 
         | You can already disable it locally: the unsafe keyword is for
         | that.
        
           | gpm wrote:
           | The unsafe keyword doesn't disable the borrow checker... it
           | lets you interact with different pointer types that aren't
           | borrow checked, but if you're using the normal reference
           | types in rust the same guardrails are still in place.
        
         | klysm wrote:
         | Doesn't work - you need the borrow checker guarantees to
         | implement downstream compilation steps. You can just turn off
         | assumptions
        
           | gpm wrote:
           | > you need the borrow checker guarantees to implement
           | downstream compilation steps.
           | 
           | You don't technically. The borrow checker doesn't effect the
           | semantics of the program (like, for example, type inference
           | does) and the rest of the compiler doesn't need to (and in
           | fact, doesn't) use its analysis to figure out how to compile
           | the code.
           | 
           | The downstream compiler does assume that the code followed
           | the rules for accessing references - i.e. didn't violating
           | aliasing rules. The borrow checker guarantees this, but it's
           | fundamentally a conservative check. It rejects programs it
           | can't guarantee are correct, and rice's theorem proves that
           | there are always correct programs that it can't guarantee are
           | correct.
           | 
           | That said if you just treat rust-references like C-pointers
           | you will run into issues. The aliasing rules for rust
           | references are stricter. Also not fully agreed upon yet - the
           | currently closest to accepted definition is in the "tree
           | borrows" paper but it has yet to be adopted as the official
           | one by the rust team.
        
         | pornel wrote:
         | That's not the spirit Rust wants to have. You can already
         | disable borrow checker selectively by using "raw" pointers in
         | places where you think you know better, and this is used very
         | commonly. Every String in Rust has such raw pointer inside.
         | 
         | It doesn't make much sense to globally relax restrictions of
         | Rust's references to be like C/C++ pointers, because the
         | reference types imply a set of guarantees: must be non-null
         | (affects struct layout), always initialized, and have strict
         | shared/immutable vs exclusive access distinction. If you relax
         | these guarantees, you'll break existing code that relies on
         | having them, and make the `--yolo` flag code incompatible with
         | the rest. OTOH if you don't remove them, then you still have
         | almost all of borrow checker's restrictions with none of the
         | help of upholding them. It'd be like a flag that disables the
         | sign bit of signed integers. It just makes an existing type
         | mean something else.
        
         | MangoToupe wrote:
         | Is rust simple aesthetics to you? Why use rust, or any language
         | at all really, at all then? The whole point of formal languages
         | is to point a gun at the people who refuse to be adults.
         | 
         | If we can't have this, C itself offers zero benefit over
         | assembly.
        
           | indigoabstract wrote:
           | I think it's more in the spirit of playfulness, like in
           | "don't take yourself too seriously". It's why people want to
           | mod Minecraft and Doom for example.
           | 
           | Because it's fun.
           | 
           | I can totally understand why you wouldn't want to do this
           | though - the plethora of incompatible lisp dialects come to
           | mind. That's why I said it was controversial.
        
           | Wowfunhappy wrote:
           | You don't think assembly is more tedious to write than C? I
           | don't think that's because of what C does/doesn't "allow" you
           | to do.
        
             | yazaddaruvala wrote:
             | Of course it is. C does allow named functions and
             | variables. C doesn't allow arbitrary jumps.
             | 
             | Those are two reasons why C is less tedious than assembly.
        
               | 1718627440 wrote:
               | > C doesn't allow arbitrary jumps.
               | 
               | Have you heard of longjmp?
        
       | shmerl wrote:
       | Isn't unsafe just for that? Why does it need a separate compiler?
        
         | idontsee wrote:
         | The borrow checker still applies in unsafe { } blocks. What it
         | means (iirc) is that you can do pointer/memory stuff that would
         | otherwise not be allowed. But you still fully adhere to Rust
         | semantics
        
         | andrewaylett wrote:
         | Unsafe isn't so unsafe that it disables the borrow checker!
         | 
         | The two main things the compiler allows in an unsafe block but
         | not elsewhere are calling other code marked "unsafe" and
         | dereferencing raw pointers. The net result is that safe code
         | running in a system that's not exhibiting undefined behaviour
         | is defined to continue to not exhibit undefined behaviour, but
         | the compiler is unable in general to prove that an unsafe block
         | _won 't_ trigger undefined behaviour.
         | 
         | You can side-step the borrow checker by using pointers instead
         | of references, but using that power to construct an invalid
         | reference is undefined behaviour.
        
       | JoelJacobson wrote:
       | Rust without async maybe?
        
         | juped wrote:
         | This would actually be good though!
        
       | accelbred wrote:
       | I've been thinking of writing a language with Rust's ergonomics
       | but less of the memory safety stuff. I prefer using no dynamic
       | allocations, in which case the only memory safety feature I need
       | is leaking references to locals into outer scopes. As for the
       | thread safety stuff, most of my stuff is single-threaded.
        
         | giancarlostoro wrote:
         | I've been wishing for Rust to become more ergonomic, what
         | ergonomics does Rust currently have that other languages lack?
        
           | Null-Set wrote:
           | I love how everything is an expression with a value. And
           | match expressions are quite nice, especially with the option
           | type. I really miss those when working in javascript.
        
           | zeroxfe wrote:
           | If Go had rust-style ADTs and pattern matching, and some
           | parallel of "?" to short-circuit error handling, I'd be
           | thrilled.
        
           | accelbred wrote:
           | For me its everything being an expression, macro_rules, dyn,
           | automatic conversions (the few that it does have), traits,
           | and the ? operator.
        
           | masklinn wrote:
           | Affine types / destructive moves, type-level safety signal
           | (sync/send), container-type locks.
           | 
           | I really miss these when doing concurrent stuff in other
           | languages.
        
       | QuaternionsBhop wrote:
       | Fighting the borrow checker is something you do when you're
       | learning Rust. After you learn how to design things that way in
       | the first place, it's just there to keep you honest.
        
         | tinco wrote:
         | To be fair, working on the Rust compiler is also something to
         | do when you're learning Rust. I guess this person is killing
         | two birds with one stone.
        
       | sakisv wrote:
       | As someone who's only did a couple of small toy-projects in rust
       | I was never annoyed by the borrow checker. I find it nothing but
       | a small mental shift and I kinda like it.
       | 
       | What I _do_ find annoying though and I cannot wrap my head around
       | are lifetimes. Every time I think I understand it, I end up
       | getting it wrong.
        
         | Maxatar wrote:
         | Lifetimes are the input to the borrow checker, so it doesn't
         | make much sense to say you have never been bothered by the
         | borrow checker but you are bothered by lifetimes.
        
           | ViewTrick1002 wrote:
           | Due to lifetime elision you can mostly skip lifetimes if you
           | leave a bit of performance on the table.
        
       | zemo wrote:
       | way too many people in this thread are taking this project
       | seriously
        
       | lamontcg wrote:
       | The more I write code in other languages where I think hard about
       | ownership ("does this method ultimately grab the object and throw
       | a ref onto some long-lived data structure somewhere? Then it owns
       | it, so I better clone it") the more robust my code in other
       | languages generally gets. Same with mutation. Generally better to
       | make a copy of something and then mess with it and throw it away
       | than to try to mutate-then-unmutate or something like that, even
       | though it might in principle be nanoseconds faster. Eliminate
       | loads of spooky-action-a-distance bugs where things are getting
       | mutated in one spot and used in another spot, when there should
       | have been a copy in there somewhere.
        
         | dmitrygr wrote:
         | > Generally better to make a copy of something
         | 
         | > Eliminate loads of spooky-action-a-distance bugs
         | 
         | This line of thinking so sickens me. Many things are not easy
         | when done _right_. That is no excuse to avoid understanding how
         | to do them right. Sure, making endless copies is easier. But
         | this is why machines now need 16GB of ram and four cores to run
         | the calculator.
        
       ___________________________________________________________________
       (page generated 2026-01-01 23:01 UTC)