Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAllow overlapping implementations for marker traits #1268
Conversation
This comment has been minimized.
This comment has been minimized.
|
The currently presented version of specialization won't allow this. Your proposal is basically lattice impls for marker traits. |
nrc
added
the
T-lang
label
Sep 3, 2015
aturon
self-assigned this
Sep 3, 2015
sgrif
added a commit
to diesel-rs/diesel
that referenced
this pull request
Sep 11, 2015
This comment has been minimized.
This comment has been minimized.
|
@sgrif First, sorry for the very overdue response; I'm behind on my RFC shepherding. Second: some improvements in this area would be most welcome. For example, the design I recently proposed for a trait here won't work without some adjustment to coherence for marker traits. Simply allowing overlap for marker traits (as proposed here) seems like a pure win. But I wonder if you've thought much about negative impls and potential overlap there? For example, in the comment I linked above, I propose something like: use std::cell::UnsafeCell;
trait ExnSafe {}
impl ExnSafe for .. {}
trait RefExnSafe {}
impl RefExnSafe for .. {}
impl<'a, T: RefExnSafe> ExnSafe for &'a T {}
impl<'a, T> !ExnSafe for &'a mut T {}
impl<T> !ExnSafe for UnsafeCell<T> {}
impl<T: 'static + Send> ExnSafe for T {}
// Imagine a variant of RefCell that did poisoning:
impl<T> ExnSafe for PoisoningRefCell<T> {}
struct AssertExnSafe<T>(T);
impl<T> ExnSafe for AssertExnSafe<T> {}
impl<T> Deref for AssertExnSafe<T> { ... }
impl<T> DerefMut for AssertExnSafe<T> { ... }
fn recover<F: FnOnce() -> R + ExnSafe, R>(f: F) -> thread::Result<R>which has potential for overlap between positive and negative cases. How should that work out? I've been thinking recently about a more flexible form of specialization, which @arielb1 calls "lattice impls". Whether we go that way or not, I think that we want to provide some way of resolving such ambiguities with specialization, and maybe that's the answer for these conflicts. Regardless, I don't see a lot of downside to moving forward with the simple case of "positive impl" overlap proposed here in the meantime! |
sgrif
added a commit
to diesel-rs/diesel
that referenced
this pull request
Sep 15, 2015
This comment has been minimized.
This comment has been minimized.
gereeter
commented
Sep 20, 2015
|
I'm not certain of what exact restrictions should be in place, but I'm strongly in favor of something like this as it would allow #91 to be implemented as a library. |
sgrif
added a commit
to diesel-rs/diesel
that referenced
this pull request
Sep 21, 2015
sgrif
added a commit
to diesel-rs/diesel
that referenced
this pull request
Sep 21, 2015
This comment has been minimized.
This comment has been minimized.
|
I hadn't thought too closely about negative impl overlap, but I started working on actually implementing this, and it turns out we do have an explicit test case which got me thinking about it, and illustrates it pretty well. I think the right answer here is to disallow any overlap between a negative impl and a positive impl (excluding |
sgrif
added a commit
to diesel-rs/diesel
that referenced
this pull request
Sep 30, 2015
sgrif
added a commit
to diesel-rs/diesel
that referenced
this pull request
Sep 30, 2015
sgrif
added a commit
to diesel-rs/diesel
that referenced
this pull request
Sep 30, 2015
sgrif
added a commit
to diesel-rs/diesel
that referenced
this pull request
Oct 7, 2015
This comment has been minimized.
This comment has been minimized.
|
We talked about this a bit at last week's lang team meeting, and I think everyone is on board, except for the definition of "marker trait". The consensus was that, for the purposes of this RFC, coherence rules should be relaxed for any trait that does not contain any items, regardless of what it inherits from. In particular, inheriting from a trait that happens to include items doesn't actually introduce coherence problems around the subtrait implementation. Can you update the RFC accordingly? Once you've done that, we can move to final comment period and try to land this. |
This comment has been minimized.
This comment has been minimized.
|
I've updated the RFC to use that definition of marker trait |
aturon
added
the
final-comment-period
label
Oct 9, 2015
This comment has been minimized.
This comment has been minimized.
|
This RFC is entering its Final Comment Period. |
This comment has been minimized.
This comment has been minimized.
I'm not sure of the right way to interpret this. As far as I can tell, empty traits with non-empty supertraits couldn't possibly have incoherent |
This comment has been minimized.
This comment has been minimized.
|
@glaebhoerl Yes; thanks for putting it much more clearly :) |
This comment has been minimized.
This comment has been minimized.
|
That said, I think you could actually implement a subtrait incoherently even without doing so for the supertrait (which may also be part of what you meant). Contrived example:
But this also seems fine. |
This comment has been minimized.
This comment has been minimized.
|
Was there an analysis of the interaction with the other parts of the type system, and with the interaction with the current implementation strategy (I think this would basically require the new trait system). |
This comment has been minimized.
This comment has been minimized.
|
@glaebhoerl Yes, that's what I'm trying to get at: supertraits are simply irrelevant when it comes to the coherence rules of a subtrait, because the impl blocks are separate; we can govern them by separate coherence rules. In particular, if a subtrait doesn't have any items, than there's nothing to be coherent about, which is of course what this RFC is getting at. Hence it makes sense for relaxed coherence rules to apply. @arielb1 Could you be slightly more concrete/specific? In terms of semantic interactions, this proposal doesn't seem problematic, given that the coherence property is basically vacuous in these cases. |
This comment has been minimized.
This comment has been minimized.
|
I want to find any surprises before, not after, this is stabilized, especially as I am not sure what is the best way to stabilize this. |
This comment has been minimized.
This comment has been minimized.
|
@arielb1 I'm definitely on board with that! But what I mean is, I'm not sure if you have any concrete worries in mind? Certainly both @nikomatsakis and I have given this RFC some thought in terms of semantic interactions and haven't turned up anything problematic, but you're often a little more devious, so maybe you see something fishy? |
This comment has been minimized.
This comment has been minimized.
|
Nothing particularly, except that I don't feel like we understand the current system well enough. On the other hand, this is both not stronger than lattice impls (which we may want), and feels to be semantically equivalent to fixing rust-lang/rust#27544, which we (probably) want to. |
This comment has been minimized.
This comment has been minimized.
|
For example, there was the OIBIT = negative impls interaction. |
This comment has been minimized.
This comment has been minimized.
|
One thing that worries me is that we could have non-deterministic effects about which impl gets used when inference, particularly region inference, is involved. impl<'a, 'b> Marker<'a> for &'b T {}
impl<'a> Marker<'a> for T where T: 'a {} |
This comment has been minimized.
This comment has been minimized.
|
In discussion in the lang-team meeting |
This comment has been minimized.
This comment has been minimized.
|
So I've been thinking this over. Certainly the implementation strategy is a bit unclear (as @arielb1 hinted at earlier). Simply lifting the coherence restrictions is easy enough, but we will encounter some challenges when we come to test whether a given trait impl holds. For example, if we have something like: impl<T:Send> MarkerTrait for T { }
impl<T:Sync> MarkerTrait for T { }means that a type This is not necessarily a reason not to accept this RFC, but it is a reason to tread cautiously. I've also encountered similar situations when exploring possible extensions to the specialization RFC. Similar problems arise due to where-clauses/projections (e.g. rust-lang/rust#20297) and also regions (e.g., rust-lang/rust#21974). So I definitely would like to make progress here on improving our impl and search strategy in general. |
This comment has been minimized.
This comment has been minimized.
|
Another point which arose is that the actual motivation for this RFC is somewhat thin. I feel like I can recall various examples where this has arisen in the past, but it'd be nice to document some of them better. Certainly Gabhor's transmute proposal #91 (as @gereeter pointed out) is an example. I suppose |
This comment has been minimized.
This comment has been minimized.
|
Huzzah! The language design subteam has decided to accept this RFC. I plan to add a small note to the motivation concern the |
nikomatsakis
added a commit
to nikomatsakis/rfcs
that referenced
this pull request
Nov 16, 2015
nikomatsakis
referenced this pull request
Nov 16, 2015
Open
Tracking issue for allowing overlapping implementations for marker trait #29864
nikomatsakis
added a commit
to nikomatsakis/rfcs
that referenced
this pull request
Nov 16, 2015
This comment has been minimized.
This comment has been minimized.
|
Tracking issue is rust-lang/rust#29864 |
This comment has been minimized.
This comment has been minimized.
|
Thanks! Sorry for the delay on following up |
nikomatsakis
added a commit
that referenced
this pull request
Nov 17, 2015
nikomatsakis
added a commit
that referenced
this pull request
Nov 17, 2015
This comment has been minimized.
This comment has been minimized.
|
I accidentally rebased when I landed this, so I am going to close the PR manually. |
nikomatsakis
closed this
Nov 17, 2015
sgrif
deleted the
sgrif:sg-overlapping-impls
branch
Nov 18, 2015
sgrif
added a commit
to sgrif/rfcs
that referenced
this pull request
Apr 30, 2016
sgrif
added a commit
to sgrif/rfcs
that referenced
this pull request
Apr 30, 2016
sgrif
added a commit
to sgrif/rfcs
that referenced
this pull request
Apr 30, 2016
sgrif
added a commit
to sgrif/rfcs
that referenced
this pull request
Apr 30, 2016
aturon
added a commit
that referenced
this pull request
Jul 26, 2016
burdges
referenced this pull request
Dec 13, 2016
Open
Crates should allow private impl of external traits for external structs #493
scottmcm
referenced this pull request
Aug 26, 2018
Merged
Support an explicit annotation for marker traits #53693
bors
added a commit
to rust-lang/rust
that referenced
this pull request
Sep 25, 2018
This comment has been minimized.
This comment has been minimized.
derekdreery
commented
Oct 4, 2018
|
Could you update the link at the top now it's been merged |
This comment has been minimized.
This comment has been minimized.
|
Done. |
This comment has been minimized.
This comment has been minimized.
derekdreery
commented
Oct 4, 2018
|
Thanks very much :D |
sgrif commentedSep 2, 2015
•
edited by Centril
rendered