diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 725499e5c78..517d16cd526 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2317,11 +2317,24 @@ pub enum ModKind { /// or with definition outlined to a separate file `mod foo;` and already loaded from it. /// The inner span is from the first token past `{` to the last token until `}`, /// or from the first to the last token in the loaded file. - Loaded(Vec>, Inline, Span), + Loaded(Vec>, Inline, ModSpans), /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it. Unloaded, } +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct ModSpans { + /// `inner_span` covers the body of the module; for a file module, its the whole file. + /// For an inline module, its the span inside the `{ ... }`, not including the curly braces. + pub inner_span: Span, +} + +impl Default for ModSpans { + fn default() -> ModSpans { + ModSpans { inner_span: Default::default() } + } +} + /// Foreign module declaration. /// /// E.g., `extern { .. }` or `extern "C" { .. }`. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a81a2276295..8bc3afc500a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1009,7 +1009,7 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { ItemKind::Mod(unsafety, mod_kind) => { visit_unsafety(unsafety, vis); match mod_kind { - ModKind::Loaded(items, _inline, inner_span) => { + ModKind::Loaded(items, _inline, ModSpans { inner_span }) => { vis.visit_span(inner_span); items.flat_map_in_place(|item| vis.flat_map_item(item)); } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index e8fca6f04ba..aee117e554f 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -263,7 +263,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }) } ItemKind::Mod(_, ref mod_kind) => match mod_kind { - ModKind::Loaded(items, _, inner_span) => { + ModKind::Loaded(items, _, ModSpans { inner_span }) => { hir::ItemKind::Mod(self.lower_mod(items, *inner_span)) } ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 7ee0fb9b817..a489b23bad8 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -129,7 +129,9 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { // We don't want to recurse into anything other than mods, since // mods or tests inside of functions will break things - if let ast::ItemKind::Mod(_, ModKind::Loaded(.., span)) = item.kind { + if let ast::ItemKind::Mod(_, ModKind::Loaded(.., ast::ModSpans { inner_span: span })) = + item.kind + { let prev_tests = mem::take(&mut self.tests); noop_visit_item_kind(&mut item.kind, self); self.add_test_cases(item.id, span, prev_tests); diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 1b976180509..dc4d4e90cd2 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -12,8 +12,8 @@ use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor}; use rustc_ast::{AssocItemKind, AstLike, AstLikeWrapper, AttrStyle, ExprKind, ForeignItemKind}; -use rustc_ast::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind, NestedMetaItem}; -use rustc_ast::{NodeId, PatKind, StmtKind, TyKind}; +use rustc_ast::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind, ModSpans}; +use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind}; use rustc_ast_pretty::pprust; use rustc_data_structures::map_in_place::MapInPlace; use rustc_data_structures::sync::Lrc; @@ -1112,7 +1112,7 @@ impl InvocationCollectorNode for P { ); } - *mod_kind = ModKind::Loaded(items, Inline::No, inner_span); + *mod_kind = ModKind::Loaded(items, Inline::No, ModSpans { inner_span }); node.attrs = attrs; if node.attrs.len() > old_attrs_len { // If we loaded an out-of-line module and added some inner attributes, diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index a6e1232628f..a584c69fa70 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -1,6 +1,6 @@ use crate::base::ModuleData; use rustc_ast::ptr::P; -use rustc_ast::{token, Attribute, Inline, Item}; +use rustc_ast::{token, Attribute, Inline, Item, ModSpans}; use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed}; use rustc_parse::new_parser_from_file; use rustc_parse::validate_attr; @@ -69,7 +69,7 @@ crate fn parse_external_mod( (items, inner_span, mp.file_path) }; // (1) ...instead, we return a dummy module. - let (items, inner_span, file_path) = + let (items, ModSpans { inner_span }, file_path) = result.map_err(|err| err.report(sess, span)).unwrap_or_default(); // Extract the directory path for submodules of the module. diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index ae46bfe3540..aa0d8d68748 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -26,7 +26,8 @@ use tracing::debug; impl<'a> Parser<'a> { /// Parses a source module as a crate. This is the main entry point for the parser. pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> { - let (attrs, items, span) = self.parse_mod(&token::Eof)?; + let (attrs, items, spans) = self.parse_mod(&token::Eof)?; + let span = spans.inner_span; Ok(ast::Crate { attrs, items, span, id: DUMMY_NODE_ID, is_placeholder: false }) } @@ -51,7 +52,7 @@ impl<'a> Parser<'a> { pub fn parse_mod( &mut self, term: &TokenKind, - ) -> PResult<'a, (Vec, Vec>, Span)> { + ) -> PResult<'a, (Vec, Vec>, ModSpans)> { let lo = self.token.span; let attrs = self.parse_inner_attributes()?; @@ -71,7 +72,7 @@ impl<'a> Parser<'a> { } } - Ok((attrs, items, lo.to(self.prev_token.span))) + Ok((attrs, items, ModSpans { inner_span: lo.to(self.prev_token.span) })) } } diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs index f0944a88d2f..3b4e762b6dd 100644 --- a/src/tools/rustfmt/src/parse/parser.rs +++ b/src/tools/rustfmt/src/parse/parser.rs @@ -113,7 +113,7 @@ impl<'a> Parser<'a> { let result = catch_unwind(AssertUnwindSafe(|| { let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); match parser.parse_mod(&TokenKind::Eof) { - Ok(result) => Some(result), + Ok((a, i, ast::ModSpans { inner_span })) => Some((a, i, inner_span)), Err(mut e) => { e.emit(); if sess.can_reset_errors() { diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 0177689958a..57a58c60484 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -915,7 +915,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let ident_str = rewrite_ident(&self.get_context(), ident).to_owned(); self.push_str(&ident_str); - if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, inner_span) = mod_kind { + if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ast::ModSpans{ inner_span }) = mod_kind { match self.config.brace_style() { BraceStyle::AlwaysNextLine => { let indent_str = self.block_indent.to_string_with_newline(self.config);