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

Ensure the types of methods are well-formed #28669

Merged
merged 3 commits into from
Oct 3, 2015

Conversation

arielb1
Copy link
Contributor

@arielb1 arielb1 commented Sep 26, 2015

By RFC1214:

Before calling a fn, we check that its argument and return types are WF.

The previous code only checked the trait-ref, which was not enough
in several cases.

As this is a soundness fix, it is a [breaking-change]. Some new annotations are needed, which I think are because of #18653 and the imperfection of projection_must_outlive (that can probably be worked around by moving the wf obligation later).

Fixes #28609

r? @nikomatsakis

@bors
Copy link
Contributor

bors commented Sep 26, 2015

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

@arielb1
Copy link
Contributor Author

arielb1 commented Sep 26, 2015

Minimal example for the rustc regression:

pub trait Lift<'tcx> {
    type Lifted /* adding :'tcx solves this */;
}

pub fn lift<'tcx,T:?Sized+Lift<'tcx>>(value: &T) -> T::Lifted {
    loop {}
}

pub fn my_lift_to_tcx<'tcx, T: Lift<'tcx>>(this: &T)
{   
    let mut result = Vec::new(); // adding a type annotation here solves this
    result.push(lift(this));
}

@arielb1
Copy link
Contributor Author

arielb1 commented Sep 26, 2015

The warning is

elevator.rs:12:12: 12:28 warning: the parameter type `T` may not live long enoug
h [E0309]
elevator.rs:12     result.push(lift(this));
                          ^~~~~~~~~~~~~~~~
elevator.rs:12:12: 12:28 help: run `rustc --explain E0309` to see a detailed explanation
elevator.rs:12:12: 12:28 help: consider adding an explicit lifetime bound `T: 'tcx`...
elevator.rs:12:12: 12:28 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
elevator.rs:12     result.push(lift(this));
                          ^~~~~~~~~~~~~~~~
elevator.rs:12:12: 12:28 note: ...so that the reference type `&collections::vec::Vec<<T as Lift<'_>>::Lifted>` does not outlive the data it points at
elevator.rs:12     result.push(lift(this));
                          ^~~~~~~~~~~~~~~~

I think the reference lifetime somehow becomes underconstrained.

@arielb1 arielb1 force-pushed the well-formed-methods branch from 8352807 to 98fe9eb Compare September 26, 2015 18:13

// check that static methods don't get to assume `Self` is well-formed

// TODO: I (arielb1) isn't sure whether this is a bug or feature.
Copy link
Contributor

Choose a reason for hiding this comment

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

Note tidy error: /home/travis/build/rust-lang/rust/src/test/compile-fail/wf-static-method.rs:13: TODO is deprecated; use FIXME

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 question was meant to you - I should have asked it more explicitly.

@arielb1 arielb1 force-pushed the well-formed-methods branch from 98fe9eb to 1c3645e Compare September 29, 2015 20:14
@brson
Copy link
Contributor

brson commented Sep 29, 2015

Running on crater

@brson
Copy link
Contributor

brson commented Sep 30, 2015

Toolchains built, testing crates.

@brson
Copy link
Contributor

brson commented Sep 30, 2015

Crater says.

@arielb1
Copy link
Contributor Author

arielb1 commented Oct 1, 2015

regression summary

rust_ini uses the soundness hole to get a working find_equiv - zonyitoo/rust-ini#19.
acacia is just plain RFC1214-noncompliant (milibopp/acacia#71), and for some reason cargo attempts to compile both nalgebra 0.2.3 and nalgebra 0.3.0, which fails. There are no new errors.

I think these are both acceptable

@brson brson added relnotes Marks issues that should be documented in the release notes of the next release. regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. I-needs-decision Issue: In need of a decision. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Oct 2, 2015
@brson
Copy link
Contributor

brson commented Oct 2, 2015

sgtm

Let's at least give the authors of these two crates a head's up. cc @zonyitoo @aepsil0n this soundness fix will break some of your stuff.

@zonyitoo
Copy link

zonyitoo commented Oct 2, 2015

@brson Thanks! I will update the rust-ini as soon as possible.

// option. This file may not be copied, modified, or distributed
// except according to those terms.

// check that static methods don't get to assume `Self` is well-formed
Copy link
Contributor

Choose a reason for hiding this comment

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

So I've been meaning to get back to you on this test. I'm not quite sure what this is testing... it seems like the Self type, if WF, would imply that 'b: 'a, but the various tests are erroring because 'a: 'b doesn't hold. Is this testing what you think it is?

Also, within an impl block, part of RFC 1214 was that we DO get to assume that the Self (and other input types) to the trait are well-formed, which is why we check that the trait ref is WF when we project. This was used to reduce the overhead on associated type values, but I imagine it should apply to static fns as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I got the order wrong. I also added a test on the caller side.

Ariel Ben-Yehuda added 2 commits October 2, 2015 23:40
By RFC1214:
Before calling a fn, we check that its argument and return types are WF. This check takes place after all higher-ranked lifetimes have been instantiated. Checking the argument types ensures that the implied bounds due to argument types are correct. Checking the return type ensures that the resulting type of the call is WF.

The previous code only checked the trait-ref, which was not enough
in several cases.

As this is a soundness fix, it is a [breaking-change].

Fixes rust-lang#28609
looks like some mix of rust-lang#18653 and `projection_must_outlive`, but
that needs to be investigated further (crater run?)
@arielb1 arielb1 force-pushed the well-formed-methods branch 4 times, most recently from d6924fe to db22da0 Compare October 3, 2015 09:03
also, ensure that callers are checked.
@arielb1 arielb1 force-pushed the well-formed-methods branch from db22da0 to 2f23e17 Compare October 3, 2015 09:04
@milibopp
Copy link
Contributor

milibopp commented Oct 3, 2015

@arielb1 already gave me a heads up. Will fix as soon as I find the time.

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Oct 3, 2015

📌 Commit 2f23e17 has been approved by nikomatsakis

bors added a commit that referenced this pull request Oct 3, 2015
By RFC1214:
>    Before calling a fn, we check that its argument and return types are WF.
    
The previous code only checked the trait-ref, which was not enough
in several cases.
    
As this is a soundness fix, it is a [breaking-change]. Some new annotations are needed, which I think are because of #18653 and the imperfection of `projection_must_outlive` (that can probably be worked around by moving the wf obligation later).
    
Fixes #28609

r? @nikomatsakis
@bors
Copy link
Contributor

bors commented Oct 3, 2015

⌛ Testing commit 2f23e17 with merge 130851e...

@bors bors merged commit 2f23e17 into rust-lang:master Oct 3, 2015
@eefriedman
Copy link
Contributor

@arielb1 Is there an issue tracking the pinyin regression (https://tools.taskcluster.net/task-inspector/#UFk2m1UJRweSxQNABRB84w/0)? It appears to be real (although I'm not sure it's relevant).

@eefriedman
Copy link
Contributor

Filed #28853 to track the pinyin regression.

Manishearth added a commit to Manishearth/rust that referenced this pull request Oct 14, 2015
…felix

This rather crucial requirement was not checked. In most cases, that
didn't cause any trouble because the argument types are required to
outlive the call and are subtypes of a subformula of the callee type.

However, binary ops are taken by ref only indirectly, without it being
marked in the argument types, which led to the argument types not being
constrained anywhere causing spurious errors (as these are basically
unconstrainable, I don't think this change can break code). Of course,
the old way was also incorrent with contravariance, but that is still
unsound for other reasons.

This also improves rustc::front to get RUST_LOG to *somewhat* work.

Fixes rust-lang#28999. That issue is one of the several regression introduced by rust-lang#28669.

r? @pnkfelix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-needs-decision Issue: In need of a decision. regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. relnotes Marks issues that should be documented in the release notes of the next release. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lifetime bounds on structs do not entirely constrain impl fns
7 participants