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 upImplement UFCS (Tracking RFC 132) #16293
Comments
huonw
changed the title
UFCS (Tracking RFC 46)
Implement UFCS (Tracking RFC 46)
Aug 6, 2014
huonw
added
the
I-nominated
label
Aug 6, 2014
This comment has been minimized.
This comment has been minimized.
|
This is (expected to be a) backwards-compatible change, so while we do desire it, it is not a strict necessity for 1.0 Assigning P-high, not 1.0 milestone. |
pnkfelix
added
P-high
and removed
I-nominated
labels
Aug 7, 2014
huonw
added
the
B-RFC-approved
label
Aug 14, 2014
aturon
referenced this issue
Sep 11, 2014
Closed
Ability to specify self parameter in static method call #8888
nrc
self-assigned this
Oct 12, 2014
This comment has been minimized.
This comment has been minimized.
|
Question: in a trait or impl, should it be possible to call |
nrc
added a commit
to nrc/rust
that referenced
this issue
Oct 15, 2014
bors
added a commit
that referenced
this issue
Oct 15, 2014
pnkfelix
changed the title
Implement UFCS (Tracking RFC 46)
Implement UFCS (Tracking RFC 132)
Nov 13, 2014
oko
referenced this issue
Dec 3, 2014
Closed
Update trait static methods using `Self` to use UFCS once available in language #3
This comment has been minimized.
This comment has been minimized.
alexchandel
commented
Dec 18, 2014
|
Issue #8888 is still referenced by the Float trait, which contains |
eddyb
referenced this issue
Jan 13, 2015
Merged
[r+] Implement fully qualified UFCS expressions. #21077
bors
added a commit
that referenced
this issue
Jan 15, 2015
This comment has been minimized.
This comment has been minimized.
|
I've found a few consequences of the RFC that I haven't seen mentioned before, while trying to design a full implementation: struct Foo<T>;
mod bar {
impl super::Foo<()> { // impl allowed outside of Foo's module.
fn bar(&self) -> Option<()> { None }
}
}
impl Foo<bool> {
// same method name, allowed only because Self cannot overlap
// with any other impl with the same method (as with trait impls).
fn bar(&self) -> Option<bool> { Some(true) }
}
// anonymous impls would be checked by coherence as if they were
// implementing traits from outside the current crate.
impl<T> [Foo<T>] {
fn extra(&self) -> usize { 0 }
}
impl<T> Vec<Foo<T>> {
fn extra(&self) -> usize { self.capacity() - self.len() }
}All of these combined will end up removing some extension traits, and make type aliases much more powerful, without special-casing them. This will be possible, given we complete defaulted type params: // std::collections (the collections crate wouldn't have a clue about RNGs):
type HashMap<K, V, H = RandomizedSipHash> = collections_crate::HashMap<K, V, H>;On the other hand, // in libcore:
#[lang="i32"]
enum i32 {} // unihabited enum introduces a type in scope and nothing else
// coherence would allow this impl as the type is "rooted" in the crate
// defining the lang item.
impl i32 {
fn foo(self) -> ... {...}
}That would also make the rustdoc special handling for primitives a bit simpler. Then again, that last one isn't necessary. I just checked and the only items in EDIT: |
eddyb
referenced this issue
Jan 26, 2015
Merged
Revert "RFC to require `impl MyStruct` to be nearby the definition of `MyStruct`" #735
eddyb
added
I-nominated
P-medium
and removed
P-medium
I-nominated
labels
Feb 15, 2015
This comment has been minimized.
This comment has been minimized.
|
Nevermind the label fiddling above, I thought I had a case of backward incompatibility, but it's nothing more than bugs. |
This was referenced Feb 16, 2015
bors
added a commit
that referenced
this issue
Feb 20, 2015
bors
added a commit
that referenced
this issue
Feb 20, 2015
bors
added a commit
that referenced
this issue
Feb 20, 2015
bors
added a commit
that referenced
this issue
Feb 24, 2015
bors
added a commit
that referenced
this issue
Feb 24, 2015
bors
added a commit
that referenced
this issue
Feb 24, 2015
bors
added a commit
that referenced
this issue
Feb 24, 2015
This was referenced Mar 12, 2015
This comment has been minimized.
This comment has been minimized.
nrc
removed their assignment
Apr 8, 2015
This comment has been minimized.
This comment has been minimized.
|
Seems that self-argument destructing is not implemented on UFCS. struct A(uint);
impl A {
fn b(self: &A(ref mut u), i: uint) { //~ error: expected identifier, found keyword `ref`
//~^ error: expected one of `(`, `+`, `,`, `::`, or `<`, found `mut`
*u = i;
}
} |
This comment has been minimized.
This comment has been minimized.
|
Hmm, what still needs to be done here? Anything other than self argument destructuring (see the above two comments). |
This comment has been minimized.
This comment has been minimized.
|
I hit an other problem, it works fine. |
This comment has been minimized.
This comment has been minimized.
|
@ihrwein, It still does not work in my testing: struct Foo(i32, i64);
impl Foo {
fn classic(&self) {
println!("{}, {}", self.0, self.1);
}
fn destructuring(&Foo(u, v): &Self) {
println!("{}, {}", u, v);
}
}
fn main() {
let x = Foo(3, 14);
x.classic(); // Works, but doesn't destructure
Foo::destructuring(&x); // Works, but x is not an invocant
x.destructuring(); // Explodes
}
i.e., it supports destructuring |
This comment has been minimized.
This comment has been minimized.
|
@eternaleye try this way: struct Foo(i32, i64);
impl Foo {
fn classic(&self) {
println!("{}, {}", self.0, self.1);
}
fn destructuring(self) {
let Foo(u, v) = self;
println!("{}, {}", u, v);
}
}
fn main() {
let x = Foo(3, 14);
x.classic(); // Works, but doesn't destructure
Foo::destructuring(x);
} |
This comment has been minimized.
This comment has been minimized.
|
Those are completely different. My The point is that UFCS, as far as I can see, was specified as making it such that defining a first parameter of type The problem is that the method-call syntax is being forbidden when it should be allowed - i.e., exactly UFCS. One use case where this is especially nice, for its pure concision: Implementing state machines where each state is a newtype. |
alexcrichton
added
the
T-lang
label
Aug 11, 2015
This comment has been minimized.
This comment has been minimized.
|
I believe this has all long since been implemented, so closing. |
alexcrichton
closed this
Feb 18, 2016
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton: No, my example is still broken (destructuring the invocant): http://is.gd/3i9oCg |
This comment has been minimized.
This comment has been minimized.
|
@eternaleye The accepted RFC supports nothing of the sort. |
This comment has been minimized.
This comment has been minimized.
|
@eddyb: From the opening paragraph:
Thus, defining a function that takes a first argument of type |
This comment has been minimized.
This comment has been minimized.
|
@eternaleye It refers to
EDIT: I had missed "Receiver reconciliation" which was never fully implemented AFAICT. |
This comment has been minimized.
This comment has been minimized.
|
Mm, I suppose I misunderstood then. I'll see about writing up an RFC myself. EDIT: Er, on reading RFC 48 in the repo, what I'm seeing does not match what you say.
and
and
(emphasis mine) |
This comment has been minimized.
This comment has been minimized.
|
@eternaleye it's true that we initially intended to not make the name significant, but I think that ship has sailed (and it's worth amending the RFC). For one thing, it would be backwards incompatible to make a change here, as it would introduce potential new ambiguities into method dispatch (though I don't know whether this would actually affect any crates in practice). But also, I've shifted my opinion as to what I think is best. I think it is actively useful to be able to exclude functions from being used as methods, because it allows you to avoid potential conflicts between traits (any number of traits can have associated fns with the same name, but if method notation forces those names to be in conflict if a single type implements all the traits). I also think there is just a certain amount of clarity in a rule like "associated fns whose first argument uses the It also means that we can impose a rule that says: "if you use the keyword |
This comment has been minimized.
This comment has been minimized.
|
Regarding conflict, ISTR an older syntax (from before And personally, my interest in this is for cleanliness and concision in implementing things like state machines - in particular, being able to destructure the invocant lends itself very nicely to simple, concise implementations of state machines that can be used in a method-chaining notation. I can certainly see where you're coming from regarding deciding whether the type is derefable to Self, though. Given the above, perhaps I'll do up an RFC for permitting |
huonw commentedAug 6, 2014
https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md