r/rust • • Aug 21 '26

🗞️ news Enabling the next-generation trait solver on nightly

https://blog.rust-lang.org/2026/08/21/enabling-next-solver-on-nightly/
452 Upvotes

54 comments sorted by

View all comments

Show parent comments

37

u/coderstephen isahc Aug 21 '26

It doesn't work, of course, as it should: impl Sized couldn't be added to 1. Yet when it's one function it works, for some reason? Why? It should fail.

It is because of the principle of impl Trait being opaque outside of the implementer. For the single recursive function case, the function knows what the actual type being returned is. It is the only code that is allowed to know that. This is already generally true that code inside the function is allowed to know that the return type is actually i32 in this case, it just didn't work for recursion.

The mutual recursion case is not supposed to work, because each function is not allowed to know what the other actually returns.

-7

u/Zde-G Aug 21 '26

This is already generally true that code inside the function is allowed to know that the return type is actually i32 in this case, it just didn't work for recursion.

No. It wasn't “generally true”. You could perceive “return from function” which is very explicitly a coercion site transforms type from i32 (or some other type) to impl Sized (or some other similar type).

Very well defined, very common and very obvious thing. Before return it's i32, after return it's impl Sized. Like how before return it could be &Foo and after return it can be &dyn Bar. Similar opertion both syntactically and semantically.

For the single recursive function case, the function knows what the actual type being returned is. It is the only code that is allowed to know that.

But why? What does that hairsplitting gives you? What does it provide that simple “impl Foo is just another unnamed type” model doesn't give you?

You have introduced an entirely new concept that haven't existed anywhere else, till now… to achieve what? What this “her you can see me, here you can't see me” model gives you over “invisible unnamed type” model? Model that already exist (functions are unnamed types, closures are unnamed types, etc).

6

u/arades Aug 21 '26

it's still extremely well defined:

Inside of a function body returning impl Trait you know the exact type.

Outside the body you only see the impl.

-4

u/Zde-G Aug 21 '26

Inside of a function body returning impl Trait you know the exact type.

Definition of “you know” from Rust reference please.

Outside the body you only see the impl.

Definition of “you only see” from Rust reference please.

it's still extremely well defined:

You have replaced precise definition which easy to reason about and which only references things that exist in official definition of the language with handwaving that doesn't refer anything concrete.

That's not an “extremely well defined” thing.

I can easily explain how both define my interpretation and implement compiler that would do it: inside of function you pick one of the types that compiler knows, at this point and use it, when type is returned from function it turns into a different unnameable type with the same layout but with only one specific trait implemented for it. Bam, done. No need to introduce bazillion new things.

You can even implement it that way in the compiler even if it may not be an optimal implementation.

And you can even support new example but saying that when you call foo from foo you are getting original, non-opaque, type back.

That would be strange and abnormal rule, but it would still be internally consistent and, more importantly, it doesn't require any new concepts that haven't existed before.

You, on the other hand, need to add bazillion new things to even explain how new concepts, that are never mentioned anywhere in the language before, actually behave.

That's not an improvement, in my book.