Skip to content
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

RFC: Default trait kind-bounds based on sigil #7264

Closed
bblum opened this issue Jun 20, 2013 · 6 comments
Closed

RFC: Default trait kind-bounds based on sigil #7264

bblum opened this issue Jun 20, 2013 · 6 comments
Labels
A-grammar Area: The grammar of Rust A-typesystem Area: The type system C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@bblum
Copy link
Contributor

bblum commented Jun 20, 2013

I am working on #3569, and there has arisen a question of reasonable defaults. The question is exactly the same for traits as for closures, so WLOG I'll use closures as an example.

Part of the motivation is to be able to capture non-Owned and/or borrowed (non-static) things in ~fn() and @fn() closures. So, what today is written ~fn() and @fn() will in the future mean the same as ~fn:Owned() and @fn:'static().

But I anticipate the "implied bounds" we have today being far and away the most common use cases even when you can specify your own bounds (e.g., you wanna be able to use heap fns/traits as return types)... and it might be a pain to need to write ~fn:Owned() and @fn:'static() all the time. As much as I like the type grammar to be principled, I'm sitting on a diff that makes this change across libs std, extra, syntax, and rustc, and it's 73 files large.

So my proposal is if you don't write a bounds list at all, the default bounds are used, and if you want to override that, you have to write an empty bounds list ("~fn:()"). I figure the defaults will be dependent on the pointer sigil; Niko also suggested having 'static be the default for all of them, but neither of us like that. So, here is a table which shows what the function types will look like in each proposed scheme.

                            (proposed)
today       principled      defaults-by-sigil   defaults-all-same
------------------------------------------------------------------
&fn()       &fn()           &fn()               &fn:()
~fn()       ~fn:Owned()     ~fn()               ~fn:Owned()
            ~fn()           ~fn:()              ~fn:()
@fn()       @fn:'static()   @fn()               @fn()
            @fn()           @fn:()              @fn:()

The potential downside of the defaults-by-sigil plan is that if you write something like ~fn:Const(), it may be surprising that that doesn't mean the same as ~fn:Const+Owned().

One final option that I didn't show on the table is just to always keep the "default" bound, so you couldn't capture borrowed pointers in heap fns/traits, but you could further limit the environment with more bounds. So you couldn't write ~fn:() and capture a & or @-pointer, but ~fn:Const() would mean the same as ~fn:Const+Owned().

@bblum
Copy link
Contributor Author

bblum commented Jun 20, 2013

There is also a further question of whether the default should stay if you write a different bound; for example, should @fn:Const additionally imply 'static, or should you have to write @fn:'static+Const for that? I think the latter is the better choice, because while you can usually remove 'static by writing a different lifetime, you couldn't do the corresponding thing with ~fn:Const() if you wanted to have a not-owned-but-const ~-closure.

@bblum
Copy link
Contributor Author

bblum commented Jun 20, 2013

With traits instead of closures, you end up looking like ~Object: for a trait with no bounds. I don't think this creates a parse ambiguity...

@graydon
Copy link
Contributor

graydon commented Jun 21, 2013

I think I'm ok with defaults-by-sigil, and I think .. I actually don't mind defailts-all-same. Depends if we wind up keeping closures that copy stuff into their environment. As an aside: if I want to pass a &Trait into a function and I want it to have region-pointers of a narrower lifetime than 'static, what are my odds of that working?

I don't have a strong feeling on this. It's a tension between orthogonality and non-verbosity.

@bblum
Copy link
Contributor Author

bblum commented Jun 21, 2013

Odds of that working are high, pending correct codegen for &Trait of course. With defaults-by-sigil or no defaults ("principled"), it would automatically work with &Trait, unless you needed to tie the lifetime to something else, in which case &Trait:'r (not really sure how that would be different from &'r Trait). With defaults-all-same ('static), you'd write &Trait:'r always.

@bblum
Copy link
Contributor Author

bblum commented Jun 25, 2013

This works ok with dynamically-sized types too. Instead of looking at the "trait store" (the glued-on sigil), you'd case on the thing surrounding the type. If it's a ~, then use Owned; if it's a &, then use no bounds; if it's @ or it's something else (e.g., it's sitting at the end of a struct), then use 'static. This combines nicely with the transition to library types for GC pointers -- @Gc Trait would expand to Gc<Trait>, which would get 'static.

@bblum
Copy link
Contributor Author

bblum commented Jul 3, 2013

This is done.

@bblum bblum closed this as completed Jul 3, 2013
@bblum bblum removed their assignment Jun 16, 2014
flip1995 pushed a commit to flip1995/rust that referenced this issue Jun 3, 2021
…_trait, r=llogiq

Fix invalid syntax in `from_iter_instead_of_collect` suggestion

First attempt at contributing, hopefully this is a good start and can be improved. :)

fixes rust-lang#7259

changelog: [`from_iter_instead_of_collect`] fix invalid suggestion involving "as Trait"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-grammar Area: The grammar of Rust A-typesystem Area: The type system C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

2 participants