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

Only 'static is permitted within type bounds (causes ICE: Cannot relate bound region) #5121

Closed
13 tasks done
nikomatsakis opened this issue Feb 26, 2013 · 25 comments
Closed
13 tasks done
Assignees
Labels
A-lifetimes Area: Lifetimes / regions I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@nikomatsakis
Copy link
Contributor

Once we can declare lifetime parameters, there is no reason not to permit them in type bounds. Also, I am not entirely sure if the way we are handling them is correct/sound. I've tagged places where such bounds appear with FIXMEs so that I can look into them later.


Example:

trait Iterable<'a> {
    fn my_iter(&'a self);
}

fn foo<'a, C: Iterable<'a>>(c: C) {
    c.my_iter();
}

fn main() { }
5121.rs:6:5: 6:6 error: internal compiler error: Cannot relate bound region: ReLateBound(12, BrNamed(syntax::ast::DefId{crate: 0u32, node: 21u32}, a)) <= ReInfer(1)
This message reflects a bug in the Rust compiler. 
We would appreciate a bug report: https://github.com/mozilla/rust/wiki/HOWTO-submit-a-Rust-bug-report
5121.rs:6     c.my_iter();
              ^
task 'rustc' failed at 'explicit failure', /home/huon/rust/src/libsyntax/diagnostic.rs:41
task '<main>' failed at 'explicit failure', /home/huon/rust/src/librustc/lib.rs:440

pnkfelix: I am adding a checklist to the bottom of this bug, where the unchecked issues represent problems that still remain unfixed (and the entire list of issues were closed as duplicates of this ticket).

@ghost ghost assigned nikomatsakis Feb 28, 2013
@nikomatsakis
Copy link
Contributor Author

see also #5715

@emberian
Copy link
Member

@nikomatsakis this going to land in time for 0.7? I really hope so, it's really obnoxious.

@emberian
Copy link
Member

(Also, 'self is allowed too, I think)

@brson
Copy link
Contributor

brson commented Jul 3, 2013

Bumping from 0.7

@bblum
Copy link
Contributor

bblum commented Jul 19, 2013

I ran into this when trying to devise a too-clever interface for select2 that would let me avoid code duplication, but it would not let me use non-static borrowed pointers. https://gist.github.com/bblum/6042762

@nikomatsakis
Copy link
Contributor Author

This will be the final part of #4846. Turns out that this is not so simple as I originally thought (but also not horribly scary or complex). I'll put up a blog post soon (and link it here) describing my proposal.

@nikomatsakis
Copy link
Contributor Author

See http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ for a detailed write-up of the changes I propose to fix this.

@erickt
Copy link
Contributor

erickt commented Dec 6, 2013

@nikomatsakis: I ran into another region ICE that's similar to the other ones I ran into. This is with #10506 applied:

trait Iterable<'a> {
    fn my_iter(&'a self);
}

fn foo<'a, C: Iterable<'a>>(c: C) {
    c.my_iter();
}

fn main() { }

With this error:

foo.rs:6:4: 6:5 error: internal compiler error: Cannot relate bound region: ReLateBound(11, BrNamed(syntax::ast::DefId{crate: 0u32, node: 20u32}, a)) <= ReInfer(1)
This message reflects a bug in the Rust compiler.
We would appreciate a bug report: https://github.com/mozilla/rust/wiki/HOWTO-submit-a-Rust-bug-report
foo.rs:6     c.my_iter();
             ^

Is this related to #5121 or is this a different bug?

@dwrensha
Copy link
Contributor

dwrensha commented Dec 6, 2013

@erickt: In case you want a quick workaround, I've found that something like the following sometimes works:

trait Iterable<'a> {
    fn my_iter(&'a self);
}

struct Foo;

impl <'a> Foo {
    fn foo<C: Iterable<'a>>(c: &'a C) {
        c.my_iter();
    }
}

pub fn main() { }

(Note that I changed the type of the argument of foo in order to prevent a borrow check error.)

@nikomatsakis
Copy link
Contributor Author

@erickt that is #5121. I have a partial fix for this bug just sitting around, I think I will submit it as a PR and work on perfecting it later.

@dwrensha
Copy link
Contributor

dwrensha commented Mar 4, 2014

@pnkfelix: a fix for this issue would be awesome.

In case it helps, here's an example of the kind of thing I'd like to see supported:

pub struct StructReader<'a> {
    buf : *u8,
    len : uint,
    marker : std::kinds::marker::ContravariantLifetime<'a>,
}

pub trait FromStructReader<'a> {
    fn new(struct_reader : StructReader<'a>) -> Self;
}

pub struct MessageReader {
    buf : ~[u8],
}

impl MessageReader {
    pub fn get_root<'a, T : FromStructReader<'a>>(&'a self) -> T {
        FromStructReader::<'a>::new(
            StructReader {buf : self.buf.as_ptr(),
                          len : self.buf.len(),
                          marker : std::kinds::marker::ContravariantLifetime::<'a>,
            })
    }
}

pub struct FooReader<'a> {
    reader : StructReader<'a>
}

impl <'a> FromStructReader<'a> for FooReader<'a> {
    fn new(struct_reader : StructReader<'a>) -> FooReader<'a> {
        FooReader { reader : struct_reader}
    }
}

pub fn main () {
    let message = MessageReader {buf : ~[1,2,3,4,5]};
    let foo : FooReader = message.get_root();
}

@pnkfelix
Copy link
Member

pnkfelix commented Mar 5, 2014

@dwrensha yeah I've successfully rebased niko's patches and got them passing our tests. I need to rebase them again now that OptVec has gone away but I think that will go faster, and then I'll post a PR. (Plus I think I might try to collect the test cases that people have posted and make sure they are reflected in our test suite.)

@pnkfelix
Copy link
Member

@nikomatsakis by the way, the example given by @erickt still does not work even after applying PR #12807. I think that this is because erickt's example is not quite correct: in

fn foo<'a, C: Iterable<'a>>(c: C) {
    c.my_iter();
}

the c is passed by value into foo and thus c will not live longer than this invocation of foo, which means it does not outlive 'a in general. Since my_iter requires a &'a self parameter, the borrow-checker rejects invocation of c.my_iter() in this program.

(I think erickt's example should work fine if you change the foo parameter to be a &'a C, which makes sense to me.) ((amendment to the latter note: it should work fine, but rustc is ICE'ing for me on that generalization. Will investigate.))

@pnkfelix
Copy link
Member

(the example provided by @dwrensha does compile under PR #12807 though.)

bors added a commit that referenced this issue Mar 12, 2014
…etime-params, r=pnkfelix

Fix issue #5121: Add proper support for early/late distinction for lifetime bindings.

There are some little refactoring cleanups as separate commits; the real meat that has the actual fix is in the final commit.

The original author of the work was @nikomatsakis; I have reviewed it, revised it slightly, refactored it into these separate commits, and done some rebasing work.
@flaper87
Copy link
Contributor

Taken from #12851

trait MyTrait<'a> {
    fn yo(&'a self);
}

struct MyStruct<'a> {
    inner: &'a  MyTrait<'a>,
}

impl<'a> MyStruct<'a> {

    fn foo_inner(&mut self) {
        self.inner.yo()
    }
}

@pnkfelix
Copy link
Member

well, I guess it is a good thing I didn't have bors automatically close this ticket with PR #12807.

Will investigate these ICE's. (i had noted others above, may be related.)

pnkfelix added a commit to pnkfelix/rust that referenced this issue Mar 25, 2014
The problem was that we need to apply the substitution, so that the
formal lifetime parameters get replaced with (unifiable)
free-lifetimes that can actually be fed into the constraint solver.
@pnkfelix
Copy link
Member

I have a patch that fixes most of the ICE's above, though not all of them.

I will try to put it up for review either tonight or tomorrow.

@pnkfelix
Copy link
Member

After reviewing the bugs that have been marked as duplicates of this bug, I've collected all of the cases that were not fixed by the original Early/Late patch and put them into their own modules. (Sometimes I tried to reduce them into smaller test cases, but usually when I did that I made a variant module with the reduced case while also keeping the original.)

The result of this collection process is posted in a file at the following gist:
https://gist.github.com/pnkfelix/9788730

(It wasn't originally a single file, but that is the easiest way to distribute the collection. It is easy enough to go back and forth between separate files and a single file for the modules, thanks to the beauty of Rust's module system.)

@pnkfelix
Copy link
Member

PR #13157 fixes most of the ICE's exposed by https://gist.github.com/pnkfelix/9788730

The main exceptions are the ICE's that are exposed by passing --cfg defer_for_5121_fix2 and --cfg defer_for_5121_fix3.

The other important things that are not fixed by PR #13157 (a fix to issue #13140) are the non-ICE unsoundness issues that are represented by the print out from the gisted code when you run it, namely the output:

Warning, non-3 value from m3: 140658622872720
bar.get(0) = 9
bar = [9, 9, 9, 9, 9], should be [1, 2, 3, 4, 5]

corresponding to #11971 and #12856.

bors added a commit that referenced this issue Mar 29, 2014
r? @nikomatsakis

Fix #13140

Includes two fixes, and a semi-thorough regression test.

(There is another set of tests that I linked from #5121, but those are sort of all over the place, while the ones I've included here are more directly focused on the issues at hand.)
@pnkfelix
Copy link
Member

So, as mentioned above, there still remain issues #11971 and #12856 that remain unfixed. (They are already open, since they were not marked as dupes, just related.)

Also, we probably need to make some other changes, such as allowing one to put a lifetime bound on a trait (which means that all impls need to have that bound on themSelfs (sic)).

But, most of the work has been done here, and I claim that new bugs related to this one should not be closed as dupes of this one (but rather should be classified as unique on their own or classified as dupes of some other, more specific bug). So I am going to close this bug.

bors added a commit to rust-lang-ci/rust that referenced this issue May 2, 2020
Improve compile_test and dogfood tests

* Hopefully this finally resolves the "multiple matching crates" error, e.g. rust-lang#4015
* This handle some convenient CARGO env like CARGO_TARGET_DIR and CARGO_BUILD_TARGET

changelog: none
bors added a commit to rust-lang-ci/rust that referenced this issue May 2, 2020
Fix error E0460 when compiled on Rustc repo

Sadly, this mostly reverts  rust-lang#5121. Now I use HashMap to only store one rlib
per crate. But that would not work when non-compatible version of the same crate show up.

changelog: none
calebcartwright added a commit to calebcartwright/rust that referenced this issue Dec 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests