From eb4b4c80b028d8db36285a4b1f12c4af1cbbb6ed Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 10 Aug 2021 23:09:44 -0500 Subject: [PATCH 01/16] Initial work --- compiler/rustc_ast/src/mut_visit.rs | 15 +++++++++++---- compiler/rustc_expand/src/expand.rs | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 87950b44083ef..b757236697df0 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1369,12 +1369,19 @@ pub fn noop_filter_map_expr(mut e: P, vis: &mut T) -> Optio } pub fn noop_flat_map_stmt( - Stmt { kind, mut span, mut id }: Stmt, + Stmt { kind, span, id }: Stmt, vis: &mut T, ) -> SmallVec<[Stmt; 1]> { - vis.visit_id(&mut id); - vis.visit_span(&mut span); - noop_flat_map_stmt_kind(kind, vis).into_iter().map(|kind| Stmt { id, kind, span }).collect() + let mut id = Some(id); + let res = noop_flat_map_stmt_kind(kind, vis).into_iter().map(|kind| { + let mut new_id = id.take().unwrap_or(DUMMY_NODE_ID); + let mut new_span = span; + vis.visit_id(&mut new_id); + vis.visit_span(&mut new_span); + Stmt { kind, span: new_span, id: new_id } + }).collect(); + tracing::info!("Made new statements: {:?}", res); + res } pub fn noop_flat_map_stmt_kind( diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 3629e668fa9f8..bd81b20207b31 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -20,6 +20,7 @@ use rustc_attr::is_builtin_attr; use rustc_data_structures::map_in_place::MapInPlace; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::Features; use rustc_parse::parser::{ @@ -50,6 +51,7 @@ macro_rules! ast_fragments { ) => { /// A fragment of AST that can be produced by a single macro expansion. /// Can also serve as an input and intermediate result for macro expansion operations. + #[derive(Debug)] pub enum AstFragment { OptExpr(Option>), $($Kind($AstTy),)* @@ -422,6 +424,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } }; self.cx.trace_macros_diag(); + check_ast(&mut krate); krate } @@ -528,6 +531,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let (fragment, collected_invocations) = self.collect_invocations(fragment, &derive_placeholders); + tracing::info!("Collected invocations: {:?}", fragment); // We choose to expand any derive invocations associated with this macro invocation // *before* any macro invocations collected from the output fragment derive_invocations.extend(collected_invocations); @@ -1627,3 +1631,22 @@ impl<'feat> ExpansionConfig<'feat> { self.features.map_or(false, |features| features.proc_macro_hygiene) } } + +fn check_ast(krate: &mut ast::Crate) { + struct AstChecker { + ids: FxHashSet, + } + impl MutVisitor for AstChecker { + fn visit_id(&mut self, id: &mut ast::NodeId) { + if *id != ast::DUMMY_NODE_ID && !self.ids.insert(*id) { + panic!("Duplicate id: {:?}", id); + } + } + fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { + tracing::info!("Visiting stmt: {:?}", stmt); + ast::mut_visit::noop_flat_map_stmt(stmt, self) + } + } + tracing::info!("Full ast: {:?}", krate); + //AstChecker { ids: Default::default() }.visit_crate(krate); +} From 6d07d723a992b60e01a24aa99c5bfb2378824423 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 10 Aug 2021 23:28:07 -0500 Subject: [PATCH 02/16] Work on removal of Stmt NodeId --- compiler/rustc_ast/src/ast.rs | 19 ++++++++++++++----- compiler/rustc_ast/src/ast_like.rs | 6 +++--- compiler/rustc_ast/src/mut_visit.rs | 15 ++++++++------- compiler/rustc_ast/src/visit.rs | 4 ++-- compiler/rustc_ast_lowering/src/lib.rs | 10 +++++----- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- .../src/deriving/debug.rs | 2 +- .../rustc_builtin_macros/src/deriving/mod.rs | 1 - compiler/rustc_expand/src/base.rs | 2 -- compiler/rustc_expand/src/build.rs | 9 ++++----- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_expand/src/placeholders.rs | 7 ++++--- compiler/rustc_interface/src/util.rs | 2 -- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/early.rs | 4 ++-- .../rustc_lint/src/redundant_semicolon.rs | 4 ++-- compiler/rustc_parse/src/lib.rs | 2 +- compiler/rustc_parse/src/parser/stmt.rs | 8 ++++---- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 2 +- 20 files changed, 55 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 8cab83707dcbc..c8eb6f899c10e 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -908,18 +908,26 @@ impl UnOp { /// A statement #[derive(Clone, Encodable, Decodable, Debug)] pub struct Stmt { - pub id: NodeId, pub kind: StmtKind, pub span: Span, } impl Stmt { + pub fn id(&self) -> NodeId { + match self.kind { + StmtKind::Local(ref local) => local.id, + StmtKind::Item(ref item) => item.id, + StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.id, + StmtKind::Empty { id } => id, + StmtKind::MacCall(ref mac) => mac.id, + } + } pub fn tokens(&self) -> Option<&LazyTokenStream> { match self.kind { StmtKind::Local(ref local) => local.tokens.as_ref(), StmtKind::Item(ref item) => item.tokens.as_ref(), StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.tokens.as_ref(), - StmtKind::Empty => None, + StmtKind::Empty { id: _ } => None, StmtKind::MacCall(ref mac) => mac.tokens.as_ref(), } } @@ -943,8 +951,8 @@ impl Stmt { self.kind = match self.kind { StmtKind::Expr(expr) => StmtKind::Semi(expr), StmtKind::MacCall(mac) => { - StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| { - MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens } + StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens, id }| { + MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens, id } })) } kind => kind, @@ -973,13 +981,14 @@ pub enum StmtKind { /// Expr with a trailing semi-colon. Semi(P), /// Just a trailing semi-colon. - Empty, + Empty { id: NodeId }, /// Macro. MacCall(P), } #[derive(Clone, Encodable, Decodable, Debug)] pub struct MacCallStmt { + pub id: NodeId, pub mac: MacCall, pub style: MacStmtStyle, pub attrs: AttrVec, diff --git a/compiler/rustc_ast/src/ast_like.rs b/compiler/rustc_ast/src/ast_like.rs index d586426d70ef0..c443f1a2ecca1 100644 --- a/compiler/rustc_ast/src/ast_like.rs +++ b/compiler/rustc_ast/src/ast_like.rs @@ -106,7 +106,7 @@ impl AstLike for StmtKind { StmtKind::Local(local) => local.attrs(), StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.attrs(), StmtKind::Item(item) => item.attrs(), - StmtKind::Empty => &[], + StmtKind::Empty { id: _ } => &[], StmtKind::MacCall(mac) => &mac.attrs, } } @@ -116,7 +116,7 @@ impl AstLike for StmtKind { StmtKind::Local(local) => local.visit_attrs(f), StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f), StmtKind::Item(item) => item.visit_attrs(f), - StmtKind::Empty => {} + StmtKind::Empty { id: _ } => {} StmtKind::MacCall(mac) => visit_attrvec(&mut mac.attrs, f), } } @@ -125,7 +125,7 @@ impl AstLike for StmtKind { StmtKind::Local(local) => &mut local.tokens, StmtKind::Item(item) => &mut item.tokens, StmtKind::Expr(expr) | StmtKind::Semi(expr) => &mut expr.tokens, - StmtKind::Empty => return None, + StmtKind::Empty { id: _ } => return None, StmtKind::MacCall(mac) => &mut mac.tokens, }) } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index b757236697df0..11f9d7702204a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1369,16 +1369,13 @@ pub fn noop_filter_map_expr(mut e: P, vis: &mut T) -> Optio } pub fn noop_flat_map_stmt( - Stmt { kind, span, id }: Stmt, + Stmt { kind, span }: Stmt, vis: &mut T, ) -> SmallVec<[Stmt; 1]> { - let mut id = Some(id); let res = noop_flat_map_stmt_kind(kind, vis).into_iter().map(|kind| { - let mut new_id = id.take().unwrap_or(DUMMY_NODE_ID); let mut new_span = span; - vis.visit_id(&mut new_id); vis.visit_span(&mut new_span); - Stmt { kind, span: new_span, id: new_id } + Stmt { kind, span: new_span } }).collect(); tracing::info!("Made new statements: {:?}", res); res @@ -1396,9 +1393,13 @@ pub fn noop_flat_map_stmt_kind( StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(), StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(), StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(), - StmtKind::Empty => smallvec![StmtKind::Empty], + StmtKind::Empty { mut id } => { + vis.visit_id(&mut id); + smallvec![StmtKind::Empty { id }] + }, StmtKind::MacCall(mut mac) => { - let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); + let MacCallStmt { mac: mac_, style: _, attrs, tokens, id } = mac.deref_mut(); + vis.visit_id(id); vis.visit_mac_call(mac_); visit_thin_attrs(attrs, vis); visit_lazy_tts(tokens, vis); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 1ebfcf367110f..0223f778851d3 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -691,9 +691,9 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) { StmtKind::Local(ref local) => visitor.visit_local(local), StmtKind::Item(ref item) => visitor.visit_item(item), StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr), - StmtKind::Empty => {} + StmtKind::Empty { id: _ } => {} StmtKind::MacCall(ref mac) => { - let MacCallStmt { ref mac, style: _, ref attrs, tokens: _ } = **mac; + let MacCallStmt { ref mac, style: _, ref attrs, tokens: _, id: _ } = **mac; visitor.visit_mac_call(mac); for attr in attrs.iter() { visitor.visit_attribute(attr); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 581f177ad14f6..550dd4c43c8f7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2418,7 +2418,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let (hir_id, kind) = match s.kind { StmtKind::Local(ref l) => { let l = self.lower_local(l); - let hir_id = self.lower_node_id(s.id); + let hir_id = self.lower_node_id(s.id()); self.alias_attrs(hir_id, l.hir_id); return smallvec![hir::Stmt { hir_id, @@ -2428,7 +2428,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } StmtKind::Item(ref it) => { // Can only use the ID once. - let mut id = Some(s.id); + let mut id = Some(s.id()); return self .lower_item_id(it) .into_iter() @@ -2444,17 +2444,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } StmtKind::Expr(ref e) => { let e = self.lower_expr(e); - let hir_id = self.lower_node_id(s.id); + let hir_id = self.lower_node_id(s.id()); self.alias_attrs(hir_id, e.hir_id); (hir_id, hir::StmtKind::Expr(e)) } StmtKind::Semi(ref e) => { let e = self.lower_expr(e); - let hir_id = self.lower_node_id(s.id); + let hir_id = self.lower_node_id(s.id()); self.alias_attrs(hir_id, e.hir_id); (hir_id, hir::StmtKind::Semi(e)) } - StmtKind::Empty => return smallvec![], + StmtKind::Empty { id: _ } => return smallvec![], StmtKind::MacCall(..) => panic!("shouldn't exist here"), }; smallvec![hir::Stmt { hir_id, kind, span: s.span }] diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index b910431b1ddf1..ba5e445e65178 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1527,7 +1527,7 @@ impl<'a> State<'a> { self.print_expr_outer_attr_style(expr, false); self.s.word(";"); } - ast::StmtKind::Empty => { + ast::StmtKind::Empty { id: _ } => { self.space_if_not_bol(); self.s.word(";"); } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index cc6dac52d7663..cc9c5cd6872cb 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -141,5 +141,5 @@ fn stmt_let_underscore(cx: &mut ExtCtxt<'_>, sp: Span, expr: P) -> as attrs: ast::AttrVec::new(), tokens: None, }); - ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp } + ast::Stmt { kind: ast::StmtKind::Local(local), span: sp } } diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 7dea6099f8f1b..472d7d431eaec 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -61,7 +61,6 @@ impl MultiItemModifier for BuiltinDerive { // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx' // to the function items.push(Annotatable::Stmt(P(ast::Stmt { - id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(a.expect_item()), span, }))); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index b454737fb8077..b17836d798737 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -339,7 +339,6 @@ macro_rules! make_stmts_default { ($me:expr) => { $me.make_expr().map(|e| { smallvec![ast::Stmt { - id: ast::DUMMY_NODE_ID, span: e.span, kind: ast::StmtKind::Expr(e), }] @@ -581,7 +580,6 @@ impl MacResult for DummyResult { fn make_stmts(self: Box) -> Option> { Some(smallvec![ast::Stmt { - id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.is_error)), span: self.span, }]) diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 824df2757ea90..4841bb3731cb8 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -140,7 +140,7 @@ impl<'a> ExtCtxt<'a> { } pub fn stmt_expr(&self, expr: P) -> ast::Stmt { - ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) } + ast::Stmt { span: expr.span, kind: ast::StmtKind::Expr(expr) } } pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P) -> ast::Stmt { @@ -159,7 +159,7 @@ impl<'a> ExtCtxt<'a> { attrs: AttrVec::new(), tokens: None, }); - ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp } + ast::Stmt { kind: ast::StmtKind::Local(local), span: sp } } // Generates `let _: Type;`, which is usually used for type assertions. @@ -173,18 +173,17 @@ impl<'a> ExtCtxt<'a> { attrs: AttrVec::new(), tokens: None, }); - ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span } + ast::Stmt { kind: ast::StmtKind::Local(local), span } } pub fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt { - ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(item), span: sp } + ast::Stmt { kind: ast::StmtKind::Item(item), span: sp } } pub fn block_expr(&self, expr: P) -> P { self.block( expr.span, vec![ast::Stmt { - id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr), }], diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index bd81b20207b31..c937917fa6d88 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1316,7 +1316,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } if let StmtKind::MacCall(mac) = stmt.kind { - let MacCallStmt { mac, style, attrs, tokens: _ } = mac.into_inner(); + let MacCallStmt { mac, style, attrs, tokens: _, id: _ } = mac.into_inner(); self.check_attributes(&attrs, &mac); let mut placeholder = self.collect_bang(mac, stmt.span, AstFragmentKind::Stmts).make_stmts(); diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 8e78fcbb8dbc1..f1d617929715a 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -104,8 +104,9 @@ pub fn placeholder( style: ast::MacStmtStyle::Braces, attrs: ast::AttrVec::new(), tokens: None, + id, }); - ast::Stmt { id, span, kind: ast::StmtKind::MacCall(mac) } + ast::Stmt { span, kind: ast::StmtKind::MacCall(mac) } }]), AstFragmentKind::Arms => AstFragment::Arms(smallvec![ast::Arm { attrs: Default::default(), @@ -297,7 +298,7 @@ impl MutVisitor for PlaceholderExpander { fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { let (style, mut stmts) = match stmt.kind { - ast::StmtKind::MacCall(mac) => (mac.style, self.remove(stmt.id).make_stmts()), + ast::StmtKind::MacCall(ref mac) => (mac.style, self.remove(stmt.id()).make_stmts()), _ => return noop_flat_map_stmt(stmt, self), }; @@ -324,7 +325,7 @@ impl MutVisitor for PlaceholderExpander { // FIXME: We will need to preserve the original semicolon token and // span as part of #15701 let empty_stmt = - ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Empty, span: DUMMY_SP }; + ast::Stmt { kind: ast::StmtKind::Empty { id: ast::DUMMY_NODE_ID }, span: DUMMY_SP }; if let Some(stmt) = stmts.pop() { if stmt.has_trailing_semicolon() { diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 8b41a0ff17693..9e52380ffdf9e 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -823,7 +823,6 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { }); ast::Stmt { - id: resolver.next_node_id(), kind: ast::StmtKind::Expr(expr), span: rustc_span::DUMMY_SP, } @@ -839,7 +838,6 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { }); let loop_stmt = ast::Stmt { - id: self.resolver.next_node_id(), span: rustc_span::DUMMY_SP, kind: ast::StmtKind::Expr(loop_expr), }; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 31d0d917f9093..13cb70f757e39 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1037,7 +1037,7 @@ impl EarlyLintPass for UnusedDocComment { // Disabled pending discussion in #78306 ast::StmtKind::Item(..) => return, // expressions will be reported by `check_expr`. - ast::StmtKind::Empty + ast::StmtKind::Empty { id: _ } | ast::StmtKind::Semi(_) | ast::StmtKind::Expr(_) | ast::StmtKind::MacCall(_) => return, diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 7a8b731da5c2e..d08fa07ce7ac3 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -135,9 +135,9 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> // // Note that statements get their attributes from // the AST struct that they wrap (e.g. an item) - self.with_lint_attrs(s.id, s.attrs(), |cx| { + self.with_lint_attrs(s.id(), s.attrs(), |cx| { run_early_pass!(cx, check_stmt, s); - cx.check_id(s.id); + cx.check_id(s.id()); }); // The visitor for the AST struct wrapped // by the statement (e.g. `Item`) will call diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs index 0fe6564880f01..72a56fd56f0ed 100644 --- a/compiler/rustc_lint/src/redundant_semicolon.rs +++ b/compiler/rustc_lint/src/redundant_semicolon.rs @@ -31,8 +31,8 @@ impl EarlyLintPass for RedundantSemicolons { let mut seq = None; for stmt in block.stmts.iter() { match (&stmt.kind, &mut seq) { - (StmtKind::Empty, None) => seq = Some((stmt.span, false)), - (StmtKind::Empty, Some(seq)) => *seq = (seq.0.to(stmt.span), true), + (StmtKind::Empty { id: _ }, None) => seq = Some((stmt.span, false)), + (StmtKind::Empty { id: _ }, Some(seq)) => *seq = (seq.0.to(stmt.span), true), (_, seq) => maybe_lint_redundant_semis(cx, seq), } } diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index ed3b51dc14a78..328455d9b0977 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -263,7 +263,7 @@ pub fn nt_to_tokenstream( Nonterminal::NtItem(ref item) => prepend_attrs(&item.attrs, item.tokens.as_ref()), Nonterminal::NtBlock(ref block) => convert_tokens(block.tokens.as_ref()), Nonterminal::NtStmt(ref stmt) => { - if let ast::StmtKind::Empty = stmt.kind { + if let ast::StmtKind::Empty { id: _ } = stmt.kind { let tokens = AttrAnnotatedTokenStream::new(vec![( tokenstream::AttrAnnotatedTokenTree::Token(Token::new( TokenKind::Semi, diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 9ef3f61ec346b..1463106ed5d00 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -86,7 +86,7 @@ impl<'a> Parser<'a> { } else if self.eat(&token::Semi) { // Do not attempt to parse an expression if we're done here. self.error_outer_attrs(&attrs.take_for_recovery()); - self.mk_stmt(lo, StmtKind::Empty) + self.mk_stmt(lo, StmtKind::Empty { id: DUMMY_NODE_ID }) } else if self.token != token::CloseDelim(token::Brace) { // Remainder are line-expr stmts. let e = if force_collect == ForceCollect::Yes { @@ -156,7 +156,7 @@ impl<'a> Parser<'a> { let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof { - StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None })) + StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None, id: DUMMY_NODE_ID })) } else { // Since none of the above applied, this is an expression statement macro. let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new()); @@ -507,7 +507,7 @@ impl<'a> Parser<'a> { } eat_semi = false; } - StmtKind::Empty | StmtKind::Item(_) | StmtKind::Semi(_) => eat_semi = false, + StmtKind::Empty { id: _ } | StmtKind::Item(_) | StmtKind::Semi(_) => eat_semi = false, } if eat_semi && self.eat(&token::Semi) { @@ -522,7 +522,7 @@ impl<'a> Parser<'a> { } pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt { - Stmt { id: DUMMY_NODE_ID, kind, span } + Stmt { kind, span } } pub(super) fn mk_stmt_err(&self, span: Span) -> Stmt { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 178d727418d74..1c2d24fa8eba0 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1349,7 +1349,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { fn visit_stmt(&mut self, stmt: &'b ast::Stmt) { if let ast::StmtKind::MacCall(..) = stmt.kind { - self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id); + self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id()); } else { visit::walk_stmt(self, stmt); } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 6f4f1bdaea1b7..66d9c5ba96ef0 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -300,7 +300,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { fn visit_stmt(&mut self, stmt: &'a Stmt) { match stmt.kind { - StmtKind::MacCall(..) => self.visit_macro_invoc(stmt.id), + StmtKind::MacCall(..) => self.visit_macro_invoc(stmt.id()), _ => visit::walk_stmt(self, stmt), } } From 001ef61b367cd3ff533c5b941b155eb486442521 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 10 Aug 2021 23:46:56 -0500 Subject: [PATCH 03/16] Work on removing HirId from hir::Stmt --- compiler/rustc_ast_lowering/src/lib.rs | 20 ++++++------------- compiler/rustc_hir/src/hir.rs | 13 ++++++++++-- compiler/rustc_hir/src/intravisit.rs | 1 - compiler/rustc_lint/src/late.rs | 2 +- .../rustc_middle/src/hir/map/collector.rs | 8 -------- compiler/rustc_mir_build/src/thir/cx/block.rs | 2 +- compiler/rustc_passes/src/hir_stats.rs | 2 +- compiler/rustc_passes/src/region.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 2 +- 9 files changed, 22 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 550dd4c43c8f7..920568f984c92 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2415,30 +2415,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> { - let (hir_id, kind) = match s.kind { + let kind = match s.kind { StmtKind::Local(ref l) => { let l = self.lower_local(l); let hir_id = self.lower_node_id(s.id()); self.alias_attrs(hir_id, l.hir_id); return smallvec![hir::Stmt { - hir_id, kind: hir::StmtKind::Local(self.arena.alloc(l)), span: s.span, }]; } StmtKind::Item(ref it) => { - // Can only use the ID once. - let mut id = Some(s.id()); return self .lower_item_id(it) .into_iter() .map(|item_id| { - let hir_id = id - .take() - .map(|id| self.lower_node_id(id)) - .unwrap_or_else(|| self.next_id()); - - hir::Stmt { hir_id, kind: hir::StmtKind::Item(item_id), span: s.span } + hir::Stmt { kind: hir::StmtKind::Item(item_id), span: s.span } }) .collect(); } @@ -2446,18 +2438,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let e = self.lower_expr(e); let hir_id = self.lower_node_id(s.id()); self.alias_attrs(hir_id, e.hir_id); - (hir_id, hir::StmtKind::Expr(e)) + hir::StmtKind::Expr(e) } StmtKind::Semi(ref e) => { let e = self.lower_expr(e); let hir_id = self.lower_node_id(s.id()); self.alias_attrs(hir_id, e.hir_id); - (hir_id, hir::StmtKind::Semi(e)) + hir::StmtKind::Semi(e) } StmtKind::Empty { id: _ } => return smallvec![], StmtKind::MacCall(..) => panic!("shouldn't exist here"), }; - smallvec![hir::Stmt { hir_id, kind, span: s.span }] + smallvec![hir::Stmt { kind, span: s.span }] } fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode { @@ -2492,7 +2484,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Helper methods for building HIR. fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> { - hir::Stmt { span, kind, hir_id: self.next_id() } + hir::Stmt { span, kind } } fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index fe1d190b4ec1a..a52af4ed42df3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1162,7 +1162,6 @@ impl UnOp { /// A statement. #[derive(Debug, HashStable_Generic)] pub struct Stmt<'hir> { - pub hir_id: HirId, pub kind: StmtKind<'hir>, pub span: Span, } @@ -1183,6 +1182,16 @@ pub enum StmtKind<'hir> { Semi(&'hir Expr<'hir>), } +impl<'hir> StmtKind<'hir> { + pub fn hir_id(&self) -> HirId { + match self { + StmtKind::Local(local) => local.hir_id, + StmtKind::Item(id) => id.hir_id(), + StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.hir_id, + } + } +} + /// Represents a `let` statement (i.e., `let : = ;`). #[derive(Debug, HashStable_Generic)] pub struct Local<'hir> { @@ -3233,7 +3242,6 @@ impl<'hir> Node<'hir> { Node::Field(FieldDef { hir_id, .. }) | Node::AnonConst(AnonConst { hir_id, .. }) | Node::Expr(Expr { hir_id, .. }) - | Node::Stmt(Stmt { hir_id, .. }) | Node::Ty(Ty { hir_id, .. }) | Node::Binding(Pat { hir_id, .. }) | Node::Pat(Pat { hir_id, .. }) @@ -3244,6 +3252,7 @@ impl<'hir> Node<'hir> { | Node::Param(Param { hir_id, .. }) | Node::Infer(InferArg { hir_id, .. }) | Node::GenericParam(GenericParam { hir_id, .. }) => Some(*hir_id), + Node::Stmt(stmt) => Some(stmt.kind.hir_id()), Node::TraitRef(TraitRef { hir_ref_id, .. }) => Some(*hir_ref_id), Node::PathSegment(PathSegment { hir_id, .. }) => *hir_id, Node::Variant(Variant { id, .. }) => Some(*id), diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index ae186d66004d7..d9f0db4c03366 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1102,7 +1102,6 @@ pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block<'v>) { } pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) { - visitor.visit_id(statement.hir_id); match statement.kind { StmtKind::Local(ref local) => visitor.visit_local(local), StmtKind::Item(item) => visitor.visit_nested_item(item), diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 052efa851f7cf..b513e8cf98c37 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -180,7 +180,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) { // See `EarlyContextAndPass::visit_stmt` for an explanation // of why we call `walk_stmt` outside of `with_lint_attrs` - self.with_lint_attrs(s.hir_id, |cx| { + self.with_lint_attrs(s.kind.hir_id(), |cx| { lint_callback!(cx, check_stmt, s); }); hir_visit::walk_stmt(self, s); diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index 5c166c74004a3..3592989d9fdf5 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -313,14 +313,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { }); } - fn visit_stmt(&mut self, stmt: &'hir Stmt<'hir>) { - self.insert(stmt.span, stmt.hir_id, Node::Stmt(stmt)); - - self.with_parent(stmt.hir_id, |this| { - intravisit::walk_stmt(this, stmt); - }); - } - fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment<'hir>) { if let Some(hir_id) = path_segment.hir_id { self.insert(path_span, hir_id, Node::PathSegment(path_segment)); diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 2d9b5c1d98aab..6f43df657130e 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -45,7 +45,7 @@ impl<'tcx> Cx<'tcx> { .iter() .enumerate() .filter_map(|(index, stmt)| { - let hir_id = stmt.hir_id; + let hir_id = stmt.kind.hir_id(); let opt_dxn_ext = self.region_scope_tree.opt_destruction_scope(hir_id.local_id); match stmt.kind { hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 2bed8cadeb95d..624a527010d69 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -145,7 +145,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { } fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) { - self.record("Stmt", Id::Node(s.hir_id), s); + self.record("Stmt", Id::Node(s.kind.hir_id()), s); hir_visit::walk_stmt(self, s) } diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs index c133f1a041719..90ffdfdaea021 100644 --- a/compiler/rustc_passes/src/region.rs +++ b/compiler/rustc_passes/src/region.rs @@ -185,7 +185,7 @@ fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir } fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx hir::Stmt<'tcx>) { - let stmt_id = stmt.hir_id.local_id; + let stmt_id = stmt.kind.hir_id().local_id; debug!("resolve_stmt(stmt.id={:?})", stmt_id); // Every statement will clean up the temporaries created during diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index f65cc429fbd48..b7dc534869726 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -567,7 +567,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {} } - self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement"); + self.warn_if_unreachable(stmt.kind.hir_id(), stmt.span, "statement"); // Hide the outer diverging and `has_errors` flags. let old_diverges = self.diverges.replace(Diverges::Maybe); From 0534576c8cc8ad890f1e0a47477d5daa3f73ceef Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 10 Aug 2021 23:56:26 -0500 Subject: [PATCH 04/16] Don't enter duplicate scope --- compiler/rustc_passes/src/region.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs index 90ffdfdaea021..8c091e14aee45 100644 --- a/compiler/rustc_passes/src/region.rs +++ b/compiler/rustc_passes/src/region.rs @@ -196,7 +196,6 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h visitor.terminating_scopes.insert(stmt_id); let prev_parent = visitor.cx.parent; - visitor.enter_node_scope_with_dtor(stmt_id); intravisit::walk_stmt(visitor, stmt); From ea0b13cc5f9bb3e6f44e16fe6f110a339db49eaa Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 11 Aug 2021 00:01:18 -0500 Subject: [PATCH 05/16] Create dtor scope for locals --- compiler/rustc_passes/src/region.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs index 8c091e14aee45..e2d67d2b90363 100644 --- a/compiler/rustc_passes/src/region.rs +++ b/compiler/rustc_passes/src/region.rs @@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; -use rustc_hir::{Arm, Block, Expr, Local, Node, Pat, PatKind, Stmt}; +use rustc_hir::{Arm, Block, Expr, Local, Node, Pat, PatKind, Stmt, HirId}; use rustc_index::vec::Idx; use rustc_middle::middle::region::*; use rustc_middle::ty::query::Providers; @@ -432,6 +432,7 @@ fn resolve_local<'tcx>( visitor: &mut RegionResolutionVisitor<'tcx>, pat: Option<&'tcx hir::Pat<'tcx>>, init: Option<&'tcx hir::Expr<'tcx>>, + local_hir_id: Option, ) { debug!("resolve_local(pat={:?}, init={:?})", pat, init); @@ -493,6 +494,10 @@ fn resolve_local<'tcx>( // A, but the inner rvalues `a()` and `b()` have an extended lifetime // due to rule C. + if let Some(hir_id) = local_hir_id { + visitor.enter_node_scope_with_dtor(hir_id.local_id); + } + if let Some(expr) = init { record_rvalue_scope_if_borrow_expr(visitor, &expr, blk_scope); @@ -767,7 +772,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { // (i.e., `'static`), which means that after `g` returns, it drops, // and all the associated destruction scope rules apply. self.cx.var_parent = None; - resolve_local(self, None, Some(&body.value)); + resolve_local(self, None, Some(&body.value), None); } if body.generator_kind.is_some() { @@ -794,7 +799,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { resolve_expr(self, ex); } fn visit_local(&mut self, l: &'tcx Local<'tcx>) { - resolve_local(self, Some(&l.pat), l.init.as_deref()); + resolve_local(self, Some(&l.pat), l.init.as_deref(), Some(l.hir_id)); } } From 5771bdb203029fc705993562d9be6cb76387ee71 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 11 Aug 2021 21:51:38 -0500 Subject: [PATCH 06/16] Fix lowering of hir statements --- compiler/rustc_ast_lowering/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 920568f984c92..fef26852a25ba 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2418,8 +2418,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let kind = match s.kind { StmtKind::Local(ref l) => { let l = self.lower_local(l); - let hir_id = self.lower_node_id(s.id()); - self.alias_attrs(hir_id, l.hir_id); return smallvec![hir::Stmt { kind: hir::StmtKind::Local(self.arena.alloc(l)), span: s.span, @@ -2436,14 +2434,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } StmtKind::Expr(ref e) => { let e = self.lower_expr(e); - let hir_id = self.lower_node_id(s.id()); - self.alias_attrs(hir_id, e.hir_id); hir::StmtKind::Expr(e) } StmtKind::Semi(ref e) => { let e = self.lower_expr(e); - let hir_id = self.lower_node_id(s.id()); - self.alias_attrs(hir_id, e.hir_id); hir::StmtKind::Semi(e) } StmtKind::Empty { id: _ } => return smallvec![], From 97ab6d804118be99302d32fe50f52fb38b32fd64 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 10:29:40 -0500 Subject: [PATCH 07/16] Undo some stuff --- compiler/rustc_passes/src/region.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs index e2d67d2b90363..c133f1a041719 100644 --- a/compiler/rustc_passes/src/region.rs +++ b/compiler/rustc_passes/src/region.rs @@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; -use rustc_hir::{Arm, Block, Expr, Local, Node, Pat, PatKind, Stmt, HirId}; +use rustc_hir::{Arm, Block, Expr, Local, Node, Pat, PatKind, Stmt}; use rustc_index::vec::Idx; use rustc_middle::middle::region::*; use rustc_middle::ty::query::Providers; @@ -185,7 +185,7 @@ fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir } fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx hir::Stmt<'tcx>) { - let stmt_id = stmt.kind.hir_id().local_id; + let stmt_id = stmt.hir_id.local_id; debug!("resolve_stmt(stmt.id={:?})", stmt_id); // Every statement will clean up the temporaries created during @@ -196,6 +196,7 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h visitor.terminating_scopes.insert(stmt_id); let prev_parent = visitor.cx.parent; + visitor.enter_node_scope_with_dtor(stmt_id); intravisit::walk_stmt(visitor, stmt); @@ -432,7 +433,6 @@ fn resolve_local<'tcx>( visitor: &mut RegionResolutionVisitor<'tcx>, pat: Option<&'tcx hir::Pat<'tcx>>, init: Option<&'tcx hir::Expr<'tcx>>, - local_hir_id: Option, ) { debug!("resolve_local(pat={:?}, init={:?})", pat, init); @@ -494,10 +494,6 @@ fn resolve_local<'tcx>( // A, but the inner rvalues `a()` and `b()` have an extended lifetime // due to rule C. - if let Some(hir_id) = local_hir_id { - visitor.enter_node_scope_with_dtor(hir_id.local_id); - } - if let Some(expr) = init { record_rvalue_scope_if_borrow_expr(visitor, &expr, blk_scope); @@ -772,7 +768,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { // (i.e., `'static`), which means that after `g` returns, it drops, // and all the associated destruction scope rules apply. self.cx.var_parent = None; - resolve_local(self, None, Some(&body.value), None); + resolve_local(self, None, Some(&body.value)); } if body.generator_kind.is_some() { @@ -799,7 +795,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { resolve_expr(self, ex); } fn visit_local(&mut self, l: &'tcx Local<'tcx>) { - resolve_local(self, Some(&l.pat), l.init.as_deref(), Some(l.hir_id)); + resolve_local(self, Some(&l.pat), l.init.as_deref()); } } From d31dd804d74a1d1059e4866e5f50d661507bda1f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 11:17:17 -0500 Subject: [PATCH 08/16] Add for_stmt --- compiler/rustc_middle/src/ich/impls_hir.rs | 9 ++++ compiler/rustc_middle/src/middle/region.rs | 26 +++++----- compiler/rustc_middle/src/thir.rs | 2 +- compiler/rustc_mir_build/src/build/mod.rs | 4 +- compiler/rustc_mir_build/src/thir/cx/block.rs | 8 +++- compiler/rustc_mir_build/src/thir/cx/expr.rs | 28 +++++------ compiler/rustc_passes/src/region.rs | 48 +++++++++++-------- .../src/check/generator_interior.rs | 2 +- 8 files changed, 75 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_middle/src/ich/impls_hir.rs b/compiler/rustc_middle/src/ich/impls_hir.rs index 5dfd00bc6d42c..3c300422b4aab 100644 --- a/compiler/rustc_middle/src/ich/impls_hir.rs +++ b/compiler/rustc_middle/src/ich/impls_hir.rs @@ -123,6 +123,15 @@ impl<'a> ToStableHashKey> for hir::ItemLocalId { } } +impl<'a> ToStableHashKey> for (hir::ItemLocalId, bool) { + type KeyType = (hir::ItemLocalId, bool); + + #[inline] + fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> (hir::ItemLocalId, bool) { + *self + } +} + impl<'a> HashStable> for hir::Body<'_> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let hir::Body { params, value, generator_kind } = self; diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index f44267a404bf3..5403ef78dda5e 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -84,21 +84,23 @@ use std::fmt; #[derive(HashStable)] pub struct Scope { pub id: hir::ItemLocalId, + pub for_stmt: bool, pub data: ScopeData, } impl fmt::Debug for Scope { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self.data { - ScopeData::Node => write!(fmt, "Node({:?})", self.id), - ScopeData::CallSite => write!(fmt, "CallSite({:?})", self.id), - ScopeData::Arguments => write!(fmt, "Arguments({:?})", self.id), - ScopeData::Destruction => write!(fmt, "Destruction({:?})", self.id), + ScopeData::Node => write!(fmt, "Node({:?}, {:?})", self.id, self.for_stmt), + ScopeData::CallSite => write!(fmt, "CallSite({:?}. {:?})", self.id, self.for_stmt), + ScopeData::Arguments => write!(fmt, "Arguments({:?}, {:?})", self.id, self.for_stmt), + ScopeData::Destruction => write!(fmt, "Destruction({:?}, {:?})", self.id, self.for_stmt), ScopeData::Remainder(fsi) => write!( fmt, - "Remainder {{ block: {:?}, first_statement_index: {}}}", + "Remainder {{ block: {:?}, first_statement_index: {}, for_stmt: {:?}}}", self.id, fsi.as_u32(), + self.for_stmt, ), } } @@ -223,7 +225,7 @@ pub struct ScopeTree { var_map: FxHashMap, /// Maps from a `NodeId` to the associated destruction scope (if any). - destruction_scopes: FxHashMap, + destruction_scopes: FxHashMap<(hir::ItemLocalId, bool), Scope>, /// `rvalue_scopes` includes entries for those expressions whose /// cleanup scope is larger than the default. The map goes from the @@ -331,17 +333,17 @@ impl ScopeTree { if let Some(p) = parent { let prev = self.parent_map.insert(child, p); - assert!(prev.is_none()); + assert!(prev.is_none(), "Scope {:?} with parent {:?} has prev {:?}", child, p, prev); } // Record the destruction scopes for later so we can query them. if let ScopeData::Destruction = child.data { - self.destruction_scopes.insert(child.item_local_id(), child); + assert_eq!(self.destruction_scopes.insert((child.item_local_id(), child.for_stmt), child), None); } } - pub fn opt_destruction_scope(&self, n: hir::ItemLocalId) -> Option { - self.destruction_scopes.get(&n).cloned() + pub fn opt_destruction_scope(&self, n: hir::ItemLocalId, for_stmt: bool) -> Option { + self.destruction_scopes.get(&(n, for_stmt)).cloned() } pub fn record_var_scope(&mut self, var: hir::ItemLocalId, lifetime: Scope) { @@ -372,7 +374,7 @@ impl ScopeTree { } /// Returns the scope when the temp created by `expr_id` will be cleaned up. - pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> Option { + pub fn temporary_scope(&self, expr_id: hir::ItemLocalId, for_stmt: bool) -> Option { // Check for a designated rvalue scope. if let Some(&s) = self.rvalue_scopes.get(&expr_id) { debug!("temporary_scope({:?}) = {:?} [custom]", expr_id, s); @@ -383,7 +385,7 @@ impl ScopeTree { // if there's one. Static items, for instance, won't // have an enclosing scope, hence no scope will be // returned. - let mut id = Scope { id: expr_id, data: ScopeData::Node }; + let mut id = Scope { id: expr_id, data: ScopeData::Node, for_stmt }; while let Some(&(p, _)) = self.parent_map.get(&id) { match p.data { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index cdefc9effa1e9..120200891aaa4 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -189,7 +189,7 @@ pub enum StmtKind<'tcx> { // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Expr<'_>, 104); +rustc_data_structures::static_assert_size!(Expr<'_>, 112); /// A THIR expression. #[derive(Debug, HashStable)] diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 0d623806eb7e1..2d6890d4e45e7 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -625,9 +625,9 @@ where ); let call_site_scope = - region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite }; + region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite, for_stmt: false }; let arg_scope = - region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::Arguments }; + region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::Arguments, for_stmt: false }; let source_info = builder.source_info(span); let call_site_s = (call_site_scope, source_info); unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 6f43df657130e..05335bc65f4e9 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -13,12 +13,13 @@ impl<'tcx> Cx<'tcx> { // in order to get the lexical scoping correctly. let stmts = self.mirror_stmts(block.hir_id.local_id, block.stmts); let opt_destruction_scope = - self.region_scope_tree.opt_destruction_scope(block.hir_id.local_id); + self.region_scope_tree.opt_destruction_scope(block.hir_id.local_id, false); Block { targeted_by_break: block.targeted_by_break, region_scope: region::Scope { id: block.hir_id.local_id, data: region::ScopeData::Node, + for_stmt: false, }, opt_destruction_scope, span: block.span, @@ -46,7 +47,7 @@ impl<'tcx> Cx<'tcx> { .enumerate() .filter_map(|(index, stmt)| { let hir_id = stmt.kind.hir_id(); - let opt_dxn_ext = self.region_scope_tree.opt_destruction_scope(hir_id.local_id); + let opt_dxn_ext = self.region_scope_tree.opt_destruction_scope(hir_id.local_id, true); match stmt.kind { hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { let stmt = Stmt { @@ -54,6 +55,7 @@ impl<'tcx> Cx<'tcx> { scope: region::Scope { id: hir_id.local_id, data: region::ScopeData::Node, + for_stmt: true, }, expr: self.mirror_expr(expr), }, @@ -71,6 +73,7 @@ impl<'tcx> Cx<'tcx> { data: region::ScopeData::Remainder(region::FirstStatementIndex::new( index, )), + for_stmt: false, }; let mut pattern = self.pattern_from_hir(local.pat); @@ -101,6 +104,7 @@ impl<'tcx> Cx<'tcx> { init_scope: region::Scope { id: hir_id.local_id, data: region::ScopeData::Node, + for_stmt: true, }, pattern, initializer: local.init.map(|init| self.mirror_expr(init)), diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c3908ddd4fbe8..3e20e7f3a40b6 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -31,9 +31,9 @@ impl<'tcx> Cx<'tcx> { } pub(super) fn mirror_expr_inner(&mut self, hir_expr: &'tcx hir::Expr<'tcx>) -> ExprId { - let temp_lifetime = self.region_scope_tree.temporary_scope(hir_expr.hir_id.local_id); + let temp_lifetime = self.region_scope_tree.temporary_scope(hir_expr.hir_id.local_id, false); let expr_scope = - region::Scope { id: hir_expr.hir_id.local_id, data: region::ScopeData::Node }; + region::Scope { id: hir_expr.hir_id.local_id, data: region::ScopeData::Node, for_stmt: false }; debug!("Expr::make_mirror(): id={}, span={:?}", hir_expr.hir_id, hir_expr.span); @@ -59,7 +59,7 @@ impl<'tcx> Cx<'tcx> { // Finally, create a destruction scope, if any. if let Some(region_scope) = - self.region_scope_tree.opt_destruction_scope(hir_expr.hir_id.local_id) + self.region_scope_tree.opt_destruction_scope(hir_expr.hir_id.local_id, false) { expr = Expr { temp_lifetime, @@ -150,7 +150,7 @@ impl<'tcx> Cx<'tcx> { fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> { let expr_ty = self.typeck_results().expr_ty(expr); - let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); + let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id, false); let kind = match expr.kind { // Here comes the interesting stuff: @@ -499,7 +499,7 @@ impl<'tcx> Cx<'tcx> { ), }; let temp_lifetime = - self.region_scope_tree.temporary_scope(expr.hir_id.local_id); + self.region_scope_tree.temporary_scope(expr.hir_id.local_id, false); let res = self.typeck_results().qpath_res(qpath, expr.hir_id); let ty; match res { @@ -579,14 +579,14 @@ impl<'tcx> Cx<'tcx> { } hir::ExprKind::Break(dest, ref value) => match dest.target_id { Ok(target_id) => ExprKind::Break { - label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node }, + label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node, for_stmt: false, }, value: value.as_ref().map(|value| self.mirror_expr(value)), }, Err(err) => bug!("invalid loop id for break: {}", err), }, hir::ExprKind::Continue(dest) => match dest.target_id { Ok(loop_id) => ExprKind::Continue { - label: region::Scope { id: loop_id.local_id, data: region::ScopeData::Node }, + label: region::Scope { id: loop_id.local_id, data: region::ScopeData::Node, for_stmt: false, }, }, Err(err) => bug!("invalid loop id for continue: {}", err), }, @@ -601,7 +601,7 @@ impl<'tcx> Cx<'tcx> { }, hir::ExprKind::Loop(ref body, ..) => { let block_ty = self.typeck_results().node_type(body.hir_id); - let temp_lifetime = self.region_scope_tree.temporary_scope(body.hir_id.local_id); + let temp_lifetime = self.region_scope_tree.temporary_scope(body.hir_id.local_id, false); let block = self.mirror_block(body); let body = self.thir.exprs.push(Expr { ty: block_ty, @@ -800,7 +800,7 @@ impl<'tcx> Cx<'tcx> { span: Span, overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>, ) -> Expr<'tcx> { - let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); + let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id, false); let (def_id, substs, user_ty) = match overloaded_callee { Some((def_id, substs)) => (def_id, substs, None), None => { @@ -837,7 +837,7 @@ impl<'tcx> Cx<'tcx> { }), body: self.mirror_expr(arm.body), lint_level: LintLevel::Explicit(arm.hir_id), - scope: region::Scope { id: arm.hir_id.local_id, data: region::ScopeData::Node }, + scope: region::Scope { id: arm.hir_id.local_id, data: region::ScopeData::Node, for_stmt: false }, span: arm.span, }; self.thir.arms.push(arm) @@ -922,7 +922,7 @@ impl<'tcx> Cx<'tcx> { // a constant reference (or constant raw pointer for `static mut`) in MIR Res::Def(DefKind::Static, id) => { let ty = self.tcx.static_ptr_ty(id); - let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); + let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id, false); let kind = if self.tcx.is_thread_local_static(id) { ExprKind::ThreadLocalRef(id) } else { @@ -1006,7 +1006,7 @@ impl<'tcx> Cx<'tcx> { // construct the complete expression `foo()` for the overloaded call, // which will yield the &T type - let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); + let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id, false); let fun = self.method_callee(expr, span, overloaded_callee); let fun = self.thir.exprs.push(fun); let fun_ty = self.thir[fun].ty; @@ -1026,7 +1026,7 @@ impl<'tcx> Cx<'tcx> { closure_expr: &'tcx hir::Expr<'tcx>, place: HirPlace<'tcx>, ) -> Expr<'tcx> { - let temp_lifetime = self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id); + let temp_lifetime = self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id, false); let var_ty = place.base_ty; // The result of capture analysis in `rustc_typeck/check/upvar.rs`represents a captured path @@ -1081,7 +1081,7 @@ impl<'tcx> Cx<'tcx> { let upvar_capture = captured_place.info.capture_kind; let captured_place_expr = self.convert_captured_hir_place(closure_expr, captured_place.place.clone()); - let temp_lifetime = self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id); + let temp_lifetime = self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id, false); match upvar_capture { ty::UpvarCapture::ByValue(_) => captured_place_expr, diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs index c133f1a041719..4c77bf8404c09 100644 --- a/compiler/rustc_passes/src/region.rs +++ b/compiler/rustc_passes/src/region.rs @@ -67,7 +67,7 @@ struct RegionResolutionVisitor<'tcx> { /// arbitrary amounts of stack space. Terminating scopes end /// up being contained in a DestructionScope that contains the /// destructor's execution. - terminating_scopes: FxHashSet, + terminating_scopes: FxHashSet<(hir::ItemLocalId, bool)>, } /// Records the lifetime of a local variable as `cx.var_parent` @@ -116,7 +116,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h // `other_argument()` has run and also the call to `quux(..)` // itself has returned. - visitor.enter_node_scope_with_dtor(blk.hir_id.local_id); + visitor.enter_node_scope_with_dtor(blk.hir_id.local_id, false); visitor.cx.var_parent = visitor.cx.parent; { @@ -137,6 +137,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h visitor.enter_scope(Scope { id: blk.hir_id.local_id, data: ScopeData::Remainder(FirstStatementIndex::new(i)), + for_stmt: false, }); visitor.cx.var_parent = visitor.cx.parent; } @@ -153,13 +154,13 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir::Arm<'tcx>) { let prev_cx = visitor.cx; - visitor.enter_scope(Scope { id: arm.hir_id.local_id, data: ScopeData::Node }); + visitor.enter_scope(Scope { id: arm.hir_id.local_id, data: ScopeData::Node, for_stmt: false }); visitor.cx.var_parent = visitor.cx.parent; - visitor.terminating_scopes.insert(arm.body.hir_id.local_id); + visitor.terminating_scopes.insert((arm.body.hir_id.local_id, false)); if let Some(hir::Guard::If(ref expr)) = arm.guard { - visitor.terminating_scopes.insert(expr.hir_id.local_id); + visitor.terminating_scopes.insert((expr.hir_id.local_id, false)); } intravisit::walk_arm(visitor, arm); @@ -168,7 +169,7 @@ fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir } fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir::Pat<'tcx>) { - visitor.record_child_scope(Scope { id: pat.hir_id.local_id, data: ScopeData::Node }); + visitor.record_child_scope(Scope { id: pat.hir_id.local_id, data: ScopeData::Node, for_stmt: false }); // If this is a binding then record the lifetime of that binding. if let PatKind::Binding(..) = pat.kind { @@ -185,18 +186,25 @@ fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir } fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx hir::Stmt<'tcx>) { - let stmt_id = stmt.hir_id.local_id; - debug!("resolve_stmt(stmt.id={:?})", stmt_id); + debug!("resolve_stmt(stmt.kind.hir_id={:?})", stmt.kind.hir_id()); // Every statement will clean up the temporaries created during // execution of that statement. Therefore each statement has an // associated destruction scope that represents the scope of the // statement plus its destructors, and thus the scope for which // regions referenced by the destructors need to survive. - visitor.terminating_scopes.insert(stmt_id); + // let prev_parent = visitor.cx.parent; - visitor.enter_node_scope_with_dtor(stmt_id); + + match &stmt.kind { + kind @ (hir::StmtKind::Local(_) | hir::StmtKind::Expr(_) | hir::StmtKind::Semi(_)) => { + let local_id = kind.hir_id().local_id; + visitor.terminating_scopes.insert((local_id, true)); + visitor.enter_node_scope_with_dtor(local_id, true); + } + hir::StmtKind::Item(_) => {} + } intravisit::walk_stmt(visitor, stmt); @@ -207,12 +215,12 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr); let prev_cx = visitor.cx; - visitor.enter_node_scope_with_dtor(expr.hir_id.local_id); + visitor.enter_node_scope_with_dtor(expr.hir_id.local_id, false); { let terminating_scopes = &mut visitor.terminating_scopes; let mut terminating = |id: hir::ItemLocalId| { - terminating_scopes.insert(id); + terminating_scopes.insert((id, false)); }; match expr.kind { // Conditional or repeating scopes are always terminating @@ -401,7 +409,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h if let hir::ExprKind::Yield(_, source) = &expr.kind { // Mark this expr's scope and all parent scopes as containing `yield`. - let mut scope = Scope { id: expr.hir_id.local_id, data: ScopeData::Node }; + let mut scope = Scope { id: expr.hir_id.local_id, data: ScopeData::Node, for_stmt: false }; loop { let data = YieldData { span: expr.span, @@ -687,15 +695,15 @@ impl<'tcx> RegionResolutionVisitor<'tcx> { self.cx.parent = Some((child_scope, child_depth)); } - fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) { + fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId, for_stmt: bool) { // If node was previously marked as a terminating scope during the // recursive visit of its parent node in the AST, then we need to // account for the destruction scope representing the scope of // the destructors that run immediately after it completes. - if self.terminating_scopes.contains(&id) { - self.enter_scope(Scope { id, data: ScopeData::Destruction }); + if self.terminating_scopes.contains(&(id, for_stmt)) { + self.enter_scope(Scope { id, data: ScopeData::Destruction, for_stmt }); } - self.enter_scope(Scope { id, data: ScopeData::Node }); + self.enter_scope(Scope { id, data: ScopeData::Node, for_stmt }); } } @@ -733,10 +741,10 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { // control flow assumptions. This doesn't apply to nested // bodies within the `+=` statements. See #69307. let outer_pessimistic_yield = mem::replace(&mut self.pessimistic_yield, false); - self.terminating_scopes.insert(body.value.hir_id.local_id); + self.terminating_scopes.insert((body.value.hir_id.local_id, false)); - self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::CallSite }); - self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::Arguments }); + self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::CallSite, for_stmt: false }); + self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::Arguments, for_stmt: false }); // The arguments and `self` are parented to the fn. self.cx.var_parent = self.cx.parent.take(); diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 5f26e701c0ab7..c908402e5a9dd 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -337,7 +337,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { self.expr_count += 1; - let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); + let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id, false); // If there are adjustments, then record the final type -- // this is the actual value that is being produced. From b4e2c4e48038b13c1f9024abe10ceecf85252c9a Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 11:24:11 -0500 Subject: [PATCH 09/16] Change stderr --- .../async-await/issue-70935-complex-spans.stderr | 4 ++-- .../issues/issue-65436-raw-ptr-not-send.stderr | 4 ++-- .../borrowck/borrowck-borrowed-uniq-rvalue.stderr | 2 +- src/test/ui/borrowck/issue-17545.stderr | 5 +++-- src/test/ui/issues/issue-47646.stderr | 2 +- src/test/ui/loops/loop-no-implicit-break.stderr | 11 +++-------- .../issue-54382-use-span-of-tail-of-block.stderr | 8 ++++---- .../issue-54556-temps-in-tail-diagnostic.stderr | 8 ++++---- .../nll/issue-54556-used-vs-unused-tails.stderr | 11 +++++++---- .../regions/regions-var-type-out-of-scope.stderr | 5 +++-- .../span/borrowck-let-suggestion-suffixes.stderr | 6 +++--- .../ui/static/static-reference-to-fn-2.stderr | 15 +++++++++------ src/test/ui/thir-tree.stdout | 12 ++++++------ 13 files changed, 48 insertions(+), 45 deletions(-) diff --git a/src/test/ui/async-await/issue-70935-complex-spans.stderr b/src/test/ui/async-await/issue-70935-complex-spans.stderr index 8451fb840992c..1b88476d01207 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.stderr @@ -13,10 +13,10 @@ LL | | foo(tx.clone()); LL | | }).await; | |________________^ first, await occurs here, with the value maybe used later... note: the value is later dropped here - --> $DIR/issue-70935-complex-spans.rs:15:17 + --> $DIR/issue-70935-complex-spans.rs:15:16 | LL | }).await; - | ^ + | ^ note: this has type `[closure@$DIR/issue-70935-complex-spans.rs:13:13: 15:10]` which is not `Send` --> $DIR/issue-70935-complex-spans.rs:13:13 | diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr index 5568dab86556a..5d34290fa51a6 100644 --- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr +++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr @@ -14,10 +14,10 @@ note: future is not `Send` as this value is used across an await LL | bar(Foo(std::ptr::null())).await; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ first, await occurs here, with `std::ptr::null()` maybe used later... note: `std::ptr::null()` is later dropped here - --> $DIR/issue-65436-raw-ptr-not-send.rs:14:41 + --> $DIR/issue-65436-raw-ptr-not-send.rs:14:40 | LL | bar(Foo(std::ptr::null())).await; - | ---------------- ^ + | ---------------- ^ | | | has type `*const u8` which is not `Send` help: consider moving this into a `let` binding to create a shorter lived borrow diff --git a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr index c91a4377b4c67..28d1c9395330d 100644 --- a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr +++ b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowck-borrowed-uniq-rvalue.rs:10:28 | LL | buggy_map.insert(42, &*Box::new(1)); - | ^^^^^^^^^^^ - temporary value is freed at the end of this statement + | ^^^^^^^^^^^- temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use ... diff --git a/src/test/ui/borrowck/issue-17545.stderr b/src/test/ui/borrowck/issue-17545.stderr index 79a1e09bd7cc6..bb9fef4b4c519 100644 --- a/src/test/ui/borrowck/issue-17545.stderr +++ b/src/test/ui/borrowck/issue-17545.stderr @@ -7,8 +7,9 @@ LL | / bar.call(( LL | | &id(()), | | ^^^^^^ creates a temporary which is freed while still in use LL | | )); - | | -- temporary value is freed at the end of this statement - | |______| + | | - + | | | + | |______temporary value is freed at the end of this statement | argument requires that borrow lasts for `'a` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-47646.stderr b/src/test/ui/issues/issue-47646.stderr index b46c277d04566..a3d7ff14a4a9b 100644 --- a/src/test/ui/issues/issue-47646.stderr +++ b/src/test/ui/issues/issue-47646.stderr @@ -11,7 +11,7 @@ LL | println!("{:?}", heap); | ^^^^ immutable borrow occurs here ... LL | }; - | - ... and the mutable borrow might be used here, when that temporary is dropped and runs the destructor for type `(Option>, ())` + | - ... and the mutable borrow might be used here, when that temporary is dropped and runs the destructor for type `(Option>, ())` error: aborting due to previous error diff --git a/src/test/ui/loops/loop-no-implicit-break.stderr b/src/test/ui/loops/loop-no-implicit-break.stderr index 8a1afdea24936..9a8e0d9a640e6 100644 --- a/src/test/ui/loops/loop-no-implicit-break.stderr +++ b/src/test/ui/loops/loop-no-implicit-break.stderr @@ -3,11 +3,6 @@ error[E0308]: mismatched types | LL | 1 | ^ expected `()`, found integer - | -help: you might have meant to break the loop with this value - | -LL | break 1; - | +++++ + error[E0308]: mismatched types --> $DIR/loop-no-implicit-break.rs:13:9 @@ -15,10 +10,10 @@ error[E0308]: mismatched types LL | 1 | ^ expected `()`, found integer | -help: you might have meant to break the loop with this value +help: you might have meant to return this value | -LL | break 1; - | +++++ + +LL | return 1; + | ++++++ + error[E0308]: mismatched types --> $DIR/loop-no-implicit-break.rs:21:9 diff --git a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr index 6dacfd1f264c6..cb45c1f5fdc07 100644 --- a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr +++ b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr @@ -8,10 +8,10 @@ LL | D("other").next(&_thing1) | a temporary with access to the borrow is created here ... ... LL | } - | - `_thing1` dropped here while still borrowed -LL | -LL | ; - | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` + | - + | | + | `_thing1` dropped here while still borrowed + | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped | diff --git a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr index 68d3cef8aa13b..c1a7dcfb595c1 100644 --- a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr +++ b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr @@ -7,10 +7,10 @@ LL | D(&_thing1).end() | | borrowed value does not live long enough | a temporary with access to the borrow is created here ... LL | } - | - `_thing1` dropped here while still borrowed -LL | -LL | ; - | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` + | - + | | + | `_thing1` dropped here while still borrowed + | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped | diff --git a/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr b/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr index 25226e2967353..c8012e0f2f7d7 100644 --- a/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr +++ b/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr @@ -2,9 +2,10 @@ error[E0597]: `_t1` does not live long enough --> $DIR/issue-54556-used-vs-unused-tails.rs:10:55 | LL | { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // suggest `;` - | --^^^^- - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` + | --^^^^- - | | | | | | | `_t1` dropped here while still borrowed + | | | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | borrowed value does not live long enough | a temporary with access to the borrow is created here ... | @@ -17,7 +18,7 @@ error[E0597]: `_t1` does not live long enough --> $DIR/issue-54556-used-vs-unused-tails.rs:13:55 | LL | { { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } } ; // suggest `;` - | --^^^^- - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` + | --^^^^- - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | | | | | | `_t1` dropped here while still borrowed | | borrowed value does not live long enough @@ -32,9 +33,10 @@ error[E0597]: `_t1` does not live long enough --> $DIR/issue-54556-used-vs-unused-tails.rs:16:55 | LL | { { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }; } // suggest `;` - | --^^^^- -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` + | --^^^^- - | | | | | | | `_t1` dropped here while still borrowed + | | | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | borrowed value does not live long enough | a temporary with access to the borrow is created here ... | @@ -94,9 +96,10 @@ error[E0597]: `_t1` does not live long enough --> $DIR/issue-54556-used-vs-unused-tails.rs:30:55 | LL | _y = { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // `let x = ...; x` - | --^^^^- - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` + | --^^^^- - | | | | | | | `_t1` dropped here while still borrowed + | | | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | borrowed value does not live long enough | a temporary with access to the borrow is created here ... | diff --git a/src/test/ui/regions/regions-var-type-out-of-scope.stderr b/src/test/ui/regions/regions-var-type-out-of-scope.stderr index d95717676855e..9fb32bbac282c 100644 --- a/src/test/ui/regions/regions-var-type-out-of-scope.stderr +++ b/src/test/ui/regions/regions-var-type-out-of-scope.stderr @@ -2,8 +2,9 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/regions-var-type-out-of-scope.rs:9:14 | LL | x = &id(3); - | ^^^^^- temporary value is freed at the end of this statement - | | + | ^^^^- + | | | + | | temporary value is freed at the end of this statement | creates a temporary which is freed while still in use LL | assert_eq!(*x, 3); | ------------------ borrow later used here diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr index 7ba909d208aff..c864095f96387 100644 --- a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr +++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr @@ -14,7 +14,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowck-let-suggestion-suffixes.rs:19:14 | LL | v3.push(&id('x')); // statement 6 - | ^^^^^^^ - temporary value is freed at the end of this statement + | ^^^^^^^- temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use ... @@ -27,7 +27,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowck-let-suggestion-suffixes.rs:29:18 | LL | v4.push(&id('y')); - | ^^^^^^^ - temporary value is freed at the end of this statement + | ^^^^^^^- temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use ... @@ -40,7 +40,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowck-let-suggestion-suffixes.rs:40:14 | LL | v5.push(&id('z')); - | ^^^^^^^ - temporary value is freed at the end of this statement + | ^^^^^^^- temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use ... diff --git a/src/test/ui/static/static-reference-to-fn-2.stderr b/src/test/ui/static/static-reference-to-fn-2.stderr index ff15884bd445d..0fbd4e38e03e3 100644 --- a/src/test/ui/static/static-reference-to-fn-2.stderr +++ b/src/test/ui/static/static-reference-to-fn-2.stderr @@ -4,8 +4,9 @@ error[E0716]: temporary value dropped while borrowed LL | fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { | ----- has type `&mut StateMachineIter<'1>` LL | self_.statefn = &id(state2 as StateMachineFunc); - | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement - | | | + | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | | | + | | | temporary value is freed at the end of this statement | | creates a temporary which is freed while still in use | assignment requires that borrow lasts for `'1` @@ -15,8 +16,9 @@ error[E0716]: temporary value dropped while borrowed LL | fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { | ----- has type `&mut StateMachineIter<'1>` LL | self_.statefn = &id(state3 as StateMachineFunc); - | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement - | | | + | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | | | + | | | temporary value is freed at the end of this statement | | creates a temporary which is freed while still in use | assignment requires that borrow lasts for `'1` @@ -26,8 +28,9 @@ error[E0716]: temporary value dropped while borrowed LL | fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { | ----- has type `&mut StateMachineIter<'1>` LL | self_.statefn = &id(finished as StateMachineFunc); - | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement - | | | + | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | | | + | | | temporary value is freed at the end of this statement | | creates a temporary which is freed while still in use | assignment requires that borrow lasts for `'1` diff --git a/src/test/ui/thir-tree.stdout b/src/test/ui/thir-tree.stdout index 389eaf5e715b2..f63dda434fdb7 100644 --- a/src/test/ui/thir-tree.stdout +++ b/src/test/ui/thir-tree.stdout @@ -5,13 +5,13 @@ Thir { Expr { ty: (), temp_lifetime: Some( - Node(2), + Node(2, false), ), span: $DIR/thir-tree.rs:4:15: 4:17 (#0), kind: Block { body: Block { targeted_by_break: false, - region_scope: Node(1), + region_scope: Node(1, false), opt_destruction_scope: None, span: $DIR/thir-tree.rs:4:15: 4:17 (#0), stmts: [], @@ -23,11 +23,11 @@ Thir { Expr { ty: (), temp_lifetime: Some( - Node(2), + Node(2, false), ), span: $DIR/thir-tree.rs:4:15: 4:17 (#0), kind: Scope { - region_scope: Node(2), + region_scope: Node(2, false), lint_level: Explicit( HirId { owner: DefId(0:3 ~ thir_tree[348d]::main), @@ -40,11 +40,11 @@ Thir { Expr { ty: (), temp_lifetime: Some( - Node(2), + Node(2, false), ), span: $DIR/thir-tree.rs:4:15: 4:17 (#0), kind: Scope { - region_scope: Destruction(2), + region_scope: Destruction(2, false), lint_level: Inherited, value: e1, }, From daa5a9bb30022e65e4df805f72de3a7ab95f3fce Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 12:02:51 -0500 Subject: [PATCH 10/16] Use statement span for statement scope --- compiler/rustc_middle/src/hir/map/mod.rs | 16 ++++++++++++++++ compiler/rustc_middle/src/middle/region.rs | 7 ++++++- .../async-await/issue-70935-complex-spans.stderr | 4 ++-- .../issues/issue-65436-raw-ptr-not-send.stderr | 4 ++-- .../borrowck-borrowed-uniq-rvalue.stderr | 2 +- src/test/ui/borrowck/issue-17545.stderr | 5 ++--- src/test/ui/issues/issue-47646.stderr | 2 +- .../issue-54382-use-span-of-tail-of-block.stderr | 8 ++++---- .../issue-54556-temps-in-tail-diagnostic.stderr | 8 ++++---- .../nll/issue-54556-used-vs-unused-tails.stderr | 11 ++++------- .../regions/regions-var-type-out-of-scope.stderr | 5 ++--- .../span/borrowck-let-suggestion-suffixes.stderr | 6 +++--- .../ui/static/static-reference-to-fn-2.stderr | 15 ++++++--------- 13 files changed, 53 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index c313146b07222..b368f44befa10 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -818,6 +818,22 @@ impl<'hir> Map<'hir> { self.tcx.hir_attrs(id.owner).get(id.local_id) } + pub fn stmt_span(&self, hir_id: HirId) -> Span { + match self.find(hir_id).unwrap() { + Node::Local(_) | Node::Item(_) | Node::Expr(_) => { + if let Some(Node::Block(block)) = self.find(self.get_parent_node(hir_id)) { + for stmt in block.stmts { + if stmt.kind.hir_id() == hir_id { + return stmt.span; + } + } + } + } + _ => {} + } + self.span(hir_id) + } + /// Gets the span of the definition of the specified HIR node. /// This is used by `tcx.get_span` pub fn span(&self, hir_id: HirId) -> Span { diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 5403ef78dda5e..9feeda8f32b7f 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -175,7 +175,12 @@ impl Scope { Some(hir_id) => hir_id, None => return DUMMY_SP, }; - let span = tcx.hir().span(hir_id); + let span = if self.for_stmt { + tcx.hir().stmt_span(hir_id) + } else { + tcx.hir().span(hir_id) + }; + if let ScopeData::Remainder(first_statement_index) = self.data { if let Node::Block(ref blk) = tcx.hir().get(hir_id) { // Want span for scope starting after the diff --git a/src/test/ui/async-await/issue-70935-complex-spans.stderr b/src/test/ui/async-await/issue-70935-complex-spans.stderr index 1b88476d01207..8451fb840992c 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.stderr @@ -13,10 +13,10 @@ LL | | foo(tx.clone()); LL | | }).await; | |________________^ first, await occurs here, with the value maybe used later... note: the value is later dropped here - --> $DIR/issue-70935-complex-spans.rs:15:16 + --> $DIR/issue-70935-complex-spans.rs:15:17 | LL | }).await; - | ^ + | ^ note: this has type `[closure@$DIR/issue-70935-complex-spans.rs:13:13: 15:10]` which is not `Send` --> $DIR/issue-70935-complex-spans.rs:13:13 | diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr index 5d34290fa51a6..5568dab86556a 100644 --- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr +++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr @@ -14,10 +14,10 @@ note: future is not `Send` as this value is used across an await LL | bar(Foo(std::ptr::null())).await; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ first, await occurs here, with `std::ptr::null()` maybe used later... note: `std::ptr::null()` is later dropped here - --> $DIR/issue-65436-raw-ptr-not-send.rs:14:40 + --> $DIR/issue-65436-raw-ptr-not-send.rs:14:41 | LL | bar(Foo(std::ptr::null())).await; - | ---------------- ^ + | ---------------- ^ | | | has type `*const u8` which is not `Send` help: consider moving this into a `let` binding to create a shorter lived borrow diff --git a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr index 28d1c9395330d..c91a4377b4c67 100644 --- a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr +++ b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowck-borrowed-uniq-rvalue.rs:10:28 | LL | buggy_map.insert(42, &*Box::new(1)); - | ^^^^^^^^^^^- temporary value is freed at the end of this statement + | ^^^^^^^^^^^ - temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use ... diff --git a/src/test/ui/borrowck/issue-17545.stderr b/src/test/ui/borrowck/issue-17545.stderr index bb9fef4b4c519..79a1e09bd7cc6 100644 --- a/src/test/ui/borrowck/issue-17545.stderr +++ b/src/test/ui/borrowck/issue-17545.stderr @@ -7,9 +7,8 @@ LL | / bar.call(( LL | | &id(()), | | ^^^^^^ creates a temporary which is freed while still in use LL | | )); - | | - - | | | - | |______temporary value is freed at the end of this statement + | | -- temporary value is freed at the end of this statement + | |______| | argument requires that borrow lasts for `'a` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-47646.stderr b/src/test/ui/issues/issue-47646.stderr index a3d7ff14a4a9b..b46c277d04566 100644 --- a/src/test/ui/issues/issue-47646.stderr +++ b/src/test/ui/issues/issue-47646.stderr @@ -11,7 +11,7 @@ LL | println!("{:?}", heap); | ^^^^ immutable borrow occurs here ... LL | }; - | - ... and the mutable borrow might be used here, when that temporary is dropped and runs the destructor for type `(Option>, ())` + | - ... and the mutable borrow might be used here, when that temporary is dropped and runs the destructor for type `(Option>, ())` error: aborting due to previous error diff --git a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr index cb45c1f5fdc07..6dacfd1f264c6 100644 --- a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr +++ b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr @@ -8,10 +8,10 @@ LL | D("other").next(&_thing1) | a temporary with access to the borrow is created here ... ... LL | } - | - - | | - | `_thing1` dropped here while still borrowed - | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` + | - `_thing1` dropped here while still borrowed +LL | +LL | ; + | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped | diff --git a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr index c1a7dcfb595c1..68d3cef8aa13b 100644 --- a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr +++ b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr @@ -7,10 +7,10 @@ LL | D(&_thing1).end() | | borrowed value does not live long enough | a temporary with access to the borrow is created here ... LL | } - | - - | | - | `_thing1` dropped here while still borrowed - | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` + | - `_thing1` dropped here while still borrowed +LL | +LL | ; + | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped | diff --git a/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr b/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr index c8012e0f2f7d7..25226e2967353 100644 --- a/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr +++ b/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr @@ -2,10 +2,9 @@ error[E0597]: `_t1` does not live long enough --> $DIR/issue-54556-used-vs-unused-tails.rs:10:55 | LL | { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // suggest `;` - | --^^^^- - + | --^^^^- - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | | | | | | `_t1` dropped here while still borrowed - | | | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | borrowed value does not live long enough | a temporary with access to the borrow is created here ... | @@ -18,7 +17,7 @@ error[E0597]: `_t1` does not live long enough --> $DIR/issue-54556-used-vs-unused-tails.rs:13:55 | LL | { { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } } ; // suggest `;` - | --^^^^- - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` + | --^^^^- - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | | | | | | `_t1` dropped here while still borrowed | | borrowed value does not live long enough @@ -33,10 +32,9 @@ error[E0597]: `_t1` does not live long enough --> $DIR/issue-54556-used-vs-unused-tails.rs:16:55 | LL | { { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }; } // suggest `;` - | --^^^^- - + | --^^^^- -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | | | | | | `_t1` dropped here while still borrowed - | | | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | borrowed value does not live long enough | a temporary with access to the borrow is created here ... | @@ -96,10 +94,9 @@ error[E0597]: `_t1` does not live long enough --> $DIR/issue-54556-used-vs-unused-tails.rs:30:55 | LL | _y = { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // `let x = ...; x` - | --^^^^- - + | --^^^^- - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | | | | | | `_t1` dropped here while still borrowed - | | | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D` | | borrowed value does not live long enough | a temporary with access to the borrow is created here ... | diff --git a/src/test/ui/regions/regions-var-type-out-of-scope.stderr b/src/test/ui/regions/regions-var-type-out-of-scope.stderr index 9fb32bbac282c..d95717676855e 100644 --- a/src/test/ui/regions/regions-var-type-out-of-scope.stderr +++ b/src/test/ui/regions/regions-var-type-out-of-scope.stderr @@ -2,9 +2,8 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/regions-var-type-out-of-scope.rs:9:14 | LL | x = &id(3); - | ^^^^- - | | | - | | temporary value is freed at the end of this statement + | ^^^^^- temporary value is freed at the end of this statement + | | | creates a temporary which is freed while still in use LL | assert_eq!(*x, 3); | ------------------ borrow later used here diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr index c864095f96387..7ba909d208aff 100644 --- a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr +++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr @@ -14,7 +14,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowck-let-suggestion-suffixes.rs:19:14 | LL | v3.push(&id('x')); // statement 6 - | ^^^^^^^- temporary value is freed at the end of this statement + | ^^^^^^^ - temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use ... @@ -27,7 +27,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowck-let-suggestion-suffixes.rs:29:18 | LL | v4.push(&id('y')); - | ^^^^^^^- temporary value is freed at the end of this statement + | ^^^^^^^ - temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use ... @@ -40,7 +40,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowck-let-suggestion-suffixes.rs:40:14 | LL | v5.push(&id('z')); - | ^^^^^^^- temporary value is freed at the end of this statement + | ^^^^^^^ - temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use ... diff --git a/src/test/ui/static/static-reference-to-fn-2.stderr b/src/test/ui/static/static-reference-to-fn-2.stderr index 0fbd4e38e03e3..ff15884bd445d 100644 --- a/src/test/ui/static/static-reference-to-fn-2.stderr +++ b/src/test/ui/static/static-reference-to-fn-2.stderr @@ -4,9 +4,8 @@ error[E0716]: temporary value dropped while borrowed LL | fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { | ----- has type `&mut StateMachineIter<'1>` LL | self_.statefn = &id(state2 as StateMachineFunc); - | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | | - | | | temporary value is freed at the end of this statement + | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement + | | | | | creates a temporary which is freed while still in use | assignment requires that borrow lasts for `'1` @@ -16,9 +15,8 @@ error[E0716]: temporary value dropped while borrowed LL | fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { | ----- has type `&mut StateMachineIter<'1>` LL | self_.statefn = &id(state3 as StateMachineFunc); - | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | | - | | | temporary value is freed at the end of this statement + | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement + | | | | | creates a temporary which is freed while still in use | assignment requires that borrow lasts for `'1` @@ -28,9 +26,8 @@ error[E0716]: temporary value dropped while borrowed LL | fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { | ----- has type `&mut StateMachineIter<'1>` LL | self_.statefn = &id(finished as StateMachineFunc); - | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | | - | | | temporary value is freed at the end of this statement + | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement + | | | | | creates a temporary which is freed while still in use | assignment requires that borrow lasts for `'1` From c77433c969e6344c5ea54aac63bfc4e3fbeb07ed Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 12:13:31 -0500 Subject: [PATCH 11/16] Fix check for local statement --- .../rustc_typeck/src/check/fn_ctxt/suggestions.rs | 2 +- src/test/ui/loops/loop-no-implicit-break.stderr | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 0acf1d26e257d..101b5a0390580 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -569,6 +569,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn is_local_statement(&self, id: hir::HirId) -> bool { let node = self.tcx.hir().get(id); - matches!(node, Node::Stmt(Stmt { kind: StmtKind::Local(..), .. })) + matches!(node, Node::Local(_)) } } diff --git a/src/test/ui/loops/loop-no-implicit-break.stderr b/src/test/ui/loops/loop-no-implicit-break.stderr index 9a8e0d9a640e6..8a1afdea24936 100644 --- a/src/test/ui/loops/loop-no-implicit-break.stderr +++ b/src/test/ui/loops/loop-no-implicit-break.stderr @@ -3,6 +3,11 @@ error[E0308]: mismatched types | LL | 1 | ^ expected `()`, found integer + | +help: you might have meant to break the loop with this value + | +LL | break 1; + | +++++ + error[E0308]: mismatched types --> $DIR/loop-no-implicit-break.rs:13:9 @@ -10,10 +15,10 @@ error[E0308]: mismatched types LL | 1 | ^ expected `()`, found integer | -help: you might have meant to return this value +help: you might have meant to break the loop with this value | -LL | return 1; - | ++++++ + +LL | break 1; + | +++++ + error[E0308]: mismatched types --> $DIR/loop-no-implicit-break.rs:21:9 From dbc29a004278884ee09cbc4c08eba01a465522b3 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 12:14:01 -0500 Subject: [PATCH 12/16] Run fmt --- compiler/rustc_ast/src/mut_visit.rs | 15 ++++--- compiler/rustc_ast_lowering/src/lib.rs | 4 +- compiler/rustc_expand/src/base.rs | 7 +--- compiler/rustc_expand/src/build.rs | 8 +--- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_interface/src/util.rs | 11 ++--- compiler/rustc_middle/src/middle/region.rs | 15 +++---- compiler/rustc_mir_build/src/build/mod.rs | 14 +++++-- compiler/rustc_mir_build/src/thir/cx/block.rs | 3 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 42 ++++++++++++++----- compiler/rustc_passes/src/region.rs | 18 ++++++-- 11 files changed, 82 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 11f9d7702204a..bf330c5cd2612 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1372,11 +1372,14 @@ pub fn noop_flat_map_stmt( Stmt { kind, span }: Stmt, vis: &mut T, ) -> SmallVec<[Stmt; 1]> { - let res = noop_flat_map_stmt_kind(kind, vis).into_iter().map(|kind| { - let mut new_span = span; - vis.visit_span(&mut new_span); - Stmt { kind, span: new_span } - }).collect(); + let res = noop_flat_map_stmt_kind(kind, vis) + .into_iter() + .map(|kind| { + let mut new_span = span; + vis.visit_span(&mut new_span); + Stmt { kind, span: new_span } + }) + .collect(); tracing::info!("Made new statements: {:?}", res); res } @@ -1396,7 +1399,7 @@ pub fn noop_flat_map_stmt_kind( StmtKind::Empty { mut id } => { vis.visit_id(&mut id); smallvec![StmtKind::Empty { id }] - }, + } StmtKind::MacCall(mut mac) => { let MacCallStmt { mac: mac_, style: _, attrs, tokens, id } = mac.deref_mut(); vis.visit_id(id); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index fef26852a25ba..bfecfbfc2b7b1 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2427,9 +2427,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return self .lower_item_id(it) .into_iter() - .map(|item_id| { - hir::Stmt { kind: hir::StmtKind::Item(item_id), span: s.span } - }) + .map(|item_id| hir::Stmt { kind: hir::StmtKind::Item(item_id), span: s.span }) .collect(); } StmtKind::Expr(ref e) => { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index b17836d798737..ec0bea5a9a51c 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -337,12 +337,7 @@ where // Use a macro because forwarding to a simple function has type system issues macro_rules! make_stmts_default { ($me:expr) => { - $me.make_expr().map(|e| { - smallvec![ast::Stmt { - span: e.span, - kind: ast::StmtKind::Expr(e), - }] - }) + $me.make_expr().map(|e| smallvec![ast::Stmt { span: e.span, kind: ast::StmtKind::Expr(e) }]) }; } diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 4841bb3731cb8..da44d25b7e907 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -181,13 +181,7 @@ impl<'a> ExtCtxt<'a> { } pub fn block_expr(&self, expr: P) -> P { - self.block( - expr.span, - vec![ast::Stmt { - span: expr.span, - kind: ast::StmtKind::Expr(expr), - }], - ) + self.block(expr.span, vec![ast::Stmt { span: expr.span, kind: ast::StmtKind::Expr(expr) }]) } pub fn block(&self, span: Span, stmts: Vec) -> P { P(ast::Block { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index c937917fa6d88..180dda91fcdfc 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -17,10 +17,10 @@ use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, ModKind, NestedMetaItem use rustc_ast::{NodeId, PatKind, Path, StmtKind, Unsafe}; use rustc_ast_pretty::pprust; use rustc_attr::is_builtin_attr; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::map_in_place::MapInPlace; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lrc; -use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::Features; use rustc_parse::parser::{ diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 9e52380ffdf9e..f0022a3dfc3ef 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -822,10 +822,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { tokens: None, }); - ast::Stmt { - kind: ast::StmtKind::Expr(expr), - span: rustc_span::DUMMY_SP, - } + ast::Stmt { kind: ast::StmtKind::Expr(expr), span: rustc_span::DUMMY_SP } } let empty_block = stmt_to_block(BlockCheckMode::Default, None, self.resolver); @@ -837,10 +834,8 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { tokens: None, }); - let loop_stmt = ast::Stmt { - span: rustc_span::DUMMY_SP, - kind: ast::StmtKind::Expr(loop_expr), - }; + let loop_stmt = + ast::Stmt { span: rustc_span::DUMMY_SP, kind: ast::StmtKind::Expr(loop_expr) }; if self.within_static_or_const { noop_visit_block(b, self) diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 9feeda8f32b7f..7abf70e43a146 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -94,7 +94,9 @@ impl fmt::Debug for Scope { ScopeData::Node => write!(fmt, "Node({:?}, {:?})", self.id, self.for_stmt), ScopeData::CallSite => write!(fmt, "CallSite({:?}. {:?})", self.id, self.for_stmt), ScopeData::Arguments => write!(fmt, "Arguments({:?}, {:?})", self.id, self.for_stmt), - ScopeData::Destruction => write!(fmt, "Destruction({:?}, {:?})", self.id, self.for_stmt), + ScopeData::Destruction => { + write!(fmt, "Destruction({:?}, {:?})", self.id, self.for_stmt) + } ScopeData::Remainder(fsi) => write!( fmt, "Remainder {{ block: {:?}, first_statement_index: {}, for_stmt: {:?}}}", @@ -175,11 +177,7 @@ impl Scope { Some(hir_id) => hir_id, None => return DUMMY_SP, }; - let span = if self.for_stmt { - tcx.hir().stmt_span(hir_id) - } else { - tcx.hir().span(hir_id) - }; + let span = if self.for_stmt { tcx.hir().stmt_span(hir_id) } else { tcx.hir().span(hir_id) }; if let ScopeData::Remainder(first_statement_index) = self.data { if let Node::Block(ref blk) = tcx.hir().get(hir_id) { @@ -343,7 +341,10 @@ impl ScopeTree { // Record the destruction scopes for later so we can query them. if let ScopeData::Destruction = child.data { - assert_eq!(self.destruction_scopes.insert((child.item_local_id(), child.for_stmt), child), None); + assert_eq!( + self.destruction_scopes.insert((child.item_local_id(), child.for_stmt), child), + None + ); } } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 2d6890d4e45e7..f023724c90d0c 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -624,10 +624,16 @@ where body.generator_kind, ); - let call_site_scope = - region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite, for_stmt: false }; - let arg_scope = - region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::Arguments, for_stmt: false }; + let call_site_scope = region::Scope { + id: body.value.hir_id.local_id, + data: region::ScopeData::CallSite, + for_stmt: false, + }; + let arg_scope = region::Scope { + id: body.value.hir_id.local_id, + data: region::ScopeData::Arguments, + for_stmt: false, + }; let source_info = builder.source_info(span); let call_site_s = (call_site_scope, source_info); unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 05335bc65f4e9..b27406ea0467f 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -47,7 +47,8 @@ impl<'tcx> Cx<'tcx> { .enumerate() .filter_map(|(index, stmt)| { let hir_id = stmt.kind.hir_id(); - let opt_dxn_ext = self.region_scope_tree.opt_destruction_scope(hir_id.local_id, true); + let opt_dxn_ext = + self.region_scope_tree.opt_destruction_scope(hir_id.local_id, true); match stmt.kind { hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { let stmt = Stmt { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 3e20e7f3a40b6..4627ba36670fc 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -32,8 +32,11 @@ impl<'tcx> Cx<'tcx> { pub(super) fn mirror_expr_inner(&mut self, hir_expr: &'tcx hir::Expr<'tcx>) -> ExprId { let temp_lifetime = self.region_scope_tree.temporary_scope(hir_expr.hir_id.local_id, false); - let expr_scope = - region::Scope { id: hir_expr.hir_id.local_id, data: region::ScopeData::Node, for_stmt: false }; + let expr_scope = region::Scope { + id: hir_expr.hir_id.local_id, + data: region::ScopeData::Node, + for_stmt: false, + }; debug!("Expr::make_mirror(): id={}, span={:?}", hir_expr.hir_id, hir_expr.span); @@ -498,8 +501,9 @@ impl<'tcx> Cx<'tcx> { expr.kind ), }; - let temp_lifetime = - self.region_scope_tree.temporary_scope(expr.hir_id.local_id, false); + let temp_lifetime = self + .region_scope_tree + .temporary_scope(expr.hir_id.local_id, false); let res = self.typeck_results().qpath_res(qpath, expr.hir_id); let ty; match res { @@ -579,14 +583,22 @@ impl<'tcx> Cx<'tcx> { } hir::ExprKind::Break(dest, ref value) => match dest.target_id { Ok(target_id) => ExprKind::Break { - label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node, for_stmt: false, }, + label: region::Scope { + id: target_id.local_id, + data: region::ScopeData::Node, + for_stmt: false, + }, value: value.as_ref().map(|value| self.mirror_expr(value)), }, Err(err) => bug!("invalid loop id for break: {}", err), }, hir::ExprKind::Continue(dest) => match dest.target_id { Ok(loop_id) => ExprKind::Continue { - label: region::Scope { id: loop_id.local_id, data: region::ScopeData::Node, for_stmt: false, }, + label: region::Scope { + id: loop_id.local_id, + data: region::ScopeData::Node, + for_stmt: false, + }, }, Err(err) => bug!("invalid loop id for continue: {}", err), }, @@ -601,7 +613,8 @@ impl<'tcx> Cx<'tcx> { }, hir::ExprKind::Loop(ref body, ..) => { let block_ty = self.typeck_results().node_type(body.hir_id); - let temp_lifetime = self.region_scope_tree.temporary_scope(body.hir_id.local_id, false); + let temp_lifetime = + self.region_scope_tree.temporary_scope(body.hir_id.local_id, false); let block = self.mirror_block(body); let body = self.thir.exprs.push(Expr { ty: block_ty, @@ -837,7 +850,11 @@ impl<'tcx> Cx<'tcx> { }), body: self.mirror_expr(arm.body), lint_level: LintLevel::Explicit(arm.hir_id), - scope: region::Scope { id: arm.hir_id.local_id, data: region::ScopeData::Node, for_stmt: false }, + scope: region::Scope { + id: arm.hir_id.local_id, + data: region::ScopeData::Node, + for_stmt: false, + }, span: arm.span, }; self.thir.arms.push(arm) @@ -922,7 +939,8 @@ impl<'tcx> Cx<'tcx> { // a constant reference (or constant raw pointer for `static mut`) in MIR Res::Def(DefKind::Static, id) => { let ty = self.tcx.static_ptr_ty(id); - let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id, false); + let temp_lifetime = + self.region_scope_tree.temporary_scope(expr.hir_id.local_id, false); let kind = if self.tcx.is_thread_local_static(id) { ExprKind::ThreadLocalRef(id) } else { @@ -1026,7 +1044,8 @@ impl<'tcx> Cx<'tcx> { closure_expr: &'tcx hir::Expr<'tcx>, place: HirPlace<'tcx>, ) -> Expr<'tcx> { - let temp_lifetime = self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id, false); + let temp_lifetime = + self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id, false); let var_ty = place.base_ty; // The result of capture analysis in `rustc_typeck/check/upvar.rs`represents a captured path @@ -1081,7 +1100,8 @@ impl<'tcx> Cx<'tcx> { let upvar_capture = captured_place.info.capture_kind; let captured_place_expr = self.convert_captured_hir_place(closure_expr, captured_place.place.clone()); - let temp_lifetime = self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id, false); + let temp_lifetime = + self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id, false); match upvar_capture { ty::UpvarCapture::ByValue(_) => captured_place_expr, diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs index 4c77bf8404c09..ea03dec2dcdd1 100644 --- a/compiler/rustc_passes/src/region.rs +++ b/compiler/rustc_passes/src/region.rs @@ -169,7 +169,11 @@ fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir } fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir::Pat<'tcx>) { - visitor.record_child_scope(Scope { id: pat.hir_id.local_id, data: ScopeData::Node, for_stmt: false }); + visitor.record_child_scope(Scope { + id: pat.hir_id.local_id, + data: ScopeData::Node, + for_stmt: false, + }); // If this is a binding then record the lifetime of that binding. if let PatKind::Binding(..) = pat.kind { @@ -743,8 +747,16 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { let outer_pessimistic_yield = mem::replace(&mut self.pessimistic_yield, false); self.terminating_scopes.insert((body.value.hir_id.local_id, false)); - self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::CallSite, for_stmt: false }); - self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::Arguments, for_stmt: false }); + self.enter_scope(Scope { + id: body.value.hir_id.local_id, + data: ScopeData::CallSite, + for_stmt: false, + }); + self.enter_scope(Scope { + id: body.value.hir_id.local_id, + data: ScopeData::Arguments, + for_stmt: false, + }); // The arguments and `self` are parented to the fn. self.cx.var_parent = self.cx.parent.take(); From 036dd8b353a1dd5ab6494ff6bd405a3a8e637b07 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 12:50:19 -0500 Subject: [PATCH 13/16] Remove unused imports --- compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 101b5a0390580..b40a7baa98b3f 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -8,7 +8,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind}; use rustc_hir::lang_items::LangItem; -use rustc_hir::{Expr, ExprKind, ItemKind, Node, Stmt, StmtKind}; +use rustc_hir::{Expr, ExprKind, ItemKind, Node}; use rustc_infer::infer; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, Binder, Ty}; From 85afbb06260127881a9fc22e4469c36fb0fa246e Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 13:44:47 -0500 Subject: [PATCH 14/16] Update clippy and rustfmt --- src/tools/clippy/clippy_lints/src/default.rs | 2 +- .../clippy/clippy_lints/src/items_after_statements.rs | 2 +- src/tools/clippy/clippy_lints/src/loops/utils.rs | 8 -------- .../clippy/clippy_lints/src/slow_vector_initialization.rs | 2 +- src/tools/clippy/clippy_lints/src/utils/author.rs | 2 +- src/tools/clippy/clippy_lints/src/utils/inspector.rs | 2 +- src/tools/clippy/clippy_utils/src/ast_utils.rs | 2 +- src/tools/rustfmt/src/attr.rs | 2 +- src/tools/rustfmt/src/closures.rs | 1 - src/tools/rustfmt/src/expr.rs | 2 +- src/tools/rustfmt/src/spanned.rs | 2 +- src/tools/rustfmt/src/stmt.rs | 4 ++-- src/tools/rustfmt/src/visitor.rs | 4 ++-- 13 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index db8f2171348f7..fa375c5c62f8b 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -134,7 +134,7 @@ impl LateLintPass<'_> for Default { if adt.is_struct(); let variant = adt.non_enum_variant(); if adt.did.is_local() || !variant.is_field_list_non_exhaustive(); - let module_did = cx.tcx.parent_module(stmt.hir_id).to_def_id(); + let module_did = cx.tcx.parent_module(stmt.kind.hir_id()).to_def_id(); if variant .fields .iter() diff --git a/src/tools/clippy/clippy_lints/src/items_after_statements.rs b/src/tools/clippy/clippy_lints/src/items_after_statements.rs index 429c6ed7d2d77..245cf05d6e81b 100644 --- a/src/tools/clippy/clippy_lints/src/items_after_statements.rs +++ b/src/tools/clippy/clippy_lints/src/items_after_statements.rs @@ -63,7 +63,7 @@ impl EarlyLintPass for ItemsAfterStatements { .stmts .iter() .map(|stmt| &stmt.kind) - .skip_while(|s| matches!(**s, StmtKind::Item(..) | StmtKind::Empty)); + .skip_while(|s| matches!(**s, StmtKind::Item(..) | StmtKind::Empty { id: _ })); // lint on all further items for stmt in stmts { diff --git a/src/tools/clippy/clippy_lints/src/loops/utils.rs b/src/tools/clippy/clippy_lints/src/loops/utils.rs index 2f7360210ba4d..dfc63edae4840 100644 --- a/src/tools/clippy/clippy_lints/src/loops/utils.rs +++ b/src/tools/clippy/clippy_lints/src/loops/utils.rs @@ -256,14 +256,6 @@ pub(super) struct LoopNestVisitor { impl<'tcx> Visitor<'tcx> for LoopNestVisitor { type Map = Map<'tcx>; - fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) { - if stmt.hir_id == self.hir_id { - self.nesting = LookFurther; - } else if self.nesting == Unknown { - walk_stmt(self, stmt); - } - } - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { if self.nesting != Unknown { return; diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs index 3d039e1306560..198e820574432 100644 --- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs +++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs @@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit { len_expr: len_arg, }; - Self::search_initialization(cx, vi, stmt.hir_id); + Self::search_initialization(cx, vi, stmt.kind.hir_id()); } } } diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 61fd375a9892c..bd24f06de794b 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) { - if !has_attr(cx, stmt.hir_id) { + if !has_attr(cx, stmt.kind.hir_id()) { return; } match stmt.kind { diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index f7ddee12dcf64..20e24fd66f87e 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector { } fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) { - if !has_attr(cx.sess(), cx.tcx.hir().attrs(stmt.hir_id)) { + if !has_attr(cx.sess(), cx.tcx.hir().attrs(stmt.kind.hir_id())) { return; } match stmt.kind { diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 30c2260d15cac..c62e13bd5485f 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -226,7 +226,7 @@ pub fn eq_stmt(l: &Stmt, r: &Stmt) -> bool { }, (Item(l), Item(r)) => eq_item(l, r, eq_item_kind), (Expr(l), Expr(r)) | (Semi(l), Semi(r)) => eq_expr(l, r), - (Empty, Empty) => true, + (Empty { id: _ }, Empty { id : _ }) => true, (MacCall(l), MacCall(r)) => { l.style == r.style && eq_mac_call(&l.mac, &r.mac) && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r)) }, diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs index 315eb10a9dbc0..2d3341177c816 100644 --- a/src/tools/rustfmt/src/attr.rs +++ b/src/tools/rustfmt/src/attr.rs @@ -43,7 +43,7 @@ pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span { ast::StmtKind::Item(ref item) => item.span, ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => expr.span, ast::StmtKind::MacCall(ref mac_stmt) => mac_stmt.mac.span(), - ast::StmtKind::Empty => stmt.span, + ast::StmtKind::Empty { id: _ } => stmt.span, } } diff --git a/src/tools/rustfmt/src/closures.rs b/src/tools/rustfmt/src/closures.rs index c9d46aef294a0..1c0756d186b15 100644 --- a/src/tools/rustfmt/src/closures.rs +++ b/src/tools/rustfmt/src/closures.rs @@ -148,7 +148,6 @@ fn rewrite_closure_with_block( let block = ast::Block { stmts: vec![ast::Stmt { - id: ast::NodeId::root(), kind: ast::StmtKind::Expr(ptr::P(body.clone())), span: body.span, }], diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index 6cfeb9977a966..7b6a5aa8e669f 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -1138,7 +1138,7 @@ fn block_has_statements(block: &ast::Block) -> bool { block .stmts .iter() - .any(|stmt| !matches!(stmt.kind, ast::StmtKind::Empty)) + .any(|stmt| !matches!(stmt.kind, ast::StmtKind::Empty { id: _ })) } /// Checks whether a block contains no statements, expressions, comments, or diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 7e3786b7cd94c..978e81c04c2d1 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -73,7 +73,7 @@ impl Spanned for ast::Stmt { mk_sp(mac_stmt.attrs[0].span.lo(), self.span.hi()) } } - ast::StmtKind::Empty => self.span, + ast::StmtKind::Empty { id: _ } => self.span, } } } diff --git a/src/tools/rustfmt/src/stmt.rs b/src/tools/rustfmt/src/stmt.rs index 0b3854425ea5f..14b13d0e135e9 100644 --- a/src/tools/rustfmt/src/stmt.rs +++ b/src/tools/rustfmt/src/stmt.rs @@ -53,7 +53,7 @@ impl<'a> Stmt<'a> { } pub(crate) fn is_empty(&self) -> bool { - matches!(self.inner.kind, ast::StmtKind::Empty) + matches!(self.inner.kind, ast::StmtKind::Empty { id: _ }) } fn is_last_expr(&self) -> bool { @@ -110,7 +110,7 @@ fn format_stmt( let shape = shape.sub_width(suffix.len())?; format_expr(ex, expr_type, context, shape).map(|s| s + suffix) } - ast::StmtKind::MacCall(..) | ast::StmtKind::Item(..) | ast::StmtKind::Empty => None, + ast::StmtKind::MacCall(..) | ast::StmtKind::Item(..) | ast::StmtKind::Empty { id: _ } => None, }; result.and_then(|res| recover_comment_removed(res, stmt.span(), context)) } diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 3f251bf7c16b3..b30b4549ad605 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -180,7 +180,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } self.format_missing(stmt.span().hi()); } - ast::StmtKind::Empty => (), + ast::StmtKind::Empty { id: _ } => (), } } @@ -955,7 +955,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let include_next_empty = if stmts.len() > 1 { matches!( (&stmts[0].as_ast_node().kind, &stmts[1].as_ast_node().kind), - (ast::StmtKind::Item(_), ast::StmtKind::Empty) + (ast::StmtKind::Item(_), ast::StmtKind::Empty { id: _ }) ) } else { false From a404da8d8695d82e557ee1e218439cc01e4be85b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 20:20:57 -0500 Subject: [PATCH 15/16] Store less information for destruction scopes --- compiler/rustc_middle/src/middle/region.rs | 11 ++++------- compiler/rustc_mir_build/src/thir/cx/block.rs | 13 ++++++++----- compiler/rustc_mir_build/src/thir/cx/expr.rs | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 7abf70e43a146..45978ae19d452 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -228,7 +228,7 @@ pub struct ScopeTree { var_map: FxHashMap, /// Maps from a `NodeId` to the associated destruction scope (if any). - destruction_scopes: FxHashMap<(hir::ItemLocalId, bool), Scope>, + destruction_scopes: FxHashMap, /// `rvalue_scopes` includes entries for those expressions whose /// cleanup scope is larger than the default. The map goes from the @@ -341,15 +341,12 @@ impl ScopeTree { // Record the destruction scopes for later so we can query them. if let ScopeData::Destruction = child.data { - assert_eq!( - self.destruction_scopes.insert((child.item_local_id(), child.for_stmt), child), - None - ); + assert_eq!(self.destruction_scopes.insert(child.item_local_id(), child), None); } } - pub fn opt_destruction_scope(&self, n: hir::ItemLocalId, for_stmt: bool) -> Option { - self.destruction_scopes.get(&(n, for_stmt)).cloned() + pub fn opt_destruction_scope(&self, n: hir::ItemLocalId) -> Option { + self.destruction_scopes.get(&n).cloned() } pub fn record_var_scope(&mut self, var: hir::ItemLocalId, lifetime: Scope) { diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index b27406ea0467f..31a54263ff8ca 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -13,7 +13,7 @@ impl<'tcx> Cx<'tcx> { // in order to get the lexical scoping correctly. let stmts = self.mirror_stmts(block.hir_id.local_id, block.stmts); let opt_destruction_scope = - self.region_scope_tree.opt_destruction_scope(block.hir_id.local_id, false); + self.region_scope_tree.opt_destruction_scope(block.hir_id.local_id); Block { targeted_by_break: block.targeted_by_break, region_scope: region::Scope { @@ -47,8 +47,11 @@ impl<'tcx> Cx<'tcx> { .enumerate() .filter_map(|(index, stmt)| { let hir_id = stmt.kind.hir_id(); - let opt_dxn_ext = - self.region_scope_tree.opt_destruction_scope(hir_id.local_id, true); + let dxn_scope = region::Scope { + id: hir_id.local_id, + data: region::ScopeData::Destruction, + for_stmt: true, + }; match stmt.kind { hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { let stmt = Stmt { @@ -60,7 +63,7 @@ impl<'tcx> Cx<'tcx> { }, expr: self.mirror_expr(expr), }, - opt_destruction_scope: opt_dxn_ext, + opt_destruction_scope: Some(dxn_scope), }; Some(self.thir.stmts.push(stmt)) } @@ -111,7 +114,7 @@ impl<'tcx> Cx<'tcx> { initializer: local.init.map(|init| self.mirror_expr(init)), lint_level: LintLevel::Explicit(local.hir_id), }, - opt_destruction_scope: opt_dxn_ext, + opt_destruction_scope: Some(dxn_scope), }; Some(self.thir.stmts.push(stmt)) } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 4627ba36670fc..033555d1c477d 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -62,7 +62,7 @@ impl<'tcx> Cx<'tcx> { // Finally, create a destruction scope, if any. if let Some(region_scope) = - self.region_scope_tree.opt_destruction_scope(hir_expr.hir_id.local_id, false) + self.region_scope_tree.opt_destruction_scope(hir_expr.hir_id.local_id) { expr = Expr { temp_lifetime, From cd8eedfafbd212d0b01643044913ce5e43313656 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 13 Aug 2021 11:44:34 -0500 Subject: [PATCH 16/16] Simplify terminating_scopes --- compiler/rustc_passes/src/region.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs index ea03dec2dcdd1..469c6d28fbc58 100644 --- a/compiler/rustc_passes/src/region.rs +++ b/compiler/rustc_passes/src/region.rs @@ -67,7 +67,7 @@ struct RegionResolutionVisitor<'tcx> { /// arbitrary amounts of stack space. Terminating scopes end /// up being contained in a DestructionScope that contains the /// destructor's execution. - terminating_scopes: FxHashSet<(hir::ItemLocalId, bool)>, + terminating_scopes: FxHashSet, } /// Records the lifetime of a local variable as `cx.var_parent` @@ -116,7 +116,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h // `other_argument()` has run and also the call to `quux(..)` // itself has returned. - visitor.enter_node_scope_with_dtor(blk.hir_id.local_id, false); + visitor.enter_node_scope_with_dtor(blk.hir_id.local_id); visitor.cx.var_parent = visitor.cx.parent; { @@ -157,10 +157,10 @@ fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir visitor.enter_scope(Scope { id: arm.hir_id.local_id, data: ScopeData::Node, for_stmt: false }); visitor.cx.var_parent = visitor.cx.parent; - visitor.terminating_scopes.insert((arm.body.hir_id.local_id, false)); + visitor.terminating_scopes.insert(arm.body.hir_id.local_id); if let Some(hir::Guard::If(ref expr)) = arm.guard { - visitor.terminating_scopes.insert((expr.hir_id.local_id, false)); + visitor.terminating_scopes.insert(expr.hir_id.local_id); } intravisit::walk_arm(visitor, arm); @@ -203,9 +203,9 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h match &stmt.kind { kind @ (hir::StmtKind::Local(_) | hir::StmtKind::Expr(_) | hir::StmtKind::Semi(_)) => { - let local_id = kind.hir_id().local_id; - visitor.terminating_scopes.insert((local_id, true)); - visitor.enter_node_scope_with_dtor(local_id, true); + let id = kind.hir_id().local_id; + visitor.enter_scope(Scope { id, data: ScopeData::Destruction, for_stmt: true }); + visitor.enter_scope(Scope { id, data: ScopeData::Node, for_stmt: true }); } hir::StmtKind::Item(_) => {} } @@ -219,12 +219,12 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr); let prev_cx = visitor.cx; - visitor.enter_node_scope_with_dtor(expr.hir_id.local_id, false); + visitor.enter_node_scope_with_dtor(expr.hir_id.local_id); { let terminating_scopes = &mut visitor.terminating_scopes; let mut terminating = |id: hir::ItemLocalId| { - terminating_scopes.insert((id, false)); + terminating_scopes.insert(id); }; match expr.kind { // Conditional or repeating scopes are always terminating @@ -699,15 +699,15 @@ impl<'tcx> RegionResolutionVisitor<'tcx> { self.cx.parent = Some((child_scope, child_depth)); } - fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId, for_stmt: bool) { + fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) { // If node was previously marked as a terminating scope during the // recursive visit of its parent node in the AST, then we need to // account for the destruction scope representing the scope of // the destructors that run immediately after it completes. - if self.terminating_scopes.contains(&(id, for_stmt)) { - self.enter_scope(Scope { id, data: ScopeData::Destruction, for_stmt }); + if self.terminating_scopes.contains(&id) { + self.enter_scope(Scope { id, data: ScopeData::Destruction, for_stmt: false }); } - self.enter_scope(Scope { id, data: ScopeData::Node, for_stmt }); + self.enter_scope(Scope { id, data: ScopeData::Node, for_stmt: false }); } } @@ -745,7 +745,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { // control flow assumptions. This doesn't apply to nested // bodies within the `+=` statements. See #69307. let outer_pessimistic_yield = mem::replace(&mut self.pessimistic_yield, false); - self.terminating_scopes.insert((body.value.hir_id.local_id, false)); + self.terminating_scopes.insert(body.value.hir_id.local_id); self.enter_scope(Scope { id: body.value.hir_id.local_id,