You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
HRTB variants are missing a std::fmt::Pointer impl #50280
It seems that there is a missing implementation of std::fmt::Pointer on some function pointers:
function pointers like fn test() -> f32 can be passed as argument to println!("{:p}", ...)
but function pointers like fn test(Vec<T> a) -> f32 can't because it's a HRTB variant.
Your link is broken. Can you please post a code snippet?
Printing an HRTB fn pointer should be impossible, because the address depends on the type arguments. Printing test::<i8> might be possible; I'm not sure, because playing around with it in the playpen, it seems to me that even a simple fn foo() does not impl Pointer.
Your arg type was fn (&Vec<i8>)->f32, which adds an important detail (the reference in the argument, which adds an invisible HRTB lifetime parameter that should not affect the function address. This makes the issue more legitimate
But the address's interpretation doesn't depends on the function type, isn't it ? HRTB type makes it difficult to reach the correct implementation of methods and traits but that doesn't affect the fact that it's a pointer ?
There's a macro in std that is used to generate the various std::fmt::Pointer impls for fn's of different arity. Probably what's missing are the HRTB variants, e.g. impl<Ret, A> Pointer for for<'a> fn(&'a A) -> Ret and so on for the other combinations.
@ExpHP, I agree that it’s not exhaustive. The existing impls are handcoded as well with someone making the choice of which arities and types to support.
Perhaps the real solution would be compiler support (eg a lang item) or some auto trait or something else. It’s a bad look when these fn pointers should just work but don’t and it all depends for which impls Pointer was implemented.
But barring a more principled solution, adding more combinations could bandaid this for now.
fn show(a: fn () -> f32, b: fn (&Vec<i8>)->f32) {
println!("the two pointers: {:p} {:p}", a, b);
}
gives this error:
error[E0277]: the trait bound `for<'r> fn(&'r std::vec::Vec<i8>) -> f32: std::fmt::Pointer` is not satisfied
--> src/lib.rs:2:48
|
2 | println!("the two pointers: {:p} {:p}", a, b);
| ^ the trait `std::fmt::Pointer` is not implemented for `for<'r> fn(&'r std::vec::Vec<i8>) -> f32`
|
= help: the following implementations were found:
<extern "C" fn(A) -> Ret as std::fmt::Pointer>
<extern "C" fn(A, ...) -> Ret as std::fmt::Pointer>
<fn(A) -> Ret as std::fmt::Pointer>
<unsafe extern "C" fn(A) -> Ret as std::fmt::Pointer>
and 2 others
= note: required by `std::fmt::Pointer::fmt`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
Reacted by Dennis Duda, Ryo Onodera and colecovision
054009d17ee fix long line
b17e6680d66 Move const trait bounds checks to MIR constck
b38732f25c3 Add "Platform-specific behavior" heading and link to changes disclaimer
e3b0a728b4a Erase impl regions when checking for impossible to eagerly monomorphize items
1354a38afd7 Document the heuristics IsTerminal uses on Windows
7bbc8ef0223 Make doc comment a little bit more accurate
901f10899c3 Add `#[inline]` to CStr trait implementations
f738b44c6d0 no shadow plz
904dd2c3987 Bless tidy
8af42f695d4 Remove useless Clone bounds
436afdf1fea Don't skip all directories when tidy-checking
3c4fabc341c Improve documentation for E0223
7cba12c5a9f Update books
9fc7eca935a Always set `RUSTC_BOOTSTRAP` with `x doc`
ed5c0f66ac1 socket ancillary data implementation for FreeBSD (from 13 and above).
73c34cbaf71 Add notes to non-structural const in pattern error message
41807938d2f fix advance_by impl for vec_deque and add tests
9cd9da2cd1c update documentation
e29b27b4a4c replace advance_by returning usize with Result<(), NonZeroUsize>
5ae6caa0f04 Use the FnPtr trait to avoid implementing common traits via macros
9e27c6c133b Some tracing/instrument cleanups
0c13565ca66 Add a builtin `FnPtr` trait
69db91b8b25 Change advance(_back)_by to return `usize` instead of `Result<(), usize>`
64927b973b6 Fix LVI test post LLVM 16 update
2a3177a8bcc tolerate region vars in implied bounds
b20aa97d480 exhaustive match on implied bounds regions
9cfb5f73ba3 add test
d1743c98170 resolve regions before implied bounds
b197f1ac2e4 remove obsolete `givens` from regionck
27c44d2e28d Update indexmap and rayon crates
4d5501037a3 Allow long link names in tar files
a1f48047bf9 Use Rayon's TLV directly
8b1be44758f Update ar_archive_writer to 0.1.3
d13b423859b use llvm 16.0.0 instead of 16.0.0-rc4
5456eecab0e Clean up substs building
08284449a24 Subst gat normalize pred correctly
73c79cd8063 stop special-casing `'static` in evaluate
Most likely #108080, which didn't add a test for this case, and I couldn't find any other test either.
Activity
ExpHP commentedon Apr 27, 2018
Your link is broken. Can you please post a code snippet?
Printing an HRTB fn pointer should be impossible, because the address depends on the type arguments. Printing
test::<i8>might be possible; I'm not sure, because playing around with it in the playpen, it seems to me that even a simplefn foo()does not impl Pointer.ExpHP commentedon Apr 27, 2018
Found it by copying the link text.
Your arg type was
fn (&Vec<i8>)->f32, which adds an important detail (the reference in the argument, which adds an invisible HRTB lifetime parameter that should not affect the function address. This makes the issue more legitimatejimy-byerley commentedon Apr 27, 2018
But the address's interpretation doesn't depends on the function type, isn't it ? HRTB type makes it difficult to reach the correct implementation of methods and traits but that doesn't affect the fact that it's a pointer ?
vitalyd commentedon Apr 27, 2018
There's a macro in std that is used to generate the various
std::fmt::Pointerimpls forfn's of different arity. Probably what's missing are the HRTB variants, e.g.impl<Ret, A> Pointer for for<'a> fn(&'a A) -> Retand so on for the other combinations.ExpHP commentedon Apr 27, 2018
@vitalyd that solution has exponentially scaling complexity just to support
&and&mutarguments, and that's without even support for:&that have lifetime parameters'b: 'aconstraintsvitalyd commentedon Apr 27, 2018
@ExpHP, I agree that it’s not exhaustive. The existing impls are handcoded as well with someone making the choice of which arities and types to support.
Perhaps the real solution would be compiler support (eg a lang item) or some auto trait or something else. It’s a bad look when these fn pointers should just work but don’t and it all depends for which impls Pointer was implemented.
But barring a more principled solution, adding more combinations could bandaid this for now.
steveklabnik commentedon May 8, 2020
Triage: no change. This program: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=844d632aee1147f2dc9e7d05d3ef9462
gives this error:
fmease commentedon Sep 24, 2024
Triage: The code provided in the comment above now compiles just fine.
Marking as
E-needs-test, however we might already have a test for this.Enselic commentedon Dec 17, 2025
This was fixed in
nightly-2023-03-29git log ^2036fdd24f77d607dcfaa24c48fbe85d3f785823 478cbb4 --no-merges --oneline
Most likely #108080, which didn't add a test for this case, and I couldn't find any other test either.
So I added a test in #150082.
@rustbot claim
Rollup merge of rust-lang#150082 - Enselic:hrtb-fn-pointer, r=fee1-dead
Rollup merge of rust-lang#150082 - Enselic:hrtb-fn-pointer, r=fee1-dead
Rollup merge of rust-lang#150082 - Enselic:hrtb-fn-pointer, r=fee1-dead
Rollup merge of rust-lang#150082 - Enselic:hrtb-fn-pointer, r=fee1-dead
Rollup merge of rust-lang#150082 - Enselic:hrtb-fn-pointer, r=fee1-dead
Unrolled build for #150082
Rollup merge of #150082 - Enselic:hrtb-fn-pointer, r=fee1-dead