rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.5k stars 12.74k forks source link

Higher-ranked lifetime bounds give confusing errors #29061

Open wthrowe opened 9 years ago

wthrowe commented 9 years ago
#![allow(dead_code)]

fn x(_: &()) {}

trait HR {}
impl HR for fn(&()) {}
fn hr<T: HR>(_: T) {}

trait NotHR {}
impl<'a> NotHR for fn(&'a ()) {}
fn not_hr<T: NotHR>(_: T) {}

fn a<'a>() {
    let not_hr_func: fn(&'a ()) = x;
    let hr_func: fn(&()) = x;
    let hr_func2: for<'b> fn(&'b ()) = x;
    hr(not_hr_func);
    not_hr(hr_func);
    not_hr(hr_func2);
}

fn main() {}

gives

<anon>:17:5: 17:7 error: the trait `HR` is not implemented for the type `fn(&())` [E0277]
<anon>:17     hr(not_hr_func);
              ^~
<anon>:17:5: 17:7 help: see the detailed explanation for E0277
<anon>:17:5: 17:7 note: required by `hr`
<anon>:18:5: 18:11 error: the trait `NotHR` is not implemented for the type `fn(&())` [E0277]
<anon>:18     not_hr(hr_func);
              ^~~~~~
<anon>:18:5: 18:11 help: see the detailed explanation for E0277
<anon>:18:5: 18:11 note: required by `not_hr`
<anon>:19:5: 19:11 error: the trait `NotHR` is not implemented for the type `fn(&'b ())` [E0277]
<anon>:19     not_hr(hr_func2);
              ^~~~~~
<anon>:19:5: 19:11 help: see the detailed explanation for E0277
<anon>:19:5: 19:11 note: required by `not_hr`
error: aborting due to 3 previous errors
playpen: application terminated with error code 101

Summarizing, given the type declaration, we have the printed form:

Declaration Display
fn(&'a ()) fn(&())
fn(&()) fn(&())
for<'b> fn(&'b ()) fn(&'b ())

So the non-higher-ranked type has its lifetime elided and is printed like a higher-ranked type, and higher-ranked types are sometimes printed without the quantifier but with the lifetime, looking like non-higher-ranked types.

cyplo commented 7 years ago

the message now seems to be as follows - would that be good enough, @wthrowe ?

    rustc 1.18.0 (03fc9d622 2017-06-06)
error[E0277]: the trait bound `fn(&()): HR` is not satisfied
  --> <anon>:17:5
   |
17 |     hr(not_hr_func);
   |     ^^ the trait `HR` is not implemented for `fn(&())`
   |
   = help: the following implementations were found:
         <fn(&()) as HR>
   = note: required by `hr`

error[E0277]: the trait bound `fn(&()): NotHR` is not satisfied
  --> <anon>:18:5
   |
18 |     not_hr(hr_func);
   |     ^^^^^^ the trait `NotHR` is not implemented for `fn(&())`
   |
   = help: the following implementations were found:
         <fn(&'a ()) as NotHR>
   = note: required by `not_hr`

error[E0277]: the trait bound `fn(&'b ()): NotHR` is not satisfied
  --> <anon>:19:5
   |
19 |     not_hr(hr_func2);
   |     ^^^^^^ the trait `NotHR` is not implemented for `fn(&'b ())`
   |
   = help: the following implementations were found:
         <fn(&'a ()) as NotHR>
   = note: required by `not_hr`

error: aborting due to 3 previous errors
memoryruins commented 5 years ago

Triage:

rustc: 1.32.0 errors with the same message cyplo posted

rust version 1.33.0-beta.4 (635817b9d 2019-01-24) errors with the following:

error[E0308]: mismatched types
  --> src/main.rs:17:5
   |
17 |     hr(not_hr_func);
   |     ^^ one type is more general than the other
   |
   = note: expected type `HR`
              found type `HR`

rust version 1.34.0-nightly (c1c3c4e95 2019-01-29) errors with the following:

error: implementation of `HR` is not general enough
  --> src/main.rs:17:5
   |
17 |     hr(not_hr_func);
   |     ^^
   |
   = note: Due to a where-clause on `hr`,
   = note: `HR` would have to be implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`
   = note: but `HR` is actually implemented for the type `for<'r> fn(&'r ())`
estebank commented 5 years ago

Current output:

error[E0277]: the trait bound `fn(&()): HR` is not satisfied
  --> file5.rs:17:8
   |
7  | fn hr<T: HR>(_: T) {}
   | ------------------ required by `hr`
...
17 |     hr(not_hr_func);
   |        ^^^^^^^^^^^ the trait `HR` is not implemented for `fn(&())`
   |
   = help: the following implementations were found:
             <for<'r> fn(&'r ()) as HR>

error[E0277]: the trait bound `for<'r> fn(&'r ()): NotHR` is not satisfied
  --> file5.rs:18:12
   |
11 | fn not_hr<T: NotHR>(_: T) {}
   | ------------------------- required by `not_hr`
...
18 |     not_hr(hr_func);
   |            ^^^^^^^ the trait `NotHR` is not implemented for `for<'r> fn(&'r ())`
   |
   = help: the following implementations were found:
             <fn(&'a ()) as NotHR>

error[E0277]: the trait bound `for<'b> fn(&'b ()): NotHR` is not satisfied
  --> file5.rs:19:12
   |
11 | fn not_hr<T: NotHR>(_: T) {}
   | ------------------------- required by `not_hr`
...
19 |     not_hr(hr_func2);
   |            ^^^^^^^^ the trait `NotHR` is not implemented for `for<'b> fn(&'b ())`
   |
   = help: the following implementations were found:
             <fn(&'a ()) as NotHR>

The only case that doesn't refer to the signature in the same way it was written is fn(&())/for<'r> fn(&'r ()).

estebank commented 4 years ago

Update, little change:

error[E0277]: the trait bound `fn(&()): HR` is not satisfied
  --> src/main.rs:17:8
   |
7  | fn hr<T: HR>(_: T) {}
   |          -- required by this bound in `hr`
...
17 |     hr(not_hr_func);
   |        ^^^^^^^^^^^ the trait `HR` is not implemented for `fn(&())`
   |
   = help: the following implementations were found:
             <for<'r> fn(&'r ()) as HR>

error[E0277]: the trait bound `for<'r> fn(&'r ()): NotHR` is not satisfied
  --> src/main.rs:18:12
   |
11 | fn not_hr<T: NotHR>(_: T) {}
   |              ----- required by this bound in `not_hr`
...
18 |     not_hr(hr_func);
   |            ^^^^^^^ the trait `NotHR` is not implemented for `for<'r> fn(&'r ())`
   |
   = help: the following implementations were found:
             <fn(&'a ()) as NotHR>

error[E0277]: the trait bound `for<'b> fn(&'b ()): NotHR` is not satisfied
  --> src/main.rs:19:12
   |
11 | fn not_hr<T: NotHR>(_: T) {}
   |              ----- required by this bound in `not_hr`
...
19 |     not_hr(hr_func2);
   |            ^^^^^^^^ the trait `NotHR` is not implemented for `for<'b> fn(&'b ())`
   |
   = help: the following implementations were found:
             <fn(&'a ()) as NotHR>
Dylan-DPC commented 1 year ago

Current output:

error: implementation of `HR` is not general enough
  --> src/main.rs:17:5
   |
17 |     hr(not_hr_func);
   |     ^^^^^^^^^^^^^^^ implementation of `HR` is not general enough
   |
   = note: `HR` would have to be implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`...
   = note: ...but `HR` is actually implemented for the type `for<'a> fn(&'a ())`

error: implementation of `NotHR` is not general enough
  --> src/main.rs:18:5
   |
18 |     not_hr(hr_func);
   |     ^^^^^^^^^^^^^^^ implementation of `NotHR` is not general enough
   |
   = note: `NotHR` would have to be implemented for the type `for<'a> fn(&'a ())`
   = note: ...but `NotHR` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`