Skip to content

Higher-ranked function pointers implement Fn traits without enforcing necessary trait bounds to make sure the return type exists #85455

Closed
@steffahn

Description

@steffahn
cargo build

on the following code produces an ICE (just cargo check doesn’t ICE)

#![feature(unboxed_closures)]

trait SomeTrait<'a> {
    type Associated;
}

fn give_me_ice<T>() {
    callee::<fn(&()) -> <T as SomeTrait<'_>>::Associated>();
}

fn callee<T: Fn<(&'static (),)>>() {
    println!(
        "{}",
        std::any::type_name::<<T as FnOnce<(&'static (),)>>::Output>()
    );
}

fn main() {
    give_me_ice::<()>();
}
   Compiling playground v0.0.1 (/playground)
error: internal compiler error: compiler/rustc_traits/src/normalize_erasing_regions.rs:54:32: could not fully normalize `fn() -> &'static str {std::any::type_name::<<for<'r> fn(&'r ()) -> <() as SomeTrait<'r>>::Associated as std::ops::FnOnce<(&(),)>>::Output>}`

thread 'rustc' panicked at 'Box<Any>', /rustc/3e99439f4dacc8ba0d2ca48d221694362d587927/library/std/src/panic.rs:59:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.54.0-nightly (3e99439f4 2021-05-17) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 --crate-type bin

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [normalize_generic_arg_after_erasing_regions] normalizing `fn() -> &'static str {std::any::type_name::<<for<'r> fn(&'r ()) -> <() as SomeTrait<'r>>::Associated as std::ops::FnOnce<(&(),)>>::Output>}`
#1 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack
error: aborting due to previous error

error: could not compile `playground`

To learn more, run the command again with --verbose.

(playground)

Possibly, this bug can also lead to unsoundness in some way. (I haven’t fully explored that [yet].) Notably, Box<dyn Fn…> doesn’t come with the same problem:

#![feature(unboxed_closures)]

trait SomeTrait<'a> {
    type Associated;
}

fn give_me_ice<T>() {
    callee::<Box<dyn Fn(&()) -> <T as SomeTrait<'_>>::Associated>>();
}

fn callee<T: Fn<(&'static (),)>>() {
    println!(
        "{}",
        std::any::type_name::<<T as FnOnce<(&'static (),)>>::Output>()
    );
}

fn main() {
    give_me_ice::<()>();
}
   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `T: SomeTrait<'_>` is not satisfied
  --> src/main.rs:8:5
   |
8  |     callee::<Box<dyn Fn(&()) -> <T as SomeTrait<'_>>::Associated>>();
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `SomeTrait<'_>` is not implemented for `T`
...
11 | fn callee<T: Fn<(&'static (),)>>() {
   |              ------------------ required by this bound in `callee`
   |
   = note: required because of the requirements on the impl of `Fn<(&'static (),)>` for `Box<dyn for<'r> Fn(&'r ()) -> <T as SomeTrait<'_>>::Associated>`
help: consider restricting type parameter `T`
   |
7  | fn give_me_ice<T: SomeTrait<'_>>() {
   |                 ^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

I would’ve expected a similar error message for the fn… case as well.

(Further, note that the way things currently stand, the type Box<dyn Fn(&()) -> <T as SomeTrait<'_>>::Associated> itself is not leading to any error. It’s only the call to callee which has an Fn<…> bound. The error also successfully appears if callee has a higher-ranked Fn<…> bound and/or is not actually called but just instantiated with the type argument, here’s a playground doing both.)

@rustbot label requires-nightly, F-unboxed_closures, A-traits, A-typesystem, A-associated-items

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-trait-systemArea: Trait systemA-type-systemArea: Type systemC-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.F-unboxed_closures`#![feature(unboxed_closures)]`I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions