From 4a8816512477513f57986685738cd065e72c4908 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 17 Feb 2021 00:56:07 +0300 Subject: [PATCH] ast: Keep expansion status for out-of-line module items Also remove `ast::Mod` which is mostly redundant now --- compiler/rustc_ast/src/ast.rs | 33 +++---- compiler/rustc_ast/src/mut_visit.rs | 18 ++-- compiler/rustc_ast/src/visit.rs | 7 +- compiler/rustc_ast_lowering/src/item.rs | 7 +- .../rustc_ast_passes/src/ast_validation.rs | 6 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 42 +++++---- .../rustc_builtin_macros/src/test_harness.rs | 13 ++- compiler/rustc_expand/src/expand.rs | 90 ++++++++++--------- compiler/rustc_expand/src/module.rs | 23 +++-- compiler/rustc_expand/src/parse/tests.rs | 4 +- compiler/rustc_parse/src/parser/item.rs | 12 +-- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 6 +- .../clippy_lints/src/utils/ast_utils.rs | 9 +- 14 files changed, 147 insertions(+), 125 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b01e8ccd677..3550055ac10 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2299,21 +2299,22 @@ impl FnRetTy { } } -/// Module declaration. -/// -/// E.g., `mod foo;` or `mod foo { .. }`. +#[derive(Clone, PartialEq, Encodable, Decodable, Debug)] +pub enum Inline { + Yes, + No, +} + +/// Module item kind. #[derive(Clone, Encodable, Decodable, Debug)] -pub struct Mod { - /// A span from the first token past `{` to the last token until `}`. - /// For `mod foo;`, the inner span ranges from the first token - /// to the last token in the external file. - pub inner: Span, - /// `unsafe` keyword accepted syntactically for macro DSLs, but not - /// semantically by Rust. - pub unsafety: Unsafe, - pub items: Vec>, - /// `true` for `mod foo { .. }`; `false` for `mod foo;`. - pub inline: bool, +pub enum ModKind { + /// Module with inlined definition `mod foo { ... }`, + /// 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), + /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it. + Unloaded, } /// Foreign module declaration. @@ -2710,7 +2711,9 @@ pub enum ItemKind { /// A module declaration (`mod`). /// /// E.g., `mod foo;` or `mod foo { .. }`. - Mod(Mod), + /// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not + /// semantically by Rust. + Mod(Unsafe, ModKind), /// An external module (`extern`). /// /// 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 5333da07aa0..c286738811c 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -913,11 +913,13 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { vis.visit_generics(generics); visit_opt(body, |body| vis.visit_block(body)); } - ItemKind::Mod(m) => { - let Mod { inner, unsafety: _, items, inline: _ } = m; - vis.visit_span(inner); - items.flat_map_in_place(|item| vis.flat_map_item(item)); - } + ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { + ModKind::Loaded(items, _inline, inner_span) => { + vis.visit_span(inner_span); + items.flat_map_in_place(|item| vis.flat_map_item(item)); + } + ModKind::Unloaded => {} + }, ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), ItemKind::GlobalAsm(_ga) => {} ItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => { @@ -1010,7 +1012,7 @@ pub fn noop_visit_crate(krate: &mut Crate, vis: &mut T) { id: DUMMY_NODE_ID, vis: item_vis, span, - kind: ItemKind::Mod(Mod { inner: span, unsafety: Unsafe::No, items, inline: true }), + kind: ItemKind::Mod(Unsafe::No, ModKind::Loaded(items, Inline::Yes, span)), tokens: None, }); let items = vis.flat_map_item(item); @@ -1021,7 +1023,9 @@ pub fn noop_visit_crate(krate: &mut Crate, vis: &mut T) { } else if len == 1 { let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner(); match kind { - ItemKind::Mod(module) => Crate { attrs, items: module.items, span, proc_macros }, + ItemKind::Mod(_, ModKind::Loaded(items, ..)) => { + Crate { attrs, items, span, proc_macros } + } _ => panic!("visitor converted a module to not a module"), } } else { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 3fa53bb391f..32b9dd46bae 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -290,7 +290,12 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref()); visitor.visit_fn(kind, item.span, item.id) } - ItemKind::Mod(ref module) => walk_list!(visitor, visit_item, &module.items), + ItemKind::Mod(_unsafety, ref mod_kind) => match mod_kind { + ModKind::Loaded(items, _inline, _inner_span) => { + walk_list!(visitor, visit_item, items) + } + ModKind::Unloaded => {} + }, ItemKind::ForeignMod(ref foreign_module) => { walk_list!(visitor, visit_foreign_item, &foreign_module.items); } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 5bdf0fd50ae..8b740b77740 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -314,7 +314,12 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ItemKind::Fn(sig, generics, body_id) }) } - ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(&m.items, m.inner)), + ItemKind::Mod(_, ref mod_kind) => match mod_kind { + ModKind::Loaded(items, _, inner_span) => { + hir::ItemKind::Mod(self.lower_mod(items, *inner_span)) + } + ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), + }, ItemKind::ForeignMod(ref fm) => { if fm.abi.is_none() { self.maybe_lint_missing_abi(span, id, abi::Abi::C); diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 8defd91c688..563bcda5190 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1054,12 +1054,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> { walk_list!(self, visit_attribute, &item.attrs); return; } - ItemKind::Mod(Mod { inline, unsafety, .. }) => { + ItemKind::Mod(unsafety, ref mod_kind) => { if let Unsafe::Yes(span) = unsafety { self.err_handler().span_err(span, "module cannot be declared unsafe"); } // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). - if !inline && !self.session.contains_name(&item.attrs, sym::path) { + if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) + && !self.session.contains_name(&item.attrs, sym::path) + { self.check_mod_file_item_asciionly(item.ident); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index bd9c209b659..2189e6eaa02 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -9,7 +9,7 @@ use rustc_ast::util::classify; use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; use rustc_ast::util::parser::{self, AssocOp, Fixity}; use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; -use rustc_ast::{GenericArg, MacArgs}; +use rustc_ast::{GenericArg, MacArgs, ModKind}; use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; @@ -87,7 +87,6 @@ pub struct State<'a> { pub s: pp::Printer, comments: Option>, ann: &'a (dyn PpAnn + 'a), - is_expanded: bool, } crate const INDENT_UNIT: usize = 4; @@ -103,12 +102,8 @@ pub fn print_crate<'a>( is_expanded: bool, edition: Edition, ) -> String { - let mut s = State { - s: pp::mk_printer(), - comments: Some(Comments::new(sm, filename, input)), - ann, - is_expanded, - }; + let mut s = + State { s: pp::mk_printer(), comments: Some(Comments::new(sm, filename, input)), ann }; if is_expanded && !krate.attrs.iter().any(|attr| attr.has_name(sym::no_core)) { // We need to print `#![no_std]` (and its feature gate) so that @@ -856,7 +851,7 @@ impl<'a> PrintState<'a> for State<'a> { impl<'a> State<'a> { pub fn new() -> State<'a> { - State { s: pp::mk_printer(), comments: None, ann: &NoAnn, is_expanded: false } + State { s: pp::mk_printer(), comments: None, ann: &NoAnn } } // Synthesizes a comment that was not textually present in the original source @@ -1134,26 +1129,29 @@ impl<'a> State<'a> { let body = body.as_deref(); self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs); } - ast::ItemKind::Mod(ref _mod) => { + ast::ItemKind::Mod(unsafety, ref mod_kind) => { self.head(self.to_string(|s| { s.print_visibility(&item.vis); - s.print_unsafety(_mod.unsafety); + s.print_unsafety(unsafety); s.word("mod"); })); self.print_ident(item.ident); - if _mod.inline || self.is_expanded { - self.nbsp(); - self.bopen(); - self.print_inner_attributes(&item.attrs); - for item in &_mod.items { - self.print_item(item); + match mod_kind { + ModKind::Loaded(items, ..) => { + self.nbsp(); + self.bopen(); + self.print_inner_attributes(&item.attrs); + for item in items { + self.print_item(item); + } + self.bclose(item.span); + } + ModKind::Unloaded => { + self.s.word(";"); + self.end(); // end inner head-block + self.end(); // end outer head-block } - self.bclose(item.span); - } else { - self.s.word(";"); - self.end(); // end inner head-block - self.end(); // end outer head-block } } ast::ItemKind::ForeignMod(ref nmod) => { diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 8c5431a47db..28e82597843 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -1,10 +1,10 @@ // Code that generates a test runner to run all the tests in a crate use rustc_ast as ast; -use rustc_ast::attr; use rustc_ast::entry::EntryPointType; use rustc_ast::mut_visit::{ExpectOne, *}; use rustc_ast::ptr::P; +use rustc_ast::{attr, ModKind}; use rustc_expand::base::{ExtCtxt, ResolverExpand}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; use rustc_feature::Features; @@ -106,10 +106,6 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { if let ast::ItemKind::Mod(..) = item.kind { let tests = mem::take(&mut self.tests); noop_visit_item_kind(&mut item.kind, self); - let module = match item.kind { - ast::ItemKind::Mod(module) => module, - _ => unreachable!(), - }; let mut tests = mem::replace(&mut self.tests, tests); if !tests.is_empty() { @@ -117,8 +113,12 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { if item.id == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { item.id }; // Create an identifier that will hygienically resolve the test // case name, even in another module. + let inner_span = match item.kind { + ast::ItemKind::Mod(_, ModKind::Loaded(.., span)) => span, + _ => unreachable!(), + }; let expn_id = self.cx.ext_cx.resolver.expansion_for_ast_pass( - module.inner, + inner_span, AstPass::TestHarness, &[], Some(parent), @@ -130,7 +130,6 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { } self.cx.test_cases.extend(tests); } - item.kind = ast::ItemKind::Mod(module); } smallvec![P(item)] } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index c570cc1ff35..5a4737842f0 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -12,8 +12,8 @@ use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor}; -use rustc_ast::{AttrItem, AttrStyle, Block, ItemKind, LitKind, MacArgs}; -use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, NestedMetaItem}; +use rustc_ast::{AttrItem, AttrStyle, Block, Inline, ItemKind, LitKind, MacArgs}; +use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, ModKind, NestedMetaItem}; use rustc_ast::{NodeId, PatKind, Path, StmtKind, Unsafe}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, is_builtin_attr, HasAttrs}; @@ -367,12 +367,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let krate_item = AstFragment::Items(smallvec![P(ast::Item { attrs: krate.attrs, span: krate.span, - kind: ast::ItemKind::Mod(ast::Mod { - inner: krate.span, - unsafety: Unsafe::No, - items: krate.items, - inline: true - }), + kind: ast::ItemKind::Mod( + Unsafe::No, + ModKind::Loaded(krate.items, Inline::Yes, krate.span) + ), ident: Ident::invalid(), id: ast::DUMMY_NODE_ID, vis: ast::Visibility { @@ -384,9 +382,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> { })]); match self.fully_expand_fragment(krate_item).make_items().pop().map(P::into_inner) { - Some(ast::Item { attrs, kind: ast::ItemKind::Mod(module), .. }) => { + Some(ast::Item { + attrs, + kind: ast::ItemKind::Mod(_, ModKind::Loaded(items, ..)), + .. + }) => { krate.attrs = attrs; - krate.items = module.items; + krate.items = items; } None => { // Resolution failed so we return an empty expansion @@ -809,7 +811,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> { fn visit_item(&mut self, item: &'ast ast::Item) { match &item.kind { - ast::ItemKind::Mod(module) if !module.inline => { + ast::ItemKind::Mod(_, mod_kind) + if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) => + { feature_err( self.parse_sess, sym::proc_macro_hygiene, @@ -1266,47 +1270,47 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { _ => unreachable!(), }) } - ast::ItemKind::Mod(ref mut old_mod @ ast::Mod { .. }) if ident != Ident::invalid() => { + ast::ItemKind::Mod(_, ref mut mod_kind) if ident != Ident::invalid() => { let sess = &self.cx.sess.parse_sess; let orig_ownership = self.cx.current_expansion.directory_ownership; let mut module = (*self.cx.current_expansion.module).clone(); let pushed = &mut false; // Record `parse_external_mod` pushing so we can pop. let dir = Directory { ownership: orig_ownership, path: module.directory }; - let Directory { ownership, path } = if old_mod.inline { - // Inline `mod foo { ... }`, but we still need to push directories. - item.attrs = attrs; - push_directory(&self.cx.sess, ident, &item.attrs, dir) - } else { - // We have an outline `mod foo;` so we need to parse the file. - let (ast::Mod { unsafety, inline, items, inner }, dir) = parse_external_mod( - &self.cx.sess, - ident, - span, - old_mod.unsafety, - dir, - &mut attrs, - pushed, - ); - - let krate = ast::Crate { attrs, items, span: inner, proc_macros: vec![] }; - if let Some(extern_mod_loaded) = self.cx.extern_mod_loaded { - extern_mod_loaded(&krate, ident); + let Directory { ownership, path } = match mod_kind { + ModKind::Loaded(_, Inline::Yes, _) => { + // Inline `mod foo { ... }`, but we still need to push directories. + item.attrs = attrs; + push_directory(&self.cx.sess, ident, &item.attrs, dir) } + ModKind::Loaded(_, Inline::No, _) => { + panic!("`mod` item is loaded from a file for the second time") + } + ModKind::Unloaded => { + // We have an outline `mod foo;` so we need to parse the file. + let (items, inner_span, dir) = + parse_external_mod(&self.cx.sess, ident, span, dir, &mut attrs, pushed); - *old_mod = ast::Mod { unsafety, inline, items: krate.items, inner }; - item.attrs = krate.attrs; - // File can have inline attributes, e.g., `#![cfg(...)]` & co. => Reconfigure. - item = match self.configure(item) { - Some(node) => node, - None => { - if *pushed { - sess.included_mod_stack.borrow_mut().pop(); - } - return Default::default(); + let krate = + ast::Crate { attrs, items, span: inner_span, proc_macros: vec![] }; + if let Some(extern_mod_loaded) = self.cx.extern_mod_loaded { + extern_mod_loaded(&krate, ident); } - }; - dir + + *mod_kind = ModKind::Loaded(krate.items, Inline::No, inner_span); + item.attrs = krate.attrs; + // File can have inline attributes, e.g., `#![cfg(...)]` & co. => Reconfigure. + item = match self.configure(item) { + Some(node) => node, + None => { + if *pushed { + sess.included_mod_stack.borrow_mut().pop(); + } + return Default::default(); + } + }; + dir + } }; // Set the module info before we flat map. diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index d63625fea46..076d3b02be9 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -1,4 +1,5 @@ -use rustc_ast::{token, Attribute, Mod, Unsafe}; +use rustc_ast::ptr::P; +use rustc_ast::{token, Attribute, Item}; use rustc_errors::{struct_span_err, PResult}; use rustc_parse::new_parser_from_file; use rustc_session::parse::ParseSess; @@ -42,11 +43,10 @@ crate fn parse_external_mod( sess: &Session, id: Ident, span: Span, // The span to blame on errors. - unsafety: Unsafe, Directory { mut ownership, path }: Directory, attrs: &mut Vec, pop_mod_stack: &mut bool, -) -> (Mod, Directory) { +) -> (Vec>, Span, Directory) { // We bail on the first error, but that error does not cause a fatal error... (1) let result: PResult<'_, _> = try { // Extract the file path and the new ownership. @@ -62,25 +62,22 @@ crate fn parse_external_mod( // Actually parse the external file as a module. let mut parser = new_parser_from_file(&sess.parse_sess, &mp.path, Some(span)); - let (inner_attrs, items, inner) = parser.parse_mod(&token::Eof)?; - (Mod { unsafety, inline: false, items, inner }, inner_attrs) + let (mut inner_attrs, items, inner_span) = parser.parse_mod(&token::Eof)?; + attrs.append(&mut inner_attrs); + (items, inner_span) }; // (1) ...instead, we return a dummy module. - let (module, mut new_attrs) = result.map_err(|mut err| err.emit()).unwrap_or_else(|_| { - let module = Mod { inner: Span::default(), unsafety, items: Vec::new(), inline: false }; - (module, Vec::new()) - }); - attrs.append(&mut new_attrs); + let (items, inner_span) = result.map_err(|mut err| err.emit()).unwrap_or_default(); - // Extract the directory path for submodules of `module`. - let path = sess.source_map().span_to_unmapped_path(module.inner); + // Extract the directory path for submodules of the module. + let path = sess.source_map().span_to_unmapped_path(inner_span); let mut path = match path { FileName::Real(name) => name.into_local_path(), other => PathBuf::from(other.to_string()), }; path.pop(); - (module, Directory { ownership, path }) + (items, inner_span, Directory { ownership, path }) } fn error_on_circular_module<'a>( diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index f4fcaf5c0a4..56f25ffdb01 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -309,8 +309,8 @@ fn out_of_line_mod() { .unwrap() .unwrap(); - if let ast::ItemKind::Mod(ref m) = item.kind { - assert!(m.items.len() == 2); + if let ast::ItemKind::Mod(_, ref mod_kind) = item.kind { + assert!(matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2)); } else { panic!(); } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index c0464c3edbc..0f907859a19 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -35,14 +35,16 @@ impl<'a> Parser<'a> { let unsafety = self.parse_unsafety(); self.expect_keyword(kw::Mod)?; let id = self.parse_ident()?; - let ((mut inner_attrs, items, inner), inline) = if self.eat(&token::Semi) { - ((Vec::new(), Vec::new(), Span::default()), false) + let mod_kind = if self.eat(&token::Semi) { + ModKind::Unloaded } else { self.expect(&token::OpenDelim(token::Brace))?; - (self.parse_mod(&token::CloseDelim(token::Brace))?, true) + let (mut inner_attrs, items, inner_span) = + self.parse_mod(&token::CloseDelim(token::Brace))?; + attrs.append(&mut inner_attrs); + ModKind::Loaded(items, Inline::Yes, inner_span) }; - attrs.append(&mut inner_attrs); - Ok((id, ItemKind::Mod(Mod { unsafety, inline, items, inner }))) + Ok((id, ItemKind::Mod(unsafety, mod_kind))) } /// Parses the contents of a module (inner attributes followed by module items). diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index cca40a793dd..09ab84eaeb6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1023,7 +1023,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }); } - ItemKind::Mod(_) | ItemKind::ForeignMod(_) => { + ItemKind::Mod(..) | ItemKind::ForeignMod(_) => { self.with_scope(item.id, |this| { visit::walk_item(this, item); }); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 81407004719..77fbbaa1532 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -29,7 +29,7 @@ use rustc_ast::unwrap_or; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, NodeId}; use rustc_ast::{Crate, CRATE_NODE_ID}; -use rustc_ast::{ItemKind, Path}; +use rustc_ast::{ItemKind, ModKind, Path}; use rustc_ast_lowering::ResolverAstLowering; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; @@ -339,8 +339,8 @@ impl UsePlacementFinder { impl<'tcx> Visitor<'tcx> for UsePlacementFinder { fn visit_item(&mut self, item: &'tcx ast::Item) { - if let ItemKind::Mod(module) = &item.kind { - if let ControlFlow::Break(..) = self.check_mod(&module.items, item.id) { + if let ItemKind::Mod(_, ModKind::Loaded(items, ..)) = &item.kind { + if let ControlFlow::Break(..) = self.check_mod(items, item.id) { return; } } diff --git a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs index 64232646972..9ff7ef7cc3b 100644 --- a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs +++ b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs @@ -241,9 +241,12 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r)) } - (Mod(l), Mod(r)) => { - l.inline == r.inline && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_item_kind)) - } + (Mod(lu, lmk), Mod(ru, rmk)) => lu == ru && match (lmk, rmk) { + (ModKind::Loaded(litems, linline, _), ModKind::Loaded(ritems, rinline, _)) => + linline == rinline && over(litems, ritems, |l, r| eq_item(l, r, eq_item_kind)), + (ModKind::Unloaded, ModKind::Unloaded) => true, + _ => false, + }, (ForeignMod(l), ForeignMod(r)) => { both(&l.abi, &r.abi, |l, r| eq_str_lit(l, r)) && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))