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

Code no longer builds because of RFC 1214 #30829

Open
yongqli opened this Issue Jan 11, 2016 · 10 comments

Comments

@yongqli
Copy link

yongqli commented Jan 11, 2016

This code no longer builds on nightly:

pub fn use_r<I, R>(xs: I, r: &R) {
    unimplemented!()
}

fn test2<R>(r: &mut R) {
    let a = |r: &mut R| {
        [(|| use_r(vec![0.].into_iter(), r))()]
    };
    a(r);
    a(r);
}

fn main() { 
}

Rust playground link

See also https://internals.rust-lang.org/t/rfc-1214-regression-report-where-to-go-from-here/2788/10

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jan 11, 2016

Looks like closure inference and overloaded call notation gone amiss:

#![feature(unboxed_closures, fn_traits)]

fn test2<R>(r: &mut R) {
    let _f = |r: &mut R| {
        let x = || -> () { let _ = &r; };
        Fn::call(&x, ()); // compiles
        // x(); //~ ERROR the parameter type `R` may not live long enough [E0311]
    };
}

fn main() { 
}
@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jan 14, 2016

triage: P-high

@rust-highfive rust-highfive added P-high and removed I-nominated labels Jan 14, 2016

@nikomatsakis nikomatsakis self-assigned this Jan 14, 2016

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jan 14, 2016

Not sure if this is a bug or what, but it sure looks suspicious.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Mar 15, 2016

OK so the problem is a complex one. It would (honestly) probably be easier to solve in a MIR context. I don't know why this regressed yet (that is, I don't know why it ever worked), but I suspect it is related to @pnkfelix's fixes for extending the lifetime of return values (but only indirectly). Here is a minimal test case:

fn test2<R>() {
    |u: &mut R| {
        (|| u)();
    };
}

fn main() {
}

The problem is that we must infer the kind for the inner closure (|| u). This occurs at the very end, where we deduce FnOnce. We then register an obligation that the inner closure type should implement FnOnce. The problem is that we do this during the closure inference phase, using the fcx for the outermost fn -- which means the root_id of the resulting obligation is for the outer fn, which in turn means that we do not get the implied bounds for the outer closure here. Without those implied bounds, we indeed cannot prove that its argument type &'a mut R is well-formed, since the implied bounds are what let us deduce that R: 'a.

I'm not 100% sure of the easiest fix here. I guess we could try to gin up an fcx in DeferredCallResolution::resolve that has the appropriate body_id, but that feels like a royal pain in the neck. We could also keep the fcx for each of the inner closures around somewhere and pull it up. That's probably easier. It may not be better.

In the glorious MIR future, these region details would be erased and would get checked on the desugared representation, which seems much easier.

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Jun 23, 2016

@rust-lang/compiler No movement on this one. Still P-high?

@brson brson added the I-nominated label Jun 23, 2016

@pnkfelix

This comment has been minimized.

Copy link
Member

pnkfelix commented Jun 23, 2016

demoting to P-medium

@Mark-Simulacrum

This comment has been minimized.

Copy link
Member

Mark-Simulacrum commented May 13, 2017

@nikomatsakis You assigned to yourself a while back, still investigating?

Original example:

error[E0311]: the parameter type `R` may not live long enough
 --> test.rs:7:10
  |
7 |         [(|| use_r(vec![0.].into_iter(), r))()]
  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = help: consider adding an explicit lifetime bound for `R`
note: the parameter type `R` must be valid for the anonymous lifetime #1 defined on the body at 6:24...
 --> test.rs:6:25
  |
6 |       let a = |r: &mut R| {
  |  _________________________^
7 | |         [(|| use_r(vec![0.].into_iter(), r))()]
8 | |     };
  | |_____^
note: ...so that the reference type `&mut R` does not outlive the data it points at
 --> test.rs:7:10
  |
7 |         [(|| use_r(vec![0.].into_iter(), r))()]
  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

@arielb1's example compiles.

@nikomatsakis's example:

error[E0311]: the parameter type `R` may not live long enough
 --> test.rs:3:9
  |
3 |         (|| u)();
  |         ^^^^^^^^
  |
  = help: consider adding an explicit lifetime bound for `R`
note: the parameter type `R` must be valid for the anonymous lifetime #1 defined on the body at 2:16...
 --> test.rs:2:17
  |
2 |       |u: &mut R| {
  |  _________________^
3 | |         (|| u)();
4 | |     };
  | |_____^
note: ...so that the reference type `&mut R` does not outlive the data it points at
 --> test.rs:3:9
  |
3 |         (|| u)();
  |         ^^^^^^^^

error: aborting due to previous error
@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented May 25, 2017

I've not done any investigation, to be honest.

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jun 1, 2017

This will probably be fixed when we reform lifetime inference for NLL, and not before then.

@Mark-Simulacrum Mark-Simulacrum added C-bug and removed I-wrong labels Jul 24, 2017

@moxian

This comment has been minimized.

Copy link
Contributor

moxian commented Jun 29, 2018

Both the original example and the one by @nikomatsakis compile on stable (1.27.0).
@arielb1 example compiles on nightly (but not on stable, due to the need of #[feature(fn_traits)]

Should this be declared fixed?

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.