Skip to content

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

Closed
@bblum

Description

@bblum

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().

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-grammarArea: The grammar of RustA-type-systemArea: Type systemC-enhancementCategory: An issue proposing an enhancement or a PR with one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions