{"record":{"id":"942c922c148b393b","repo":"rust-lang/rust-analyzer","slug":"failed-to-make-expr-node-node-from-text-text","errorCode":null,"errorMessage":"Failed to make expr node `{node}` from text `{text}`","messagePattern":"Failed to make expr node `(.+?)` from text `(.+?)`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/syntax/src/ast/make.rs","lineNumber":1386,"sourceCode":"}\n\npub fn expr_let(pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr {\n    expr_from_text(&format!(\"while let {pattern} = {expr} {{}}\"))\n}\n\n#[track_caller]\nfn expr_from_text<E: Into<ast::Expr> + AstNode>(text: &str) -> E {\n    expr_from_text_with_edition(text, Edition::CURRENT)\n}\n\n#[track_caller]\nfn expr_from_text_with_edition<E: Into<ast::Expr> + AstNode>(text: &str, edition: Edition) -> E {\n    let parse = ast::Expr::parse(text, edition);\n    let node = match parse.tree().syntax().descendants().find_map(E::cast) {\n        Some(it) => it,\n        None => {\n            let node = std::any::type_name::<E>();\n            panic!(\"Failed to make expr 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\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 => {","sourceCodeStart":1368,"sourceCodeEnd":1404,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/syntax/src/ast/make.rs#L1368-L1404","documentation":"`expr_from_text(_with_edition)` in `syntax::ast::make` parses the snippet as a Rust expression and casts the first descendant matching type `E`. If the parse yields no node of the expected expression type, it panics naming the type and the offending text. This is an internal invariant failure: an `make::expr_*` constructor was given text that does not produce the expected expression node.","triggerScenarios":"Calling a `make::expr_*` constructor with text that parses to a different syntactic category than `E` or fails to parse entirely (empty string, a statement like `let x = 1;`, a type, or edition-invalid syntax), so `E::cast` finds nothing.","commonSituations":"Interpolating untrusted or user-edited source text into `format!` templates fed to make constructors; assist/fix logic generating empty or malformed fragments; edition mismatches where the expression is only valid in one edition.","solutions":["Check `{text}` in the panic message and ensure it is a single well-formed Rust expression of the type named by `{node}`.","Verify the fragment by running `ast::Expr::parse(text, edition)` and inspecting `parse.errors()` before constructing nodes.","If text comes from user code, sanitize/validate it (extract via parsing and re-serialize) instead of passing raw text.","Confirm the correct `Edition`; use the `_with_edition` variant explicitly for edition-sensitive syntax."],"exampleFix":"// before (panics: `let x = 1;` is not an expr)\nlet e = make::expr_call(f, ta(make::expr_from_text(\"let x = 1;\")));\n// after\nlet e = make::expr_call(f, ta(make::expr_from_text(\"1 + 2\")));","handlingStrategy":"validation","validationCode":"fn expr_text_is_valid(text: &str, edition: span::Edition) -> bool {\n    let parse = syntax::ast::Expr::parse(text, edition);\n    parse.errors().is_empty()\n        && parse.syntax().first_child_or_token().is_some()\n}","typeGuard":"fn as_expr_node<N: Into<syntax::ast::Expr> + syntax::AstNode>(\n    text: &str,\n    edition: span::Edition,\n) -> Option<N> {\n    let parse = syntax::ast::Expr::parse(text, edition);\n    parse.tree().syntax().descendants().find_map(N::cast)\n}","tryCatchPattern":null,"preventionTips":["Validate that snippet text parses as an expression before passing it to `make::expr_*` constructors.","Never feed raw user code or interpolated strings into make constructors without sanitizing.","Check `parse.errors()` during development for generated fragments.","Use the correct `Edition` via the `_with_edition` variants."],"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"}