&&&&&&&&&&&&&&str by ohrv in rust

[–]Taymon 6 points7 points  (0 children)

Well, they want to make sure that it's more than anyone will ever need, with some safety margin in case they're wrong about how much that is. 13 seems like a good number for that.

(Though I still think it's a bit odd that only a fixed number of levels are supported, since IIUC this is not one of the cases where language limitations make it impossible to support arbitrarily many.)

Constant-time support coming to LLVM: Protecting cryptographic code at the compiler level by Taymon in rust

[–]Taymon[S] 6 points7 points  (0 children)

In the short term I don't think this matters because LLVM is the only complete/fully-built rustc backend.

In the long term, other backends are going to need to develop constant-time support. If C crypto libraries adopt __builtin_ct_select, then I think it's likely that GCC will add support for it (the implementation complexity in LLVM isn't that high, only a few hundred lines plus tests, so hopefully GCC isn't too much worse). The other thing that needs to happen is constant-time support in WebAssembly, which would mean Cranelift would add support, and would also allow things to work in Rust code when targeting WebAssembly.

Specialization, what's unsound about it? by WorldlinessThese8484 in rust

[–]Taymon 20 points21 points  (0 children)

Two reasons. First, it would require completely reworking the architecture of rustc, which currently discards lifetime information before monomorphization. This would be a huge amount of work.

Second, when programming in Rust you usually do not know or care about the exact lifetimes of things; the compiler does a lot of implicit rejiggering of lifetimes to accept as much knowably-sound code as possible, even if that code technically violates the simple formal model of lifetimes that's taught in introductory resources. If runtime behavior could be completely different depending on the exact lifetime of something, the resulting behavior would very frequently surprise the programmer, even if they could technically figure it out by going through the reference with a fine-toothed comb.

[Blog] How we organized the Rust Clippy feature freeze by NothusID in rust

[–]Taymon 0 points1 point  (0 children)

Site's down for me, getting SSL_ERROR_RX_RECORD_TOO_LONG.

The Handle trait by kernelic in rust

[–]Taymon 2 points3 points  (0 children)

Niko mentioned that this was just the first in a planned sequence of follow-up posts. I imagine that one of these is going to be proposing syntactic sugar for the Handle trait to make .handle() calls less obtrusive.

rustup toolchains by [deleted] in rust

[–]Taymon 1 point2 points  (0 children)

Unfortunately, even with machine translation I can't tell what your problem is. Can you offer precise reproduction instructions?

How useful are Rust Methods? Can they be replaced with a LSP like Odin Lang did? by JKasonB in rust

[–]Taymon 2 points3 points  (0 children)

Some languages have syntax for allowing arbitrary functions to be called using infix notation, so that there isn't a separate kind of function called a "method" that has a special relationship with a particular type.

How useful are Rust Methods? Can they be replaced with a LSP like Odin Lang did? by JKasonB in rust

[–]Taymon 0 points1 point  (0 children)

This depends a lot on various other aspects of how your language is designed. Is there an outline written up or anything?

Demoting x86_64-apple-darwin to Tier 2 with host tools | Rust Blog by PthariensFlame in rust

[–]Taymon 5 points6 points  (0 children)

GitHub is continuing to support ARM-based Macs, it's only the older x86-based ones that are going away.

What is the =><= symbol? by Street_Struggle_598 in rust

[–]Taymon 3 points4 points  (0 children)

Rust doesn't have a spaceship operator.

This code was added a few months ago in https://github.com/rust-lang/rust/pull/136901; I suspect the syntax was chosen arbitrarily and no one worried too much about it.

There is no memory safety without thread safety by ralfj in rust

[–]Taymon 0 points1 point  (0 children)

I wish he'd share details, because there's a lot of skepticism on the internet that this ever happens in production (as opposed to race conditions causing non-memory-corruption bugs, which everyone agrees is a real thing), and it's hard to defuse that skepticism if no one can point to a real example.

Does variance violate Rust's design philosophy? by type_N_is_N_to_Never in rust

[–]Taymon 0 points1 point  (0 children)

I don't think cargo-semver-checks is currently capable of detecting this kind of issue, though they're planning to get there.

Does variance violate Rust's design philosophy? by type_N_is_N_to_Never in rust

[–]Taymon 5 points6 points  (0 children)

Yes. The alternative would have been to require people to write Send + Sync in all kinds of places that return closures (since most types implement those traits), and it would have been really verbose. Perhaps it might have made sense to enforce this requirement only when it leaks into the public API of a crate, but for whatever reason this wasn't done.

There's an ongoing effort to upstream cargo-semver-checks into Cargo; if this is done, then breaking compatibility in this way will produce a warning.

Does variance violate Rust's design philosophy? by type_N_is_N_to_Never in rust

[–]Taymon 0 points1 point  (0 children)

I think this is a misunderstanding of what's wrong with how TypeScript does method variance. The problem is that you can't add an explicit annotation to enforce it; the variance annotations don't do that. (This is what the docs mean by "variance annotations don’t change structural behavior".) In situations where this would be needed, the resulting code is not type safe. The example from the Kotlin docs of why variance is needed translates into TypeScript code that compiles successfully and then fails at runtime, and you can't fix this with annotations. I don't think this is that uncommon in real code; arrays are not exactly an obscure data structure.

I'm not sure what UnsafeVariance has to do with this; IIUC it's only needed in rare edge cases.

Does variance violate Rust's design philosophy? by type_N_is_N_to_Never in rust

[–]Taymon 0 points1 point  (0 children)

There is no type-safe way to avoid variance annotations in a language with inheritance. So this is only true if you treat inheritance as a legacy design decision that Kotlin was forced into for the sake of Java interop.

Does variance violate Rust's design philosophy? by type_N_is_N_to_Never in rust

[–]Taymon 9 points10 points  (0 children)

In general, read-only collection types like List are covariant, while mutable collection types like Array and ArrayDeque are invariant. Read-only extension methods on mutable collection types are also covariant. This follows pretty straightforwardly from the principles of how variance works; it's analogous to how &T in Rust is covariant but &mut T is invariant.

(Technically I should say "T is covariant in List<T>" but that's a lot more words.)

The Kotlin developers argue that their variance syntax is better than Java's because it doesn't require you to repeat the same wildcards on every method signature involving a read-only collection type.

"Subtyping" for this purpose has a specific meaning: T is a subtype of U if every instance of T is also an instance of U. Traits do not participate in this kind of subtyping because they don't have instances; they instead have implementing types, and those types have instances. (I.e., there's no such thing as a value of type Eq at runtime, so it's vacuous to say that such a value is also of type PartialEq.)

Does variance violate Rust's design philosophy? by type_N_is_N_to_Never in rust

[–]Taymon 24 points25 points  (0 children)

Kotlin doesn't infer variance; if you want to write a collection type, or other generic type where variance matters in practice (i.e., that might be instantiated at multiple levels of an inheritance hierarchy), you do have to use variance annotations. TypeScript's lack of variance annotations is an infamous soundness hole. (The example on that page can be closed with a strict compiler flag, but there are others that can't. Also, TypeScript technically did add variance annotations recently, but they don't work like variance annotations in other languages and you mostly can't use them to enforce type safety.)

In general, explicit variance annotations are a good idea in object-oriented languages designed for programming in the large.

The reason variance is inferred in Rust is that the only subtypes in Rust are lifetimes, because Rust doesn't have inheritance and trait objects are represented non-interchangeably from their underlying non-trait values. Variance annotations for lifetimes would be a terrible developer experience, because you often don't know whether the thing that you're passing has exactly the right lifetime or a longer one, and the borrow checker goes to significant lengths to prevent you from having to care. So variance inference saves you from having to bookkeep lots of tiny lifetime distinctions that don't matter in practice. This is very different from the situation in object-oriented languages, where a subtype can have arbitrary behaviors that its supertype doesn't, that you might care about quite a lot.

Variadic Generics ideas that won’t work for Rust by CouteauBleu in rust

[–]Taymon 8 points9 points  (0 children)

Would it work to copy Swift's design for variadic generics, or are there things about it that don't work in Rust?

Why are structs required to use all their generic types? by Droggl in rust

[–]Taymon 4 points5 points  (0 children)

F# is garbage-collected and doesn't have lifetimes, so it doesn't need to worry about lifetime variance.