From 8133ae491c760bc9514ad6bd6d1c105da27ed4e5 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 09:38:49 +0000 Subject: [PATCH 1/7] Replace kw_span by full span. --- compiler/rustc_ast/src/ast.rs | 7 ++----- compiler/rustc_ast/src/mut_visit.rs | 3 ++- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_ast_passes/src/ast_validation.rs | 4 ++-- .../src/deriving/generic/mod.rs | 4 ++-- compiler/rustc_parse/src/parser/generics.rs | 14 ++++++++++++-- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- src/tools/clippy/clippy_utils/src/ast_utils.rs | 4 ++-- src/tools/rustfmt/src/spanned.rs | 2 +- src/tools/rustfmt/src/types.rs | 4 ++-- 12 files changed, 29 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f5e79c04d784f..d1dd8d23e9acc 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -351,7 +351,7 @@ pub enum GenericParamKind { Const { ty: P, /// Span of the `const` keyword. - kw_span: Span, + span: Span, /// Optional default value for the const generic param default: Option, }, @@ -375,10 +375,7 @@ impl GenericParam { self.ident.span } GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span), - GenericParamKind::Const { kw_span, default: Some(default), .. } => { - kw_span.to(default.value.span) - } - GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span), + GenericParamKind::Const { span, .. } => *span, } } } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 27e781a5a6385..bbbeb15d5a213 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -941,8 +941,9 @@ pub fn noop_flat_map_generic_param( GenericParamKind::Type { default } => { visit_opt(default, |default| vis.visit_ty(default)); } - GenericParamKind::Const { ty, kw_span: _, default } => { + GenericParamKind::Const { ty, span, default } => { vis.visit_ty(ty); + vis.visit_span(span); visit_opt(default, |default| vis.visit_anon_const(default)); } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 26cb04d4d47fc..eed6fb2b7619a 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -758,7 +758,7 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>( match kind { GenericParamKind::Lifetime => (), GenericParamKind::Type { default } => visit_opt!(visitor, visit_ty, default), - GenericParamKind::Const { ty, default, kw_span: _ } => { + GenericParamKind::Const { ty, default, span: _ } => { try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_anon_const, default); } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8fba46625ab9a..58ce252f87502 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2209,7 +2209,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(self.lower_ident(param.ident)), kind) } - GenericParamKind::Const { ty, kw_span: _, default } => { + GenericParamKind::Const { ty, span: _, default } => { let ty = self .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault)); diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 022f953c6e70f..6c66be5b5950f 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -889,11 +889,11 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara } GenericParamKind::Type { default: None } => (), GenericParamKind::Lifetime => (), - GenericParamKind::Const { ty: _, kw_span: _, default: Some(default) } => { + GenericParamKind::Const { ty: _, span: _, default: Some(default) } => { ordered_params += " = "; ordered_params += &pprust::expr_to_string(&default.value); } - GenericParamKind::Const { ty: _, kw_span: _, default: None } => (), + GenericParamKind::Const { ty: _, span: _, default: None } => (), } first = false; } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index ba289f9552e22..f97a1290d8357 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -668,10 +668,10 @@ impl<'a> TraitDef<'a> { cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None) } - GenericParamKind::Const { ty, kw_span, .. } => { + GenericParamKind::Const { ty, span, .. } => { let const_nodefault_kind = GenericParamKind::Const { ty: ty.clone(), - kw_span: kw_span.with_ctxt(ctxt), + span: span.with_ctxt(ctxt), // We can't have default values inside impl block default: None, diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 10c7715c7dcd5..f28319bb3aa10 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -116,13 +116,18 @@ impl<'a> Parser<'a> { // Parse optional const generics default value. let default = if self.eat(&token::Eq) { Some(self.parse_const_arg()?) } else { None }; + let span = if let Some(ref default) = default { + const_span.to(default.value.span) + } else { + const_span.to(ty.span) + }; Ok(GenericParam { ident, id: ast::DUMMY_NODE_ID, attrs: preceding_attrs, bounds: Vec::new(), - kind: GenericParamKind::Const { ty, kw_span: const_span, default }, + kind: GenericParamKind::Const { ty, span, default }, is_placeholder: false, colon_span: None, }) @@ -139,6 +144,11 @@ impl<'a> Parser<'a> { // Parse optional const generics default value. let default = if self.eat(&token::Eq) { Some(self.parse_const_arg()?) } else { None }; + let span = if let Some(ref default) = default { + mistyped_const_ident.span.to(default.value.span) + } else { + mistyped_const_ident.span.to(ty.span) + }; self.dcx() .struct_span_err( @@ -158,7 +168,7 @@ impl<'a> Parser<'a> { id: ast::DUMMY_NODE_ID, attrs: preceding_attrs, bounds: Vec::new(), - kind: GenericParamKind::Const { ty, kw_span: mistyped_const_ident.span, default }, + kind: GenericParamKind::Const { ty, span, default }, is_placeholder: false, colon_span: None, }) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 66a1c05289b7d..98ff01e23f7de 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1498,7 +1498,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { .bindings .remove(&Ident::with_dummy_span(param.ident.name)); } - GenericParamKind::Const { ref ty, kw_span: _, ref default } => { + GenericParamKind::Const { ref ty, span: _, ref default } => { // Const parameters can't have param bounds. assert!(param.bounds.is_empty()); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 764cc350182a6..eb28d07536a00 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2547,7 +2547,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let span = if let [.., bound] = ¶m.bounds[..] { bound.span() } else if let GenericParam { - kind: GenericParamKind::Const { ty, kw_span: _, default }, .. + kind: GenericParamKind::Const { ty, span: _, default }, .. } = param { default.as_ref().map(|def| def.value.span).unwrap_or(ty.span) } else { diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 181bbdde8e5f1..1f243aa576681 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -762,13 +762,13 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool { ( Const { ty: lt, - kw_span: _, default: ld, + span: _, }, Const { ty: rt, - kw_span: _, default: rd, + span: _, }, ) => eq_ty(lt, rt) && both(ld, rd, eq_anon_const), _ => false, diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 1ee691b4ade0e..1b23ed93acc1d 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -120,7 +120,7 @@ impl Spanned for ast::GenericParam { fn span(&self) -> Span { let lo = match self.kind { _ if !self.attrs.is_empty() => self.attrs[0].span.lo(), - ast::GenericParamKind::Const { kw_span, .. } => kw_span.lo(), + ast::GenericParamKind::Const { span, .. } => span.lo(), _ => self.ident.span.lo(), }; let hi = if self.bounds.is_empty() { diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index c0bf9482b1143..3e4f4f7a0b991 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -603,7 +603,7 @@ impl Rewrite for ast::GenericParam { let param_start = if let ast::GenericParamKind::Const { ref ty, - kw_span, + span, default, } = &self.kind { @@ -621,7 +621,7 @@ impl Rewrite for ast::GenericParam { let rewrite = default.rewrite(context, Shape::legacy(budget, shape.indent))?; param.push_str(&rewrite); } - kw_span.lo() + span.lo() } else { param.push_str(rewrite_ident(context, self.ident)); self.ident.span.lo() From 4fbff98bf2d1d42525cf9cf331057ab276770d53 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 09:39:17 +0000 Subject: [PATCH 2/7] Complete mut_visit. --- compiler/rustc_ast/src/mut_visit.rs | 108 +++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index bbbeb15d5a213..49deef50f009f 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -871,7 +871,8 @@ fn visit_constness(constness: &mut Const, vis: &mut T) { fn noop_visit_closure_binder(binder: &mut ClosureBinder, vis: &mut T) { match binder { ClosureBinder::NotPresent => {} - ClosureBinder::For { span: _, generic_params } => { + ClosureBinder::For { span, generic_params } => { + vis.visit_span(span); generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); } } @@ -904,7 +905,10 @@ fn noop_visit_fn_ret_ty(fn_ret_ty: &mut FnRetTy, vis: &mut T) { fn noop_visit_param_bound(pb: &mut GenericBound, vis: &mut T) { match pb { - GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty), + GenericBound::Trait(ty, modifier) => { + vis.visit_poly_trait_ref(ty); + visit_trait_bound_modifier(modifier, vis); + } GenericBound::Outlives(lifetime) => noop_visit_lifetime(lifetime, vis), GenericBound::Use(args, span) => { for arg in args { @@ -915,6 +919,22 @@ fn noop_visit_param_bound(pb: &mut GenericBound, vis: &mut T) { } } +fn visit_trait_bound_modifier(tbm: &mut TraitBoundModifiers, vis: &mut T) { + let TraitBoundModifiers { constness, asyncness, polarity } = tbm; + match constness { + BoundConstness::Never => {} + BoundConstness::Always(span) | BoundConstness::Maybe(span) => vis.visit_span(span), + } + match asyncness { + BoundAsyncness::Normal => {} + BoundAsyncness::Async(span) => vis.visit_span(span), + } + match polarity { + BoundPolarity::Positive => {} + BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => vis.visit_span(span), + } +} + fn noop_visit_precise_capturing_arg(arg: &mut PreciseCapturingArg, vis: &mut T) { match arg { PreciseCapturingArg::Lifetime(lt) => { @@ -1369,21 +1389,24 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { vis.visit_span(span); } -fn noop_visit_anon_const(AnonConst { id, value }: &mut AnonConst, vis: &mut T) { +pub fn noop_visit_anon_const(AnonConst { id, value }: &mut AnonConst, vis: &mut T) { vis.visit_id(id); vis.visit_expr(value); } fn noop_visit_inline_asm(asm: &mut InlineAsm, vis: &mut T) { - // FIXME: Visit spans inside all this currently ignored stuff. - let InlineAsm { - template: _, - template_strs: _, - operands, - clobber_abis: _, - options: _, - line_spans: _, - } = asm; + let InlineAsm { template, template_strs, operands, clobber_abis, options: _, line_spans } = asm; + for piece in template.iter_mut() { + match piece { + InlineAsmTemplatePiece::String(_str) => {} + InlineAsmTemplatePiece::Placeholder { operand_idx: _, modifier: _, span } => { + vis.visit_span(span) + } + } + } + for (_s1, _s2, span) in template_strs.iter_mut() { + vis.visit_span(span) + } for (op, span) in operands { match op { InlineAsmOperand::In { expr, reg: _ } @@ -1402,6 +1425,12 @@ fn noop_visit_inline_asm(asm: &mut InlineAsm, vis: &mut T) { } vis.visit_span(span); } + for (_s1, span) in clobber_abis.iter_mut() { + vis.visit_span(span) + } + for span in line_spans.iter_mut() { + vis.visit_span(span) + } } fn noop_visit_inline_asm_sym( @@ -1414,8 +1443,7 @@ fn noop_visit_inline_asm_sym( } fn noop_visit_format_args(fmt: &mut FormatArgs, vis: &mut T) { - // FIXME: visit the template exhaustively. - let FormatArgs { span, template: _, arguments } = fmt; + let FormatArgs { span, template, arguments } = fmt; for FormatArgument { kind, expr } in arguments.all_args_mut() { match kind { FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { @@ -1425,9 +1453,48 @@ fn noop_visit_format_args(fmt: &mut FormatArgs, vis: &mut T) { } vis.visit_expr(expr); } + for piece in template.iter_mut() { + match piece { + FormatArgsPiece::Literal(_symbol) => {} + FormatArgsPiece::Placeholder(placeholder) => visit_format_placeholder(placeholder, vis), + } + } vis.visit_span(span); } +fn visit_format_placeholder( + FormatPlaceholder { argument, span, format_options, format_trait: _ }: &mut FormatPlaceholder, + vis: &mut T, +) { + visit_opt(span, |span| vis.visit_span(span)); + let FormatArgPosition { span, index: _, kind: _ } = argument; + visit_opt(span, |span| vis.visit_span(span)); + let FormatOptions { + width, + precision, + alignment: _, + fill: _, + sign: _, + alternate: _, + zero_pad: _, + debug_hex: _, + } = format_options; + match width { + None => {} + Some(FormatCount::Literal(_)) => {} + Some(FormatCount::Argument(FormatArgPosition { span, index: _, kind: _ })) => { + visit_opt(span, |span| vis.visit_span(span)) + } + } + match precision { + None => {} + Some(FormatCount::Literal(_)) => {} + Some(FormatCount::Argument(FormatArgPosition { span, index: _, kind: _ })) => { + visit_opt(span, |span| vis.visit_span(span)) + } + } +} + pub fn noop_visit_expr( Expr { kind, id, span, attrs, tokens }: &mut Expr, vis: &mut T, @@ -1461,7 +1528,8 @@ pub fn noop_visit_expr( visit_thin_exprs(call_args, vis); vis.visit_span(span); } - ExprKind::Binary(_binop, lhs, rhs) => { + ExprKind::Binary(Spanned { node: _binop, span }, lhs, rhs) => { + vis.visit_span(span); vis.visit_expr(lhs); vis.visit_expr(rhs); } @@ -1529,9 +1597,10 @@ pub fn noop_visit_expr( visit_opt(label, |label| vis.visit_label(label)); vis.visit_block(blk); } - ExprKind::Gen(_capture_by, body, _kind, decl_span) => { + ExprKind::Gen(capture_clause, body, _kind, decl_span) => { vis.visit_block(body); vis.visit_span(decl_span); + vis.visit_capture_by(capture_clause); } ExprKind::Await(expr, await_kw_span) => { vis.visit_expr(expr); @@ -1542,7 +1611,8 @@ pub fn noop_visit_expr( vis.visit_expr(er); vis.visit_span(span); } - ExprKind::AssignOp(_op, el, er) => { + ExprKind::AssignOp(Spanned { node: _binop, span }, el, er) => { + vis.visit_span(span); vis.visit_expr(el); vis.visit_expr(er); } @@ -1594,7 +1664,7 @@ pub fn noop_visit_expr( fields.flat_map_in_place(|field| vis.flat_map_expr_field(field)); match rest { StructRest::Base(expr) => vis.visit_expr(expr), - StructRest::Rest(_span) => {} + StructRest::Rest(span) => vis.visit_span(span), StructRest::None => {} } } @@ -1627,6 +1697,7 @@ pub fn noop_flat_map_stmt( vis: &mut T, ) -> SmallVec<[Stmt; 1]> { vis.visit_id(&mut id); + vis.visit_span(&mut span); let stmts: SmallVec<_> = noop_flat_map_stmt_kind(kind, vis) .into_iter() .map(|kind| Stmt { id, kind, span }) @@ -1637,7 +1708,6 @@ pub fn noop_flat_map_stmt( the visitor should implement custom statement visiting" ); } - vis.visit_span(&mut span); stmts } From 101653b3b8c3a80f5feab253b297594f6ddddd46 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 13:52:47 +0000 Subject: [PATCH 3/7] Remove parents from diagnostic hashing. --- compiler/rustc_error_messages/src/lib.rs | 11 ++++++++++ compiler/rustc_errors/src/diagnostic.rs | 23 ++++++++++++++------ compiler/rustc_errors/src/lib.rs | 27 +++++++++++++++++++----- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 26a68454ab3b1..93ea58f2dc20c 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -513,6 +513,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 d500f6d88a01b..3beff818e74f6 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -431,19 +431,23 @@ impl DiagInner { &Level, &[(DiagMessage, Style)], &Option, - &MultiSpan, - &[Subdiag], - &Result, SuggestionsDisabled>, + MultiSpan, + Vec, + Result, SuggestionsDisabled>, Vec<(&DiagArgName, &DiagArgValue)>, &Option, ) { + let suggestions = match &self.suggestions { + Ok(sugg) => Ok(sugg.iter().map(CodeSuggestion::clone_ignoring_parents).collect()), + Err(SuggestionsDisabled) => Err(SuggestionsDisabled), + }; ( &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, @@ -476,6 +480,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 2086d4030f905..c6af44f1156e1 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -197,9 +197,29 @@ impl SubstitutionPart { sm.span_to_snippet(self.span) .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() } + } } 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( @@ -1575,6 +1595,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) }; @@ -1584,18 +1605,14 @@ impl DiagCtxtInner { // Only emit the diagnostic if we've been asked to deduplicate or // haven't already emitted an equivalent diagnostic. if !(self.flags.deduplicate_diagnostics && already_emitted) { - debug!(?diagnostic); - debug!(?self.emitted_diagnostics); - let already_emitted_sub = |sub: &mut Subdiag| { - debug!(?sub); if sub.level != OnceNote && sub.level != OnceHelp { return false; } let mut hasher = StableHasher::new(); sub.hash(&mut hasher); let diagnostic_hash = hasher.finish(); - debug!(?diagnostic_hash); + debug!(?sub, ?diagnostic_hash); !self.emitted_diagnostics.insert(diagnostic_hash) }; diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {}); From 13306162673301dd12a9531fe23a6691d0f1245a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 11:28:17 +0000 Subject: [PATCH 4/7] Make def_collector a MutVisitor. --- compiler/rustc_ast/src/mut_visit.rs | 8 +- 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 | 384 ++++++++++++------ compiler/rustc_resolve/src/macros.rs | 2 +- 6 files changed, 272 insertions(+), 130 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 49deef50f009f..570bfbcf0be86 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -367,7 +367,7 @@ where } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_attrs(attrs: &mut AttrVec, vis: &mut T) { +pub fn visit_attrs(attrs: &mut AttrVec, vis: &mut T) { for attr in attrs.iter_mut() { vis.visit_attribute(attr); } @@ -390,7 +390,7 @@ fn visit_bounds(bounds: &mut GenericBounds, vis: &mut T) { } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_fn_sig(FnSig { header, decl, span }: &mut FnSig, vis: &mut T) { +pub fn visit_fn_sig(FnSig { header, decl, span }: &mut FnSig, vis: &mut T) { vis.visit_fn_header(header); vis.visit_fn_decl(decl); vis.visit_span(span); @@ -637,7 +637,7 @@ fn noop_visit_local(local: &mut P, vis: &mut T) { vis.visit_span(span); } -fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { +pub fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { let Attribute { kind, id: _, style: _, span } = attr; match kind { AttrKind::Normal(normal) => { @@ -836,7 +836,7 @@ fn visit_nonterminal(nt: &mut token::Nonterminal, vis: &mut T) { } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_defaultness(defaultness: &mut Defaultness, vis: &mut T) { +pub fn visit_defaultness(defaultness: &mut Defaultness, vis: &mut T) { match defaultness { Defaultness::Default(span) => vis.visit_span(span), Defaultness::Final => {} diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index d8e6d3525da8a..64d772fe7af1e 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -999,7 +999,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 26fc77c7f33d4..2d96ba72fc4d5 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -126,7 +126,7 @@ macro_rules! ast_fragments { T::fragment_to_output(self) } - pub(crate) fn mut_visit_with(&mut self, vis: &mut F) { + pub fn mut_visit_with(&mut self, vis: &mut F) { match self { AstFragment::OptExpr(opt_expr) => { visit_clobber(opt_expr, |opt_expr| { @@ -598,7 +598,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 4e0f2792d9749..bd37ca68eae10 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -183,7 +183,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { pub(crate) fn build_reduced_graph( &mut self, - fragment: &AstFragment, + fragment: &mut AstFragment, parent_scope: ParentScope<'a>, ) -> MacroRulesScopeRef<'a> { 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 80619c59cc381..1cec76388dabd 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -1,6 +1,7 @@ use crate::{ImplTraitContext, Resolver}; -use rustc_ast::visit::FnKind; +use rustc_ast::ptr::P; use rustc_ast::*; +use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_expand::expand::AstFragment; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind}; @@ -8,15 +9,21 @@ use rustc_hir::def_id::LocalDefId; use rustc_span::hygiene::LocalExpnId; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; +use smallvec::{smallvec, SmallVec}; use tracing::debug; pub(crate) fn collect_definitions( resolver: &mut Resolver<'_, '_>, - fragment: &AstFragment, + fragment: &mut AstFragment, expansion: LocalExpnId, ) { let (parent_def, impl_trait_context) = resolver.invocation_parents[&expansion]; - fragment.visit_with(&mut DefCollector { resolver, parent_def, expansion, impl_trait_context }); + fragment.mut_visit_with(&mut DefCollector { + resolver, + parent_def, + expansion, + impl_trait_context, + }); } /// Creates `DefId`s for nodes in the AST. @@ -52,23 +59,30 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> { .def_id() } - fn with_parent(&mut self, parent_def: LocalDefId, f: F) { + fn with_parent R>(&mut self, parent_def: LocalDefId, f: F) -> R { let orig_parent_def = std::mem::replace(&mut self.parent_def, parent_def); - f(self); + let res = f(self); self.parent_def = orig_parent_def; + res } - fn with_impl_trait( + fn with_impl_trait R>( &mut self, impl_trait_context: ImplTraitContext, f: F, - ) { + ) -> R { let orig_itc = std::mem::replace(&mut self.impl_trait_context, impl_trait_context); - f(self); + let res = f(self); self.impl_trait_context = orig_itc; + res } - fn collect_field(&mut self, field: &'a FieldDef, index: Option) { + #[tracing::instrument(level = "trace", skip(self))] + fn collect_field( + &mut self, + mut field: FieldDef, + index: Option, + ) -> SmallVec<[FieldDef; 1]> { let index = |this: &Self| { index.unwrap_or_else(|| { let node_id = NodeId::placeholder_from_expn_id(this.expansion); @@ -80,15 +94,18 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> { let old_index = self.resolver.placeholder_field_indices.insert(field.id, index(self)); assert!(old_index.is_none(), "placeholder field index is reset for a node ID"); self.visit_macro_invoc(field.id); + return smallvec![field]; } else { let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name); let def = self.create_def(field.id, name, DefKind::Field, field.span); - self.with_parent(def, |this| visit::walk_field_def(this, field)); - self.visit_anon_adt(&field.ty); + self.with_parent(def, |this| { + this.visit_anon_adt(&mut field.ty); + mut_visit::noop_flat_map_field_def(field, this) + }) } } - fn visit_anon_adt(&mut self, ty: &'a Ty) { + fn visit_anon_adt(&mut self, ty: &mut P) { let def_kind = match &ty.kind { TyKind::AnonStruct(..) => DefKind::Struct, TyKind::AnonUnion(..) => DefKind::Union, @@ -97,12 +114,13 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> { match &ty.kind { TyKind::AnonStruct(node_id, _) | TyKind::AnonUnion(node_id, _) => { let def_id = self.create_def(*node_id, kw::Empty, def_kind, ty.span); - self.with_parent(def_id, |this| visit::walk_ty(this, ty)); + self.with_parent(def_id, |this| mut_visit::noop_visit_ty(ty, this)); } _ => {} } } + #[tracing::instrument(level = "trace", skip(self))] fn visit_macro_invoc(&mut self, id: NodeId) { let id = id.placeholder_to_expn_id(); let old_parent = @@ -111,10 +129,9 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> { } } -impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { - fn visit_item(&mut self, i: &'a Item) { - debug!("visit_item: {:?}", i); - +impl<'a, 'b, 'tcx> mut_visit::MutVisitor for DefCollector<'a, 'b, 'tcx> { + #[tracing::instrument(level = "trace", skip(self))] + fn flat_map_item(&mut self, mut i: P) -> SmallVec<[P; 1]> { // Pick the def data. This need not be unique, but the more // information we encapsulate into, the better let mut opt_macro_data = None; @@ -137,15 +154,16 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { ItemKind::Const(..) => DefKind::Const, ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn, ItemKind::MacroDef(..) => { - let macro_data = self.resolver.compile_macro(i, self.resolver.tcx.sess.edition()); + let macro_data = self.resolver.compile_macro(&i, self.resolver.tcx.sess.edition()); let macro_kind = macro_data.ext.macro_kind(); opt_macro_data = Some(macro_data); DefKind::Macro(macro_kind) } ItemKind::GlobalAsm(..) => DefKind::GlobalAsm, - ItemKind::Use(..) => return visit::walk_item(self, i), + ItemKind::Use(..) => DefKind::Use, ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => { - return self.visit_macro_invoc(i.id); + self.visit_macro_invoc(i.id); + return smallvec![i]; } }; let def_id = self.create_def(i.id, i.ident.name, def_kind, i.span); @@ -156,7 +174,8 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { self.with_parent(def_id, |this| { this.with_impl_trait(ImplTraitContext::Existential, |this| { - match i.kind { + let item = &mut *i; + match &mut item.kind { ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => { // If this is a unit or tuple-like struct, register the constructor. if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(struct_def) { @@ -164,58 +183,74 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { ctor_node_id, kw::Empty, DefKind::Ctor(CtorOf::Struct, ctor_kind), - i.span, + item.span, ); } } + ItemKind::Fn(box Fn { defaultness, generics, sig, body }) + if let Some(coroutine_kind) = sig.header.coroutine_kind => + { + // 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 `noop_flat_map_item` below does. + mut_visit::visit_attrs(&mut item.attrs, this); + this.visit_vis(&mut item.vis); + this.visit_ident(&mut item.ident); + this.visit_span(&mut item.span); + mut_visit::visit_defaultness(defaultness, this); + this.visit_generics(generics); + mut_visit::visit_fn_sig(sig, this); + // 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 = this.create_def( + coroutine_kind.closure_id(), + kw::Empty, + DefKind::Closure, + item.span, + ); + this.with_parent(closure_def, |this| this.visit_block(body)); + } + return smallvec![i]; + } _ => {} } - visit::walk_item(this, i); + mut_visit::noop_flat_map_item(i, this) }) - }); + }) } - fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { - if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind { - match sig.header.coroutine_kind { - Some(coroutine_kind) => { - self.visit_generics(generics); - - // 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. - self.visit_fn_header(&sig.header); - for param in &sig.decl.inputs { - self.visit_param(param); - } - self.visit_fn_ret_ty(&sig.decl.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(), - kw::Empty, - DefKind::Closure, - span, - ); - self.with_parent(closure_def, |this| this.visit_block(body)); - } - return; + 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, + // and not to `self.parent_def` which is the topmost `use` item. + self.resolver.create_def( + self.resolver.tcx.local_parent(self.parent_def), + *id, + kw::Empty, + DefKind::Use, + self.expansion.to_expn_id(), + span.with_parent(None), + ); + self.visit_use_tree(tree); } - None => {} + self.visit_span(span); } + UseTreeKind::Glob => {} } - - visit::walk_fn(self, fn_kind); - } - - fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) { - self.create_def(id, kw::Empty, DefKind::Use, use_tree.span); - visit::walk_use_tree(self, use_tree, id); + self.visit_span(span); } - fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { + fn flat_map_foreign_item(&mut self, fi: P) -> SmallVec<[P; 1]> { let def_kind = match fi.kind { ForeignItemKind::Static(box StaticItem { ty: _, mutability, expr: _, safety }) => { let safety = match safety { @@ -227,17 +262,21 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { } ForeignItemKind::Fn(_) => DefKind::Fn, ForeignItemKind::TyAlias(_) => DefKind::ForeignTy, - ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id), + ForeignItemKind::MacCall(_) => { + self.visit_macro_invoc(fi.id); + return smallvec![fi]; + } }; let def = self.create_def(fi.id, fi.ident.name, def_kind, fi.span); - self.with_parent(def, |this| visit::walk_item(this, fi)); + self.with_parent(def, |this| mut_visit::noop_flat_map_item(fi, this)) } - fn visit_variant(&mut self, v: &'a Variant) { + fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { if v.is_placeholder { - return self.visit_macro_invoc(v.id); + self.visit_macro_invoc(v.id); + return smallvec![v]; } let def = self.create_def(v.id, v.ident.name, DefKind::Variant, v.span); self.with_parent(def, |this| { @@ -249,23 +288,37 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { v.span, ); } - visit::walk_variant(this, v) - }); + mut_visit::noop_flat_map_variant(v, this) + }) } - 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() { - self.collect_field(field, Some(index)); - } + 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; + } + }; + let mut index = 0; + fields.flat_map_in_place(|field| { + let field = self.collect_field(field, Some(index)); + index = index + 1; + field + }) } - fn visit_generic_param(&mut self, param: &'a GenericParam) { + fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { if param.is_placeholder { self.visit_macro_invoc(param.id); - return; + return smallvec![param]; } let def_kind = match param.kind { GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam, @@ -281,40 +334,121 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, '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::noop_flat_map_generic_param(param, this) + }) + } + + fn flat_map_trait_item(&mut self, mut i: P) -> SmallVec<[P; 1]> { + let def_kind = match &i.kind { + AssocItemKind::Fn(..) | AssocItemKind::Delegation(..) => DefKind::AssocFn, + AssocItemKind::Const(..) => DefKind::AssocConst, + AssocItemKind::Type(..) => DefKind::AssocTy, + AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { + self.visit_macro_invoc(i.id); + return smallvec![i]; + } + }; + + let span = i.span; + let def = self.create_def(i.id, i.ident.name, def_kind, span); + self.with_parent(def, |this| { + let item = &mut *i; + if let AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) = &mut item.kind + && let Some(coroutine_kind) = sig.header.coroutine_kind + { + // 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. + mut_visit::visit_attrs(&mut item.attrs, this); + this.visit_vis(&mut item.vis); + this.visit_ident(&mut item.ident); + this.visit_span(&mut item.span); + mut_visit::visit_defaultness(defaultness, this); + this.visit_generics(generics); + mut_visit::visit_fn_sig(sig, this); + // 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 = this.create_def( + coroutine_kind.closure_id(), + kw::Empty, + DefKind::Closure, + span, + ); + this.with_parent(closure_def, |this| this.visit_block(body)); + } + return smallvec![i]; + } + mut_visit::noop_flat_map_item(i, this) + }) } - fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) { + fn flat_map_impl_item(&mut self, mut i: P) -> SmallVec<[P; 1]> { let def_kind = match &i.kind { AssocItemKind::Fn(..) | AssocItemKind::Delegation(..) => DefKind::AssocFn, AssocItemKind::Const(..) => DefKind::AssocConst, AssocItemKind::Type(..) => DefKind::AssocTy, AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { - return self.visit_macro_invoc(i.id); + self.visit_macro_invoc(i.id); + return smallvec![i]; } }; - let def = self.create_def(i.id, i.ident.name, def_kind, i.span); - self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); + let span = i.span; + let def = self.create_def(i.id, i.ident.name, def_kind, span); + self.with_parent(def, |this| { + let item = &mut *i; + if let AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) = &mut item.kind + && let Some(coroutine_kind) = sig.header.coroutine_kind + { + // 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. + mut_visit::visit_attrs(&mut item.attrs, this); + this.visit_vis(&mut item.vis); + this.visit_ident(&mut item.ident); + this.visit_span(&mut item.span); + mut_visit::visit_defaultness(defaultness, this); + this.visit_generics(generics); + mut_visit::visit_fn_sig(sig, this); + // 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 = this.create_def( + coroutine_kind.closure_id(), + kw::Empty, + DefKind::Closure, + span, + ); + this.with_parent(closure_def, |this| this.visit_block(body)); + } + return smallvec![i]; + } + mut_visit::noop_flat_map_item(i, this) + }) } - 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 P) { + if let PatKind::MacCall(..) = pat.kind { + return self.visit_macro_invoc(pat.id); } + mut_visit::noop_visit_pat(pat, self) } - fn visit_anon_const(&mut self, constant: &'a AnonConst) { + fn visit_anon_const(&mut self, constant: &mut AnonConst) { let def = self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span); - self.with_parent(def, |this| visit::walk_anon_const(this, constant)); + self.with_parent(def, |this| mut_visit::noop_visit_anon_const(constant, this)) } - fn visit_expr(&mut self, expr: &'a Expr) { + fn visit_expr(&mut self, expr: &mut P) { + let expr = &mut **expr; let parent_def = match expr.kind { - ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id), - ExprKind::Closure(ref closure) => { + ExprKind::MacCall(..) => { + return self.visit_macro_invoc(expr.id); + } + ExprKind::Closure(ref mut closure) => { // Async closures desugar to closures inside of closures, so // we must create two defs. let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span); @@ -327,7 +461,9 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { DefKind::Closure, expr.span, ); - this.with_parent(coroutine_def, |this| visit::walk_expr(this, expr)); + this.with_parent(coroutine_def, |this| { + mut_visit::noop_visit_expr(expr, this) + }); }); return; } @@ -337,80 +473,86 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { ExprKind::Gen(_, _, _, _) => { self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span) } - ExprKind::ConstBlock(ref constant) => { - for attr in &expr.attrs { - visit::walk_attribute(self, attr); - } + ExprKind::ConstBlock(ref mut constant) => { + mut_visit::visit_attrs(&mut expr.attrs, self); + self.visit_span(&mut expr.span); let def = self.create_def( constant.id, kw::Empty, DefKind::InlineConst, constant.value.span, ); - self.with_parent(def, |this| visit::walk_anon_const(this, constant)); + self.with_parent(def, |this| mut_visit::noop_visit_anon_const(constant, this)); return; } _ => self.parent_def, }; - self.with_parent(parent_def, |this| visit::walk_expr(this, expr)); + self.with_parent(parent_def, |this| mut_visit::noop_visit_expr(expr, this)) } - fn visit_ty(&mut self, ty: &'a Ty) { + #[tracing::instrument(level = "trace", skip(self))] + fn visit_ty(&mut self, ty: &mut P) { match &ty.kind { - TyKind::MacCall(..) => self.visit_macro_invoc(ty.id), + TyKind::MacCall(..) => return self.visit_macro_invoc(ty.id), // Anonymous structs or unions are visited later after defined. TyKind::AnonStruct(..) | TyKind::AnonUnion(..) => {} - _ => visit::walk_ty(self, ty), + _ => mut_visit::noop_visit_ty(ty, self), } } - fn visit_stmt(&mut self, stmt: &'a Stmt) { - match stmt.kind { - StmtKind::MacCall(..) => self.visit_macro_invoc(stmt.id), - _ => visit::walk_stmt(self, stmt), + fn flat_map_stmt(&mut self, stmt: Stmt) -> SmallVec<[Stmt; 1]> { + if let StmtKind::MacCall(..) = stmt.kind { + self.visit_macro_invoc(stmt.id); + return smallvec![stmt]; } + mut_visit::noop_flat_map_stmt(stmt, self) } - 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 flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { + if arm.is_placeholder { + self.visit_macro_invoc(arm.id); + return smallvec![arm]; + } + mut_visit::noop_flat_map_arm(arm, self) } - fn visit_expr_field(&mut self, f: &'a ExprField) { + fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { if f.is_placeholder { - self.visit_macro_invoc(f.id) - } else { - visit::walk_expr_field(self, f) + self.visit_macro_invoc(f.id); + return smallvec![f]; } + mut_visit::noop_flat_map_expr_field(f, self) } - fn visit_pat_field(&mut self, fp: &'a PatField) { + fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { if fp.is_placeholder { - self.visit_macro_invoc(fp.id) - } else { - visit::walk_pat_field(self, fp) + self.visit_macro_invoc(fp.id); + return smallvec![fp]; } + mut_visit::noop_flat_map_pat_field(fp, self) } - fn visit_param(&mut self, p: &'a Param) { + fn flat_map_param(&mut self, p: Param) -> SmallVec<[Param; 1]> { if p.is_placeholder { - self.visit_macro_invoc(p.id) - } else { - self.with_impl_trait(ImplTraitContext::Universal, |this| visit::walk_param(this, p)) + self.visit_macro_invoc(p.id); + return smallvec![p]; } + self.with_impl_trait(ImplTraitContext::Universal, |this| { + mut_visit::noop_flat_map_param(p, this) + }) } // 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 flat_map_field_def(&mut self, field: FieldDef) -> SmallVec<[FieldDef; 1]> { + 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::noop_visit_crate(krate, self) } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 026a2ca14128e..eb11719189956 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -193,7 +193,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, '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 e7da3f0911986b36e7620acc7bffbd40ba82c195 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 11:40:02 +0000 Subject: [PATCH 5/7] Mark span parent in def_collector. --- compiler/rustc_ast_lowering/src/expr.rs | 38 +++++++++++++------ compiler/rustc_ast_lowering/src/item.rs | 2 + .../rustc_hir_typeck/src/method/suggest.rs | 4 +- compiler/rustc_resolve/src/def_collector.rs | 4 ++ .../issue-69396-const-no-type-in-macro.stderr | 5 ++- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 218fa9740229d..1d3abe0704c2d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -20,7 +20,6 @@ use rustc_middle::span_bug; use rustc_session::errors::report_lit_error; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::DUMMY_SP; use rustc_span::{DesugaringKind, Span}; use thin_vec::{thin_vec, ThinVec}; @@ -190,7 +189,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::Closure(box Closure { binder, capture_clause, @@ -256,9 +257,11 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::Field(el, ident) => { hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident)) } - ExprKind::Index(el, er, brackets_span) => { - hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er), *brackets_span) - } + ExprKind::Index(el, er, brackets_span) => hir::ExprKind::Index( + self.lower_expr(el), + self.lower_expr(er), + self.lower_span(*brackets_span), + ), ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => { self.lower_expr_range_closed(e.span, e1, e2) } @@ -400,7 +403,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, }))); @@ -747,20 +750,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, @@ -1692,7 +1699,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 }) } }; @@ -1998,6 +2010,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 = self .arena .alloc(hir::Lit { span: sp, node: ast::LitKind::Str(value, ast::StrStyle::Cooked) }); @@ -2052,7 +2065,8 @@ impl<'hir> LoweringContext<'_, 'hir> { lang_item: hir::LangItem, name: Symbol, ) -> hir::Expr<'hir> { - let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span)); + let span = self.lower_span(span); + let qpath = self.make_lang_item_qpath(lang_item, span); let path = hir::ExprKind::Path(hir::QPath::TypeRelative( self.arena.alloc(self.ty(span, hir::TyKind::Path(qpath))), self.arena.alloc(hir::PathSegment::new( diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d59ac5766298d..e5d5e5cdb65f1 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -179,6 +179,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, ident, attrs) } ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => { @@ -591,6 +592,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: smallvec![], 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 e310730bf9e91..df3a95fa39c7d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -772,9 +772,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 1cec76388dabd..cbc3f6b0fae26 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -130,6 +130,10 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> { } impl<'a, 'b, 'tcx> mut_visit::MutVisitor for DefCollector<'a, 'b, 'tcx> { + fn visit_span(&mut self, span: &mut Span) { + *span = span.with_parent(Some(self.parent_def)); + } + #[tracing::instrument(level = "trace", skip(self))] fn flat_map_item(&mut self, mut i: P) -> SmallVec<[P; 1]> { // Pick the def data. This need not be unique, but the more diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr index 89aeafebac497..f581429a28154 100644 --- a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr +++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr @@ -2,7 +2,10 @@ error[E0428]: the name `A` is defined multiple times --> $DIR/issue-69396-const-no-type-in-macro.rs:4:13 | LL | const A = "A".$fn(); - | ^^^^^^^^^^^^^^^^^^^^ `A` redefined here + | ^^^^^^^^^^^^^^^^^^^^ + | | + | `A` redefined here + | previous definition of the value `A` here ... LL | / suite! { LL | | len; From bd46218c3872716326b00269c5da44f4cb868e11 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 12:51:33 +0000 Subject: [PATCH 6/7] 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 | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 154 ++++++---------- compiler/rustc_ast_lowering/src/item.rs | 99 +++++------ compiler/rustc_ast_lowering/src/lib.rs | 166 +++++++----------- compiler/rustc_ast_lowering/src/pat.rs | 14 +- compiler/rustc_ast_lowering/src/path.rs | 20 +-- 8 files changed, 178 insertions(+), 300 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 666e7763e6276..fff4e0aeb4a48 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -250,7 +250,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(); @@ -458,7 +458,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { late: true, expr: None, }, - self.lower_span(abi_span), + abi_span, )); clobbered.insert(clobber); } @@ -468,12 +468,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 { template, template_strs, operands, options: asm.options, line_spans }; self.arena.alloc(hir_asm) diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index e821a08bf1817..af16ceefe0e73 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -21,7 +21,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let (stmts, expr) = self.lower_stmts(&b.stmts); let rules = self.lower_block_check_mode(&b.rules); let hir_id = self.lower_node_id(b.id); - 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( @@ -37,7 +37,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) => { @@ -48,7 +48,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 } }, )); @@ -61,7 +61,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 }); } } @@ -70,7 +70,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 => {} @@ -94,7 +94,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); self.arena.alloc(hir::LetStmt { hir_id, 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 678cac210f413..eca146842bacf 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -88,7 +88,7 @@ impl<'hir> LoweringContext<'_, 'hir> { delegation: &Delegation, item_id: NodeId, ) -> 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); match sig_id { Ok(sig_id) => { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 1d3abe0704c2d..2d54adb9a5732 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -40,7 +40,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() { @@ -108,7 +108,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); @@ -130,14 +130,13 @@ impl<'hir> LoweringContext<'_, 'hir> { LitKind::Err(guar) } }; - let lit = self.arena.alloc(respan(self.lower_span(e.span), lit_kind)); + let lit = self.arena.alloc(respan(e.span, lit_kind)); hir::ExprKind::Lit(lit) } ExprKind::IncludedBytes(bytes) => { - let lit = self.arena.alloc(respan( - self.lower_span(e.span), - LitKind::ByteStr(bytes.clone(), StrStyle::Cooked), - )); + let lit = self + .arena + .alloc(respan(e.span, LitKind::ByteStr(bytes.clone(), StrStyle::Cooked))); hir::ExprKind::Lit(lit) } ExprKind::Cast(expr, ty) => { @@ -158,7 +157,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), @@ -175,9 +174,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::Loop(body, opt_label, span) => self.with_loop_scope(e.id, |this| { hir::ExprKind::Loop( this.lower_block(body, false), - this.lower_label(*opt_label), + *opt_label, hir::LoopSource::Loop, - this.lower_span(*span), + *span, ) }), ExprKind::TryBlock(body) => self.lower_expr_try_block(body), @@ -245,8 +244,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } ExprKind::Block(blk, opt_label) => { - let opt_label = self.lower_label(*opt_label); - hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label) + hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), *opt_label) } ExprKind::Assign(el, er, span) => self.lower_expr_assign(el, er, *span, e.span), ExprKind::AssignOp(op, el, er) => hir::ExprKind::AssignOp( @@ -254,14 +252,10 @@ 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) } - ExprKind::Index(el, er, brackets_span) => hir::ExprKind::Index( - self.lower_expr(el), - self.lower_expr(er), - self.lower_span(*brackets_span), - ), ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => { self.lower_expr_range_closed(e.span, e1, e2) } @@ -308,7 +302,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 { @@ -349,7 +343,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span), }; - hir::Expr { hir_id, kind, span: self.lower_span(e.span) } + hir::Expr { hir_id, kind, span: e.span } }) } @@ -362,7 +356,7 @@ 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_legacy_const_generics( @@ -501,8 +495,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 opt_label = self.lower_label(opt_label); + let span = span.with_hi(cond.span.hi()); hir::ExprKind::Loop(block, opt_label, hir::LoopSource::While, span) } @@ -563,7 +556,7 @@ 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); + let span = arm.span; self.lower_attrs(hir_id, &arm.attrs); let is_never_pattern = pat.is_never_pattern(); let body = if let Some(body) = &arm.body @@ -634,7 +627,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(self.allow_gen_future.clone()), ); let resume_ty = self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span); @@ -651,12 +644,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)) @@ -664,8 +652,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, @@ -696,7 +683,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, @@ -916,8 +903,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) }; @@ -926,13 +912,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 { ... } @@ -1007,8 +988,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), }); @@ -1053,7 +1034,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) } }; @@ -1119,8 +1100,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`. @@ -1161,11 +1142,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![]; @@ -1180,7 +1157,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;`. @@ -1320,10 +1297,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( @@ -1366,11 +1343,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 @@ -1410,7 +1386,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]) } @@ -1444,22 +1420,13 @@ 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))), - fields, - None, - ) - } - - fn lower_label(&self, opt_label: Option