Skip to content

Instantly share code, notes, and snippets.

@nikomatsakis
Last active July 15, 2019 14:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikomatsakis/5996e4f58899ef5c6926948b6f76835e to your computer and use it in GitHub Desktop.
Save nikomatsakis/5996e4f58899ef5c6926948b6f76835e to your computer and use it in GitHub Desktop.
Row Self Case Master #61207 Niko's take notes
S1 Foo fn(self: Pin<&mut Self>, f: &u8) -> &u8 f self +
S2 Foo fn(self: Pin<&mut Foo>, f: &u8) -> &u8 f self +
S3 Foo<'a> fn(self: Pin<&mut Self>, f: &u8) -> &u8 f self +
S4 Foo<'a> fn(self: Pin<&mut Foo>, f: &u8) -> &u8 f self +
S5 Foo<'a> fn(self: Self, f: &u8) -> &u8 f f ? lifetime inside self is ignored
S6 Foo<'a> fn(self: Foo<'a>, f: &u8) -> &u8 f f ? lifetime inside self is ignored
S7 Foo<'a> fn(self: Box<Foo<'a>>, f: &u8) -> &u8 f f ? lifetime inside self is ignored
S8 Foo<'a> fn(self: Box<Foo>, f: &u8) -> &u8 X X
S9 Foo fn(self: &Alias, f: &u8) -> &u8 f f ? Alias is not recognized as self here
N1 Foo<'a> fn(self: Box<&Self>, f: &u8) -> &u8 f self +
N2 Foo<'a> fn(self: Box<Box<&Self>>, f: &u8) -> &u8 f self +
N3 Foo<'a> fn(self: Box<Pin<&Self>>, f: &u8) -> &u8 f self +
  • Sn -- works on stable
  • Nn -- works on nightly
  • + -- behavior improved
  • ? -- behavior unchanged, but questionable
  • assume type Alias = Foo

Plausible Spec

  1. Each elided lifetime in the parameters becomes a distinct lifetime parameter.
  2. If there is exactly one lifetime used in the parameters (elided or not), that lifetime is assigned to all elided output lifetimes.
  3. In a method signature:
    • Stable: If the receiver has the semantic type &'lt mut? Self, then 'lt is assigned to all elided output lifetime parameters.
    • 61207: In the receiver, if all mentions of the semantic type &'lt mut? Self use a unique lifetime 'lt, then 'lt is assigned to all elided output lifetime parameters.

Current behavior on stable (and under the PR) does not meet this specification. For example case S7 does not.

Further, we do not look for a "precise match" for the Self type but rather we look for "some instance of the current struct/enum/union".

Niko's take: This spec itself may not be the thing we want, but obviously we have backwards compatibility concerns to consider as well, so we may simply want to introduce deprecations.

Other relevant questions

  • Cases marked with ? above are in violation of the rule as stated
  • Do we want a purely syntactic rule? (e.g., match Self but not other things equivalent to Self)
  • What about fn foo<'a>(x: &'a self) -> &u32? Can we deprecate this? (Elision expanding to a named lifetime)
  • What about impl<'a> Foo<'a> { fn foo(&self) -> &u32 }? In the past, people have complained about this. I'm inclined to keep it. -- Niko

More complex concerns

The test for the "self" type is currently just checking if it is an instance of the same struct/enum/union that we are implementing on. This implies that in very strange cases like this one, you get ambiguity:

#![allow(dead_code)]
#![feature(arbitrary_self_types)]

use std::pin::Pin;
use std::ops::Deref;

struct Foo<T> { d: T }

struct Extra<A, B> {
    data: (A, B)
}

impl<A, B> Deref for Extra<A, B> {
    type Target = B;

    fn deref(&self) -> &B {
        panic!()
    }
}

impl<T> Foo<T> {
    fn and_self<'a, 'b>(self: Extra<&'a Foo<u32>, &'b Foo<T>>, a: &'a u8, b: &'b u8) -> &u8 {
        a
    }
}

fn main() {
}
@pnkfelix
Copy link

convenience link to PR : rust-lang/rust#61207

@eddyb
Copy link

eddyb commented Jul 1, 2019

Further, we do not look for a "precise match" for the Self type but rather we look for "some instance of the current struct/enum/union".

Niko's take: This spec itself may not be the thing we want, but obviously we have backwards compatibility concerns to consider as well, so we may simply want to introduce deprecations.

I'm trying to get some crater results from rust-lang/rust#62181 regarding this, btw.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment