{"id":"dad17b5fc54551c7","repo":"rust-lang/rust","slug":"must-contain-self-type-as-selfty-propagation-kin","errorCode":null,"errorMessage":"must contain self type as `SelfTy` propagation kind is specified","messagePattern":"must contain self type as `SelfTy` propagation kind is specified","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_ast_lowering/src/delegation/mod.rs","lineNumber":424,"sourceCode":"                            None => hir::Ty { kind, hir_id: self.next_id(), span },\n                        };\n\n                        Some(&*self.arena.alloc(ty))\n                    }\n                    _ => ty,\n                };\n\n                hir::QPath::Resolved(ty, self.arena.alloc(new_path))\n            }\n            hir::QPath::TypeRelative(..) => unreachable!(\"until inherent methods are supported\"),\n        };\n\n        if let Some(hir::DelegationSelfTyPropagationKind::SelfTy(id)) =\n            generics.self_ty_propagation_kind.as_mut()\n        {\n            *id = match new_path {\n                hir::QPath::Resolved(ty, _) => {\n                    ty.expect(\"must contain self type as `SelfTy` propagation kind is specified\")\n                }\n                hir::QPath::TypeRelative(ty, _) => ty,\n            }\n            .hir_id;\n        }\n\n        let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(new_path), span));\n        let args = self.arena.alloc_from_iter(args);\n        let call = self.mk_expr(hir::ExprKind::Call(callee_path, args), span);\n\n        let expr = if res.sig_mapping.map_return {\n            let res = Res::SelfTyAlias {\n                alias_to: res.parent.to_def_id(),\n                is_trait_impl: self.tcx.def_kind(res.parent) == DefKind::Impl { of_trait: true },\n            };\n\n            let ident = Ident::new(kw::SelfUpper, span);\n            let path = self.create_resolved_path(res, ident, span);","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_ast_lowering/src/delegation/mod.rs#L406-L442","documentation":"This `expect` fires in the Rust `rustc_ast_lowering` delegation pass when a `DelegationSelfTyPropagationKind::SelfTy` is registered for a callee path but the resulting `QPath::Resolved` carries `None` for its leading type. Delegation macros that propagate the parent's `Self` type must always attach a self-type to the resolved path; if the path was constructed without one, this internal invariant is violated. It is an ICE (internal compiler error), not a user diagnostic — the front-end is supposed to guarantee the self type is present whenever the propagation kind is set.","triggerScenarios":"Triggered when lowering a `delegate`/`pub reuse` (RFC 3530 delegated items) item where `self_ty_propagation_kind` was set to `SelfTy(_)` but the path used to identify the delegated callee omitted its self-type argument (e.g. an inherent-method delegation that does not yet support a type-relative path — see the adjacent `unreachable!(\"until inherent methods are supported\")` at line 416). The path produced a `QPath::Resolved(None, _)`, then `generics.self_ty_propagation_kind` is `Some(SelfTy(_))` at line 419, so the `.expect` at line 424 is hit.","commonSituations":"Developers experimenting with the nightly `fn_delegation` feature (e.g. `#![feature(fn_delegation)]`) hit this when combining delegation with method-call paths (`delegate * to self.method;`), delegating across impl blocks with unusual generic-self propagation, or using a rustc build where the delegation dir is mid-refactor. It is a known limitation area marked with `FIXME(fn_delegation)`.","solutions":["File an issue at https://github.com/rust-lang/rust/issues with the ICE backtrace and a minimal `#![feature(fn_delegation)]` reproducer; this is a compiler bug, not your code.","Rewrite the delegation to avoid inherent-method / type-relative callee paths — delegate to a free function or trait method path that resolves to a unit/`Self`-typed path instead.","Update to a newer nightly: the delegation dir changes frequently and the self-type-propagation invariant may already be fixed for your case.","If you are hacking on rustc itself, audit `lower_qpath`/`create_generic_arg_path` (around `delegation/mod.rs:400-410`) to ensure a `Ty` is always allocated when `self_ty_propagation_kind` is set."],"exampleFix":"// before — delegating to an inherent method path (unsupported, trips the invariant)\n#![feature(fn_delegation)]\nimpl S {\n    delegate * to self.method; // path resolves TypeRelative/Resolved(None)\n}\n\n// after — delegate to a free function or fully self-typed trait path\n#![feature(fn_delegation)]\nimpl S {\n    delegate * to Trait::method; // resolves with a self type attached\n}","handlingStrategy":"validation","validationCode":"// Self-propagating delegation requires `Self` to resolve in the\n// enclosing item. Validate BEFORE relying on implicit Self propagation:\n// 1. Confirm the delegate lives inside an `impl`/trait-impl with a receiver.\n// 2. Prefer an explicit propagation kind instead of leaving it implicit.\n//\n// Safe pattern (explicit target, no implicit SelfTy inference):\n//   impl T for Foo {\n//       pub delegate::to(Bar::method); // Bar::method's Self == Foo\n//   }\n// Pre-commit grep to catch risky bare `delegate::to(...)` outside impls:\n//   rg -n 'delegate::to\\(' --type rust | rg -v 'impl '","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use self-propagating `delegate` inside impl blocks where `Self` is in scope","Specify the propagation kind explicitly rather than relying on lowering-time inference","Delegation + SelfTy propagation is nightly-only; pin the toolchain and syntax you tested against","This is an ICE (panic in rustc), not a recoverable API error — file a bug with a minimized repro"],"tags":["rustc","ast-lowering","delegation","ice","nightly"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}