Skip to content

Commit 2157f31

Browse files
committed
Add a way to decouple the implementation and the declaration of a TyCtxt method.
1 parent 8759de0 commit 2157f31

File tree

13 files changed

+96
-28
lines changed

13 files changed

+96
-28
lines changed

compiler/rustc_codegen_gcc/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ use rustc_metadata::EncodedMetadata;
8282
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
8383
use rustc_middle::query::Providers;
8484
use rustc_middle::ty::TyCtxt;
85+
use rustc_middle::hooks;
8586
use rustc_session::config::{Lto, OptLevel, OutputFilenames};
8687
use rustc_session::Session;
8788
use rustc_span::Symbol;
@@ -127,7 +128,7 @@ impl CodegenBackend for GccCodegenBackend {
127128
*self.supports_128bit_integers.lock().expect("lock") = check_context.get_last_error() == Ok(None);
128129
}
129130

130-
fn provide(&self, providers: &mut Providers) {
131+
fn provide(&self, providers: &mut Providers, _: &mut hooks::Providers) {
131132
// FIXME(antoyo) compute list of enabled features from cli flags
132133
providers.global_backend_features = |_tcx, ()| vec![];
133134
}

compiler/rustc_codegen_llvm/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, Subd
3939
use rustc_fluent_macro::fluent_messages;
4040
use rustc_metadata::EncodedMetadata;
4141
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
42+
use rustc_middle::hooks;
4243
use rustc_middle::query::Providers;
4344
use rustc_middle::ty::TyCtxt;
4445
use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest};
@@ -268,7 +269,7 @@ impl CodegenBackend for LlvmCodegenBackend {
268269
llvm_util::init(sess); // Make sure llvm is inited
269270
}
270271

271-
fn provide(&self, providers: &mut Providers) {
272+
fn provide(&self, providers: &mut Providers, _hooks: &mut hooks::Providers) {
272273
providers.global_backend_features =
273274
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
274275
}

compiler/rustc_codegen_ssa/src/traits/backend.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_data_structures::sync::{DynSend, DynSync};
1111
use rustc_errors::ErrorGuaranteed;
1212
use rustc_metadata::EncodedMetadata;
1313
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
14+
use rustc_middle::hooks;
1415
use rustc_middle::query::{ExternProviders, Providers};
1516
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
1617
use rustc_middle::ty::{Ty, TyCtxt};
@@ -84,7 +85,7 @@ pub trait CodegenBackend {
8485
Box::new(crate::back::metadata::DefaultMetadataLoader)
8586
}
8687

87-
fn provide(&self, _providers: &mut Providers) {}
88+
fn provide(&self, _providers: &mut Providers, _hooks: &mut hooks::Providers) {}
8889
fn provide_extern(&self, _providers: &mut ExternProviders) {}
8990
fn codegen_crate<'tcx>(
9091
&self,

compiler/rustc_const_eval/src/const_eval/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::errors::MaxNumNodesInConstErr;
44
use crate::interpret::{intern_const_alloc_recursive, InternKind, InterpCx, Scalar};
55
use rustc_middle::mir;
66
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
7+
use rustc_middle::query::TyCtxtAt;
78
use rustc_middle::ty::{self, Ty, TyCtxt};
89
use rustc_span::{source_map::DUMMY_SP, symbol::Symbol};
910

@@ -86,17 +87,17 @@ pub(crate) fn eval_to_valtree<'tcx>(
8687

8788
#[instrument(skip(tcx), level = "debug")]
8889
pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>(
89-
tcx: TyCtxt<'tcx>,
90+
tcx: TyCtxtAt<'tcx>,
9091
val: mir::ConstValue<'tcx>,
9192
ty: Ty<'tcx>,
9293
) -> Option<mir::DestructuredConstant<'tcx>> {
9394
let param_env = ty::ParamEnv::reveal_all();
94-
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
95+
let ecx = mk_eval_cx(tcx.tcx, tcx.span, param_env, CanAccessStatics::No);
9596
let op = ecx.const_val_to_op(val, ty, None).ok()?;
9697

9798
// We go to `usize` as we cannot allocate anything bigger anyway.
9899
let (field_count, variant, down) = match ty.kind() {
99-
ty::Array(_, len) => (len.eval_target_usize(tcx, param_env) as usize, None, op),
100+
ty::Array(_, len) => (len.eval_target_usize(tcx.tcx, param_env) as usize, None, op),
100101
ty::Adt(def, _) if def.variants().is_empty() => {
101102
return None;
102103
}

compiler/rustc_const_eval/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ pub use errors::ReportErrorExt;
3939
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
4040
use rustc_fluent_macro::fluent_messages;
4141
use rustc_middle::query::Providers;
42-
use rustc_middle::ty;
42+
use rustc_middle::{hooks, ty};
4343

4444
fluent_messages! { "../messages.ftl" }
4545

46-
pub fn provide(providers: &mut Providers) {
46+
pub fn provide(providers: &mut Providers, hooks: &mut hooks::Providers) {
4747
const_eval::provide(providers);
4848
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
4949
providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
@@ -52,8 +52,8 @@ pub fn provide(providers: &mut Providers) {
5252
let (param_env, raw) = param_env_and_value.into_parts();
5353
const_eval::eval_to_valtree(tcx, param_env, raw)
5454
};
55-
providers.try_destructure_mir_constant_for_diagnostics =
56-
|tcx, (cv, ty)| const_eval::try_destructure_mir_constant_for_diagnostics(tcx, cv, ty);
55+
hooks.try_destructure_mir_constant_for_diagnostics =
56+
const_eval::try_destructure_mir_constant_for_diagnostics;
5757
providers.valtree_to_const_val = |tcx, (ty, valtree)| {
5858
const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree)
5959
};

compiler/rustc_interface/src/passes.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintSto
1818
use rustc_metadata::creader::CStore;
1919
use rustc_middle::arena::Arena;
2020
use rustc_middle::dep_graph::DepGraph;
21+
use rustc_middle::hooks;
2122
use rustc_middle::query::{ExternProviders, Providers};
2223
use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
2324
use rustc_mir_build as mir_build;
@@ -645,15 +646,16 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
645646
outputs.into()
646647
}
647648

648-
pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
649+
pub static DEFAULT_QUERY_PROVIDERS: LazyLock<(Providers, hooks::Providers)> = LazyLock::new(|| {
649650
let providers = &mut Providers::default();
651+
let hooks = &mut hooks::Providers::default();
650652
providers.analysis = analysis;
651653
providers.hir_crate = rustc_ast_lowering::lower_to_hir;
652654
providers.output_filenames = output_filenames;
653655
providers.resolver_for_lowering = resolver_for_lowering;
654656
providers.early_lint_checks = early_lint_checks;
655657
proc_macro_decls::provide(providers);
656-
rustc_const_eval::provide(providers);
658+
rustc_const_eval::provide(providers, hooks);
657659
rustc_middle::hir::provide(providers);
658660
mir_borrowck::provide(providers);
659661
mir_build::provide(providers);
@@ -672,7 +674,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
672674
rustc_lint::provide(providers);
673675
rustc_symbol_mangling::provide(providers);
674676
rustc_codegen_ssa::provide(providers);
675-
*providers
677+
(*providers, *hooks)
676678
});
677679

678680
pub static DEFAULT_EXTERN_QUERY_PROVIDERS: LazyLock<ExternProviders> = LazyLock::new(|| {
@@ -702,8 +704,8 @@ pub fn create_global_ctxt<'tcx>(
702704
let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
703705

704706
let codegen_backend = compiler.codegen_backend();
705-
let mut local_providers = *DEFAULT_QUERY_PROVIDERS;
706-
codegen_backend.provide(&mut local_providers);
707+
let (mut local_providers, mut hooks) = *DEFAULT_QUERY_PROVIDERS;
708+
codegen_backend.provide(&mut local_providers, &mut hooks);
707709

708710
let mut extern_providers = *DEFAULT_EXTERN_QUERY_PROVIDERS;
709711
codegen_backend.provide_extern(&mut extern_providers);
@@ -732,6 +734,7 @@ pub fn create_global_ctxt<'tcx>(
732734
query_result_on_disk_cache,
733735
incremental,
734736
),
737+
hooks,
735738
)
736739
})
737740
})
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use crate::mir;
2+
use crate::query::TyCtxtAt;
3+
use crate::ty::{Ty, TyCtxt};
4+
use rustc_span::DUMMY_SP;
5+
6+
macro_rules! declare_hooks {
7+
($($(#[$attr:meta])*hook $name:ident($($arg:ident: $K:ty),*) -> $V:ty;)*) => {
8+
9+
impl<'tcx> TyCtxt<'tcx> {
10+
$(
11+
$(#[$attr])*
12+
#[inline(always)]
13+
#[must_use]
14+
pub fn $name(self, $($arg: $K,)*) -> $V
15+
{
16+
self.at(DUMMY_SP).$name($($arg,)*)
17+
}
18+
)*
19+
}
20+
21+
impl<'tcx> TyCtxtAt<'tcx> {
22+
$(
23+
$(#[$attr])*
24+
#[inline(always)]
25+
#[must_use]
26+
pub fn $name(self, $($arg: $K,)*) -> $V
27+
{
28+
(self.tcx.hooks.$name)(self, $($arg,)*)
29+
}
30+
)*
31+
}
32+
33+
pub struct Providers {
34+
$(pub $name: for<'tcx> fn(
35+
TyCtxtAt<'tcx>,
36+
$($arg: $K,)*
37+
) -> $V,)*
38+
}
39+
40+
impl Default for Providers {
41+
fn default() -> Self {
42+
Providers {
43+
$($name: |_, $($arg,)*| bug!(
44+
"`tcx.{}{:?}` cannot be called as `{}` was never assigned to a provider function.\n",
45+
stringify!($name),
46+
($($arg,)*),
47+
stringify!($name),
48+
),)*
49+
}
50+
}
51+
}
52+
53+
impl Copy for Providers {}
54+
impl Clone for Providers {
55+
fn clone(&self) -> Self { *self }
56+
}
57+
};
58+
}
59+
60+
declare_hooks! {
61+
/// Tries to destructure an `mir::Const` ADT or array into its variant index
62+
/// and its field values. This should only be used for pretty printing.
63+
hook try_destructure_mir_constant_for_diagnostics(val: mir::ConstValue<'tcx>, ty: Ty<'tcx>) -> Option<mir::DestructuredConstant<'tcx>>;
64+
}

compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ mod macros;
8989
pub mod arena;
9090
pub mod error;
9191
pub mod hir;
92+
pub mod hooks;
9293
pub mod infer;
9394
pub mod lint;
9495
pub mod metadata;

compiler/rustc_middle/src/mir/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,7 @@ fn pretty_print_const_value_tcx<'tcx>(
16911691
(_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_non_region_param() => {
16921692
let ct = tcx.lift(ct).unwrap();
16931693
let ty = tcx.lift(ty).unwrap();
1694-
if let Some(contents) = tcx.try_destructure_mir_constant_for_diagnostics((ct, ty)) {
1694+
if let Some(contents) = tcx.try_destructure_mir_constant_for_diagnostics(ct, ty) {
16951695
let fields: Vec<(ConstValue<'_>, Ty<'_>)> = contents.fields.to_vec();
16961696
match *ty.kind() {
16971697
ty::Array(..) => {

compiler/rustc_middle/src/query/mod.rs

-10
Original file line numberDiff line numberDiff line change
@@ -1100,16 +1100,6 @@ rustc_queries! {
11001100
desc { "destructuring type level constant"}
11011101
}
11021102

1103-
/// Tries to destructure an `mir::Const` ADT or array into its variant index
1104-
/// and its field values. This should only be used for pretty printing.
1105-
query try_destructure_mir_constant_for_diagnostics(
1106-
key: (mir::ConstValue<'tcx>, Ty<'tcx>)
1107-
) -> Option<mir::DestructuredConstant<'tcx>> {
1108-
desc { "destructuring MIR constant"}
1109-
no_hash
1110-
eval_always
1111-
}
1112-
11131103
query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> mir::ConstValue<'tcx> {
11141104
desc { "getting a &core::panic::Location referring to a span" }
11151105
}

compiler/rustc_middle/src/ty/context.rs

+6
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,10 @@ pub struct GlobalCtxt<'tcx> {
554554
/// Common consts, pre-interned for your convenience.
555555
pub consts: CommonConsts<'tcx>,
556556

557+
/// Hooks to be able to register functions in other crates that can then still
558+
/// be called from rustc_middle.
559+
pub(crate) hooks: crate::hooks::Providers,
560+
557561
untracked: Untracked,
558562

559563
pub query_system: QuerySystem<'tcx>,
@@ -703,6 +707,7 @@ impl<'tcx> TyCtxt<'tcx> {
703707
dep_graph: DepGraph,
704708
query_kinds: &'tcx [DepKindStruct<'tcx>],
705709
query_system: QuerySystem<'tcx>,
710+
hooks: crate::hooks::Providers,
706711
) -> GlobalCtxt<'tcx> {
707712
let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
708713
s.emit_fatal(err);
@@ -721,6 +726,7 @@ impl<'tcx> TyCtxt<'tcx> {
721726
hir_arena,
722727
interners,
723728
dep_graph,
729+
hooks,
724730
prof: s.prof.clone(),
725731
types: common_types,
726732
lifetimes: common_lifetimes,

src/librustdoc/core.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ pub(crate) fn create_config(
286286
let body = hir.body(hir.body_owned_by(def_id));
287287
debug!("visiting body for {def_id:?}");
288288
EmitIgnoredResolutionErrors::new(tcx).visit_body(body);
289-
(rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id)
289+
(rustc_interface::DEFAULT_QUERY_PROVIDERS.0.typeck)(tcx, def_id)
290290
};
291291
}),
292292
make_codegen_backend: None,

src/tools/clippy/clippy_utils/src/consts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ fn field_of_struct<'tcx>(
718718
field: &Ident,
719719
) -> Option<mir::Const<'tcx>> {
720720
if let mir::Const::Val(result, ty) = result
721-
&& let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_diagnostics((result, ty))
721+
&& let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_diagnostics(result, ty)
722722
&& let Some(dc_variant) = dc.variant
723723
&& let Some(variant) = adt_def.variants().get(dc_variant)
724724
&& let Some(field_idx) = variant.fields.iter().position(|el| el.name == field.name)

0 commit comments

Comments
 (0)