{"id":"8fc190d57cbbddbc","repo":"rust-lang/rust","slug":"reservation-impl-for-trait-with-assoc-item","errorCode":null,"errorMessage":"reservation impl for trait with assoc item: {:?}","messagePattern":"reservation impl for trait with assoc item: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs","lineNumber":276,"sourceCode":"    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {\n        let cx = ecx.cx();\n\n        let alias_def_id = goal.predicate.alias.expect_projection_def_id();\n        let goal_trait_ref = goal.predicate.alias.trait_ref(cx);\n        let impl_trait_ref = cx.impl_trait_ref(impl_def_id);\n        if !DeepRejectCtxt::relate_rigid_infer(ecx.cx()).args_may_unify(\n            goal.predicate.alias.trait_ref(cx).args,\n            impl_trait_ref.skip_binder().args,\n        ) {\n            return Err(NoSolution.into());\n        }\n\n        // We have to ignore negative impls when projecting.\n        let impl_polarity = cx.impl_polarity(impl_def_id);\n        match impl_polarity {\n            ty::ImplPolarity::Negative => return Err(NoSolution.into()),\n            ty::ImplPolarity::Reservation => {\n                unimplemented!(\"reservation impl for trait with assoc item: {:?}\", goal)\n            }\n            ty::ImplPolarity::Positive => {}\n        };\n\n        ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {\n            let impl_args = ecx.fresh_args_for_item(impl_def_id.into());\n            let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args).skip_norm_wip();\n\n            ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;\n\n            let where_clause_bounds = cx\n                .clauses_of(impl_def_id.into())\n                .iter_instantiated(cx, impl_args)\n                .map(Unnormalized::skip_norm_wip)\n                .map(|clause| goal.with(cx, clause));\n            ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds)?;\n\n            // Bail if the nested goals don't hold here. This is to avoid unnecessarily","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs#L258-L294","documentation":"An `unimplemented!` in `consider_impl_candidate` (projection of an associated item through an impl) when the matched impl has polarity `Reservation` (`#[rustc_reservation_impl]`). Reservation impls are reserved for traits that have NO associated items; the solver does not know how to project an associated type/const through one, so it explicitly bails. Encountering it means a reservation impl was placed on a trait that declares an associated item — a configuration the new solver refuses to handle.","triggerScenarios":"A type has an `#[rustc_reservation_impl] impl Trait for ..` annotation AND `Trait` declares an associated type or associated const, and a `NormalizesTo` goal for that associated item is evaluated (e.g. `<T as Trait>::Item` is normalized). Only reachable on nightly/with the next solver since reservation impls are std-internal.","commonSituations":"Editing `core`/`std`/`alloc` internals where `#[rustc_reservation_impl]` is used (e.g. reserved impls for `Future`, auto traits). Almost never seen in third-party crates; if you see it, you are likely using the attribute incorrectly or added an associated item to a trait that still carries a reservation impl.","solutions":["Remove the associated item from the trait, or remove the `#[rustc_reservation_impl]` attribute from the impl — the two are mutually exclusive for projection.","If you are upstreaming a change to a std trait, consult the reservation-impl contract (the attribute exists to reserve a slot without providing the impl) before adding assoc items.","Report as a rustc bug only if the trait genuinely has no associated items and the panic still fires (then it is a solver dispatch bug)."],"exampleFix":"// before — reservation impl on a trait WITH an associated item\n#[rustc_reservation_impl]\nimpl Trait for () {}\ntrait Trait { type Item; }\n// after — drop the reservation attribute, or drop the associated item\nimpl Trait for () { type Item = (); }\ntrait Trait { type Item; }\n","handlingStrategy":"validation","validationCode":"// A reservation impl (#[rustc_reservation_impl]) is only legal on a\n// marker/auto trait that has NO associated items. Verify before relying\n// on one.\nfn reservation_impl_legal(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {\n    let assoc = tcx.associated_item_def_ids(trait_def_id);\n    assoc.is_empty()\n}","typeGuard":"// True only when the trait is a bare marker with no associated items,\n// i.e. safe to attach a reservation impl to.\nfn is_marker_trait_without_items(tcx: TyCtxt<'_>, did: DefId) -> bool {\n    tcx.associated_item_def_ids(did).is_empty() && tcx.is_auto_trait(did)\n}","tryCatchPattern":"use std::panic;\nmatch panic::catch_unwind(panic::AssertUnwindSafe(|| solver.normalizes_to(goal))) {\n    Ok(v) => v,\n    Err(_) => Err(\"reservation impl requires a trait with no associated items\"),\n}","preventionTips":["Never place `#[rustc_reservation_impl]` on a trait that declares associated items.","Treat reservation impls as reserved for pure marker/auto traits only.","Audit downstream crates that introduce reservation impls against the trait's item list.","If a trait gains an associated item, remove any pre-existing reservation impl."],"tags":["rustc","trait-solver","reservation-impl","associated-types","compiler-internal","ice"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}