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 RFC 1679 #36340

Merged
merged 1 commit into from
Nov 27, 2016
Merged

Implement RFC 1679 #36340

merged 1 commit into from
Nov 27, 2016

Conversation

sfackler
Copy link
Member

@sfackler sfackler commented Sep 8, 2016

@alexcrichton
Copy link
Member

Nice! Could you also add tests that are exercising these new abilities as well?

@sfackler
Copy link
Member Author

sfackler commented Sep 9, 2016

@alexcrichton updated

@alexcrichton
Copy link
Member

Ok so I finally got around to actually running this on crater, and the result was three regressions: https://gist.github.com/alexcrichton/0c44e2a95044ae9f4d364496bbd0a388. One of those is spurious but the other two look legitimate.

These seem kinda worrisome :(

@sfackler
Copy link
Member Author

The gilrs failure looks like the kind of breakage we'd expect from our back compat guarantees and should be easy to fix. The rss-rs issue is way weirder - not sure what's going on with that.

@alexcrichton alexcrichton added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Sep 11, 2016
@alexcrichton
Copy link
Member

I'm guessing this is all because the output type is now generic, so there's cases where there's just not enough inference to figure out what it should actually be

@alexcrichton
Copy link
Member

Ok, minimizing the rss-rs case a little further:

fn foo<'a>(split: &[&'a [u8]]) -> (&'a [u8], &'a [u8]) {
    (
        unsafe { split.get_unchecked(0) },
        unsafe { split.get_unchecked(1) },
    )
}

On stable that compiles and with this patch it yields

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
 --> src/lib.rs:3:24
  |
3 |         unsafe { split.get_unchecked(0) },
  |                        ^^^^^^^^^^^^^

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
 --> src/lib.rs:4:24
  |
4 |         unsafe { split.get_unchecked(1) },
  |                        ^^^^^^^^^^^^^
  |
help: consider using an explicit lifetime parameter as shown: fn foo<'a>(split: &'a [&'a [u8]]) -> (&'a [u8], &'a [u8])
 --> src/lib.rs:1:1
  |
1 | fn foo<'a>(split: &[&'a [u8]]) -> (&'a [u8], &'a [u8]) {
  | ^

error: aborting due to 2 previous errors

That help message seems pretty suspicious for what might be happening here/

@sfackler
Copy link
Member Author

@alexcrichton do you see the same error using normal indexing with/without the patch?

@alexcrichton
Copy link
Member

@sfackler interestingly, no! If I change the return value to (split[0], split[1]), it works on stable, nightly, and with this patch. Even if I change it to (&split[0], &split[1]) it works on all three compilers...

@sfackler
Copy link
Member Author

That's bizarre. It is a difference between parameterized impls and parameterized methods, but I wouldn't have expected that to matter in this way.

@bors
Copy link
Contributor

bors commented Sep 15, 2016

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

@aturon
Copy link
Member

aturon commented Sep 26, 2016

cc @nikomatsakis, see #36340 (comment) in particular.

@nikomatsakis
Copy link
Contributor

Hmm. I have some theories but no concrete idea. I think I'll have to dig in a bit.

@nikomatsakis
Copy link
Contributor

I spent about an hour digging into this case today. Got to do a few other things now, but I'll try to come back to it. I haven't yet gotten to the bottom of what's going on, but I am going to leave myself a few notes here:

  • the value being returned has type &'1 &'2 [u8], which is then automatically coerced via deref-coercion to &'a [u8] (those are region variables). IOW, the compiler inserts to something like &**split.get_unchecked(0). However, if you add this by hand, everything works. =) So that's a sign of a compiler bug.
  • the bad constraint seems to be 'a <= '1, which is added as part of a subtype check when subtyping &'1 [u8] <: &'a [u8]. That is ... valid but I'm not yet quite sure why this subtyping is happening. Anyway, I think this is the problem.
  • here '1 represents the lifetime of the return value; there is a constraint that '1 <= '0, where '0 is the lifetime of the reference to self that is passed into get_unchecked. This seems correct too.

@sfackler
Copy link
Member Author

Thanks for looking into it!

@alexcrichton Given that the weird breakage seems to be something that "should" work modulo compiler bugs, I'd lean towards fixing the two crates that regress and landing this. Thoughts?

@alexcrichton
Copy link
Member

Hm this is a change to such a core type I'd personally prefer to wait for the compiler bug, if any, to get fixed.

@brson brson added the relnotes Marks issues that should be documented in the release notes of the next release. label Oct 24, 2016
@nikomatsakis
Copy link
Contributor

I'd be more comfortable waiting; I'll try to dig in a bit more asap

On Fri, Oct 21, 2016 at 10:04:18AM -0700, Alex Crichton wrote:

Hm this is a change to such a core type I'd personally prefer to wait for the compiler bug, if any, to get fixed.

You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#36340 (comment)

@nikomatsakis
Copy link
Contributor

OK, sorry for the delay, last week was crazy, but I dug in some more and I understand the problem. In particular, we have this bit of cleverness called expected_types_for_fn_args() which attempts to propagate constraints from the return type to the arguments. The intention here was things like Some(foo) apply coercions to foo.

In this case, though, we know that the return type like be &'1 [T], and we have the expected return type of &'a [u8]. From this we conclude (falsely) that we should give an expected type of &'a [u8] and we relate that '1: 'a. But ultimately the coercion becomes &** which doesn't require that '1: 'a.

I'm not entirely sure what's the best solution here. I have to kind of bring this coercion bit back in my head, and in particular under what circumstances it is required to commit region edges; it may be that we can apply it in more limited circumstances, or avoid committing all of the region inference edges. I suspect region edges are only needed when they affect new region variables that get created during the coercion -- e.g., the edge here, if it were truly needed, would be recreated, I believe.

cc @eddyb who wrote the code originally

@eddyb
Copy link
Member

eddyb commented Oct 31, 2016

Yeah, the region stuff was never great. We only truly care about "type skeletons" - as long as the coercion is triggered, having more freedom around regions (i.e. even replacing them all with fresh vars) shouldn't break anything.
Regular subtyping and then later regionck should (re)create all necessary relationships anyway.

@nikomatsakis
Copy link
Contributor

@eddyb

Regular subtyping and then later regionck should (re)create all necessary relationships anyway.

Do you remember why we had to commit the regions? I guess I can remove that step (and perhaps replace them with fresh vars) and see what happens.

@nikomatsakis
Copy link
Contributor

OK, I have a provisional fix for the compiler bug in question. Doing more testing now.

@brson
Copy link
Contributor

brson commented Nov 9, 2016

Thanks @nikomatsakis!

@sfackler
Copy link
Member Author

Rebased - can we run crater one more time now that niko's fix is in?

@eddyb
Copy link
Member

eddyb commented Nov 25, 2016

Starting crater run.

@sfackler
Copy link
Member Author

Thanks!

//~| NOTE required because of the requirements on the impl of `std::ops::Index<i32>`
x[..1i32]; //~ ERROR E0277
//~| NOTE slice indices are of type `usize` or ranges of `usize`
//~| NOTE trait `std::slice::SliceIndex<i32>` is not implemented for `std::ops::RangeTo<i32>`
Copy link
Member

Choose a reason for hiding this comment

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

tidy failed, line longer than 100 chars (should not impact the crater run though).

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops, fixed.

@eddyb
Copy link
Member

eddyb commented Nov 25, 2016

Crater report shows one root regression (postgres).

sfackler added a commit to sfackler/rust-postgres that referenced this pull request Nov 25, 2016
@sfackler
Copy link
Member Author

Well that's easy! sfackler/rust-postgres@11f1186

@sfackler
Copy link
Member Author

@alexcrichton I think this is good to go now?

@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:index out of bounds
// error-pattern:assertion failed: self < slice.len()
Copy link
Member

Choose a reason for hiding this comment

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

As per travis:

error: error pattern 'assertion failed: self < slice.len()' not found!

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops, fixed.

@alexcrichton
Copy link
Member

@bors: r+

Nice!

@bors
Copy link
Contributor

bors commented Nov 26, 2016

📌 Commit 5377b5e has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Nov 27, 2016

⌛ Testing commit 5377b5e with merge f8614c3...

bors added a commit that referenced this pull request Nov 27, 2016
@bors bors merged commit 5377b5e into rust-lang:master Nov 27, 2016
emk added a commit to faradayio/rust-postgres that referenced this pull request Nov 30, 2016
sfackler added a commit to sfackler/rust-postgres that referenced this pull request Nov 30, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
relnotes Marks issues that should be documented in the release notes of the next release. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants