-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
support default impl
for specialization
#37653
Comments
#37653 support `default impl` for specialization this commit implements the first step of the `default impl` feature: > all items in a `default impl` are (implicitly) `default` and hence > specializable. In order to test this feature I've copied all the tests provided for the `default` method implementation (in run-pass/specialization and compile-fail/specialization directories) and moved the `default` keyword from the item to the impl. See [referenced](#37653) issue for further info r? @aturon
@nikomatsakis |
@giannicic awesome! |
Any progress on this? |
@Phlosioneer
a call like |
Can inherent impls be default? This currently compiles successfully, but the compiler has zero tests for it, so it's probably unintended. #![feature(specialization)]
struct S;
default impl S {}
fn main() {} The general idea is reasonable though, e.g. struct S<T>(T);
default impl<T> S<T> { fn f() { println!("Hello world!") } }
impl S<u8> { fn f() { println!("Goodbye world!") } } // This currently errors |
Can auto trait impls (including negative ones) be default? This is currently accepted: struct S;
struct Z;
default unsafe impl Send for S {}
default impl !Send for Z {} |
#46455 conservatively makes both #37653 (comment) and #37653 (comment) errors. |
Really excited for full support of specialization (esp. point 2)! +1 |
@petrochenkov |
syntax: Rewrite parsing of impls Properly parse impls for the never type `!` Recover from missing `for` in `impl Trait for Type` Prohibit inherent default impls and default impls of auto traits (#37653 (comment), #37653 (comment)) Change wording in more diagnostics to use "auto traits" Fix some spans in diagnostics Some other minor code cleanups in the parser Disambiguate generics and qualified paths in impls (parse `impl <Type as Trait>::AssocTy { ... }`) Replace the future-compatibility hack from #38268 with actually parsing generic parameters Add a test for #46438
#37653 support `default impl` for specialization this commit implements the second part of the `default impl` feature: > - a `default impl` need not include all items from the trait > - a `default impl` alone does not mean that a type implements the trait The first point allows rustc to compile and run something like this: ``` trait Foo { fn foo_one(&self) -> &'static str; fn foo_two(&self) -> &'static str; } default impl<T> Foo for T { fn foo_one(&self) -> &'static str { "generic" } } struct MyStruct; fn main() { assert!(MyStruct.foo_one() == "generic"); } ``` but it shows a proper error if trying to call `MyStruct.foo_two()` The second point allows a `default impl` to be considered as not implementing the `Trait` if it doesn't implement all the trait items. The tests provided (in the compile-fail section) should cover all the possible trait resolutions. Let me know if some tests is missed. See [referenced ](#37653) issue for further info r? @nikomatsakis
As seen in the PR #45404, many people are confused about the syntax. The author of #45404, the author of #44790, the author of Perhaps it is a good idea to propose a change to the syntax? For example resurrecting the |
I don't think it's confusing, I think it just needs to be documented in the error messages of default impl. For example, in the parquet-rs error, the confusion would go away with a help message:
Which would make the full error:
I think that does a really good job of not only pointing out the mistake with relevant info, but also teaching the user why it's an error and how it can be fixed. @nikomatsakis @giannicic Pinging because of your work on #45404 Edit: formatting. |
I am torn. On the one hand, I liked the "economy" of using |
Personally, I was slightly confused as to why |
I think this is a serious limitation, because it means there is no way to have a partial impl where some items are not specializable. I do not see that limitation discussed in the RFC, nor a motivation for why it might be required. It's a big RFC though, so maybe I missed it? Here is a short discussion with a use-case for a partial unspecializable impl. Basically the idea is to implement some associated types of the trait, and then provide some default implementations that require this particular choice of associated type. I think the current approach makes that kind of reuse fundamentally impossible. |
@RalfJung it was a deliberate simplification, but one that I'm still not 100% sure was the right call. The initial version of the RFC had |
@nikomatsakis I see. IMO that limitation should be lifted before stabilization, it's rather surprising and frustrating that what seems like a purely syntactic choice makes some interesting specialization use-cases fundamentally impossible. Having Could we get this listed as a concern to revisit in some tracking issue, maybe here? |
@RalfJung I'd be willing to revisit this prior to stabilization, yes. |
Actually, @RalfJung, it's already listed:
|
Oh, I was checking the items in this issue but not the main one. oops |
Will it be possible to define different default impls for differently trait bounded type parameters? e.g. default impl<A: ToRoute> Routable for A {
type Route = <A as ToRoute>::Route;
fn route(&self) -> Self::Route {
self.to_route()
}
}
default impl<B: ToString> Routable for B {
type Route = DefaultRoute;
fn route(&self) -> Self::Route {
DefaultRoute::from(self.to_string())
}
} In case of |
I posted a suggestion on |
@joergbrech I think you would be interested in the future possibilities section of RFC 2532 (associated type defaults). |
@jplatte, thanks for the link. Yes default groups would be much more flexible! |
rust-lang/rfcs#1210 included support for
default impl
, which declared a set of defaults that other impls can inherit (if they correspond to a subset of the default impl's types). This was intended as a replacement/improvement of the existing default methods that appear in trait bodies (it was also originally calledpartial impl
). Unfortunately, this feature is not yet implemented!Some things to be sure of:
default impl
need not include all items from the traitdefault impl
alone does not mean that a type implements the traitdefault impl
are (implicitly)default
and hence specializablecc #31844
The text was updated successfully, but these errors were encountered: