Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disambiguate expansions relative to the creating DepNode #111815

Closed
wants to merge 10 commits into from
41 changes: 24 additions & 17 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_expr_if(cond, then, else_opt.as_deref())
}
ExprKind::While(cond, body, opt_label) => self.with_loop_scope(e.id, |this| {
let span = this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None);
let span =
this.tcx.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None);
this.lower_expr_while_in_loop_scope(span, cond, body, *opt_label)
}),
ExprKind::Loop(body, opt_label, span) => self.with_loop_scope(e.id, |this| {
Expand Down Expand Up @@ -448,7 +449,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
_ => {
let cond = self.lower_expr(cond);
let reason = DesugaringKind::CondTemporary;
let span_block = self.mark_span_with_reason(reason, cond.span, None);
let span_block = self.tcx.mark_span_with_reason(reason, cond.span, None);
self.expr_drop_temps(span_block, cond)
}
}
Expand Down Expand Up @@ -501,15 +502,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Final expression of the block (if present) or `()` with span at the end of block
let (try_span, tail_expr) = if let Some(expr) = block.expr.take() {
(
this.mark_span_with_reason(
this.tcx.mark_span_with_reason(
DesugaringKind::TryBlock,
expr.span,
this.allow_try_trait.clone(),
),
expr,
)
} else {
let try_span = this.mark_span_with_reason(
let try_span = this.tcx.mark_span_with_reason(
DesugaringKind::TryBlock,
this.tcx.sess.source_map().end_point(body.span),
this.allow_try_trait.clone(),
Expand All @@ -519,7 +520,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
};

let ok_wrapped_span =
this.mark_span_with_reason(DesugaringKind::TryBlock, tail_expr.span, None);
this.tcx.mark_span_with_reason(DesugaringKind::TryBlock, tail_expr.span, None);

// `::std::ops::Try::from_output($tail_expr)`
block.expr = Some(this.wrap_in_try_constructor(
Expand Down Expand Up @@ -591,8 +592,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));

// Resume argument type: `ResumeTy`
let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
let unstable_span = self.tcx.mark_span_with_reason(
DesugaringKind::Async,
span,
self.allow_gen_future.clone(),
);
let resume_ty = hir::QPath::LangItem(hir::LangItem::ResumeTy, unstable_span, None);
let input_ty = hir::Ty {
hir_id: self.next_id(),
Expand Down Expand Up @@ -661,7 +665,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&& attrs.into_iter().any(|attr| attr.has_name(sym::track_caller))
{
let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
self.tcx.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
self.lower_attrs(
inner_hir_id,
&[Attribute {
Expand Down Expand Up @@ -707,8 +711,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
});
}
}
let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, None);
let gen_future_span = self.mark_span_with_reason(
let span = self.tcx.mark_span_with_reason(DesugaringKind::Await, await_kw_span, None);
let gen_future_span = self.tcx.mark_span_with_reason(
DesugaringKind::Await,
full_span,
self.allow_gen_future.clone(),
Expand Down Expand Up @@ -1466,9 +1470,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
let head = self.lower_expr_mut(head);
let pat = self.lower_pat(pat);
let for_span =
self.mark_span_with_reason(DesugaringKind::ForLoop, self.lower_span(e.span), None);
let head_span = self.mark_span_with_reason(DesugaringKind::ForLoop, head.span, None);
let pat_span = self.mark_span_with_reason(DesugaringKind::ForLoop, pat.span, None);
self.tcx.mark_span_with_reason(DesugaringKind::ForLoop, self.lower_span(e.span), None);
let head_span = self.tcx.mark_span_with_reason(DesugaringKind::ForLoop, head.span, None);
let pat_span = self.tcx.mark_span_with_reason(DesugaringKind::ForLoop, pat.span, None);

// `None => break`
let none_arm = {
Expand Down Expand Up @@ -1562,13 +1566,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// }
/// ```
fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind<'hir> {
let unstable_span = self.mark_span_with_reason(
let unstable_span = self.tcx.mark_span_with_reason(
DesugaringKind::QuestionMark,
span,
self.allow_try_trait.clone(),
);
let try_span = self.tcx.sess.source_map().end_point(span);
let try_span = self.mark_span_with_reason(
let try_span = self.tcx.mark_span_with_reason(
DesugaringKind::QuestionMark,
try_span,
self.allow_try_trait.clone(),
Expand Down Expand Up @@ -1659,10 +1663,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (yeeted_span, yeeted_expr) = if let Some(sub_expr) = sub_expr {
(sub_expr.span, self.lower_expr(sub_expr))
} else {
(self.mark_span_with_reason(DesugaringKind::YeetExpr, span, None), self.expr_unit(span))
(
self.tcx.mark_span_with_reason(DesugaringKind::YeetExpr, span, None),
self.expr_unit(span),
)
};

let unstable_span = self.mark_span_with_reason(
let unstable_span = self.tcx.mark_span_with_reason(
DesugaringKind::YeetExpr,
span,
self.allow_try_trait.clone(),
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
};

let desugared_span = this.mark_span_with_reason(DesugaringKind::Async, span, None);
let desugared_span =
this.tcx.mark_span_with_reason(DesugaringKind::Async, span, None);

// Construct a parameter representing `__argN: <ty>` to replace the parameter of the
// async function.
Expand Down Expand Up @@ -1160,7 +1161,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

// Transform into `drop-temps { <user-body> }`, an expression:
let desugared_span =
this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
this.tcx.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
let user_body =
this.expr_drop_temps(desugared_span, this.arena.alloc(user_body));

Expand Down
17 changes: 2 additions & 15 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -762,19 +762,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.tcx.sess.diagnostic()
}

/// Reuses the span but adds information like the kind of the desugaring and features that are
/// allowed inside this span.
fn mark_span_with_reason(
&self,
reason: DesugaringKind,
span: Span,
allow_internal_unstable: Option<Lrc<[Symbol]>>,
) -> Span {
self.tcx.with_stable_hashing_context(|hcx| {
span.mark_with_reason(allow_internal_unstable, reason, self.tcx.sess.edition(), hcx)
})
}

/// Intercept all spans entering HIR.
/// Mark a span as relative to the current owning item.
fn lower_span(&self, span: Span) -> Span {
Expand Down Expand Up @@ -1529,7 +1516,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// desugaring that explicitly states that we don't want to track that.
// Not tracking it makes lints in rustc and clippy very fragile, as
// frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
let opaque_ty_span = self.tcx.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);

let opaque_ty_def_id = self.create_def(
self.current_hir_id_owner.def_id,
Expand Down Expand Up @@ -1893,7 +1880,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> hir::FnRetTy<'hir> {
let span = output.span();

let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
let opaque_ty_span = self.tcx.mark_span_with_reason(DesugaringKind::Async, span, None);

let fn_def_id = self.local_def_id(fn_node_id);

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_data_structures/src/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ impl<D: Decoder> Decodable<D> for Fingerprint {
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)]
pub struct PackedFingerprint(Fingerprint);

impl PackedFingerprint {
pub const ZERO: PackedFingerprint = PackedFingerprint(Fingerprint::ZERO);
}

impl std::fmt::Display for PackedFingerprint {
#[inline]
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
.map(|(path, item, _exts, is_const)| {
// FIXME: Consider using the derive resolutions (`_exts`)
// instead of enqueuing the derives to be resolved again later.
let expn_id = LocalExpnId::fresh_empty();
let expn_id = LocalExpnId::reserve_expn_id();
derive_invocations.push((
Invocation {
kind: InvocationKind::Derive { path, item, is_const },
Expand Down Expand Up @@ -1548,7 +1548,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
}

fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment {
let expn_id = LocalExpnId::fresh_empty();
let expn_id = LocalExpnId::reserve_expn_id();
let vis = kind.placeholder_visibility();
self.invocations.push((
Invocation {
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/dep_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item};

pub type DepGraph = rustc_query_system::dep_graph::DepGraph<DepKind>;

pub type CurrentDepNode = rustc_query_system::dep_graph::CurrentDepNode<DepKind>;
pub type TaskDeps = rustc_query_system::dep_graph::TaskDeps<DepKind>;
pub type TaskDepsRef<'a> = rustc_query_system::dep_graph::TaskDepsRef<'a, DepKind>;
pub type DepGraphQuery = rustc_query_system::dep_graph::DepGraphQuery<DepKind>;
Expand Down Expand Up @@ -48,12 +49,13 @@ impl rustc_query_system::dep_graph::DepKind for DepKind {
write!(f, ")")
}

fn with_deps<OP, R>(task_deps: TaskDepsRef<'_>, op: OP) -> R
fn with_deps<OP, R>(current_node: CurrentDepNode, task_deps: TaskDepsRef<'_>, op: OP) -> R
where
OP: FnOnce() -> R,
{
ty::tls::with_context(|icx| {
let icx = ty::tls::ImplicitCtxt { task_deps, ..icx.clone() };
let icx =
ty::tls::ImplicitCtxt { current_node: &current_node, task_deps, ..icx.clone() };

ty::tls::enter_context(&icx, op)
})
Expand Down
15 changes: 1 addition & 14 deletions compiler/rustc_middle/src/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,20 +630,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {

let data: ExpnData = decoder
.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA));
let expn_id = rustc_span::hygiene::register_local_expn_id(data, hash);

#[cfg(debug_assertions)]
{
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
let local_hash = decoder.tcx.with_stable_hashing_context(|mut hcx| {
let mut hasher = StableHasher::new();
expn_id.expn_data().hash_stable(&mut hcx, &mut hasher);
hasher.finish()
});
debug_assert_eq!(hash.local_hash(), local_hash);
}

expn_id
rustc_span::hygiene::register_local_expn_id(data, hash)
} else {
let index_guess = decoder.foreign_expn_data[&hash];
decoder.tcx.cstore_untracked().expn_hash_to_expn_id(
Expand Down
54 changes: 52 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
pub mod tls;

use crate::arena::Arena;
use crate::dep_graph::{DepGraph, DepKindStruct};
use crate::dep_graph::{CurrentDepNode, DepGraph, DepKindStruct, DepNode};
use crate::infer::canonical::CanonicalVarInfo;
use crate::lint::struct_lint_level;
use crate::metadata::ModChild;
Expand Down Expand Up @@ -65,6 +65,7 @@ use rustc_session::Limit;
use rustc_session::Session;
use rustc_span::def_id::{DefPathHash, StableCrateId};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{DesugaringKind, ExpnData, ExpnKind, LocalExpnId};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi;
Expand Down Expand Up @@ -547,7 +548,12 @@ impl<'tcx> GlobalCtxt<'tcx> {
where
F: FnOnce(TyCtxt<'tcx>) -> R,
{
let icx = tls::ImplicitCtxt::new(self);
let current_node = if self.dep_graph.is_fully_enabled() {
CurrentDepNode::Untracked
} else {
CurrentDepNode::regular(DepNode::NULL)
};
let icx = tls::ImplicitCtxt::new(self, &current_node);
tls::enter_context(&icx, || f(icx.tcx))
}
}
Expand Down Expand Up @@ -901,6 +907,50 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

impl<'tcx> TyCtxt<'tcx> {
#[instrument(level = "trace", skip(self), ret)]
pub fn create_expn(self, expn_data: ExpnData) -> LocalExpnId {
tls::with_related_context(self, |icx| {
let CurrentDepNode::Regular { dep_node, expn_disambiguators } = icx.current_node else {
bug!("creating an expansion outside of a query")
};
self.with_stable_hashing_context(|ctx| {
LocalExpnId::create_untracked_expn(expn_data, dep_node, ctx, &expn_disambiguators)
})
})
}

/// Fill an empty expansion. This method must not be used outside of the resolver.
#[inline]
#[instrument(level = "trace", skip(self))]
pub fn finalize_expn(self, expn_id: LocalExpnId, expn_data: ExpnData) {
tls::with_related_context(self, |icx| {
let CurrentDepNode::Regular { dep_node, expn_disambiguators } = icx.current_node else {
bug!("creating an expansion outside of a query")
};
self.with_stable_hashing_context(|ctx| {
expn_id.set_untracked_expn_data(expn_data, dep_node, ctx, &expn_disambiguators)
})
});
}

/// Reuses the span but adds information like the kind of the desugaring and features that are
/// allowed inside this span.
pub fn mark_span_with_reason(
self,
reason: DesugaringKind,
span: Span,
allow_internal_unstable: Option<Lrc<[Symbol]>>,
) -> Span {
let edition = self.sess.edition();
let mut expn_data =
ExpnData::default(ExpnKind::Desugaring(reason), span, edition, None, None);
expn_data.allow_internal_unstable = allow_internal_unstable;
let expn_id = self.create_expn(expn_data);
span.fresh_expansion(expn_id)
}
}

impl<'tcx> TyCtxtAt<'tcx> {
/// Create a new definition within the incr. comp. engine.
pub fn create_def(
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_middle/src/ty/context/tls.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{GlobalCtxt, TyCtxt};

use crate::dep_graph::TaskDepsRef;
use crate::dep_graph::{CurrentDepNode, TaskDepsRef};
use crate::query::plumbing::QueryJobId;
use rustc_data_structures::sync::{self, Lock};
use rustc_errors::Diagnostic;
Expand Down Expand Up @@ -31,19 +31,24 @@ pub struct ImplicitCtxt<'a, 'tcx> {
/// Used to prevent queries from calling too deeply.
pub query_depth: usize,

/// The DepNode of the query being executed. This is updated by the dep-graph. This is used to
/// know which query created an expansion.
pub current_node: &'a CurrentDepNode,

/// The current dep graph task. This is used to add dependencies to queries
/// when executing them.
pub task_deps: TaskDepsRef<'a>,
}

impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
pub fn new(gcx: &'tcx GlobalCtxt<'tcx>, current_node: &'a CurrentDepNode) -> Self {
let tcx = TyCtxt { gcx };
ImplicitCtxt {
tcx,
query: None,
diagnostics: None,
query_depth: 0,
current_node,
task_deps: TaskDepsRef::Ignore,
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_query_impl/src/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ impl QueryContext for QueryCtxt<'_> {
query: Some(token),
diagnostics,
query_depth: current_icx.query_depth + depth_limit as usize,
current_node: current_icx.current_node,
task_deps: current_icx.task_deps,
};

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_query_system/src/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pub struct DepNode<K> {
}

impl<K: DepKind> DepNode<K> {
pub const NULL: DepNode<K> = DepNode { kind: K::NULL, hash: PackedFingerprint::ZERO };

/// Creates a new, parameterless DepNode. This method will assert
/// that the DepNode corresponding to the given DepKind actually
/// does not require any parameters.
Expand Down
Loading