-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
todo! and unimplemented! does not work with impl Trait return types #69882
Comments
This is expected behavior since |
Given that 4 bugs have been opened in such a short period of time for the same reason, I don't think that a wontfix, works as intented is the right approach. At minimum an alternative should be provided in the help message from the compiler, but I personnaly think that |
rust/src/librustc_interface/util.rs Lines 587 to 594 in 567ad74
|
Reopening this to have a canonical issue to direct people to. This is still working as expected for the moment though. |
Actually, let's classify this as a diagnostics enhancement |
Is there any suggested work-around for this? It sure seems like the bottom type ought (by definition) to type-check as anything, but as a practical matter, is there any placeholder at all that can be used as a return value from an unimplemented function whose signature demands an impl trait? |
@jeffs in the general case, no, because there could be no type that implements the trait: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=beb24c95bf6be2a8b48f6381c2b7ad6d |
I don't get what the example shows; you can add |
It shows that it's impossible to return a placeholder type because there might not be a type that impls the trait. |
|
No that wouldn't be enough. The trait might also have associated types or constants, which would have to be implemented as well. |
Error message could definitely be improved. Currently this code: trait Trait {}
fn magic() -> impl Trait {
panic!()
} Results in
Which is really confusing. Using
Why is it not shown in the first case? |
I want to fix this. Unfortunately if you had an I could try to just fix the diagnostic, but it feels like just piling on hacks (the fact that this works if My preferred solution would be to just always error like in the vec case |
A concrete example that would be unsound or at least ICE the compiler is https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ea0e808536f4373dc7be9f002159fa1d If we just didn't register any hidden type, the If we used This gets worse when we'll have type alias impl trait, as then you can directly name the opaque type and access associated items directly without jumping through hoops like in my playground. We could special case |
I just hit this. It makes it impossible to stub out anything that returns |
If you know a type that satisfies the trait bounds you can use I mean... in theory we could just pick a random type automatically that satisfies the trait, but then someone would start relying on this and we have enough problems with things like the one-impl-rule which are a similar situation |
Idea: we could make the error have a suggestion that suggests casting the This way we don't create more language corner cases and allow you to fix all those todos with |
Currently such a cast gets flagged as unreachable (technically correct) so either that lint needs to get tweaked or the suggestion also needs to include a well-placed |
Yeah, I get this, but during the initial sketching, you don't have any implementations. In an API-first design, there's nothing but the trait until the API has been sketched. So needing to stub the whole thing out with noop impls to stub any of it out is a massive pain. Perhaps this is a "wrong problem" problem, and maybe instead there's a concept of "an unimplemented type" that's a bit like unimplemented code? Like a middle ground between "the type exists and is FOO" and "there is no type FOO", that's "There is no type FOO yet, but if there was, ...". And at some point in the compilation chain, the compilation would bail with "unimplemented types", but at least you'd be able to typecheck through them? This is probably a horrible idea for various reasons that I've not thought through. Sorry not to be more help. |
I just hit this issue also. In my case my trait has a blocking run() method and a run_async() method. I wanted to provide an unimplemented default for each, so that trait implementor's ony need to impl appropriate run method, blocking or async. unimplemented!() works just fine in run(), but won't compile in run_async(). This forces the trait implementor to define a run_async() even if it won't be used. That works, but is ugly. I illustrate the above only to describe a real use-case where this limitation is problematic. |
This code
does not compile because
the trait
SomeTraitis not implemented for ()
But such code
compiles correctly. Can this problem be resolved to use both todo!() and impl Trait?
The text was updated successfully, but these errors were encountered: