{"id":"0fb94d40baf8acc1","repo":"rust-lang/rust","slug":"if-we-had-an-explicit-self-we-wouldn-t-be-here","errorCode":null,"errorMessage":"if we had an explicit self, we wouldn't be here","messagePattern":"if we had an explicit self, we wouldn't be here","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_ast/src/ast.rs","lineNumber":2952,"sourceCode":"    /// `self`, `mut self`\n    Value(Mutability),\n    /// `&'lt self`, `&'lt mut self`\n    Region(Option<Lifetime>, Mutability),\n    /// `&'lt pin const self`, `&'lt pin mut self`\n    Pinned(Option<Lifetime>, Mutability),\n    /// `self: TYPE`, `mut self: TYPE`\n    Explicit(Box<Ty>, Mutability),\n}\n\nimpl SelfKind {\n    pub fn to_ref_suggestion(&self) -> String {\n        match self {\n            SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),\n            SelfKind::Region(Some(lt), mutbl) => format!(\"&{lt} {}\", mutbl.prefix_str()),\n            SelfKind::Pinned(None, mutbl) => format!(\"&pin {}\", mutbl.ptr_str()),\n            SelfKind::Pinned(Some(lt), mutbl) => format!(\"&{lt} pin {}\", mutbl.ptr_str()),\n            SelfKind::Value(_) | SelfKind::Explicit(_, _) => {\n                unreachable!(\"if we had an explicit self, we wouldn't be here\")\n            }\n        }\n    }\n}\n\npub type ExplicitSelf = Spanned<SelfKind>;\n\nimpl Param {\n    /// Attempts to cast parameter to `ExplicitSelf`.\n    pub fn to_self(&self) -> Option<ExplicitSelf> {\n        if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {\n            if ident.name == kw::SelfLower {\n                return match self.ty.kind {\n                    TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),\n                    TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {\n                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))\n                    }\n                    TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })","sourceCodeStart":2934,"sourceCodeEnd":2970,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_ast/src/ast.rs#L2934-L2970","documentation":"This `unreachable!` is fired by `SelfKind::to_ref_suggestion` when the receiver is a `SelfKind::Value` (`self` / `mut self`) or `SelfKind::Explicit` (`self: TYPE`). The method only knows how to render a *reference* suggestion string (e.g. `&self`, `&pin mut self`); value/explicit selves have no reference prefix to suggest, so reaching this arm means the caller violated that contract. It is an internal rustc invariant, not a user-visible diagnostic.","triggerScenarios":"A rustc internals caller invokes `SelfKind::to_ref_suggestion()` (or a downstream helper that calls it) on a `SelfKind::Value(..)` or `SelfKind::Explicit(..)` variant — for example, code that builds a `&self`-style suggestion without first excluding value/explicit self kinds. Reachable via lints, suggestions, or HIR lowering paths that ask every `SelfKind` for a reference prefix.","commonSituations":"Custom rustc patches or new lints that want to emit a borrow-receiver suggestion and route all `SelfKind` variants through `to_ref_suggestion` instead of matching only `Region`/`Pinned`. Also surfaces during refactors that change how method receivers are classified.","solutions":["Match only `SelfKind::Region` and `SelfKind::Pinned` before calling `to_ref_suggestion`, and handle `Value`/`Explicit` separately.","If you need a suggestion for value/explicit self, return the original receiver text or use `Mutability::prefix_str()` directly instead of this method.","Add a regression test that exercises the lint/suggestion path with `self`, `mut self`, and `self: Box<Self>` receivers."],"exampleFix":"// before\nlet s = self_kind.to_ref_suggestion();\n\n// after\nlet s = match &self_kind {\n    SelfKind::Region(..) | SelfKind::Pinned(..) => self_kind.to_ref_suggestion(),\n    SelfKind::Value(mutbl) => mutbl.prefix_str().to_string(),\n    SelfKind::Explicit(_, mutbl) => mutbl.prefix_str().to_string(),\n};","handlingStrategy":"type-guard","validationCode":"// Before calling to_ref_suggestion, confirm the SelfKind is a reference form.\nlet kind: &SelfKind = /* ... */;\nlet is_ref = matches!(\n    kind,\n    SelfKind::Region(_, _) | SelfKind::Pinned(_, _)\n);\nif !is_ref {\n    // skip suggestion; kind is Value/Explicit and has no ref form\n}","typeGuard":"fn is_ref_self_kind(kind: &SelfKind) -> bool {\n    matches!(kind, SelfKind::Region(_, _) | SelfKind::Pinned(_, _))\n}","tryCatchPattern":null,"preventionTips":["Never call `to_ref_suggestion()` on `SelfKind::Value` or `SelfKind::Explicit`; the function documents it only handles reference receivers.","Pattern-match on `SelfKind` first and only fall into the reference arm.","Treat `to_ref_suggestion` as a refinement helper, not a total function over the enum."],"tags":["rustc","internals","unreachable","ast","self-receiver"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}