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

Change lifetime of the self pointer in an &self method #5656

Closed
nikomatsakis opened this issue Apr 1, 2013 · 1 comment
Closed

Change lifetime of the self pointer in an &self method #5656

nikomatsakis opened this issue Apr 1, 2013 · 1 comment

Comments

@nikomatsakis
Copy link
Contributor

This is a part of the new region syntax in #4846, but it has proven hard enough that I am making a separate issue for it. The goal is to change the meaning of a method like:

impl<'self> Foo<'self> {
  fn foo(&self, ...) {...}
}

so that instead of being roughly equivalent to a function like:

impl<'self> Foo<'self> {
  fn foo(self: &'self Foo<'self>, ...) {...}
}

it is instead equivalent to:

impl<'self> Foo<'self> {
  fn foo(self: &Foo<'self>, ...) {...}
}

There are several reasons for this. One is the poor interaction with &mut self that I explained in this e-mail message. The other is that it is more consistent with the treatment of other parameters and it scales better to the case where impls may have more than one type parameter. The final one is that the current rules are kind of... bizarre in terms of their implications for the underlying type system.

For example, consider a case where the impl type does not have any lifetime parameters itself:

impl Foo {
  fn foo(&self, ...) {...}
}

Here there is no lifetime 'self. The current treatment here is a bit dodgy and kind of frightening to me.

I have an in-progress patch but there are lots of sides to this issue and it's not yet ready to land.

nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Apr 5, 2013
signature.  In a nutshell, the idea is to (1) report an error if, for
a region pointer `'a T`, the lifetime `'a` is longer than any
lifetimes that appear in `T` (in other words, if a borrowed pointer
outlives any portion of its contents) and then (2) use this to assume
that in a function like `fn(self: &'a &'b T)`, the relationship `'a <=
'b` holds. This is needed for rust-lang#5656.
bors added a commit that referenced this issue Apr 6, 2013
… r=catamorphism

r? @catamorphism (just the last commit)

This is a minor patch to #3184 (which you also reviewed), needed for #5656
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Apr 9, 2013
signature.  In a nutshell, the idea is to (1) report an error if, for
a region pointer `'a T`, the lifetime `'a` is longer than any
lifetimes that appear in `T` (in other words, if a borrowed pointer
outlives any portion of its contents) and then (2) use this to assume
that in a function like `fn(self: &'a &'b T)`, the relationship `'a <=
'b` holds. This is needed for rust-lang#5656.  Fixes rust-lang#5728.
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Apr 9, 2013
…mber of ways.

- In a TraitRef, use the self type consistently to refer to the Self type:
  - trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
  - trait ref in `A:Trait` has the self type `A`
  - trait ref associated with a trait decl has self type `Self`
  - trait ref associated with a supertype has self type `Self`
  - trait ref in an object type `@Trait` has no self type

- Rewrite `each_bound_traits_and_supertraits` to perform
  substitutions as it goes, and thus yield a series of trait refs
  that are always in the same 'namespace' as the type parameter
  bound given as input.  Before, we left this to the caller, but
  this doesn't work because the caller lacks adequare information
  to perform the type substitutions correctly.

- For provided methods, substitute the generics involved in the provided
  method correctly.

- Introduce TypeParameterDef, which tracks the bounds declared on a type
  parameter and brings them together with the def_id and (in the future)
  other information (maybe even the parameter's name!).

- Introduce Subst trait, which helps to cleanup a lot of the
  repetitive code involved with doing type substitution.

- Introduce Repr trait, which makes debug printouts far more convenient.

Fixes rust-lang#4183.  Needed for rust-lang#5656.
bors added a commit that referenced this issue Apr 10, 2013
…komatsakis

Cleanup substitutions and treatment of generics around traits in a number of ways

- In a TraitRef, use the self type consistently to refer to the Self type:
  - trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
  - trait ref in `A:Trait` has the self type `A`
  - trait ref associated with a trait decl has self type `Self`
  - trait ref associated with a supertype has self type `Self`
  - trait ref in an object type `@Trait` has no self type

- Rewrite `each_bound_traits_and_supertraits` to perform
  substitutions as it goes, and thus yield a series of trait refs
  that are always in the same 'namespace' as the type parameter
  bound given as input.  Before, we left this to the caller, but
  this doesn't work because the caller lacks adequare information
  to perform the type substitutions correctly.

- For provided methods, substitute the generics involved in the provided
  method correctly.

- Introduce TypeParameterDef, which tracks the bounds declared on a type
  parameter and brings them together with the def_id and (in the future)
  other information (maybe even the parameter's name!).

- Introduce Subst trait, which helps to cleanup a lot of the
  repetitive code involved with doing type substitution.

- Introduce Repr trait, which makes debug printouts far more convenient.

Fixes #4183.  Needed for #5656.

r? @catamorphism
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Apr 10, 2013
rather than a tuple.  The current setup iterates over
`BaseIter<(&'self K, &'self V)>` where 'self is a lifetime declared
*in the each method*.  You can't place such a type in
the impl declaration.  The compiler currently allows it,
but this will not be legal under rust-lang#5656 and I'm pretty sure
it's not sound now.
bors added a commit that referenced this issue Apr 10, 2013
… r=nikomatsakis

Revert map.each to something which takes two parameters rather than a tuple.  The current setup iterates over `BaseIter<(&'self K, &'self V)>` where 'self is a lifetime declared *in the `each()` method*.  You can't place such a type in the impl declaration.  The compiler currently allows it, but this will not be legal under #5656 and I'm pretty sure it's not sound now.  It's too bad that maps can't implement `BaseIter` (at least not over a tuple as they do here) but I think it has to be this way for the time being.

r? @thestinger
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Apr 10, 2013
signature.  In a nutshell, the idea is to (1) report an error if, for
a region pointer `'a T`, the lifetime `'a` is longer than any
lifetimes that appear in `T` (in other words, if a borrowed pointer
outlives any portion of its contents) and then (2) use this to assume
that in a function like `fn(self: &'a &'b T)`, the relationship `'a <=
'b` holds. This is needed for rust-lang#5656.  Fixes rust-lang#5728.
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Apr 11, 2013
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Apr 11, 2013
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Apr 11, 2013
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Apr 11, 2013
bors added a commit that referenced this issue Apr 12, 2013
@nikomatsakis
Copy link
Contributor Author

done as part of #5827

tesuji pushed a commit to tesuji/rustc that referenced this issue Jun 4, 2020
len_zero: skip ranges if feature `range_is_empty` is not enabled

If the feature is not enabled, calling `is_empty()` on a range is ambiguous. Moreover, the two possible resolutions are unstable methods, one inherent to the range and the other being part of the `ExactSizeIterator` trait.

Since `len_zero` only checks for existing `is_empty()` inherent methods, we only take into account the `range_is_empty` feature.

Related: rust-lang#48111 (comment)

changelog: len_zero: avoid linting ranges without #![feature(range_is_empty)]

Fixes: rust-lang#3807
tesuji pushed a commit to tesuji/rustc that referenced this issue Jun 4, 2020
Rollup of 3 pull requests

Successful merges:

 - rust-lang#5637 (new lint: vec_resize_to_zero)
 - rust-lang#5656 (len_zero: skip ranges if feature `range_is_empty` is not enabled)
 - rust-lang#5663 (add testcase that no longer ICEs)

Failed merges:

r? @ghost

changelog: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant