Skip to content

Commit 612e8d5

Browse files
refactor: apply rustc mod parsing changes
1 parent 2c63395 commit 612e8d5

File tree

5 files changed

+130
-70
lines changed

5 files changed

+130
-70
lines changed

Diff for: src/formatting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> {
145145
module: &Module<'_>,
146146
is_macro_def: bool,
147147
) -> Result<(), ErrorKind> {
148-
let snippet_provider = self.parse_session.snippet_provider(module.as_ref().inner);
148+
let snippet_provider = self.parse_session.snippet_provider(module.span);
149149
let mut visitor = FmtVisitor::from_parse_sess(
150150
&self.parse_session,
151151
&self.config,

Diff for: src/items.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3271,8 +3271,8 @@ pub(crate) fn rewrite_extern_crate(
32713271
/// Returns `true` for `mod foo;`, false for `mod foo { .. }`.
32723272
pub(crate) fn is_mod_decl(item: &ast::Item) -> bool {
32733273
match item.kind {
3274-
ast::ItemKind::Mod(ref m) => m.inner.hi() != item.span.hi(),
3275-
_ => false,
3274+
ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _)) => false,
3275+
_ => true,
32763276
}
32773277
}
32783278

Diff for: src/modules.rs

+110-49
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_ast::ast;
66
use rustc_ast::attr::HasAttrs;
77
use rustc_ast::visit::Visitor;
88
use rustc_span::symbol::{self, sym, Symbol};
9+
use rustc_span::Span;
910
use thiserror::Error;
1011

1112
use crate::attr::MetaVisitor;
@@ -24,20 +25,31 @@ type FileModMap<'ast> = BTreeMap<FileName, Module<'ast>>;
2425
/// Represents module with its inner attributes.
2526
#[derive(Debug, Clone)]
2627
pub(crate) struct Module<'a> {
27-
ast_mod: Cow<'a, ast::Mod>,
28+
ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
29+
pub(crate) items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
30+
attrs: Cow<'a, Vec<ast::Attribute>>,
2831
inner_attr: Vec<ast::Attribute>,
32+
pub(crate) span: Span,
2933
}
3034

3135
impl<'a> Module<'a> {
32-
pub(crate) fn new(ast_mod: Cow<'a, ast::Mod>, attrs: &[ast::Attribute]) -> Self {
33-
let inner_attr = attrs
36+
pub(crate) fn new(
37+
mod_span: Span,
38+
ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
39+
mod_items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
40+
mod_attrs: Cow<'a, Vec<ast::Attribute>>,
41+
) -> Self {
42+
let inner_attr = mod_attrs
3443
.iter()
3544
.filter(|attr| attr.style == ast::AttrStyle::Inner)
3645
.cloned()
3746
.collect();
3847
Module {
39-
ast_mod,
48+
items: mod_items,
49+
attrs: mod_attrs,
4050
inner_attr,
51+
span: mod_span,
52+
ast_mod_kind,
4153
}
4254
}
4355
}
@@ -51,12 +63,6 @@ impl<'a> HasAttrs for Module<'a> {
5163
}
5264
}
5365

54-
impl<'a> AsRef<ast::Mod> for Module<'a> {
55-
fn as_ref(&self) -> &ast::Mod {
56-
&self.ast_mod
57-
}
58-
}
59-
6066
/// Maps each module to the corresponding file.
6167
pub(crate) struct ModResolver<'ast, 'sess> {
6268
parse_sess: &'sess ParseSess,
@@ -124,12 +130,17 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
124130

125131
// Skip visiting sub modules when the input is from stdin.
126132
if self.recursive {
127-
self.visit_mod_from_ast(&krate.module)?;
133+
self.visit_mod_from_ast(&krate.items)?;
128134
}
129135

130136
self.file_map.insert(
131137
root_filename,
132-
Module::new(Cow::Borrowed(&krate.module), &krate.attrs),
138+
Module::new(
139+
krate.span,
140+
None,
141+
Cow::Borrowed(&krate.items),
142+
Cow::Borrowed(&krate.attrs),
143+
),
133144
);
134145
Ok(self.file_map)
135146
}
@@ -139,40 +150,69 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
139150
let mut visitor = visitor::CfgIfVisitor::new(self.parse_sess);
140151
visitor.visit_item(&item);
141152
for module_item in visitor.mods() {
142-
if let ast::ItemKind::Mod(ref sub_mod) = module_item.item.kind {
153+
if let ast::ItemKind::Mod(_, ref sub_mod_kind) = module_item.item.kind {
143154
self.visit_sub_mod(
144155
&module_item.item,
145-
Module::new(Cow::Owned(sub_mod.clone()), &module_item.item.attrs),
156+
Module::new(
157+
module_item.item.span,
158+
Some(Cow::Owned(sub_mod_kind.clone())),
159+
Cow::Owned(vec![]),
160+
Cow::Owned(vec![]),
161+
),
146162
)?;
147163
}
148164
}
149165
Ok(())
150166
}
151167

152168
/// Visit modules defined inside macro calls.
153-
fn visit_mod_outside_ast(&mut self, module: ast::Mod) -> Result<(), ModuleResolutionError> {
154-
for item in module.items {
169+
fn visit_mod_outside_ast(
170+
&mut self,
171+
items: Vec<rustc_ast::ptr::P<ast::Item>>,
172+
) -> Result<(), ModuleResolutionError> {
173+
for item in items {
155174
if is_cfg_if(&item) {
156175
self.visit_cfg_if(Cow::Owned(item.into_inner()))?;
157176
continue;
158177
}
159178

160-
if let ast::ItemKind::Mod(ref sub_mod) = item.kind {
161-
self.visit_sub_mod(&item, Module::new(Cow::Owned(sub_mod.clone()), &item.attrs))?;
179+
if let ast::ItemKind::Mod(_, ref sub_mod_kind) = item.kind {
180+
let span = item.span;
181+
self.visit_sub_mod(
182+
&item,
183+
Module::new(
184+
span,
185+
Some(Cow::Owned(sub_mod_kind.clone())),
186+
Cow::Owned(vec![]),
187+
Cow::Owned(vec![]),
188+
),
189+
)?;
162190
}
163191
}
164192
Ok(())
165193
}
166194

167195
/// Visit modules from AST.
168-
fn visit_mod_from_ast(&mut self, module: &'ast ast::Mod) -> Result<(), ModuleResolutionError> {
169-
for item in &module.items {
196+
fn visit_mod_from_ast(
197+
&mut self,
198+
items: &'ast Vec<rustc_ast::ptr::P<ast::Item>>,
199+
) -> Result<(), ModuleResolutionError> {
200+
for item in items {
170201
if is_cfg_if(item) {
171202
self.visit_cfg_if(Cow::Borrowed(item))?;
172203
}
173204

174-
if let ast::ItemKind::Mod(ref sub_mod) = item.kind {
175-
self.visit_sub_mod(item, Module::new(Cow::Borrowed(sub_mod), &item.attrs))?;
205+
if let ast::ItemKind::Mod(_, ref sub_mod_kind) = item.kind {
206+
let span = item.span;
207+
self.visit_sub_mod(
208+
item,
209+
Module::new(
210+
span,
211+
Some(Cow::Borrowed(sub_mod_kind)),
212+
Cow::Owned(vec![]),
213+
Cow::Borrowed(&item.attrs),
214+
),
215+
)?;
176216
}
177217
}
178218
Ok(())
@@ -273,9 +313,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
273313
if let Some(directory) = directory {
274314
self.directory = directory;
275315
}
276-
match sub_mod.ast_mod {
277-
Cow::Borrowed(sub_mod) => self.visit_mod_from_ast(sub_mod),
278-
Cow::Owned(sub_mod) => self.visit_mod_outside_ast(sub_mod),
316+
match (sub_mod.ast_mod_kind, sub_mod.items) {
317+
(Some(Cow::Borrowed(ast::ModKind::Loaded(items, ast::Inline::No, _))), _) => {
318+
self.visit_mod_from_ast(&items)
319+
}
320+
(Some(Cow::Owned(..)), Cow::Owned(items)) => self.visit_mod_outside_ast(items),
321+
(_, _) => Ok(()),
279322
}
280323
}
281324

@@ -294,13 +337,17 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
294337
if self.parse_sess.is_file_parsed(&path) {
295338
return Ok(None);
296339
}
297-
return match Parser::parse_file_as_module(self.parse_sess, &path, sub_mod.ast_mod.inner)
298-
{
299-
Ok((_, ref attrs)) if contains_skip(attrs) => Ok(None),
300-
Ok(m) => Ok(Some(SubModKind::External(
340+
return match Parser::parse_file_as_module(self.parse_sess, &path, sub_mod.span) {
341+
Ok((ref attrs, _, _)) if contains_skip(attrs) => Ok(None),
342+
Ok((attrs, items, span)) => Ok(Some(SubModKind::External(
301343
path,
302344
DirectoryOwnership::Owned { relative: None },
303-
Module::new(Cow::Owned(m.0), &m.1),
345+
Module::new(
346+
span,
347+
Some(Cow::Owned(ast::ModKind::Unloaded)),
348+
Cow::Owned(items),
349+
Cow::Owned(attrs),
350+
),
304351
))),
305352
Err(ParserError::ParseError) => Err(ModuleResolutionError {
306353
module: mod_name.to_string(),
@@ -338,18 +385,30 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
338385
return Ok(Some(SubModKind::MultiExternal(mods_outside_ast)));
339386
}
340387
}
341-
match Parser::parse_file_as_module(self.parse_sess, &path, sub_mod.ast_mod.inner) {
342-
Ok((_, ref attrs)) if contains_skip(attrs) => Ok(None),
343-
Ok(m) if outside_mods_empty => Ok(Some(SubModKind::External(
344-
path,
345-
ownership,
346-
Module::new(Cow::Owned(m.0), &m.1),
347-
))),
348-
Ok(m) => {
388+
match Parser::parse_file_as_module(self.parse_sess, &path, sub_mod.span) {
389+
Ok((ref attrs, _, _)) if contains_skip(attrs) => Ok(None),
390+
Ok((attrs, items, span)) if outside_mods_empty => {
391+
Ok(Some(SubModKind::External(
392+
path,
393+
ownership,
394+
Module::new(
395+
span,
396+
Some(Cow::Owned(ast::ModKind::Unloaded)),
397+
Cow::Owned(items),
398+
Cow::Owned(attrs),
399+
),
400+
)))
401+
}
402+
Ok((attrs, items, span)) => {
349403
mods_outside_ast.push((
350404
path.clone(),
351405
ownership,
352-
Module::new(Cow::Owned(m.0), &m.1),
406+
Module::new(
407+
span,
408+
Some(Cow::Owned(ast::ModKind::Unloaded)),
409+
Cow::Owned(items),
410+
Cow::Owned(attrs),
411+
),
353412
));
354413
if should_insert {
355414
mods_outside_ast.push((path, ownership, sub_mod.clone()));
@@ -437,20 +496,22 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
437496
));
438497
continue;
439498
}
440-
let m = match Parser::parse_file_as_module(
441-
self.parse_sess,
442-
&actual_path,
443-
sub_mod.ast_mod.inner,
444-
) {
445-
Ok((_, ref attrs)) if contains_skip(attrs) => continue,
446-
Ok(m) => m,
447-
Err(..) => continue,
448-
};
499+
let (attrs, items, span) =
500+
match Parser::parse_file_as_module(self.parse_sess, &actual_path, sub_mod.span) {
501+
Ok((ref attrs, _, _)) if contains_skip(attrs) => continue,
502+
Ok(m) => m,
503+
Err(..) => continue,
504+
};
449505

450506
result.push((
451507
actual_path,
452508
DirectoryOwnership::Owned { relative: None },
453-
Module::new(Cow::Owned(m.0), &m.1),
509+
Module::new(
510+
span,
511+
Some(Cow::Owned(ast::ModKind::Unloaded)),
512+
Cow::Owned(items),
513+
Cow::Owned(attrs),
514+
),
454515
))
455516
}
456517
result

Diff for: src/syntux/parser.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::panic::{catch_unwind, AssertUnwindSafe};
22
use std::path::{Path, PathBuf};
33

4-
use rustc_ast::ast;
54
use rustc_ast::token::{DelimToken, TokenKind};
5+
use rustc_ast::{ast, ptr};
66
use rustc_errors::Diagnostic;
77
use rustc_parse::{
88
new_parser_from_file,
@@ -109,10 +109,10 @@ impl<'a> Parser<'a> {
109109
sess: &'a ParseSess,
110110
path: &Path,
111111
span: Span,
112-
) -> Result<(ast::Mod, Vec<ast::Attribute>), ParserError> {
112+
) -> Result<(Vec<ast::Attribute>, Vec<ptr::P<ast::Item>>, Span), ParserError> {
113113
let result = catch_unwind(AssertUnwindSafe(|| {
114114
let mut parser = new_parser_from_file(sess.inner(), &path, Some(span));
115-
match parser.parse_mod(&TokenKind::Eof, ast::Unsafe::No) {
115+
match parser.parse_mod(&TokenKind::Eof) {
116116
Ok(result) => Some(result),
117117
Err(mut e) => {
118118
sess.emit_or_cancel_diagnostic(&mut e);

Diff for: src/visitor.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
524524
self.visit_enum(item.ident, &item.vis, def, generics, item.span);
525525
self.last_pos = source!(self, item.span).hi();
526526
}
527-
ast::ItemKind::Mod(ref module) => {
528-
let is_inline = !is_mod_decl(item);
527+
ast::ItemKind::Mod(unsafety, ref mod_kind) => {
529528
self.format_missing_with_indent(source!(self, item.span).lo());
530-
self.format_mod(module, &item.vis, item.span, item.ident, attrs, is_inline);
529+
self.format_mod(mod_kind, unsafety, &item.vis, item.span, item.ident, attrs);
531530
}
532531
ast::ItemKind::MacCall(ref mac) => {
533532
self.visit_mac(mac, Some(item.ident), MacroPosition::Item);
@@ -921,8 +920,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
921920
!is_skip_attr(segments)
922921
}
923922

924-
fn walk_mod_items(&mut self, m: &ast::Mod) {
925-
self.visit_items_with_reordering(&ptr_vec_to_ref_vec(&m.items));
923+
fn walk_mod_items(&mut self, items: &Vec<rustc_ast::ptr::P<ast::Item>>) {
924+
self.visit_items_with_reordering(&ptr_vec_to_ref_vec(&items));
926925
}
927926

928927
fn walk_stmts(&mut self, stmts: &[Stmt<'_>], include_current_empty_semi: bool) {
@@ -974,22 +973,22 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
974973

975974
fn format_mod(
976975
&mut self,
977-
m: &ast::Mod,
976+
mod_kind: &ast::ModKind,
977+
unsafety: ast::Unsafe,
978978
vis: &ast::Visibility,
979979
s: Span,
980980
ident: symbol::Ident,
981981
attrs: &[ast::Attribute],
982-
is_internal: bool,
983982
) {
984983
let vis_str = utils::format_visibility(&self.get_context(), vis);
985984
self.push_str(&*vis_str);
986-
self.push_str(format_unsafety(m.unsafety));
985+
self.push_str(format_unsafety(unsafety));
987986
self.push_str("mod ");
988987
// Calling `to_owned()` to work around borrow checker.
989988
let ident_str = rewrite_ident(&self.get_context(), ident).to_owned();
990989
self.push_str(&ident_str);
991990

992-
if is_internal {
991+
if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, inner_span) = mod_kind {
993992
match self.config.brace_style() {
994993
BraceStyle::AlwaysNextLine => {
995994
let indent_str = self.block_indent.to_string_with_newline(self.config);
@@ -1001,19 +1000,19 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
10011000
// Hackery to account for the closing }.
10021001
let mod_lo = self.snippet_provider.span_after(source!(self, s), "{");
10031002
let body_snippet =
1004-
self.snippet(mk_sp(mod_lo, source!(self, m.inner).hi() - BytePos(1)));
1003+
self.snippet(mk_sp(mod_lo, source!(self, inner_span).hi() - BytePos(1)));
10051004
let body_snippet = body_snippet.trim();
10061005
if body_snippet.is_empty() {
10071006
self.push_str("}");
10081007
} else {
10091008
self.last_pos = mod_lo;
10101009
self.block_indent = self.block_indent.block_indent(self.config);
10111010
self.visit_attrs(attrs, ast::AttrStyle::Inner);
1012-
self.walk_mod_items(m);
1013-
let missing_span = self.next_span(m.inner.hi() - BytePos(1));
1011+
self.walk_mod_items(items);
1012+
let missing_span = self.next_span(inner_span.hi() - BytePos(1));
10141013
self.close_block(missing_span, false);
10151014
}
1016-
self.last_pos = source!(self, m.inner).hi();
1015+
self.last_pos = source!(self, inner_span).hi();
10171016
} else {
10181017
self.push_str(";");
10191018
self.last_pos = source!(self, s).hi();
@@ -1023,9 +1022,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
10231022
pub(crate) fn format_separate_mod(&mut self, m: &Module<'_>, end_pos: BytePos) {
10241023
self.block_indent = Indent::empty();
10251024
if self.visit_attrs(m.attrs(), ast::AttrStyle::Inner) {
1026-
self.push_skipped_with_span(m.attrs(), m.as_ref().inner, m.as_ref().inner);
1025+
self.push_skipped_with_span(m.attrs(), m.span, m.span);
10271026
} else {
1028-
self.walk_mod_items(m.as_ref());
1027+
self.walk_mod_items(&m.items);
10291028
self.format_missing_with_indent(end_pos);
10301029
}
10311030
}

0 commit comments

Comments
 (0)