Stream: t-lang

Topic: LLVM capabilities vs cranelift


nikomatsakis (Mar 12 2020 at 20:40, on Zulip):

So, in the meeting today, the question of whether it's ok for some features to not be supported by all backends came up. In particular, we were talking about the proposed #[instruction_set] attribute, which may be easy to support in LLVM (I don't know that for a fact, I'm assuming) but would probably be more work for (say) cranelift. I said that to my mind it'd be ok if a hypothetical cranelift backend gave an error on code that used it, but @centril disagreed. I thought it might be worth talking that out in more detail, because I foresee this being a topic that comes up again, especially as we talk about supporting more low-level features. It certainly arose for inline assembly, for example.

nikomatsakis (Mar 12 2020 at 20:41, on Zulip):

I feel like my preferred outcome is that #[instruction_set] is considered a hint, and that it works uniformly across all backends (perhaps with a warning on cranelift or something if it's unsupported).

nikomatsakis (Mar 12 2020 at 20:42, on Zulip):

An interesting question is whether it'd be ok to have inline assembly be unsupported in a similar way. I might be ok with that, but I also feel somewhat differently about inline asm vs instruction-set, I guess because the latter seems rather more niche, whereas it seems quite possible that you'll pull down some random crate from crates.io that requires inline assembly.

pnkfelix (Mar 12 2020 at 20:42, on Zulip):

context: https://github.com/rust-lang/rfcs/pull/2867

nikomatsakis (Mar 12 2020 at 20:43, on Zulip):

Overall I guess I am worried about some kind of rule that says "everything must be easily supported by any 'ordinary' backend" -- it seems like it will limit us from taking full advantage of LLVM.

pnkfelix (Mar 12 2020 at 20:43, on Zulip):

(and it might also be in conflict with our goal of "parity with C" ... depending on what that means ...)

nikomatsakis (Mar 12 2020 at 20:44, on Zulip):

(At the same time, I don't want us to be permanently wedded to LLVM, so there's some kind of line there...)

nikomatsakis (Mar 12 2020 at 20:44, on Zulip):

pnkfelix said:

(and it might also be in conflict with our goal of "parity with C" ... depending on what that means ...)

right

simulacrum (Mar 12 2020 at 20:45, on Zulip):

I personally think we should try to avoid tying to LLVM specifics, but we should also be open to "not all backends do this" -- e.g., #[inline] though entirely a hint is kinda like this -- not all backends would inline anything of course

nikomatsakis (Mar 12 2020 at 20:45, on Zulip):

Yes, this kind of optimization hint is sort of the "easy case"

nikomatsakis (Mar 12 2020 at 20:46, on Zulip):

But there's a difference between "tying to LLVM specifics" and "taking advantage of what LLVM offers"

nikomatsakis (Mar 12 2020 at 20:46, on Zulip):

Naked functions are another potential example

simulacrum (Mar 12 2020 at 20:47, on Zulip):

My line would personally be that things might be a warning, but we should try to avoid cases where it's a hard error if you swap backends on the common case

nikomatsakis (Mar 12 2020 at 20:47, on Zulip):

(From what I understand, this is a common feature in many C compilers, but maybe not supported by cranelift. Not to get into whether we want it specifically or not, of course.)

pnkfelix (Mar 12 2020 at 20:47, on Zulip):

I continue to be concerned about ABI impact.

simulacrum (Mar 12 2020 at 20:47, on Zulip):

(but e.g. for the ARM instruction_set stuff, it seems like people in that world are used to and would be quite fine with "well I need to use LLVM as a backend")

Amanieu (Mar 12 2020 at 20:48, on Zulip):

Regarding #[instruction_set], it should be an error if it is not supported by the backend. There are visible effects, e.g. if that function uses inline asm, or if it uses floats (not supported on Thumb, gets lowered to a compiler-rt call).

pnkfelix (Mar 12 2020 at 20:48, on Zulip):

From Lokathor's summary:

The linkers for ARM targets can adjust function calls so that calls from ARM to Thumb and back can use bx and blx as appropriate (eg: GNU ld calls the flag -mthumb-interwork), again based on the address of the jump target.

pnkfelix (Mar 12 2020 at 20:48, on Zulip):

The fact that you have to invoke GNU ld with a special flag to make this work adds to my concern.

centril (Mar 12 2020 at 20:49, on Zulip):

Taking advantage of LLVM in hints is quite different than adding new requirements & behaviors in the language spec

centril (Mar 12 2020 at 20:49, on Zulip):

Hints can be entirely ignored in the spec

centril (Mar 12 2020 at 20:49, on Zulip):

Lints are similarly not part of the spec

pnkfelix (Mar 12 2020 at 20:49, on Zulip):

pnkfelix said:

The fact that you have to invoke GNU ld with a special flag to make this work adds to my concern.

(but maybe that flag is not that special? I'm often confused my the -mfamily of flags in gcc)

nikomatsakis (Mar 12 2020 at 20:50, on Zulip):

simulacrum said:

My line would personally be that things might be a warning, but we should try to avoid cases where it's a hard error if you swap backends on the common case

this is kind of where I fall. For a feature that we expect to be "commonly found" in crates, I would want it to not rely on highly specialized features (though I think there is a choice here; it seems ok to me for us to make demands of our backends too). But I expect some things to be more narrowly used and for that I don't necessarily feel all targets/backends must support it.

centril (Mar 12 2020 at 20:51, on Zulip):

Making demands on our backend might not be successful, depending on "our power" and the backend

simulacrum (Mar 12 2020 at 20:51, on Zulip):

Maybe there's also some middle ground here -- e.g., I would hope that maybe we can find a way to have "backend-specific" details that are still RFCd and such. I think having that is pretty key in some way. Having to tie everything to a lowest common denominator feels pretty bad

centril (Mar 12 2020 at 20:51, on Zulip):

e.g. cranelift might be amenable to make changes for us

centril (Mar 12 2020 at 20:52, on Zulip):

I don't think it's bad personally; I don't think we should be making too many demands on a backend, to the point that making one becomes unreasonably hard, and it might also create problems for future backends.

pnkfelix (Mar 12 2020 at 20:52, on Zulip):

pnkfelix said:

I continue to be concerned about ABI impact.

also from Lokathor's summary:

Nope. LLVM, the linker, and the CPU all carry around the correct info about functions and function pointers based on the lowest bit of the address. [...] The inter-procedure call format also doesn't change [...]

centril (Mar 12 2020 at 20:54, on Zulip):

As for LLVM specifically, I am wary of our dependence on it... I am wary of being at the mercy of C++ and LLVM's priorities (esp. wrt. soundness, compile times).
If features that a lot of users use can only be used on LLVM, then it means that any alternative backend is a second class citizen, and won't really be used.

centril (Mar 12 2020 at 20:55, on Zulip):

nikomatsakis said:

I feel like my preferred outcome is that #[instruction_set] is considered a hint, and that it works uniformly across all backends (perhaps with a warning on cranelift or something if it's unsupported).

I think that means we don't have any spec dependence on LLVM here, and that would be good. If that's the outcome we can tuck it under #[optimize(...)], simplifying the spec in the process.

simulacrum (Mar 12 2020 at 20:57, on Zulip):

Also, am I wrong, or is instruction_set not actually spec dependence on LLVM? i.e. the details on what it means are entirely "open" and not tied to LLVM specific details?

pnkfelix (Mar 12 2020 at 20:57, on Zulip):

If we are putting any particular weight on Lokathor's expertise here, they also said this:

pnkfelix (Mar 12 2020 at 20:58, on Zulip):

My reading is that this is not LLVM specific at all, at least not in this context. Or at least, if GNU ld supports it, then I infer its not an LLVM specific thing.

centril (Mar 12 2020 at 20:58, on Zulip):

simulacrum said:

Also, am I wrong, or is instruction_set not actually spec dependence on LLVM? i.e. the details on what it means are entirely "open" and not tied to LLVM specific details?

Well if it is not a hint, then it compells other backends to expose a way to also achieve the behavior (unless it's an error on those backends)

pnkfelix (Mar 12 2020 at 20:59, on Zulip):

(And it is rather an ARM architecture thing. Maybe MIPS as well; need to double check the conversation there.)

pnkfelix (Mar 12 2020 at 20:59, on Zulip):

The whole magic dispatch based on the low order bit sounds very target specific

simulacrum (Mar 12 2020 at 20:59, on Zulip):

My point is that I can understand being against LLVM-specific details finding their way into our spec -- but I'm pretty fine with saying "we accept this feature, with the implication that yes, any backend that wants to be a Rust backend, will need to support it"

centril (Mar 12 2020 at 20:59, on Zulip):

pnkfelix said:

(and it might also be in conflict with our goal of "parity with C" ... depending on what that means ...)

This sorta makes me wary of "party with C" as a goal. At least in the way I think it is being used ("parity with various non-standard GCC extensions"); and I think that comes with a huge amount of ad-hoc complexity to the language.

simulacrum (Mar 12 2020 at 21:00, on Zulip):

Is that your stance as well @centril ?

centril (Mar 12 2020 at 21:01, on Zulip):

@simulacrum depends; you can phrase things LLVM supports in such a way that the backend must look very LLVM-ish

centril (Mar 12 2020 at 21:01, on Zulip):

and making too many requirements on a backend can also be a problem

centril (Mar 12 2020 at 21:01, on Zulip):

but highly LLVM-specific things would be worse

simulacrum (Mar 12 2020 at 21:02, on Zulip):

...Yes? But you agree that we can have things that today are implemented only in LLVM (and not, for example, cranelift), without even necessarily the cranelift developers saying "we will do this"

simulacrum (Mar 12 2020 at 21:02, on Zulip):

or do you feel that we need to okay features affecting codegen with cranelft development?

centril (Mar 12 2020 at 21:02, on Zulip):

Not in general, I don't agree.

centril (Mar 12 2020 at 21:03, on Zulip):

It depends on the feature, but I think cranelift should be consulted

simulacrum (Mar 12 2020 at 21:03, on Zulip):

I don't mean in general. I mean features that are not LLVM specific (e.g., instruction set, I imagine there's dozens of others), but do need backend support.

centril (Mar 12 2020 at 21:04, on Zulip):

@simulacrum that would be e.g. a backend feature that both gcc and llvm support, for example?

simulacrum (Mar 12 2020 at 21:04, on Zulip):

For example, sure.

centril (Mar 12 2020 at 21:04, on Zulip):

Same answer then

centril (Mar 12 2020 at 21:04, on Zulip):

In practical terms it means relying on LLVM specifics, as we don't have another backend

simulacrum (Mar 12 2020 at 21:04, on Zulip):

(e.g., something supported across MSVC/GCC/LLVM, but not yet in cranelift, with a solid spec not tied to the internals of those impls)

simulacrum (Mar 12 2020 at 21:05, on Zulip):

imo, I think we should accept features that have that reach and not block on cranelft agreeing to it

simulacrum (Mar 12 2020 at 21:05, on Zulip):

(modulo us wanting that feature, of course)

centril (Mar 12 2020 at 21:06, on Zulip):

I think this is starting to get rather hypothetical and feature specific so I don't want to answer the question in its generality

simulacrum (Mar 12 2020 at 21:06, on Zulip):

I mean, I definitely don't expect to quote you later and say "but you felt this way" -- I'm just trying to get a read of your position on this

simulacrum (Mar 12 2020 at 21:07, on Zulip):

(and maybe your position is that you don't want to make any general statement at all because you feel that each feature is sufficiently unique. I disagree, but that's fine :)

centril (Mar 12 2020 at 21:08, on Zulip):

hehe :slight_smile:
Well, depending on how solid the spec is and how much it ties us to things looking like LLVM, etc. I might feel differently.
At any rate, I think at minimum, talking to the cranelift people is at least a courteous and polite thing to do.

centril (Mar 12 2020 at 21:08, on Zulip):

We shouldn't be surprising them with stuff

simulacrum (Mar 12 2020 at 21:08, on Zulip):

Certainly I think it would be helpful to have a read on whether a backend like cranelift could implement it -- that helps provide us context on how well written the spec is and how truly "cross backend" it is

centril (Mar 12 2020 at 21:09, on Zulip):

Yep

simulacrum (Mar 12 2020 at 21:09, on Zulip):

but I would be against blocking instruction_set or other features on an implementation in cranelift existing

pnkfelix (Mar 12 2020 at 21:09, on Zulip):

Thinking more about Lokathor's comment regarding whether this "cannot' be a hint.. I wonder if we would be best served with two attributes: One that is a best-effort hint, and another that causes a compile-time failure if the backend doesn't support the requested setting.

simulacrum (Mar 12 2020 at 21:10, on Zulip):

@pnkfelix my impression was that most use cases for this really can't be a hint because the thing you're doing inside the function is dependent on that instruction set (e.g., inline assembly)

pnkfelix (Mar 12 2020 at 21:10, on Zulip):

(at least, it seems like the discussion so far implies that we would need to choose between those two options. But maybe that choice is better left to the fn-implementer, depending on whether the request is indeed a mere optimization vs inline assembly.)

pnkfelix (Mar 12 2020 at 21:11, on Zulip):

Right, I understand that there are plenty of cases where it really does need to hard error

centril (Mar 12 2020 at 21:12, on Zulip):

(Well my inference re. interactions with inline asm is that this is an argument against inline asm... but let's not dive into that here)

pnkfelix (Mar 12 2020 at 21:12, on Zulip):

but when we talk about categorizing this under the umbrella of optimize, then that to me falls more into the category of "best effort attempt to use the more compact instruction set"

centril (Mar 12 2020 at 21:13, on Zulip):

@pnkfelix right, that feels like @nikomatsakis's preferred outcome

centril (Mar 12 2020 at 21:14, on Zulip):

simulacrum said:

but I would be against blocking instruction_set or other features on an implementation in cranelift existing

I think we have a difference of opinion here. :slight_smile:

simulacrum (Mar 12 2020 at 21:14, on Zulip):

I agree :)

simulacrum (Mar 12 2020 at 21:15, on Zulip):

I wonder if the middle ground is a optimize-like attribute, and then a intrinsic (stabilized, I guess) which says "you're in this instruction mode" -- the idea being that if you really need it you can do if !is_small() { panic!("..."); } or something like that

centril (Mar 12 2020 at 21:15, on Zulip):

Anyways... Dinner awaits, so I bid y'all adieu for now :egg: :bread:

simulacrum (Mar 12 2020 at 21:15, on Zulip):

that at least sort of forces people to handle it at runtime

simulacrum (Mar 12 2020 at 21:16, on Zulip):

(though arguably that's perhaps worse than a compile time error, so I'm not sure)

nikomatsakis (Mar 12 2020 at 21:16, on Zulip):

Thinking about backends a bit more

nikomatsakis (Mar 12 2020 at 21:16, on Zulip):

It seems obvious that cranelift won't be able to support all targets

nikomatsakis (Mar 12 2020 at 21:16, on Zulip):

centril said:

As for LLVM specifically, I am wary of our dependence on it... I am wary of being at the mercy of C++ and LLVM's priorities (esp. wrt. soundness, compile times).
If features that a lot of users use can only be used on LLVM, then it means that any alternative backend is a second class citizen, and won't really be used.

I found this comment helpful to understand better where @centril is coming from

nikomatsakis (Mar 12 2020 at 21:17, on Zulip):

I guess what I was most hoping to get out of this conversation was not an "answer"

simulacrum (Mar 12 2020 at 21:17, on Zulip):

Yes, I found this helpful as well -- and indeed agree with it.

nikomatsakis (Mar 12 2020 at 21:17, on Zulip):

but a better feeling for what the "concerns" are and factors we might consider

nikomatsakis (Mar 12 2020 at 21:18, on Zulip):

It does seem good to me to ponder "how hard is it for backends like cranelift to support this", for example.

nikomatsakis (Mar 12 2020 at 21:19, on Zulip):

That said, i'm not sure I agree with the premise that cranelift would be a "second class citizen" if it can't support features like #[instruction_set]. I think that is one outcome, but I could also imagine pushback on using those features if the cranelift backend is sufficiently better (e.g. faster). I could also imagine someone just extending cranelift with that feature :)

nikomatsakis (Mar 12 2020 at 21:20, on Zulip):

probably the bigger concern is stuff like debuginfo etc

nikomatsakis (Mar 12 2020 at 21:20, on Zulip):

but that's clearly table stakes :)

simulacrum (Mar 12 2020 at 21:20, on Zulip):

I think this is why my opinion settles mostly on it being possible if hard to implement -- where possible to me essentially means "you can go read some website/PDF/or something" and not "you have to read LLVM's impl" basically

simulacrum (Mar 12 2020 at 21:21, on Zulip):

e.g. for debuginfo there's a DWARF standard, and while someone implementing may look for reference at what is done "in practice" it's not actually required that they do so

Lokathor (Mar 12 2020 at 22:28, on Zulip):

Hello all.

Lokathor (Mar 12 2020 at 22:31, on Zulip):

So let me see if i can help clear up some stuff.

for Cranelift to support this and the initial a32/t32 support it would need:
, the ability to generate a32 code, which is already necessary to support arm target triples
, the ability to generate t32 code, which is already necessary to support thumb target triples
, knowing to call the linker with the extra flag

Lokathor (Mar 12 2020 at 22:33, on Zulip):

That is it really

Lokathor (Mar 12 2020 at 22:34, on Zulip):

Currently Cranelift supports nothing at all in the ARM family, but if it adds support for those two codegen types then the instruction_set attribute essentially just falls out of it as a consequence

Lokathor (Mar 12 2020 at 23:03, on Zulip):

Also, I would like to stress again that this is not a hint. Some hardware will have function pointers you can assign via MMIO and then the firmware will jump to that function and the function must be in the correct code format or it's UB.

Lokathor (Mar 12 2020 at 23:04, on Zulip):

So, in the same way that you probably wouldn't accept if a wasm backend just gave up some of the time and insterted x86_64 code instead, it would be unacceptable to have the wrong codegen with this attribute.

Lokathor (Mar 12 2020 at 23:05, on Zulip):

It's perfectly fine for the backend to just error and say it can't support the requested operation of course.

Lokathor (Mar 12 2020 at 23:05, on Zulip):

but it can't silently decode to do something else

Josh Triplett (Mar 12 2020 at 23:10, on Zulip):

nikomatsakis said:

I feel like my preferred outcome is that #[instruction_set] is considered a hint, and that it works uniformly across all backends (perhaps with a warning on cranelift or something if it's unsupported).

instruction_set is not a hint, it's potentially required for correctness, for multiple reasons. Cranelift is going to need to support Thumb at some point. In the meantime, I think it's perfectly reasonable for it to emit an error stating that it isn't supported.

Josh Triplett (Mar 12 2020 at 23:11, on Zulip):

nikomatsakis said:

Overall I guess I am worried about some kind of rule that says "everything must be easily supported by any 'ordinary' backend" -- it seems like it will limit us from taking full advantage of LLVM.

Agreed completely. We are not a magical portability layer that must abstract over every possible difference between targets, and we certainly shouldn't force a lowest common denominator. We should take full advantage of a target when doing so provides value.

Josh Triplett (Mar 12 2020 at 23:17, on Zulip):

centril said:

I don't think it's bad personally; I don't think we should be making too many demands on a backend, to the point that making one becomes unreasonably hard, and it might also create problems for future backends.

I feel precisely the opposite: we should hopefully, one day, be the force pushing our backends forward faster than C does, and providing access to interesting new functionality. At the very least, we should not be refusing to support existing functionality that our users need because of another backend that doesn't support it, let alone for a backend that we don't have yet.

Josh Triplett (Mar 12 2020 at 23:18, on Zulip):

centril said:

As for LLVM specifically, I am wary of our dependence on it... I am wary of being at the mercy of C++ and LLVM's priorities (esp. wrt. soundness, compile times).
If features that a lot of users use can only be used on LLVM, then it means that any alternative backend is a second class citizen, and won't really be used.

If we're not the ones pushing LLVM forward, then we are inherently at the mercy of their priorities. We can't have it both ways: either we're on the leading edge or we take what we get from the languages that are.
And it isn't up to us to determine whether an alternative backend is "second-class" or not; that's up to the features of the backend. We should not choose to make every backend "second-class" so that none of them are.

Josh Triplett (Mar 12 2020 at 23:19, on Zulip):

centril said:

simulacrum said:

Also, am I wrong, or is instruction_set not actually spec dependence on LLVM? i.e. the details on what it means are entirely "open" and not tied to LLVM specific details?

Well if it is not a hint, then it compells other backends to expose a way to also achieve the behavior (unless it's an error on those backends)

Either of those is acceptable. Either it works, or it gives an error saying it can't work. (If people want their code to work on that backend, they can either avoid that feature, use cfg, or fix the backend.

Josh Triplett (Mar 12 2020 at 23:20, on Zulip):

pnkfelix said:

(And it is rather an ARM architecture thing. Maybe MIPS as well; need to double check the conversation there.)

MIPS has mips16 with very similar properties.

Josh Triplett (Mar 12 2020 at 23:22, on Zulip):

centril said:

but highly LLVM-specific things would be worse

For the record, this I agree with: we shouldn't unnecessarily tie our implementation to LLVM's if there's no good reason to do so. Witness the major effort we're going through to make our inline assembly syntax safer and simpler than LLVM's, and no longer subject to LLVM's ICE-producing limitations. We should specify features in a way that any backend could theoretically support. But we shouldn't refuse to specify a feature just because a backend doesn't support it.

centril (Apr 09 2020 at 07:00, on Zulip):

Josh Triplett said:

nikomatsakis said:

Overall I guess I am worried about some kind of rule that says "everything must be easily supported by any 'ordinary' backend" -- it seems like it will limit us from taking full advantage of LLVM.

Agreed completely. We are not a magical portability layer that must abstract over every possible difference between targets, and we certainly shouldn't force a lowest common denominator. We should take full advantage of a target when doing so provides value.

I don't know what "magical" means here. However, in my view, a general-purpose high-level language like Rust is supposed to be a "portability layer" atop of the platform as that too provides value. It is reasonable to, and we do provide platform-specific functionality as well, but at a certain point, Rust is the wrong abstraction layer.

Josh Triplett said:

centril said:

I don't think it's bad personally; I don't think we should be making too many demands on a backend, to the point that making one becomes unreasonably hard, and it might also create problems for future backends.

I feel precisely the opposite: we should hopefully, one day, be the force pushing our backends forward faster than C does, and providing access to interesting new functionality. At the very least, we should not be refusing to support existing functionality that our users need because of another backend that doesn't support it, let alone for a backend that we don't have yet.

I think that depends on how widely applicable some addition requiring backend changes are wrt. "interesting new functionality" (usually this means more ad-hoc knobs in my experience). Making it too hard to implement a backend for Rust does in my view make us dependent on the limited set of backends we have. Also, I believe there will be a real effort to push us towards a Cranelift backend, which we had a compiler-team design meeting about recently.

Josh Triplett said:

centril said:

As for LLVM specifically, I am wary of our dependence on it... I am wary of being at the mercy of C++ and LLVM's priorities (esp. wrt. soundness, compile times).
If features that a lot of users use can only be used on LLVM, then it means that any alternative backend is a second class citizen, and won't really be used.

If we're not the ones pushing LLVM forward, then we are inherently at the mercy of their priorities. We can't have it both ways: either we're on the leading edge or we take what we get from the languages that are.
And it isn't up to us to determine whether an alternative backend is "second-class" or not; that's up to the features of the backend. We should not choose to make every backend "second-class" so that none of them are.

LLVM caters to C++, in my view, because that's what it was made for and because C++ has more users, not because C++ is supposedly pushing LLVM forward in terms of special knobs, which I personally believe most users don't use and don't know about. Also, many changes to LLVM have nothing to do with additional knobs that languages using LLVM expose. Rather, they include optimizations that get applied automatically and new forms of IR we can emit for better codegen.

I don't follow how it is not up to us to decide what minimal and maximal constraints we put on backends; that seems entirely up to us.

The argument that we would render every backend "second-class" resembles in my view "under X, everyone is equally poor", but second-class is a relative notion and is meaningless in the absolute.

Josh Triplett said:

centril said:

simulacrum said:

Also, am I wrong, or is instruction_set not actually spec dependence on LLVM? i.e. the details on what it means are entirely "open" and not tied to LLVM specific details?

Well if it is not a hint, then it compells other backends to expose a way to also achieve the behavior (unless it's an error on those backends)

Either of those is acceptable. Either it works, or it gives an error saying it can't work. (If people want their code to work on that backend, they can either avoid that feature, use cfg, or fix the backend.

I'm not sure if you mean it that way, probably not, but "fix" suggests there's something wrong with the backend, but there might be perfectly good reasons why a backend does not want to support a certain feature, as it could be detrimental to other aspects of the backend. I think it's perfectly acceptable to weigh the detriment to portability in rendering certain backends "second class" vs. the benefits a certain feature comes with. How that will stack up in a particular case will depend on the specifics there.

Josh Triplett said:

centril said:

but highly LLVM-specific things would be worse

[...] We should specify features in a way that any backend could theoretically support. But we shouldn't refuse to specify a feature just because a backend doesn't support it.

There are of course considerations beyond just the backend in accepting or rejecting a feature, but sticking just to the backend, I think "theoretically" is not enough; the constraints should not be set up in such a way that an implementation is only possible in principle but not in practice -- that would not be useful.

Lokathor (Apr 09 2020 at 07:35, on Zulip):

But "it's an error" was deemed acceptable.

Last update: Jun 05 2020 at 23:10UTC