{"id":"768caf97a28a075b","repo":"rust-lang/rust","slug":"fn-are-not-yet-const","errorCode":null,"errorMessage":"Fn* are not yet const","messagePattern":"Fn\\* are not yet const","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_next_trait_solver/src/solve/effect_goals.rs","lineNumber":292,"sourceCode":"                        goal.with(\n                            cx,\n                            ty::ClauseKind::HostEffect(\n                                goal.predicate.with_replaced_self_ty(cx, ty),\n                            ),\n                        )\n                    }),\n                )\n            })?;\n\n            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)\n        })\n    }\n\n    fn consider_builtin_fn_ptr_trait_candidate(\n        _ecx: &mut EvalCtxt<'_, D>,\n        _goal: Goal<I, Self>,\n    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {\n        unimplemented!(\"Fn* are not yet const\")\n    }\n\n    #[instrument(level = \"trace\", skip_all, ret)]\n    fn consider_builtin_fn_trait_candidates(\n        ecx: &mut EvalCtxt<'_, D>,\n        goal: Goal<I, Self>,\n        _kind: rustc_type_ir::ClosureKind,\n    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {\n        let cx = ecx.cx();\n\n        let self_ty = goal.predicate.self_ty();\n        let (inputs_and_output, def_id, args) =\n            structural_traits::extract_fn_def_from_const_callable(cx, self_ty)?;\n        let (inputs, output) = ecx.instantiate_binder_with_infer(inputs_and_output);\n\n        // A built-in `Fn` impl only holds if the output is sized.\n        // (FIXME: technically we only need to check this if the type is a fn ptr...)\n        let output_is_sized_pred =","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs#L274-L310","documentation":"`consider_builtin_fn_ptr_trait_candidate` (effect_goals.rs:292) is `unimplemented!` because built-in `Fn`/`FnMut`/`FnOnce` impls for raw fn pointers (`fn(..) -> ..`) are not yet supported under the const/host-effect system. Unlike the truly-unreachable cases, this is a deliberate 'not implemented yet' marker — the compiler knows fn pointers should eventually be const-callable but the candidate builder has not landed.","triggerScenarios":"Reached when the next solver, evaluating a `T: const Fn(..)` (or `FnMut`/`FnOnce`) host-effect goal for a function-pointer self type, reaches the fn-pointer built-in candidate branch (effect_goals.rs:288).","commonSituations":"Calling a `const fn` through a function pointer inside another `const fn`/`const` context under `#![feature(const_for)]`/`host_effects`; storing a `const fn` in a `fn` typed value and then requiring it `~const Fn`.","solutions":["Avoid invoking the target through a fn pointer — call the `const fn` directly by name so the `FnDef` candidate (which IS handled, effect_goals.rs:296) is used instead of the fn-pointer path.","Remove the `const`/`~const Fn` bound that is forcing the fn-pointer candidate.","Upgrade nightly and track the const-fn-ptr implementation status; report the ICE if still present.","Gate the affected module behind a non-const path until the feature stabilizes."],"exampleFix":"// before: const call through a function pointer triggers the unimplemented path\nconst fn add(a: u32, b: u32) -> u32 { a + b }\nconst fn run(f: fn(u32, u32) -> u32) -> u32 { f(1, 2) } // ICE: fn ptr not yet const\n\n// after: call the const fn directly so the FnDef candidate applies\nconst fn add(a: u32, b: u32) -> u32 { a + b }\nconst fn run() -> u32 { add(1, 2) }","handlingStrategy":"validation","validationCode":"// Fn*/FnMut*/FnOnce are explicitly non-const today. Reject closures passed to const eval.\nconst fn reject_fn_in_const<F: Fn()>(_f: &F) {} // will fail effect_goals if the next solver reaches it","typeGuard":"// Narrow away from callable values before entering a const context.\nfn is_closure_or_fn<T: ?Sized>() -> bool { false } // approximated; at the type level keep callables out of const generic params","tryCatchPattern":null,"preventionTips":["Never pass closures or function pointers into `const fn` or `const` generics; Fn* traits are not const-evaluable.","Replace a const-time callable with a monomorphized `const fn` item referenced by name, not a closure.","If you need a const callable, use a marker-type + `const fn` associated function pattern instead of `impl Fn`."],"tags":["rustc-ice","const-traits","host-effects","fn-ptr","nightly","not-yet-implemented"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}