1
Fork 0

Use Option<Symbol> in ModuleKind::Def.

This way, `None` represents "crate root without a name" instead of
`kw::Empty`. This changes makes it impossible to forget to handle the
exceptional case.
This commit is contained in:
Nicholas Nethercote 2025-03-25 09:09:01 +11:00
parent 2469ab195a
commit 3f32a321bc
4 changed files with 20 additions and 18 deletions

View file

@ -131,7 +131,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let expn_id = self.cstore().expn_that_defined_untracked(def_id, self.tcx.sess); let expn_id = self.cstore().expn_that_defined_untracked(def_id, self.tcx.sess);
return Some(self.new_module( return Some(self.new_module(
parent, parent,
ModuleKind::Def(def_kind, def_id, self.tcx.item_name(def_id)), ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))),
expn_id, expn_id,
self.def_span(def_id), self.def_span(def_id),
// FIXME: Account for `#[no_implicit_prelude]` attributes. // FIXME: Account for `#[no_implicit_prelude]` attributes.
@ -594,7 +594,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
// HACK(eddyb) unclear how good this is, but keeping `$crate` // HACK(eddyb) unclear how good this is, but keeping `$crate`
// in `source` breaks `tests/ui/imports/import-crate-var.rs`, // in `source` breaks `tests/ui/imports/import-crate-var.rs`,
// while the current crate doesn't have a valid `crate_name`. // while the current crate doesn't have a valid `crate_name`.
if crate_name != kw::Empty { if let Some(crate_name) = crate_name {
// `crate_name` should not be interpreted as relative. // `crate_name` should not be interpreted as relative.
module_path.push(Segment::from_ident_and_id( module_path.push(Segment::from_ident_and_id(
Ident { name: kw::PathRoot, span: source.ident.span }, Ident { name: kw::PathRoot, span: source.ident.span },
@ -603,7 +603,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
source.ident.name = crate_name; source.ident.name = crate_name;
} }
if rename.is_none() { if rename.is_none() {
ident.name = crate_name; ident.name = sym::dummy;
} }
self.r.dcx().emit_err(errors::CrateImported { span: item.span }); self.r.dcx().emit_err(errors::CrateImported { span: item.span });
@ -775,7 +775,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
ItemKind::Mod(.., ref mod_kind) => { ItemKind::Mod(.., ref mod_kind) => {
let module = self.r.new_module( let module = self.r.new_module(
Some(parent), Some(parent),
ModuleKind::Def(def_kind, def_id, ident.name), ModuleKind::Def(def_kind, def_id, Some(ident.name)),
expansion.to_expn_id(), expansion.to_expn_id(),
item.span, item.span,
parent.no_implicit_prelude parent.no_implicit_prelude
@ -811,7 +811,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
ItemKind::Enum(_, _) | ItemKind::Trait(..) => { ItemKind::Enum(_, _) | ItemKind::Trait(..) => {
let module = self.r.new_module( let module = self.r.new_module(
Some(parent), Some(parent),
ModuleKind::Def(def_kind, def_id, ident.name), ModuleKind::Def(def_kind, def_id, Some(ident.name)),
expansion.to_expn_id(), expansion.to_expn_id(),
item.span, item.span,
parent.no_implicit_prelude, parent.no_implicit_prelude,

View file

@ -2439,7 +2439,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() else { let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() else {
return None; return None;
}; };
let module_name = crate_module.kind.name().unwrap(); let module_name = crate_module.kind.name().unwrap_or(kw::Empty);
let import_snippet = match import.kind { let import_snippet = match import.kind {
ImportKind::Single { source, target, .. } if source != target => { ImportKind::Single { source, target, .. } if source != target => {
format!("{source} as {target}") format!("{source} as {target}")

View file

@ -503,18 +503,18 @@ enum ModuleKind {
/// ///
/// * A normal module either `mod from_file;` or `mod from_block { }` /// * A normal module either `mod from_file;` or `mod from_block { }`
/// or the crate root (which is conceptually a top-level module). /// or the crate root (which is conceptually a top-level module).
/// Note that the crate root's [name][Self::name] will be [`kw::Empty`]. /// The crate root will have `None` for the symbol.
/// * A trait or an enum (it implicitly contains associated types, methods and variant /// * A trait or an enum (it implicitly contains associated types, methods and variant
/// constructors). /// constructors).
Def(DefKind, DefId, Symbol), Def(DefKind, DefId, Option<Symbol>),
} }
impl ModuleKind { impl ModuleKind {
/// Get name of the module. /// Get name of the module.
fn name(&self) -> Option<Symbol> { fn name(&self) -> Option<Symbol> {
match self { match *self {
ModuleKind::Block => None, ModuleKind::Block => None,
ModuleKind::Def(.., name) => Some(*name), ModuleKind::Def(.., name) => name,
} }
} }
} }
@ -1402,7 +1402,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let mut module_self_bindings = FxHashMap::default(); let mut module_self_bindings = FxHashMap::default();
let graph_root = arenas.new_module( let graph_root = arenas.new_module(
None, None,
ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty), ModuleKind::Def(DefKind::Mod, root_def_id, None),
ExpnId::root(), ExpnId::root(),
crate_span, crate_span,
attr::contains_name(attrs, sym::no_implicit_prelude), attr::contains_name(attrs, sym::no_implicit_prelude),
@ -1411,7 +1411,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
); );
let empty_module = arenas.new_module( let empty_module = arenas.new_module(
None, None,
ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty), ModuleKind::Def(DefKind::Mod, root_def_id, None),
ExpnId::root(), ExpnId::root(),
DUMMY_SP, DUMMY_SP,
true, true,
@ -2286,7 +2286,8 @@ fn module_to_string(mut module: Module<'_>) -> Option<String> {
loop { loop {
if let ModuleKind::Def(.., name) = module.kind { if let ModuleKind::Def(.., name) = module.kind {
if let Some(parent) = module.parent { if let Some(parent) = module.parent {
names.push(name); // `unwrap` is safe: the presence of a parent means it's not the crate root.
names.push(name.unwrap());
module = parent module = parent
} else { } else {
break; break;

View file

@ -168,7 +168,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
hygiene::update_dollar_crate_names(|ctxt| { hygiene::update_dollar_crate_names(|ctxt| {
let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt)); let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt));
match self.resolve_crate_root(ident).kind { match self.resolve_crate_root(ident).kind {
ModuleKind::Def(.., name) if name != kw::Empty => name, ModuleKind::Def(.., name) if let Some(name) = name => name,
_ => kw::Crate, _ => kw::Crate,
} }
}); });
@ -1068,11 +1068,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
); );
if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) { if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) {
let location = match parent_scope.module.kind { let location = match parent_scope.module.kind {
ModuleKind::Def(_, _, name) if name == kw::Empty => {
"the crate root".to_string()
}
ModuleKind::Def(kind, def_id, name) => { ModuleKind::Def(kind, def_id, name) => {
format!("{} `{name}`", kind.descr(def_id)) if let Some(name) = name {
format!("{} `{name}`", kind.descr(def_id))
} else {
"the crate root".to_string()
}
} }
ModuleKind::Block => "this scope".to_string(), ModuleKind::Block => "this scope".to_string(),
}; };