From 2f2cb6dac414754f8b3a207be9db77664dc12128 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 13:52:47 +0000 Subject: [PATCH 01/10] 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 96c7ba6ed27b9..ef0680c3c5de5 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 da965d370e049fb0f16ecf449ff38aef3c98c2fb Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 26 Jul 2025 21:37:41 +0000 Subject: [PATCH 02/10] Also visit FormatOptions in AST. --- compiler/rustc_ast/src/format.rs | 8 +++++--- compiler/rustc_ast/src/visit.rs | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast/src/format.rs b/compiler/rustc_ast/src/format.rs index c2a1de60a9816..c75d1d5982ba5 100644 --- a/compiler/rustc_ast/src/format.rs +++ b/compiler/rustc_ast/src/format.rs @@ -180,7 +180,6 @@ pub struct FormatPlaceholder { #[visitable(ignore)] pub format_trait: FormatTrait, /// `{}` or `{:.5}` or `{:-^20}`, etc. - #[visitable(ignore)] pub format_options: FormatOptions, } @@ -229,23 +228,26 @@ pub enum FormatTrait { UpperHex, } -#[derive(Clone, Encodable, Decodable, Default, Debug, PartialEq, Eq)] +#[derive(Clone, Encodable, Decodable, Default, Debug, PartialEq, Eq, Walkable)] pub struct FormatOptions { /// The width. E.g. `{:5}` or `{:width$}`. pub width: Option, /// The precision. E.g. `{:.5}` or `{:.precision$}`. pub precision: Option, /// The alignment. E.g. `{:>}` or `{:<}` or `{:^}`. + #[visitable(ignore)] pub alignment: Option, /// The fill character. E.g. the `.` in `{:.>10}`. pub fill: Option, /// The `+` or `-` flag. + #[visitable(ignore)] pub sign: Option, /// The `#` flag. pub alternate: bool, /// The `0` flag. E.g. the `0` in `{:02x}`. pub zero_pad: bool, /// The `x` or `X` flag (for `Debug` only). E.g. the `x` in `{:x?}`. + #[visitable(ignore)] pub debug_hex: Option, } @@ -275,7 +277,7 @@ pub enum FormatAlignment { Center, } -#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)] +#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)] pub enum FormatCount { /// `{:5}` or `{:.5}` Literal(u16), diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ab15cb28fa12d..ecbb2540727da 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -375,6 +375,7 @@ macro_rules! common_visitor_and_walkers { std::borrow::Cow<'_, str>, Symbol, u8, + u16, usize, ); // `Span` is only a no-op for the non-mutable visitor. @@ -436,6 +437,8 @@ macro_rules! common_visitor_and_walkers { FormatArgument, FormatArgumentKind, FormatArguments, + FormatCount, + FormatOptions, FormatPlaceholder, GenericParamKind, Impl, From 1d07d68a051523707f891a3dc784ccc06d8840fa Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 11:28:17 +0000 Subject: [PATCH 03/10] Make def_collector a MutVisitor. --- compiler/rustc_ast/src/visit.rs | 1 + 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 | 294 +++++++++++------- compiler/rustc_resolve/src/macros.rs | 2 +- 6 files changed, 196 insertions(+), 109 deletions(-) diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ecbb2540727da..b5ec5bad2613f 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1070,6 +1070,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_contract(FnContract); pub fn walk_coroutine_kind(CoroutineKind); pub fn walk_crate(Crate); + pub fn walk_defaultness(Defaultness); pub fn walk_expr(Expr); pub fn walk_expr_field(ExprField); pub fn walk_field_def(FieldDef); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 25ec540111117..43672eaefd02b 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1063,7 +1063,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 79ec79a2fdf42..337433d0f5b3e 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -137,7 +137,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() { @@ -664,7 +664,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 83ec037a975d4..fa0b5b7f4993b 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -183,7 +183,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 7d51fef28d3ba..ba5dc63ce8dde 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, ShouldEmit}; 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; @@ -156,7 +156,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); @@ -186,68 +188,115 @@ 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::walk_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); + if let Some(define_opaque) = define_opaque { + for (node_id, path) in define_opaque { + self.visit_id(node_id); + self.visit_path(path); + } + } // 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, @@ -270,14 +319,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) { @@ -288,31 +337,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, @@ -328,11 +387,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), @@ -344,43 +403,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, _) => { @@ -392,96 +453,114 @@ 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: _, - template_strs: _, + template, + template_strs, operands, - clobber_abis: _, + clobber_abis, options: _, - line_spans: _, + line_spans, } = asm; - for (op, _span) in operands { + for piece in template { + match piece { + InlineAsmTemplatePiece::String(_str) => {} + InlineAsmTemplatePiece::Placeholder { operand_idx: _, modifier: _, span } => { + self.visit_span(span); + } + } + } + for (_s1, _s2, span) in template_strs { + self.visit_span(span); + } + for (op, span) in operands { match op { InlineAsmOperand::In { expr, reg: _ } | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } @@ -502,11 +581,18 @@ 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), } + self.visit_span(span); + } + for (_s1, span) in clobber_abis { + self.visit_span(span); + } + for span in line_spans { + self.visit_span(span); } } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index f0225daa09dbb..ab21341160025 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 ddc5eb03385776c5fea71c1ddb14bced2aed63e0 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 11:40:02 +0000 Subject: [PATCH 04/10] Mark span parent in def_collector. --- compiler/rustc_resolve/src/def_collector.rs | 6 ++++++ tests/incremental/hashes/function_interfaces.rs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index ba5dc63ce8dde..2fd303e7cf38d 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 ffbbfe4180587aa7861ce5043df4b77d96405fe5 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 20 Jul 2025 20:26:37 +0000 Subject: [PATCH 05/10] 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 | 148 ++++++---------- compiler/rustc_ast_lowering/src/index.rs | 40 ++--- compiler/rustc_ast_lowering/src/item.rs | 127 ++++++-------- 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 +- 11 files changed, 214 insertions(+), 381 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 15e736261d583..a12c65d3c2eeb 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, ) }) } @@ -279,9 +276,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) } @@ -329,7 +324,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 { @@ -376,7 +371,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 } }) } @@ -429,7 +424,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 { @@ -441,11 +436,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( @@ -573,7 +568,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) } @@ -635,7 +630,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, @@ -650,8 +644,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 }); @@ -666,16 +660,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. @@ -710,7 +704,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 = @@ -728,12 +722,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)) @@ -741,8 +730,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, @@ -773,7 +761,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, @@ -990,8 +978,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) }; @@ -1000,13 +987,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 { ... } @@ -1087,8 +1069,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), }); @@ -1133,7 +1115,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) } }; @@ -1201,8 +1183,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`. @@ -1243,11 +1225,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![]; @@ -1262,7 +1240,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;`. @@ -1397,7 +1375,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); } @@ -1408,10 +1386,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( @@ -1455,11 +1433,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 @@ -1499,7 +1476,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]) } @@ -1557,14 +1534,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, ) @@ -1580,7 +1557,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> Option