{"record":{"id":"374d147d6d2e8c6a","repo":"rust-lang/rust-analyzer","slug":"failed-to-make-ast-node-node-from-text-text","errorCode":null,"errorMessage":"Failed to make ast node `{node}` from text `{text}`","messagePattern":"Failed to make ast node `(.+?)` from text `(.+?)`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/syntax/src/ast/make.rs","lineNumber":1406,"sourceCode":"    };\n    let node = node.clone_subtree();\n    assert_eq!(node.syntax().text_range().start(), 0.into());\n    node\n}\n\n#[track_caller]\nfn ast_from_text<N: AstNode>(text: &str) -> N {\n    ast_from_text_with_edition(text, Edition::CURRENT)\n}\n\n#[track_caller]\nfn ast_from_text_with_edition<N: AstNode>(text: &str, edition: Edition) -> N {\n    let parse = SourceFile::parse(text, edition);\n    let node = match parse.tree().syntax().descendants().find_map(N::cast) {\n        Some(it) => it,\n        None => {\n            let node = std::any::type_name::<N>();\n            panic!(\"Failed to make ast node `{node}` from text `{text}`\")\n        }\n    };\n    let node = node.clone_subtree();\n    assert_eq!(node.syntax().text_range().start(), 0.into());\n    node\n}\n\npub fn token(kind: SyntaxKind) -> SyntaxToken {\n    tokens::SOURCE_FILE\n        .tree()\n        .syntax()\n        .descendants_with_tokens()\n        .filter_map(|it| it.into_token())\n        .find(|it| it.kind() == kind)\n        .unwrap_or_else(|| panic!(\"unhandled token: {kind:?}\"))\n}\n\npub mod tokens {","sourceCodeStart":1388,"sourceCodeEnd":1424,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/syntax/src/ast/make.rs#L1388-L1424","documentation":"`ast_from_text(_with_edition)` in `syntax::ast::make` parses a snippet as a `SourceFile` and casts the first descendant to the requested AST node type `N`. If the tree contains no node of type `N` (malformed text or a different syntactic category), it panics with the type name and text. Nearly all `make::*` constructors route through this helper, so this panic means a constructor was handed text it cannot build its node from.","triggerScenarios":"Any `make::*` constructor whose `format!` template was filled with malformed content — a bad name/signature in `make::fn_`, an invalid path in `make::path_from_text`, unbalanced delimiters, or an empty string — so `SourceFile::parse` yields no descendant castable to `N`.","commonSituations":"Buggy assists/syntax rewrites interpolating user identifiers containing spaces or operators into templates; empty-string arguments; edition-sensitive syntax fed with the wrong `Edition`; regressions after editing a `make::` template format string.","solutions":["Read `{node}` and `{text}` in the panic to identify which constructor template produced unparseable output.","Fix the caller so interpolated fragments are syntactically valid (validate identifiers/paths before formatting).","Reproduce the text and run `SourceFile::parse(text, edition)` to see parse errors, then adjust the template.","If the syntax is edition-dependent, call the `_with_edition` constructor with the correct `Edition`.","Add a unit test for the `make::` constructor with the previously failing input."],"exampleFix":"// before (panics: `1 +` is not a valid path)\nlet p = make::path_from_text(\"1 +\");\n// after\nlet p = make::path_from_text(\"std::mem::drop\");","handlingStrategy":"validation","validationCode":"fn ast_text_is_valid(text: &str, edition: span::Edition) -> bool {\n    let parse = syntax::SourceFile::parse(text, edition);\n    parse.errors().is_empty()\n}","typeGuard":"fn as_ast_node<N: syntax::AstNode>(text: &str, edition: span::Edition) -> Option<N> {\n    let parse = syntax::SourceFile::parse(text, edition);\n    parse.tree().syntax().descendants().find_map(N::cast)\n}","tryCatchPattern":null,"preventionTips":["Pre-parse template output with `SourceFile::parse` and assert no errors in tests.","Validate interpolated identifiers/paths/types before formatting into make templates.","Keep a unit test per `make::` constructor covering the exact template output.","Pass the correct `Edition` when snippets use edition-specific syntax."],"tags":["ast","make","panic","syntax"],"backgroundTag":"ast-construction-from-text-failed","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}