From d14a9a470ed245ba89bd45e476e7c9fbc8a951fe Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 13:52:47 +0000 Subject: [PATCH 1/4] Remove parents from diagnostic hashing. --- compiler/rustc_error_messages/src/lib.rs | 11 ++++++++++ compiler/rustc_errors/src/diagnostic.rs | 28 +++++++++++++++++++----- compiler/rustc_errors/src/lib.rs | 21 ++++++++++++++++++ 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 4b3ecad307fe7..b45ee5a5f26d0 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -498,6 +498,17 @@ impl MultiSpan { pub fn clone_ignoring_labels(&self) -> Self { Self { primary_spans: self.primary_spans.clone(), ..MultiSpan::new() } } + + pub fn clone_ignoring_parents(&self) -> Self { + Self { + primary_spans: self.primary_spans.iter().map(|s| s.with_parent(None)).collect(), + span_labels: self + .span_labels + .iter() + .map(|(s, l)| (s.with_parent(None), l.clone())) + .collect(), + } + } } impl From for MultiSpan { diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index a128f8d31a134..39e0ec544ff93 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -433,19 +433,28 @@ impl DiagInner { &Level, &[(DiagMessage, Style)], &Option, - &MultiSpan, - &[Subdiag], - &Suggestions, + MultiSpan, + Vec, + Suggestions, Vec<(&DiagArgName, &DiagArgValue)>, &Option, ) { + let suggestions = match &self.suggestions { + Suggestions::Enabled(sugg) => Suggestions::Enabled( + sugg.iter().map(CodeSuggestion::clone_ignoring_parents).collect(), + ), + Suggestions::Sealed(sugg) => Suggestions::Sealed( + sugg.iter().map(CodeSuggestion::clone_ignoring_parents).collect(), + ), + Suggestions::Disabled => Suggestions::Disabled, + }; ( &self.level, &self.messages, &self.code, - &self.span, - &self.children, - &self.suggestions, + self.span.clone_ignoring_parents(), + self.children.iter().map(Subdiag::clone_ignoring_parents).collect(), + suggestions, self.args.iter().collect(), // omit self.sort_span &self.is_lint, @@ -478,6 +487,13 @@ pub struct Subdiag { pub span: MultiSpan, } +impl Subdiag { + fn clone_ignoring_parents(&self) -> Subdiag { + let Subdiag { level, messages, span } = self; + Subdiag { level: *level, messages: messages.clone(), span: span.clone_ignoring_parents() } + } +} + /// Used for emitting structured error messages and other diagnostic information. /// Wraps a `DiagInner`, adding some useful things. /// - The `dcx` field, allowing it to (a) emit itself, and (b) do a drop check diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 381d780077d19..362e4d4e1c646 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -259,6 +259,11 @@ impl SubstitutionPart { .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty()) } + fn clone_ignoring_parents(&self) -> SubstitutionPart { + let SubstitutionPart { span, snippet } = self; + SubstitutionPart { span: span.with_parent(None), snippet: snippet.clone() } + } + /// Try to turn a replacement into an addition when the span that is being /// overwritten matches either the prefix or suffix of the replacement. fn trim_trivial_replacements(&mut self, sm: &SourceMap) { @@ -303,6 +308,21 @@ fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a s } impl CodeSuggestion { + pub fn clone_ignoring_parents(&self) -> CodeSuggestion { + let CodeSuggestion { substitutions, msg, style, applicability } = self; + CodeSuggestion { + substitutions: substitutions + .iter() + .map(|Substitution { parts }| Substitution { + parts: parts.iter().map(SubstitutionPart::clone_ignoring_parents).collect(), + }) + .collect(), + msg: msg.clone(), + style: *style, + applicability: *applicability, + } + } + /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. pub(crate) fn splice_lines( @@ -1612,6 +1632,7 @@ impl DiagCtxtInner { let mut hasher = StableHasher::new(); diagnostic.hash(&mut hasher); let diagnostic_hash = hasher.finish(); + debug!(?diagnostic, ?diagnostic_hash); !self.emitted_diagnostics.insert(diagnostic_hash) }; From 1d312bd143974fb0e5539411dac8a8e0afc8fd64 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 11:28:17 +0000 Subject: [PATCH 2/4] Make def_collector a MutVisitor. --- compiler/rustc_ast/src/visit.rs | 42 +-- compiler/rustc_expand/src/base.rs | 2 +- compiler/rustc_expand/src/expand.rs | 4 +- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 261 +++++++++++------- compiler/rustc_resolve/src/macros.rs | 2 +- 6 files changed, 190 insertions(+), 123 deletions(-) diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 37fcc0d2167b2..d7b5dfec9d2fa 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -527,7 +527,7 @@ macro_rules! common_visitor_and_walkers { } } - fn visit_defaultness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, defaultness: &$($lt)? $($mut)? Defaultness) -> V::Result { + pub fn visit_defaultness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, defaultness: &$($lt)? $($mut)? Defaultness) -> V::Result { match defaultness { Defaultness::Default(span) => visit_span(vis, span), Defaultness::Final => { @@ -807,7 +807,7 @@ macro_rules! common_visitor_and_walkers { visit_foreign_items(vis, items) } - fn walk_define_opaques<$($lt,)? V: $Visitor$(<$lt>)?>( + pub fn walk_define_opaques<$($lt,)? V: $Visitor$(<$lt>)?>( visitor: &mut V, define_opaque: &$($lt)? $($mut)? Option>, ) -> V::Result { @@ -1225,6 +1225,27 @@ macro_rules! common_visitor_and_walkers { V::Result::output() } + pub fn walk_stmt<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + statement: &$($lt)? $($mut)? Stmt, + ) -> V::Result { + let Stmt { id, kind, span } = statement; + try_visit!(visit_id(vis, id)); + match kind { + StmtKind::Let(local) => try_visit!(vis.visit_local(local)), + StmtKind::Item(item) => try_visit!(vis.visit_item(item)), + StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(vis.visit_expr(expr)), + StmtKind::Empty => {} + StmtKind::MacCall(mac) => { + let MacCallStmt { mac, attrs, style: _, tokens: _ } = &$($mut)? **mac; + walk_list!(vis, visit_attribute, attrs); + try_visit!(vis.visit_mac_call(mac)); + } + } + try_visit!(visit_span(vis, span)); + V::Result::output() + } + pub fn walk_path<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, path: &$($lt)? $($mut)? Path, @@ -1944,20 +1965,3 @@ fn visit_nested_use_tree<'a, V: Visitor<'a>>( ) -> V::Result { vis.visit_nested_use_tree(nested_tree, nested_id) } - -pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result { - let Stmt { id, kind, span: _ } = statement; - try_visit!(visit_id(visitor, id)); - match kind { - StmtKind::Let(local) => try_visit!(visitor.visit_local(local)), - StmtKind::Item(item) => try_visit!(visitor.visit_item(item)), - StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(visitor.visit_expr(expr)), - StmtKind::Empty => {} - StmtKind::MacCall(mac) => { - let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_mac_call(mac)); - } - } - V::Result::output() -} diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 757a7e1c8e77f..a2069fb84dc91 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1066,7 +1066,7 @@ pub trait ResolverExpand { fn visit_ast_fragment_with_placeholders( &mut self, expn_id: LocalExpnId, - fragment: &AstFragment, + fragment: &mut AstFragment, ); fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind); diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 2de09aa1a2802..f98f22733fafb 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -136,7 +136,7 @@ macro_rules! ast_fragments { T::fragment_to_output(self) } - pub(crate) fn mut_visit_with(&mut self, vis: &mut impl MutVisitor) { + pub fn mut_visit_with(&mut self, vis: &mut impl MutVisitor) { match self { AstFragment::OptExpr(opt_expr) => { if let Some(expr) = opt_expr.take() { @@ -663,7 +663,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if self.monotonic { self.cx .resolver - .visit_ast_fragment_with_placeholders(self.cx.current_expansion.id, &fragment); + .visit_ast_fragment_with_placeholders(self.cx.current_expansion.id, &mut fragment); if self.cx.sess.opts.incremental.is_some() { for (invoc, _) in invocations.iter_mut() { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 6979d89a8e7bb..7a7b6a8b27c57 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -189,7 +189,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn build_reduced_graph( &mut self, - fragment: &AstFragment, + fragment: &mut AstFragment, parent_scope: ParentScope<'ra>, ) -> MacroRulesScopeRef<'ra> { collect_definitions(self, fragment, parent_scope.expansion); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index e2caf632dd2d5..571990e08a372 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -1,6 +1,7 @@ use std::mem; -use rustc_ast::visit::FnKind; +use rustc_ast::mut_visit::FnKind; +use rustc_ast::visit::AssocCtxt; use rustc_ast::*; use rustc_attr_parsing::{AttributeParser, Early, OmitDoc}; use rustc_expand::expand::AstFragment; @@ -10,18 +11,20 @@ use rustc_hir::def_id::LocalDefId; use rustc_middle::span_bug; use rustc_span::hygiene::LocalExpnId; use rustc_span::{Span, Symbol, sym}; +use smallvec::{SmallVec, smallvec}; use tracing::debug; use crate::{ImplTraitContext, InvocationParent, Resolver}; +#[tracing::instrument(level = "trace", skip(resolver, fragment), ret)] pub(crate) fn collect_definitions( resolver: &mut Resolver<'_, '_>, - fragment: &AstFragment, + fragment: &mut AstFragment, expansion: LocalExpnId, ) { let invocation_parent = resolver.invocation_parents[&expansion]; let mut visitor = DefCollector { resolver, expansion, invocation_parent }; - fragment.visit_with(&mut visitor); + fragment.mut_visit_with(&mut visitor); } /// Creates `DefId`s for nodes in the AST. @@ -56,24 +59,20 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { .def_id() } - fn with_parent(&mut self, parent_def: LocalDefId, f: F) { + fn with_parent(&mut self, parent_def: LocalDefId, f: impl FnOnce(&mut Self)) { let orig_parent_def = mem::replace(&mut self.invocation_parent.parent_def, parent_def); f(self); self.invocation_parent.parent_def = orig_parent_def; } - fn with_impl_trait( - &mut self, - impl_trait_context: ImplTraitContext, - f: F, - ) { + fn with_impl_trait(&mut self, impl_trait_context: ImplTraitContext, f: impl FnOnce(&mut Self)) { let orig_itc = mem::replace(&mut self.invocation_parent.impl_trait_context, impl_trait_context); f(self); self.invocation_parent.impl_trait_context = orig_itc; } - fn collect_field(&mut self, field: &'a FieldDef, index: Option) { + fn collect_field(&mut self, field: &mut FieldDef, index: Option) { let index = |this: &Self| { index.unwrap_or_else(|| { let node_id = NodeId::placeholder_from_expn_id(this.expansion); @@ -88,10 +87,11 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { } else { let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name); let def = self.create_def(field.id, Some(name), DefKind::Field, field.span); - self.with_parent(def, |this| visit::walk_field_def(this, field)); + self.with_parent(def, |this| mut_visit::walk_field_def(this, field)) } } + #[tracing::instrument(level = "trace", skip(self))] fn visit_macro_invoc(&mut self, id: NodeId) { let id = id.placeholder_to_expn_id(); let old_parent = self.resolver.invocation_parents.insert(id, self.invocation_parent); @@ -99,8 +99,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { } } -impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { - fn visit_item(&mut self, i: &'a Item) { +impl<'a, 'ra, 'tcx> mut_visit::MutVisitor for DefCollector<'a, 'ra, 'tcx> { + fn visit_item(&mut self, i: &mut Item) { // Pick the def data. This need not be unique, but the more // information we encapsulate into, the better let mut opt_macro_data = None; @@ -155,7 +155,9 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { ItemKind::GlobalAsm(..) => DefKind::GlobalAsm, ItemKind::Use(use_tree) => { self.create_def(i.id, None, DefKind::Use, use_tree.span); - return visit::walk_item(self, i); + // HIR lowers use trees as a flat stream of `ItemKind::Use`. + // This means all the def-ids must be parented to the module. + return mut_visit::walk_item(self, i); } ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => { return self.visit_macro_invoc(i.id); @@ -185,68 +187,110 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } _ => {} } - visit::walk_item(this, i); + mut_visit::walk_item(this, i) }) - }); + }) } - fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { - match fn_kind { + #[tracing::instrument(level = "trace", skip(self))] + fn visit_fn(&mut self, mut fn_kind: FnKind<'_>, fn_span: Span, _: NodeId) { + match &mut fn_kind { FnKind::Fn( _ctxt, _vis, Fn { - sig: FnSig { header, decl, span: _ }, ident, generics, contract, body, .. + defaultness, + ident, + sig: FnSig { header, decl, span }, + generics, + contract, + body, + define_opaque, }, - ) if let Some(coroutine_kind) = header.coroutine_kind => { + ) => { + mut_visit::visit_defaultness(self, defaultness); self.visit_ident(ident); self.visit_fn_header(header); self.visit_generics(generics); if let Some(contract) = contract { self.visit_contract(contract); } + self.visit_span(span); + mut_visit::walk_define_opaques(self, define_opaque); // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. Besides that, // we must mirror everything that `visit::walk_fn` below does. - let FnDecl { inputs, output } = &**decl; + let FnDecl { inputs, output } = &mut **decl; for param in inputs { self.visit_param(param); } - let (return_id, return_span) = coroutine_kind.return_id(); - let return_def = self.create_def(return_id, None, DefKind::OpaqueTy, return_span); + let return_def = if let Some(coroutine_kind) = header.coroutine_kind { + // coroutine_kind has been visited by visit_header. + let (return_id, return_span) = coroutine_kind.return_id(); + self.create_def(return_id, None, DefKind::OpaqueTy, return_span) + } else { + self.invocation_parent.parent_def + }; self.with_parent(return_def, |this| this.visit_fn_ret_ty(output)); // If this async fn has no body (i.e. it's an async fn signature in a trait) // then the closure_def will never be used, and we should avoid generating a // def-id for it. if let Some(body) = body { - let closure_def = - self.create_def(coroutine_kind.closure_id(), None, DefKind::Closure, span); + let closure_def = if let Some(coroutine_kind) = header.coroutine_kind { + self.create_def( + coroutine_kind.closure_id(), + None, + DefKind::Closure, + fn_span, + ) + } else { + self.invocation_parent.parent_def + }; self.with_parent(closure_def, |this| this.visit_block(body)); } } - FnKind::Closure(binder, Some(coroutine_kind), decl, body) => { + FnKind::Closure(binder, coroutine_kind, decl, body) => { self.visit_closure_binder(binder); - visit::walk_fn_decl(self, decl); + self.visit_fn_decl(decl); // Async closures desugar to closures inside of closures, so // we must create two defs. - let coroutine_def = - self.create_def(coroutine_kind.closure_id(), None, DefKind::Closure, span); - self.with_parent(coroutine_def, |this| this.visit_expr(body)); + let closure_def = if let Some(coroutine_kind) = coroutine_kind { + self.visit_coroutine_kind(coroutine_kind); + self.create_def(coroutine_kind.closure_id(), None, DefKind::Closure, fn_span) + } else { + self.invocation_parent.parent_def + }; + self.with_parent(closure_def, |this| this.visit_expr(body)); } - _ => visit::walk_fn(self, fn_kind), } } - fn visit_nested_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId) { - self.create_def(id, None, DefKind::Use, use_tree.span); - visit::walk_use_tree(self, use_tree); + fn visit_use_tree(&mut self, use_tree: &mut UseTree) { + let UseTree { prefix, kind, span } = use_tree; + self.visit_path(prefix); + match kind { + UseTreeKind::Simple(None) => {} + UseTreeKind::Simple(Some(rename)) => self.visit_ident(rename), + UseTreeKind::Nested { items, span } => { + for (tree, id) in items { + self.visit_id(id); + // HIR lowers use trees as a flat stream of `ItemKind::Use`. + // This means all the def-ids must be parented to the module. + self.create_def(*id, None, DefKind::Use, *span); + self.visit_use_tree(tree); + } + self.visit_span(span); + } + UseTreeKind::Glob => {} + } + self.visit_span(span); } - fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { + fn visit_foreign_item(&mut self, fi: &mut ForeignItem) { let (ident, def_kind) = match fi.kind { ForeignItemKind::Static(box StaticItem { ident, @@ -269,14 +313,14 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { }; let def = self.create_def(fi.id, Some(ident.name), def_kind, fi.span); - - self.with_parent(def, |this| visit::walk_item(this, fi)); + self.with_parent(def, |this| mut_visit::walk_item(this, fi)) } - fn visit_variant(&mut self, v: &'a Variant) { + fn visit_variant(&mut self, v: &mut Variant) { if v.is_placeholder { return self.visit_macro_invoc(v.id); } + let def = self.create_def(v.id, Some(v.ident.name), DefKind::Variant, v.span); self.with_parent(def, |this| { if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&v.data) { @@ -287,31 +331,41 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { v.span, ); } - visit::walk_variant(this, v) - }); + mut_visit::walk_variant(this, v) + }) } - fn visit_where_predicate(&mut self, pred: &'a WherePredicate) { + fn visit_where_predicate(&mut self, pred: &mut WherePredicate) { if pred.is_placeholder { self.visit_macro_invoc(pred.id) } else { - visit::walk_where_predicate(self, pred) + mut_visit::walk_where_predicate(self, pred) } } - fn visit_variant_data(&mut self, data: &'a VariantData) { + fn visit_variant_data(&mut self, data: &mut VariantData) { // The assumption here is that non-`cfg` macro expansion cannot change field indices. // It currently holds because only inert attributes are accepted on fields, // and every such attribute expands into a single field after it's resolved. - for (index, field) in data.fields().iter().enumerate() { + let fields = match data { + VariantData::Struct { fields, recovered: _ } => fields, + VariantData::Tuple(fields, id) => { + self.visit_id(id); + fields + } + VariantData::Unit(id) => { + self.visit_id(id); + return; + } + }; + for (index, field) in fields.iter_mut().enumerate() { self.collect_field(field, Some(index)); } } - fn visit_generic_param(&mut self, param: &'a GenericParam) { + fn visit_generic_param(&mut self, param: &mut GenericParam) { if param.is_placeholder { - self.visit_macro_invoc(param.id); - return; + return self.visit_macro_invoc(param.id); } let def_kind = match param.kind { GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam, @@ -327,11 +381,11 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // // In that case, the impl-trait is lowered as an additional generic parameter. self.with_impl_trait(ImplTraitContext::Universal, |this| { - visit::walk_generic_param(this, param) - }); + mut_visit::walk_generic_param(this, param) + }) } - fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) { + fn visit_assoc_item(&mut self, i: &mut AssocItem, ctxt: AssocCtxt) { let (ident, def_kind) = match &i.kind { AssocItemKind::Fn(box Fn { ident, .. }) | AssocItemKind::Delegation(box Delegation { ident, .. }) => (*ident, DefKind::AssocFn), @@ -343,43 +397,45 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { }; let def = self.create_def(i.id, Some(ident.name), def_kind, i.span); - self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); + self.with_parent(def, |this| mut_visit::walk_assoc_item(this, i, ctxt)); } - fn visit_pat(&mut self, pat: &'a Pat) { - match pat.kind { - PatKind::MacCall(..) => self.visit_macro_invoc(pat.id), - _ => visit::walk_pat(self, pat), + fn visit_pat(&mut self, pat: &mut Pat) { + if let PatKind::MacCall(..) = pat.kind { + return self.visit_macro_invoc(pat.id); } + mut_visit::walk_pat(self, pat) } - fn visit_anon_const(&mut self, constant: &'a AnonConst) { + fn visit_anon_const(&mut self, constant: &mut AnonConst) { let parent = self.create_def(constant.id, None, DefKind::AnonConst, constant.value.span); - self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); + self.with_parent(parent, |this| mut_visit::walk_anon_const(this, constant)); } - fn visit_expr(&mut self, expr: &'a Expr) { + fn visit_expr(&mut self, expr: &mut Expr) { let parent_def = match expr.kind { ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id), ExprKind::Closure(..) | ExprKind::Gen(..) => { self.create_def(expr.id, None, DefKind::Closure, expr.span) } - ExprKind::ConstBlock(ref constant) => { - for attr in &expr.attrs { - visit::walk_attribute(self, attr); + ExprKind::ConstBlock(ref mut constant) => { + let Expr { id: _, kind: _, span, attrs, tokens: _ } = expr; + for attr in attrs { + self.visit_attribute(attr); } let def = self.create_def(constant.id, None, DefKind::InlineConst, constant.value.span); - self.with_parent(def, |this| visit::walk_anon_const(this, constant)); + self.with_parent(def, |this| mut_visit::walk_anon_const(this, constant)); + self.visit_span(span); return; } _ => self.invocation_parent.parent_def, }; - self.with_parent(parent_def, |this| visit::walk_expr(this, expr)) + self.with_parent(parent_def, |this| mut_visit::walk_expr(this, expr)) } - fn visit_ty(&mut self, ty: &'a Ty) { + fn visit_ty(&mut self, ty: &mut Ty) { match ty.kind { TyKind::MacCall(..) => self.visit_macro_invoc(ty.id), TyKind::ImplTrait(opaque_id, _) => { @@ -391,86 +447,93 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { let kind = match self.invocation_parent.impl_trait_context { ImplTraitContext::Universal => DefKind::TyParam, ImplTraitContext::Existential => DefKind::OpaqueTy, - ImplTraitContext::InBinding => return visit::walk_ty(self, ty), + ImplTraitContext::InBinding => return mut_visit::walk_ty(self, ty), }; let id = self.create_def(opaque_id, Some(name), kind, ty.span); match self.invocation_parent.impl_trait_context { // Do not nest APIT, as we desugar them as `impl_trait: bounds`, // so the `impl_trait` node is not a parent to `bounds`. - ImplTraitContext::Universal => visit::walk_ty(self, ty), + ImplTraitContext::Universal => mut_visit::walk_ty(self, ty), ImplTraitContext::Existential => { - self.with_parent(id, |this| visit::walk_ty(this, ty)) + self.with_parent(id, |this| mut_visit::walk_ty(this, ty)) } ImplTraitContext::InBinding => unreachable!(), }; } - _ => visit::walk_ty(self, ty), + _ => mut_visit::walk_ty(self, ty), } } - fn visit_stmt(&mut self, stmt: &'a Stmt) { - match stmt.kind { - StmtKind::MacCall(..) => self.visit_macro_invoc(stmt.id), + fn flat_map_stmt(&mut self, mut stmt: Stmt) -> SmallVec<[Stmt; 1]> { + let Stmt { id, kind, span } = &mut stmt; + match kind { + StmtKind::MacCall(..) => { + self.visit_macro_invoc(*id); + smallvec![stmt] + } // FIXME(impl_trait_in_bindings): We don't really have a good way of // introducing the right `ImplTraitContext` here for all the cases we // care about, in case we want to introduce ITIB to other positions // such as turbofishes (e.g. `foo::(|| {})`). - StmtKind::Let(ref local) => self.with_impl_trait(ImplTraitContext::InBinding, |this| { - visit::walk_local(this, local) - }), - _ => visit::walk_stmt(self, stmt), + StmtKind::Let(local) => { + self.with_impl_trait(ImplTraitContext::InBinding, |this| { + mut_visit::walk_local(this, local); + this.visit_span(span); + }); + smallvec![stmt] + } + _ => mut_visit::walk_flat_map_stmt(self, stmt), } } - fn visit_arm(&mut self, arm: &'a Arm) { - if arm.is_placeholder { self.visit_macro_invoc(arm.id) } else { visit::walk_arm(self, arm) } + fn visit_arm(&mut self, arm: &mut Arm) { + if arm.is_placeholder { + return self.visit_macro_invoc(arm.id); + } + mut_visit::walk_arm(self, arm) } - fn visit_expr_field(&mut self, f: &'a ExprField) { + fn visit_expr_field(&mut self, f: &mut ExprField) { if f.is_placeholder { - self.visit_macro_invoc(f.id) - } else { - visit::walk_expr_field(self, f) + return self.visit_macro_invoc(f.id); } + mut_visit::walk_expr_field(self, f) } - fn visit_pat_field(&mut self, fp: &'a PatField) { + fn visit_pat_field(&mut self, fp: &mut PatField) { if fp.is_placeholder { - self.visit_macro_invoc(fp.id) - } else { - visit::walk_pat_field(self, fp) + return self.visit_macro_invoc(fp.id); } + mut_visit::walk_pat_field(self, fp) } - fn visit_param(&mut self, p: &'a Param) { + fn visit_param(&mut self, p: &mut Param) { if p.is_placeholder { - self.visit_macro_invoc(p.id) - } else { - self.with_impl_trait(ImplTraitContext::Universal, |this| visit::walk_param(this, p)) + return self.visit_macro_invoc(p.id); } + self.with_impl_trait(ImplTraitContext::Universal, |this| mut_visit::walk_param(this, p)) } // This method is called only when we are visiting an individual field // after expanding an attribute on it. - fn visit_field_def(&mut self, field: &'a FieldDef) { - self.collect_field(field, None); + fn visit_field_def(&mut self, field: &mut FieldDef) { + self.collect_field(field, None) } - fn visit_crate(&mut self, krate: &'a Crate) { + fn visit_crate(&mut self, krate: &mut Crate) { if krate.is_placeholder { - self.visit_macro_invoc(krate.id) - } else { - visit::walk_crate(self, krate) + return self.visit_macro_invoc(krate.id); } + mut_visit::walk_crate(self, krate) } - fn visit_attribute(&mut self, attr: &'a Attribute) -> Self::Result { + fn visit_attribute(&mut self, attr: &mut Attribute) { let orig_in_attr = mem::replace(&mut self.invocation_parent.in_attr, true); - visit::walk_attribute(self, attr); + mut_visit::walk_attribute(self, attr); self.invocation_parent.in_attr = orig_in_attr; } - fn visit_inline_asm(&mut self, asm: &'a InlineAsm) { + fn visit_inline_asm(&mut self, asm: &mut InlineAsm) { let InlineAsm { asm_macro: _, template: _, @@ -501,7 +564,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { DefKind::InlineConst, anon_const.value.span, ); - self.with_parent(def, |this| visit::walk_anon_const(this, anon_const)); + self.with_parent(def, |this| mut_visit::walk_anon_const(this, anon_const)); } InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym), InlineAsmOperand::Label { block } => self.visit_block(block), diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 5864b035f73df..2115c574cf7c6 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -184,7 +184,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { fn visit_ast_fragment_with_placeholders( &mut self, expansion: LocalExpnId, - fragment: &AstFragment, + fragment: &mut AstFragment, ) { // Integrate the new AST fragment into all the definition and module structures. // We are inside the `expansion` now, but other parent scope components are still the same. From 15261f5a3a0c92d62ccdd19a204d75be6f03d2af Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 11:40:02 +0000 Subject: [PATCH 3/4] Mark span parent in def_collector. --- compiler/rustc_ast_lowering/src/expr.rs | 28 +++++++++++++------ compiler/rustc_ast_lowering/src/item.rs | 2 ++ .../rustc_hir_typeck/src/method/suggest.rs | 4 +-- compiler/rustc_resolve/src/def_collector.rs | 6 ++++ .../incremental/hashes/function_interfaces.rs | 2 +- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 15e736261d583..6573c4eb1377d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -13,7 +13,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::TyCtxt; use rustc_session::errors::report_lit_error; use rustc_span::source_map::{Spanned, respan}; -use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym}; +use rustc_span::{DesugaringKind, Ident, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; use visit::{Visitor, walk_expr}; @@ -207,7 +207,9 @@ impl<'hir> LoweringContext<'_, 'hir> { MatchKind::Postfix => hir::MatchSource::Postfix, }, ), - ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr), + ExprKind::Await(expr, await_kw_span) => { + self.lower_expr_await(*await_kw_span, e.span, expr) + } ExprKind::Use(expr, use_kw_span) => self.lower_expr_use(*use_kw_span, expr), ExprKind::Closure(box Closure { binder, @@ -513,7 +515,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let last_segment = path.segments.last_mut().unwrap(); assert!(last_segment.args.is_none()); last_segment.args = Some(AstP(GenericArgs::AngleBracketed(AngleBracketedArgs { - span: DUMMY_SP, + span: last_segment.span().shrink_to_hi(), args: generic_args, }))); @@ -828,20 +830,24 @@ impl<'hir> LoweringContext<'_, 'hir> { /// } /// } /// ``` - fn lower_expr_await(&mut self, await_kw_span: Span, expr: &Expr) -> hir::ExprKind<'hir> { + fn lower_expr_await( + &mut self, + await_kw_span: Span, + full_span: Span, + expr: &Expr, + ) -> hir::ExprKind<'hir> { let expr = self.arena.alloc(self.lower_expr_mut(expr)); - self.make_lowered_await(await_kw_span, expr, FutureKind::Future) + self.make_lowered_await(await_kw_span, full_span, expr, FutureKind::Future) } /// Takes an expr that has already been lowered and generates a desugared await loop around it fn make_lowered_await( &mut self, await_kw_span: Span, + full_span: Span, expr: &'hir hir::Expr<'hir>, await_kind: FutureKind, ) -> hir::ExprKind<'hir> { - let full_span = expr.span.to(await_kw_span); - let is_async_gen = match self.coroutine_kind { Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => false, Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true, @@ -1820,7 +1826,12 @@ impl<'hir> LoweringContext<'_, 'hir> { )); // `unsafe { ... }` let iter = self.arena.alloc(self.expr_unsafe(iter)); - let kind = self.make_lowered_await(head_span, iter, FutureKind::AsyncIterator); + let kind = self.make_lowered_await( + head_span, + head_span, + iter, + FutureKind::AsyncIterator, + ); self.arena.alloc(hir::Expr { hir_id: self.next_id(), kind, span: head_span }) } }; @@ -2120,6 +2131,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> { + let sp = self.lower_span(sp); let lit = hir::Lit { span: sp, node: ast::LitKind::Str(value, ast::StrStyle::Cooked) }; self.expr(sp, hir::ExprKind::Lit(lit)) } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 9d40a7386f69c..aec3cd14cc3c2 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -170,6 +170,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Start with an empty prefix. let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None }; + let vis_span = self.lower_span(vis_span); self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs) } ItemKind::Static(box ast::StaticItem { @@ -619,6 +620,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } else { // For non-empty lists we can just drop all the data, the prefix is already // present in HIR as a part of nested imports. + let span = self.lower_span(span); self.arena.alloc(hir::UsePath { res: PerNS::default(), segments: &[], span }) }; hir::ItemKind::Use(path, hir::UseKind::ListStem) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 2815621ffdecf..c4fa77f3f767e 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -770,9 +770,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected.only_has_type(self), ); } - if let Some(span) = - tcx.resolutions(()).confused_type_with_std_module.get(&span.with_parent(None)) - { + if let Some(span) = tcx.resolutions(()).confused_type_with_std_module.get(&span) { err.span_suggestion( span.shrink_to_lo(), "you are looking for the module in `std`, not the primitive type", diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 571990e08a372..dbc02a672a10f 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -100,6 +100,12 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { } impl<'a, 'ra, 'tcx> mut_visit::MutVisitor for DefCollector<'a, 'ra, 'tcx> { + fn visit_span(&mut self, span: &mut Span) { + if self.resolver.tcx.sess.opts.incremental.is_some() { + *span = span.with_parent(Some(self.invocation_parent.parent_def)); + } + } + fn visit_item(&mut self, i: &mut Item) { // Pick the def data. This need not be unique, but the more // information we encapsulate into, the better diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs index 016a1813babd7..a1adc546390c6 100644 --- a/tests/incremental/hashes/function_interfaces.rs +++ b/tests/incremental/hashes/function_interfaces.rs @@ -320,7 +320,7 @@ pub fn change_return_impl_trait() -> impl Clone { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes")] #[rustc_clean(cfg = "cfail3")] -#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes")] #[rustc_clean(cfg = "cfail6")] pub fn change_return_impl_trait() -> impl Copy { 0u32 From 278958882d3092d467e2399ac5ad75250495dbab Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 12:51:33 +0000 Subject: [PATCH 4/4] Stop lowering spans for HIR. --- compiler/rustc_ast_lowering/src/asm.rs | 11 +- compiler/rustc_ast_lowering/src/block.rs | 12 +- compiler/rustc_ast_lowering/src/delegation.rs | 5 +- compiler/rustc_ast_lowering/src/expr.rs | 149 ++++++---------- compiler/rustc_ast_lowering/src/item.rs | 129 ++++++-------- compiler/rustc_ast_lowering/src/lib.rs | 160 +++++------------- compiler/rustc_ast_lowering/src/pat.rs | 32 ++-- compiler/rustc_ast_lowering/src/path.rs | 20 +-- compiler/rustc_attr_parsing/src/context.rs | 28 ++- compiler/rustc_resolve/src/def_collector.rs | 12 +- 10 files changed, 198 insertions(+), 360 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index af279e07acc6e..4b398cc4c44e6 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -237,7 +237,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::InlineAsmOperand::Label { block: self.lower_block(block, false) } } }; - (op, self.lower_span(*op_sp)) + (op, *op_sp) }) .collect(); @@ -463,7 +463,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { late: true, expr: None, }, - self.lower_span(abi_span), + abi_span, )); clobbered.insert(clobber); } @@ -497,12 +497,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let operands = self.arena.alloc_from_iter(operands); let template = self.arena.alloc_from_iter(asm.template.iter().cloned()); let template_strs = self.arena.alloc_from_iter( - asm.template_strs - .iter() - .map(|(sym, snippet, span)| (*sym, *snippet, self.lower_span(*span))), + asm.template_strs.iter().map(|(sym, snippet, span)| (*sym, *snippet, *span)), ); - let line_spans = - self.arena.alloc_from_iter(asm.line_spans.iter().map(|span| self.lower_span(*span))); + let line_spans = self.arena.alloc_from_iter(asm.line_spans.iter().copied()); let hir_asm = hir::InlineAsm { asm_macro: asm.asm_macro, template, diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index c3222b79e55c9..5f3b717157dab 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -23,7 +23,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::Block<'hir> { let (stmts, expr) = self.lower_stmts(&b.stmts); let rules = self.lower_block_check_mode(&b.rules); - hir::Block { hir_id, stmts, expr, rules, span: self.lower_span(b.span), targeted_by_break } + hir::Block { hir_id, stmts, expr, rules, span: b.span, targeted_by_break } } fn lower_stmts( @@ -39,7 +39,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let local = self.lower_local(local); self.alias_attrs(hir_id, local.hir_id); let kind = hir::StmtKind::Let(local); - let span = self.lower_span(s.span); + let span = s.span; stmts.push(hir::Stmt { hir_id, kind, span }); } StmtKind::Item(it) => { @@ -50,7 +50,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { _ => self.next_id(), }; let kind = hir::StmtKind::Item(item_id); - let span = self.lower_span(s.span); + let span = s.span; hir::Stmt { hir_id, kind, span } }, )); @@ -63,7 +63,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let hir_id = self.lower_node_id(s.id); self.alias_attrs(hir_id, e.hir_id); let kind = hir::StmtKind::Expr(e); - let span = self.lower_span(s.span); + let span = s.span; stmts.push(hir::Stmt { hir_id, kind, span }); } } @@ -72,7 +72,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let hir_id = self.lower_node_id(s.id); self.alias_attrs(hir_id, e.hir_id); let kind = hir::StmtKind::Semi(e); - let span = self.lower_span(s.span); + let span = s.span; stmts.push(hir::Stmt { hir_id, kind, span }); } StmtKind::Empty => {} @@ -107,7 +107,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { None }; - let span = self.lower_span(l.span); + let span = l.span; let source = hir::LocalSource::Normal; self.lower_attrs(hir_id, &l.attrs, l.span); self.arena.alloc(hir::LetStmt { hir_id, super_, ty, pat, init, els, span, source }) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 9bfcd232221ba..15930a6f6908c 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -83,7 +83,7 @@ impl<'hir> LoweringContext<'_, 'hir> { item_id: NodeId, is_in_trait_impl: bool, ) -> DelegationResults<'hir> { - let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span); + let span = delegation.path.segments.last().unwrap().ident.span; let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl); match sig_id { Ok(sig_id) => { @@ -92,9 +92,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span); let sig = self.lower_delegation_sig(sig_id, decl, span); let body_id = self.lower_delegation_body(delegation, is_method, param_count, span); - let ident = self.lower_ident(delegation.ident); let generics = self.lower_delegation_generics(span); - DelegationResults { body_id, sig, ident, generics } + DelegationResults { body_id, sig, ident: delegation.ident, generics } } Err(err) => self.generate_delegation_error(err, span), } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 6573c4eb1377d..a0902dcac2333 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -69,7 +69,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut ex = self.lower_expr_mut(ex); // Include parens in span, but only if it is a super-span. if e.span.contains(ex.span) { - ex.span = self.lower_span(e.span); + ex.span = e.span; } // Merge attributes into the inner expression. if !e.attrs.is_empty() { @@ -130,7 +130,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let receiver = self.lower_expr(receiver); let args = self.arena.alloc_from_iter(args.iter().map(|x| self.lower_expr_mut(x))); - hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(*span)) + hir::ExprKind::MethodCall(hir_seg, receiver, args, *span) } ExprKind::Binary(binop, lhs, rhs) => { let binop = self.lower_binop(*binop); @@ -145,10 +145,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::Lit(token_lit) => hir::ExprKind::Lit(self.lower_lit(token_lit, e.span)), ExprKind::IncludedBytes(byte_sym) => { - let lit = respan( - self.lower_span(e.span), - LitKind::ByteStr(*byte_sym, StrStyle::Cooked), - ); + let lit = respan(e.span, LitKind::ByteStr(*byte_sym, StrStyle::Cooked)); hir::ExprKind::Lit(lit) } ExprKind::Cast(expr, ty) => { @@ -169,7 +166,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::Let(pat, scrutinee, span, recovered) => { hir::ExprKind::Let(self.arena.alloc(hir::LetExpr { - span: self.lower_span(*span), + span: *span, pat: self.lower_pat(pat), ty: None, init: self.lower_expr(scrutinee), @@ -194,7 +191,7 @@ impl<'hir> LoweringContext<'_, 'hir> { this.lower_block(body, false), opt_label, hir::LoopSource::Loop, - this.lower_span(*span), + *span, ) }) } @@ -281,9 +278,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_expr(el), self.lower_expr(er), ), - ExprKind::Field(el, ident) => { - hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident)) - } + ExprKind::Field(el, ident) => hir::ExprKind::Field(self.lower_expr(el), *ident), ExprKind::Index(el, er, brackets_span) => { hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er), *brackets_span) } @@ -331,7 +326,7 @@ impl<'hir> LoweringContext<'_, 'hir> { container, ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf), ), - self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))), + self.arena.alloc_from_iter(fields.iter().copied()), ), ExprKind::Struct(se) => { let rest = match &se.rest { @@ -378,7 +373,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span), }; - hir::Expr { hir_id: expr_hir_id, kind, span: self.lower_span(e.span) } + hir::Expr { hir_id: expr_hir_id, kind, span: e.span } }) } @@ -431,7 +426,7 @@ impl<'hir> LoweringContext<'_, 'hir> { LitKind::Err(guar) } }; - respan(self.lower_span(span), lit_kind) + respan(span, lit_kind) } fn lower_unop(&mut self, u: UnOp) -> hir::UnOp { @@ -443,11 +438,11 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_binop(&mut self, b: BinOp) -> BinOp { - Spanned { node: b.node, span: self.lower_span(b.span) } + Spanned { node: b.node, span: b.span } } fn lower_assign_op(&mut self, a: AssignOp) -> AssignOp { - Spanned { node: a.node, span: self.lower_span(a.span) } + Spanned { node: a.node, span: a.span } } fn lower_legacy_const_generics( @@ -575,7 +570,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let if_kind = hir::ExprKind::If(lowered_cond, self.arena.alloc(then), Some(else_expr)); let if_expr = self.expr(span, if_kind); let block = self.block_expr(self.arena.alloc(if_expr)); - let span = self.lower_span(span.with_hi(cond.span.hi())); + let span = span.with_hi(cond.span.hi()); hir::ExprKind::Loop(block, opt_label, hir::LoopSource::While, span) } @@ -637,7 +632,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let pat = self.lower_pat(&arm.pat); let guard = arm.guard.as_ref().map(|cond| self.lower_expr(cond)); let hir_id = self.next_id(); - let span = self.lower_span(arm.span); self.lower_attrs(hir_id, &arm.attrs, arm.span); let is_never_pattern = pat.is_never_pattern(); // We need to lower the body even if it's unneeded for never pattern in match, @@ -652,8 +646,8 @@ impl<'hir> LoweringContext<'_, 'hir> { if !is_never_pattern { if self.tcx.features().never_patterns() { // If the feature is off we already emitted the error after parsing. - let suggestion = span.shrink_to_hi(); - self.dcx().emit_err(MatchArmWithNoBody { span, suggestion }); + let suggestion = arm.span.shrink_to_hi(); + self.dcx().emit_err(MatchArmWithNoBody { span: arm.span, suggestion }); } } else if let Some(body) = &arm.body { self.dcx().emit_err(NeverPatternWithBody { span: body.span }); @@ -668,16 +662,16 @@ impl<'hir> LoweringContext<'_, 'hir> { expr: None, hir_id: self.next_id(), rules: hir::BlockCheckMode::DefaultBlock, - span, + span: arm.span, targeted_by_break: false, }); self.arena.alloc(hir::Expr { hir_id: self.next_id(), - kind: hir::ExprKind::Loop(block, None, hir::LoopSource::Loop, span), - span, + kind: hir::ExprKind::Loop(block, None, hir::LoopSource::Loop, arm.span), + span: arm.span, }) }; - hir::Arm { hir_id, pat, guard, body, span } + hir::Arm { hir_id, pat, guard, body, span: arm.span } } /// Lower/desugar a coroutine construct. @@ -712,7 +706,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Resume argument type: `ResumeTy` let unstable_span = self.mark_span_with_reason( DesugaringKind::Async, - self.lower_span(span), + span, Some(Arc::clone(&self.allow_gen_future)), ); let resume_ty = @@ -730,12 +724,7 @@ impl<'hir> LoweringContext<'_, 'hir> { Ident::with_dummy_span(sym::_task_context), hir::BindingMode::MUT, ); - let param = hir::Param { - hir_id: self.next_id(), - pat, - ty_span: self.lower_span(span), - span: self.lower_span(span), - }; + let param = hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }; let params = arena_vec![self; param]; (inputs, params, Some(task_context_hid)) @@ -743,8 +732,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::CoroutineDesugaring::Gen => (&[], &[], None), }; - let output = - return_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span))); + let output = return_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(span)); let fn_decl = self.arena.alloc(hir::FnDecl { inputs, @@ -775,7 +763,7 @@ impl<'hir> LoweringContext<'_, 'hir> { bound_generic_params: &[], fn_decl, body, - fn_decl_span: self.lower_span(fn_decl_span), + fn_decl_span, fn_arg_span: None, kind: hir::ClosureKind::Coroutine(coroutine_kind), constness: hir::Constness::NotConst, @@ -996,8 +984,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }; let lhs = self.expr_ident(span, task_context_ident, task_context_hid); - let assign = - self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span))); + let assign = self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, span)); self.stmt_expr(span, assign) }; @@ -1006,13 +993,8 @@ impl<'hir> LoweringContext<'_, 'hir> { // loop { .. } let loop_expr = self.arena.alloc(hir::Expr { hir_id: loop_hir_id, - kind: hir::ExprKind::Loop( - loop_block, - None, - hir::LoopSource::Loop, - self.lower_span(span), - ), - span: self.lower_span(span), + kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop, span), + span, }); // mut __awaitee => loop { ... } @@ -1093,8 +1075,8 @@ impl<'hir> LoweringContext<'_, 'hir> { bound_generic_params, fn_decl, body: body_id, - fn_decl_span: self.lower_span(fn_decl_span), - fn_arg_span: Some(self.lower_span(fn_arg_span)), + fn_decl_span, + fn_arg_span: Some(fn_arg_span), kind: closure_kind, constness: self.lower_constness(constness), }); @@ -1139,7 +1121,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (binder, params) = match binder { ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]), ClosureBinder::For { span, generic_params } => { - let span = self.lower_span(*span); + let span = *span; (hir::ClosureBinder::For { span }, &**generic_params) } }; @@ -1207,8 +1189,8 @@ impl<'hir> LoweringContext<'_, 'hir> { bound_generic_params, fn_decl, body, - fn_decl_span: self.lower_span(fn_decl_span), - fn_arg_span: Some(self.lower_span(fn_arg_span)), + fn_decl_span, + fn_arg_span: Some(fn_arg_span), // Lower this as a `CoroutineClosure`. That will ensure that HIR typeck // knows that a `FnDecl` output type like `-> &str` actually means // "coroutine that returns &str", rather than directly returning a `&str`. @@ -1249,11 +1231,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } if is_ordinary(self, lhs) { - return hir::ExprKind::Assign( - self.lower_expr(lhs), - self.lower_expr(rhs), - self.lower_span(eq_sign_span), - ); + return hir::ExprKind::Assign(self.lower_expr(lhs), self.lower_expr(rhs), eq_sign_span); } let mut assignments = vec![]; @@ -1268,7 +1246,7 @@ impl<'hir> LoweringContext<'_, 'hir> { whole_span, Some(rhs), pat, - hir::LocalSource::AssignDesugar(self.lower_span(eq_sign_span)), + hir::LocalSource::AssignDesugar(eq_sign_span), ); // `a = lhs1; b = lhs2;`. @@ -1403,7 +1381,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unit_struct_pat = hir::PatKind::Expr(self.arena.alloc(hir::PatExpr { kind: hir::PatExprKind::Path(qpath), hir_id: self.next_id(), - span: self.lower_span(lhs.span), + span: lhs.span, })); return self.pat_without_dbm(lhs.span, unit_struct_pat); } @@ -1414,10 +1392,10 @@ impl<'hir> LoweringContext<'_, 'hir> { let pat = self.destructure_assign(&f.expr, eq_sign_span, assignments); hir::PatField { hir_id: self.next_id(), - ident: self.lower_ident(f.ident), + ident: f.ident, pat, is_shorthand: f.is_shorthand, - span: self.lower_span(f.span), + span: f.span, } })); let qpath = self.lower_qpath( @@ -1461,11 +1439,10 @@ impl<'hir> LoweringContext<'_, 'hir> { _ => {} } // Treat all other cases as normal lvalue. - let ident = Ident::new(sym::lhs, self.lower_span(lhs.span)); + let ident = Ident::new(sym::lhs, lhs.span); let (pat, binding) = self.pat_ident_mut(lhs.span, ident); let ident = self.expr_ident(lhs.span, ident, binding); - let assign = - hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span)); + let assign = hir::ExprKind::Assign(self.lower_expr(lhs), ident, eq_sign_span); let expr = self.expr(lhs.span, assign); assignments.push(self.stmt_expr(lhs.span, expr)); pat @@ -1505,7 +1482,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> { let e1 = self.lower_expr_mut(e1); let e2 = self.lower_expr_mut(e2); - let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span)); + let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, span); let fn_expr = self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path))); hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2]) } @@ -1563,14 +1540,14 @@ impl<'hir> LoweringContext<'_, 'hir> { e1.iter().map(|e| (sym::start, e)).chain(e2.iter().map(|e| (sym::end, e))).map( |(s, e)| { let expr = self.lower_expr(e); - let ident = Ident::new(s, self.lower_span(e.span)); + let ident = Ident::new(s, e.span); self.expr_field(ident, expr, e.span) }, ), ); hir::ExprKind::Struct( - self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span))), + self.arena.alloc(hir::QPath::LangItem(lang_item, span)), fields, hir::StructTailExpr::None, ) @@ -1586,7 +1563,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> Option