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

Unsized tuple coercions #42527

Merged
merged 6 commits into from
Jun 29, 2017
Merged

Unsized tuple coercions #42527

merged 6 commits into from
Jun 29, 2017

Conversation

qnighy
Copy link
Contributor

@qnighy qnighy commented Jun 8, 2017

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.

@rust-highfive
Copy link
Collaborator

r? @arielb1

(rust_highfive has picked a reviewer for you, use r? to override)

@qnighy
Copy link
Contributor Author

qnighy commented Jun 8, 2017

Travis failed, but I suppose it is spurious.

@oli-obk
Copy link
Contributor

oli-obk commented Jun 8, 2017

You can close and reopen the PR to restart travis

@qnighy qnighy closed this Jun 8, 2017
@qnighy qnighy reopened this Jun 8, 2017
@qnighy
Copy link
Contributor Author

qnighy commented Jun 8, 2017

@oli-obk Thank you!

@alexcrichton alexcrichton added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 8, 2017
@carols10cents
Copy link
Member

Friendly ping @arielb1 to keep this on your radar!

@arielb1
Copy link
Contributor

arielb1 commented Jun 12, 2017

Don't we want to feature-gate this somehow? Pinging @rust-lang/lang.

@@ -2612,6 +2617,37 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
&[inner_target]));
}

// (.., T) -> (.., U).
(&ty::TyTuple(tys_a, _), &ty::TyTuple(tys_b, _)) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll prefer to merge this with the ADT code somehow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've thought before that we should have an "infinite family" of tuple ADTs. One complication is that ADTs have def-ids...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code above mk_adt largely depends on def-ids and type parameters, so I doubt I can merge this part with tuple's. The codes below mk_adt/mk_tup are similar, but I don't think its worth merging...

f: isize
}

trait ToBar {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why these extra methods?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just because it was copied from dst-bad-assign.rs.

@@ -28,7 +28,8 @@ struct Fat<T: ?Sized> {

pub fn main() {
{
let _x: Box<Fat<Trait>> = Box::<Fat<Foo>>::new(Fat { f: Foo });
let _x: Box<(i32, Fat<Trait>)> =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you have this in addition to the original test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -25,7 +25,8 @@ struct Fat<T: ?Sized> {

pub fn main() {
{
let _x: Box<Fat<[Foo]>> = Box::<Fat<[Foo; 3]>>::new(Fat { f: [Foo, Foo, Foo] });
let _x: Box<(Fat<[Foo]>,)> =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you have this in addition to the original test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@arielb1
Copy link
Contributor

arielb1 commented Jun 12, 2017

I'm generally ok with these changes modulo select cleanup and a feature gate.

@arielb1 arielb1 added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 13, 2017
@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 17, 2017
@arielb1
Copy link
Contributor

arielb1 commented Jun 20, 2017

Hi @qnighy. We don't want this change to be insta-stable, so we need to add a feature gate and a tracking issue.

@arielb1
Copy link
Contributor

arielb1 commented Jun 28, 2017

r+ modulo comment

Copy link
Contributor

@arielb1 arielb1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+ modulo comment. Nice PR!

let b_last = tys_b.last().unwrap();

// Check that the source tuple with the target's
// last element is a subtype of the target.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: comment should not say "subtype" but rather "has the same type". Yes I know this is a copy of another comment that says "subtype". Both are wrong. The code does a type equality, and subtyping would be unsound (#40288).

So this comment should be

// Check that the source tuple with the target's
// last element is equal to the target.

And the other one

// Check that the source struct with the target's
// unsized parameters equal to the target.

We should probably be comparing all other type parameters instead of doing this hack. Feel free to do that (in both places), but I'm not going to block this PR on that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks!

// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
// inference might unify those two inner type variables later.
let traits = [coerce_unsized_did, unsize_did];
while let Some(obligation) = queue.pop_front() {
debug!("coerce_unsized resolve step: {:?}", obligation);
let trait_ref = match obligation.predicate {
ty::Predicate::Trait(ref tr) if traits.contains(&tr.def_id()) => tr.clone(),
ty::Predicate::Trait(ref tr) if traits.contains(&tr.def_id()) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is... ok.

@bors
Copy link
Contributor

bors commented Jun 28, 2017

☔ The latest upstream changes (presumably #42850) made this pull request unmergeable. Please resolve the merge conflicts.

@qnighy qnighy force-pushed the unsized-tuple-coercions branch from 1fe43a5 to 0812b33 Compare June 29, 2017 11:08
@bors
Copy link
Contributor

bors commented Jun 29, 2017

☔ The latest upstream changes (presumably #42964) made this pull request unmergeable. Please resolve the merge conflicts.

@qnighy qnighy force-pushed the unsized-tuple-coercions branch from 0812b33 to 94862c6 Compare June 29, 2017 12:26
@arielb1
Copy link
Contributor

arielb1 commented Jun 29, 2017

@bors r+

@bors
Copy link
Contributor

bors commented Jun 29, 2017

📌 Commit 94862c6 has been approved by arielb1

@bors
Copy link
Contributor

bors commented Jun 29, 2017

⌛ Testing commit 94862c6 with merge 686ec28...

bors added a commit that referenced this pull request Jun 29, 2017
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.
@bors
Copy link
Contributor

bors commented Jun 29, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: arielb1
Pushing 686ec28 to master...

@bors bors merged commit 94862c6 into rust-lang:master Jun 29, 2017
@qnighy qnighy deleted the unsized-tuple-coercions branch June 30, 2017 16:32
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this pull request Jul 12, 2017
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants