Rollup merge of #145590 - nnethercote:ModKind-Inline, r=petrochenkov
Prevent impossible combinations in `ast::ModKind`. `ModKind::Loaded` has an `inline` field and a `had_parse_error` field. If the `inline` field is `Inline::Yes` then `had_parse_error` must be `Ok(())`. This commit moves the `had_parse_error` field into the `Inline::No` variant. This makes it impossible to create the nonsensical combination of `inline == Inline::Yes` and `had_parse_error = Err(_)`. r? ```@Urgau```
This commit is contained in:
commit
25b81bf5ad
17 changed files with 28 additions and 25 deletions
|
|
@ -3137,7 +3137,7 @@ impl FnRetTy {
|
|||
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
|
||||
pub enum Inline {
|
||||
Yes,
|
||||
No,
|
||||
No { had_parse_error: Result<(), ErrorGuaranteed> },
|
||||
}
|
||||
|
||||
/// Module item kind.
|
||||
|
|
@ -3147,7 +3147,7 @@ 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(ThinVec<Box<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
|
||||
Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
|
||||
/// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
|
||||
Unloaded,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
ItemKind::Mod(_, ident, mod_kind) => {
|
||||
let ident = self.lower_ident(*ident);
|
||||
match mod_kind {
|
||||
ModKind::Loaded(items, _, spans, _) => {
|
||||
ModKind::Loaded(items, _, spans) => {
|
||||
hir::ItemKind::Mod(ident, self.lower_mod(items, spans))
|
||||
}
|
||||
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
|
||||
|
|
|
|||
|
|
@ -1169,7 +1169,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });
|
||||
}
|
||||
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
|
||||
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _))
|
||||
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _))
|
||||
&& !attr::contains_name(&item.attrs, sym::path)
|
||||
{
|
||||
self.check_mod_file_item_asciionly(*ident);
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
|||
if let ast::ItemKind::Mod(
|
||||
_,
|
||||
_,
|
||||
ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }, _),
|
||||
ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }),
|
||||
) = item.kind
|
||||
{
|
||||
let prev_tests = mem::take(&mut self.tests);
|
||||
|
|
|
|||
|
|
@ -801,7 +801,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
ItemKind::Mod(
|
||||
_,
|
||||
_,
|
||||
ModKind::Unloaded | ModKind::Loaded(_, Inline::No, _, _),
|
||||
ModKind::Unloaded
|
||||
| ModKind::Loaded(_, Inline::No { .. }, _),
|
||||
)
|
||||
) =>
|
||||
{
|
||||
|
|
@ -1035,7 +1036,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
fn visit_item(&mut self, item: &'ast ast::Item) {
|
||||
match &item.kind {
|
||||
ItemKind::Mod(_, _, mod_kind)
|
||||
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _)) =>
|
||||
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) =>
|
||||
{
|
||||
feature_err(
|
||||
self.sess,
|
||||
|
|
@ -1346,7 +1347,7 @@ impl InvocationCollectorNode for Box<ast::Item> {
|
|||
let ItemKind::Mod(_, ident, ref mut mod_kind) = node.kind else { unreachable!() };
|
||||
let ecx = &mut collector.cx;
|
||||
let (file_path, dir_path, dir_ownership) = match mod_kind {
|
||||
ModKind::Loaded(_, inline, _, _) => {
|
||||
ModKind::Loaded(_, inline, _) => {
|
||||
// Inline `mod foo { ... }`, but we still need to push directories.
|
||||
let (dir_path, dir_ownership) = mod_dir_path(
|
||||
ecx.sess,
|
||||
|
|
@ -1360,7 +1361,7 @@ impl InvocationCollectorNode for Box<ast::Item> {
|
|||
// This lets `parse_external_mod` catch cycles if it's self-referential.
|
||||
let file_path = match inline {
|
||||
Inline::Yes => None,
|
||||
Inline::No => mod_file_path_from_attr(ecx.sess, &attrs, &dir_path),
|
||||
Inline::No { .. } => mod_file_path_from_attr(ecx.sess, &attrs, &dir_path),
|
||||
};
|
||||
node.attrs = attrs;
|
||||
(file_path, dir_path, dir_ownership)
|
||||
|
|
@ -1396,7 +1397,7 @@ impl InvocationCollectorNode for Box<ast::Item> {
|
|||
);
|
||||
}
|
||||
|
||||
*mod_kind = ModKind::Loaded(items, Inline::No, spans, had_parse_error);
|
||||
*mod_kind = ModKind::Loaded(items, Inline::No { had_parse_error }, spans);
|
||||
node.attrs = attrs;
|
||||
if node.attrs.len() > old_attrs_len {
|
||||
// If we loaded an out-of-line module and added some inner attributes,
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ pub(crate) fn mod_dir_path(
|
|||
|
||||
(dir_path, dir_ownership)
|
||||
}
|
||||
Inline::No => {
|
||||
Inline::No { .. } => {
|
||||
// FIXME: This is a subset of `parse_external_mod` without actual parsing,
|
||||
// check whether the logic for unloaded, loaded and inline modules can be unified.
|
||||
let file_path = mod_file_path(sess, ident, attrs, &module.dir_path, dir_ownership)
|
||||
|
|
|
|||
|
|
@ -3097,7 +3097,7 @@ impl EarlyLintPass for SpecialModuleName {
|
|||
if let ast::ItemKind::Mod(
|
||||
_,
|
||||
ident,
|
||||
ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _, _),
|
||||
ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No { .. }, _),
|
||||
) = item.kind
|
||||
{
|
||||
if item.attrs.iter().any(|a| a.has_name(sym::path)) {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ impl<'a> Parser<'a> {
|
|||
self.expect(exp!(OpenBrace))?;
|
||||
let (inner_attrs, items, inner_span) = self.parse_mod(exp!(CloseBrace))?;
|
||||
attrs.extend(inner_attrs);
|
||||
ModKind::Loaded(items, Inline::Yes, inner_span, Ok(()))
|
||||
ModKind::Loaded(items, Inline::Yes, inner_span)
|
||||
};
|
||||
Ok(ItemKind::Mod(safety, ident, mod_kind))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use std::sync::Arc;
|
|||
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
|
||||
use rustc_ast::{
|
||||
self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
|
||||
ForeignItemKind, Item, ItemKind, NodeId, StaticItem, StmtKind, TyAlias,
|
||||
ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TyAlias,
|
||||
};
|
||||
use rustc_attr_parsing as attr;
|
||||
use rustc_attr_parsing::AttributeParser;
|
||||
|
|
@ -813,7 +813,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
ItemKind::Mod(_, ident, ref mod_kind) => {
|
||||
self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion);
|
||||
|
||||
if let ast::ModKind::Loaded(_, _, _, Err(_)) = mod_kind {
|
||||
if let ast::ModKind::Loaded(_, Inline::No { had_parse_error: Err(_) }, _) = mod_kind
|
||||
{
|
||||
self.r.mods_with_parse_errors.insert(def_id);
|
||||
}
|
||||
self.parent_scope.module = self.r.new_local_module(
|
||||
|
|
|
|||
|
|
@ -3410,7 +3410,7 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
|
|||
|
||||
fn visit_item(&mut self, item: &'tcx ast::Item) {
|
||||
if self.target_module == item.id {
|
||||
if let ItemKind::Mod(_, _, ModKind::Loaded(items, _inline, mod_spans, _)) = &item.kind {
|
||||
if let ItemKind::Mod(_, _, ModKind::Loaded(items, _inline, mod_spans)) = &item.kind {
|
||||
let inject = mod_spans.inject_use_span;
|
||||
if is_span_suitable_for_use_injection(inject) {
|
||||
self.first_legal_span = Some(inject);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]);
|
|||
|
||||
impl EarlyLintPass for DuplicateMod {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||
if let ItemKind::Mod(_, _, ModKind::Loaded(_, Inline::No, mod_spans, _)) = &item.kind
|
||||
if let ItemKind::Mod(_, _, ModKind::Loaded(_, Inline::No { .. }, mod_spans)) = &item.kind
|
||||
&& let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span)
|
||||
&& let Some(local_path) = real.into_local_path()
|
||||
&& let Ok(absolute_path) = local_path.canonicalize()
|
||||
|
|
|
|||
|
|
@ -442,7 +442,7 @@ impl EmptyLineAfter {
|
|||
None => span.shrink_to_lo(),
|
||||
},
|
||||
mod_items: match kind {
|
||||
ItemKind::Mod(_, _, ModKind::Loaded(items, _, _, _)) => items
|
||||
ItemKind::Mod(_, _, ModKind::Loaded(items, _, _)) => items
|
||||
.iter()
|
||||
.filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
|
||||
.map(|i| i.id)
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ impl Visitor<'_> for NestingVisitor<'_, '_> {
|
|||
}
|
||||
|
||||
match &item.kind {
|
||||
ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _, _)) => {
|
||||
ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _)) => {
|
||||
self.nest_level += 1;
|
||||
|
||||
if !self.check_indent(item.span, item.id) {
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
|||
ls == rs
|
||||
&& eq_id(*li, *ri)
|
||||
&& match (lmk, rmk) {
|
||||
(ModKind::Loaded(litems, linline, _, _), ModKind::Loaded(ritems, rinline, _, _)) => {
|
||||
(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,
|
||||
|
|
|
|||
|
|
@ -3600,7 +3600,7 @@ pub(crate) fn rewrite_extern_crate(
|
|||
pub(crate) fn is_mod_decl(item: &ast::Item) -> bool {
|
||||
!matches!(
|
||||
item.kind,
|
||||
ast::ItemKind::Mod(_, _, ast::ModKind::Loaded(_, ast::Inline::Yes, _, _))
|
||||
ast::ItemKind::Mod(_, _, ast::ModKind::Loaded(_, ast::Inline::Yes, _))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -316,11 +316,12 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
|
|||
self.directory = directory;
|
||||
}
|
||||
match (sub_mod.ast_mod_kind, sub_mod.items) {
|
||||
(Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _, _))), _) => {
|
||||
(Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => {
|
||||
self.visit_mod_from_ast(items)
|
||||
}
|
||||
(Some(Cow::Owned(ast::ModKind::Loaded(items, _, _, _))), _)
|
||||
| (_, Cow::Owned(items)) => self.visit_mod_outside_ast(items),
|
||||
(Some(Cow::Owned(ast::ModKind::Loaded(items, _, _))), _) | (_, Cow::Owned(items)) => {
|
||||
self.visit_mod_outside_ast(items)
|
||||
}
|
||||
(_, _) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -942,7 +942,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, ref spans, _) = mod_kind {
|
||||
if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans) = mod_kind {
|
||||
let ast::ModSpans {
|
||||
inner_span,
|
||||
inject_use_span: _,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue