Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ Guillaume Gomez <guillaume1.gomez@gmail.com>
Guillaume Gomez <guillaume1.gomez@gmail.com> ggomez <ggomez@ggo.ifr.lan>
Guillaume Gomez <guillaume1.gomez@gmail.com> Guillaume Gomez <ggomez@ggo.ifr.lan>
Guillaume Gomez <guillaume1.gomez@gmail.com> Guillaume Gomez <guillaume.gomez@huawei.com>
Guillaume Gomez <guillaume1.gomez@gmail.com> Guillaume Gomez <contact@guillaume-gomez.fr>
gnzlbg <gonzalobg88@gmail.com> <gnzlbg@users.noreply.github.com>
hamidreza kalbasi <hamidrezakalbasi@protonmail.com>
Hanna Kruppe <hanna.kruppe@gmail.com> <robin.kruppe@gmail.com>
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ declare_features! (
/// Allows giving non-const impls custom diagnostic messages if attempted to be used as const
(unstable, diagnostic_on_const, "1.93.0", Some(143874)),
/// Allows giving on-move borrowck custom diagnostic messages for a type
(unstable, diagnostic_on_move, "CURRENT_RUSTC_VERSION", Some(150935)),
(unstable, diagnostic_on_move, "CURRENT_RUSTC_VERSION", Some(154181)),
/// Allows `#[doc(cfg(...))]`.
(unstable, doc_cfg, "1.21.0", Some(43781)),
/// Allows `#[doc(masked)]`.
Expand Down
19 changes: 16 additions & 3 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,13 @@ pub enum Res<Id = hir::HirId> {
/// **Belongs to the type namespace.**
ToolMod,

/// The resolution for an open module in a namespaced crate. E.g. `my_api`
/// in the namespaced crate `my_api::utils` when `my_api` isn't part of the
/// extern prelude.
///
/// **Belongs to the type namespace.**
OpenMod(Symbol),

// Macro namespace
/// An attribute that is *not* implemented via macro.
/// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
Expand Down Expand Up @@ -838,6 +845,7 @@ impl<Id> Res<Id> {
| Res::SelfTyAlias { .. }
| Res::SelfCtor(..)
| Res::ToolMod
| Res::OpenMod(..)
| Res::NonMacroAttr(..)
| Res::Err => None,
}
Expand Down Expand Up @@ -869,6 +877,7 @@ impl<Id> Res<Id> {
Res::Local(..) => "local variable",
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type",
Res::ToolMod => "tool module",
Res::OpenMod(..) => "namespaced crate",
Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
Res::Err => "unresolved item",
}
Expand All @@ -895,6 +904,7 @@ impl<Id> Res<Id> {
Res::SelfTyAlias { alias_to, is_trait_impl }
}
Res::ToolMod => Res::ToolMod,
Res::OpenMod(sym) => Res::OpenMod(sym),
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
}
Expand All @@ -911,6 +921,7 @@ impl<Id> Res<Id> {
Res::SelfTyAlias { alias_to, is_trait_impl }
}
Res::ToolMod => Res::ToolMod,
Res::OpenMod(sym) => Res::OpenMod(sym),
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
})
Expand All @@ -936,9 +947,11 @@ impl<Id> Res<Id> {
pub fn ns(&self) -> Option<Namespace> {
match self {
Res::Def(kind, ..) => kind.ns(),
Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => {
Some(Namespace::TypeNS)
}
Res::PrimTy(..)
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
| Res::ToolMod
| Res::OpenMod(..) => Some(Namespace::TypeNS),
Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
Res::Err => None,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2830,6 +2830,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
| Res::SelfCtor(_)
| Res::Local(_)
| Res::ToolMod
| Res::OpenMod(..)
| Res::NonMacroAttr(_)
| Res::Err) => Const::new_error_with_message(
tcx,
Expand Down
63 changes: 40 additions & 23 deletions compiler/rustc_middle/src/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,10 @@ impl DepGraph {
);
assert_eq!(red_node_index, DepNodeIndex::FOREVER_RED_NODE);
if prev_graph_node_count > 0 {
colors.insert_red(SerializedDepNodeIndex::from_u32(
DepNodeIndex::FOREVER_RED_NODE.as_u32(),
));
let prev_index =
const { SerializedDepNodeIndex::from_u32(DepNodeIndex::FOREVER_RED_NODE.as_u32()) };
let result = colors.try_set_color(prev_index, DesiredColor::Red);
assert_matches!(result, TrySetColorResult::Success);
}

DepGraph {
Expand Down Expand Up @@ -1415,28 +1416,29 @@ impl DepNodeColorMap {
if value <= DepNodeIndex::MAX_AS_U32 { Some(DepNodeIndex::from_u32(value)) } else { None }
}

/// This tries to atomically mark a node green and assign `index` as the new
/// index if `green` is true, otherwise it will try to atomicaly mark it red.
/// Atomically sets the color of a previous-session dep node to either green
/// or red, if it has not already been colored.
///
/// This returns `Ok` if `index` gets assigned or the node is marked red, otherwise it returns
/// the already allocated index in `Err` if it is green already. If it was already
/// red, `Err(None)` is returned.
/// If the node already has a color, the new color is ignored, and the
/// return value indicates the existing color.
#[inline(always)]
pub(super) fn try_mark(
pub(super) fn try_set_color(
&self,
prev_index: SerializedDepNodeIndex,
index: DepNodeIndex,
green: bool,
) -> Result<(), Option<DepNodeIndex>> {
let value = &self.values[prev_index];
match value.compare_exchange(
color: DesiredColor,
) -> TrySetColorResult {
match self.values[prev_index].compare_exchange(
COMPRESSED_UNKNOWN,
if green { index.as_u32() } else { COMPRESSED_RED },
match color {
DesiredColor::Red => COMPRESSED_RED,
DesiredColor::Green { index } => index.as_u32(),
},
Ordering::Relaxed,
Ordering::Relaxed,
) {
Ok(_) => Ok(()),
Err(v) => Err(if v == COMPRESSED_RED { None } else { Some(DepNodeIndex::from_u32(v)) }),
Ok(_) => TrySetColorResult::Success,
Err(COMPRESSED_RED) => TrySetColorResult::AlreadyRed,
Err(index) => TrySetColorResult::AlreadyGreen { index: DepNodeIndex::from_u32(index) },
}
}

Expand All @@ -1454,13 +1456,28 @@ impl DepNodeColorMap {
DepNodeColor::Unknown
}
}
}

#[inline]
pub(super) fn insert_red(&self, index: SerializedDepNodeIndex) {
let value = self.values[index].swap(COMPRESSED_RED, Ordering::Release);
// Sanity check for duplicate nodes
assert_eq!(value, COMPRESSED_UNKNOWN, "tried to color an already colored node as red");
}
/// The color that [`DepNodeColorMap::try_set_color`] should try to apply to a node.
#[derive(Clone, Copy, Debug)]
pub(super) enum DesiredColor {
/// Try to mark the node red.
Red,
/// Try to mark the node green, associating it with a current-session node index.
Green { index: DepNodeIndex },
}

/// Return value of [`DepNodeColorMap::try_set_color`], indicating success or failure,
/// and (on failure) what the existing color is.
#[derive(Clone, Copy, Debug)]
pub(super) enum TrySetColorResult {
/// The [`DesiredColor`] was freshly applied to the node.
Success,
/// Coloring failed because the node was already marked red.
AlreadyRed,
/// Coloring failed because the node was already marked green,
/// and corresponds to node `index` in the current-session dep graph.
AlreadyGreen { index: DepNodeIndex },
}

#[inline(never)]
Expand Down
25 changes: 14 additions & 11 deletions compiler/rustc_middle/src/dep_graph/serialized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_session::Session;
use tracing::{debug, instrument};

use super::graph::{CurrentDepGraph, DepNodeColorMap};
use super::graph::{CurrentDepGraph, DepNodeColorMap, DesiredColor, TrySetColorResult};
use super::retained::RetainedDepGraph;
use super::{DepKind, DepNode, DepNodeIndex};
use crate::dep_graph::edges::EdgesVec;
Expand Down Expand Up @@ -905,13 +905,14 @@ impl GraphEncoder {
let mut local = self.status.local.borrow_mut();

let index = self.status.next_index(&mut *local);
let color = if is_green { DesiredColor::Green { index } } else { DesiredColor::Red };

// Use `try_mark` to avoid racing when `send_promoted` is called concurrently
// Use `try_set_color` to avoid racing when `send_promoted` is called concurrently
// on the same index.
match colors.try_mark(prev_index, index, is_green) {
Ok(()) => (),
Err(None) => panic!("dep node {:?} is unexpectedly red", prev_index),
Err(Some(dep_node_index)) => return dep_node_index,
match colors.try_set_color(prev_index, color) {
TrySetColorResult::Success => {}
TrySetColorResult::AlreadyRed => panic!("dep node {prev_index:?} is unexpectedly red"),
TrySetColorResult::AlreadyGreen { index } => return index,
}

self.status.bump_index(&mut *local);
Expand All @@ -923,7 +924,8 @@ impl GraphEncoder {
/// from the previous dep graph and expects all edges to already have a new dep node index
/// assigned.
///
/// This will also ensure the dep node is marked green if `Some` is returned.
/// Tries to mark the dep node green, and returns Some if it is now green,
/// or None if had already been concurrently marked red.
#[inline]
pub(crate) fn send_promoted(
&self,
Expand All @@ -935,10 +937,10 @@ impl GraphEncoder {
let mut local = self.status.local.borrow_mut();
let index = self.status.next_index(&mut *local);

// Use `try_mark_green` to avoid racing when `send_promoted` or `send_and_color`
// Use `try_set_color` to avoid racing when `send_promoted` or `send_and_color`
// is called concurrently on the same index.
match colors.try_mark(prev_index, index, true) {
Ok(()) => {
match colors.try_set_color(prev_index, DesiredColor::Green { index }) {
TrySetColorResult::Success => {
self.status.bump_index(&mut *local);
self.status.encode_promoted_node(
index,
Expand All @@ -949,7 +951,8 @@ impl GraphEncoder {
);
Some(index)
}
Err(dep_node_index) => dep_node_index,
TrySetColorResult::AlreadyRed => None,
TrySetColorResult::AlreadyGreen { index } => Some(index),
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
Res::Def(_, def_id) => self.check_def_id(def_id),
Res::SelfTyParam { trait_: t } => self.check_def_id(t),
Res::SelfTyAlias { alias_to: i, .. } => self.check_def_id(i),
Res::ToolMod | Res::NonMacroAttr(..) | Res::Err => {}
Res::ToolMod | Res::NonMacroAttr(..) | Res::OpenMod(..) | Res::Err => {}
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
| Res::SelfCtor(..)
| Res::OpenMod(..)
| Res::Err => bug!("unexpected resolution: {:?}", res),
}
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1740,8 +1740,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Res::Def(DefKind::Macro(kinds), _) => {
format!("{} {}", kinds.article(), kinds.descr())
}
Res::ToolMod => {
// Don't confuse the user with tool modules.
Res::ToolMod | Res::OpenMod(..) => {
// Don't confuse the user with tool modules or open modules.
continue;
}
Res::Def(DefKind::Trait, _) if macro_kind == MacroKind::Derive => {
Expand Down Expand Up @@ -1978,7 +1978,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let (built_in, from) = match scope {
Scope::StdLibPrelude | Scope::MacroUsePrelude => ("", " from prelude"),
Scope::ExternPreludeFlags
if self.tcx.sess.opts.externs.get(ident.as_str()).is_some() =>
if self.tcx.sess.opts.externs.get(ident.as_str()).is_some()
|| matches!(res, Res::OpenMod(..)) =>
{
("", " passed with `--extern`")
}
Expand Down
16 changes: 13 additions & 3 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{
AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind,
Determinacy, Finalize, IdentKey, ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot,
ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet,
Segment, Stage, Used, errors,
Segment, Stage, Symbol, Used, errors,
};

#[derive(Copy, Clone)]
Expand Down Expand Up @@ -386,7 +386,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}

/// Resolve an identifier in the specified set of scopes.
#[instrument(level = "debug", skip(self))]
pub(crate) fn resolve_ident_in_scope_set<'r>(
self: CmResolver<'r, 'ra, 'tcx>,
orig_ident: Ident,
Expand Down Expand Up @@ -976,6 +975,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ignore_import,
)
}
ModuleOrUniformRoot::OpenModule(sym) => {
let open_ns_name = format!("{}::{}", sym.as_str(), ident.name);
let ns_ident = IdentKey::with_root_ctxt(Symbol::intern(&open_ns_name));
match self.extern_prelude_get_flag(ns_ident, ident.span, finalize.is_some()) {
Some(decl) => Ok(decl),
None => Err(Determinacy::Determined),
}
}
ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set(
ident,
ScopeSet::ModuleAndExternPrelude(ns, module),
Expand Down Expand Up @@ -1962,7 +1969,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}

let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
if let Some(def_id) = binding.res().module_like_def_id() {
if let Res::OpenMod(sym) = binding.res() {
module = Some(ModuleOrUniformRoot::OpenModule(sym));
record_segment_res(self.reborrow(), finalize, res, id);
} else if let Some(def_id) = binding.res().module_like_def_id() {
if self.mods_with_parse_errors.contains(&def_id) {
module_had_parse_errors = true;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type Res = def::Res<NodeId>;

/// A potential import declaration in the process of being planted into a module.
/// Also used for lazily planting names from `--extern` flags to extern prelude.
#[derive(Clone, Copy, Default, PartialEq)]
#[derive(Clone, Copy, Default, PartialEq, Debug)]
pub(crate) enum PendingDecl<'ra> {
Ready(Option<Decl<'ra>>),
#[default]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3381,7 +3381,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
&& def_id.is_local()
&& let Some(local_def_id) = def_id.as_local()
&& let Some(struct_generics) = self.r.struct_generics.get(&local_def_id)
&& let target_param = &struct_generics.params[idx]
&& let Some(target_param) = &struct_generics.params.get(idx)
&& let GenericParamKind::Const { ty, .. } = &target_param.kind
&& let TyKind::Path(_, path) = &ty.kind
{
Expand Down
Loading
Loading