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

"cannot relate bound region" in a concrete lifetime vs for<'a> mismatch. #30906

Closed
eddyb opened this issue Jan 14, 2016 · 5 comments
Closed

"cannot relate bound region" in a concrete lifetime vs for<'a> mismatch. #30906

eddyb opened this issue Jan 14, 2016 · 5 comments
Labels
A-closures Area: closures (`|args| { .. }`) A-diagnostics Area: Messages for errors, warnings, and lints F-unboxed_closures `#![feature(unboxed_closures)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@eddyb
Copy link
Member

eddyb commented Jan 14, 2016

#![feature(fn_traits, unboxed_closures)]

fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {}

struct Compose<F,G>(F,G);
impl<T,F,G> FnOnce<(T,)> for Compose<F,G>
where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> {
    type Output = G::Output;
    extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output {
        (self.1)((self.0)(x))
    }
}

fn bad<T>(f: fn(&'static str) -> T) {
    // internal compiler error: cannot relate bound region:
    //   ReLateBound(DebruijnIndex { depth: 2 },
    //     BrNamed(DefId { krate: 0, node: DefIndex(6) => test::'x }, 'x(65)))
    //<= ReSkolemized(0,
    //     BrNamed(DefId { krate: 0, node: DefIndex(6) => test::'x }, 'x(65)))
    test(Compose(f, |_| {}));
}

Usage of FnOnce<(T,)> is to avoid proving an explicit type parameter for the Output associated type, as an workaround for #30867.

Originally submitted as part of #30904.

@eddyb eddyb added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Jan 14, 2016
@eddyb
Copy link
Member Author

eddyb commented Jan 14, 2016

Must be caused by the built-in implementation of FnOnce for fn types, the following testcase (run on playpen) gives a regular error instead of an ICE:

fn test<F: for<'x> Lambda<&'x str>>(_: F) {}

trait Lambda<T> {
    type Output;
}

impl<T, U> Lambda<T> for fn(T) -> U {
    type Output = U;
}

struct Compose<F,G>(F,G);
impl<T,F,G> Lambda<T> for Compose<F,G>
where F: Lambda<T>, G: Lambda<F::Output> {
    type Output = G::Output;
}

fn bad<T>(f: fn(&'static str) -> T) {
    test(Compose(f, std::mem::drop as fn(T)));
}

@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@shepmaster
Copy link
Member

shepmaster commented Jan 20, 2018

@eddyb does this look the same or should I open a new issue:

trait SomeTrait {}

fn foo<P, Q, F>(func: F)
where
    for<'a> F: Fake<'a, P, Q>,
    // just for an impl
    P: Default,
    Q: std::fmt::Debug,
{
    let p = P::default();
    let q = func(&p);
    println!("{:?}", q);
}

trait Fake<'a, P: 'a, Q>: Fn(&'a P) -> Q
where
    Self::Output: SomeTrait + 'a,
{
}

impl<'a, P: 'a, Q, F> Fake<'a, P, Q> for F
where
    F: Fn(&'a P) -> Q,
    F::Output: SomeTrait + 'a,
{
}

#[derive(Debug)]
struct Wrapper<'a>(&'a u8);

impl<'a> SomeTrait for Wrapper<'a> {}

fn main() {
    foo(Wrapper);
}
error: internal compiler error: /checkout/src/librustc/infer/region_constraints/mod.rs:685: cannot relate bound region: ReLateBound(DebruijnIndex { depth: 2 }, BrNamed(CrateNum(0):DefIndex(1:12), 'a(91))) <= ReSkolemized(0, BrNamed(CrateNum(0):DefIndex(1:12), 'a(91)))
  --> src/main.rs:34:5
   |
34 |     foo(Wrapper);
   |     ^^^

@estebank
Copy link
Contributor

No longer ICEs:

error: implementation of `std::ops::FnOnce` is not general enough
  --> src/lib.rs:20:5
   |
20 |     test(Compose(f, |_| {}));
   |     ^^^^
   |
   = note: Due to a where-clause on `test`,
   = note: `Compose<fn(&str) -> T, [closure@src/lib.rs:20:21: 20:27]>` must implement `std::ops::FnOnce<(&'0 str,)>`, for any lifetime `'0`
   = note: but `Compose<fn(&str) -> T, [closure@src/lib.rs:20:21: 20:27]>` actually implements `std::ops::FnOnce<(&'1 str,)>`, for some specific lifetime `'1`
error: implementation of `Lambda` is not general enough
  --> src/lib.rs:18:5
   |
18 |     test(Compose(f, std::mem::drop as fn(T)));
   |     ^^^^
   |
   = note: Due to a where-clause on `test`,
   = note: `Compose<fn(&str) -> T, fn(T)>` must implement `Lambda<&'0 str>`, for any lifetime `'0`
   = note: but `Compose<fn(&str) -> T, fn(T)>` actually implements `Lambda<&'1 str>`, for some specific lifetime `'1`
error: implementation of `Fake` is not general enough
  --> src/main.rs:34:5
   |
34 |     foo(Wrapper);
   |     ^^^
   |
   = note: Due to a where-clause on `foo`,
   = note: `fn(&u8) -> Wrapper<'_> {Wrapper<'_>}` must implement `Fake<'0, u8, Wrapper<'_>>`, for any lifetime `'0`
   = note: but `fn(&u8) -> Wrapper<'_> {Wrapper<'_>}` actually implements `Fake<'1, u8, Wrapper<'_>>`, for some specific lifetime `'1`

@estebank estebank reopened this Jan 30, 2019
@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints A-closures Area: closures (`|args| { .. }`) and removed I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ C-bug Category: This is a bug. labels Jan 30, 2019
@estebank
Copy link
Contributor

estebank commented May 22, 2019

Current output:

error[E0308]: mismatched types
  --> src/lib.rs:20:5
   |
20 |     test(Compose(f, |_| {}));
   |     ^^^^ one type is more general than the other
   |
   = note: expected type `std::ops::FnOnce<(&'x str,)>`
              found type `std::ops::FnOnce<(&str,)>`
error: implementation of `Lambda` is not general enough
  --> src/lib.rs:18:5
   |
18 |     test(Compose(f, std::mem::drop as fn(T)));
   |     ^^^^
   |
   = note: `Lambda<&'0 str>` would have to be implemented for the type `fn(&str) -> T`, for any lifetime `'0`
   = note: but `Lambda<&'1 str>` is actually implemented for the type `fn(&'1 str) -> T`, for some specific lifetime `'1`
error: implementation of `Fake` is not general enough
  --> src/main.rs:34:5
   |
34 |     foo(Wrapper);
   |     ^^^
   |
   = note: Due to a where-clause on `foo`,
   = note: `fn(&u8) -> Wrapper<'_> {Wrapper<'_>}` must implement `Fake<'0, u8, Wrapper<'_>>`, for any lifetime `'0`
   = note: but `fn(&u8) -> Wrapper<'_> {Wrapper<'_>}` actually implements `Fake<'1, u8, Wrapper<'_>>`, for some specific lifetime `'1`

@JohnTitor JohnTitor added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Oct 1, 2019
@Centril Centril added F-unboxed_closures `#![feature(unboxed_closures)]` requires-nightly This issue requires a nightly compiler in some way. labels Nov 5, 2019
@eddyb
Copy link
Member Author

eddyb commented Nov 13, 2019

#30904 (comment) should've been posted here - this is what's been fixed, not #30904.

@eddyb eddyb closed this as completed Nov 13, 2019
JohnTitor added a commit to JohnTitor/rust that referenced this issue Nov 15, 2019
Add more tests for fixed ICEs

Closes rust-lang#36122 (fixed in 1.20.0)
Closes rust-lang#58094 (fixed in rust-lang#66054)
Also, fix mistaken test case, from rust-lang#30904 to rust-lang#30906 (cc @eddyb)

r? @Centril
Centril added a commit to Centril/rust that referenced this issue Nov 15, 2019
Add more tests for fixed ICEs

Closes rust-lang#36122 (fixed in 1.20.0)
Closes rust-lang#58094 (fixed in rust-lang#66054)
Also, fix mistaken test case, from rust-lang#30904 to rust-lang#30906 (cc @eddyb)

r? @Centril
Centril added a commit to Centril/rust that referenced this issue Nov 15, 2019
Add more tests for fixed ICEs

Closes rust-lang#36122 (fixed in 1.20.0)
Closes rust-lang#58094 (fixed in rust-lang#66054)
Also, fix mistaken test case, from rust-lang#30904 to rust-lang#30906 (cc @eddyb)

r? @Centril
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: closures (`|args| { .. }`) A-diagnostics Area: Messages for errors, warnings, and lints F-unboxed_closures `#![feature(unboxed_closures)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants