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

Implement revised coercion rules #18469

Open
aturon opened this Issue Oct 30, 2014 · 21 comments

Comments

Projects
None yet
@aturon
Copy link
Member

aturon commented Oct 30, 2014

Tracking issue for RFC 401.

@aturon

This comment has been minimized.

Copy link
Member Author

aturon commented Oct 30, 2014

Nominating: this contains backwards-incompatible changes.

For triage purposes, we probably want to pull out the DST coercions part of this as P-High.

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Nov 4, 2014

Summary of changes to make from the RFC:

  • Add cast from unsized slices to raw pointers (&[V] to *V);
  • allow coercions as casts and add lint for trivial casts - #18601;
  • ensure we support all coercion sites;
  • * remove [T, .. n] to &[T]/*[T] coercions - #18645;
  • add raw pointer coercions - #19766;
  • add sub-trait coercions - #5665;
  • add unsized tuple coercions - #42877;
  • add all transitive coercions - #18602;
  • receiver coercions - add referencing to raw pointers;
  • * receiver coercions - remove double referencing for slices - #19761;
  • * remove function coercions, add function type polymorphism - #18599;
  • add DST/custom coercions - #18598.

We should double check that these changes actually get us to the right destination as defined by the RFC.

I filed bugs for the larger pieces of work, the rest are pretty minor and can be tracked here. Those marked with an asterisk are backwards incompatible.

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Nov 4, 2014

Assigning myself for misc back-compat parts of this, I don't intend to do the rest right now.

@pnkfelix

This comment has been minimized.

Copy link
Member

pnkfelix commented Nov 6, 2014

Assigning P-backcompat-lang, 1.0.

@pnkfelix pnkfelix added this to the 1.0 milestone Nov 6, 2014

nrc added a commit to nrc/rust that referenced this issue Dec 12, 2014

Remove the double auto-ref on arrays/strings as receivers
Part of rust-lang#18469

[breaking-change]

A receiver will only ever get a single auto-reference. Previously arrays and strings would get two, e.g., [T] would be auto-ref'ed to &&[T]. This is usually apparent when a trait is implemented for `&[T]` and has a method takes self by reference. The usual solution is to implement the trait for `[T]` (the DST form).

nrc added a commit to nrc/rust that referenced this issue Dec 12, 2014

Remove the double auto-ref on arrays/strings as receivers
Part of rust-lang#18469

[breaking-change]

A receiver will only ever get a single auto-reference. Previously arrays and strings would get two, e.g., [T] would be auto-ref'ed to &&[T]. This is usually apparent when a trait is implemented for `&[T]` and has a method takes self by reference. The usual solution is to implement the trait for `[T]` (the DST form).

nrc added a commit to nrc/rust that referenced this issue Dec 16, 2014

Remove the double auto-ref on arrays/strings as receivers
Part of rust-lang#18469

[breaking-change]

A receiver will only ever get a single auto-reference. Previously arrays and strings would get two, e.g., [T] would be auto-ref'ed to &&[T]. This is usually apparent when a trait is implemented for `&[T]` and has a method takes self by reference. The usual solution is to implement the trait for `[T]` (the DST form).

bors added a commit that referenced this issue Dec 17, 2014

auto merge of #19761 : nick29581/rust/coerce-double, r=nikomatsakis
Part of #18469

[breaking-change]

A receiver will only ever get a single auto-reference. Previously arrays and strings would get two, e.g., [T] would be auto-ref'ed to &&[T]. This is usually apparent when a trait is implemented for `&[T]` and has a method takes self by reference. The usual solution is to implement the trait for `[T]` (the DST form).

r? @nikomatsakis (or anyone else, really)
@aturon

This comment has been minimized.

Copy link
Member Author

aturon commented Jan 5, 2015

@nick29581 Are the back-compat parts done? If so, let's re-nominate.

@nrc nrc added the I-nominated label Jan 5, 2015

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Jan 5, 2015

Yep, should no longer block

@pnkfelix

This comment has been minimized.

Copy link
Member

pnkfelix commented Jan 8, 2015

No more back incompat stuff; just usability issues. P-high.

@pnkfelix pnkfelix added P-medium and removed P-backcompat-lang labels Jan 8, 2015

@pnkfelix pnkfelix removed this from the 1.0 milestone Jan 8, 2015

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Mar 6, 2015

@nrc

You can involve type inference quite deeply here:

fn unify<T>(a: T, _: T) -> T { a }
trait Confusing { fn get() -> Self; }
impl Confusing for Box<[u32]> { fn get() -> Box<[u32]> { Box::new([0]) } }
impl Confusing for Box<[u32; 3]> { fn get() -> Box<[u32; 3]> { Box::new([7,8,9]) } }

#[cfg(not(type_error))]
fn f(x: bool) -> u32 {
    let a = Confusing::get();
    let v: Box<[u32]> = Box::new([1,2,3]);
    let s = match x {
        true => unify(a, v),
        false => unify(a, Box::new([1,2,3])),
    };
    s[0]
}

#[cfg(type_error)]
fn f(x: bool) -> u32 {
    let a = Confusing::get();
    let v: Box<[u32]> = Box::new([1,2,3]);
    let s = match x {
        false => unify(a, Box::new([1,2,3])),
        true => unify(a, v), //~ ERROR mismatched types
                             //| expected `Box<[u32; 3]>`
                             //|    found `Box<[u32]>`
    };
    s[0]
}

fn main() { println!("{}", f(false)); }

But I guess we have to do something like this.

Manishearth added a commit to Manishearth/rust that referenced this issue Jun 4, 2015

Rollup merge of rust-lang#25900 - lorenzb:more_about_types, r=nikomat…
…sakis

My main sources of information are [RFC401](https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md), the rust IRC channel, and a bunch of experiments to figure out what `rustc` currently supports.
Note that the RFC calls for some coercion behaviour that is not implemented yet (see rust-lang#18469).
The documentation in this PR mostly covers current behaviour of rust and doesn't document the future behaviour. I haven't written about receiver expression coercion.

I would be happy to rewrite/adapt the PR according to feedback.

r? @steveklabnik

bors added a commit that referenced this issue Jun 4, 2015

Auto merge of #25900 - lorenzb:more_about_types, r=nikomatsakis
My main sources of information are [RFC401](https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md), the rust IRC channel, and a bunch of experiments to figure out what `rustc` currently supports.
Note that the RFC calls for some coercion behaviour that is not implemented yet (see #18469).
The documentation in this PR mostly covers current behaviour of rust and doesn't document the future behaviour. I haven't written about receiver expression coercion.

I would be happy to rewrite/adapt the PR according to feedback.

r? @steveklabnik

bors added a commit that referenced this issue Jun 4, 2015

Auto merge of #25900 - lorenzb:more_about_types, r=nikomatsakis
My main sources of information are [RFC401](https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md), the rust IRC channel, and a bunch of experiments to figure out what `rustc` currently supports.
Note that the RFC calls for some coercion behaviour that is not implemented yet (see #18469).
The documentation in this PR mostly covers current behaviour of rust and doesn't document the future behaviour. I haven't written about receiver expression coercion.

I would be happy to rewrite/adapt the PR according to feedback.

r? @steveklabnik

bors added a commit that referenced this issue Jun 4, 2015

Auto merge of #25900 - lorenzb:more_about_types, r=nikomatsakis
My main sources of information are [RFC401](https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md), the rust IRC channel, and a bunch of experiments to figure out what `rustc` currently supports.
Note that the RFC calls for some coercion behaviour that is not implemented yet (see #18469).
The documentation in this PR mostly covers current behaviour of rust and doesn't document the future behaviour. I haven't written about receiver expression coercion.

I would be happy to rewrite/adapt the PR according to feedback.

r? @steveklabnik

@alexcrichton alexcrichton added the T-lang label Aug 11, 2015

@brson brson added the I-nominated label Jul 14, 2016

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Jul 14, 2016

Triage: ancient RFC tracking bug slipping through the cracks cc @rust-lang/lang what's up?

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Jul 14, 2016

Discussed at the lang meeting. I will go through the checklist to make sure it is up to date. We think it should remain p-medium since periodic check ins will be worthwhile.

@qnighy

This comment has been minimized.

Copy link
Contributor

qnighy commented Jun 4, 2017

Looking through rust-lang/rfcs#401, #37685, #32702, #34451, and this, it seems that tuple DSTs and their coercion should be allowed but the coercion is not implemented. Am I right?

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jun 5, 2017

@qnighy I think that is correct. I'm not sure just how much implementation work would be needed, there may be random bits of the compiler that need to be updated scattered around.

@qnighy

This comment has been minimized.

Copy link
Contributor

qnighy commented Jun 7, 2017

@nikomatsakis Thank you. I'm working on it.

@qnighy

This comment has been minimized.

Copy link
Contributor

qnighy commented Jun 7, 2017

Another question: PartialEq, Eq, PartialOrd, Ord, Debug, Hash can be generalized to unsized tuples. Are there any RFCs referring to this possibility?

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jun 9, 2017

@qnighy not that I'm aware of; I don't think we necessarily need an RFC for such a thing though

bors added a commit that referenced this issue Jun 29, 2017

Auto merge of #42527 - qnighy:unsized-tuple-coercions, r=arielb1
Unsized tuple coercions

Part of #18469. Fixes #32702.

#37685 and #34451 might also be related.

This PR does the following:

- Introduce explicit `Sized` constraints on tuple initializers, similar to that of record-struct initializers. Not much relevant to the main contribution but I noticed this when making tests for unsized tuple coercions.
- Implement `(.., T): Unsize<(.., U)>` where `T: Unsize<U>`.
- Assume `(.., T)` is MaybeUnsizedUnivariant.
- Modify `src/librustc/ty/util.rs` and `src/librustc_trans/glue.rs` so that tuples and structs are uniformly traversed when translating.

Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue Jul 12, 2017

Rollup merge of rust-lang#43011 - qnighy:unsized-tuple-impls, r=aturon
Implement Eq/Hash/Debug etc. for unsized tuples.

As I mentioned in [the comment in rust-lang#18469](rust-lang#18469 (comment)), the implementations of `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `Debug`, `Hash` can be generalized to unsized tuples.

This is consistent with the `derive` behavior for unsized structs.

```rust
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
struct MyTuple<X, Y, Z: ?Sized>(X, Y, Z);

fn f(x: &MyTuple<i32, i32, [i32]>) {
    x == x;
    x < x;
    println!("{:?}", x);
}
```

Questions:

- Need an RFC?
- Need a feature gate? I don't think it does because the unsized tuple coercion rust-lang#42527 is feature-gated.
- I changed `builder.field($name);` into `builder.field(&$name);` in the `Debug` implementation to pass compilation. This won't affect the behavior because `Debug for &'a T` is a mere redirection to `Debug for T`. However, I don't know if it affects code size / performance.
@torkleyy

This comment has been minimized.

Copy link

torkleyy commented Mar 30, 2018

Can I use any workaround until this is resolved? I have a custom type that I want to convert from Foo<[u32; 10]> to Foo<[u32]>. I could write a method which replaces the PhantomData, but I want it to work for all Unsize-able types.

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Nov 14, 2018

cc @rust-lang/lang Do we want to close this and all the unfinished sub-issues, and require a new RFC for any new features in this area, even if the old RFC covers them?
One thing to note is that we should probably not implement any new coercions until we get a new system built on top of traits and/or chalk, that can handle arbitrary library opt-in.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Dec 1, 2018

@eddyb What exactly remains to be done here; could you clarify the unfinished sub-issues?

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Dec 2, 2018

@Centril I'm just referring to this comment #18469 (comment) and the unchecked checkboxes in it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.