Skip to content

Commit 12dbfa8

Browse files
committed
Auto merge of #152299 - b-naber:namespaced-crate-names, r=<try>
Introduce changes for packages as namespaces
2 parents 59fd4ef + 1c05050 commit 12dbfa8

File tree

22 files changed

+490
-67
lines changed

22 files changed

+490
-67
lines changed

compiler/rustc_hir/src/def.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,13 @@ pub enum Res<Id = hir::HirId> {
600600
///
601601
/// **Not bound to a specific namespace.**
602602
Err,
603+
604+
/// The resolution for a virtual module in a namespaced crate. E.g. `my_api`
605+
/// in the namespaced crate `my_api::utils` when `my_api` isn't part of the
606+
/// extern prelude.
607+
///
608+
/// **Belongs to the type namespace.**
609+
VirtualMod(Symbol),
603610
}
604611

605612
impl<Id> IntoDiagArg for Res<Id> {
@@ -834,6 +841,7 @@ impl<Id> Res<Id> {
834841
| Res::SelfTyAlias { .. }
835842
| Res::SelfCtor(..)
836843
| Res::ToolMod
844+
| Res::VirtualMod(..)
837845
| Res::NonMacroAttr(..)
838846
| Res::Err => None,
839847
}
@@ -865,6 +873,7 @@ impl<Id> Res<Id> {
865873
Res::Local(..) => "local variable",
866874
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type",
867875
Res::ToolMod => "tool module",
876+
Res::VirtualMod(..) => "virtual module for namespaced crate",
868877
Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
869878
Res::Err => "unresolved item",
870879
}
@@ -891,6 +900,7 @@ impl<Id> Res<Id> {
891900
Res::SelfTyAlias { alias_to, is_trait_impl }
892901
}
893902
Res::ToolMod => Res::ToolMod,
903+
Res::VirtualMod(sym) => Res::VirtualMod(sym),
894904
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
895905
Res::Err => Res::Err,
896906
}
@@ -907,6 +917,7 @@ impl<Id> Res<Id> {
907917
Res::SelfTyAlias { alias_to, is_trait_impl }
908918
}
909919
Res::ToolMod => Res::ToolMod,
920+
Res::VirtualMod(sym) => Res::VirtualMod(sym),
910921
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
911922
Res::Err => Res::Err,
912923
})
@@ -932,9 +943,11 @@ impl<Id> Res<Id> {
932943
pub fn ns(&self) -> Option<Namespace> {
933944
match self {
934945
Res::Def(kind, ..) => kind.ns(),
935-
Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => {
936-
Some(Namespace::TypeNS)
937-
}
946+
Res::PrimTy(..)
947+
| Res::SelfTyParam { .. }
948+
| Res::SelfTyAlias { .. }
949+
| Res::ToolMod
950+
| Res::VirtualMod(..) => Some(Namespace::TypeNS),
938951
Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
939952
Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
940953
Res::Err => None,

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2764,6 +2764,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
27642764
| Res::SelfCtor(_)
27652765
| Res::Local(_)
27662766
| Res::ToolMod
2767+
| Res::VirtualMod(..)
27672768
| Res::NonMacroAttr(_)
27682769
| Res::Err) => Const::new_error_with_message(
27692770
tcx,

compiler/rustc_passes/src/dead.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
155155
Res::Def(_, def_id) => self.check_def_id(def_id),
156156
Res::SelfTyParam { trait_: t } => self.check_def_id(t),
157157
Res::SelfTyAlias { alias_to: i, .. } => self.check_def_id(i),
158-
Res::ToolMod | Res::NonMacroAttr(..) | Res::Err => {}
158+
Res::ToolMod | Res::NonMacroAttr(..) | Res::VirtualMod(..) | Res::Err => {}
159159
}
160160
}
161161

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
326326
_,
327327
)
328328
| Res::PrimTy(..)
329+
| Res::VirtualMod(..)
329330
| Res::ToolMod => define_extern(TypeNS),
330331
Res::Def(
331332
DefKind::Fn

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12041204
Scope::ModuleGlobs(..) => {
12051205
// Already handled in `ModuleNonGlobs`.
12061206
}
1207+
Scope::NamespacedCrates(..) => {}
12071208
Scope::MacroUsePrelude => {
12081209
suggestions.extend(this.macro_use_prelude.iter().filter_map(
12091210
|(name, binding)| {
@@ -1733,8 +1734,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
17331734
Res::Def(DefKind::Macro(kinds), _) => {
17341735
format!("{} {}", kinds.article(), kinds.descr())
17351736
}
1736-
Res::ToolMod => {
1737-
// Don't confuse the user with tool modules.
1737+
Res::ToolMod | Res::VirtualMod(..) => {
1738+
// Don't confuse the user with tool modules or virtual modules.
17381739
continue;
17391740
}
17401741
Res::Def(DefKind::Trait, _) if macro_kind == MacroKind::Derive => {

compiler/rustc_resolve/src/ident.rs

Lines changed: 111 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use crate::macros::{MacroRulesScope, sub_namespace_match};
2525
use crate::{
2626
AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind,
2727
Determinacy, Finalize, IdentKey, ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot,
28-
ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet,
29-
Segment, Stage, Used, errors,
28+
NamespacedCrateRoot, ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver,
29+
Scope, ScopeSet, Segment, Stage, Symbol, Used, errors,
3030
};
3131

3232
#[derive(Copy, Clone)]
@@ -109,26 +109,40 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
109109
let (ns, macro_kind) = match scope_set {
110110
ScopeSet::All(ns)
111111
| ScopeSet::Module(ns, _)
112-
| ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
112+
| ScopeSet::ModuleAndExternPrelude(ns, _)
113+
| ScopeSet::NamespacedCrate(ns, _) => (ns, None),
113114
ScopeSet::ExternPrelude => (TypeNS, None),
114115
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
115116
};
116117
let module = match scope_set {
117118
// Start with the specified module.
118-
ScopeSet::Module(_, module) | ScopeSet::ModuleAndExternPrelude(_, module) => module,
119+
ScopeSet::Module(_, module) | ScopeSet::ModuleAndExternPrelude(_, module) => {
120+
Some(module)
121+
}
122+
ScopeSet::NamespacedCrate(_, _) => None,
119123
// Jump out of trait or enum modules, they do not act as scopes.
120-
_ => parent_scope.module.nearest_item_scope(),
124+
_ => Some(parent_scope.module.nearest_item_scope()),
121125
};
122126
let module_only = matches!(scope_set, ScopeSet::Module(..));
123127
let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
124128
let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude);
129+
let namespace_crate_only = matches!(scope_set, ScopeSet::NamespacedCrate(..));
125130
let mut scope = match ns {
126-
_ if module_only || module_and_extern_prelude => Scope::ModuleNonGlobs(module, None),
131+
_ if module_only || module_and_extern_prelude => {
132+
Scope::ModuleNonGlobs(module.unwrap(), None)
133+
}
134+
_ if namespace_crate_only => {
135+
let ScopeSet::NamespacedCrate(_, root_name) = scope_set else {
136+
unreachable!();
137+
};
138+
139+
Scope::NamespacedCrates(NamespacedCrateRoot::VirtualMod(root_name), None)
140+
}
127141
_ if extern_prelude => Scope::ExternPreludeItems,
128-
TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None),
142+
TypeNS | ValueNS => Scope::ModuleNonGlobs(module.unwrap(), None),
129143
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
130144
};
131-
let mut use_prelude = !module.no_implicit_prelude;
145+
let mut use_prelude = module.map(|m| !m.no_implicit_prelude).unwrap_or_else(|| true);
132146

133147
loop {
134148
let visit = match scope {
@@ -151,7 +165,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
151165
}
152166
true
153167
}
154-
Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..) => true,
168+
Scope::ModuleNonGlobs(..)
169+
| Scope::ModuleGlobs(..)
170+
| Scope::NamespacedCrates(..) => true,
155171
Scope::MacroUsePrelude => use_prelude || orig_ident_span.is_rust_2015(),
156172
Scope::BuiltinAttrs => true,
157173
Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {
@@ -192,18 +208,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
192208
MacroRulesScope::Invocation(invoc_id) => {
193209
Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
194210
}
195-
MacroRulesScope::Empty => Scope::ModuleNonGlobs(module, None),
211+
MacroRulesScope::Empty => Scope::ModuleNonGlobs(module.unwrap(), None),
196212
},
197213
Scope::ModuleNonGlobs(module, lint_id) => Scope::ModuleGlobs(module, lint_id),
198-
Scope::ModuleGlobs(..) if module_only => break,
199-
Scope::ModuleGlobs(..) if module_and_extern_prelude => match ns {
214+
Scope::ModuleGlobs(module, lint_id) if module_only => {
215+
Scope::NamespacedCrates(NamespacedCrateRoot::Mod(module), lint_id)
216+
}
217+
Scope::NamespacedCrates(..) if module_only | namespace_crate_only => break,
218+
Scope::ModuleGlobs(module, lint_id) if module_and_extern_prelude => {
219+
Scope::NamespacedCrates(NamespacedCrateRoot::Mod(module), lint_id)
220+
}
221+
Scope::NamespacedCrates(..) if module_and_extern_prelude => match ns {
200222
TypeNS => {
201223
ctxt.update_unchecked(|ctxt| ctxt.adjust(ExpnId::root()));
202224
Scope::ExternPreludeItems
203225
}
204226
ValueNS | MacroNS => break,
205227
},
206228
Scope::ModuleGlobs(module, prev_lint_id) => {
229+
Scope::NamespacedCrates(NamespacedCrateRoot::Mod(module), prev_lint_id)
230+
}
231+
Scope::NamespacedCrates(namespace_crate_root, prev_lint_id) => {
232+
let module = namespace_crate_root.get_mod();
207233
use_prelude = !module.no_implicit_prelude;
208234
match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {
209235
Some((parent_module, lint_id)) => {
@@ -386,7 +412,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
386412
}
387413

388414
/// Resolve an identifier in the specified set of scopes.
389-
#[instrument(level = "debug", skip(self))]
390415
pub(crate) fn resolve_ident_in_scope_set<'r>(
391416
self: CmResolver<'r, 'ra, 'tcx>,
392417
orig_ident: Ident,
@@ -425,7 +450,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
425450
let (ns, macro_kind) = match scope_set {
426451
ScopeSet::All(ns)
427452
| ScopeSet::Module(ns, _)
428-
| ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
453+
| ScopeSet::ModuleAndExternPrelude(ns, _)
454+
| ScopeSet::NamespacedCrate(ns, _) => (ns, None),
429455
ScopeSet::ExternPrelude => (TypeNS, None),
430456
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
431457
};
@@ -686,6 +712,65 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
686712
Err(ControlFlow::Break(..)) => return binding,
687713
}
688714
}
715+
Scope::NamespacedCrates(ns_root, _) => {
716+
let try_find_namespaced_crate = |root_name: &Symbol| {
717+
self.namespaced_crate_names
718+
.get(root_name.as_str())
719+
.into_iter()
720+
.flatten()
721+
.find(|s| s.split("::").nth(1) == Some(ident.name.as_str()))
722+
};
723+
724+
match ns_root {
725+
NamespacedCrateRoot::Mod(module) => {
726+
if let Some(def_id) = module.opt_def_id() {
727+
if let Some(ns_base_name) =
728+
self.def_id_to_namespaced_crate_names.borrow().get(&def_id)
729+
{
730+
let ns_crate_cand = try_find_namespaced_crate(ns_base_name);
731+
match ns_crate_cand {
732+
Some(ns_cand) => {
733+
let ns_ident =
734+
IdentKey::with_root_ctxt(Symbol::intern(ns_cand));
735+
736+
match self.extern_prelude_get_flag(
737+
ns_ident,
738+
module.span,
739+
finalize.is_some(),
740+
) {
741+
Some(decl) => Ok(decl),
742+
None => Err(Determinacy::Determined),
743+
}
744+
}
745+
None => Err(Determinacy::Determined),
746+
}
747+
} else {
748+
Err(Determinacy::Determined)
749+
}
750+
} else {
751+
Err(Determinacy::Determined)
752+
}
753+
}
754+
NamespacedCrateRoot::VirtualMod(sym) => {
755+
let ns_crate_cand = try_find_namespaced_crate(&sym);
756+
match ns_crate_cand {
757+
Some(ns_cand) => {
758+
let ns_ident = IdentKey::with_root_ctxt(Symbol::intern(ns_cand));
759+
760+
match self.extern_prelude_get_flag(
761+
ns_ident,
762+
orig_ident_span,
763+
finalize.is_some(),
764+
) {
765+
Some(decl) => Ok(decl),
766+
None => Err(Determinacy::Determined),
767+
}
768+
}
769+
None => Err(Determinacy::Determined),
770+
}
771+
}
772+
}
773+
}
689774
Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() {
690775
Some(decl) => Ok(decl),
691776
None => Err(Determinacy::determined(
@@ -951,6 +1036,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
9511036
ignore_import,
9521037
)
9531038
}
1039+
ModuleOrUniformRoot::VirtualNamespacedCrate(sym) => self.resolve_ident_in_scope_set(
1040+
ident,
1041+
ScopeSet::NamespacedCrate(ns, sym),
1042+
parent_scope,
1043+
finalize,
1044+
ignore_decl,
1045+
ignore_import,
1046+
),
9541047
ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set(
9551048
ident,
9561049
ScopeSet::ModuleAndExternPrelude(ns, module),
@@ -1919,7 +2012,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19192012
}
19202013

19212014
let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1922-
if let Some(def_id) = binding.res().module_like_def_id() {
2015+
if let Res::VirtualMod(sym) = binding.res() {
2016+
module = Some(ModuleOrUniformRoot::VirtualNamespacedCrate(sym));
2017+
record_segment_res(self.reborrow(), finalize, res, id);
2018+
} else if let Some(def_id) = binding.res().module_like_def_id() {
19232019
if self.mods_with_parse_errors.contains(&def_id) {
19242020
module_had_parse_errors = true;
19252021
}

compiler/rustc_resolve/src/imports.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type Res = def::Res<NodeId>;
4141

4242
/// A potential import declaration in the process of being planted into a module.
4343
/// Also used for lazily planting names from `--extern` flags to extern prelude.
44-
#[derive(Clone, Copy, Default, PartialEq)]
44+
#[derive(Clone, Copy, Default, PartialEq, Debug)]
4545
pub(crate) enum PendingDecl<'ra> {
4646
Ready(Option<Decl<'ra>>),
4747
#[default]

0 commit comments

Comments
 (0)