Skip to main content

rustc_mir_build/builder/custom/
parse.rs

1use rustc_data_structures::thin_vec::ThinVec;
2use rustc_index::IndexSlice;
3use rustc_middle::mir::*;
4use rustc_middle::thir::*;
5use rustc_middle::ty::{self, Ty};
6use rustc_span::Span;
7
8use super::{PResult, ParseCtxt, ParseError};
9
10mod instruction;
11
12/// Helper macro for parsing custom MIR.
13///
14/// Example usage looks something like:
15/// ```rust,ignore (incomplete example)
16/// parse_by_kind!(
17///     self, // : &ParseCtxt
18///     expr_id, // what you're matching against
19///     "assignment", // the thing you're trying to parse
20///     @call("mir_assign", args) => { args[0] }, // match invocations of the `mir_assign` special function
21///     ExprKind::Assign { lhs, .. } => { lhs }, // match thir assignment expressions
22///     // no need for fallthrough case - reasonable error is automatically generated
23/// )
24/// ```
25macro_rules! parse_by_kind {
26    (
27        $self:ident,
28        $expr_id:expr,
29        $expr_name:pat,
30        $expected:literal,
31        $(
32            @call($name:ident, $args:ident) => $call_expr:expr,
33        )*
34        $(
35            @variant($adt:ident, $variant:ident) => $variant_expr:expr,
36        )*
37        $(
38            $pat:pat $(if $guard:expr)? => $expr:expr,
39        )*
40    ) => {{
41        let expr_id = $self.preparse($expr_id);
42        let expr = &$self.thir[expr_id];
43        tracing::debug!("Trying to parse {:?} as {}", expr.kind, $expected);
44        let $expr_name = expr;
45        match &expr.kind {
46            $(
47                ExprKind::Call { ty, fun: _, args: $args, .. } if {
48                    match ty.kind() {
49                        ty::FnDef(did, _) => {
50                            $self.tcx.is_diagnostic_item(rustc_span::sym::$name, *did)
51                        }
52                        _ => false,
53                    }
54                } => $call_expr,
55            )*
56            $(
57                ExprKind::Adt(AdtExpr { adt_def, variant_index, .. }) if {
58                    $self.tcx.is_diagnostic_item(rustc_span::sym::$adt, adt_def.did()) &&
59                    adt_def.variants()[*variant_index].name == rustc_span::sym::$variant
60                } => $variant_expr,
61            )*
62            $(
63                $pat $(if $guard)? => $expr,
64            )*
65            #[allow(unreachable_patterns)]
66            _ => return Err($self.expr_error(expr_id, $expected))
67        }
68    }};
69}
70pub(crate) use parse_by_kind;
71
72impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
73    /// Expressions should only ever be matched on after preparsing them. This removes extra scopes
74    /// we don't care about.
75    fn preparse(&self, expr_id: ExprId) -> ExprId {
76        let expr = &self.thir[expr_id];
77        match expr.kind {
78            ExprKind::Scope { value, .. } => self.preparse(value),
79            _ => expr_id,
80        }
81    }
82
83    fn statement_as_expr(&self, stmt_id: StmtId) -> PResult<ExprId> {
84        match &self.thir[stmt_id].kind {
85            StmtKind::Expr { expr, .. } => Ok(*expr),
86            kind @ StmtKind::Let { pattern, .. } => Err(ParseError {
87                span: pattern.span,
88                item_description: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", kind))
    })format!("{kind:?}"),
89                expected: "expression".to_string(),
90            }),
91        }
92    }
93
94    pub(crate) fn parse_args(&mut self, params: &IndexSlice<ParamId, Param<'tcx>>) -> PResult<()> {
95        for param in params.iter() {
96            let (var, span) = {
97                let pat = param.pat.as_ref().unwrap();
98                match &pat.kind {
99                    PatKind::Binding { var, .. } => (*var, pat.span),
100                    _ => {
101                        return Err(ParseError {
102                            span: pat.span,
103                            item_description: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", pat.kind))
    })format!("{:?}", pat.kind),
104                            expected: "local".to_string(),
105                        });
106                    }
107                }
108            };
109            let decl = LocalDecl::new(param.ty, span);
110            let local = self.body.local_decls.push(decl);
111            self.local_map.insert(var, local);
112        }
113
114        Ok(())
115    }
116
117    /// Bodies are of the form:
118    ///
119    /// ```text
120    /// {
121    ///     let bb1: BasicBlock;
122    ///     let bb2: BasicBlock;
123    ///     {
124    ///         let RET: _;
125    ///         let local1;
126    ///         let local2;
127    ///
128    ///         {
129    ///             { // entry block
130    ///                 statement1;
131    ///                 terminator1
132    ///             };
133    ///
134    ///             bb1 = {
135    ///                 statement2;
136    ///                 terminator2
137    ///             };
138    ///
139    ///             bb2 = {
140    ///                 statement3;
141    ///                 terminator3
142    ///             }
143    ///
144    ///             RET
145    ///         }
146    ///     }
147    /// }
148    /// ```
149    ///
150    /// This allows us to easily parse the basic blocks declarations, local declarations, and
151    /// basic block definitions in order.
152    pub(crate) fn parse_body(&mut self, expr_id: ExprId) -> PResult<()> {
153        let body = {
    let expr_id = self.preparse(expr_id);
    let expr = &self.thir[expr_id];
    {
        use ::tracing::__macro_support::Callsite as _;
        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
            {
                static META: ::tracing::Metadata<'static> =
                    {
                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/custom/parse.rs:153",
                            "rustc_mir_build::builder::custom::parse",
                            ::tracing::Level::DEBUG,
                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/custom/parse.rs"),
                            ::tracing_core::__macro_support::Option::Some(153u32),
                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::custom::parse"),
                            ::tracing_core::field::FieldSet::new(&["message"],
                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                            ::tracing::metadata::Kind::EVENT)
                    };
                ::tracing::callsite::DefaultCallsite::new(&META)
            };
        let enabled =
            ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                    ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::LevelFilter::current() &&
                {
                    let interest = __CALLSITE.interest();
                    !interest.is_never() &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest)
                };
        if enabled {
            (|value_set: ::tracing::field::ValueSet|
                        {
                            let meta = __CALLSITE.metadata();
                            ::tracing::Event::dispatch(meta, &value_set);
                            ;
                        })({
                    #[allow(unused_imports)]
                    use ::tracing::field::{debug, display, Value};
                    let mut iter = __CALLSITE.metadata().fields().iter();
                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                        ::tracing::__macro_support::Option::Some(&format_args!("Trying to parse {0:?} as {1}",
                                                        expr.kind, "whole body") as &dyn Value))])
                });
        } else { ; }
    };
    let _ = expr;
    match &expr.kind {
        ExprKind::Block { block } =>
            self.thir[*block].expr.unwrap(),
            #[allow(unreachable_patterns)]
            _ => return Err(self.expr_error(expr_id, "whole body")),
    }
}parse_by_kind!(self, expr_id, _, "whole body",
154            ExprKind::Block { block } => self.thir[*block].expr.unwrap(),
155        );
156        let (block_decls, rest) = {
    let expr_id = self.preparse(body);
    let expr = &self.thir[expr_id];
    {
        use ::tracing::__macro_support::Callsite as _;
        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
            {
                static META: ::tracing::Metadata<'static> =
                    {
                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/custom/parse.rs:156",
                            "rustc_mir_build::builder::custom::parse",
                            ::tracing::Level::DEBUG,
                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/custom/parse.rs"),
                            ::tracing_core::__macro_support::Option::Some(156u32),
                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::custom::parse"),
                            ::tracing_core::field::FieldSet::new(&["message"],
                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                            ::tracing::metadata::Kind::EVENT)
                    };
                ::tracing::callsite::DefaultCallsite::new(&META)
            };
        let enabled =
            ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                    ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::LevelFilter::current() &&
                {
                    let interest = __CALLSITE.interest();
                    !interest.is_never() &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest)
                };
        if enabled {
            (|value_set: ::tracing::field::ValueSet|
                        {
                            let meta = __CALLSITE.metadata();
                            ::tracing::Event::dispatch(meta, &value_set);
                            ;
                        })({
                    #[allow(unused_imports)]
                    use ::tracing::field::{debug, display, Value};
                    let mut iter = __CALLSITE.metadata().fields().iter();
                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                        ::tracing::__macro_support::Option::Some(&format_args!("Trying to parse {0:?} as {1}",
                                                        expr.kind, "body with block decls") as &dyn Value))])
                });
        } else { ; }
    };
    let _ = expr;
    match &expr.kind {
        ExprKind::Block { block } => {
            let block = &self.thir[*block];
            (&block.stmts, block.expr.unwrap())
        }
            #[allow(unreachable_patterns)]
            _ =>
            return Err(self.expr_error(expr_id, "body with block decls")),
    }
}parse_by_kind!(self, body, _, "body with block decls",
157            ExprKind::Block { block } => {
158                let block = &self.thir[*block];
159                (&block.stmts, block.expr.unwrap())
160            },
161        );
162        self.parse_block_decls(block_decls.iter().copied())?;
163
164        let (local_decls, rest) = {
    let expr_id = self.preparse(rest);
    let expr = &self.thir[expr_id];
    {
        use ::tracing::__macro_support::Callsite as _;
        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
            {
                static META: ::tracing::Metadata<'static> =
                    {
                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/custom/parse.rs:164",
                            "rustc_mir_build::builder::custom::parse",
                            ::tracing::Level::DEBUG,
                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/custom/parse.rs"),
                            ::tracing_core::__macro_support::Option::Some(164u32),
                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::custom::parse"),
                            ::tracing_core::field::FieldSet::new(&["message"],
                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                            ::tracing::metadata::Kind::EVENT)
                    };
                ::tracing::callsite::DefaultCallsite::new(&META)
            };
        let enabled =
            ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                    ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::LevelFilter::current() &&
                {
                    let interest = __CALLSITE.interest();
                    !interest.is_never() &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest)
                };
        if enabled {
            (|value_set: ::tracing::field::ValueSet|
                        {
                            let meta = __CALLSITE.metadata();
                            ::tracing::Event::dispatch(meta, &value_set);
                            ;
                        })({
                    #[allow(unused_imports)]
                    use ::tracing::field::{debug, display, Value};
                    let mut iter = __CALLSITE.metadata().fields().iter();
                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                        ::tracing::__macro_support::Option::Some(&format_args!("Trying to parse {0:?} as {1}",
                                                        expr.kind, "body with local decls") as &dyn Value))])
                });
        } else { ; }
    };
    let _ = expr;
    match &expr.kind {
        ExprKind::Block { block } => {
            let block = &self.thir[*block];
            (&block.stmts, block.expr.unwrap())
        }
            #[allow(unreachable_patterns)]
            _ =>
            return Err(self.expr_error(expr_id, "body with local decls")),
    }
}parse_by_kind!(self, rest, _, "body with local decls",
165            ExprKind::Block { block } => {
166                let block = &self.thir[*block];
167                (&block.stmts, block.expr.unwrap())
168            },
169        );
170        self.parse_local_decls(local_decls.iter().copied())?;
171
172        let (debuginfo, rest) = {
    let expr_id = self.preparse(rest);
    let expr = &self.thir[expr_id];
    {
        use ::tracing::__macro_support::Callsite as _;
        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
            {
                static META: ::tracing::Metadata<'static> =
                    {
                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/custom/parse.rs:172",
                            "rustc_mir_build::builder::custom::parse",
                            ::tracing::Level::DEBUG,
                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/custom/parse.rs"),
                            ::tracing_core::__macro_support::Option::Some(172u32),
                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::custom::parse"),
                            ::tracing_core::field::FieldSet::new(&["message"],
                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                            ::tracing::metadata::Kind::EVENT)
                    };
                ::tracing::callsite::DefaultCallsite::new(&META)
            };
        let enabled =
            ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                    ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::LevelFilter::current() &&
                {
                    let interest = __CALLSITE.interest();
                    !interest.is_never() &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest)
                };
        if enabled {
            (|value_set: ::tracing::field::ValueSet|
                        {
                            let meta = __CALLSITE.metadata();
                            ::tracing::Event::dispatch(meta, &value_set);
                            ;
                        })({
                    #[allow(unused_imports)]
                    use ::tracing::field::{debug, display, Value};
                    let mut iter = __CALLSITE.metadata().fields().iter();
                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                        ::tracing::__macro_support::Option::Some(&format_args!("Trying to parse {0:?} as {1}",
                                                        expr.kind, "body with debuginfo") as &dyn Value))])
                });
        } else { ; }
    };
    let _ = expr;
    match &expr.kind {
        ExprKind::Block { block } => {
            let block = &self.thir[*block];
            (&block.stmts, block.expr.unwrap())
        }
            #[allow(unreachable_patterns)]
            _ => return Err(self.expr_error(expr_id, "body with debuginfo")),
    }
}parse_by_kind!(self, rest, _, "body with debuginfo",
173            ExprKind::Block { block } => {
174                let block = &self.thir[*block];
175                (&block.stmts, block.expr.unwrap())
176            },
177        );
178        self.parse_debuginfo(debuginfo.iter().copied())?;
179
180        let block_defs = {
    let expr_id = self.preparse(rest);
    let expr = &self.thir[expr_id];
    {
        use ::tracing::__macro_support::Callsite as _;
        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
            {
                static META: ::tracing::Metadata<'static> =
                    {
                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/custom/parse.rs:180",
                            "rustc_mir_build::builder::custom::parse",
                            ::tracing::Level::DEBUG,
                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/custom/parse.rs"),
                            ::tracing_core::__macro_support::Option::Some(180u32),
                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::custom::parse"),
                            ::tracing_core::field::FieldSet::new(&["message"],
                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                            ::tracing::metadata::Kind::EVENT)
                    };
                ::tracing::callsite::DefaultCallsite::new(&META)
            };
        let enabled =
            ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                    ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::LevelFilter::current() &&
                {
                    let interest = __CALLSITE.interest();
                    !interest.is_never() &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest)
                };
        if enabled {
            (|value_set: ::tracing::field::ValueSet|
                        {
                            let meta = __CALLSITE.metadata();
                            ::tracing::Event::dispatch(meta, &value_set);
                            ;
                        })({
                    #[allow(unused_imports)]
                    use ::tracing::field::{debug, display, Value};
                    let mut iter = __CALLSITE.metadata().fields().iter();
                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                        ::tracing::__macro_support::Option::Some(&format_args!("Trying to parse {0:?} as {1}",
                                                        expr.kind, "body with block defs") as &dyn Value))])
                });
        } else { ; }
    };
    let _ = expr;
    match &expr.kind {
        ExprKind::Block { block } =>
            &self.thir[*block].stmts,
            #[allow(unreachable_patterns)]
            _ => return Err(self.expr_error(expr_id, "body with block defs")),
    }
}parse_by_kind!(self, rest, _, "body with block defs",
181            ExprKind::Block { block } => &self.thir[*block].stmts,
182        );
183        for (i, block_def) in block_defs.iter().enumerate() {
184            let is_cleanup = self.body.basic_blocks_mut()[BasicBlock::from_usize(i)].is_cleanup;
185            let block = self.parse_block_def(self.statement_as_expr(*block_def)?, is_cleanup)?;
186            self.body.basic_blocks_mut()[BasicBlock::from_usize(i)] = block;
187        }
188
189        Ok(())
190    }
191
192    fn parse_block_decls(&mut self, stmts: impl Iterator<Item = StmtId>) -> PResult<()> {
193        for stmt in stmts {
194            self.parse_basic_block_decl(stmt)?;
195        }
196        Ok(())
197    }
198
199    fn parse_basic_block_decl(&mut self, stmt: StmtId) -> PResult<()> {
200        match &self.thir[stmt].kind {
201            StmtKind::Let { pattern, initializer: Some(initializer), .. } => {
202                let (var, ..) = self.parse_var(pattern)?;
203                let data = BasicBlockData::new(
204                    None,
205                    {
    let expr_id = self.preparse(*initializer);
    let expr = &self.thir[expr_id];
    {
        use ::tracing::__macro_support::Callsite as _;
        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
            {
                static META: ::tracing::Metadata<'static> =
                    {
                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/custom/parse.rs:205",
                            "rustc_mir_build::builder::custom::parse",
                            ::tracing::Level::DEBUG,
                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/custom/parse.rs"),
                            ::tracing_core::__macro_support::Option::Some(205u32),
                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::custom::parse"),
                            ::tracing_core::field::FieldSet::new(&["message"],
                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                            ::tracing::metadata::Kind::EVENT)
                    };
                ::tracing::callsite::DefaultCallsite::new(&META)
            };
        let enabled =
            ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                    ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::LevelFilter::current() &&
                {
                    let interest = __CALLSITE.interest();
                    !interest.is_never() &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest)
                };
        if enabled {
            (|value_set: ::tracing::field::ValueSet|
                        {
                            let meta = __CALLSITE.metadata();
                            ::tracing::Event::dispatch(meta, &value_set);
                            ;
                        })({
                    #[allow(unused_imports)]
                    use ::tracing::field::{debug, display, Value};
                    let mut iter = __CALLSITE.metadata().fields().iter();
                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                        ::tracing::__macro_support::Option::Some(&format_args!("Trying to parse {0:?} as {1}",
                                                        expr.kind, "basic block declaration") as &dyn Value))])
                });
        } else { ; }
    };
    let _ = expr;
    match &expr.kind {
        ExprKind::Adt(AdtExpr { adt_def, variant_index, .. }) if
            {
                self.tcx.is_diagnostic_item(rustc_span::sym::mir_basic_block,
                        adt_def.did()) &&
                    adt_def.variants()[*variant_index].name ==
                        rustc_span::sym::Normal
            } => false,
        ExprKind::Adt(AdtExpr { adt_def, variant_index, .. }) if
            {
                self.tcx.is_diagnostic_item(rustc_span::sym::mir_basic_block,
                        adt_def.did()) &&
                    adt_def.variants()[*variant_index].name ==
                        rustc_span::sym::Cleanup
            } =>
            true,
            #[allow(unreachable_patterns)]
            _ =>
            return Err(self.expr_error(expr_id, "basic block declaration")),
    }
}parse_by_kind!(self, *initializer, _, "basic block declaration",
206                        @variant(mir_basic_block, Normal) => false,
207                        @variant(mir_basic_block, Cleanup) => true,
208                    ),
209                );
210                let block = self.body.basic_blocks_mut().push(data);
211                self.block_map.insert(var, block);
212                Ok(())
213            }
214            _ => Err(self.stmt_error(stmt, "let statement with an initializer")),
215        }
216    }
217
218    fn parse_local_decls(&mut self, mut stmts: impl Iterator<Item = StmtId>) -> PResult<()> {
219        let (ret_var, ..) = self.parse_let_statement(stmts.next().unwrap())?;
220        self.local_map.insert(ret_var, Local::ZERO);
221
222        for stmt in stmts {
223            let (var, ty, span) = self.parse_let_statement(stmt)?;
224            let decl = LocalDecl::new(ty, span);
225            let local = self.body.local_decls.push(decl);
226            self.local_map.insert(var, local);
227        }
228
229        Ok(())
230    }
231
232    fn parse_debuginfo(&mut self, stmts: impl Iterator<Item = StmtId>) -> PResult<()> {
233        for stmt in stmts {
234            let stmt = &self.thir[stmt];
235            let expr = match stmt.kind {
236                StmtKind::Let { span, .. } => {
237                    return Err(ParseError {
238                        span,
239                        item_description: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", stmt))
    })format!("{:?}", stmt),
240                        expected: "debuginfo".to_string(),
241                    });
242                }
243                StmtKind::Expr { expr, .. } => expr,
244            };
245            let span = self.thir[expr].span;
246            let (name, operand) = {
    let expr_id = self.preparse(expr);
    let expr = &self.thir[expr_id];
    {
        use ::tracing::__macro_support::Callsite as _;
        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
            {
                static META: ::tracing::Metadata<'static> =
                    {
                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/custom/parse.rs:246",
                            "rustc_mir_build::builder::custom::parse",
                            ::tracing::Level::DEBUG,
                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/custom/parse.rs"),
                            ::tracing_core::__macro_support::Option::Some(246u32),
                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::custom::parse"),
                            ::tracing_core::field::FieldSet::new(&["message"],
                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                            ::tracing::metadata::Kind::EVENT)
                    };
                ::tracing::callsite::DefaultCallsite::new(&META)
            };
        let enabled =
            ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                    ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::LevelFilter::current() &&
                {
                    let interest = __CALLSITE.interest();
                    !interest.is_never() &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest)
                };
        if enabled {
            (|value_set: ::tracing::field::ValueSet|
                        {
                            let meta = __CALLSITE.metadata();
                            ::tracing::Event::dispatch(meta, &value_set);
                            ;
                        })({
                    #[allow(unused_imports)]
                    use ::tracing::field::{debug, display, Value};
                    let mut iter = __CALLSITE.metadata().fields().iter();
                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                        ::tracing::__macro_support::Option::Some(&format_args!("Trying to parse {0:?} as {1}",
                                                        expr.kind, "debuginfo") as &dyn Value))])
                });
        } else { ; }
    };
    let _ = expr;
    match &expr.kind {
        ExprKind::Call { ty, fun: _, args: args, .. } if
            {
                match ty.kind() {
                    ty::FnDef(did, _) => {
                        self.tcx.is_diagnostic_item(rustc_span::sym::mir_debuginfo,
                            *did)
                    }
                    _ => false,
                }
            } => {
            (args[0], args[1])
        }
            #[allow(unreachable_patterns)]
            _ => return Err(self.expr_error(expr_id, "debuginfo")),
    }
}parse_by_kind!(self, expr, _, "debuginfo",
247                @call(mir_debuginfo, args) => {
248                    (args[0], args[1])
249                },
250            );
251            let name = {
    let expr_id = self.preparse(name);
    let expr = &self.thir[expr_id];
    {
        use ::tracing::__macro_support::Callsite as _;
        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
            {
                static META: ::tracing::Metadata<'static> =
                    {
                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/custom/parse.rs:251",
                            "rustc_mir_build::builder::custom::parse",
                            ::tracing::Level::DEBUG,
                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/custom/parse.rs"),
                            ::tracing_core::__macro_support::Option::Some(251u32),
                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::custom::parse"),
                            ::tracing_core::field::FieldSet::new(&["message"],
                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                            ::tracing::metadata::Kind::EVENT)
                    };
                ::tracing::callsite::DefaultCallsite::new(&META)
            };
        let enabled =
            ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                    ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::LevelFilter::current() &&
                {
                    let interest = __CALLSITE.interest();
                    !interest.is_never() &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest)
                };
        if enabled {
            (|value_set: ::tracing::field::ValueSet|
                        {
                            let meta = __CALLSITE.metadata();
                            ::tracing::Event::dispatch(meta, &value_set);
                            ;
                        })({
                    #[allow(unused_imports)]
                    use ::tracing::field::{debug, display, Value};
                    let mut iter = __CALLSITE.metadata().fields().iter();
                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                        ::tracing::__macro_support::Option::Some(&format_args!("Trying to parse {0:?} as {1}",
                                                        expr.kind, "debuginfo") as &dyn Value))])
                });
        } else { ; }
    };
    let _ = expr;
    match &expr.kind {
        ExprKind::Literal { lit, neg: false } =>
            lit,
            #[allow(unreachable_patterns)]
            _ => return Err(self.expr_error(expr_id, "debuginfo")),
    }
}parse_by_kind!(self, name, _, "debuginfo",
252                ExprKind::Literal { lit, neg: false } => lit,
253            );
254            let Some(name) = name.node.str() else {
255                return Err(ParseError {
256                    span,
257                    item_description: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", name))
    })format!("{:?}", name),
258                    expected: "string".to_string(),
259                });
260            };
261            let operand = self.parse_operand(operand)?;
262            let value = match operand {
263                Operand::Constant(c) => VarDebugInfoContents::Const(*c),
264                Operand::Copy(p) | Operand::Move(p) => VarDebugInfoContents::Place(p),
265                Operand::RuntimeChecks(_) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
266            };
267            let dbginfo = VarDebugInfo {
268                name,
269                source_info: SourceInfo { span, scope: self.source_scope },
270                composite: None,
271                argument_index: None,
272                value,
273            };
274            self.body.var_debug_info.push(dbginfo);
275        }
276
277        Ok(())
278    }
279
280    fn parse_let_statement(&mut self, stmt_id: StmtId) -> PResult<(LocalVarId, Ty<'tcx>, Span)> {
281        let pattern = match &self.thir[stmt_id].kind {
282            StmtKind::Let { pattern, .. } => pattern,
283            StmtKind::Expr { expr, .. } => {
284                return Err(self.expr_error(*expr, "let statement"));
285            }
286        };
287
288        self.parse_var(pattern)
289    }
290
291    fn parse_var(&mut self, pat: &Pat<'tcx>) -> PResult<(LocalVarId, Ty<'tcx>, Span)> {
292        match &pat.kind {
293            PatKind::Binding { var, ty, .. } => Ok((*var, *ty, pat.span)),
294            _ => Err(ParseError {
295                span: pat.span,
296                item_description: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", pat.kind))
    })format!("{:?}", pat.kind),
297                expected: "local".to_string(),
298            }),
299        }
300    }
301
302    fn parse_block_def(&self, expr_id: ExprId, is_cleanup: bool) -> PResult<BasicBlockData<'tcx>> {
303        let block = {
    let expr_id = self.preparse(expr_id);
    let expr = &self.thir[expr_id];
    {
        use ::tracing::__macro_support::Callsite as _;
        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
            {
                static META: ::tracing::Metadata<'static> =
                    {
                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/custom/parse.rs:303",
                            "rustc_mir_build::builder::custom::parse",
                            ::tracing::Level::DEBUG,
                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/custom/parse.rs"),
                            ::tracing_core::__macro_support::Option::Some(303u32),
                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::custom::parse"),
                            ::tracing_core::field::FieldSet::new(&["message"],
                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                            ::tracing::metadata::Kind::EVENT)
                    };
                ::tracing::callsite::DefaultCallsite::new(&META)
            };
        let enabled =
            ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                    ::tracing::Level::DEBUG <=
                        ::tracing::level_filters::LevelFilter::current() &&
                {
                    let interest = __CALLSITE.interest();
                    !interest.is_never() &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest)
                };
        if enabled {
            (|value_set: ::tracing::field::ValueSet|
                        {
                            let meta = __CALLSITE.metadata();
                            ::tracing::Event::dispatch(meta, &value_set);
                            ;
                        })({
                    #[allow(unused_imports)]
                    use ::tracing::field::{debug, display, Value};
                    let mut iter = __CALLSITE.metadata().fields().iter();
                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                        ::tracing::__macro_support::Option::Some(&format_args!("Trying to parse {0:?} as {1}",
                                                        expr.kind, "basic block") as &dyn Value))])
                });
        } else { ; }
    };
    let _ = expr;
    match &expr.kind {
        ExprKind::Block { block } =>
            &self.thir[*block],
            #[allow(unreachable_patterns)]
            _ => return Err(self.expr_error(expr_id, "basic block")),
    }
}parse_by_kind!(self, expr_id, _, "basic block",
304            ExprKind::Block { block } => &self.thir[*block],
305        );
306
307        let mut data = BasicBlockData::new(None, is_cleanup);
308        for stmt_id in &*block.stmts {
309            let stmt = self.statement_as_expr(*stmt_id)?;
310            let span = self.thir[stmt].span;
311            let statement = self.parse_statement(stmt)?;
312            data.statements
313                .push(Statement::new(SourceInfo { span, scope: self.source_scope }, statement));
314        }
315
316        let Some(trailing) = block.expr else { return Err(self.expr_error(expr_id, "terminator")) };
317        let span = self.thir[trailing].span;
318        let terminator = self.parse_terminator(trailing)?;
319        data.terminator = Some(Terminator {
320            source_info: SourceInfo { span, scope: self.source_scope },
321            kind: terminator,
322            attributes: ThinVec::new(),
323        });
324
325        Ok(data)
326    }
327}