Skip to content

Commit 7e11379

Browse files
committed
Auto merge of #74113 - lcnr:type-dependent-consts-2, r=eddyb
Support const args in type dependent paths (Take 2) once more, except it is sound this time 🥰 previously #71154 ----- ```rust #![feature(const_generics)] struct A; impl A { fn foo<const N: usize>(&self) -> usize { N } } struct B; impl B { fn foo<const N: usize>(&self) -> usize { 42 } } fn main() { let a = A; a.foo::<7>(); } ``` When calling `type_of` for generic const arguments, we now use the `TypeckTables` of the surrounding body to get the expected type. This alone causes cycle errors though, as we now have `typeck_tables_of(main)` -> `...` -> `type_of(main_ANON0 := 7)` -> `typeck_tables_of(main)` ⚡ (see #68400 (comment)) To prevent this we must not call `type_of(const_arg)` during `typeck_tables_of`. This is achieved by calling `type_of(param_def_id)` instead. We have to somehow remember the `DefId` of the param through all of typeck, which is done using the struct `ty::WithOptConstParam<DefId>`, which replaces `DefId` where needed and contains an `Option<DefId>` to be able to store the const parameter in case it exists. Queries which are currently cached on disk are split into two variants: `query_name`(cached) and `query_name_(of|for)_const_arg`(not cached), with `query_name_of_const_arg` taking a pair `(did, param_did): (LocalDefId, DefId)`. For some queries a method `query_name_of_opt_const_arg` is added to `TyCtxt` which takes a `ty::WithOptConstParam` and either calls `query_name` or `query_name_of_const_arg` depending on the value of `const_param_did`. r? @eddyb @varkor
2 parents d9e8d62 + 2666aed commit 7e11379

File tree

101 files changed

+1547
-622
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+1547
-622
lines changed

src/librustc_codegen_ssa/back/symbol_export.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,9 @@ fn exported_symbols_provider_local(
248248
}
249249

250250
match *mono_item {
251-
MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) => {
251+
MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => {
252252
if substs.non_erasable_generics().next().is_some() {
253-
let symbol = ExportedSymbol::Generic(def_id, substs);
253+
let symbol = ExportedSymbol::Generic(def.did, substs);
254254
symbols.push((symbol, SymbolExportLevel::Rust));
255255
}
256256
}

src/librustc_codegen_ssa/mir/constant.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2525
constant: &mir::Constant<'tcx>,
2626
) -> Result<ConstValue<'tcx>, ErrorHandled> {
2727
match self.monomorphize(&constant.literal).val {
28-
ty::ConstKind::Unevaluated(def_id, substs, promoted) => self
28+
ty::ConstKind::Unevaluated(def, substs, promoted) => self
2929
.cx
3030
.tcx()
31-
.const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None)
31+
.const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None)
3232
.map_err(|err| {
3333
if promoted.is_none() {
3434
self.cx

src/librustc_incremental/persist/dirty_clean.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ const BASE_IMPL: &[&str] =
6464

6565
/// DepNodes for mir_built/Optimized, which is relevant in "executable"
6666
/// code, i.e., functions+methods
67-
const BASE_MIR: &[&str] =
68-
&[label_strs::optimized_mir, label_strs::promoted_mir, label_strs::mir_built];
67+
const BASE_MIR: &[&str] = &[label_strs::optimized_mir, label_strs::promoted_mir];
6968

7069
/// Struct, Enum and Union DepNodes
7170
///
@@ -376,7 +375,7 @@ impl DirtyCleanVisitor<'tcx> {
376375
let def_path_hash = self.tcx.def_path_hash(def_id);
377376
labels.iter().map(move |label| match DepNode::from_label_string(label, def_path_hash) {
378377
Ok(dep_node) => dep_node,
379-
Err(()) => unreachable!(),
378+
Err(()) => unreachable!("label: {}", label),
380379
})
381380
}
382381

src/librustc_infer/infer/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1536,7 +1536,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15361536
pub fn const_eval_resolve(
15371537
&self,
15381538
param_env: ty::ParamEnv<'tcx>,
1539-
def_id: DefId,
1539+
def: ty::WithOptConstParam<DefId>,
15401540
substs: SubstsRef<'tcx>,
15411541
promoted: Option<mir::Promoted>,
15421542
span: Option<Span>,
@@ -1547,7 +1547,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15471547
let (param_env, substs) = canonical.value;
15481548
// The return value is the evaluated value which doesn't contain any reference to inference
15491549
// variables, thus we don't need to substitute back the original values.
1550-
self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, span)
1550+
self.tcx.const_eval_resolve(param_env, def, substs, promoted, span)
15511551
}
15521552

15531553
/// If `typ` is a type variable of some kind, resolve it one level

src/librustc_interface/passes.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,8 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
891891
mir::transform::check_unsafety::check_unsafety(tcx, def_id);
892892

893893
if tcx.hir().body_const_context(def_id).is_some() {
894-
tcx.ensure().mir_drops_elaborated_and_const_checked(def_id);
894+
tcx.ensure()
895+
.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(def_id));
895896
}
896897
}
897898
});

src/librustc_metadata/rmeta/decoder/cstore_impl.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
111111
bug!("coerce_unsized_info: `{:?}` is missing its info", def_id);
112112
})
113113
}
114-
optimized_mir => { cdata.get_optimized_mir(tcx, def_id.index) }
115-
promoted_mir => { cdata.get_promoted_mir(tcx, def_id.index) }
114+
optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
115+
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
116116
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
117117
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
118118
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }

src/librustc_middle/arena.rs

+30
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,37 @@ macro_rules! arena_types {
1414
[] layouts: rustc_target::abi::Layout, rustc_target::abi::Layout;
1515
// AdtDef are interned and compared by address
1616
[] adt_def: rustc_middle::ty::AdtDef, rustc_middle::ty::AdtDef;
17+
[] steal_mir:
18+
rustc_middle::ty::steal::Steal<rustc_middle::mir::Body<$tcx>>,
19+
rustc_middle::ty::steal::Steal<rustc_middle::mir::Body<$tcx>>;
20+
[decode] mir: rustc_middle::mir::Body<$tcx>, rustc_middle::mir::Body<'_x>;
21+
[] steal_promoted:
22+
rustc_middle::ty::steal::Steal<
23+
rustc_index::vec::IndexVec<
24+
rustc_middle::mir::Promoted,
25+
rustc_middle::mir::Body<$tcx>
26+
>
27+
>,
28+
rustc_middle::ty::steal::Steal<
29+
rustc_index::vec::IndexVec<
30+
rustc_middle::mir::Promoted,
31+
rustc_middle::mir::Body<$tcx>
32+
>
33+
>;
34+
[decode] promoted:
35+
rustc_index::vec::IndexVec<
36+
rustc_middle::mir::Promoted,
37+
rustc_middle::mir::Body<$tcx>
38+
>,
39+
rustc_index::vec::IndexVec<
40+
rustc_middle::mir::Promoted,
41+
rustc_middle::mir::Body<'_x>
42+
>;
1743
[decode] tables: rustc_middle::ty::TypeckTables<$tcx>, rustc_middle::ty::TypeckTables<'_x>;
44+
[decode] borrowck_result:
45+
rustc_middle::mir::BorrowCheckResult<$tcx>,
46+
rustc_middle::mir::BorrowCheckResult<'_x>;
47+
[decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult, rustc_middle::mir::UnsafetyCheckResult;
1848
[] const_allocs: rustc_middle::mir::interpret::Allocation, rustc_middle::mir::interpret::Allocation;
1949
// Required for the incremental on-disk cache
2050
[few, decode] mir_keys: rustc_hir::def_id::DefIdSet, rustc_hir::def_id::DefIdSet;

src/librustc_middle/mir/interpret/queries.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ impl<'tcx> TyCtxt<'tcx> {
3434
pub fn const_eval_resolve(
3535
self,
3636
param_env: ty::ParamEnv<'tcx>,
37-
def_id: DefId,
37+
def: ty::WithOptConstParam<DefId>,
3838
substs: SubstsRef<'tcx>,
3939
promoted: Option<mir::Promoted>,
4040
span: Option<Span>,
4141
) -> ConstEvalResult<'tcx> {
42-
match ty::Instance::resolve(self, param_env, def_id, substs) {
42+
match ty::Instance::resolve_opt_const_arg(self, param_env, def, substs) {
4343
Ok(Some(instance)) => {
4444
let cid = GlobalId { instance, promoted };
4545
self.const_eval_global_id(param_env, cid, span)

src/librustc_middle/mir/mono.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,8 @@ impl<'tcx> CodegenUnit<'tcx> {
346346
// instances into account. The others don't matter for
347347
// the codegen tests and can even make item order
348348
// unstable.
349-
InstanceDef::Item(def_id) => {
350-
def_id.as_local().map(|def_id| tcx.hir().as_local_hir_id(def_id))
349+
InstanceDef::Item(def) => {
350+
def.did.as_local().map(|def_id| tcx.hir().as_local_hir_id(def_id))
351351
}
352352
InstanceDef::VtableShim(..)
353353
| InstanceDef::ReifyShim(..)

src/librustc_middle/mir/query.rs

+38-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
//! Values computed by queries that use MIR.
22
3-
use crate::ty::{self, Ty};
3+
use crate::mir::{Body, Promoted};
4+
use crate::ty::{self, Ty, TyCtxt};
45
use rustc_data_structures::fx::FxHashMap;
56
use rustc_data_structures::sync::Lrc;
67
use rustc_hir as hir;
7-
use rustc_hir::def_id::DefId;
8+
use rustc_hir::def_id::{DefId, LocalDefId};
89
use rustc_index::bit_set::BitMatrix;
910
use rustc_index::vec::IndexVec;
1011
use rustc_span::{Span, Symbol};
@@ -323,3 +324,38 @@ pub struct CoverageInfo {
323324
/// The total number of coverage region counters added to the MIR `Body`.
324325
pub num_counters: u32,
325326
}
327+
328+
impl<'tcx> TyCtxt<'tcx> {
329+
pub fn mir_borrowck_opt_const_arg(
330+
self,
331+
def: ty::WithOptConstParam<LocalDefId>,
332+
) -> &'tcx BorrowCheckResult<'tcx> {
333+
if let Some(param_did) = def.const_param_did {
334+
self.mir_borrowck_const_arg((def.did, param_did))
335+
} else {
336+
self.mir_borrowck(def.did)
337+
}
338+
}
339+
340+
pub fn mir_const_qualif_opt_const_arg(
341+
self,
342+
def: ty::WithOptConstParam<LocalDefId>,
343+
) -> ConstQualifs {
344+
if let Some(param_did) = def.const_param_did {
345+
self.mir_const_qualif_const_arg((def.did, param_did))
346+
} else {
347+
self.mir_const_qualif(def.did)
348+
}
349+
}
350+
351+
pub fn promoted_mir_of_opt_const_arg(
352+
self,
353+
def: ty::WithOptConstParam<DefId>,
354+
) -> &'tcx IndexVec<Promoted, Body<'tcx>> {
355+
if let Some((did, param_did)) = def.as_const_arg() {
356+
self.promoted_mir_of_const_arg((did, param_did))
357+
} else {
358+
self.promoted_mir(def.did)
359+
}
360+
}
361+
}

0 commit comments

Comments
 (0)